VPP-358: Add IPv6 ND Event Notification and Termination
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/mpls-gre/mpls.h>
39 #if DPDK > 0
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #else
43 #include <inttypes.h>
44 #endif
45 #include <vnet/map/map.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52
53 #include "vat/json_format.h"
54
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248 #if DPDK > 0
249   u32 *r = va_arg (*args, u32 *);
250
251   if (0);
252 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
253   foreach_ipsec_policy_action
254 #undef _
255     else
256     return 0;
257   return 1;
258 #else
259   return 0;
260 #endif
261 }
262
263 uword
264 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
265 {
266 #if DPDK > 0
267   u32 *r = va_arg (*args, u32 *);
268
269   if (0);
270 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
271   foreach_ipsec_crypto_alg
272 #undef _
273     else
274     return 0;
275   return 1;
276 #else
277   return 0;
278 #endif
279 }
280
281 u8 *
282 format_ipsec_crypto_alg (u8 * s, va_list * args)
283 {
284 #if DPDK > 0
285   u32 i = va_arg (*args, u32);
286   u8 *t = 0;
287
288   switch (i)
289     {
290 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
291       foreach_ipsec_crypto_alg
292 #undef _
293     default:
294       return format (s, "unknown");
295     }
296   return format (s, "%s", t);
297 #else
298   return format (s, "Unimplemented");
299 #endif
300 }
301
302 uword
303 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
304 {
305 #if DPDK > 0
306   u32 *r = va_arg (*args, u32 *);
307
308   if (0);
309 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
310   foreach_ipsec_integ_alg
311 #undef _
312     else
313     return 0;
314   return 1;
315 #else
316   return 0;
317 #endif
318 }
319
320 u8 *
321 format_ipsec_integ_alg (u8 * s, va_list * args)
322 {
323 #if DPDK > 0
324   u32 i = va_arg (*args, u32);
325   u8 *t = 0;
326
327   switch (i)
328     {
329 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
330       foreach_ipsec_integ_alg
331 #undef _
332     default:
333       return format (s, "unknown");
334     }
335   return format (s, "%s", t);
336 #else
337   return format (s, "Unsupported");
338 #endif
339 }
340
341 uword
342 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
343 {
344 #if DPDK > 0
345   u32 *r = va_arg (*args, u32 *);
346
347   if (0);
348 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
349   foreach_ikev2_auth_method
350 #undef _
351     else
352     return 0;
353   return 1;
354 #else
355   return 0;
356 #endif
357 }
358
359 uword
360 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
361 {
362 #if DPDK > 0
363   u32 *r = va_arg (*args, u32 *);
364
365   if (0);
366 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
367   foreach_ikev2_id_type
368 #undef _
369     else
370     return 0;
371   return 1;
372 #else
373   return 0;
374 #endif
375 }
376
377 uword
378 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
379 {
380   u8 *r = va_arg (*args, u8 *);
381
382   if (unformat (input, "kbps"))
383     *r = SSE2_QOS_RATE_KBPS;
384   else if (unformat (input, "pps"))
385     *r = SSE2_QOS_RATE_PPS;
386   else
387     return 0;
388   return 1;
389 }
390
391 uword
392 unformat_policer_round_type (unformat_input_t * input, va_list * args)
393 {
394   u8 *r = va_arg (*args, u8 *);
395
396   if (unformat (input, "closest"))
397     *r = SSE2_QOS_ROUND_TO_CLOSEST;
398   else if (unformat (input, "up"))
399     *r = SSE2_QOS_ROUND_TO_UP;
400   else if (unformat (input, "down"))
401     *r = SSE2_QOS_ROUND_TO_DOWN;
402   else
403     return 0;
404   return 1;
405 }
406
407 uword
408 unformat_policer_type (unformat_input_t * input, va_list * args)
409 {
410   u8 *r = va_arg (*args, u8 *);
411
412   if (unformat (input, "1r2c"))
413     *r = SSE2_QOS_POLICER_TYPE_1R2C;
414   else if (unformat (input, "1r3c"))
415     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
416   else if (unformat (input, "2r3c-2698"))
417     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
418   else if (unformat (input, "2r3c-4115"))
419     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
420   else if (unformat (input, "2r3c-mef5cf1"))
421     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
422   else
423     return 0;
424   return 1;
425 }
426
427 uword
428 unformat_dscp (unformat_input_t * input, va_list * va)
429 {
430   u8 *r = va_arg (*va, u8 *);
431
432   if (0);
433 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
434   foreach_vnet_dscp
435 #undef _
436     else
437     return 0;
438   return 1;
439 }
440
441 uword
442 unformat_policer_action_type (unformat_input_t * input, va_list * va)
443 {
444   sse2_qos_pol_action_params_st *a
445     = va_arg (*va, sse2_qos_pol_action_params_st *);
446
447   if (unformat (input, "drop"))
448     a->action_type = SSE2_QOS_ACTION_DROP;
449   else if (unformat (input, "transmit"))
450     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
451   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
452     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
453   else
454     return 0;
455   return 1;
456 }
457
458 uword
459 unformat_classify_table_type (unformat_input_t * input, va_list * va)
460 {
461   u32 *r = va_arg (*va, u32 *);
462   u32 tid;
463
464   if (unformat (input, "ip4"))
465     tid = POLICER_CLASSIFY_TABLE_IP4;
466   else if (unformat (input, "ip6"))
467     tid = POLICER_CLASSIFY_TABLE_IP6;
468   else if (unformat (input, "l2"))
469     tid = POLICER_CLASSIFY_TABLE_L2;
470   else
471     return 0;
472
473   *r = tid;
474   return 1;
475 }
476
477 u8 *
478 format_ip4_address (u8 * s, va_list * args)
479 {
480   u8 *a = va_arg (*args, u8 *);
481   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
482 }
483
484 u8 *
485 format_ip6_address (u8 * s, va_list * args)
486 {
487   ip6_address_t *a = va_arg (*args, ip6_address_t *);
488   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
489
490   i_max_n_zero = ARRAY_LEN (a->as_u16);
491   max_n_zeros = 0;
492   i_first_zero = i_max_n_zero;
493   n_zeros = 0;
494   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
495     {
496       u32 is_zero = a->as_u16[i] == 0;
497       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
498         {
499           i_first_zero = i;
500           n_zeros = 0;
501         }
502       n_zeros += is_zero;
503       if ((!is_zero && n_zeros > max_n_zeros)
504           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
505         {
506           i_max_n_zero = i_first_zero;
507           max_n_zeros = n_zeros;
508           i_first_zero = ARRAY_LEN (a->as_u16);
509           n_zeros = 0;
510         }
511     }
512
513   last_double_colon = 0;
514   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
515     {
516       if (i == i_max_n_zero && max_n_zeros > 1)
517         {
518           s = format (s, "::");
519           i += max_n_zeros - 1;
520           last_double_colon = 1;
521         }
522       else
523         {
524           s = format (s, "%s%x",
525                       (last_double_colon || i == 0) ? "" : ":",
526                       clib_net_to_host_u16 (a->as_u16[i]));
527           last_double_colon = 0;
528         }
529     }
530
531   return s;
532 }
533
534 /* Format an IP46 address. */
535 u8 *
536 format_ip46_address (u8 * s, va_list * args)
537 {
538   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
539   ip46_type_t type = va_arg (*args, ip46_type_t);
540   int is_ip4 = 1;
541
542   switch (type)
543     {
544     case IP46_TYPE_ANY:
545       is_ip4 = ip46_address_is_ip4 (ip46);
546       break;
547     case IP46_TYPE_IP4:
548       is_ip4 = 1;
549       break;
550     case IP46_TYPE_IP6:
551       is_ip4 = 0;
552       break;
553     }
554
555   return is_ip4 ?
556     format (s, "%U", format_ip4_address, &ip46->ip4) :
557     format (s, "%U", format_ip6_address, &ip46->ip6);
558 }
559
560 u8 *
561 format_ethernet_address (u8 * s, va_list * args)
562 {
563   u8 *a = va_arg (*args, u8 *);
564
565   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
566                  a[0], a[1], a[2], a[3], a[4], a[5]);
567 }
568
569 void
570 increment_v4_address (ip4_address_t * a)
571 {
572   u32 v;
573
574   v = ntohl (a->as_u32) + 1;
575   a->as_u32 = ntohl (v);
576 }
577
578 void
579 increment_v6_address (ip6_address_t * a)
580 {
581   u64 v0, v1;
582
583   v0 = clib_net_to_host_u64 (a->as_u64[0]);
584   v1 = clib_net_to_host_u64 (a->as_u64[1]);
585
586   v1 += 1;
587   if (v1 == 0)
588     v0 += 1;
589   a->as_u64[0] = clib_net_to_host_u64 (v0);
590   a->as_u64[1] = clib_net_to_host_u64 (v1);
591 }
592
593 void
594 increment_mac_address (u64 * mac)
595 {
596   u64 tmp = *mac;
597
598   tmp = clib_net_to_host_u64 (tmp);
599   tmp += 1 << 16;               /* skip unused (least significant) octets */
600   tmp = clib_host_to_net_u64 (tmp);
601   *mac = tmp;
602 }
603
604 static void vl_api_create_loopback_reply_t_handler
605   (vl_api_create_loopback_reply_t * mp)
606 {
607   vat_main_t *vam = &vat_main;
608   i32 retval = ntohl (mp->retval);
609
610   vam->retval = retval;
611   vam->regenerate_interface_table = 1;
612   vam->sw_if_index = ntohl (mp->sw_if_index);
613   vam->result_ready = 1;
614 }
615
616 static void vl_api_create_loopback_reply_t_handler_json
617   (vl_api_create_loopback_reply_t * mp)
618 {
619   vat_main_t *vam = &vat_main;
620   vat_json_node_t node;
621
622   vat_json_init_object (&node);
623   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
624   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
625
626   vat_json_print (vam->ofp, &node);
627   vat_json_free (&node);
628   vam->retval = ntohl (mp->retval);
629   vam->result_ready = 1;
630 }
631
632 static void vl_api_af_packet_create_reply_t_handler
633   (vl_api_af_packet_create_reply_t * mp)
634 {
635   vat_main_t *vam = &vat_main;
636   i32 retval = ntohl (mp->retval);
637
638   vam->retval = retval;
639   vam->regenerate_interface_table = 1;
640   vam->sw_if_index = ntohl (mp->sw_if_index);
641   vam->result_ready = 1;
642 }
643
644 static void vl_api_af_packet_create_reply_t_handler_json
645   (vl_api_af_packet_create_reply_t * mp)
646 {
647   vat_main_t *vam = &vat_main;
648   vat_json_node_t node;
649
650   vat_json_init_object (&node);
651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
652   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
653
654   vat_json_print (vam->ofp, &node);
655   vat_json_free (&node);
656
657   vam->retval = ntohl (mp->retval);
658   vam->result_ready = 1;
659 }
660
661 static void vl_api_create_vlan_subif_reply_t_handler
662   (vl_api_create_vlan_subif_reply_t * mp)
663 {
664   vat_main_t *vam = &vat_main;
665   i32 retval = ntohl (mp->retval);
666
667   vam->retval = retval;
668   vam->regenerate_interface_table = 1;
669   vam->sw_if_index = ntohl (mp->sw_if_index);
670   vam->result_ready = 1;
671 }
672
673 static void vl_api_create_vlan_subif_reply_t_handler_json
674   (vl_api_create_vlan_subif_reply_t * mp)
675 {
676   vat_main_t *vam = &vat_main;
677   vat_json_node_t node;
678
679   vat_json_init_object (&node);
680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
681   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
682
683   vat_json_print (vam->ofp, &node);
684   vat_json_free (&node);
685
686   vam->retval = ntohl (mp->retval);
687   vam->result_ready = 1;
688 }
689
690 static void vl_api_create_subif_reply_t_handler
691   (vl_api_create_subif_reply_t * mp)
692 {
693   vat_main_t *vam = &vat_main;
694   i32 retval = ntohl (mp->retval);
695
696   vam->retval = retval;
697   vam->regenerate_interface_table = 1;
698   vam->sw_if_index = ntohl (mp->sw_if_index);
699   vam->result_ready = 1;
700 }
701
702 static void vl_api_create_subif_reply_t_handler_json
703   (vl_api_create_subif_reply_t * mp)
704 {
705   vat_main_t *vam = &vat_main;
706   vat_json_node_t node;
707
708   vat_json_init_object (&node);
709   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
710   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
711
712   vat_json_print (vam->ofp, &node);
713   vat_json_free (&node);
714
715   vam->retval = ntohl (mp->retval);
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   i32 retval = ntohl (mp->retval);
724
725   vam->retval = retval;
726   vam->regenerate_interface_table = 1;
727   vam->result_ready = 1;
728 }
729
730 static void vl_api_interface_name_renumber_reply_t_handler_json
731   (vl_api_interface_name_renumber_reply_t * mp)
732 {
733   vat_main_t *vam = &vat_main;
734   vat_json_node_t node;
735
736   vat_json_init_object (&node);
737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
738
739   vat_json_print (vam->ofp, &node);
740   vat_json_free (&node);
741
742   vam->retval = ntohl (mp->retval);
743   vam->result_ready = 1;
744 }
745
746 /*
747  * Special-case: build the interface table, maintain
748  * the next loopback sw_if_index vbl.
749  */
750 static void vl_api_sw_interface_details_t_handler
751   (vl_api_sw_interface_details_t * mp)
752 {
753   vat_main_t *vam = &vat_main;
754   u8 *s = format (0, "%s%c", mp->interface_name, 0);
755
756   hash_set_mem (vam->sw_if_index_by_interface_name, s,
757                 ntohl (mp->sw_if_index));
758
759   /* In sub interface case, fill the sub interface table entry */
760   if (mp->sw_if_index != mp->sup_sw_if_index)
761     {
762       sw_interface_subif_t *sub = NULL;
763
764       vec_add2 (vam->sw_if_subif_table, sub, 1);
765
766       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
767       strncpy ((char *) sub->interface_name, (char *) s,
768                vec_len (sub->interface_name));
769       sub->sw_if_index = ntohl (mp->sw_if_index);
770       sub->sub_id = ntohl (mp->sub_id);
771
772       sub->sub_dot1ad = mp->sub_dot1ad;
773       sub->sub_number_of_tags = mp->sub_number_of_tags;
774       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
775       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
776       sub->sub_exact_match = mp->sub_exact_match;
777       sub->sub_default = mp->sub_default;
778       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
779       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
780
781       /* vlan tag rewrite */
782       sub->vtr_op = ntohl (mp->vtr_op);
783       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
784       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
785       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
786     }
787 }
788
789 static void vl_api_sw_interface_details_t_handler_json
790   (vl_api_sw_interface_details_t * mp)
791 {
792   vat_main_t *vam = &vat_main;
793   vat_json_node_t *node = NULL;
794
795   if (VAT_JSON_ARRAY != vam->json_tree.type)
796     {
797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
798       vat_json_init_array (&vam->json_tree);
799     }
800   node = vat_json_array_add (&vam->json_tree);
801
802   vat_json_init_object (node);
803   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
804   vat_json_object_add_uint (node, "sup_sw_if_index",
805                             ntohl (mp->sup_sw_if_index));
806   vat_json_object_add_uint (node, "l2_address_length",
807                             ntohl (mp->l2_address_length));
808   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
809                              sizeof (mp->l2_address));
810   vat_json_object_add_string_copy (node, "interface_name",
811                                    mp->interface_name);
812   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
813   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
814   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
815   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
816   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
817   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
818   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
819   vat_json_object_add_uint (node, "sub_number_of_tags",
820                             mp->sub_number_of_tags);
821   vat_json_object_add_uint (node, "sub_outer_vlan_id",
822                             ntohs (mp->sub_outer_vlan_id));
823   vat_json_object_add_uint (node, "sub_inner_vlan_id",
824                             ntohs (mp->sub_inner_vlan_id));
825   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
826   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
827   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
828                             mp->sub_outer_vlan_id_any);
829   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
830                             mp->sub_inner_vlan_id_any);
831   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
832   vat_json_object_add_uint (node, "vtr_push_dot1q",
833                             ntohl (mp->vtr_push_dot1q));
834   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
835   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   vat_main_t *vam = &vat_main;
842   if (vam->interface_event_display)
843     errmsg ("interface flags: sw_if_index %d %s %s\n",
844             ntohl (mp->sw_if_index),
845             mp->admin_up_down ? "admin-up" : "admin-down",
846             mp->link_up_down ? "link-up" : "link-down");
847 }
848
849 static void vl_api_sw_interface_set_flags_t_handler_json
850   (vl_api_sw_interface_set_flags_t * mp)
851 {
852   /* JSON output not supported */
853 }
854
855 static void
856 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->shmem_result = (u8 *) mp->reply_in_shmem;
863   vam->result_ready = 1;
864 }
865
866 static void
867 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
868 {
869   vat_main_t *vam = &vat_main;
870   vat_json_node_t node;
871   api_main_t *am = &api_main;
872   void *oldheap;
873   u8 *reply;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "reply_in_shmem",
878                             ntohl (mp->reply_in_shmem));
879   /* Toss the shared-memory original... */
880   pthread_mutex_lock (&am->vlib_rp->mutex);
881   oldheap = svm_push_data_heap (am->vlib_rp);
882
883   reply = (u8 *) (mp->reply_in_shmem);
884   vec_free (reply);
885
886   svm_pop_heap (oldheap);
887   pthread_mutex_unlock (&am->vlib_rp->mutex);
888
889   vat_json_print (vam->ofp, &node);
890   vat_json_free (&node);
891
892   vam->retval = ntohl (mp->retval);
893   vam->result_ready = 1;
894 }
895
896 static void vl_api_classify_add_del_table_reply_t_handler
897   (vl_api_classify_add_del_table_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   i32 retval = ntohl (mp->retval);
901   if (vam->async_mode)
902     {
903       vam->async_errors += (retval < 0);
904     }
905   else
906     {
907       vam->retval = retval;
908       if (retval == 0 &&
909           ((mp->new_table_index != 0xFFFFFFFF) ||
910            (mp->skip_n_vectors != 0xFFFFFFFF) ||
911            (mp->match_n_vectors != 0xFFFFFFFF)))
912         /*
913          * Note: this is just barely thread-safe, depends on
914          * the main thread spinning waiting for an answer...
915          */
916         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
917                 ntohl (mp->new_table_index),
918                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
919       vam->result_ready = 1;
920     }
921 }
922
923 static void vl_api_classify_add_del_table_reply_t_handler_json
924   (vl_api_classify_add_del_table_reply_t * mp)
925 {
926   vat_main_t *vam = &vat_main;
927   vat_json_node_t node;
928
929   vat_json_init_object (&node);
930   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
931   vat_json_object_add_uint (&node, "new_table_index",
932                             ntohl (mp->new_table_index));
933   vat_json_object_add_uint (&node, "skip_n_vectors",
934                             ntohl (mp->skip_n_vectors));
935   vat_json_object_add_uint (&node, "match_n_vectors",
936                             ntohl (mp->match_n_vectors));
937
938   vat_json_print (vam->ofp, &node);
939   vat_json_free (&node);
940
941   vam->retval = ntohl (mp->retval);
942   vam->result_ready = 1;
943 }
944
945 static void vl_api_get_node_index_reply_t_handler
946   (vl_api_get_node_index_reply_t * mp)
947 {
948   vat_main_t *vam = &vat_main;
949   i32 retval = ntohl (mp->retval);
950   if (vam->async_mode)
951     {
952       vam->async_errors += (retval < 0);
953     }
954   else
955     {
956       vam->retval = retval;
957       if (retval == 0)
958         errmsg ("node index %d\n", ntohl (mp->node_index));
959       vam->result_ready = 1;
960     }
961 }
962
963 static void vl_api_get_node_index_reply_t_handler_json
964   (vl_api_get_node_index_reply_t * mp)
965 {
966   vat_main_t *vam = &vat_main;
967   vat_json_node_t node;
968
969   vat_json_init_object (&node);
970   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
971   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
972
973   vat_json_print (vam->ofp, &node);
974   vat_json_free (&node);
975
976   vam->retval = ntohl (mp->retval);
977   vam->result_ready = 1;
978 }
979
980 static void vl_api_get_next_index_reply_t_handler
981   (vl_api_get_next_index_reply_t * mp)
982 {
983   vat_main_t *vam = &vat_main;
984   i32 retval = ntohl (mp->retval);
985   if (vam->async_mode)
986     {
987       vam->async_errors += (retval < 0);
988     }
989   else
990     {
991       vam->retval = retval;
992       if (retval == 0)
993         errmsg ("next node index %d\n", ntohl (mp->next_index));
994       vam->result_ready = 1;
995     }
996 }
997
998 static void vl_api_get_next_index_reply_t_handler_json
999   (vl_api_get_next_index_reply_t * mp)
1000 {
1001   vat_main_t *vam = &vat_main;
1002   vat_json_node_t node;
1003
1004   vat_json_init_object (&node);
1005   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1006   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1007
1008   vat_json_print (vam->ofp, &node);
1009   vat_json_free (&node);
1010
1011   vam->retval = ntohl (mp->retval);
1012   vam->result_ready = 1;
1013 }
1014
1015 static void vl_api_add_node_next_reply_t_handler
1016   (vl_api_add_node_next_reply_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   i32 retval = ntohl (mp->retval);
1020   if (vam->async_mode)
1021     {
1022       vam->async_errors += (retval < 0);
1023     }
1024   else
1025     {
1026       vam->retval = retval;
1027       if (retval == 0)
1028         errmsg ("next index %d\n", ntohl (mp->next_index));
1029       vam->result_ready = 1;
1030     }
1031 }
1032
1033 static void vl_api_add_node_next_reply_t_handler_json
1034   (vl_api_add_node_next_reply_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   vat_json_node_t node;
1038
1039   vat_json_init_object (&node);
1040   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1041   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1042
1043   vat_json_print (vam->ofp, &node);
1044   vat_json_free (&node);
1045
1046   vam->retval = ntohl (mp->retval);
1047   vam->result_ready = 1;
1048 }
1049
1050 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1051   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   i32 retval = ntohl (mp->retval);
1055   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1056
1057   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1058     {
1059       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1060     }
1061   vam->retval = retval;
1062   vam->result_ready = 1;
1063 }
1064
1065 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1066   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1067 {
1068   vat_main_t *vam = &vat_main;
1069   vat_json_node_t node;
1070
1071   vat_json_init_object (&node);
1072   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1073   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1074                             ntohl (mp->tunnel_sw_if_index));
1075
1076   vat_json_print (vam->ofp, &node);
1077   vat_json_free (&node);
1078
1079   vam->retval = ntohl (mp->retval);
1080   vam->result_ready = 1;
1081 }
1082
1083
1084 static void vl_api_show_version_reply_t_handler
1085   (vl_api_show_version_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   i32 retval = ntohl (mp->retval);
1089
1090   if (retval >= 0)
1091     {
1092       errmsg ("        program: %s\n", mp->program);
1093       errmsg ("        version: %s\n", mp->version);
1094       errmsg ("     build date: %s\n", mp->build_date);
1095       errmsg ("build directory: %s\n", mp->build_directory);
1096     }
1097   vam->retval = retval;
1098   vam->result_ready = 1;
1099 }
1100
1101 static void vl_api_show_version_reply_t_handler_json
1102   (vl_api_show_version_reply_t * mp)
1103 {
1104   vat_main_t *vam = &vat_main;
1105   vat_json_node_t node;
1106
1107   vat_json_init_object (&node);
1108   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1109   vat_json_object_add_string_copy (&node, "program", mp->program);
1110   vat_json_object_add_string_copy (&node, "version", mp->version);
1111   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1112   vat_json_object_add_string_copy (&node, "build_directory",
1113                                    mp->build_directory);
1114
1115   vat_json_print (vam->ofp, &node);
1116   vat_json_free (&node);
1117
1118   vam->retval = ntohl (mp->retval);
1119   vam->result_ready = 1;
1120 }
1121
1122 static void
1123 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1124 {
1125   vat_main_t *vam = &vat_main;
1126   errmsg ("arp event: address %U new mac %U sw_if_index %d\n",
1127           format_ip4_address, &mp->address,
1128           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1129 }
1130
1131 static void
1132 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1133 {
1134   /* JSON output not supported */
1135 }
1136
1137 static void
1138 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1139 {
1140   vat_main_t *vam = &vat_main;
1141   errmsg ("ip6 nd event: address %U new mac %U sw_if_index %d\n",
1142           format_ip6_address, mp->address,
1143           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1144 }
1145
1146 static void
1147 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1148 {
1149   /* JSON output not supported */
1150 }
1151
1152 /*
1153  * Special-case: build the bridge domain table, maintain
1154  * the next bd id vbl.
1155  */
1156 static void vl_api_bridge_domain_details_t_handler
1157   (vl_api_bridge_domain_details_t * mp)
1158 {
1159   vat_main_t *vam = &vat_main;
1160   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1161
1162   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1163            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1164
1165   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1166            ntohl (mp->bd_id), mp->learn, mp->forward,
1167            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1168
1169   if (n_sw_ifs)
1170     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1171              "Interface Name");
1172 }
1173
1174 static void vl_api_bridge_domain_details_t_handler_json
1175   (vl_api_bridge_domain_details_t * mp)
1176 {
1177   vat_main_t *vam = &vat_main;
1178   vat_json_node_t *node, *array = NULL;
1179
1180   if (VAT_JSON_ARRAY != vam->json_tree.type)
1181     {
1182       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1183       vat_json_init_array (&vam->json_tree);
1184     }
1185   node = vat_json_array_add (&vam->json_tree);
1186
1187   vat_json_init_object (node);
1188   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1189   vat_json_object_add_uint (node, "flood", mp->flood);
1190   vat_json_object_add_uint (node, "forward", mp->forward);
1191   vat_json_object_add_uint (node, "learn", mp->learn);
1192   vat_json_object_add_uint (node, "bvi_sw_if_index",
1193                             ntohl (mp->bvi_sw_if_index));
1194   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1195   array = vat_json_object_add (node, "sw_if");
1196   vat_json_init_array (array);
1197 }
1198
1199 /*
1200  * Special-case: build the bridge domain sw if table.
1201  */
1202 static void vl_api_bridge_domain_sw_if_details_t_handler
1203   (vl_api_bridge_domain_sw_if_details_t * mp)
1204 {
1205   vat_main_t *vam = &vat_main;
1206   hash_pair_t *p;
1207   u8 *sw_if_name = 0;
1208   u32 sw_if_index;
1209
1210   sw_if_index = ntohl (mp->sw_if_index);
1211   /* *INDENT-OFF* */
1212   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1213   ({
1214     if ((u32) p->value[0] == sw_if_index)
1215       {
1216         sw_if_name = (u8 *)(p->key);
1217         break;
1218       }
1219   }));
1220   /* *INDENT-ON* */
1221
1222   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1223            mp->shg, sw_if_name ? (char *) sw_if_name :
1224            "sw_if_index not found!");
1225 }
1226
1227 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1228   (vl_api_bridge_domain_sw_if_details_t * mp)
1229 {
1230   vat_main_t *vam = &vat_main;
1231   vat_json_node_t *node = NULL;
1232   uword last_index = 0;
1233
1234   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1235   ASSERT (vec_len (vam->json_tree.array) >= 1);
1236   last_index = vec_len (vam->json_tree.array) - 1;
1237   node = &vam->json_tree.array[last_index];
1238   node = vat_json_object_get_element (node, "sw_if");
1239   ASSERT (NULL != node);
1240   node = vat_json_array_add (node);
1241
1242   vat_json_init_object (node);
1243   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1244   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1245   vat_json_object_add_uint (node, "shg", mp->shg);
1246 }
1247
1248 static void vl_api_control_ping_reply_t_handler
1249   (vl_api_control_ping_reply_t * mp)
1250 {
1251   vat_main_t *vam = &vat_main;
1252   i32 retval = ntohl (mp->retval);
1253   if (vam->async_mode)
1254     {
1255       vam->async_errors += (retval < 0);
1256     }
1257   else
1258     {
1259       vam->retval = retval;
1260       vam->result_ready = 1;
1261     }
1262 }
1263
1264 static void vl_api_control_ping_reply_t_handler_json
1265   (vl_api_control_ping_reply_t * mp)
1266 {
1267   vat_main_t *vam = &vat_main;
1268   i32 retval = ntohl (mp->retval);
1269
1270   if (VAT_JSON_NONE != vam->json_tree.type)
1271     {
1272       vat_json_print (vam->ofp, &vam->json_tree);
1273       vat_json_free (&vam->json_tree);
1274       vam->json_tree.type = VAT_JSON_NONE;
1275     }
1276   else
1277     {
1278       /* just print [] */
1279       vat_json_init_array (&vam->json_tree);
1280       vat_json_print (vam->ofp, &vam->json_tree);
1281       vam->json_tree.type = VAT_JSON_NONE;
1282     }
1283
1284   vam->retval = retval;
1285   vam->result_ready = 1;
1286 }
1287
1288 static void vl_api_noprint_control_ping_reply_t_handler
1289   (vl_api_noprint_control_ping_reply_t * mp)
1290 {
1291   vat_main_t *vam = &vat_main;
1292   i32 retval = ntohl (mp->retval);
1293   if (vam->async_mode)
1294     {
1295       vam->async_errors += (retval < 0);
1296     }
1297   else
1298     {
1299       vam->retval = retval;
1300       vam->result_ready = 1;
1301     }
1302 }
1303
1304 static void vl_api_noprint_control_ping_reply_t_handler_json
1305   (vl_api_noprint_control_ping_reply_t * mp)
1306 {
1307   vat_main_t *vam = &vat_main;
1308   i32 retval = ntohl (mp->retval);
1309
1310   if (vam->noprint_msg)
1311     {
1312       vam->retval = retval;
1313       vam->result_ready = 1;
1314       return;
1315     }
1316
1317   if (VAT_JSON_NONE != vam->json_tree.type)
1318     {
1319       vat_json_print (vam->ofp, &vam->json_tree);
1320       vat_json_free (&vam->json_tree);
1321       vam->json_tree.type = VAT_JSON_NONE;
1322     }
1323   else
1324     {
1325       /* just print [] */
1326       vat_json_init_array (&vam->json_tree);
1327       vat_json_print (vam->ofp, &vam->json_tree);
1328       vam->json_tree.type = VAT_JSON_NONE;
1329     }
1330
1331   vam->retval = retval;
1332   vam->result_ready = 1;
1333 }
1334
1335 static void
1336 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1337 {
1338   vat_main_t *vam = &vat_main;
1339   i32 retval = ntohl (mp->retval);
1340   if (vam->async_mode)
1341     {
1342       vam->async_errors += (retval < 0);
1343     }
1344   else
1345     {
1346       vam->retval = retval;
1347       vam->result_ready = 1;
1348     }
1349 }
1350
1351 static void vl_api_l2_flags_reply_t_handler_json
1352   (vl_api_l2_flags_reply_t * mp)
1353 {
1354   vat_main_t *vam = &vat_main;
1355   vat_json_node_t node;
1356
1357   vat_json_init_object (&node);
1358   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1359   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1360                             ntohl (mp->resulting_feature_bitmap));
1361
1362   vat_json_print (vam->ofp, &node);
1363   vat_json_free (&node);
1364
1365   vam->retval = ntohl (mp->retval);
1366   vam->result_ready = 1;
1367 }
1368
1369 static void vl_api_bridge_flags_reply_t_handler
1370   (vl_api_bridge_flags_reply_t * mp)
1371 {
1372   vat_main_t *vam = &vat_main;
1373   i32 retval = ntohl (mp->retval);
1374   if (vam->async_mode)
1375     {
1376       vam->async_errors += (retval < 0);
1377     }
1378   else
1379     {
1380       vam->retval = retval;
1381       vam->result_ready = 1;
1382     }
1383 }
1384
1385 static void vl_api_bridge_flags_reply_t_handler_json
1386   (vl_api_bridge_flags_reply_t * mp)
1387 {
1388   vat_main_t *vam = &vat_main;
1389   vat_json_node_t node;
1390
1391   vat_json_init_object (&node);
1392   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1393   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1394                             ntohl (mp->resulting_feature_bitmap));
1395
1396   vat_json_print (vam->ofp, &node);
1397   vat_json_free (&node);
1398
1399   vam->retval = ntohl (mp->retval);
1400   vam->result_ready = 1;
1401 }
1402
1403 static void vl_api_tap_connect_reply_t_handler
1404   (vl_api_tap_connect_reply_t * mp)
1405 {
1406   vat_main_t *vam = &vat_main;
1407   i32 retval = ntohl (mp->retval);
1408   if (vam->async_mode)
1409     {
1410       vam->async_errors += (retval < 0);
1411     }
1412   else
1413     {
1414       vam->retval = retval;
1415       vam->sw_if_index = ntohl (mp->sw_if_index);
1416       vam->result_ready = 1;
1417     }
1418
1419 }
1420
1421 static void vl_api_tap_connect_reply_t_handler_json
1422   (vl_api_tap_connect_reply_t * mp)
1423 {
1424   vat_main_t *vam = &vat_main;
1425   vat_json_node_t node;
1426
1427   vat_json_init_object (&node);
1428   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1429   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1430
1431   vat_json_print (vam->ofp, &node);
1432   vat_json_free (&node);
1433
1434   vam->retval = ntohl (mp->retval);
1435   vam->result_ready = 1;
1436
1437 }
1438
1439 static void
1440 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1441 {
1442   vat_main_t *vam = &vat_main;
1443   i32 retval = ntohl (mp->retval);
1444   if (vam->async_mode)
1445     {
1446       vam->async_errors += (retval < 0);
1447     }
1448   else
1449     {
1450       vam->retval = retval;
1451       vam->sw_if_index = ntohl (mp->sw_if_index);
1452       vam->result_ready = 1;
1453     }
1454 }
1455
1456 static void vl_api_tap_modify_reply_t_handler_json
1457   (vl_api_tap_modify_reply_t * mp)
1458 {
1459   vat_main_t *vam = &vat_main;
1460   vat_json_node_t node;
1461
1462   vat_json_init_object (&node);
1463   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1464   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1465
1466   vat_json_print (vam->ofp, &node);
1467   vat_json_free (&node);
1468
1469   vam->retval = ntohl (mp->retval);
1470   vam->result_ready = 1;
1471 }
1472
1473 static void
1474 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1475 {
1476   vat_main_t *vam = &vat_main;
1477   i32 retval = ntohl (mp->retval);
1478   if (vam->async_mode)
1479     {
1480       vam->async_errors += (retval < 0);
1481     }
1482   else
1483     {
1484       vam->retval = retval;
1485       vam->result_ready = 1;
1486     }
1487 }
1488
1489 static void vl_api_tap_delete_reply_t_handler_json
1490   (vl_api_tap_delete_reply_t * mp)
1491 {
1492   vat_main_t *vam = &vat_main;
1493   vat_json_node_t node;
1494
1495   vat_json_init_object (&node);
1496   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1497
1498   vat_json_print (vam->ofp, &node);
1499   vat_json_free (&node);
1500
1501   vam->retval = ntohl (mp->retval);
1502   vam->result_ready = 1;
1503 }
1504
1505 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1506   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1507 {
1508   vat_main_t *vam = &vat_main;
1509   i32 retval = ntohl (mp->retval);
1510   if (vam->async_mode)
1511     {
1512       vam->async_errors += (retval < 0);
1513     }
1514   else
1515     {
1516       vam->retval = retval;
1517       vam->result_ready = 1;
1518     }
1519 }
1520
1521 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1522   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1523 {
1524   vat_main_t *vam = &vat_main;
1525   vat_json_node_t node;
1526
1527   vat_json_init_object (&node);
1528   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1529   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1530                             ntohl (mp->tunnel_sw_if_index));
1531
1532   vat_json_print (vam->ofp, &node);
1533   vat_json_free (&node);
1534
1535   vam->retval = ntohl (mp->retval);
1536   vam->result_ready = 1;
1537 }
1538
1539 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1540   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1541 {
1542   vat_main_t *vam = &vat_main;
1543   i32 retval = ntohl (mp->retval);
1544   if (vam->async_mode)
1545     {
1546       vam->async_errors += (retval < 0);
1547     }
1548   else
1549     {
1550       vam->retval = retval;
1551       vam->sw_if_index = ntohl (mp->sw_if_index);
1552       vam->result_ready = 1;
1553     }
1554 }
1555
1556 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1557   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1558 {
1559   vat_main_t *vam = &vat_main;
1560   vat_json_node_t node;
1561
1562   vat_json_init_object (&node);
1563   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1564   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1565
1566   vat_json_print (vam->ofp, &node);
1567   vat_json_free (&node);
1568
1569   vam->retval = ntohl (mp->retval);
1570   vam->result_ready = 1;
1571 }
1572
1573
1574 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1575   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1576 {
1577   vat_main_t *vam = &vat_main;
1578   i32 retval = ntohl (mp->retval);
1579   if (vam->async_mode)
1580     {
1581       vam->async_errors += (retval < 0);
1582     }
1583   else
1584     {
1585       vam->retval = retval;
1586       vam->result_ready = 1;
1587     }
1588 }
1589
1590 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1591   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1592 {
1593   vat_main_t *vam = &vat_main;
1594   vat_json_node_t node;
1595
1596   vat_json_init_object (&node);
1597   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1598   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1599
1600   vat_json_print (vam->ofp, &node);
1601   vat_json_free (&node);
1602
1603   vam->retval = ntohl (mp->retval);
1604   vam->result_ready = 1;
1605 }
1606
1607 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1608   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1609 {
1610   vat_main_t *vam = &vat_main;
1611   i32 retval = ntohl (mp->retval);
1612   if (vam->async_mode)
1613     {
1614       vam->async_errors += (retval < 0);
1615     }
1616   else
1617     {
1618       vam->retval = retval;
1619       vam->sw_if_index = ntohl (mp->sw_if_index);
1620       vam->result_ready = 1;
1621     }
1622 }
1623
1624 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1625   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1626 {
1627   vat_main_t *vam = &vat_main;
1628   vat_json_node_t node;
1629
1630   vat_json_init_object (&node);
1631   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1632   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1633
1634   vat_json_print (vam->ofp, &node);
1635   vat_json_free (&node);
1636
1637   vam->retval = ntohl (mp->retval);
1638   vam->result_ready = 1;
1639 }
1640
1641 static void vl_api_gre_add_del_tunnel_reply_t_handler
1642   (vl_api_gre_add_del_tunnel_reply_t * mp)
1643 {
1644   vat_main_t *vam = &vat_main;
1645   i32 retval = ntohl (mp->retval);
1646   if (vam->async_mode)
1647     {
1648       vam->async_errors += (retval < 0);
1649     }
1650   else
1651     {
1652       vam->retval = retval;
1653       vam->sw_if_index = ntohl (mp->sw_if_index);
1654       vam->result_ready = 1;
1655     }
1656 }
1657
1658 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1659   (vl_api_gre_add_del_tunnel_reply_t * mp)
1660 {
1661   vat_main_t *vam = &vat_main;
1662   vat_json_node_t node;
1663
1664   vat_json_init_object (&node);
1665   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1666   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1667
1668   vat_json_print (vam->ofp, &node);
1669   vat_json_free (&node);
1670
1671   vam->retval = ntohl (mp->retval);
1672   vam->result_ready = 1;
1673 }
1674
1675 static void vl_api_create_vhost_user_if_reply_t_handler
1676   (vl_api_create_vhost_user_if_reply_t * mp)
1677 {
1678   vat_main_t *vam = &vat_main;
1679   i32 retval = ntohl (mp->retval);
1680   if (vam->async_mode)
1681     {
1682       vam->async_errors += (retval < 0);
1683     }
1684   else
1685     {
1686       vam->retval = retval;
1687       vam->sw_if_index = ntohl (mp->sw_if_index);
1688       vam->result_ready = 1;
1689     }
1690 }
1691
1692 static void vl_api_create_vhost_user_if_reply_t_handler_json
1693   (vl_api_create_vhost_user_if_reply_t * mp)
1694 {
1695   vat_main_t *vam = &vat_main;
1696   vat_json_node_t node;
1697
1698   vat_json_init_object (&node);
1699   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1700   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1701
1702   vat_json_print (vam->ofp, &node);
1703   vat_json_free (&node);
1704
1705   vam->retval = ntohl (mp->retval);
1706   vam->result_ready = 1;
1707 }
1708
1709 static void vl_api_ip_address_details_t_handler
1710   (vl_api_ip_address_details_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   static ip_address_details_t empty_ip_address_details = { {0} };
1714   ip_address_details_t *address = NULL;
1715   ip_details_t *current_ip_details = NULL;
1716   ip_details_t *details = NULL;
1717
1718   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1719
1720   if (!details || vam->current_sw_if_index >= vec_len (details)
1721       || !details[vam->current_sw_if_index].present)
1722     {
1723       errmsg ("ip address details arrived but not stored\n");
1724       errmsg ("ip_dump should be called first\n");
1725       return;
1726     }
1727
1728   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1729
1730 #define addresses (current_ip_details->addr)
1731
1732   vec_validate_init_empty (addresses, vec_len (addresses),
1733                            empty_ip_address_details);
1734
1735   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1736
1737   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1738   address->prefix_length = mp->prefix_length;
1739 #undef addresses
1740 }
1741
1742 static void vl_api_ip_address_details_t_handler_json
1743   (vl_api_ip_address_details_t * mp)
1744 {
1745   vat_main_t *vam = &vat_main;
1746   vat_json_node_t *node = NULL;
1747   struct in6_addr ip6;
1748   struct in_addr ip4;
1749
1750   if (VAT_JSON_ARRAY != vam->json_tree.type)
1751     {
1752       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1753       vat_json_init_array (&vam->json_tree);
1754     }
1755   node = vat_json_array_add (&vam->json_tree);
1756
1757   vat_json_init_object (node);
1758   if (vam->is_ipv6)
1759     {
1760       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1761       vat_json_object_add_ip6 (node, "ip", ip6);
1762     }
1763   else
1764     {
1765       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1766       vat_json_object_add_ip4 (node, "ip", ip4);
1767     }
1768   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1769 }
1770
1771 static void
1772 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1773 {
1774   vat_main_t *vam = &vat_main;
1775   static ip_details_t empty_ip_details = { 0 };
1776   ip_details_t *ip = NULL;
1777   u32 sw_if_index = ~0;
1778
1779   sw_if_index = ntohl (mp->sw_if_index);
1780
1781   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1782                            sw_if_index, empty_ip_details);
1783
1784   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1785                          sw_if_index);
1786
1787   ip->present = 1;
1788 }
1789
1790 static void
1791 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1792 {
1793   vat_main_t *vam = &vat_main;
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   vat_json_array_add_uint (&vam->json_tree,
1801                            clib_net_to_host_u32 (mp->sw_if_index));
1802 }
1803
1804 static void vl_api_map_domain_details_t_handler_json
1805   (vl_api_map_domain_details_t * mp)
1806 {
1807   vat_json_node_t *node = NULL;
1808   vat_main_t *vam = &vat_main;
1809   struct in6_addr ip6;
1810   struct in_addr ip4;
1811
1812   if (VAT_JSON_ARRAY != vam->json_tree.type)
1813     {
1814       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1815       vat_json_init_array (&vam->json_tree);
1816     }
1817
1818   node = vat_json_array_add (&vam->json_tree);
1819   vat_json_init_object (node);
1820
1821   vat_json_object_add_uint (node, "domain_index",
1822                             clib_net_to_host_u32 (mp->domain_index));
1823   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1824   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1825   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1826   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1827   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1828   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1829   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1830   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1831   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1832   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1833   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1834   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1835   vat_json_object_add_uint (node, "flags", mp->flags);
1836   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1837   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1838 }
1839
1840 static void vl_api_map_domain_details_t_handler
1841   (vl_api_map_domain_details_t * mp)
1842 {
1843   vat_main_t *vam = &vat_main;
1844
1845   if (mp->is_translation)
1846     {
1847       fformat (vam->ofp,
1848                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1849                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1850                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1851                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1852                clib_net_to_host_u32 (mp->domain_index));
1853     }
1854   else
1855     {
1856       fformat (vam->ofp,
1857                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1858                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1859                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1860                format_ip6_address, mp->ip6_src,
1861                clib_net_to_host_u32 (mp->domain_index));
1862     }
1863   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1864            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1865            mp->is_translation ? "map-t" : "");
1866 }
1867
1868 static void vl_api_map_rule_details_t_handler_json
1869   (vl_api_map_rule_details_t * mp)
1870 {
1871   struct in6_addr ip6;
1872   vat_json_node_t *node = NULL;
1873   vat_main_t *vam = &vat_main;
1874
1875   if (VAT_JSON_ARRAY != vam->json_tree.type)
1876     {
1877       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1878       vat_json_init_array (&vam->json_tree);
1879     }
1880
1881   node = vat_json_array_add (&vam->json_tree);
1882   vat_json_init_object (node);
1883
1884   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1885   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1886   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1887 }
1888
1889 static void
1890 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1891 {
1892   vat_main_t *vam = &vat_main;
1893   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1894            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1895 }
1896
1897 static void
1898 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1899 {
1900   vat_main_t *vam = &vat_main;
1901   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1902           "router_addr %U host_mac %U\n",
1903           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1904           format_ip4_address, &mp->host_address,
1905           format_ip4_address, &mp->router_address,
1906           format_ethernet_address, mp->host_mac);
1907 }
1908
1909 static void vl_api_dhcp_compl_event_t_handler_json
1910   (vl_api_dhcp_compl_event_t * mp)
1911 {
1912   /* JSON output not supported */
1913 }
1914
1915 static void
1916 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1917                               u32 counter)
1918 {
1919   vat_main_t *vam = &vat_main;
1920   static u64 default_counter = 0;
1921
1922   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1923                            NULL);
1924   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1925                            sw_if_index, default_counter);
1926   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1927 }
1928
1929 static void
1930 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1931                                 interface_counter_t counter)
1932 {
1933   vat_main_t *vam = &vat_main;
1934   static interface_counter_t default_counter = { 0, };
1935
1936   vec_validate_init_empty (vam->combined_interface_counters,
1937                            vnet_counter_type, NULL);
1938   vec_validate_init_empty (vam->combined_interface_counters
1939                            [vnet_counter_type], sw_if_index, default_counter);
1940   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1941 }
1942
1943 static void vl_api_vnet_interface_counters_t_handler
1944   (vl_api_vnet_interface_counters_t * mp)
1945 {
1946   /* not supported */
1947 }
1948
1949 static void vl_api_vnet_interface_counters_t_handler_json
1950   (vl_api_vnet_interface_counters_t * mp)
1951 {
1952   interface_counter_t counter;
1953   vlib_counter_t *v;
1954   u64 *v_packets;
1955   u64 packets;
1956   u32 count;
1957   u32 first_sw_if_index;
1958   int i;
1959
1960   count = ntohl (mp->count);
1961   first_sw_if_index = ntohl (mp->first_sw_if_index);
1962
1963   if (!mp->is_combined)
1964     {
1965       v_packets = (u64 *) & mp->data;
1966       for (i = 0; i < count; i++)
1967         {
1968           packets =
1969             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1970           set_simple_interface_counter (mp->vnet_counter_type,
1971                                         first_sw_if_index + i, packets);
1972           v_packets++;
1973         }
1974     }
1975   else
1976     {
1977       v = (vlib_counter_t *) & mp->data;
1978       for (i = 0; i < count; i++)
1979         {
1980           counter.packets =
1981             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1982           counter.bytes =
1983             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1984           set_combined_interface_counter (mp->vnet_counter_type,
1985                                           first_sw_if_index + i, counter);
1986           v++;
1987         }
1988     }
1989 }
1990
1991 static u32
1992 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1993 {
1994   vat_main_t *vam = &vat_main;
1995   u32 i;
1996
1997   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1998     {
1999       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2000         {
2001           return i;
2002         }
2003     }
2004   return ~0;
2005 }
2006
2007 static u32
2008 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2009 {
2010   vat_main_t *vam = &vat_main;
2011   u32 i;
2012
2013   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2014     {
2015       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2016         {
2017           return i;
2018         }
2019     }
2020   return ~0;
2021 }
2022
2023 static void vl_api_vnet_ip4_fib_counters_t_handler
2024   (vl_api_vnet_ip4_fib_counters_t * mp)
2025 {
2026   /* not supported */
2027 }
2028
2029 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2030   (vl_api_vnet_ip4_fib_counters_t * mp)
2031 {
2032   vat_main_t *vam = &vat_main;
2033   vl_api_ip4_fib_counter_t *v;
2034   ip4_fib_counter_t *counter;
2035   struct in_addr ip4;
2036   u32 vrf_id;
2037   u32 vrf_index;
2038   u32 count;
2039   int i;
2040
2041   vrf_id = ntohl (mp->vrf_id);
2042   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2043   if (~0 == vrf_index)
2044     {
2045       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2046       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2047       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2048       vec_validate (vam->ip4_fib_counters, vrf_index);
2049       vam->ip4_fib_counters[vrf_index] = NULL;
2050     }
2051
2052   vec_free (vam->ip4_fib_counters[vrf_index]);
2053   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2054   count = ntohl (mp->count);
2055   for (i = 0; i < count; i++)
2056     {
2057       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2058       counter = &vam->ip4_fib_counters[vrf_index][i];
2059       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2060       counter->address = ip4;
2061       counter->address_length = v->address_length;
2062       counter->packets = clib_net_to_host_u64 (v->packets);
2063       counter->bytes = clib_net_to_host_u64 (v->bytes);
2064       v++;
2065     }
2066 }
2067
2068 static void vl_api_vnet_ip6_fib_counters_t_handler
2069   (vl_api_vnet_ip6_fib_counters_t * mp)
2070 {
2071   /* not supported */
2072 }
2073
2074 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2075   (vl_api_vnet_ip6_fib_counters_t * mp)
2076 {
2077   vat_main_t *vam = &vat_main;
2078   vl_api_ip6_fib_counter_t *v;
2079   ip6_fib_counter_t *counter;
2080   struct in6_addr ip6;
2081   u32 vrf_id;
2082   u32 vrf_index;
2083   u32 count;
2084   int i;
2085
2086   vrf_id = ntohl (mp->vrf_id);
2087   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2088   if (~0 == vrf_index)
2089     {
2090       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2091       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2092       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2093       vec_validate (vam->ip6_fib_counters, vrf_index);
2094       vam->ip6_fib_counters[vrf_index] = NULL;
2095     }
2096
2097   vec_free (vam->ip6_fib_counters[vrf_index]);
2098   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2099   count = ntohl (mp->count);
2100   for (i = 0; i < count; i++)
2101     {
2102       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2103       counter = &vam->ip6_fib_counters[vrf_index][i];
2104       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2105       counter->address = ip6;
2106       counter->address_length = v->address_length;
2107       counter->packets = clib_net_to_host_u64 (v->packets);
2108       counter->bytes = clib_net_to_host_u64 (v->bytes);
2109       v++;
2110     }
2111 }
2112
2113 static void vl_api_get_first_msg_id_reply_t_handler
2114   (vl_api_get_first_msg_id_reply_t * mp)
2115 {
2116   vat_main_t *vam = &vat_main;
2117   i32 retval = ntohl (mp->retval);
2118
2119   if (vam->async_mode)
2120     {
2121       vam->async_errors += (retval < 0);
2122     }
2123   else
2124     {
2125       vam->retval = retval;
2126       vam->result_ready = 1;
2127     }
2128   if (retval >= 0)
2129     {
2130       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2131     }
2132 }
2133
2134 static void vl_api_get_first_msg_id_reply_t_handler_json
2135   (vl_api_get_first_msg_id_reply_t * mp)
2136 {
2137   vat_main_t *vam = &vat_main;
2138   vat_json_node_t node;
2139
2140   vat_json_init_object (&node);
2141   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2142   vat_json_object_add_uint (&node, "first_msg_id",
2143                             (uint) ntohs (mp->first_msg_id));
2144
2145   vat_json_print (vam->ofp, &node);
2146   vat_json_free (&node);
2147
2148   vam->retval = ntohl (mp->retval);
2149   vam->result_ready = 1;
2150 }
2151
2152 static void vl_api_get_node_graph_reply_t_handler
2153   (vl_api_get_node_graph_reply_t * mp)
2154 {
2155   vat_main_t *vam = &vat_main;
2156   api_main_t *am = &api_main;
2157   i32 retval = ntohl (mp->retval);
2158   u8 *pvt_copy, *reply;
2159   void *oldheap;
2160   vlib_node_t *node;
2161   int i;
2162
2163   if (vam->async_mode)
2164     {
2165       vam->async_errors += (retval < 0);
2166     }
2167   else
2168     {
2169       vam->retval = retval;
2170       vam->result_ready = 1;
2171     }
2172
2173   /* "Should never happen..." */
2174   if (retval != 0)
2175     return;
2176
2177   reply = (u8 *) (mp->reply_in_shmem);
2178   pvt_copy = vec_dup (reply);
2179
2180   /* Toss the shared-memory original... */
2181   pthread_mutex_lock (&am->vlib_rp->mutex);
2182   oldheap = svm_push_data_heap (am->vlib_rp);
2183
2184   vec_free (reply);
2185
2186   svm_pop_heap (oldheap);
2187   pthread_mutex_unlock (&am->vlib_rp->mutex);
2188
2189   if (vam->graph_nodes)
2190     {
2191       hash_free (vam->graph_node_index_by_name);
2192
2193       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2194         {
2195           node = vam->graph_nodes[i];
2196           vec_free (node->name);
2197           vec_free (node->next_nodes);
2198           vec_free (node);
2199         }
2200       vec_free (vam->graph_nodes);
2201     }
2202
2203   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2204   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2205   vec_free (pvt_copy);
2206
2207   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2208     {
2209       node = vam->graph_nodes[i];
2210       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2211     }
2212 }
2213
2214 static void vl_api_get_node_graph_reply_t_handler_json
2215   (vl_api_get_node_graph_reply_t * mp)
2216 {
2217   vat_main_t *vam = &vat_main;
2218   api_main_t *am = &api_main;
2219   void *oldheap;
2220   vat_json_node_t node;
2221   u8 *reply;
2222
2223   /* $$$$ make this real? */
2224   vat_json_init_object (&node);
2225   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2226   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2227
2228   reply = (u8 *) (mp->reply_in_shmem);
2229
2230   /* Toss the shared-memory original... */
2231   pthread_mutex_lock (&am->vlib_rp->mutex);
2232   oldheap = svm_push_data_heap (am->vlib_rp);
2233
2234   vec_free (reply);
2235
2236   svm_pop_heap (oldheap);
2237   pthread_mutex_unlock (&am->vlib_rp->mutex);
2238
2239   vat_json_print (vam->ofp, &node);
2240   vat_json_free (&node);
2241
2242   vam->retval = ntohl (mp->retval);
2243   vam->result_ready = 1;
2244 }
2245
2246 static void
2247 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2248 {
2249   vat_main_t *vam = &vat_main;
2250   locator_msg_t loc;
2251   u8 *tmp_str = 0;
2252
2253   memset (&loc, 0, sizeof (loc));
2254   if (vam->noprint_msg)
2255     {
2256       loc.local = mp->local;
2257       loc.priority = mp->priority;
2258       loc.weight = mp->weight;
2259       if (loc.local)
2260         {
2261           loc.sw_if_index = ntohl (mp->sw_if_index);
2262         }
2263       else
2264         {
2265           loc.is_ipv6 = mp->is_ipv6;
2266           clib_memcpy (loc.ip_address, mp->ip_address,
2267                        sizeof (loc.ip_address));
2268         }
2269       vec_add1 (vam->locator_msg, loc);
2270     }
2271   else
2272     {
2273       if (mp->local)
2274         {
2275           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
2276                             ntohl (mp->sw_if_index),
2277                             mp->priority, mp->weight);
2278         }
2279       else
2280         {
2281           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
2282                             mp->is_ipv6 ? format_ip6_address :
2283                             format_ip4_address,
2284                             mp->ip_address, mp->priority, mp->weight);
2285         }
2286
2287       fformat (vam->ofp, "%s", tmp_str);
2288
2289       vec_free (tmp_str);
2290     }
2291 }
2292
2293 static void
2294 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2295                                             mp)
2296 {
2297   vat_main_t *vam = &vat_main;
2298   vat_json_node_t *node = NULL;
2299   locator_msg_t loc;
2300   struct in6_addr ip6;
2301   struct in_addr ip4;
2302
2303   memset (&loc, 0, sizeof (loc));
2304   if (vam->noprint_msg)
2305     {
2306       loc.local = mp->local;
2307       loc.priority = mp->priority;
2308       loc.weight = mp->weight;
2309       if (loc.local)
2310         {
2311           loc.sw_if_index = ntohl (mp->sw_if_index);
2312         }
2313       else
2314         {
2315           loc.is_ipv6 = mp->is_ipv6;
2316           clib_memcpy (loc.ip_address, mp->ip_address,
2317                        sizeof (loc.ip_address));
2318         }
2319       vec_add1 (vam->locator_msg, loc);
2320       return;
2321     }
2322
2323   if (VAT_JSON_ARRAY != vam->json_tree.type)
2324     {
2325       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2326       vat_json_init_array (&vam->json_tree);
2327     }
2328   node = vat_json_array_add (&vam->json_tree);
2329
2330   vat_json_init_object (node);
2331
2332   if (mp->local)
2333     {
2334       vat_json_object_add_uint (node, "locator_index",
2335                                 ntohl (mp->sw_if_index));
2336     }
2337   else
2338     {
2339       if (mp->is_ipv6)
2340         {
2341           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2342           vat_json_object_add_ip6 (node, "locator", ip6);
2343         }
2344       else
2345         {
2346           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2347           vat_json_object_add_ip4 (node, "locator", ip4);
2348         }
2349     }
2350   vat_json_object_add_uint (node, "priority", mp->priority);
2351   vat_json_object_add_uint (node, "weight", mp->weight);
2352 }
2353
2354 static void
2355 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2356                                            mp)
2357 {
2358   vat_main_t *vam = &vat_main;
2359   locator_set_msg_t ls;
2360
2361   ls.locator_set_index = ntohl (mp->locator_set_index);
2362   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2363   vec_add1 (vam->locator_set_msg, ls);
2364 }
2365
2366 static void
2367   vl_api_lisp_locator_set_details_t_handler_json
2368   (vl_api_lisp_locator_set_details_t * mp)
2369 {
2370   vat_main_t *vam = &vat_main;
2371   locator_set_msg_t ls;
2372
2373   ls.locator_set_index = ntohl (mp->locator_set_index);
2374   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2375   vec_add1 (vam->locator_set_msg, ls);
2376 }
2377
2378 static void
2379 add_lisp_eid_table_entry (vat_main_t * vam,
2380                           vl_api_lisp_eid_table_details_t * mp)
2381 {
2382   eid_table_t eid_table;
2383
2384   memset (&eid_table, 0, sizeof (eid_table));
2385   eid_table.is_local = mp->is_local;
2386   eid_table.locator_set_index = clib_net_to_host_u32 (mp->locator_set_index);
2387   eid_table.eid_type = mp->eid_type;
2388   eid_table.vni = clib_net_to_host_u32 (mp->vni);
2389   eid_table.eid_prefix_len = mp->eid_prefix_len;
2390   eid_table.ttl = clib_net_to_host_u32 (mp->ttl);
2391   eid_table.action = mp->action;
2392   eid_table.authoritative = mp->authoritative;
2393   clib_memcpy (eid_table.eid, mp->eid, sizeof (eid_table.eid));
2394   vec_add1 (vam->eid_tables, eid_table);
2395 }
2396
2397 static void
2398 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2399 {
2400   vat_main_t *vam = &vat_main;
2401   add_lisp_eid_table_entry (vam, mp);
2402 }
2403
2404 static void
2405 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2406                                               * mp)
2407 {
2408   vat_main_t *vam = &vat_main;
2409   add_lisp_eid_table_entry (vam, mp);
2410 }
2411
2412 static void
2413   vl_api_lisp_eid_table_map_details_t_handler
2414   (vl_api_lisp_eid_table_map_details_t * mp)
2415 {
2416   vat_main_t *vam = &vat_main;
2417
2418   u8 *line = format (0, "%=10d%=10d",
2419                      clib_net_to_host_u32 (mp->vni),
2420                      clib_net_to_host_u32 (mp->dp_table));
2421   fformat (vam->ofp, "%v\n", line);
2422   vec_free (line);
2423 }
2424
2425 static void
2426   vl_api_lisp_eid_table_map_details_t_handler_json
2427   (vl_api_lisp_eid_table_map_details_t * mp)
2428 {
2429   vat_main_t *vam = &vat_main;
2430   vat_json_node_t *node = NULL;
2431
2432   if (VAT_JSON_ARRAY != vam->json_tree.type)
2433     {
2434       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2435       vat_json_init_array (&vam->json_tree);
2436     }
2437   node = vat_json_array_add (&vam->json_tree);
2438   vat_json_init_object (node);
2439   vat_json_object_add_uint (node, "dp_table",
2440                             clib_net_to_host_u32 (mp->dp_table));
2441   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2442 }
2443
2444 static void
2445   vl_api_lisp_eid_table_vni_details_t_handler
2446   (vl_api_lisp_eid_table_vni_details_t * mp)
2447 {
2448   vat_main_t *vam = &vat_main;
2449
2450   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2451   fformat (vam->ofp, "%v\n", line);
2452   vec_free (line);
2453 }
2454
2455 static void
2456   vl_api_lisp_eid_table_vni_details_t_handler_json
2457   (vl_api_lisp_eid_table_vni_details_t * mp)
2458 {
2459   vat_main_t *vam = &vat_main;
2460   vat_json_node_t *node = NULL;
2461
2462   if (VAT_JSON_ARRAY != vam->json_tree.type)
2463     {
2464       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2465       vat_json_init_array (&vam->json_tree);
2466     }
2467   node = vat_json_array_add (&vam->json_tree);
2468   vat_json_init_object (node);
2469   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2470 }
2471
2472 static u8 *
2473 format_decap_next (u8 * s, va_list * args)
2474 {
2475   u32 next_index = va_arg (*args, u32);
2476
2477   switch (next_index)
2478     {
2479     case LISP_GPE_INPUT_NEXT_DROP:
2480       return format (s, "drop");
2481     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2482       return format (s, "ip4");
2483     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2484       return format (s, "ip6");
2485     default:
2486       return format (s, "unknown %d", next_index);
2487     }
2488   return s;
2489 }
2490
2491 static void
2492 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2493                                           mp)
2494 {
2495   vat_main_t *vam = &vat_main;
2496   u8 *iid_str;
2497   u8 *flag_str = NULL;
2498
2499   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2500
2501 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2502   foreach_lisp_gpe_flag_bit;
2503 #undef _
2504
2505   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2506            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2507            mp->tunnels,
2508            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2509            mp->source_ip,
2510            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2511            mp->destination_ip,
2512            ntohl (mp->encap_fib_id),
2513            ntohl (mp->decap_fib_id),
2514            format_decap_next, ntohl (mp->dcap_next),
2515            mp->ver_res >> 6,
2516            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2517
2518   vec_free (iid_str);
2519 }
2520
2521 static void
2522   vl_api_lisp_gpe_tunnel_details_t_handler_json
2523   (vl_api_lisp_gpe_tunnel_details_t * mp)
2524 {
2525   vat_main_t *vam = &vat_main;
2526   vat_json_node_t *node = NULL;
2527   struct in6_addr ip6;
2528   struct in_addr ip4;
2529   u8 *next_decap_str;
2530
2531   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2532
2533   if (VAT_JSON_ARRAY != vam->json_tree.type)
2534     {
2535       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2536       vat_json_init_array (&vam->json_tree);
2537     }
2538   node = vat_json_array_add (&vam->json_tree);
2539
2540   vat_json_init_object (node);
2541   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2542   if (mp->is_ipv6)
2543     {
2544       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2545       vat_json_object_add_ip6 (node, "source address", ip6);
2546       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2547       vat_json_object_add_ip6 (node, "destination address", ip6);
2548     }
2549   else
2550     {
2551       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2552       vat_json_object_add_ip4 (node, "source address", ip4);
2553       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2554       vat_json_object_add_ip4 (node, "destination address", ip4);
2555     }
2556   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2557   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2558   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2559   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2560   vat_json_object_add_uint (node, "flags", mp->flags);
2561   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2562   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2563   vat_json_object_add_uint (node, "res", mp->res);
2564   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2565
2566   vec_free (next_decap_str);
2567 }
2568
2569 static void
2570 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2571                                             * mp)
2572 {
2573   vat_main_t *vam = &vat_main;
2574
2575   fformat (vam->ofp, "%=20U\n",
2576            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2577            mp->ip_address);
2578 }
2579
2580 static void
2581   vl_api_lisp_map_resolver_details_t_handler_json
2582   (vl_api_lisp_map_resolver_details_t * mp)
2583 {
2584   vat_main_t *vam = &vat_main;
2585   vat_json_node_t *node = NULL;
2586   struct in6_addr ip6;
2587   struct in_addr ip4;
2588
2589   if (VAT_JSON_ARRAY != vam->json_tree.type)
2590     {
2591       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2592       vat_json_init_array (&vam->json_tree);
2593     }
2594   node = vat_json_array_add (&vam->json_tree);
2595
2596   vat_json_init_object (node);
2597   if (mp->is_ipv6)
2598     {
2599       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2600       vat_json_object_add_ip6 (node, "map resolver", ip6);
2601     }
2602   else
2603     {
2604       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2605       vat_json_object_add_ip4 (node, "map resolver", ip4);
2606     }
2607 }
2608
2609 static void
2610   vl_api_show_lisp_status_reply_t_handler
2611   (vl_api_show_lisp_status_reply_t * mp)
2612 {
2613   vat_main_t *vam = &vat_main;
2614   i32 retval = ntohl (mp->retval);
2615
2616   if (0 <= retval)
2617     {
2618       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2619                mp->feature_status ? "enabled" : "disabled",
2620                mp->gpe_status ? "enabled" : "disabled");
2621     }
2622
2623   vam->retval = retval;
2624   vam->result_ready = 1;
2625 }
2626
2627 static void
2628   vl_api_show_lisp_status_reply_t_handler_json
2629   (vl_api_show_lisp_status_reply_t * mp)
2630 {
2631   vat_main_t *vam = &vat_main;
2632   vat_json_node_t node;
2633   u8 *gpe_status = NULL;
2634   u8 *feature_status = NULL;
2635
2636   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2637   feature_status = format (0, "%s",
2638                            mp->feature_status ? "enabled" : "disabled");
2639   vec_add1 (gpe_status, 0);
2640   vec_add1 (feature_status, 0);
2641
2642   vat_json_init_object (&node);
2643   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2644   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2645
2646   vec_free (gpe_status);
2647   vec_free (feature_status);
2648
2649   vat_json_print (vam->ofp, &node);
2650   vat_json_free (&node);
2651
2652   vam->retval = ntohl (mp->retval);
2653   vam->result_ready = 1;
2654 }
2655
2656 static void
2657   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2658   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2659 {
2660   vat_main_t *vam = &vat_main;
2661   i32 retval = ntohl (mp->retval);
2662
2663   if (retval >= 0)
2664     {
2665       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2666     }
2667
2668   vam->retval = retval;
2669   vam->result_ready = 1;
2670 }
2671
2672 static void
2673   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2674   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2675 {
2676   vat_main_t *vam = &vat_main;
2677   vat_json_node_t *node = NULL;
2678
2679   if (VAT_JSON_ARRAY != vam->json_tree.type)
2680     {
2681       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2682       vat_json_init_array (&vam->json_tree);
2683     }
2684   node = vat_json_array_add (&vam->json_tree);
2685
2686   vat_json_init_object (node);
2687   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2688
2689   vat_json_print (vam->ofp, node);
2690   vat_json_free (node);
2691
2692   vam->retval = ntohl (mp->retval);
2693   vam->result_ready = 1;
2694 }
2695
2696 static void
2697 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2698 {
2699   vat_main_t *vam = &vat_main;
2700   i32 retval = ntohl (mp->retval);
2701
2702   if (0 <= retval)
2703     {
2704       fformat (vam->ofp, "%-20s%-16s\n",
2705                mp->status ? "enabled" : "disabled",
2706                mp->status ? (char *) mp->locator_set_name : "");
2707     }
2708
2709   vam->retval = retval;
2710   vam->result_ready = 1;
2711 }
2712
2713 static void
2714 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2715                                             mp)
2716 {
2717   vat_main_t *vam = &vat_main;
2718   vat_json_node_t node;
2719   u8 *status = 0;
2720
2721   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2722   vec_add1 (status, 0);
2723
2724   vat_json_init_object (&node);
2725   vat_json_object_add_string_copy (&node, "status", status);
2726   if (mp->status)
2727     {
2728       vat_json_object_add_string_copy (&node, "locator_set",
2729                                        mp->locator_set_name);
2730     }
2731
2732   vec_free (status);
2733
2734   vat_json_print (vam->ofp, &node);
2735   vat_json_free (&node);
2736
2737   vam->retval = ntohl (mp->retval);
2738   vam->result_ready = 1;
2739 }
2740
2741 static u8 *
2742 format_policer_type (u8 * s, va_list * va)
2743 {
2744   u32 i = va_arg (*va, u32);
2745
2746   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2747     s = format (s, "1r2c");
2748   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2749     s = format (s, "1r3c");
2750   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2751     s = format (s, "2r3c-2698");
2752   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2753     s = format (s, "2r3c-4115");
2754   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2755     s = format (s, "2r3c-mef5cf1");
2756   else
2757     s = format (s, "ILLEGAL");
2758   return s;
2759 }
2760
2761 static u8 *
2762 format_policer_rate_type (u8 * s, va_list * va)
2763 {
2764   u32 i = va_arg (*va, u32);
2765
2766   if (i == SSE2_QOS_RATE_KBPS)
2767     s = format (s, "kbps");
2768   else if (i == SSE2_QOS_RATE_PPS)
2769     s = format (s, "pps");
2770   else
2771     s = format (s, "ILLEGAL");
2772   return s;
2773 }
2774
2775 static u8 *
2776 format_policer_round_type (u8 * s, va_list * va)
2777 {
2778   u32 i = va_arg (*va, u32);
2779
2780   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2781     s = format (s, "closest");
2782   else if (i == SSE2_QOS_ROUND_TO_UP)
2783     s = format (s, "up");
2784   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2785     s = format (s, "down");
2786   else
2787     s = format (s, "ILLEGAL");
2788   return s;
2789 }
2790
2791 static u8 *
2792 format_policer_action_type (u8 * s, va_list * va)
2793 {
2794   u32 i = va_arg (*va, u32);
2795
2796   if (i == SSE2_QOS_ACTION_DROP)
2797     s = format (s, "drop");
2798   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2799     s = format (s, "transmit");
2800   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2801     s = format (s, "mark-and-transmit");
2802   else
2803     s = format (s, "ILLEGAL");
2804   return s;
2805 }
2806
2807 static u8 *
2808 format_dscp (u8 * s, va_list * va)
2809 {
2810   u32 i = va_arg (*va, u32);
2811   char *t = 0;
2812
2813   switch (i)
2814     {
2815 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2816       foreach_vnet_dscp
2817 #undef _
2818     default:
2819       return format (s, "ILLEGAL");
2820     }
2821   s = format (s, "%s", t);
2822   return s;
2823 }
2824
2825 static void
2826 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2827 {
2828   vat_main_t *vam = &vat_main;
2829   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2830
2831   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2832     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2833   else
2834     conform_dscp_str = format (0, "");
2835
2836   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2837     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2838   else
2839     exceed_dscp_str = format (0, "");
2840
2841   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2842     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2843   else
2844     violate_dscp_str = format (0, "");
2845
2846   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2847            "rate type %U, round type %U, %s rate, %s color-aware, "
2848            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2849            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2850            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2851            mp->name,
2852            format_policer_type, mp->type,
2853            ntohl (mp->cir),
2854            ntohl (mp->eir),
2855            clib_net_to_host_u64 (mp->cb),
2856            clib_net_to_host_u64 (mp->eb),
2857            format_policer_rate_type, mp->rate_type,
2858            format_policer_round_type, mp->round_type,
2859            mp->single_rate ? "single" : "dual",
2860            mp->color_aware ? "is" : "not",
2861            ntohl (mp->cir_tokens_per_period),
2862            ntohl (mp->pir_tokens_per_period),
2863            ntohl (mp->scale),
2864            ntohl (mp->current_limit),
2865            ntohl (mp->current_bucket),
2866            ntohl (mp->extended_limit),
2867            ntohl (mp->extended_bucket),
2868            clib_net_to_host_u64 (mp->last_update_time),
2869            format_policer_action_type, mp->conform_action_type,
2870            conform_dscp_str,
2871            format_policer_action_type, mp->exceed_action_type,
2872            exceed_dscp_str,
2873            format_policer_action_type, mp->violate_action_type,
2874            violate_dscp_str);
2875
2876   vec_free (conform_dscp_str);
2877   vec_free (exceed_dscp_str);
2878   vec_free (violate_dscp_str);
2879 }
2880
2881 static void vl_api_policer_details_t_handler_json
2882   (vl_api_policer_details_t * mp)
2883 {
2884   vat_main_t *vam = &vat_main;
2885   vat_json_node_t *node;
2886   u8 *rate_type_str, *round_type_str, *type_str;
2887   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2888
2889   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2890   round_type_str =
2891     format (0, "%U", format_policer_round_type, mp->round_type);
2892   type_str = format (0, "%U", format_policer_type, mp->type);
2893   conform_action_str = format (0, "%U", format_policer_action_type,
2894                                mp->conform_action_type);
2895   exceed_action_str = format (0, "%U", format_policer_action_type,
2896                               mp->exceed_action_type);
2897   violate_action_str = format (0, "%U", format_policer_action_type,
2898                                mp->violate_action_type);
2899
2900   if (VAT_JSON_ARRAY != vam->json_tree.type)
2901     {
2902       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2903       vat_json_init_array (&vam->json_tree);
2904     }
2905   node = vat_json_array_add (&vam->json_tree);
2906
2907   vat_json_init_object (node);
2908   vat_json_object_add_string_copy (node, "name", mp->name);
2909   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2910   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2911   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
2912   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
2913   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2914   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2915   vat_json_object_add_string_copy (node, "type", type_str);
2916   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2917   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2918   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2919   vat_json_object_add_uint (node, "cir_tokens_per_period",
2920                             ntohl (mp->cir_tokens_per_period));
2921   vat_json_object_add_uint (node, "eir_tokens_per_period",
2922                             ntohl (mp->pir_tokens_per_period));
2923   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2924   vat_json_object_add_uint (node, "current_bucket",
2925                             ntohl (mp->current_bucket));
2926   vat_json_object_add_uint (node, "extended_limit",
2927                             ntohl (mp->extended_limit));
2928   vat_json_object_add_uint (node, "extended_bucket",
2929                             ntohl (mp->extended_bucket));
2930   vat_json_object_add_uint (node, "last_update_time",
2931                             ntohl (mp->last_update_time));
2932   vat_json_object_add_string_copy (node, "conform_action",
2933                                    conform_action_str);
2934   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2935     {
2936       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2937       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2938       vec_free (dscp_str);
2939     }
2940   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2941   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2942     {
2943       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2944       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2945       vec_free (dscp_str);
2946     }
2947   vat_json_object_add_string_copy (node, "violate_action",
2948                                    violate_action_str);
2949   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2950     {
2951       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2952       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2953       vec_free (dscp_str);
2954     }
2955
2956   vec_free (rate_type_str);
2957   vec_free (round_type_str);
2958   vec_free (type_str);
2959   vec_free (conform_action_str);
2960   vec_free (exceed_action_str);
2961   vec_free (violate_action_str);
2962 }
2963
2964 static void
2965 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2966                                            mp)
2967 {
2968   vat_main_t *vam = &vat_main;
2969   int i, count = ntohl (mp->count);
2970
2971   if (count > 0)
2972     fformat (vam->ofp, "classify table ids (%d) : ", count);
2973   for (i = 0; i < count; i++)
2974     {
2975       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
2976       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
2977     }
2978   vam->retval = ntohl (mp->retval);
2979   vam->result_ready = 1;
2980 }
2981
2982 static void
2983   vl_api_classify_table_ids_reply_t_handler_json
2984   (vl_api_classify_table_ids_reply_t * mp)
2985 {
2986   vat_main_t *vam = &vat_main;
2987   int i, count = ntohl (mp->count);
2988
2989   if (count > 0)
2990     {
2991       vat_json_node_t node;
2992
2993       vat_json_init_object (&node);
2994       for (i = 0; i < count; i++)
2995         {
2996           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
2997         }
2998       vat_json_print (vam->ofp, &node);
2999       vat_json_free (&node);
3000     }
3001   vam->retval = ntohl (mp->retval);
3002   vam->result_ready = 1;
3003 }
3004
3005 static void
3006   vl_api_classify_table_by_interface_reply_t_handler
3007   (vl_api_classify_table_by_interface_reply_t * mp)
3008 {
3009   vat_main_t *vam = &vat_main;
3010   u32 table_id;
3011
3012   table_id = ntohl (mp->l2_table_id);
3013   if (table_id != ~0)
3014     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3015   else
3016     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3017   table_id = ntohl (mp->ip4_table_id);
3018   if (table_id != ~0)
3019     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3020   else
3021     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3022   table_id = ntohl (mp->ip6_table_id);
3023   if (table_id != ~0)
3024     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3025   else
3026     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3027   vam->retval = ntohl (mp->retval);
3028   vam->result_ready = 1;
3029 }
3030
3031 static void
3032   vl_api_classify_table_by_interface_reply_t_handler_json
3033   (vl_api_classify_table_by_interface_reply_t * mp)
3034 {
3035   vat_main_t *vam = &vat_main;
3036   vat_json_node_t node;
3037
3038   vat_json_init_object (&node);
3039
3040   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3041   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3042   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3043
3044   vat_json_print (vam->ofp, &node);
3045   vat_json_free (&node);
3046
3047   vam->retval = ntohl (mp->retval);
3048   vam->result_ready = 1;
3049 }
3050
3051 static void vl_api_policer_add_del_reply_t_handler
3052   (vl_api_policer_add_del_reply_t * mp)
3053 {
3054   vat_main_t *vam = &vat_main;
3055   i32 retval = ntohl (mp->retval);
3056   if (vam->async_mode)
3057     {
3058       vam->async_errors += (retval < 0);
3059     }
3060   else
3061     {
3062       vam->retval = retval;
3063       vam->result_ready = 1;
3064       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3065         /*
3066          * Note: this is just barely thread-safe, depends on
3067          * the main thread spinning waiting for an answer...
3068          */
3069         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3070     }
3071 }
3072
3073 static void vl_api_policer_add_del_reply_t_handler_json
3074   (vl_api_policer_add_del_reply_t * mp)
3075 {
3076   vat_main_t *vam = &vat_main;
3077   vat_json_node_t node;
3078
3079   vat_json_init_object (&node);
3080   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3081   vat_json_object_add_uint (&node, "policer_index",
3082                             ntohl (mp->policer_index));
3083
3084   vat_json_print (vam->ofp, &node);
3085   vat_json_free (&node);
3086
3087   vam->retval = ntohl (mp->retval);
3088   vam->result_ready = 1;
3089 }
3090
3091 /* Format hex dump. */
3092 u8 *
3093 format_hex_bytes (u8 * s, va_list * va)
3094 {
3095   u8 *bytes = va_arg (*va, u8 *);
3096   int n_bytes = va_arg (*va, int);
3097   uword i;
3098
3099   /* Print short or long form depending on byte count. */
3100   uword short_form = n_bytes <= 32;
3101   uword indent = format_get_indent (s);
3102
3103   if (n_bytes == 0)
3104     return s;
3105
3106   for (i = 0; i < n_bytes; i++)
3107     {
3108       if (!short_form && (i % 32) == 0)
3109         s = format (s, "%08x: ", i);
3110       s = format (s, "%02x", bytes[i]);
3111       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3112         s = format (s, "\n%U", format_white_space, indent);
3113     }
3114
3115   return s;
3116 }
3117
3118 static void
3119 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3120                                             * mp)
3121 {
3122   vat_main_t *vam = &vat_main;
3123   i32 retval = ntohl (mp->retval);
3124   if (retval == 0)
3125     {
3126       fformat (vam->ofp, "classify table info :\n");
3127       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3128                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3129                ntohl (mp->miss_next_index));
3130       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3131                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3132                ntohl (mp->match_n_vectors));
3133       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3134                ntohl (mp->mask_length));
3135     }
3136   vam->retval = retval;
3137   vam->result_ready = 1;
3138 }
3139
3140 static void
3141   vl_api_classify_table_info_reply_t_handler_json
3142   (vl_api_classify_table_info_reply_t * mp)
3143 {
3144   vat_main_t *vam = &vat_main;
3145   vat_json_node_t node;
3146
3147   i32 retval = ntohl (mp->retval);
3148   if (retval == 0)
3149     {
3150       vat_json_init_object (&node);
3151
3152       vat_json_object_add_int (&node, "sessions",
3153                                ntohl (mp->active_sessions));
3154       vat_json_object_add_int (&node, "nexttbl",
3155                                ntohl (mp->next_table_index));
3156       vat_json_object_add_int (&node, "nextnode",
3157                                ntohl (mp->miss_next_index));
3158       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3159       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3160       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3161       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3162                       ntohl (mp->mask_length), 0);
3163       vat_json_object_add_string_copy (&node, "mask", s);
3164
3165       vat_json_print (vam->ofp, &node);
3166       vat_json_free (&node);
3167     }
3168   vam->retval = ntohl (mp->retval);
3169   vam->result_ready = 1;
3170 }
3171
3172 static void
3173 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3174                                            mp)
3175 {
3176   vat_main_t *vam = &vat_main;
3177
3178   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3179            ntohl (mp->hit_next_index), ntohl (mp->advance),
3180            ntohl (mp->opaque_index));
3181   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3182            ntohl (mp->match_length));
3183 }
3184
3185 static void
3186   vl_api_classify_session_details_t_handler_json
3187   (vl_api_classify_session_details_t * mp)
3188 {
3189   vat_main_t *vam = &vat_main;
3190   vat_json_node_t *node = NULL;
3191
3192   if (VAT_JSON_ARRAY != vam->json_tree.type)
3193     {
3194       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3195       vat_json_init_array (&vam->json_tree);
3196     }
3197   node = vat_json_array_add (&vam->json_tree);
3198
3199   vat_json_init_object (node);
3200   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3201   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3202   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3203   u8 *s =
3204     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3205             0);
3206   vat_json_object_add_string_copy (node, "match", s);
3207 }
3208
3209 static void vl_api_pg_create_interface_reply_t_handler
3210   (vl_api_pg_create_interface_reply_t * mp)
3211 {
3212   vat_main_t *vam = &vat_main;
3213
3214   vam->retval = ntohl (mp->retval);
3215   vam->result_ready = 1;
3216 }
3217
3218 static void vl_api_pg_create_interface_reply_t_handler_json
3219   (vl_api_pg_create_interface_reply_t * mp)
3220 {
3221   vat_main_t *vam = &vat_main;
3222   vat_json_node_t node;
3223
3224   i32 retval = ntohl (mp->retval);
3225   if (retval == 0)
3226     {
3227       vat_json_init_object (&node);
3228
3229       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3230
3231       vat_json_print (vam->ofp, &node);
3232       vat_json_free (&node);
3233     }
3234   vam->retval = ntohl (mp->retval);
3235   vam->result_ready = 1;
3236 }
3237
3238 static void vl_api_policer_classify_details_t_handler
3239   (vl_api_policer_classify_details_t * mp)
3240 {
3241   vat_main_t *vam = &vat_main;
3242
3243   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3244            ntohl (mp->table_index));
3245 }
3246
3247 static void vl_api_policer_classify_details_t_handler_json
3248   (vl_api_policer_classify_details_t * mp)
3249 {
3250   vat_main_t *vam = &vat_main;
3251   vat_json_node_t *node;
3252
3253   if (VAT_JSON_ARRAY != vam->json_tree.type)
3254     {
3255       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3256       vat_json_init_array (&vam->json_tree);
3257     }
3258   node = vat_json_array_add (&vam->json_tree);
3259
3260   vat_json_init_object (node);
3261   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3262   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3263 }
3264
3265 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3266   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3267 {
3268   vat_main_t *vam = &vat_main;
3269   i32 retval = ntohl (mp->retval);
3270   if (vam->async_mode)
3271     {
3272       vam->async_errors += (retval < 0);
3273     }
3274   else
3275     {
3276       vam->retval = retval;
3277       vam->sw_if_index = ntohl (mp->sw_if_index);
3278       vam->result_ready = 1;
3279     }
3280 }
3281
3282 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3283   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3284 {
3285   vat_main_t *vam = &vat_main;
3286   vat_json_node_t node;
3287
3288   vat_json_init_object (&node);
3289   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3290   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3291
3292   vat_json_print (vam->ofp, &node);
3293   vat_json_free (&node);
3294
3295   vam->retval = ntohl (mp->retval);
3296   vam->result_ready = 1;
3297 }
3298
3299 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3300 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3301 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3302 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3303
3304 /*
3305  * Generate boilerplate reply handlers, which
3306  * dig the return value out of the xxx_reply_t API message,
3307  * stick it into vam->retval, and set vam->result_ready
3308  *
3309  * Could also do this by pointing N message decode slots at
3310  * a single function, but that could break in subtle ways.
3311  */
3312
3313 #define foreach_standard_reply_retval_handler           \
3314 _(sw_interface_set_flags_reply)                         \
3315 _(sw_interface_add_del_address_reply)                   \
3316 _(sw_interface_set_table_reply)                         \
3317 _(sw_interface_set_vpath_reply)                         \
3318 _(sw_interface_set_l2_bridge_reply)                     \
3319 _(bridge_domain_add_del_reply)                          \
3320 _(sw_interface_set_l2_xconnect_reply)                   \
3321 _(l2fib_add_del_reply)                                  \
3322 _(ip_add_del_route_reply)                               \
3323 _(proxy_arp_add_del_reply)                              \
3324 _(proxy_arp_intfc_enable_disable_reply)                 \
3325 _(mpls_add_del_encap_reply)                             \
3326 _(mpls_add_del_decap_reply)                             \
3327 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3328 _(sw_interface_set_unnumbered_reply)                    \
3329 _(ip_neighbor_add_del_reply)                            \
3330 _(reset_vrf_reply)                                      \
3331 _(oam_add_del_reply)                                    \
3332 _(reset_fib_reply)                                      \
3333 _(dhcp_proxy_config_reply)                              \
3334 _(dhcp_proxy_config_2_reply)                            \
3335 _(dhcp_proxy_set_vss_reply)                             \
3336 _(dhcp_client_config_reply)                             \
3337 _(set_ip_flow_hash_reply)                               \
3338 _(sw_interface_ip6_enable_disable_reply)                \
3339 _(sw_interface_ip6_set_link_local_address_reply)        \
3340 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3341 _(sw_interface_ip6nd_ra_config_reply)                   \
3342 _(set_arp_neighbor_limit_reply)                         \
3343 _(l2_patch_add_del_reply)                               \
3344 _(sr_tunnel_add_del_reply)                              \
3345 _(sr_policy_add_del_reply)                              \
3346 _(sr_multicast_map_add_del_reply)                       \
3347 _(classify_add_del_session_reply)                       \
3348 _(classify_set_interface_ip_table_reply)                \
3349 _(classify_set_interface_l2_tables_reply)               \
3350 _(l2tpv3_set_tunnel_cookies_reply)                      \
3351 _(l2tpv3_interface_enable_disable_reply)                \
3352 _(l2tpv3_set_lookup_key_reply)                          \
3353 _(l2_fib_clear_table_reply)                             \
3354 _(l2_interface_efp_filter_reply)                        \
3355 _(l2_interface_vlan_tag_rewrite_reply)                  \
3356 _(modify_vhost_user_if_reply)                           \
3357 _(delete_vhost_user_if_reply)                           \
3358 _(want_ip4_arp_events_reply)                            \
3359 _(want_ip6_nd_events_reply)                             \
3360 _(input_acl_set_interface_reply)                        \
3361 _(ipsec_spd_add_del_reply)                              \
3362 _(ipsec_interface_add_del_spd_reply)                    \
3363 _(ipsec_spd_add_del_entry_reply)                        \
3364 _(ipsec_sad_add_del_entry_reply)                        \
3365 _(ipsec_sa_set_key_reply)                               \
3366 _(ikev2_profile_add_del_reply)                          \
3367 _(ikev2_profile_set_auth_reply)                         \
3368 _(ikev2_profile_set_id_reply)                           \
3369 _(ikev2_profile_set_ts_reply)                           \
3370 _(ikev2_set_local_key_reply)                            \
3371 _(delete_loopback_reply)                                \
3372 _(bd_ip_mac_add_del_reply)                              \
3373 _(map_del_domain_reply)                                 \
3374 _(map_add_del_rule_reply)                               \
3375 _(want_interface_events_reply)                          \
3376 _(want_stats_reply)                                     \
3377 _(cop_interface_enable_disable_reply)                   \
3378 _(cop_whitelist_enable_disable_reply)                   \
3379 _(sw_interface_clear_stats_reply)                       \
3380 _(trace_profile_add_reply)                              \
3381 _(trace_profile_apply_reply)                            \
3382 _(trace_profile_del_reply)                              \
3383 _(lisp_add_del_locator_reply)                           \
3384 _(lisp_add_del_local_eid_reply)                         \
3385 _(lisp_add_del_remote_mapping_reply)                    \
3386 _(lisp_add_del_adjacency_reply)                         \
3387 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3388 _(lisp_add_del_map_resolver_reply)                      \
3389 _(lisp_gpe_enable_disable_reply)                        \
3390 _(lisp_gpe_add_del_iface_reply)                         \
3391 _(lisp_enable_disable_reply)                            \
3392 _(lisp_pitr_set_locator_set_reply)                      \
3393 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3394 _(lisp_eid_table_add_del_map_reply)                     \
3395 _(vxlan_gpe_add_del_tunnel_reply)                       \
3396 _(af_packet_delete_reply)                               \
3397 _(policer_classify_set_interface_reply)                 \
3398 _(netmap_create_reply)                                  \
3399 _(netmap_delete_reply)                                  \
3400 _(ipfix_enable_reply)                                   \
3401 _(pg_capture_reply)                                     \
3402 _(pg_enable_disable_reply)                              \
3403 _(ip_source_and_port_range_check_add_del_reply)         \
3404 _(ip_source_and_port_range_check_interface_add_del_reply)\
3405 _(delete_subif_reply)
3406
3407 #define _(n)                                    \
3408     static void vl_api_##n##_t_handler          \
3409     (vl_api_##n##_t * mp)                       \
3410     {                                           \
3411         vat_main_t * vam = &vat_main;           \
3412         i32 retval = ntohl(mp->retval);         \
3413         if (vam->async_mode) {                  \
3414             vam->async_errors += (retval < 0);  \
3415         } else {                                \
3416             vam->retval = retval;               \
3417             vam->result_ready = 1;              \
3418         }                                       \
3419     }
3420 foreach_standard_reply_retval_handler;
3421 #undef _
3422
3423 #define _(n)                                    \
3424     static void vl_api_##n##_t_handler_json     \
3425     (vl_api_##n##_t * mp)                       \
3426     {                                           \
3427         vat_main_t * vam = &vat_main;           \
3428         vat_json_node_t node;                   \
3429         vat_json_init_object(&node);            \
3430         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3431         vat_json_print(vam->ofp, &node);        \
3432         vam->retval = ntohl(mp->retval);        \
3433         vam->result_ready = 1;                  \
3434     }
3435 foreach_standard_reply_retval_handler;
3436 #undef _
3437
3438 /*
3439  * Table of message reply handlers, must include boilerplate handlers
3440  * we just generated
3441  */
3442
3443 #define foreach_vpe_api_reply_msg                                       \
3444 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3445 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3446 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3447 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3448 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3449 _(NOPRINT_CONTROL_PING_REPLY, noprint_control_ping_reply)               \
3450 _(CLI_REPLY, cli_reply)                                                 \
3451 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3452   sw_interface_add_del_address_reply)                                   \
3453 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3454 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3455 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3456   sw_interface_set_l2_xconnect_reply)                                   \
3457 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3458   sw_interface_set_l2_bridge_reply)                                     \
3459 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3460 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3461 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3462 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3463 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3464 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3465 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3466 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3467 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3468 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3469 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3470 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3471 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3472   proxy_arp_intfc_enable_disable_reply)                                 \
3473 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3474 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3475 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3476 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3477   mpls_ethernet_add_del_tunnel_reply)                                   \
3478 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3479   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3480 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3481   sw_interface_set_unnumbered_reply)                                    \
3482 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3483 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3484 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3485 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3486 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3487 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3488 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3489 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3490 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3491 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3492 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3493 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3494   sw_interface_ip6_enable_disable_reply)                                \
3495 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3496   sw_interface_ip6_set_link_local_address_reply)                        \
3497 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3498   sw_interface_ip6nd_ra_prefix_reply)                                   \
3499 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3500   sw_interface_ip6nd_ra_config_reply)                                   \
3501 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3502 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3503 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3504 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3505 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3506 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3507 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3508 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3509 classify_set_interface_ip_table_reply)                                  \
3510 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3511   classify_set_interface_l2_tables_reply)                               \
3512 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3513 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3514 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3515 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3516 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3517   l2tpv3_interface_enable_disable_reply)                                \
3518 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3519 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3520 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3521 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3522 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3523 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3524 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3525 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3526 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3527 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3528 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3529 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3530 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3531 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3532 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3533 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3534 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3535 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3536 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3537 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3538 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3539 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3540 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3541 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3542 _(IP_DETAILS, ip_details)                                               \
3543 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3544 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3545 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3546 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3547 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3548 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3549 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3550 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3551 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3552 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3553 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3554 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3555 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3556 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3557 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3558 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3559 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3560 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3561 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3562 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3563 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3564 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3565 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3566 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3567 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3568 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3569 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3570 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3571 _(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply)                   \
3572 _(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply)               \
3573 _(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply)                     \
3574 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3575 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3576 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3577 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3578 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3579 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3580 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3581 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3582 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3583 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3584 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3585 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3586 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3587 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3588 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3589 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3590 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3591 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3592 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3593 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3594 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3595   lisp_add_del_map_request_itr_rlocs_reply)                             \
3596 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3597   lisp_get_map_request_itr_rlocs_reply)                                 \
3598 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3599 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3600 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3601 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3602 _(POLICER_DETAILS, policer_details)                                     \
3603 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3604 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3605 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3606 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3607 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3608 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3609 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3610 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3611 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3612 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3613 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3614 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3615 _(IPFIX_ENABLE_REPLY, ipfix_enable_reply)                               \
3616 _(IPFIX_DETAILS, ipfix_details)                                         \
3617 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3618 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3619 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3620 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3621 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3622  ip_source_and_port_range_check_add_del_reply)                          \
3623 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3624  ip_source_and_port_range_check_interface_add_del_reply)                \
3625 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3626 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3627 _(DELETE_SUBIF_REPLY, delete_subif_reply)
3628
3629 /* M: construct, but don't yet send a message */
3630
3631 #define M(T,t)                                  \
3632 do {                                            \
3633     vam->result_ready = 0;                      \
3634     mp = vl_msg_api_alloc(sizeof(*mp));         \
3635     memset (mp, 0, sizeof (*mp));               \
3636     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3637     mp->client_index = vam->my_client_index;    \
3638 } while(0);
3639
3640 #define M2(T,t,n)                               \
3641 do {                                            \
3642     vam->result_ready = 0;                      \
3643     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3644     memset (mp, 0, sizeof (*mp));               \
3645     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3646     mp->client_index = vam->my_client_index;    \
3647 } while(0);
3648
3649
3650 /* S: send a message */
3651 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3652
3653 /* W: wait for results, with timeout */
3654 #define W                                       \
3655 do {                                            \
3656     timeout = vat_time_now (vam) + 1.0;         \
3657                                                 \
3658     while (vat_time_now (vam) < timeout) {      \
3659         if (vam->result_ready == 1) {           \
3660             return (vam->retval);               \
3661         }                                       \
3662     }                                           \
3663     return -99;                                 \
3664 } while(0);
3665
3666 /* W2: wait for results, with timeout */
3667 #define W2(body)                                \
3668 do {                                            \
3669     timeout = vat_time_now (vam) + 1.0;         \
3670                                                 \
3671     while (vat_time_now (vam) < timeout) {      \
3672         if (vam->result_ready == 1) {           \
3673           (body);                               \
3674           return (vam->retval);                 \
3675         }                                       \
3676     }                                           \
3677     return -99;                                 \
3678 } while(0);
3679
3680 /* W_L: wait for results, with timeout */
3681 #define W_L(body)                               \
3682 do {                                            \
3683     timeout = vat_time_now (vam) + 1.0;         \
3684                                                 \
3685     while (vat_time_now (vam) < timeout) {      \
3686         if (vam->result_ready == 1) {           \
3687           (body);                               \
3688           return (vam->retval);                 \
3689         }                                       \
3690     }                                           \
3691     vam->noprint_msg = 0;     \
3692     return -99;                                 \
3693 } while(0);
3694
3695 typedef struct
3696 {
3697   u8 *name;
3698   u32 value;
3699 } name_sort_t;
3700
3701
3702 #define STR_VTR_OP_CASE(op)     \
3703     case L2_VTR_ ## op:         \
3704         return "" # op;
3705
3706 static const char *
3707 str_vtr_op (u32 vtr_op)
3708 {
3709   switch (vtr_op)
3710     {
3711       STR_VTR_OP_CASE (DISABLED);
3712       STR_VTR_OP_CASE (PUSH_1);
3713       STR_VTR_OP_CASE (PUSH_2);
3714       STR_VTR_OP_CASE (POP_1);
3715       STR_VTR_OP_CASE (POP_2);
3716       STR_VTR_OP_CASE (TRANSLATE_1_1);
3717       STR_VTR_OP_CASE (TRANSLATE_1_2);
3718       STR_VTR_OP_CASE (TRANSLATE_2_1);
3719       STR_VTR_OP_CASE (TRANSLATE_2_2);
3720     }
3721
3722   return "UNKNOWN";
3723 }
3724
3725 static int
3726 dump_sub_interface_table (vat_main_t * vam)
3727 {
3728   const sw_interface_subif_t *sub = NULL;
3729
3730   if (vam->json_output)
3731     {
3732       clib_warning
3733         ("JSON output supported only for VPE API calls and dump_stats_table");
3734       return -99;
3735     }
3736
3737   fformat (vam->ofp,
3738            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3739            "Interface", "sw_if_index",
3740            "sub id", "dot1ad", "tags", "outer id",
3741            "inner id", "exact", "default", "outer any", "inner any");
3742
3743   vec_foreach (sub, vam->sw_if_subif_table)
3744   {
3745     fformat (vam->ofp,
3746              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3747              sub->interface_name,
3748              sub->sw_if_index,
3749              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3750              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3751              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3752              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3753     if (sub->vtr_op != L2_VTR_DISABLED)
3754       {
3755         fformat (vam->ofp,
3756                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3757                  "tag1: %d tag2: %d ]\n",
3758                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3759                  sub->vtr_tag1, sub->vtr_tag2);
3760       }
3761   }
3762
3763   return 0;
3764 }
3765
3766 static int
3767 name_sort_cmp (void *a1, void *a2)
3768 {
3769   name_sort_t *n1 = a1;
3770   name_sort_t *n2 = a2;
3771
3772   return strcmp ((char *) n1->name, (char *) n2->name);
3773 }
3774
3775 static int
3776 dump_interface_table (vat_main_t * vam)
3777 {
3778   hash_pair_t *p;
3779   name_sort_t *nses = 0, *ns;
3780
3781   if (vam->json_output)
3782     {
3783       clib_warning
3784         ("JSON output supported only for VPE API calls and dump_stats_table");
3785       return -99;
3786     }
3787
3788   /* *INDENT-OFF* */
3789   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3790   ({
3791     vec_add2 (nses, ns, 1);
3792     ns->name = (u8 *)(p->key);
3793     ns->value = (u32) p->value[0];
3794   }));
3795   /* *INDENT-ON* */
3796
3797   vec_sort_with_function (nses, name_sort_cmp);
3798
3799   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3800   vec_foreach (ns, nses)
3801   {
3802     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3803   }
3804   vec_free (nses);
3805   return 0;
3806 }
3807
3808 static int
3809 dump_ip_table (vat_main_t * vam, int is_ipv6)
3810 {
3811   const ip_details_t *det = NULL;
3812   const ip_address_details_t *address = NULL;
3813   u32 i = ~0;
3814
3815   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3816
3817   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3818   {
3819     i++;
3820     if (!det->present)
3821       {
3822         continue;
3823       }
3824     fformat (vam->ofp, "%-12d\n", i);
3825     fformat (vam->ofp,
3826              "            %-30s%-13s\n", "Address", "Prefix length");
3827     if (!det->addr)
3828       {
3829         continue;
3830       }
3831     vec_foreach (address, det->addr)
3832     {
3833       fformat (vam->ofp,
3834                "            %-30U%-13d\n",
3835                is_ipv6 ? format_ip6_address : format_ip4_address,
3836                address->ip, address->prefix_length);
3837     }
3838   }
3839
3840   return 0;
3841 }
3842
3843 static int
3844 dump_ipv4_table (vat_main_t * vam)
3845 {
3846   if (vam->json_output)
3847     {
3848       clib_warning
3849         ("JSON output supported only for VPE API calls and dump_stats_table");
3850       return -99;
3851     }
3852
3853   return dump_ip_table (vam, 0);
3854 }
3855
3856 static int
3857 dump_ipv6_table (vat_main_t * vam)
3858 {
3859   if (vam->json_output)
3860     {
3861       clib_warning
3862         ("JSON output supported only for VPE API calls and dump_stats_table");
3863       return -99;
3864     }
3865
3866   return dump_ip_table (vam, 1);
3867 }
3868
3869 static char *
3870 counter_type_to_str (u8 counter_type, u8 is_combined)
3871 {
3872   if (!is_combined)
3873     {
3874       switch (counter_type)
3875         {
3876         case VNET_INTERFACE_COUNTER_DROP:
3877           return "drop";
3878         case VNET_INTERFACE_COUNTER_PUNT:
3879           return "punt";
3880         case VNET_INTERFACE_COUNTER_IP4:
3881           return "ip4";
3882         case VNET_INTERFACE_COUNTER_IP6:
3883           return "ip6";
3884         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3885           return "rx-no-buf";
3886         case VNET_INTERFACE_COUNTER_RX_MISS:
3887           return "rx-miss";
3888         case VNET_INTERFACE_COUNTER_RX_ERROR:
3889           return "rx-error";
3890         case VNET_INTERFACE_COUNTER_TX_ERROR:
3891           return "tx-error";
3892         default:
3893           return "INVALID-COUNTER-TYPE";
3894         }
3895     }
3896   else
3897     {
3898       switch (counter_type)
3899         {
3900         case VNET_INTERFACE_COUNTER_RX:
3901           return "rx";
3902         case VNET_INTERFACE_COUNTER_TX:
3903           return "tx";
3904         default:
3905           return "INVALID-COUNTER-TYPE";
3906         }
3907     }
3908 }
3909
3910 static int
3911 dump_stats_table (vat_main_t * vam)
3912 {
3913   vat_json_node_t node;
3914   vat_json_node_t *msg_array;
3915   vat_json_node_t *msg;
3916   vat_json_node_t *counter_array;
3917   vat_json_node_t *counter;
3918   interface_counter_t c;
3919   u64 packets;
3920   ip4_fib_counter_t *c4;
3921   ip6_fib_counter_t *c6;
3922   int i, j;
3923
3924   if (!vam->json_output)
3925     {
3926       clib_warning ("dump_stats_table supported only in JSON format");
3927       return -99;
3928     }
3929
3930   vat_json_init_object (&node);
3931
3932   /* interface counters */
3933   msg_array = vat_json_object_add (&node, "interface_counters");
3934   vat_json_init_array (msg_array);
3935   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
3936     {
3937       msg = vat_json_array_add (msg_array);
3938       vat_json_init_object (msg);
3939       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3940                                        (u8 *) counter_type_to_str (i, 0));
3941       vat_json_object_add_int (msg, "is_combined", 0);
3942       counter_array = vat_json_object_add (msg, "data");
3943       vat_json_init_array (counter_array);
3944       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
3945         {
3946           packets = vam->simple_interface_counters[i][j];
3947           vat_json_array_add_uint (counter_array, packets);
3948         }
3949     }
3950   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
3951     {
3952       msg = vat_json_array_add (msg_array);
3953       vat_json_init_object (msg);
3954       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3955                                        (u8 *) counter_type_to_str (i, 1));
3956       vat_json_object_add_int (msg, "is_combined", 1);
3957       counter_array = vat_json_object_add (msg, "data");
3958       vat_json_init_array (counter_array);
3959       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
3960         {
3961           c = vam->combined_interface_counters[i][j];
3962           counter = vat_json_array_add (counter_array);
3963           vat_json_init_object (counter);
3964           vat_json_object_add_uint (counter, "packets", c.packets);
3965           vat_json_object_add_uint (counter, "bytes", c.bytes);
3966         }
3967     }
3968
3969   /* ip4 fib counters */
3970   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
3971   vat_json_init_array (msg_array);
3972   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
3973     {
3974       msg = vat_json_array_add (msg_array);
3975       vat_json_init_object (msg);
3976       vat_json_object_add_uint (msg, "vrf_id",
3977                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
3978       counter_array = vat_json_object_add (msg, "c");
3979       vat_json_init_array (counter_array);
3980       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
3981         {
3982           counter = vat_json_array_add (counter_array);
3983           vat_json_init_object (counter);
3984           c4 = &vam->ip4_fib_counters[i][j];
3985           vat_json_object_add_ip4 (counter, "address", c4->address);
3986           vat_json_object_add_uint (counter, "address_length",
3987                                     c4->address_length);
3988           vat_json_object_add_uint (counter, "packets", c4->packets);
3989           vat_json_object_add_uint (counter, "bytes", c4->bytes);
3990         }
3991     }
3992
3993   /* ip6 fib counters */
3994   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
3995   vat_json_init_array (msg_array);
3996   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
3997     {
3998       msg = vat_json_array_add (msg_array);
3999       vat_json_init_object (msg);
4000       vat_json_object_add_uint (msg, "vrf_id",
4001                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4002       counter_array = vat_json_object_add (msg, "c");
4003       vat_json_init_array (counter_array);
4004       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4005         {
4006           counter = vat_json_array_add (counter_array);
4007           vat_json_init_object (counter);
4008           c6 = &vam->ip6_fib_counters[i][j];
4009           vat_json_object_add_ip6 (counter, "address", c6->address);
4010           vat_json_object_add_uint (counter, "address_length",
4011                                     c6->address_length);
4012           vat_json_object_add_uint (counter, "packets", c6->packets);
4013           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4014         }
4015     }
4016
4017   vat_json_print (vam->ofp, &node);
4018   vat_json_free (&node);
4019
4020   return 0;
4021 }
4022
4023 int
4024 exec (vat_main_t * vam)
4025 {
4026   api_main_t *am = &api_main;
4027   vl_api_cli_request_t *mp;
4028   f64 timeout;
4029   void *oldheap;
4030   u8 *cmd = 0;
4031   unformat_input_t *i = vam->input;
4032
4033   if (vec_len (i->buffer) == 0)
4034     return -1;
4035
4036   if (vam->exec_mode == 0 && unformat (i, "mode"))
4037     {
4038       vam->exec_mode = 1;
4039       return 0;
4040     }
4041   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4042     {
4043       vam->exec_mode = 0;
4044       return 0;
4045     }
4046
4047
4048   M (CLI_REQUEST, cli_request);
4049
4050   /*
4051    * Copy cmd into shared memory.
4052    * In order for the CLI command to work, it
4053    * must be a vector ending in \n, not a C-string ending
4054    * in \n\0.
4055    */
4056   pthread_mutex_lock (&am->vlib_rp->mutex);
4057   oldheap = svm_push_data_heap (am->vlib_rp);
4058
4059   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4060   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4061
4062   svm_pop_heap (oldheap);
4063   pthread_mutex_unlock (&am->vlib_rp->mutex);
4064
4065   mp->cmd_in_shmem = (u64) cmd;
4066   S;
4067   timeout = vat_time_now (vam) + 10.0;
4068
4069   while (vat_time_now (vam) < timeout)
4070     {
4071       if (vam->result_ready == 1)
4072         {
4073           u8 *free_me;
4074           if (vam->shmem_result != NULL)
4075             fformat (vam->ofp, "%s", vam->shmem_result);
4076           pthread_mutex_lock (&am->vlib_rp->mutex);
4077           oldheap = svm_push_data_heap (am->vlib_rp);
4078
4079           free_me = (u8 *) vam->shmem_result;
4080           vec_free (free_me);
4081
4082           svm_pop_heap (oldheap);
4083           pthread_mutex_unlock (&am->vlib_rp->mutex);
4084           return 0;
4085         }
4086     }
4087   return -99;
4088 }
4089
4090 static int
4091 api_create_loopback (vat_main_t * vam)
4092 {
4093   unformat_input_t *i = vam->input;
4094   vl_api_create_loopback_t *mp;
4095   f64 timeout;
4096   u8 mac_address[6];
4097   u8 mac_set = 0;
4098
4099   memset (mac_address, 0, sizeof (mac_address));
4100
4101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4102     {
4103       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4104         mac_set = 1;
4105       else
4106         break;
4107     }
4108
4109   /* Construct the API message */
4110   M (CREATE_LOOPBACK, create_loopback);
4111   if (mac_set)
4112     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4113
4114   S;
4115   W;
4116 }
4117
4118 static int
4119 api_delete_loopback (vat_main_t * vam)
4120 {
4121   unformat_input_t *i = vam->input;
4122   vl_api_delete_loopback_t *mp;
4123   f64 timeout;
4124   u32 sw_if_index = ~0;
4125
4126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4127     {
4128       if (unformat (i, "sw_if_index %d", &sw_if_index))
4129         ;
4130       else
4131         break;
4132     }
4133
4134   if (sw_if_index == ~0)
4135     {
4136       errmsg ("missing sw_if_index\n");
4137       return -99;
4138     }
4139
4140   /* Construct the API message */
4141   M (DELETE_LOOPBACK, delete_loopback);
4142   mp->sw_if_index = ntohl (sw_if_index);
4143
4144   S;
4145   W;
4146 }
4147
4148 static int
4149 api_want_stats (vat_main_t * vam)
4150 {
4151   unformat_input_t *i = vam->input;
4152   vl_api_want_stats_t *mp;
4153   f64 timeout;
4154   int enable = -1;
4155
4156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4157     {
4158       if (unformat (i, "enable"))
4159         enable = 1;
4160       else if (unformat (i, "disable"))
4161         enable = 0;
4162       else
4163         break;
4164     }
4165
4166   if (enable == -1)
4167     {
4168       errmsg ("missing enable|disable\n");
4169       return -99;
4170     }
4171
4172   M (WANT_STATS, want_stats);
4173   mp->enable_disable = enable;
4174
4175   S;
4176   W;
4177 }
4178
4179 static int
4180 api_want_interface_events (vat_main_t * vam)
4181 {
4182   unformat_input_t *i = vam->input;
4183   vl_api_want_interface_events_t *mp;
4184   f64 timeout;
4185   int enable = -1;
4186
4187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4188     {
4189       if (unformat (i, "enable"))
4190         enable = 1;
4191       else if (unformat (i, "disable"))
4192         enable = 0;
4193       else
4194         break;
4195     }
4196
4197   if (enable == -1)
4198     {
4199       errmsg ("missing enable|disable\n");
4200       return -99;
4201     }
4202
4203   M (WANT_INTERFACE_EVENTS, want_interface_events);
4204   mp->enable_disable = enable;
4205
4206   vam->interface_event_display = enable;
4207
4208   S;
4209   W;
4210 }
4211
4212
4213 /* Note: non-static, called once to set up the initial intfc table */
4214 int
4215 api_sw_interface_dump (vat_main_t * vam)
4216 {
4217   vl_api_sw_interface_dump_t *mp;
4218   f64 timeout;
4219   hash_pair_t *p;
4220   name_sort_t *nses = 0, *ns;
4221   sw_interface_subif_t *sub = NULL;
4222
4223   /* Toss the old name table */
4224   /* *INDENT-OFF* */
4225   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4226   ({
4227     vec_add2 (nses, ns, 1);
4228     ns->name = (u8 *)(p->key);
4229     ns->value = (u32) p->value[0];
4230   }));
4231   /* *INDENT-ON* */
4232
4233   hash_free (vam->sw_if_index_by_interface_name);
4234
4235   vec_foreach (ns, nses) vec_free (ns->name);
4236
4237   vec_free (nses);
4238
4239   vec_foreach (sub, vam->sw_if_subif_table)
4240   {
4241     vec_free (sub->interface_name);
4242   }
4243   vec_free (vam->sw_if_subif_table);
4244
4245   /* recreate the interface name hash table */
4246   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4247
4248   /* Get list of ethernets */
4249   M (SW_INTERFACE_DUMP, sw_interface_dump);
4250   mp->name_filter_valid = 1;
4251   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4252   S;
4253
4254   /* and local / loopback interfaces */
4255   M (SW_INTERFACE_DUMP, sw_interface_dump);
4256   mp->name_filter_valid = 1;
4257   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4258   S;
4259
4260
4261   /* and vxlan-gpe tunnel interfaces */
4262   M (SW_INTERFACE_DUMP, sw_interface_dump);
4263   mp->name_filter_valid = 1;
4264   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4265            sizeof (mp->name_filter) - 1);
4266   S;
4267
4268   /* and vxlan tunnel interfaces */
4269   M (SW_INTERFACE_DUMP, sw_interface_dump);
4270   mp->name_filter_valid = 1;
4271   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4272   S;
4273
4274   /* and host (af_packet) interfaces */
4275   M (SW_INTERFACE_DUMP, sw_interface_dump);
4276   mp->name_filter_valid = 1;
4277   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4278   S;
4279
4280   /* and l2tpv3 tunnel interfaces */
4281   M (SW_INTERFACE_DUMP, sw_interface_dump);
4282   mp->name_filter_valid = 1;
4283   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4284            sizeof (mp->name_filter) - 1);
4285   S;
4286
4287   /* and GRE tunnel interfaces */
4288   M (SW_INTERFACE_DUMP, sw_interface_dump);
4289   mp->name_filter_valid = 1;
4290   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4291   S;
4292
4293   /* Use a control ping for synchronization */
4294   {
4295     vl_api_control_ping_t *mp;
4296     M (CONTROL_PING, control_ping);
4297     S;
4298   }
4299   W;
4300 }
4301
4302 static int
4303 api_sw_interface_set_flags (vat_main_t * vam)
4304 {
4305   unformat_input_t *i = vam->input;
4306   vl_api_sw_interface_set_flags_t *mp;
4307   f64 timeout;
4308   u32 sw_if_index;
4309   u8 sw_if_index_set = 0;
4310   u8 admin_up = 0, link_up = 0;
4311
4312   /* Parse args required to build the message */
4313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4314     {
4315       if (unformat (i, "admin-up"))
4316         admin_up = 1;
4317       else if (unformat (i, "admin-down"))
4318         admin_up = 0;
4319       else if (unformat (i, "link-up"))
4320         link_up = 1;
4321       else if (unformat (i, "link-down"))
4322         link_up = 0;
4323       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4324         sw_if_index_set = 1;
4325       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4326         sw_if_index_set = 1;
4327       else
4328         break;
4329     }
4330
4331   if (sw_if_index_set == 0)
4332     {
4333       errmsg ("missing interface name or sw_if_index\n");
4334       return -99;
4335     }
4336
4337   /* Construct the API message */
4338   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4339   mp->sw_if_index = ntohl (sw_if_index);
4340   mp->admin_up_down = admin_up;
4341   mp->link_up_down = link_up;
4342
4343   /* send it... */
4344   S;
4345
4346   /* Wait for a reply, return the good/bad news... */
4347   W;
4348 }
4349
4350 static int
4351 api_sw_interface_clear_stats (vat_main_t * vam)
4352 {
4353   unformat_input_t *i = vam->input;
4354   vl_api_sw_interface_clear_stats_t *mp;
4355   f64 timeout;
4356   u32 sw_if_index;
4357   u8 sw_if_index_set = 0;
4358
4359   /* Parse args required to build the message */
4360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4361     {
4362       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4363         sw_if_index_set = 1;
4364       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4365         sw_if_index_set = 1;
4366       else
4367         break;
4368     }
4369
4370   /* Construct the API message */
4371   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4372
4373   if (sw_if_index_set == 1)
4374     mp->sw_if_index = ntohl (sw_if_index);
4375   else
4376     mp->sw_if_index = ~0;
4377
4378   /* send it... */
4379   S;
4380
4381   /* Wait for a reply, return the good/bad news... */
4382   W;
4383 }
4384
4385 static int
4386 api_sw_interface_add_del_address (vat_main_t * vam)
4387 {
4388   unformat_input_t *i = vam->input;
4389   vl_api_sw_interface_add_del_address_t *mp;
4390   f64 timeout;
4391   u32 sw_if_index;
4392   u8 sw_if_index_set = 0;
4393   u8 is_add = 1, del_all = 0;
4394   u32 address_length = 0;
4395   u8 v4_address_set = 0;
4396   u8 v6_address_set = 0;
4397   ip4_address_t v4address;
4398   ip6_address_t v6address;
4399
4400   /* Parse args required to build the message */
4401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4402     {
4403       if (unformat (i, "del-all"))
4404         del_all = 1;
4405       else if (unformat (i, "del"))
4406         is_add = 0;
4407       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4408         sw_if_index_set = 1;
4409       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4410         sw_if_index_set = 1;
4411       else if (unformat (i, "%U/%d",
4412                          unformat_ip4_address, &v4address, &address_length))
4413         v4_address_set = 1;
4414       else if (unformat (i, "%U/%d",
4415                          unformat_ip6_address, &v6address, &address_length))
4416         v6_address_set = 1;
4417       else
4418         break;
4419     }
4420
4421   if (sw_if_index_set == 0)
4422     {
4423       errmsg ("missing interface name or sw_if_index\n");
4424       return -99;
4425     }
4426   if (v4_address_set && v6_address_set)
4427     {
4428       errmsg ("both v4 and v6 addresses set\n");
4429       return -99;
4430     }
4431   if (!v4_address_set && !v6_address_set && !del_all)
4432     {
4433       errmsg ("no addresses set\n");
4434       return -99;
4435     }
4436
4437   /* Construct the API message */
4438   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4439
4440   mp->sw_if_index = ntohl (sw_if_index);
4441   mp->is_add = is_add;
4442   mp->del_all = del_all;
4443   if (v6_address_set)
4444     {
4445       mp->is_ipv6 = 1;
4446       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4447     }
4448   else
4449     {
4450       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4451     }
4452   mp->address_length = address_length;
4453
4454   /* send it... */
4455   S;
4456
4457   /* Wait for a reply, return good/bad news  */
4458   W;
4459 }
4460
4461 static int
4462 api_sw_interface_set_table (vat_main_t * vam)
4463 {
4464   unformat_input_t *i = vam->input;
4465   vl_api_sw_interface_set_table_t *mp;
4466   f64 timeout;
4467   u32 sw_if_index, vrf_id = 0;
4468   u8 sw_if_index_set = 0;
4469   u8 is_ipv6 = 0;
4470
4471   /* Parse args required to build the message */
4472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4473     {
4474       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4475         sw_if_index_set = 1;
4476       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4477         sw_if_index_set = 1;
4478       else if (unformat (i, "vrf %d", &vrf_id))
4479         ;
4480       else if (unformat (i, "ipv6"))
4481         is_ipv6 = 1;
4482       else
4483         break;
4484     }
4485
4486   if (sw_if_index_set == 0)
4487     {
4488       errmsg ("missing interface name or sw_if_index\n");
4489       return -99;
4490     }
4491
4492   /* Construct the API message */
4493   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4494
4495   mp->sw_if_index = ntohl (sw_if_index);
4496   mp->is_ipv6 = is_ipv6;
4497   mp->vrf_id = ntohl (vrf_id);
4498
4499   /* send it... */
4500   S;
4501
4502   /* Wait for a reply... */
4503   W;
4504 }
4505
4506 static int
4507 api_sw_interface_set_vpath (vat_main_t * vam)
4508 {
4509   unformat_input_t *i = vam->input;
4510   vl_api_sw_interface_set_vpath_t *mp;
4511   f64 timeout;
4512   u32 sw_if_index = 0;
4513   u8 sw_if_index_set = 0;
4514   u8 is_enable = 0;
4515
4516   /* Parse args required to build the message */
4517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4518     {
4519       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4520         sw_if_index_set = 1;
4521       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4522         sw_if_index_set = 1;
4523       else if (unformat (i, "enable"))
4524         is_enable = 1;
4525       else if (unformat (i, "disable"))
4526         is_enable = 0;
4527       else
4528         break;
4529     }
4530
4531   if (sw_if_index_set == 0)
4532     {
4533       errmsg ("missing interface name or sw_if_index\n");
4534       return -99;
4535     }
4536
4537   /* Construct the API message */
4538   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4539
4540   mp->sw_if_index = ntohl (sw_if_index);
4541   mp->enable = is_enable;
4542
4543   /* send it... */
4544   S;
4545
4546   /* Wait for a reply... */
4547   W;
4548 }
4549
4550 static int
4551 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4552 {
4553   unformat_input_t *i = vam->input;
4554   vl_api_sw_interface_set_l2_xconnect_t *mp;
4555   f64 timeout;
4556   u32 rx_sw_if_index;
4557   u8 rx_sw_if_index_set = 0;
4558   u32 tx_sw_if_index;
4559   u8 tx_sw_if_index_set = 0;
4560   u8 enable = 1;
4561
4562   /* Parse args required to build the message */
4563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4564     {
4565       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4566         rx_sw_if_index_set = 1;
4567       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4568         tx_sw_if_index_set = 1;
4569       else if (unformat (i, "rx"))
4570         {
4571           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4572             {
4573               if (unformat (i, "%U", unformat_sw_if_index, vam,
4574                             &rx_sw_if_index))
4575                 rx_sw_if_index_set = 1;
4576             }
4577           else
4578             break;
4579         }
4580       else if (unformat (i, "tx"))
4581         {
4582           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4583             {
4584               if (unformat (i, "%U", unformat_sw_if_index, vam,
4585                             &tx_sw_if_index))
4586                 tx_sw_if_index_set = 1;
4587             }
4588           else
4589             break;
4590         }
4591       else if (unformat (i, "enable"))
4592         enable = 1;
4593       else if (unformat (i, "disable"))
4594         enable = 0;
4595       else
4596         break;
4597     }
4598
4599   if (rx_sw_if_index_set == 0)
4600     {
4601       errmsg ("missing rx interface name or rx_sw_if_index\n");
4602       return -99;
4603     }
4604
4605   if (enable && (tx_sw_if_index_set == 0))
4606     {
4607       errmsg ("missing tx interface name or tx_sw_if_index\n");
4608       return -99;
4609     }
4610
4611   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4612
4613   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4614   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4615   mp->enable = enable;
4616
4617   S;
4618   W;
4619   /* NOTREACHED */
4620   return 0;
4621 }
4622
4623 static int
4624 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4625 {
4626   unformat_input_t *i = vam->input;
4627   vl_api_sw_interface_set_l2_bridge_t *mp;
4628   f64 timeout;
4629   u32 rx_sw_if_index;
4630   u8 rx_sw_if_index_set = 0;
4631   u32 bd_id;
4632   u8 bd_id_set = 0;
4633   u8 bvi = 0;
4634   u32 shg = 0;
4635   u8 enable = 1;
4636
4637   /* Parse args required to build the message */
4638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4639     {
4640       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4641         rx_sw_if_index_set = 1;
4642       else if (unformat (i, "bd_id %d", &bd_id))
4643         bd_id_set = 1;
4644       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
4645         rx_sw_if_index_set = 1;
4646       else if (unformat (i, "shg %d", &shg))
4647         ;
4648       else if (unformat (i, "bvi"))
4649         bvi = 1;
4650       else if (unformat (i, "enable"))
4651         enable = 1;
4652       else if (unformat (i, "disable"))
4653         enable = 0;
4654       else
4655         break;
4656     }
4657
4658   if (rx_sw_if_index_set == 0)
4659     {
4660       errmsg ("missing rx interface name or sw_if_index\n");
4661       return -99;
4662     }
4663
4664   if (enable && (bd_id_set == 0))
4665     {
4666       errmsg ("missing bridge domain\n");
4667       return -99;
4668     }
4669
4670   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4671
4672   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4673   mp->bd_id = ntohl (bd_id);
4674   mp->shg = (u8) shg;
4675   mp->bvi = bvi;
4676   mp->enable = enable;
4677
4678   S;
4679   W;
4680   /* NOTREACHED */
4681   return 0;
4682 }
4683
4684 static int
4685 api_bridge_domain_dump (vat_main_t * vam)
4686 {
4687   unformat_input_t *i = vam->input;
4688   vl_api_bridge_domain_dump_t *mp;
4689   f64 timeout;
4690   u32 bd_id = ~0;
4691
4692   /* Parse args required to build the message */
4693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4694     {
4695       if (unformat (i, "bd_id %d", &bd_id))
4696         ;
4697       else
4698         break;
4699     }
4700
4701   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4702   mp->bd_id = ntohl (bd_id);
4703   S;
4704
4705   /* Use a control ping for synchronization */
4706   {
4707     vl_api_control_ping_t *mp;
4708     M (CONTROL_PING, control_ping);
4709     S;
4710   }
4711
4712   W;
4713   /* NOTREACHED */
4714   return 0;
4715 }
4716
4717 static int
4718 api_bridge_domain_add_del (vat_main_t * vam)
4719 {
4720   unformat_input_t *i = vam->input;
4721   vl_api_bridge_domain_add_del_t *mp;
4722   f64 timeout;
4723   u32 bd_id = ~0;
4724   u8 is_add = 1;
4725   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4726
4727   /* Parse args required to build the message */
4728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4729     {
4730       if (unformat (i, "bd_id %d", &bd_id))
4731         ;
4732       else if (unformat (i, "flood %d", &flood))
4733         ;
4734       else if (unformat (i, "uu-flood %d", &uu_flood))
4735         ;
4736       else if (unformat (i, "forward %d", &forward))
4737         ;
4738       else if (unformat (i, "learn %d", &learn))
4739         ;
4740       else if (unformat (i, "arp-term %d", &arp_term))
4741         ;
4742       else if (unformat (i, "del"))
4743         {
4744           is_add = 0;
4745           flood = uu_flood = forward = learn = 0;
4746         }
4747       else
4748         break;
4749     }
4750
4751   if (bd_id == ~0)
4752     {
4753       errmsg ("missing bridge domain\n");
4754       return -99;
4755     }
4756
4757   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4758
4759   mp->bd_id = ntohl (bd_id);
4760   mp->flood = flood;
4761   mp->uu_flood = uu_flood;
4762   mp->forward = forward;
4763   mp->learn = learn;
4764   mp->arp_term = arp_term;
4765   mp->is_add = is_add;
4766
4767   S;
4768   W;
4769   /* NOTREACHED */
4770   return 0;
4771 }
4772
4773 static int
4774 api_l2fib_add_del (vat_main_t * vam)
4775 {
4776   unformat_input_t *i = vam->input;
4777   vl_api_l2fib_add_del_t *mp;
4778   f64 timeout;
4779   u64 mac = 0;
4780   u8 mac_set = 0;
4781   u32 bd_id;
4782   u8 bd_id_set = 0;
4783   u32 sw_if_index;
4784   u8 sw_if_index_set = 0;
4785   u8 is_add = 1;
4786   u8 static_mac = 0;
4787   u8 filter_mac = 0;
4788   u8 bvi_mac = 0;
4789   int count = 1;
4790   f64 before = 0;
4791   int j;
4792
4793   /* Parse args required to build the message */
4794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4795     {
4796       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4797         mac_set = 1;
4798       else if (unformat (i, "bd_id %d", &bd_id))
4799         bd_id_set = 1;
4800       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4801         sw_if_index_set = 1;
4802       else if (unformat (i, "sw_if"))
4803         {
4804           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4805             {
4806               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4807                 sw_if_index_set = 1;
4808             }
4809           else
4810             break;
4811         }
4812       else if (unformat (i, "static"))
4813         static_mac = 1;
4814       else if (unformat (i, "filter"))
4815         {
4816           filter_mac = 1;
4817           static_mac = 1;
4818         }
4819       else if (unformat (i, "bvi"))
4820         {
4821           bvi_mac = 1;
4822           static_mac = 1;
4823         }
4824       else if (unformat (i, "del"))
4825         is_add = 0;
4826       else if (unformat (i, "count %d", &count))
4827         ;
4828       else
4829         break;
4830     }
4831
4832   if (mac_set == 0)
4833     {
4834       errmsg ("missing mac address\n");
4835       return -99;
4836     }
4837
4838   if (bd_id_set == 0)
4839     {
4840       errmsg ("missing bridge domain\n");
4841       return -99;
4842     }
4843
4844   if (is_add && (sw_if_index_set == 0))
4845     {
4846       errmsg ("missing interface name or sw_if_index\n");
4847       return -99;
4848     }
4849
4850   if (count > 1)
4851     {
4852       /* Turn on async mode */
4853       vam->async_mode = 1;
4854       vam->async_errors = 0;
4855       before = vat_time_now (vam);
4856     }
4857
4858   for (j = 0; j < count; j++)
4859     {
4860       M (L2FIB_ADD_DEL, l2fib_add_del);
4861
4862       mp->mac = mac;
4863       mp->bd_id = ntohl (bd_id);
4864       mp->is_add = is_add;
4865
4866       if (is_add)
4867         {
4868           mp->sw_if_index = ntohl (sw_if_index);
4869           mp->static_mac = static_mac;
4870           mp->filter_mac = filter_mac;
4871           mp->bvi_mac = bvi_mac;
4872         }
4873       increment_mac_address (&mac);
4874       /* send it... */
4875       S;
4876     }
4877
4878   if (count > 1)
4879     {
4880       vl_api_control_ping_t *mp;
4881       f64 after;
4882
4883       /* Shut off async mode */
4884       vam->async_mode = 0;
4885
4886       M (CONTROL_PING, control_ping);
4887       S;
4888
4889       timeout = vat_time_now (vam) + 1.0;
4890       while (vat_time_now (vam) < timeout)
4891         if (vam->result_ready == 1)
4892           goto out;
4893       vam->retval = -99;
4894
4895     out:
4896       if (vam->retval == -99)
4897         errmsg ("timeout\n");
4898
4899       if (vam->async_errors > 0)
4900         {
4901           errmsg ("%d asynchronous errors\n", vam->async_errors);
4902           vam->retval = -98;
4903         }
4904       vam->async_errors = 0;
4905       after = vat_time_now (vam);
4906
4907       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4908                count, after - before, count / (after - before));
4909     }
4910   else
4911     {
4912       /* Wait for a reply... */
4913       W;
4914     }
4915   /* Return the good/bad news */
4916   return (vam->retval);
4917 }
4918
4919 static int
4920 api_l2_flags (vat_main_t * vam)
4921 {
4922   unformat_input_t *i = vam->input;
4923   vl_api_l2_flags_t *mp;
4924   f64 timeout;
4925   u32 sw_if_index;
4926   u32 feature_bitmap = 0;
4927   u8 sw_if_index_set = 0;
4928
4929   /* Parse args required to build the message */
4930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4931     {
4932       if (unformat (i, "sw_if_index %d", &sw_if_index))
4933         sw_if_index_set = 1;
4934       else if (unformat (i, "sw_if"))
4935         {
4936           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4937             {
4938               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4939                 sw_if_index_set = 1;
4940             }
4941           else
4942             break;
4943         }
4944       else if (unformat (i, "learn"))
4945         feature_bitmap |= L2INPUT_FEAT_LEARN;
4946       else if (unformat (i, "forward"))
4947         feature_bitmap |= L2INPUT_FEAT_FWD;
4948       else if (unformat (i, "flood"))
4949         feature_bitmap |= L2INPUT_FEAT_FLOOD;
4950       else if (unformat (i, "uu-flood"))
4951         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
4952       else
4953         break;
4954     }
4955
4956   if (sw_if_index_set == 0)
4957     {
4958       errmsg ("missing interface name or sw_if_index\n");
4959       return -99;
4960     }
4961
4962   M (L2_FLAGS, l2_flags);
4963
4964   mp->sw_if_index = ntohl (sw_if_index);
4965   mp->feature_bitmap = ntohl (feature_bitmap);
4966
4967   S;
4968   W;
4969   /* NOTREACHED */
4970   return 0;
4971 }
4972
4973 static int
4974 api_bridge_flags (vat_main_t * vam)
4975 {
4976   unformat_input_t *i = vam->input;
4977   vl_api_bridge_flags_t *mp;
4978   f64 timeout;
4979   u32 bd_id;
4980   u8 bd_id_set = 0;
4981   u8 is_set = 1;
4982   u32 flags = 0;
4983
4984   /* Parse args required to build the message */
4985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4986     {
4987       if (unformat (i, "bd_id %d", &bd_id))
4988         bd_id_set = 1;
4989       else if (unformat (i, "learn"))
4990         flags |= L2_LEARN;
4991       else if (unformat (i, "forward"))
4992         flags |= L2_FWD;
4993       else if (unformat (i, "flood"))
4994         flags |= L2_FLOOD;
4995       else if (unformat (i, "uu-flood"))
4996         flags |= L2_UU_FLOOD;
4997       else if (unformat (i, "arp-term"))
4998         flags |= L2_ARP_TERM;
4999       else if (unformat (i, "off"))
5000         is_set = 0;
5001       else if (unformat (i, "disable"))
5002         is_set = 0;
5003       else
5004         break;
5005     }
5006
5007   if (bd_id_set == 0)
5008     {
5009       errmsg ("missing bridge domain\n");
5010       return -99;
5011     }
5012
5013   M (BRIDGE_FLAGS, bridge_flags);
5014
5015   mp->bd_id = ntohl (bd_id);
5016   mp->feature_bitmap = ntohl (flags);
5017   mp->is_set = is_set;
5018
5019   S;
5020   W;
5021   /* NOTREACHED */
5022   return 0;
5023 }
5024
5025 static int
5026 api_bd_ip_mac_add_del (vat_main_t * vam)
5027 {
5028   unformat_input_t *i = vam->input;
5029   vl_api_bd_ip_mac_add_del_t *mp;
5030   f64 timeout;
5031   u32 bd_id;
5032   u8 is_ipv6 = 0;
5033   u8 is_add = 1;
5034   u8 bd_id_set = 0;
5035   u8 ip_set = 0;
5036   u8 mac_set = 0;
5037   ip4_address_t v4addr;
5038   ip6_address_t v6addr;
5039   u8 macaddr[6];
5040
5041
5042   /* Parse args required to build the message */
5043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5044     {
5045       if (unformat (i, "bd_id %d", &bd_id))
5046         {
5047           bd_id_set++;
5048         }
5049       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5050         {
5051           ip_set++;
5052         }
5053       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5054         {
5055           ip_set++;
5056           is_ipv6++;
5057         }
5058       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5059         {
5060           mac_set++;
5061         }
5062       else if (unformat (i, "del"))
5063         is_add = 0;
5064       else
5065         break;
5066     }
5067
5068   if (bd_id_set == 0)
5069     {
5070       errmsg ("missing bridge domain\n");
5071       return -99;
5072     }
5073   else if (ip_set == 0)
5074     {
5075       errmsg ("missing IP address\n");
5076       return -99;
5077     }
5078   else if (mac_set == 0)
5079     {
5080       errmsg ("missing MAC address\n");
5081       return -99;
5082     }
5083
5084   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5085
5086   mp->bd_id = ntohl (bd_id);
5087   mp->is_ipv6 = is_ipv6;
5088   mp->is_add = is_add;
5089   if (is_ipv6)
5090     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5091   else
5092     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5093   clib_memcpy (mp->mac_address, macaddr, 6);
5094   S;
5095   W;
5096   /* NOTREACHED */
5097   return 0;
5098 }
5099
5100 static int
5101 api_tap_connect (vat_main_t * vam)
5102 {
5103   unformat_input_t *i = vam->input;
5104   vl_api_tap_connect_t *mp;
5105   f64 timeout;
5106   u8 mac_address[6];
5107   u8 random_mac = 1;
5108   u8 name_set = 0;
5109   u8 *tap_name;
5110
5111   memset (mac_address, 0, sizeof (mac_address));
5112
5113   /* Parse args required to build the message */
5114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5115     {
5116       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5117         {
5118           random_mac = 0;
5119         }
5120       else if (unformat (i, "random-mac"))
5121         random_mac = 1;
5122       else if (unformat (i, "tapname %s", &tap_name))
5123         name_set = 1;
5124       else
5125         break;
5126     }
5127
5128   if (name_set == 0)
5129     {
5130       errmsg ("missing tap name\n");
5131       return -99;
5132     }
5133   if (vec_len (tap_name) > 63)
5134     {
5135       errmsg ("tap name too long\n");
5136     }
5137   vec_add1 (tap_name, 0);
5138
5139   /* Construct the API message */
5140   M (TAP_CONNECT, tap_connect);
5141
5142   mp->use_random_mac = random_mac;
5143   clib_memcpy (mp->mac_address, mac_address, 6);
5144   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5145   vec_free (tap_name);
5146
5147   /* send it... */
5148   S;
5149
5150   /* Wait for a reply... */
5151   W;
5152 }
5153
5154 static int
5155 api_tap_modify (vat_main_t * vam)
5156 {
5157   unformat_input_t *i = vam->input;
5158   vl_api_tap_modify_t *mp;
5159   f64 timeout;
5160   u8 mac_address[6];
5161   u8 random_mac = 1;
5162   u8 name_set = 0;
5163   u8 *tap_name;
5164   u32 sw_if_index = ~0;
5165   u8 sw_if_index_set = 0;
5166
5167   memset (mac_address, 0, sizeof (mac_address));
5168
5169   /* Parse args required to build the message */
5170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5171     {
5172       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5173         sw_if_index_set = 1;
5174       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5175         sw_if_index_set = 1;
5176       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5177         {
5178           random_mac = 0;
5179         }
5180       else if (unformat (i, "random-mac"))
5181         random_mac = 1;
5182       else if (unformat (i, "tapname %s", &tap_name))
5183         name_set = 1;
5184       else
5185         break;
5186     }
5187
5188   if (sw_if_index_set == 0)
5189     {
5190       errmsg ("missing vpp interface name");
5191       return -99;
5192     }
5193   if (name_set == 0)
5194     {
5195       errmsg ("missing tap name\n");
5196       return -99;
5197     }
5198   if (vec_len (tap_name) > 63)
5199     {
5200       errmsg ("tap name too long\n");
5201     }
5202   vec_add1 (tap_name, 0);
5203
5204   /* Construct the API message */
5205   M (TAP_MODIFY, tap_modify);
5206
5207   mp->use_random_mac = random_mac;
5208   mp->sw_if_index = ntohl (sw_if_index);
5209   clib_memcpy (mp->mac_address, mac_address, 6);
5210   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5211   vec_free (tap_name);
5212
5213   /* send it... */
5214   S;
5215
5216   /* Wait for a reply... */
5217   W;
5218 }
5219
5220 static int
5221 api_tap_delete (vat_main_t * vam)
5222 {
5223   unformat_input_t *i = vam->input;
5224   vl_api_tap_delete_t *mp;
5225   f64 timeout;
5226   u32 sw_if_index = ~0;
5227   u8 sw_if_index_set = 0;
5228
5229   /* Parse args required to build the message */
5230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5231     {
5232       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5233         sw_if_index_set = 1;
5234       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5235         sw_if_index_set = 1;
5236       else
5237         break;
5238     }
5239
5240   if (sw_if_index_set == 0)
5241     {
5242       errmsg ("missing vpp interface name");
5243       return -99;
5244     }
5245
5246   /* Construct the API message */
5247   M (TAP_DELETE, tap_delete);
5248
5249   mp->sw_if_index = ntohl (sw_if_index);
5250
5251   /* send it... */
5252   S;
5253
5254   /* Wait for a reply... */
5255   W;
5256 }
5257
5258 static int
5259 api_ip_add_del_route (vat_main_t * vam)
5260 {
5261   unformat_input_t *i = vam->input;
5262   vl_api_ip_add_del_route_t *mp;
5263   f64 timeout;
5264   u32 sw_if_index = ~0, vrf_id = 0;
5265   u8 sw_if_index_set = 0;
5266   u8 is_ipv6 = 0;
5267   u8 is_local = 0, is_drop = 0;
5268   u8 create_vrf_if_needed = 0;
5269   u8 is_add = 1;
5270   u8 next_hop_weight = 1;
5271   u8 not_last = 0;
5272   u8 is_multipath = 0;
5273   u8 address_set = 0;
5274   u8 address_length_set = 0;
5275   u32 lookup_in_vrf = 0;
5276   u32 resolve_attempts = 0;
5277   u32 dst_address_length = 0;
5278   u8 next_hop_set = 0;
5279   ip4_address_t v4_dst_address, v4_next_hop_address;
5280   ip6_address_t v6_dst_address, v6_next_hop_address;
5281   int count = 1;
5282   int j;
5283   f64 before = 0;
5284   u32 random_add_del = 0;
5285   u32 *random_vector = 0;
5286   uword *random_hash;
5287   u32 random_seed = 0xdeaddabe;
5288   u32 classify_table_index = ~0;
5289   u8 is_classify = 0;
5290
5291   /* Parse args required to build the message */
5292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5293     {
5294       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5295         sw_if_index_set = 1;
5296       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5297         sw_if_index_set = 1;
5298       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5299         {
5300           address_set = 1;
5301           is_ipv6 = 0;
5302         }
5303       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5304         {
5305           address_set = 1;
5306           is_ipv6 = 1;
5307         }
5308       else if (unformat (i, "/%d", &dst_address_length))
5309         {
5310           address_length_set = 1;
5311         }
5312
5313       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5314                                          &v4_next_hop_address))
5315         {
5316           next_hop_set = 1;
5317         }
5318       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5319                                          &v6_next_hop_address))
5320         {
5321           next_hop_set = 1;
5322         }
5323       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5324         ;
5325       else if (unformat (i, "weight %d", &next_hop_weight))
5326         ;
5327       else if (unformat (i, "drop"))
5328         {
5329           is_drop = 1;
5330         }
5331       else if (unformat (i, "local"))
5332         {
5333           is_local = 1;
5334         }
5335       else if (unformat (i, "classify %d", &classify_table_index))
5336         {
5337           is_classify = 1;
5338         }
5339       else if (unformat (i, "del"))
5340         is_add = 0;
5341       else if (unformat (i, "add"))
5342         is_add = 1;
5343       else if (unformat (i, "not-last"))
5344         not_last = 1;
5345       else if (unformat (i, "multipath"))
5346         is_multipath = 1;
5347       else if (unformat (i, "vrf %d", &vrf_id))
5348         ;
5349       else if (unformat (i, "create-vrf"))
5350         create_vrf_if_needed = 1;
5351       else if (unformat (i, "count %d", &count))
5352         ;
5353       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5354         ;
5355       else if (unformat (i, "random"))
5356         random_add_del = 1;
5357       else if (unformat (i, "seed %d", &random_seed))
5358         ;
5359       else
5360         {
5361           clib_warning ("parse error '%U'", format_unformat_error, i);
5362           return -99;
5363         }
5364     }
5365
5366   if (resolve_attempts > 0 && sw_if_index_set == 0)
5367     {
5368       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5369       return -99;
5370     }
5371
5372   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5373     {
5374       errmsg ("next hop / local / drop / classify not set\n");
5375       return -99;
5376     }
5377
5378   if (address_set == 0)
5379     {
5380       errmsg ("missing addresses\n");
5381       return -99;
5382     }
5383
5384   if (address_length_set == 0)
5385     {
5386       errmsg ("missing address length\n");
5387       return -99;
5388     }
5389
5390   /* Generate a pile of unique, random routes */
5391   if (random_add_del)
5392     {
5393       u32 this_random_address;
5394       random_hash = hash_create (count, sizeof (uword));
5395
5396       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5397       for (j = 0; j <= count; j++)
5398         {
5399           do
5400             {
5401               this_random_address = random_u32 (&random_seed);
5402               this_random_address =
5403                 clib_host_to_net_u32 (this_random_address);
5404             }
5405           while (hash_get (random_hash, this_random_address));
5406           vec_add1 (random_vector, this_random_address);
5407           hash_set (random_hash, this_random_address, 1);
5408         }
5409       hash_free (random_hash);
5410       v4_dst_address.as_u32 = random_vector[0];
5411     }
5412
5413   if (count > 1)
5414     {
5415       /* Turn on async mode */
5416       vam->async_mode = 1;
5417       vam->async_errors = 0;
5418       before = vat_time_now (vam);
5419     }
5420
5421   for (j = 0; j < count; j++)
5422     {
5423       /* Construct the API message */
5424       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5425
5426       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5427       mp->vrf_id = ntohl (vrf_id);
5428       if (resolve_attempts > 0)
5429         {
5430           mp->resolve_attempts = ntohl (resolve_attempts);
5431           mp->resolve_if_needed = 1;
5432         }
5433       mp->create_vrf_if_needed = create_vrf_if_needed;
5434
5435       mp->is_add = is_add;
5436       mp->is_drop = is_drop;
5437       mp->is_ipv6 = is_ipv6;
5438       mp->is_local = is_local;
5439       mp->is_classify = is_classify;
5440       mp->is_multipath = is_multipath;
5441       mp->not_last = not_last;
5442       mp->next_hop_weight = next_hop_weight;
5443       mp->dst_address_length = dst_address_length;
5444       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5445       mp->classify_table_index = ntohl (classify_table_index);
5446
5447       if (is_ipv6)
5448         {
5449           clib_memcpy (mp->dst_address, &v6_dst_address,
5450                        sizeof (v6_dst_address));
5451           if (next_hop_set)
5452             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5453                          sizeof (v6_next_hop_address));
5454           increment_v6_address (&v6_dst_address);
5455         }
5456       else
5457         {
5458           clib_memcpy (mp->dst_address, &v4_dst_address,
5459                        sizeof (v4_dst_address));
5460           if (next_hop_set)
5461             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5462                          sizeof (v4_next_hop_address));
5463           if (random_add_del)
5464             v4_dst_address.as_u32 = random_vector[j + 1];
5465           else
5466             increment_v4_address (&v4_dst_address);
5467         }
5468       /* send it... */
5469       S;
5470     }
5471
5472   /* When testing multiple add/del ops, use a control-ping to sync */
5473   if (count > 1)
5474     {
5475       vl_api_control_ping_t *mp;
5476       f64 after;
5477
5478       /* Shut off async mode */
5479       vam->async_mode = 0;
5480
5481       M (CONTROL_PING, control_ping);
5482       S;
5483
5484       timeout = vat_time_now (vam) + 1.0;
5485       while (vat_time_now (vam) < timeout)
5486         if (vam->result_ready == 1)
5487           goto out;
5488       vam->retval = -99;
5489
5490     out:
5491       if (vam->retval == -99)
5492         errmsg ("timeout\n");
5493
5494       if (vam->async_errors > 0)
5495         {
5496           errmsg ("%d asynchronous errors\n", vam->async_errors);
5497           vam->retval = -98;
5498         }
5499       vam->async_errors = 0;
5500       after = vat_time_now (vam);
5501
5502       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5503                count, after - before, count / (after - before));
5504     }
5505   else
5506     {
5507       /* Wait for a reply... */
5508       W;
5509     }
5510
5511   /* Return the good/bad news */
5512   return (vam->retval);
5513 }
5514
5515 static int
5516 api_proxy_arp_add_del (vat_main_t * vam)
5517 {
5518   unformat_input_t *i = vam->input;
5519   vl_api_proxy_arp_add_del_t *mp;
5520   f64 timeout;
5521   u32 vrf_id = 0;
5522   u8 is_add = 1;
5523   ip4_address_t lo, hi;
5524   u8 range_set = 0;
5525
5526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5527     {
5528       if (unformat (i, "vrf %d", &vrf_id))
5529         ;
5530       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5531                          unformat_ip4_address, &hi))
5532         range_set = 1;
5533       else if (unformat (i, "del"))
5534         is_add = 0;
5535       else
5536         {
5537           clib_warning ("parse error '%U'", format_unformat_error, i);
5538           return -99;
5539         }
5540     }
5541
5542   if (range_set == 0)
5543     {
5544       errmsg ("address range not set\n");
5545       return -99;
5546     }
5547
5548   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5549
5550   mp->vrf_id = ntohl (vrf_id);
5551   mp->is_add = is_add;
5552   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5553   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5554
5555   S;
5556   W;
5557   /* NOTREACHED */
5558   return 0;
5559 }
5560
5561 static int
5562 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5563 {
5564   unformat_input_t *i = vam->input;
5565   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5566   f64 timeout;
5567   u32 sw_if_index;
5568   u8 enable = 1;
5569   u8 sw_if_index_set = 0;
5570
5571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5572     {
5573       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5574         sw_if_index_set = 1;
5575       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5576         sw_if_index_set = 1;
5577       else if (unformat (i, "enable"))
5578         enable = 1;
5579       else if (unformat (i, "disable"))
5580         enable = 0;
5581       else
5582         {
5583           clib_warning ("parse error '%U'", format_unformat_error, i);
5584           return -99;
5585         }
5586     }
5587
5588   if (sw_if_index_set == 0)
5589     {
5590       errmsg ("missing interface name or sw_if_index\n");
5591       return -99;
5592     }
5593
5594   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5595
5596   mp->sw_if_index = ntohl (sw_if_index);
5597   mp->enable_disable = enable;
5598
5599   S;
5600   W;
5601   /* NOTREACHED */
5602   return 0;
5603 }
5604
5605 static int
5606 api_mpls_add_del_decap (vat_main_t * vam)
5607 {
5608   unformat_input_t *i = vam->input;
5609   vl_api_mpls_add_del_decap_t *mp;
5610   f64 timeout;
5611   u32 rx_vrf_id = 0;
5612   u32 tx_vrf_id = 0;
5613   u32 label = 0;
5614   u8 is_add = 1;
5615   u8 s_bit = 1;
5616   u32 next_index = 1;
5617
5618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5619     {
5620       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5621         ;
5622       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5623         ;
5624       else if (unformat (i, "label %d", &label))
5625         ;
5626       else if (unformat (i, "next-index %d", &next_index))
5627         ;
5628       else if (unformat (i, "del"))
5629         is_add = 0;
5630       else if (unformat (i, "s-bit-clear"))
5631         s_bit = 0;
5632       else
5633         {
5634           clib_warning ("parse error '%U'", format_unformat_error, i);
5635           return -99;
5636         }
5637     }
5638
5639   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5640
5641   mp->rx_vrf_id = ntohl (rx_vrf_id);
5642   mp->tx_vrf_id = ntohl (tx_vrf_id);
5643   mp->label = ntohl (label);
5644   mp->next_index = ntohl (next_index);
5645   mp->s_bit = s_bit;
5646   mp->is_add = is_add;
5647
5648   S;
5649   W;
5650   /* NOTREACHED */
5651   return 0;
5652 }
5653
5654 static int
5655 api_mpls_add_del_encap (vat_main_t * vam)
5656 {
5657   unformat_input_t *i = vam->input;
5658   vl_api_mpls_add_del_encap_t *mp;
5659   f64 timeout;
5660   u32 vrf_id = 0;
5661   u32 *labels = 0;
5662   u32 label;
5663   ip4_address_t dst_address;
5664   u8 is_add = 1;
5665
5666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5667     {
5668       if (unformat (i, "vrf %d", &vrf_id))
5669         ;
5670       else if (unformat (i, "label %d", &label))
5671         vec_add1 (labels, ntohl (label));
5672       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5673         ;
5674       else if (unformat (i, "del"))
5675         is_add = 0;
5676       else
5677         {
5678           clib_warning ("parse error '%U'", format_unformat_error, i);
5679           return -99;
5680         }
5681     }
5682
5683   if (vec_len (labels) == 0)
5684     {
5685       errmsg ("missing encap label stack\n");
5686       return -99;
5687     }
5688
5689   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
5690       sizeof (u32) * vec_len (labels));
5691
5692   mp->vrf_id = ntohl (vrf_id);
5693   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5694   mp->is_add = is_add;
5695   mp->nlabels = vec_len (labels);
5696   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
5697
5698   vec_free (labels);
5699
5700   S;
5701   W;
5702   /* NOTREACHED */
5703   return 0;
5704 }
5705
5706 static int
5707 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5708 {
5709   unformat_input_t *i = vam->input;
5710   vl_api_mpls_gre_add_del_tunnel_t *mp;
5711   f64 timeout;
5712   u32 inner_vrf_id = 0;
5713   u32 outer_vrf_id = 0;
5714   ip4_address_t src_address;
5715   ip4_address_t dst_address;
5716   ip4_address_t intfc_address;
5717   u32 tmp;
5718   u8 intfc_address_length = 0;
5719   u8 is_add = 1;
5720   u8 l2_only = 0;
5721
5722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5723     {
5724       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5725         ;
5726       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5727         ;
5728       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5729         ;
5730       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5731         ;
5732       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5733                          &intfc_address, &tmp))
5734         intfc_address_length = tmp;
5735       else if (unformat (i, "l2-only"))
5736         l2_only = 1;
5737       else if (unformat (i, "del"))
5738         is_add = 0;
5739       else
5740         {
5741           clib_warning ("parse error '%U'", format_unformat_error, i);
5742           return -99;
5743         }
5744     }
5745
5746   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5747
5748   mp->inner_vrf_id = ntohl (inner_vrf_id);
5749   mp->outer_vrf_id = ntohl (outer_vrf_id);
5750   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
5751   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5752   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
5753   mp->intfc_address_length = intfc_address_length;
5754   mp->l2_only = l2_only;
5755   mp->is_add = is_add;
5756
5757   S;
5758   W;
5759   /* NOTREACHED */
5760   return 0;
5761 }
5762
5763 static int
5764 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5765 {
5766   unformat_input_t *i = vam->input;
5767   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5768   f64 timeout;
5769   u32 inner_vrf_id = 0;
5770   ip4_address_t intfc_address;
5771   u8 dst_mac_address[6];
5772   int dst_set = 1;
5773   u32 tmp;
5774   u8 intfc_address_length = 0;
5775   u8 is_add = 1;
5776   u8 l2_only = 0;
5777   u32 tx_sw_if_index;
5778   int tx_sw_if_index_set = 0;
5779
5780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5781     {
5782       if (unformat (i, "vrf %d", &inner_vrf_id))
5783         ;
5784       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5785                          &intfc_address, &tmp))
5786         intfc_address_length = tmp;
5787       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
5788         tx_sw_if_index_set = 1;
5789       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5790         tx_sw_if_index_set = 1;
5791       else if (unformat (i, "dst %U", unformat_ethernet_address,
5792                          dst_mac_address))
5793         dst_set = 1;
5794       else if (unformat (i, "l2-only"))
5795         l2_only = 1;
5796       else if (unformat (i, "del"))
5797         is_add = 0;
5798       else
5799         {
5800           clib_warning ("parse error '%U'", format_unformat_error, i);
5801           return -99;
5802         }
5803     }
5804
5805   if (!dst_set)
5806     {
5807       errmsg ("dst (mac address) not set\n");
5808       return -99;
5809     }
5810   if (!tx_sw_if_index_set)
5811     {
5812       errmsg ("tx-intfc not set\n");
5813       return -99;
5814     }
5815
5816   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5817
5818   mp->vrf_id = ntohl (inner_vrf_id);
5819   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
5820   mp->adj_address_length = intfc_address_length;
5821   clib_memcpy (mp->dst_mac_address, dst_mac_address,
5822                sizeof (dst_mac_address));
5823   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5824   mp->l2_only = l2_only;
5825   mp->is_add = is_add;
5826
5827   S;
5828   W;
5829   /* NOTREACHED */
5830   return 0;
5831 }
5832
5833 static int
5834 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5835 {
5836   unformat_input_t *i = vam->input;
5837   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5838   f64 timeout;
5839   u32 inner_vrf_id = 0;
5840   u32 outer_vrf_id = 0;
5841   ip4_address_t adj_address;
5842   int adj_address_set = 0;
5843   ip4_address_t next_hop_address;
5844   int next_hop_address_set = 0;
5845   u32 tmp;
5846   u8 adj_address_length = 0;
5847   u8 l2_only = 0;
5848   u8 is_add = 1;
5849   u32 resolve_attempts = 5;
5850   u8 resolve_if_needed = 1;
5851
5852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5853     {
5854       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5855         ;
5856       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5857         ;
5858       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5859                          &adj_address, &tmp))
5860         {
5861           adj_address_length = tmp;
5862           adj_address_set = 1;
5863         }
5864       else if (unformat (i, "next-hop %U", unformat_ip4_address,
5865                          &next_hop_address))
5866         next_hop_address_set = 1;
5867       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5868         ;
5869       else if (unformat (i, "resolve-if-needed %d", &tmp))
5870         resolve_if_needed = tmp;
5871       else if (unformat (i, "l2-only"))
5872         l2_only = 1;
5873       else if (unformat (i, "del"))
5874         is_add = 0;
5875       else
5876         {
5877           clib_warning ("parse error '%U'", format_unformat_error, i);
5878           return -99;
5879         }
5880     }
5881
5882   if (!adj_address_set)
5883     {
5884       errmsg ("adjacency address/mask not set\n");
5885       return -99;
5886     }
5887   if (!next_hop_address_set)
5888     {
5889       errmsg ("ip4 next hop address (in outer fib) not set\n");
5890       return -99;
5891     }
5892
5893   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
5894
5895   mp->inner_vrf_id = ntohl (inner_vrf_id);
5896   mp->outer_vrf_id = ntohl (outer_vrf_id);
5897   mp->resolve_attempts = ntohl (resolve_attempts);
5898   mp->resolve_if_needed = resolve_if_needed;
5899   mp->is_add = is_add;
5900   mp->l2_only = l2_only;
5901   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
5902   mp->adj_address_length = adj_address_length;
5903   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
5904                sizeof (next_hop_address));
5905
5906   S;
5907   W;
5908   /* NOTREACHED */
5909   return 0;
5910 }
5911
5912 static int
5913 api_sw_interface_set_unnumbered (vat_main_t * vam)
5914 {
5915   unformat_input_t *i = vam->input;
5916   vl_api_sw_interface_set_unnumbered_t *mp;
5917   f64 timeout;
5918   u32 sw_if_index;
5919   u32 unnum_sw_index = ~0;
5920   u8 is_add = 1;
5921   u8 sw_if_index_set = 0;
5922
5923   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5924     {
5925       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5926         sw_if_index_set = 1;
5927       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5928         sw_if_index_set = 1;
5929       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
5930         ;
5931       else if (unformat (i, "del"))
5932         is_add = 0;
5933       else
5934         {
5935           clib_warning ("parse error '%U'", format_unformat_error, i);
5936           return -99;
5937         }
5938     }
5939
5940   if (sw_if_index_set == 0)
5941     {
5942       errmsg ("missing interface name or sw_if_index\n");
5943       return -99;
5944     }
5945
5946   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
5947
5948   mp->sw_if_index = ntohl (sw_if_index);
5949   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
5950   mp->is_add = is_add;
5951
5952   S;
5953   W;
5954   /* NOTREACHED */
5955   return 0;
5956 }
5957
5958 static int
5959 api_ip_neighbor_add_del (vat_main_t * vam)
5960 {
5961   unformat_input_t *i = vam->input;
5962   vl_api_ip_neighbor_add_del_t *mp;
5963   f64 timeout;
5964   u32 sw_if_index;
5965   u8 sw_if_index_set = 0;
5966   u32 vrf_id = 0;
5967   u8 is_add = 1;
5968   u8 is_static = 0;
5969   u8 mac_address[6];
5970   u8 mac_set = 0;
5971   u8 v4_address_set = 0;
5972   u8 v6_address_set = 0;
5973   ip4_address_t v4address;
5974   ip6_address_t v6address;
5975
5976   memset (mac_address, 0, sizeof (mac_address));
5977
5978   /* Parse args required to build the message */
5979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5980     {
5981       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5982         {
5983           mac_set = 1;
5984         }
5985       else if (unformat (i, "del"))
5986         is_add = 0;
5987       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5988         sw_if_index_set = 1;
5989       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5990         sw_if_index_set = 1;
5991       else if (unformat (i, "is_static"))
5992         is_static = 1;
5993       else if (unformat (i, "vrf %d", &vrf_id))
5994         ;
5995       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
5996         v4_address_set = 1;
5997       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
5998         v6_address_set = 1;
5999       else
6000         {
6001           clib_warning ("parse error '%U'", format_unformat_error, i);
6002           return -99;
6003         }
6004     }
6005
6006   if (sw_if_index_set == 0)
6007     {
6008       errmsg ("missing interface name or sw_if_index\n");
6009       return -99;
6010     }
6011   if (v4_address_set && v6_address_set)
6012     {
6013       errmsg ("both v4 and v6 addresses set\n");
6014       return -99;
6015     }
6016   if (!v4_address_set && !v6_address_set)
6017     {
6018       errmsg ("no address set\n");
6019       return -99;
6020     }
6021
6022   /* Construct the API message */
6023   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6024
6025   mp->sw_if_index = ntohl (sw_if_index);
6026   mp->is_add = is_add;
6027   mp->vrf_id = ntohl (vrf_id);
6028   mp->is_static = is_static;
6029   if (mac_set)
6030     clib_memcpy (mp->mac_address, mac_address, 6);
6031   if (v6_address_set)
6032     {
6033       mp->is_ipv6 = 1;
6034       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6035     }
6036   else
6037     {
6038       /* mp->is_ipv6 = 0; via memset in M macro above */
6039       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6040     }
6041
6042   /* send it... */
6043   S;
6044
6045   /* Wait for a reply, return good/bad news  */
6046   W;
6047
6048   /* NOTREACHED */
6049   return 0;
6050 }
6051
6052 static int
6053 api_reset_vrf (vat_main_t * vam)
6054 {
6055   unformat_input_t *i = vam->input;
6056   vl_api_reset_vrf_t *mp;
6057   f64 timeout;
6058   u32 vrf_id = 0;
6059   u8 is_ipv6 = 0;
6060   u8 vrf_id_set = 0;
6061
6062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6063     {
6064       if (unformat (i, "vrf %d", &vrf_id))
6065         vrf_id_set = 1;
6066       else if (unformat (i, "ipv6"))
6067         is_ipv6 = 1;
6068       else
6069         {
6070           clib_warning ("parse error '%U'", format_unformat_error, i);
6071           return -99;
6072         }
6073     }
6074
6075   if (vrf_id_set == 0)
6076     {
6077       errmsg ("missing vrf id\n");
6078       return -99;
6079     }
6080
6081   M (RESET_VRF, reset_vrf);
6082
6083   mp->vrf_id = ntohl (vrf_id);
6084   mp->is_ipv6 = is_ipv6;
6085
6086   S;
6087   W;
6088   /* NOTREACHED */
6089   return 0;
6090 }
6091
6092 static int
6093 api_create_vlan_subif (vat_main_t * vam)
6094 {
6095   unformat_input_t *i = vam->input;
6096   vl_api_create_vlan_subif_t *mp;
6097   f64 timeout;
6098   u32 sw_if_index;
6099   u8 sw_if_index_set = 0;
6100   u32 vlan_id;
6101   u8 vlan_id_set = 0;
6102
6103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6104     {
6105       if (unformat (i, "sw_if_index %d", &sw_if_index))
6106         sw_if_index_set = 1;
6107       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6108         sw_if_index_set = 1;
6109       else if (unformat (i, "vlan %d", &vlan_id))
6110         vlan_id_set = 1;
6111       else
6112         {
6113           clib_warning ("parse error '%U'", format_unformat_error, i);
6114           return -99;
6115         }
6116     }
6117
6118   if (sw_if_index_set == 0)
6119     {
6120       errmsg ("missing interface name or sw_if_index\n");
6121       return -99;
6122     }
6123
6124   if (vlan_id_set == 0)
6125     {
6126       errmsg ("missing vlan_id\n");
6127       return -99;
6128     }
6129   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6130
6131   mp->sw_if_index = ntohl (sw_if_index);
6132   mp->vlan_id = ntohl (vlan_id);
6133
6134   S;
6135   W;
6136   /* NOTREACHED */
6137   return 0;
6138 }
6139
6140 #define foreach_create_subif_bit                \
6141 _(no_tags)                                      \
6142 _(one_tag)                                      \
6143 _(two_tags)                                     \
6144 _(dot1ad)                                       \
6145 _(exact_match)                                  \
6146 _(default_sub)                                  \
6147 _(outer_vlan_id_any)                            \
6148 _(inner_vlan_id_any)
6149
6150 static int
6151 api_create_subif (vat_main_t * vam)
6152 {
6153   unformat_input_t *i = vam->input;
6154   vl_api_create_subif_t *mp;
6155   f64 timeout;
6156   u32 sw_if_index;
6157   u8 sw_if_index_set = 0;
6158   u32 sub_id;
6159   u8 sub_id_set = 0;
6160   u32 no_tags = 0;
6161   u32 one_tag = 0;
6162   u32 two_tags = 0;
6163   u32 dot1ad = 0;
6164   u32 exact_match = 0;
6165   u32 default_sub = 0;
6166   u32 outer_vlan_id_any = 0;
6167   u32 inner_vlan_id_any = 0;
6168   u32 tmp;
6169   u16 outer_vlan_id = 0;
6170   u16 inner_vlan_id = 0;
6171
6172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6173     {
6174       if (unformat (i, "sw_if_index %d", &sw_if_index))
6175         sw_if_index_set = 1;
6176       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6177         sw_if_index_set = 1;
6178       else if (unformat (i, "sub_id %d", &sub_id))
6179         sub_id_set = 1;
6180       else if (unformat (i, "outer_vlan_id %d", &tmp))
6181         outer_vlan_id = tmp;
6182       else if (unformat (i, "inner_vlan_id %d", &tmp))
6183         inner_vlan_id = tmp;
6184
6185 #define _(a) else if (unformat (i, #a)) a = 1 ;
6186       foreach_create_subif_bit
6187 #undef _
6188         else
6189         {
6190           clib_warning ("parse error '%U'", format_unformat_error, i);
6191           return -99;
6192         }
6193     }
6194
6195   if (sw_if_index_set == 0)
6196     {
6197       errmsg ("missing interface name or sw_if_index\n");
6198       return -99;
6199     }
6200
6201   if (sub_id_set == 0)
6202     {
6203       errmsg ("missing sub_id\n");
6204       return -99;
6205     }
6206   M (CREATE_SUBIF, create_subif);
6207
6208   mp->sw_if_index = ntohl (sw_if_index);
6209   mp->sub_id = ntohl (sub_id);
6210
6211 #define _(a) mp->a = a;
6212   foreach_create_subif_bit;
6213 #undef _
6214
6215   mp->outer_vlan_id = ntohs (outer_vlan_id);
6216   mp->inner_vlan_id = ntohs (inner_vlan_id);
6217
6218   S;
6219   W;
6220   /* NOTREACHED */
6221   return 0;
6222 }
6223
6224 static int
6225 api_oam_add_del (vat_main_t * vam)
6226 {
6227   unformat_input_t *i = vam->input;
6228   vl_api_oam_add_del_t *mp;
6229   f64 timeout;
6230   u32 vrf_id = 0;
6231   u8 is_add = 1;
6232   ip4_address_t src, dst;
6233   u8 src_set = 0;
6234   u8 dst_set = 0;
6235
6236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6237     {
6238       if (unformat (i, "vrf %d", &vrf_id))
6239         ;
6240       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6241         src_set = 1;
6242       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6243         dst_set = 1;
6244       else if (unformat (i, "del"))
6245         is_add = 0;
6246       else
6247         {
6248           clib_warning ("parse error '%U'", format_unformat_error, i);
6249           return -99;
6250         }
6251     }
6252
6253   if (src_set == 0)
6254     {
6255       errmsg ("missing src addr\n");
6256       return -99;
6257     }
6258
6259   if (dst_set == 0)
6260     {
6261       errmsg ("missing dst addr\n");
6262       return -99;
6263     }
6264
6265   M (OAM_ADD_DEL, oam_add_del);
6266
6267   mp->vrf_id = ntohl (vrf_id);
6268   mp->is_add = is_add;
6269   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6270   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6271
6272   S;
6273   W;
6274   /* NOTREACHED */
6275   return 0;
6276 }
6277
6278 static int
6279 api_reset_fib (vat_main_t * vam)
6280 {
6281   unformat_input_t *i = vam->input;
6282   vl_api_reset_fib_t *mp;
6283   f64 timeout;
6284   u32 vrf_id = 0;
6285   u8 is_ipv6 = 0;
6286   u8 vrf_id_set = 0;
6287
6288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6289     {
6290       if (unformat (i, "vrf %d", &vrf_id))
6291         vrf_id_set = 1;
6292       else if (unformat (i, "ipv6"))
6293         is_ipv6 = 1;
6294       else
6295         {
6296           clib_warning ("parse error '%U'", format_unformat_error, i);
6297           return -99;
6298         }
6299     }
6300
6301   if (vrf_id_set == 0)
6302     {
6303       errmsg ("missing vrf id\n");
6304       return -99;
6305     }
6306
6307   M (RESET_FIB, reset_fib);
6308
6309   mp->vrf_id = ntohl (vrf_id);
6310   mp->is_ipv6 = is_ipv6;
6311
6312   S;
6313   W;
6314   /* NOTREACHED */
6315   return 0;
6316 }
6317
6318 static int
6319 api_dhcp_proxy_config (vat_main_t * vam)
6320 {
6321   unformat_input_t *i = vam->input;
6322   vl_api_dhcp_proxy_config_t *mp;
6323   f64 timeout;
6324   u32 vrf_id = 0;
6325   u8 is_add = 1;
6326   u8 insert_cid = 1;
6327   u8 v4_address_set = 0;
6328   u8 v6_address_set = 0;
6329   ip4_address_t v4address;
6330   ip6_address_t v6address;
6331   u8 v4_src_address_set = 0;
6332   u8 v6_src_address_set = 0;
6333   ip4_address_t v4srcaddress;
6334   ip6_address_t v6srcaddress;
6335
6336   /* Parse args required to build the message */
6337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6338     {
6339       if (unformat (i, "del"))
6340         is_add = 0;
6341       else if (unformat (i, "vrf %d", &vrf_id))
6342         ;
6343       else if (unformat (i, "insert-cid %d", &insert_cid))
6344         ;
6345       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6346         v4_address_set = 1;
6347       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6348         v6_address_set = 1;
6349       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6350         v4_src_address_set = 1;
6351       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6352         v6_src_address_set = 1;
6353       else
6354         break;
6355     }
6356
6357   if (v4_address_set && v6_address_set)
6358     {
6359       errmsg ("both v4 and v6 server addresses set\n");
6360       return -99;
6361     }
6362   if (!v4_address_set && !v6_address_set)
6363     {
6364       errmsg ("no server addresses set\n");
6365       return -99;
6366     }
6367
6368   if (v4_src_address_set && v6_src_address_set)
6369     {
6370       errmsg ("both v4 and v6  src addresses set\n");
6371       return -99;
6372     }
6373   if (!v4_src_address_set && !v6_src_address_set)
6374     {
6375       errmsg ("no src addresses set\n");
6376       return -99;
6377     }
6378
6379   if (!(v4_src_address_set && v4_address_set) &&
6380       !(v6_src_address_set && v6_address_set))
6381     {
6382       errmsg ("no matching server and src addresses set\n");
6383       return -99;
6384     }
6385
6386   /* Construct the API message */
6387   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6388
6389   mp->insert_circuit_id = insert_cid;
6390   mp->is_add = is_add;
6391   mp->vrf_id = ntohl (vrf_id);
6392   if (v6_address_set)
6393     {
6394       mp->is_ipv6 = 1;
6395       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6396       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6397     }
6398   else
6399     {
6400       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6401       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6402     }
6403
6404   /* send it... */
6405   S;
6406
6407   /* Wait for a reply, return good/bad news  */
6408   W;
6409   /* NOTREACHED */
6410   return 0;
6411 }
6412
6413 static int
6414 api_dhcp_proxy_config_2 (vat_main_t * vam)
6415 {
6416   unformat_input_t *i = vam->input;
6417   vl_api_dhcp_proxy_config_2_t *mp;
6418   f64 timeout;
6419   u32 rx_vrf_id = 0;
6420   u32 server_vrf_id = 0;
6421   u8 is_add = 1;
6422   u8 insert_cid = 1;
6423   u8 v4_address_set = 0;
6424   u8 v6_address_set = 0;
6425   ip4_address_t v4address;
6426   ip6_address_t v6address;
6427   u8 v4_src_address_set = 0;
6428   u8 v6_src_address_set = 0;
6429   ip4_address_t v4srcaddress;
6430   ip6_address_t v6srcaddress;
6431
6432   /* Parse args required to build the message */
6433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6434     {
6435       if (unformat (i, "del"))
6436         is_add = 0;
6437       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6438         ;
6439       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6440         ;
6441       else if (unformat (i, "insert-cid %d", &insert_cid))
6442         ;
6443       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6444         v4_address_set = 1;
6445       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6446         v6_address_set = 1;
6447       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6448         v4_src_address_set = 1;
6449       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6450         v6_src_address_set = 1;
6451       else
6452         break;
6453     }
6454
6455   if (v4_address_set && v6_address_set)
6456     {
6457       errmsg ("both v4 and v6 server addresses set\n");
6458       return -99;
6459     }
6460   if (!v4_address_set && !v6_address_set)
6461     {
6462       errmsg ("no server addresses set\n");
6463       return -99;
6464     }
6465
6466   if (v4_src_address_set && v6_src_address_set)
6467     {
6468       errmsg ("both v4 and v6  src addresses set\n");
6469       return -99;
6470     }
6471   if (!v4_src_address_set && !v6_src_address_set)
6472     {
6473       errmsg ("no src addresses set\n");
6474       return -99;
6475     }
6476
6477   if (!(v4_src_address_set && v4_address_set) &&
6478       !(v6_src_address_set && v6_address_set))
6479     {
6480       errmsg ("no matching server and src addresses set\n");
6481       return -99;
6482     }
6483
6484   /* Construct the API message */
6485   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6486
6487   mp->insert_circuit_id = insert_cid;
6488   mp->is_add = is_add;
6489   mp->rx_vrf_id = ntohl (rx_vrf_id);
6490   mp->server_vrf_id = ntohl (server_vrf_id);
6491   if (v6_address_set)
6492     {
6493       mp->is_ipv6 = 1;
6494       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6495       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6496     }
6497   else
6498     {
6499       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6500       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6501     }
6502
6503   /* send it... */
6504   S;
6505
6506   /* Wait for a reply, return good/bad news  */
6507   W;
6508   /* NOTREACHED */
6509   return 0;
6510 }
6511
6512 static int
6513 api_dhcp_proxy_set_vss (vat_main_t * vam)
6514 {
6515   unformat_input_t *i = vam->input;
6516   vl_api_dhcp_proxy_set_vss_t *mp;
6517   f64 timeout;
6518   u8 is_ipv6 = 0;
6519   u8 is_add = 1;
6520   u32 tbl_id;
6521   u8 tbl_id_set = 0;
6522   u32 oui;
6523   u8 oui_set = 0;
6524   u32 fib_id;
6525   u8 fib_id_set = 0;
6526
6527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6528     {
6529       if (unformat (i, "tbl_id %d", &tbl_id))
6530         tbl_id_set = 1;
6531       if (unformat (i, "fib_id %d", &fib_id))
6532         fib_id_set = 1;
6533       if (unformat (i, "oui %d", &oui))
6534         oui_set = 1;
6535       else if (unformat (i, "ipv6"))
6536         is_ipv6 = 1;
6537       else if (unformat (i, "del"))
6538         is_add = 0;
6539       else
6540         {
6541           clib_warning ("parse error '%U'", format_unformat_error, i);
6542           return -99;
6543         }
6544     }
6545
6546   if (tbl_id_set == 0)
6547     {
6548       errmsg ("missing tbl id\n");
6549       return -99;
6550     }
6551
6552   if (fib_id_set == 0)
6553     {
6554       errmsg ("missing fib id\n");
6555       return -99;
6556     }
6557   if (oui_set == 0)
6558     {
6559       errmsg ("missing oui\n");
6560       return -99;
6561     }
6562
6563   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6564   mp->tbl_id = ntohl (tbl_id);
6565   mp->fib_id = ntohl (fib_id);
6566   mp->oui = ntohl (oui);
6567   mp->is_ipv6 = is_ipv6;
6568   mp->is_add = is_add;
6569
6570   S;
6571   W;
6572   /* NOTREACHED */
6573   return 0;
6574 }
6575
6576 static int
6577 api_dhcp_client_config (vat_main_t * vam)
6578 {
6579   unformat_input_t *i = vam->input;
6580   vl_api_dhcp_client_config_t *mp;
6581   f64 timeout;
6582   u32 sw_if_index;
6583   u8 sw_if_index_set = 0;
6584   u8 is_add = 1;
6585   u8 *hostname = 0;
6586   u8 disable_event = 0;
6587
6588   /* Parse args required to build the message */
6589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6590     {
6591       if (unformat (i, "del"))
6592         is_add = 0;
6593       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6594         sw_if_index_set = 1;
6595       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6596         sw_if_index_set = 1;
6597       else if (unformat (i, "hostname %s", &hostname))
6598         ;
6599       else if (unformat (i, "disable_event"))
6600         disable_event = 1;
6601       else
6602         break;
6603     }
6604
6605   if (sw_if_index_set == 0)
6606     {
6607       errmsg ("missing interface name or sw_if_index\n");
6608       return -99;
6609     }
6610
6611   if (vec_len (hostname) > 63)
6612     {
6613       errmsg ("hostname too long\n");
6614     }
6615   vec_add1 (hostname, 0);
6616
6617   /* Construct the API message */
6618   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6619
6620   mp->sw_if_index = ntohl (sw_if_index);
6621   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6622   vec_free (hostname);
6623   mp->is_add = is_add;
6624   mp->want_dhcp_event = disable_event ? 0 : 1;
6625   mp->pid = getpid ();
6626
6627   /* send it... */
6628   S;
6629
6630   /* Wait for a reply, return good/bad news  */
6631   W;
6632   /* NOTREACHED */
6633   return 0;
6634 }
6635
6636 static int
6637 api_set_ip_flow_hash (vat_main_t * vam)
6638 {
6639   unformat_input_t *i = vam->input;
6640   vl_api_set_ip_flow_hash_t *mp;
6641   f64 timeout;
6642   u32 vrf_id = 0;
6643   u8 is_ipv6 = 0;
6644   u8 vrf_id_set = 0;
6645   u8 src = 0;
6646   u8 dst = 0;
6647   u8 sport = 0;
6648   u8 dport = 0;
6649   u8 proto = 0;
6650   u8 reverse = 0;
6651
6652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6653     {
6654       if (unformat (i, "vrf %d", &vrf_id))
6655         vrf_id_set = 1;
6656       else if (unformat (i, "ipv6"))
6657         is_ipv6 = 1;
6658       else if (unformat (i, "src"))
6659         src = 1;
6660       else if (unformat (i, "dst"))
6661         dst = 1;
6662       else if (unformat (i, "sport"))
6663         sport = 1;
6664       else if (unformat (i, "dport"))
6665         dport = 1;
6666       else if (unformat (i, "proto"))
6667         proto = 1;
6668       else if (unformat (i, "reverse"))
6669         reverse = 1;
6670
6671       else
6672         {
6673           clib_warning ("parse error '%U'", format_unformat_error, i);
6674           return -99;
6675         }
6676     }
6677
6678   if (vrf_id_set == 0)
6679     {
6680       errmsg ("missing vrf id\n");
6681       return -99;
6682     }
6683
6684   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
6685   mp->src = src;
6686   mp->dst = dst;
6687   mp->sport = sport;
6688   mp->dport = dport;
6689   mp->proto = proto;
6690   mp->reverse = reverse;
6691   mp->vrf_id = ntohl (vrf_id);
6692   mp->is_ipv6 = is_ipv6;
6693
6694   S;
6695   W;
6696   /* NOTREACHED */
6697   return 0;
6698 }
6699
6700 static int
6701 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6702 {
6703   unformat_input_t *i = vam->input;
6704   vl_api_sw_interface_ip6_enable_disable_t *mp;
6705   f64 timeout;
6706   u32 sw_if_index;
6707   u8 sw_if_index_set = 0;
6708   u8 enable = 0;
6709
6710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6711     {
6712       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6713         sw_if_index_set = 1;
6714       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6715         sw_if_index_set = 1;
6716       else if (unformat (i, "enable"))
6717         enable = 1;
6718       else if (unformat (i, "disable"))
6719         enable = 0;
6720       else
6721         {
6722           clib_warning ("parse error '%U'", format_unformat_error, i);
6723           return -99;
6724         }
6725     }
6726
6727   if (sw_if_index_set == 0)
6728     {
6729       errmsg ("missing interface name or sw_if_index\n");
6730       return -99;
6731     }
6732
6733   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6734
6735   mp->sw_if_index = ntohl (sw_if_index);
6736   mp->enable = enable;
6737
6738   S;
6739   W;
6740   /* NOTREACHED */
6741   return 0;
6742 }
6743
6744 static int
6745 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6746 {
6747   unformat_input_t *i = vam->input;
6748   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6749   f64 timeout;
6750   u32 sw_if_index;
6751   u8 sw_if_index_set = 0;
6752   u32 address_length = 0;
6753   u8 v6_address_set = 0;
6754   ip6_address_t v6address;
6755
6756   /* Parse args required to build the message */
6757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6758     {
6759       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6760         sw_if_index_set = 1;
6761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6762         sw_if_index_set = 1;
6763       else if (unformat (i, "%U/%d",
6764                          unformat_ip6_address, &v6address, &address_length))
6765         v6_address_set = 1;
6766       else
6767         break;
6768     }
6769
6770   if (sw_if_index_set == 0)
6771     {
6772       errmsg ("missing interface name or sw_if_index\n");
6773       return -99;
6774     }
6775   if (!v6_address_set)
6776     {
6777       errmsg ("no address set\n");
6778       return -99;
6779     }
6780
6781   /* Construct the API message */
6782   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
6783      sw_interface_ip6_set_link_local_address);
6784
6785   mp->sw_if_index = ntohl (sw_if_index);
6786   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6787   mp->address_length = address_length;
6788
6789   /* send it... */
6790   S;
6791
6792   /* Wait for a reply, return good/bad news  */
6793   W;
6794
6795   /* NOTREACHED */
6796   return 0;
6797 }
6798
6799
6800 static int
6801 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6802 {
6803   unformat_input_t *i = vam->input;
6804   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6805   f64 timeout;
6806   u32 sw_if_index;
6807   u8 sw_if_index_set = 0;
6808   u32 address_length = 0;
6809   u8 v6_address_set = 0;
6810   ip6_address_t v6address;
6811   u8 use_default = 0;
6812   u8 no_advertise = 0;
6813   u8 off_link = 0;
6814   u8 no_autoconfig = 0;
6815   u8 no_onlink = 0;
6816   u8 is_no = 0;
6817   u32 val_lifetime = 0;
6818   u32 pref_lifetime = 0;
6819
6820   /* Parse args required to build the message */
6821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6822     {
6823       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6824         sw_if_index_set = 1;
6825       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6826         sw_if_index_set = 1;
6827       else if (unformat (i, "%U/%d",
6828                          unformat_ip6_address, &v6address, &address_length))
6829         v6_address_set = 1;
6830       else if (unformat (i, "val_life %d", &val_lifetime))
6831         ;
6832       else if (unformat (i, "pref_life %d", &pref_lifetime))
6833         ;
6834       else if (unformat (i, "def"))
6835         use_default = 1;
6836       else if (unformat (i, "noadv"))
6837         no_advertise = 1;
6838       else if (unformat (i, "offl"))
6839         off_link = 1;
6840       else if (unformat (i, "noauto"))
6841         no_autoconfig = 1;
6842       else if (unformat (i, "nolink"))
6843         no_onlink = 1;
6844       else if (unformat (i, "isno"))
6845         is_no = 1;
6846       else
6847         {
6848           clib_warning ("parse error '%U'", format_unformat_error, i);
6849           return -99;
6850         }
6851     }
6852
6853   if (sw_if_index_set == 0)
6854     {
6855       errmsg ("missing interface name or sw_if_index\n");
6856       return -99;
6857     }
6858   if (!v6_address_set)
6859     {
6860       errmsg ("no address set\n");
6861       return -99;
6862     }
6863
6864   /* Construct the API message */
6865   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6866
6867   mp->sw_if_index = ntohl (sw_if_index);
6868   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6869   mp->address_length = address_length;
6870   mp->use_default = use_default;
6871   mp->no_advertise = no_advertise;
6872   mp->off_link = off_link;
6873   mp->no_autoconfig = no_autoconfig;
6874   mp->no_onlink = no_onlink;
6875   mp->is_no = is_no;
6876   mp->val_lifetime = ntohl (val_lifetime);
6877   mp->pref_lifetime = ntohl (pref_lifetime);
6878
6879   /* send it... */
6880   S;
6881
6882   /* Wait for a reply, return good/bad news  */
6883   W;
6884
6885   /* NOTREACHED */
6886   return 0;
6887 }
6888
6889 static int
6890 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
6891 {
6892   unformat_input_t *i = vam->input;
6893   vl_api_sw_interface_ip6nd_ra_config_t *mp;
6894   f64 timeout;
6895   u32 sw_if_index;
6896   u8 sw_if_index_set = 0;
6897   u8 suppress = 0;
6898   u8 managed = 0;
6899   u8 other = 0;
6900   u8 ll_option = 0;
6901   u8 send_unicast = 0;
6902   u8 cease = 0;
6903   u8 is_no = 0;
6904   u8 default_router = 0;
6905   u32 max_interval = 0;
6906   u32 min_interval = 0;
6907   u32 lifetime = 0;
6908   u32 initial_count = 0;
6909   u32 initial_interval = 0;
6910
6911
6912   /* Parse args required to build the message */
6913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6914     {
6915       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6916         sw_if_index_set = 1;
6917       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6918         sw_if_index_set = 1;
6919       else if (unformat (i, "maxint %d", &max_interval))
6920         ;
6921       else if (unformat (i, "minint %d", &min_interval))
6922         ;
6923       else if (unformat (i, "life %d", &lifetime))
6924         ;
6925       else if (unformat (i, "count %d", &initial_count))
6926         ;
6927       else if (unformat (i, "interval %d", &initial_interval))
6928         ;
6929       else if (unformat (i, "suppress") || unformat (i, "surpress"))
6930         suppress = 1;
6931       else if (unformat (i, "managed"))
6932         managed = 1;
6933       else if (unformat (i, "other"))
6934         other = 1;
6935       else if (unformat (i, "ll"))
6936         ll_option = 1;
6937       else if (unformat (i, "send"))
6938         send_unicast = 1;
6939       else if (unformat (i, "cease"))
6940         cease = 1;
6941       else if (unformat (i, "isno"))
6942         is_no = 1;
6943       else if (unformat (i, "def"))
6944         default_router = 1;
6945       else
6946         {
6947           clib_warning ("parse error '%U'", format_unformat_error, i);
6948           return -99;
6949         }
6950     }
6951
6952   if (sw_if_index_set == 0)
6953     {
6954       errmsg ("missing interface name or sw_if_index\n");
6955       return -99;
6956     }
6957
6958   /* Construct the API message */
6959   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
6960
6961   mp->sw_if_index = ntohl (sw_if_index);
6962   mp->max_interval = ntohl (max_interval);
6963   mp->min_interval = ntohl (min_interval);
6964   mp->lifetime = ntohl (lifetime);
6965   mp->initial_count = ntohl (initial_count);
6966   mp->initial_interval = ntohl (initial_interval);
6967   mp->suppress = suppress;
6968   mp->managed = managed;
6969   mp->other = other;
6970   mp->ll_option = ll_option;
6971   mp->send_unicast = send_unicast;
6972   mp->cease = cease;
6973   mp->is_no = is_no;
6974   mp->default_router = default_router;
6975
6976   /* send it... */
6977   S;
6978
6979   /* Wait for a reply, return good/bad news  */
6980   W;
6981
6982   /* NOTREACHED */
6983   return 0;
6984 }
6985
6986 static int
6987 api_set_arp_neighbor_limit (vat_main_t * vam)
6988 {
6989   unformat_input_t *i = vam->input;
6990   vl_api_set_arp_neighbor_limit_t *mp;
6991   f64 timeout;
6992   u32 arp_nbr_limit;
6993   u8 limit_set = 0;
6994   u8 is_ipv6 = 0;
6995
6996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6997     {
6998       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
6999         limit_set = 1;
7000       else if (unformat (i, "ipv6"))
7001         is_ipv6 = 1;
7002       else
7003         {
7004           clib_warning ("parse error '%U'", format_unformat_error, i);
7005           return -99;
7006         }
7007     }
7008
7009   if (limit_set == 0)
7010     {
7011       errmsg ("missing limit value\n");
7012       return -99;
7013     }
7014
7015   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7016
7017   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7018   mp->is_ipv6 = is_ipv6;
7019
7020   S;
7021   W;
7022   /* NOTREACHED */
7023   return 0;
7024 }
7025
7026 static int
7027 api_l2_patch_add_del (vat_main_t * vam)
7028 {
7029   unformat_input_t *i = vam->input;
7030   vl_api_l2_patch_add_del_t *mp;
7031   f64 timeout;
7032   u32 rx_sw_if_index;
7033   u8 rx_sw_if_index_set = 0;
7034   u32 tx_sw_if_index;
7035   u8 tx_sw_if_index_set = 0;
7036   u8 is_add = 1;
7037
7038   /* Parse args required to build the message */
7039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7040     {
7041       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7042         rx_sw_if_index_set = 1;
7043       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7044         tx_sw_if_index_set = 1;
7045       else if (unformat (i, "rx"))
7046         {
7047           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7048             {
7049               if (unformat (i, "%U", unformat_sw_if_index, vam,
7050                             &rx_sw_if_index))
7051                 rx_sw_if_index_set = 1;
7052             }
7053           else
7054             break;
7055         }
7056       else if (unformat (i, "tx"))
7057         {
7058           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7059             {
7060               if (unformat (i, "%U", unformat_sw_if_index, vam,
7061                             &tx_sw_if_index))
7062                 tx_sw_if_index_set = 1;
7063             }
7064           else
7065             break;
7066         }
7067       else if (unformat (i, "del"))
7068         is_add = 0;
7069       else
7070         break;
7071     }
7072
7073   if (rx_sw_if_index_set == 0)
7074     {
7075       errmsg ("missing rx interface name or rx_sw_if_index\n");
7076       return -99;
7077     }
7078
7079   if (tx_sw_if_index_set == 0)
7080     {
7081       errmsg ("missing tx interface name or tx_sw_if_index\n");
7082       return -99;
7083     }
7084
7085   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7086
7087   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7088   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7089   mp->is_add = is_add;
7090
7091   S;
7092   W;
7093   /* NOTREACHED */
7094   return 0;
7095 }
7096
7097 static int
7098 api_trace_profile_add (vat_main_t * vam)
7099 {
7100   unformat_input_t *input = vam->input;
7101   vl_api_trace_profile_add_t *mp;
7102   f64 timeout;
7103   u32 id = 0;
7104   u32 trace_option_elts = 0;
7105   u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
7106   int has_pow_option = 0;
7107   int has_ppc_option = 0;
7108
7109   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7110     {
7111       if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
7112                     "trace-tsp %d node-id 0x%x app-data 0x%x",
7113                     &id, &trace_type, &trace_option_elts, &trace_tsp,
7114                     &node_id, &app_data))
7115         ;
7116       else if (unformat (input, "pow"))
7117         has_pow_option = 1;
7118       else if (unformat (input, "ppc encap"))
7119         has_ppc_option = PPC_ENCAP;
7120       else if (unformat (input, "ppc decap"))
7121         has_ppc_option = PPC_DECAP;
7122       else if (unformat (input, "ppc none"))
7123         has_ppc_option = PPC_NONE;
7124       else
7125         break;
7126     }
7127   M (TRACE_PROFILE_ADD, trace_profile_add);
7128   mp->id = htons (id);
7129   mp->trace_type = trace_type;
7130   mp->trace_num_elt = trace_option_elts;
7131   mp->trace_ppc = has_ppc_option;
7132   mp->trace_app_data = htonl (app_data);
7133   mp->pow_enable = has_pow_option;
7134   mp->trace_tsp = trace_tsp;
7135   mp->node_id = htonl (node_id);
7136
7137   S;
7138   W;
7139
7140   return (0);
7141
7142 }
7143
7144 static int
7145 api_trace_profile_apply (vat_main_t * vam)
7146 {
7147   unformat_input_t *input = vam->input;
7148   vl_api_trace_profile_apply_t *mp;
7149   f64 timeout;
7150   ip6_address_t addr;
7151   u32 mask_width = ~0;
7152   int is_add = 0;
7153   int is_pop = 0;
7154   int is_none = 0;
7155   u32 vrf_id = 0;
7156   u32 id = 0;
7157
7158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7159     {
7160       if (unformat (input, "%U/%d", unformat_ip6_address, &addr, &mask_width))
7161         ;
7162       else if (unformat (input, "id %d", &id))
7163         ;
7164       else if (unformat (input, "vrf-id %d", &vrf_id))
7165         ;
7166       else if (unformat (input, "add"))
7167         is_add = 1;
7168       else if (unformat (input, "pop"))
7169         is_pop = 1;
7170       else if (unformat (input, "none"))
7171         is_none = 1;
7172       else
7173         break;
7174     }
7175
7176   if ((is_add + is_pop + is_none) != 1)
7177     {
7178       errmsg ("One of (add, pop, none) required");
7179       return -99;
7180     }
7181   if (mask_width == ~0)
7182     {
7183       errmsg ("<address>/<mask-width> required");
7184       return -99;
7185     }
7186   M (TRACE_PROFILE_APPLY, trace_profile_apply);
7187   clib_memcpy (mp->dest_ipv6, &addr, sizeof (mp->dest_ipv6));
7188   mp->id = htons (id);
7189   mp->prefix_length = htonl (mask_width);
7190   mp->vrf_id = htonl (vrf_id);
7191   if (is_add)
7192     mp->trace_op = IOAM_HBYH_ADD;
7193   else if (is_pop)
7194     mp->trace_op = IOAM_HBYH_POP;
7195   else
7196     mp->trace_op = IOAM_HBYH_MOD;
7197
7198   if (is_none)
7199     mp->enable = 0;
7200   else
7201     mp->enable = 1;
7202
7203   S;
7204   W;
7205
7206   return 0;
7207 }
7208
7209 static int
7210 api_trace_profile_del (vat_main_t * vam)
7211 {
7212   vl_api_trace_profile_del_t *mp;
7213   f64 timeout;
7214
7215   M (TRACE_PROFILE_DEL, trace_profile_del);
7216   S;
7217   W;
7218   return 0;
7219 }
7220
7221 static int
7222 api_sr_tunnel_add_del (vat_main_t * vam)
7223 {
7224   unformat_input_t *i = vam->input;
7225   vl_api_sr_tunnel_add_del_t *mp;
7226   f64 timeout;
7227   int is_del = 0;
7228   int pl_index;
7229   ip6_address_t src_address;
7230   int src_address_set = 0;
7231   ip6_address_t dst_address;
7232   u32 dst_mask_width;
7233   int dst_address_set = 0;
7234   u16 flags = 0;
7235   u32 rx_table_id = 0;
7236   u32 tx_table_id = 0;
7237   ip6_address_t *segments = 0;
7238   ip6_address_t *this_seg;
7239   ip6_address_t *tags = 0;
7240   ip6_address_t *this_tag;
7241   ip6_address_t next_address, tag;
7242   u8 *name = 0;
7243   u8 *policy_name = 0;
7244
7245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7246     {
7247       if (unformat (i, "del"))
7248         is_del = 1;
7249       else if (unformat (i, "name %s", &name))
7250         ;
7251       else if (unformat (i, "policy %s", &policy_name))
7252         ;
7253       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7254         ;
7255       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7256         ;
7257       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7258         src_address_set = 1;
7259       else if (unformat (i, "dst %U/%d",
7260                          unformat_ip6_address, &dst_address, &dst_mask_width))
7261         dst_address_set = 1;
7262       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7263         {
7264           vec_add2 (segments, this_seg, 1);
7265           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7266                        sizeof (*this_seg));
7267         }
7268       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7269         {
7270           vec_add2 (tags, this_tag, 1);
7271           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7272         }
7273       else if (unformat (i, "clean"))
7274         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7275       else if (unformat (i, "protected"))
7276         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7277       else if (unformat (i, "InPE %d", &pl_index))
7278         {
7279           if (pl_index <= 0 || pl_index > 4)
7280             {
7281             pl_index_range_error:
7282               errmsg ("pl index %d out of range\n", pl_index);
7283               return -99;
7284             }
7285           flags |=
7286             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7287         }
7288       else if (unformat (i, "EgPE %d", &pl_index))
7289         {
7290           if (pl_index <= 0 || pl_index > 4)
7291             goto pl_index_range_error;
7292           flags |=
7293             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7294         }
7295       else if (unformat (i, "OrgSrc %d", &pl_index))
7296         {
7297           if (pl_index <= 0 || pl_index > 4)
7298             goto pl_index_range_error;
7299           flags |=
7300             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7301         }
7302       else
7303         break;
7304     }
7305
7306   if (!src_address_set)
7307     {
7308       errmsg ("src address required\n");
7309       return -99;
7310     }
7311
7312   if (!dst_address_set)
7313     {
7314       errmsg ("dst address required\n");
7315       return -99;
7316     }
7317
7318   if (!segments)
7319     {
7320       errmsg ("at least one sr segment required\n");
7321       return -99;
7322     }
7323
7324   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7325       vec_len (segments) * sizeof (ip6_address_t)
7326       + vec_len (tags) * sizeof (ip6_address_t));
7327
7328   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7329   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7330   mp->dst_mask_width = dst_mask_width;
7331   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7332   mp->n_segments = vec_len (segments);
7333   mp->n_tags = vec_len (tags);
7334   mp->is_add = is_del == 0;
7335   clib_memcpy (mp->segs_and_tags, segments,
7336                vec_len (segments) * sizeof (ip6_address_t));
7337   clib_memcpy (mp->segs_and_tags +
7338                vec_len (segments) * sizeof (ip6_address_t), tags,
7339                vec_len (tags) * sizeof (ip6_address_t));
7340
7341   mp->outer_vrf_id = ntohl (rx_table_id);
7342   mp->inner_vrf_id = ntohl (tx_table_id);
7343   memcpy (mp->name, name, vec_len (name));
7344   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7345
7346   vec_free (segments);
7347   vec_free (tags);
7348
7349   S;
7350   W;
7351   /* NOTREACHED */
7352 }
7353
7354 static int
7355 api_sr_policy_add_del (vat_main_t * vam)
7356 {
7357   unformat_input_t *input = vam->input;
7358   vl_api_sr_policy_add_del_t *mp;
7359   f64 timeout;
7360   int is_del = 0;
7361   u8 *name = 0;
7362   u8 *tunnel_name = 0;
7363   u8 **tunnel_names = 0;
7364
7365   int name_set = 0;
7366   int tunnel_set = 0;
7367   int j = 0;
7368   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7369   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7370
7371   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7372     {
7373       if (unformat (input, "del"))
7374         is_del = 1;
7375       else if (unformat (input, "name %s", &name))
7376         name_set = 1;
7377       else if (unformat (input, "tunnel %s", &tunnel_name))
7378         {
7379           if (tunnel_name)
7380             {
7381               vec_add1 (tunnel_names, tunnel_name);
7382               /* For serializer:
7383                  - length = #bytes to store in serial vector
7384                  - +1 = byte to store that length
7385                */
7386               tunnel_names_length += (vec_len (tunnel_name) + 1);
7387               tunnel_set = 1;
7388               tunnel_name = 0;
7389             }
7390         }
7391       else
7392         break;
7393     }
7394
7395   if (!name_set)
7396     {
7397       errmsg ("policy name required\n");
7398       return -99;
7399     }
7400
7401   if ((!tunnel_set) && (!is_del))
7402     {
7403       errmsg ("tunnel name required\n");
7404       return -99;
7405     }
7406
7407   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7408
7409
7410
7411   mp->is_add = !is_del;
7412
7413   memcpy (mp->name, name, vec_len (name));
7414   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7415   u8 *serial_orig = 0;
7416   vec_validate (serial_orig, tunnel_names_length);
7417   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7418   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7419
7420   for (j = 0; j < vec_len (tunnel_names); j++)
7421     {
7422       tun_name_len = vec_len (tunnel_names[j]);
7423       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7424       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7425       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7426       serial_orig += tun_name_len;      // Advance past the copy
7427     }
7428   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7429
7430   vec_free (tunnel_names);
7431   vec_free (tunnel_name);
7432
7433   S;
7434   W;
7435   /* NOTREACHED */
7436 }
7437
7438 static int
7439 api_sr_multicast_map_add_del (vat_main_t * vam)
7440 {
7441   unformat_input_t *input = vam->input;
7442   vl_api_sr_multicast_map_add_del_t *mp;
7443   f64 timeout;
7444   int is_del = 0;
7445   ip6_address_t multicast_address;
7446   u8 *policy_name = 0;
7447   int multicast_address_set = 0;
7448
7449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7450     {
7451       if (unformat (input, "del"))
7452         is_del = 1;
7453       else
7454         if (unformat
7455             (input, "address %U", unformat_ip6_address, &multicast_address))
7456         multicast_address_set = 1;
7457       else if (unformat (input, "sr-policy %s", &policy_name))
7458         ;
7459       else
7460         break;
7461     }
7462
7463   if (!is_del && !policy_name)
7464     {
7465       errmsg ("sr-policy name required\n");
7466       return -99;
7467     }
7468
7469
7470   if (!multicast_address_set)
7471     {
7472       errmsg ("address required\n");
7473       return -99;
7474     }
7475
7476   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7477
7478   mp->is_add = !is_del;
7479   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7480   clib_memcpy (mp->multicast_address, &multicast_address,
7481                sizeof (mp->multicast_address));
7482
7483
7484   vec_free (policy_name);
7485
7486   S;
7487   W;
7488   /* NOTREACHED */
7489 }
7490
7491
7492 #define foreach_ip4_proto_field                 \
7493 _(src_address)                                  \
7494 _(dst_address)                                  \
7495 _(tos)                                          \
7496 _(length)                                       \
7497 _(fragment_id)                                  \
7498 _(ttl)                                          \
7499 _(protocol)                                     \
7500 _(checksum)
7501
7502 uword
7503 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7504 {
7505   u8 **maskp = va_arg (*args, u8 **);
7506   u8 *mask = 0;
7507   u8 found_something = 0;
7508   ip4_header_t *ip;
7509
7510 #define _(a) u8 a=0;
7511   foreach_ip4_proto_field;
7512 #undef _
7513   u8 version = 0;
7514   u8 hdr_length = 0;
7515
7516
7517   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7518     {
7519       if (unformat (input, "version"))
7520         version = 1;
7521       else if (unformat (input, "hdr_length"))
7522         hdr_length = 1;
7523       else if (unformat (input, "src"))
7524         src_address = 1;
7525       else if (unformat (input, "dst"))
7526         dst_address = 1;
7527       else if (unformat (input, "proto"))
7528         protocol = 1;
7529
7530 #define _(a) else if (unformat (input, #a)) a=1;
7531       foreach_ip4_proto_field
7532 #undef _
7533         else
7534         break;
7535     }
7536
7537 #define _(a) found_something += a;
7538   foreach_ip4_proto_field;
7539 #undef _
7540
7541   if (found_something == 0)
7542     return 0;
7543
7544   vec_validate (mask, sizeof (*ip) - 1);
7545
7546   ip = (ip4_header_t *) mask;
7547
7548 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7549   foreach_ip4_proto_field;
7550 #undef _
7551
7552   ip->ip_version_and_header_length = 0;
7553
7554   if (version)
7555     ip->ip_version_and_header_length |= 0xF0;
7556
7557   if (hdr_length)
7558     ip->ip_version_and_header_length |= 0x0F;
7559
7560   *maskp = mask;
7561   return 1;
7562 }
7563
7564 #define foreach_ip6_proto_field                 \
7565 _(src_address)                                  \
7566 _(dst_address)                                  \
7567 _(payload_length)                               \
7568 _(hop_limit)                                    \
7569 _(protocol)
7570
7571 uword
7572 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7573 {
7574   u8 **maskp = va_arg (*args, u8 **);
7575   u8 *mask = 0;
7576   u8 found_something = 0;
7577   ip6_header_t *ip;
7578   u32 ip_version_traffic_class_and_flow_label;
7579
7580 #define _(a) u8 a=0;
7581   foreach_ip6_proto_field;
7582 #undef _
7583   u8 version = 0;
7584   u8 traffic_class = 0;
7585   u8 flow_label = 0;
7586
7587   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7588     {
7589       if (unformat (input, "version"))
7590         version = 1;
7591       else if (unformat (input, "traffic-class"))
7592         traffic_class = 1;
7593       else if (unformat (input, "flow-label"))
7594         flow_label = 1;
7595       else if (unformat (input, "src"))
7596         src_address = 1;
7597       else if (unformat (input, "dst"))
7598         dst_address = 1;
7599       else if (unformat (input, "proto"))
7600         protocol = 1;
7601
7602 #define _(a) else if (unformat (input, #a)) a=1;
7603       foreach_ip6_proto_field
7604 #undef _
7605         else
7606         break;
7607     }
7608
7609 #define _(a) found_something += a;
7610   foreach_ip6_proto_field;
7611 #undef _
7612
7613   if (found_something == 0)
7614     return 0;
7615
7616   vec_validate (mask, sizeof (*ip) - 1);
7617
7618   ip = (ip6_header_t *) mask;
7619
7620 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7621   foreach_ip6_proto_field;
7622 #undef _
7623
7624   ip_version_traffic_class_and_flow_label = 0;
7625
7626   if (version)
7627     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7628
7629   if (traffic_class)
7630     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7631
7632   if (flow_label)
7633     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7634
7635   ip->ip_version_traffic_class_and_flow_label =
7636     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7637
7638   *maskp = mask;
7639   return 1;
7640 }
7641
7642 uword
7643 unformat_l3_mask (unformat_input_t * input, va_list * args)
7644 {
7645   u8 **maskp = va_arg (*args, u8 **);
7646
7647   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7648     {
7649       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7650         return 1;
7651       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7652         return 1;
7653       else
7654         break;
7655     }
7656   return 0;
7657 }
7658
7659 uword
7660 unformat_l2_mask (unformat_input_t * input, va_list * args)
7661 {
7662   u8 **maskp = va_arg (*args, u8 **);
7663   u8 *mask = 0;
7664   u8 src = 0;
7665   u8 dst = 0;
7666   u8 proto = 0;
7667   u8 tag1 = 0;
7668   u8 tag2 = 0;
7669   u8 ignore_tag1 = 0;
7670   u8 ignore_tag2 = 0;
7671   u8 cos1 = 0;
7672   u8 cos2 = 0;
7673   u8 dot1q = 0;
7674   u8 dot1ad = 0;
7675   int len = 14;
7676
7677   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7678     {
7679       if (unformat (input, "src"))
7680         src = 1;
7681       else if (unformat (input, "dst"))
7682         dst = 1;
7683       else if (unformat (input, "proto"))
7684         proto = 1;
7685       else if (unformat (input, "tag1"))
7686         tag1 = 1;
7687       else if (unformat (input, "tag2"))
7688         tag2 = 1;
7689       else if (unformat (input, "ignore-tag1"))
7690         ignore_tag1 = 1;
7691       else if (unformat (input, "ignore-tag2"))
7692         ignore_tag2 = 1;
7693       else if (unformat (input, "cos1"))
7694         cos1 = 1;
7695       else if (unformat (input, "cos2"))
7696         cos2 = 1;
7697       else if (unformat (input, "dot1q"))
7698         dot1q = 1;
7699       else if (unformat (input, "dot1ad"))
7700         dot1ad = 1;
7701       else
7702         break;
7703     }
7704   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7705        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7706     return 0;
7707
7708   if (tag1 || ignore_tag1 || cos1 || dot1q)
7709     len = 18;
7710   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7711     len = 22;
7712
7713   vec_validate (mask, len - 1);
7714
7715   if (dst)
7716     memset (mask, 0xff, 6);
7717
7718   if (src)
7719     memset (mask + 6, 0xff, 6);
7720
7721   if (tag2 || dot1ad)
7722     {
7723       /* inner vlan tag */
7724       if (tag2)
7725         {
7726           mask[19] = 0xff;
7727           mask[18] = 0x0f;
7728         }
7729       if (cos2)
7730         mask[18] |= 0xe0;
7731       if (proto)
7732         mask[21] = mask[20] = 0xff;
7733       if (tag1)
7734         {
7735           mask[15] = 0xff;
7736           mask[14] = 0x0f;
7737         }
7738       if (cos1)
7739         mask[14] |= 0xe0;
7740       *maskp = mask;
7741       return 1;
7742     }
7743   if (tag1 | dot1q)
7744     {
7745       if (tag1)
7746         {
7747           mask[15] = 0xff;
7748           mask[14] = 0x0f;
7749         }
7750       if (cos1)
7751         mask[14] |= 0xe0;
7752       if (proto)
7753         mask[16] = mask[17] = 0xff;
7754
7755       *maskp = mask;
7756       return 1;
7757     }
7758   if (cos2)
7759     mask[18] |= 0xe0;
7760   if (cos1)
7761     mask[14] |= 0xe0;
7762   if (proto)
7763     mask[12] = mask[13] = 0xff;
7764
7765   *maskp = mask;
7766   return 1;
7767 }
7768
7769 uword
7770 unformat_classify_mask (unformat_input_t * input, va_list * args)
7771 {
7772   u8 **maskp = va_arg (*args, u8 **);
7773   u32 *skipp = va_arg (*args, u32 *);
7774   u32 *matchp = va_arg (*args, u32 *);
7775   u32 match;
7776   u8 *mask = 0;
7777   u8 *l2 = 0;
7778   u8 *l3 = 0;
7779   int i;
7780
7781   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7782     {
7783       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7784         ;
7785       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7786         ;
7787       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7788         ;
7789       else
7790         break;
7791     }
7792
7793   if (mask || l2 || l3)
7794     {
7795       if (l2 || l3)
7796         {
7797           /* "With a free Ethernet header in every package" */
7798           if (l2 == 0)
7799             vec_validate (l2, 13);
7800           mask = l2;
7801           if (vec_len (l3))
7802             {
7803               vec_append (mask, l3);
7804               vec_free (l3);
7805             }
7806         }
7807
7808       /* Scan forward looking for the first significant mask octet */
7809       for (i = 0; i < vec_len (mask); i++)
7810         if (mask[i])
7811           break;
7812
7813       /* compute (skip, match) params */
7814       *skipp = i / sizeof (u32x4);
7815       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7816
7817       /* Pad mask to an even multiple of the vector size */
7818       while (vec_len (mask) % sizeof (u32x4))
7819         vec_add1 (mask, 0);
7820
7821       match = vec_len (mask) / sizeof (u32x4);
7822
7823       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7824         {
7825           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7826           if (*tmp || *(tmp + 1))
7827             break;
7828           match--;
7829         }
7830       if (match == 0)
7831         clib_warning ("BUG: match 0");
7832
7833       _vec_len (mask) = match * sizeof (u32x4);
7834
7835       *matchp = match;
7836       *maskp = mask;
7837
7838       return 1;
7839     }
7840
7841   return 0;
7842 }
7843
7844 #define foreach_l2_next                         \
7845 _(drop, DROP)                                   \
7846 _(ethernet, ETHERNET_INPUT)                     \
7847 _(ip4, IP4_INPUT)                               \
7848 _(ip6, IP6_INPUT)
7849
7850 uword
7851 unformat_l2_next_index (unformat_input_t * input, va_list * args)
7852 {
7853   u32 *miss_next_indexp = va_arg (*args, u32 *);
7854   u32 next_index = 0;
7855   u32 tmp;
7856
7857 #define _(n,N) \
7858   if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
7859   foreach_l2_next;
7860 #undef _
7861
7862   if (unformat (input, "%d", &tmp))
7863     {
7864       next_index = tmp;
7865       goto out;
7866     }
7867
7868   return 0;
7869
7870 out:
7871   *miss_next_indexp = next_index;
7872   return 1;
7873 }
7874
7875 #define foreach_ip_next                         \
7876 _(miss, MISS)                                   \
7877 _(drop, DROP)                                   \
7878 _(local, LOCAL)                                 \
7879 _(rewrite, REWRITE)
7880
7881 uword
7882 unformat_ip_next_index (unformat_input_t * input, va_list * args)
7883 {
7884   u32 *miss_next_indexp = va_arg (*args, u32 *);
7885   u32 next_index = 0;
7886   u32 tmp;
7887
7888 #define _(n,N) \
7889   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7890   foreach_ip_next;
7891 #undef _
7892
7893   if (unformat (input, "%d", &tmp))
7894     {
7895       next_index = tmp;
7896       goto out;
7897     }
7898
7899   return 0;
7900
7901 out:
7902   *miss_next_indexp = next_index;
7903   return 1;
7904 }
7905
7906 #define foreach_acl_next                        \
7907 _(deny, DENY)
7908
7909 uword
7910 unformat_acl_next_index (unformat_input_t * input, va_list * args)
7911 {
7912   u32 *miss_next_indexp = va_arg (*args, u32 *);
7913   u32 next_index = 0;
7914   u32 tmp;
7915
7916 #define _(n,N) \
7917   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7918   foreach_acl_next;
7919 #undef _
7920
7921   if (unformat (input, "permit"))
7922     {
7923       next_index = ~0;
7924       goto out;
7925     }
7926   else if (unformat (input, "%d", &tmp))
7927     {
7928       next_index = tmp;
7929       goto out;
7930     }
7931
7932   return 0;
7933
7934 out:
7935   *miss_next_indexp = next_index;
7936   return 1;
7937 }
7938
7939 uword
7940 unformat_policer_precolor (unformat_input_t * input, va_list * args)
7941 {
7942   u32 *r = va_arg (*args, u32 *);
7943
7944   if (unformat (input, "conform-color"))
7945     *r = POLICE_CONFORM;
7946   else if (unformat (input, "exceed-color"))
7947     *r = POLICE_EXCEED;
7948   else
7949     return 0;
7950
7951   return 1;
7952 }
7953
7954 static int
7955 api_classify_add_del_table (vat_main_t * vam)
7956 {
7957   unformat_input_t *i = vam->input;
7958   vl_api_classify_add_del_table_t *mp;
7959
7960   u32 nbuckets = 2;
7961   u32 skip = ~0;
7962   u32 match = ~0;
7963   int is_add = 1;
7964   u32 table_index = ~0;
7965   u32 next_table_index = ~0;
7966   u32 miss_next_index = ~0;
7967   u32 memory_size = 32 << 20;
7968   u8 *mask = 0;
7969   f64 timeout;
7970
7971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7972     {
7973       if (unformat (i, "del"))
7974         is_add = 0;
7975       else if (unformat (i, "buckets %d", &nbuckets))
7976         ;
7977       else if (unformat (i, "memory_size %d", &memory_size))
7978         ;
7979       else if (unformat (i, "skip %d", &skip))
7980         ;
7981       else if (unformat (i, "match %d", &match))
7982         ;
7983       else if (unformat (i, "table %d", &table_index))
7984         ;
7985       else if (unformat (i, "mask %U", unformat_classify_mask,
7986                          &mask, &skip, &match))
7987         ;
7988       else if (unformat (i, "next-table %d", &next_table_index))
7989         ;
7990       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
7991                          &miss_next_index))
7992         ;
7993       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
7994                          &miss_next_index))
7995         ;
7996       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
7997                          &miss_next_index))
7998         ;
7999       else
8000         break;
8001     }
8002
8003   if (is_add && mask == 0)
8004     {
8005       errmsg ("Mask required\n");
8006       return -99;
8007     }
8008
8009   if (is_add && skip == ~0)
8010     {
8011       errmsg ("skip count required\n");
8012       return -99;
8013     }
8014
8015   if (is_add && match == ~0)
8016     {
8017       errmsg ("match count required\n");
8018       return -99;
8019     }
8020
8021   if (!is_add && table_index == ~0)
8022     {
8023       errmsg ("table index required for delete\n");
8024       return -99;
8025     }
8026
8027   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8028
8029   mp->is_add = is_add;
8030   mp->table_index = ntohl (table_index);
8031   mp->nbuckets = ntohl (nbuckets);
8032   mp->memory_size = ntohl (memory_size);
8033   mp->skip_n_vectors = ntohl (skip);
8034   mp->match_n_vectors = ntohl (match);
8035   mp->next_table_index = ntohl (next_table_index);
8036   mp->miss_next_index = ntohl (miss_next_index);
8037   clib_memcpy (mp->mask, mask, vec_len (mask));
8038
8039   vec_free (mask);
8040
8041   S;
8042   W;
8043   /* NOTREACHED */
8044 }
8045
8046 uword
8047 unformat_ip4_match (unformat_input_t * input, va_list * args)
8048 {
8049   u8 **matchp = va_arg (*args, u8 **);
8050   u8 *match = 0;
8051   ip4_header_t *ip;
8052   int version = 0;
8053   u32 version_val;
8054   int hdr_length = 0;
8055   u32 hdr_length_val;
8056   int src = 0, dst = 0;
8057   ip4_address_t src_val, dst_val;
8058   int proto = 0;
8059   u32 proto_val;
8060   int tos = 0;
8061   u32 tos_val;
8062   int length = 0;
8063   u32 length_val;
8064   int fragment_id = 0;
8065   u32 fragment_id_val;
8066   int ttl = 0;
8067   int ttl_val;
8068   int checksum = 0;
8069   u32 checksum_val;
8070
8071   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8072     {
8073       if (unformat (input, "version %d", &version_val))
8074         version = 1;
8075       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8076         hdr_length = 1;
8077       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8078         src = 1;
8079       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8080         dst = 1;
8081       else if (unformat (input, "proto %d", &proto_val))
8082         proto = 1;
8083       else if (unformat (input, "tos %d", &tos_val))
8084         tos = 1;
8085       else if (unformat (input, "length %d", &length_val))
8086         length = 1;
8087       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8088         fragment_id = 1;
8089       else if (unformat (input, "ttl %d", &ttl_val))
8090         ttl = 1;
8091       else if (unformat (input, "checksum %d", &checksum_val))
8092         checksum = 1;
8093       else
8094         break;
8095     }
8096
8097   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8098       + ttl + checksum == 0)
8099     return 0;
8100
8101   /*
8102    * Aligned because we use the real comparison functions
8103    */
8104   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8105
8106   ip = (ip4_header_t *) match;
8107
8108   /* These are realistically matched in practice */
8109   if (src)
8110     ip->src_address.as_u32 = src_val.as_u32;
8111
8112   if (dst)
8113     ip->dst_address.as_u32 = dst_val.as_u32;
8114
8115   if (proto)
8116     ip->protocol = proto_val;
8117
8118
8119   /* These are not, but they're included for completeness */
8120   if (version)
8121     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8122
8123   if (hdr_length)
8124     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8125
8126   if (tos)
8127     ip->tos = tos_val;
8128
8129   if (length)
8130     ip->length = length_val;
8131
8132   if (ttl)
8133     ip->ttl = ttl_val;
8134
8135   if (checksum)
8136     ip->checksum = checksum_val;
8137
8138   *matchp = match;
8139   return 1;
8140 }
8141
8142 uword
8143 unformat_ip6_match (unformat_input_t * input, va_list * args)
8144 {
8145   u8 **matchp = va_arg (*args, u8 **);
8146   u8 *match = 0;
8147   ip6_header_t *ip;
8148   int version = 0;
8149   u32 version_val;
8150   u8 traffic_class = 0;
8151   u32 traffic_class_val = 0;
8152   u8 flow_label = 0;
8153   u8 flow_label_val;
8154   int src = 0, dst = 0;
8155   ip6_address_t src_val, dst_val;
8156   int proto = 0;
8157   u32 proto_val;
8158   int payload_length = 0;
8159   u32 payload_length_val;
8160   int hop_limit = 0;
8161   int hop_limit_val;
8162   u32 ip_version_traffic_class_and_flow_label;
8163
8164   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8165     {
8166       if (unformat (input, "version %d", &version_val))
8167         version = 1;
8168       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8169         traffic_class = 1;
8170       else if (unformat (input, "flow_label %d", &flow_label_val))
8171         flow_label = 1;
8172       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8173         src = 1;
8174       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8175         dst = 1;
8176       else if (unformat (input, "proto %d", &proto_val))
8177         proto = 1;
8178       else if (unformat (input, "payload_length %d", &payload_length_val))
8179         payload_length = 1;
8180       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8181         hop_limit = 1;
8182       else
8183         break;
8184     }
8185
8186   if (version + traffic_class + flow_label + src + dst + proto +
8187       payload_length + hop_limit == 0)
8188     return 0;
8189
8190   /*
8191    * Aligned because we use the real comparison functions
8192    */
8193   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8194
8195   ip = (ip6_header_t *) match;
8196
8197   if (src)
8198     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8199
8200   if (dst)
8201     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8202
8203   if (proto)
8204     ip->protocol = proto_val;
8205
8206   ip_version_traffic_class_and_flow_label = 0;
8207
8208   if (version)
8209     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8210
8211   if (traffic_class)
8212     ip_version_traffic_class_and_flow_label |=
8213       (traffic_class_val & 0xFF) << 20;
8214
8215   if (flow_label)
8216     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8217
8218   ip->ip_version_traffic_class_and_flow_label =
8219     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8220
8221   if (payload_length)
8222     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8223
8224   if (hop_limit)
8225     ip->hop_limit = hop_limit_val;
8226
8227   *matchp = match;
8228   return 1;
8229 }
8230
8231 uword
8232 unformat_l3_match (unformat_input_t * input, va_list * args)
8233 {
8234   u8 **matchp = va_arg (*args, u8 **);
8235
8236   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8237     {
8238       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8239         return 1;
8240       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8241         return 1;
8242       else
8243         break;
8244     }
8245   return 0;
8246 }
8247
8248 uword
8249 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8250 {
8251   u8 *tagp = va_arg (*args, u8 *);
8252   u32 tag;
8253
8254   if (unformat (input, "%d", &tag))
8255     {
8256       tagp[0] = (tag >> 8) & 0x0F;
8257       tagp[1] = tag & 0xFF;
8258       return 1;
8259     }
8260
8261   return 0;
8262 }
8263
8264 uword
8265 unformat_l2_match (unformat_input_t * input, va_list * args)
8266 {
8267   u8 **matchp = va_arg (*args, u8 **);
8268   u8 *match = 0;
8269   u8 src = 0;
8270   u8 src_val[6];
8271   u8 dst = 0;
8272   u8 dst_val[6];
8273   u8 proto = 0;
8274   u16 proto_val;
8275   u8 tag1 = 0;
8276   u8 tag1_val[2];
8277   u8 tag2 = 0;
8278   u8 tag2_val[2];
8279   int len = 14;
8280   u8 ignore_tag1 = 0;
8281   u8 ignore_tag2 = 0;
8282   u8 cos1 = 0;
8283   u8 cos2 = 0;
8284   u32 cos1_val = 0;
8285   u32 cos2_val = 0;
8286
8287   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8288     {
8289       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8290         src = 1;
8291       else
8292         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8293         dst = 1;
8294       else if (unformat (input, "proto %U",
8295                          unformat_ethernet_type_host_byte_order, &proto_val))
8296         proto = 1;
8297       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8298         tag1 = 1;
8299       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8300         tag2 = 1;
8301       else if (unformat (input, "ignore-tag1"))
8302         ignore_tag1 = 1;
8303       else if (unformat (input, "ignore-tag2"))
8304         ignore_tag2 = 1;
8305       else if (unformat (input, "cos1 %d", &cos1_val))
8306         cos1 = 1;
8307       else if (unformat (input, "cos2 %d", &cos2_val))
8308         cos2 = 1;
8309       else
8310         break;
8311     }
8312   if ((src + dst + proto + tag1 + tag2 +
8313        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8314     return 0;
8315
8316   if (tag1 || ignore_tag1 || cos1)
8317     len = 18;
8318   if (tag2 || ignore_tag2 || cos2)
8319     len = 22;
8320
8321   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8322
8323   if (dst)
8324     clib_memcpy (match, dst_val, 6);
8325
8326   if (src)
8327     clib_memcpy (match + 6, src_val, 6);
8328
8329   if (tag2)
8330     {
8331       /* inner vlan tag */
8332       match[19] = tag2_val[1];
8333       match[18] = tag2_val[0];
8334       if (cos2)
8335         match[18] |= (cos2_val & 0x7) << 5;
8336       if (proto)
8337         {
8338           match[21] = proto_val & 0xff;
8339           match[20] = proto_val >> 8;
8340         }
8341       if (tag1)
8342         {
8343           match[15] = tag1_val[1];
8344           match[14] = tag1_val[0];
8345         }
8346       if (cos1)
8347         match[14] |= (cos1_val & 0x7) << 5;
8348       *matchp = match;
8349       return 1;
8350     }
8351   if (tag1)
8352     {
8353       match[15] = tag1_val[1];
8354       match[14] = tag1_val[0];
8355       if (proto)
8356         {
8357           match[17] = proto_val & 0xff;
8358           match[16] = proto_val >> 8;
8359         }
8360       if (cos1)
8361         match[14] |= (cos1_val & 0x7) << 5;
8362
8363       *matchp = match;
8364       return 1;
8365     }
8366   if (cos2)
8367     match[18] |= (cos2_val & 0x7) << 5;
8368   if (cos1)
8369     match[14] |= (cos1_val & 0x7) << 5;
8370   if (proto)
8371     {
8372       match[13] = proto_val & 0xff;
8373       match[12] = proto_val >> 8;
8374     }
8375
8376   *matchp = match;
8377   return 1;
8378 }
8379
8380
8381 uword
8382 unformat_classify_match (unformat_input_t * input, va_list * args)
8383 {
8384   u8 **matchp = va_arg (*args, u8 **);
8385   u32 skip_n_vectors = va_arg (*args, u32);
8386   u32 match_n_vectors = va_arg (*args, u32);
8387
8388   u8 *match = 0;
8389   u8 *l2 = 0;
8390   u8 *l3 = 0;
8391
8392   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8393     {
8394       if (unformat (input, "hex %U", unformat_hex_string, &match))
8395         ;
8396       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8397         ;
8398       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8399         ;
8400       else
8401         break;
8402     }
8403
8404   if (match || l2 || l3)
8405     {
8406       if (l2 || l3)
8407         {
8408           /* "Win a free Ethernet header in every packet" */
8409           if (l2 == 0)
8410             vec_validate_aligned (l2, 13, sizeof (u32x4));
8411           match = l2;
8412           if (vec_len (l3))
8413             {
8414               vec_append_aligned (match, l3, sizeof (u32x4));
8415               vec_free (l3);
8416             }
8417         }
8418
8419       /* Make sure the vector is big enough even if key is all 0's */
8420       vec_validate_aligned
8421         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8422          sizeof (u32x4));
8423
8424       /* Set size, include skipped vectors */
8425       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8426
8427       *matchp = match;
8428
8429       return 1;
8430     }
8431
8432   return 0;
8433 }
8434
8435 static int
8436 api_classify_add_del_session (vat_main_t * vam)
8437 {
8438   unformat_input_t *i = vam->input;
8439   vl_api_classify_add_del_session_t *mp;
8440   int is_add = 1;
8441   u32 table_index = ~0;
8442   u32 hit_next_index = ~0;
8443   u32 opaque_index = ~0;
8444   u8 *match = 0;
8445   i32 advance = 0;
8446   f64 timeout;
8447   u32 skip_n_vectors = 0;
8448   u32 match_n_vectors = 0;
8449
8450   /*
8451    * Warning: you have to supply skip_n and match_n
8452    * because the API client cant simply look at the classify
8453    * table object.
8454    */
8455
8456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8457     {
8458       if (unformat (i, "del"))
8459         is_add = 0;
8460       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8461                          &hit_next_index))
8462         ;
8463       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8464                          &hit_next_index))
8465         ;
8466       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8467                          &hit_next_index))
8468         ;
8469       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8470         ;
8471       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8472         ;
8473       else if (unformat (i, "opaque-index %d", &opaque_index))
8474         ;
8475       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8476         ;
8477       else if (unformat (i, "match_n %d", &match_n_vectors))
8478         ;
8479       else if (unformat (i, "match %U", unformat_classify_match,
8480                          &match, skip_n_vectors, match_n_vectors))
8481         ;
8482       else if (unformat (i, "advance %d", &advance))
8483         ;
8484       else if (unformat (i, "table-index %d", &table_index))
8485         ;
8486       else
8487         break;
8488     }
8489
8490   if (table_index == ~0)
8491     {
8492       errmsg ("Table index required\n");
8493       return -99;
8494     }
8495
8496   if (is_add && match == 0)
8497     {
8498       errmsg ("Match value required\n");
8499       return -99;
8500     }
8501
8502   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8503
8504   mp->is_add = is_add;
8505   mp->table_index = ntohl (table_index);
8506   mp->hit_next_index = ntohl (hit_next_index);
8507   mp->opaque_index = ntohl (opaque_index);
8508   mp->advance = ntohl (advance);
8509   clib_memcpy (mp->match, match, vec_len (match));
8510   vec_free (match);
8511
8512   S;
8513   W;
8514   /* NOTREACHED */
8515 }
8516
8517 static int
8518 api_classify_set_interface_ip_table (vat_main_t * vam)
8519 {
8520   unformat_input_t *i = vam->input;
8521   vl_api_classify_set_interface_ip_table_t *mp;
8522   f64 timeout;
8523   u32 sw_if_index;
8524   int sw_if_index_set;
8525   u32 table_index = ~0;
8526   u8 is_ipv6 = 0;
8527
8528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8529     {
8530       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8531         sw_if_index_set = 1;
8532       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8533         sw_if_index_set = 1;
8534       else if (unformat (i, "table %d", &table_index))
8535         ;
8536       else
8537         {
8538           clib_warning ("parse error '%U'", format_unformat_error, i);
8539           return -99;
8540         }
8541     }
8542
8543   if (sw_if_index_set == 0)
8544     {
8545       errmsg ("missing interface name or sw_if_index\n");
8546       return -99;
8547     }
8548
8549
8550   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8551
8552   mp->sw_if_index = ntohl (sw_if_index);
8553   mp->table_index = ntohl (table_index);
8554   mp->is_ipv6 = is_ipv6;
8555
8556   S;
8557   W;
8558   /* NOTREACHED */
8559   return 0;
8560 }
8561
8562 static int
8563 api_classify_set_interface_l2_tables (vat_main_t * vam)
8564 {
8565   unformat_input_t *i = vam->input;
8566   vl_api_classify_set_interface_l2_tables_t *mp;
8567   f64 timeout;
8568   u32 sw_if_index;
8569   int sw_if_index_set;
8570   u32 ip4_table_index = ~0;
8571   u32 ip6_table_index = ~0;
8572   u32 other_table_index = ~0;
8573
8574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8575     {
8576       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8577         sw_if_index_set = 1;
8578       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8579         sw_if_index_set = 1;
8580       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8581         ;
8582       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8583         ;
8584       else if (unformat (i, "other-table %d", &other_table_index))
8585         ;
8586       else
8587         {
8588           clib_warning ("parse error '%U'", format_unformat_error, i);
8589           return -99;
8590         }
8591     }
8592
8593   if (sw_if_index_set == 0)
8594     {
8595       errmsg ("missing interface name or sw_if_index\n");
8596       return -99;
8597     }
8598
8599
8600   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8601
8602   mp->sw_if_index = ntohl (sw_if_index);
8603   mp->ip4_table_index = ntohl (ip4_table_index);
8604   mp->ip6_table_index = ntohl (ip6_table_index);
8605   mp->other_table_index = ntohl (other_table_index);
8606
8607
8608   S;
8609   W;
8610   /* NOTREACHED */
8611   return 0;
8612 }
8613
8614 static int
8615 api_ipfix_enable (vat_main_t * vam)
8616 {
8617   unformat_input_t *i = vam->input;
8618   vl_api_ipfix_enable_t *mp;
8619   ip4_address_t collector_address;
8620   u8 collector_address_set = 0;
8621   u32 collector_port = ~0;
8622   ip4_address_t src_address;
8623   u8 src_address_set = 0;
8624   u32 vrf_id = ~0;
8625   u32 path_mtu = ~0;
8626   u32 template_interval = ~0;
8627   f64 timeout;
8628
8629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8630     {
8631       if (unformat (i, "collector_address %U", unformat_ip4_address,
8632                     &collector_address))
8633         collector_address_set = 1;
8634       else if (unformat (i, "collector_port %d", &collector_port))
8635         ;
8636       else if (unformat (i, "src_address %U", unformat_ip4_address,
8637                          &src_address))
8638         src_address_set = 1;
8639       else if (unformat (i, "vrf_id %d", &vrf_id))
8640         ;
8641       else if (unformat (i, "path_mtu %d", &path_mtu))
8642         ;
8643       else if (unformat (i, "template_interval %d", &template_interval))
8644         ;
8645       else
8646         break;
8647     }
8648
8649   if (collector_address_set == 0)
8650     {
8651       errmsg ("collector_address required\n");
8652       return -99;
8653     }
8654
8655   if (src_address_set == 0)
8656     {
8657       errmsg ("src_address required\n");
8658       return -99;
8659     }
8660
8661   M (IPFIX_ENABLE, ipfix_enable);
8662
8663   memcpy (mp->collector_address, collector_address.data,
8664           sizeof (collector_address.data));
8665   mp->collector_port = htons ((u16) collector_port);
8666   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8667   mp->vrf_id = htonl (vrf_id);
8668   mp->path_mtu = htonl (path_mtu);
8669   mp->template_interval = htonl (template_interval);
8670
8671   S;
8672   W;
8673   /* NOTREACHED */
8674 }
8675
8676 static int
8677 api_get_node_index (vat_main_t * vam)
8678 {
8679   unformat_input_t *i = vam->input;
8680   vl_api_get_node_index_t *mp;
8681   f64 timeout;
8682   u8 *name = 0;
8683
8684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8685     {
8686       if (unformat (i, "node %s", &name))
8687         ;
8688       else
8689         break;
8690     }
8691   if (name == 0)
8692     {
8693       errmsg ("node name required\n");
8694       return -99;
8695     }
8696   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8697     {
8698       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8699       return -99;
8700     }
8701
8702   M (GET_NODE_INDEX, get_node_index);
8703   clib_memcpy (mp->node_name, name, vec_len (name));
8704   vec_free (name);
8705
8706   S;
8707   W;
8708   /* NOTREACHED */
8709   return 0;
8710 }
8711
8712 static int
8713 api_get_next_index (vat_main_t * vam)
8714 {
8715   unformat_input_t *i = vam->input;
8716   vl_api_get_next_index_t *mp;
8717   f64 timeout;
8718   u8 *node_name = 0, *next_node_name = 0;
8719
8720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8721     {
8722       if (unformat (i, "node-name %s", &node_name))
8723         ;
8724       else if (unformat (i, "next-node-name %s", &next_node_name))
8725         break;
8726     }
8727
8728   if (node_name == 0)
8729     {
8730       errmsg ("node name required\n");
8731       return -99;
8732     }
8733   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
8734     {
8735       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8736       return -99;
8737     }
8738
8739   if (next_node_name == 0)
8740     {
8741       errmsg ("next node name required\n");
8742       return -99;
8743     }
8744   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
8745     {
8746       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
8747       return -99;
8748     }
8749
8750   M (GET_NEXT_INDEX, get_next_index);
8751   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
8752   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
8753   vec_free (node_name);
8754   vec_free (next_node_name);
8755
8756   S;
8757   W;
8758   /* NOTREACHED */
8759   return 0;
8760 }
8761
8762 static int
8763 api_add_node_next (vat_main_t * vam)
8764 {
8765   unformat_input_t *i = vam->input;
8766   vl_api_add_node_next_t *mp;
8767   f64 timeout;
8768   u8 *name = 0;
8769   u8 *next = 0;
8770
8771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8772     {
8773       if (unformat (i, "node %s", &name))
8774         ;
8775       else if (unformat (i, "next %s", &next))
8776         ;
8777       else
8778         break;
8779     }
8780   if (name == 0)
8781     {
8782       errmsg ("node name required\n");
8783       return -99;
8784     }
8785   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8786     {
8787       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8788       return -99;
8789     }
8790   if (next == 0)
8791     {
8792       errmsg ("next node required\n");
8793       return -99;
8794     }
8795   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
8796     {
8797       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
8798       return -99;
8799     }
8800
8801   M (ADD_NODE_NEXT, add_node_next);
8802   clib_memcpy (mp->node_name, name, vec_len (name));
8803   clib_memcpy (mp->next_name, next, vec_len (next));
8804   vec_free (name);
8805   vec_free (next);
8806
8807   S;
8808   W;
8809   /* NOTREACHED */
8810   return 0;
8811 }
8812
8813 static int
8814 api_l2tpv3_create_tunnel (vat_main_t * vam)
8815 {
8816   unformat_input_t *i = vam->input;
8817   ip6_address_t client_address, our_address;
8818   int client_address_set = 0;
8819   int our_address_set = 0;
8820   u32 local_session_id = 0;
8821   u32 remote_session_id = 0;
8822   u64 local_cookie = 0;
8823   u64 remote_cookie = 0;
8824   u8 l2_sublayer_present = 0;
8825   vl_api_l2tpv3_create_tunnel_t *mp;
8826   f64 timeout;
8827
8828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8829     {
8830       if (unformat (i, "client_address %U", unformat_ip6_address,
8831                     &client_address))
8832         client_address_set = 1;
8833       else if (unformat (i, "our_address %U", unformat_ip6_address,
8834                          &our_address))
8835         our_address_set = 1;
8836       else if (unformat (i, "local_session_id %d", &local_session_id))
8837         ;
8838       else if (unformat (i, "remote_session_id %d", &remote_session_id))
8839         ;
8840       else if (unformat (i, "local_cookie %lld", &local_cookie))
8841         ;
8842       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8843         ;
8844       else if (unformat (i, "l2-sublayer-present"))
8845         l2_sublayer_present = 1;
8846       else
8847         break;
8848     }
8849
8850   if (client_address_set == 0)
8851     {
8852       errmsg ("client_address required\n");
8853       return -99;
8854     }
8855
8856   if (our_address_set == 0)
8857     {
8858       errmsg ("our_address required\n");
8859       return -99;
8860     }
8861
8862   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
8863
8864   clib_memcpy (mp->client_address, client_address.as_u8,
8865                sizeof (mp->client_address));
8866
8867   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
8868
8869   mp->local_session_id = ntohl (local_session_id);
8870   mp->remote_session_id = ntohl (remote_session_id);
8871   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
8872   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
8873   mp->l2_sublayer_present = l2_sublayer_present;
8874   mp->is_ipv6 = 1;
8875
8876   S;
8877   W;
8878   /* NOTREACHED */
8879   return 0;
8880 }
8881
8882 static int
8883 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
8884 {
8885   unformat_input_t *i = vam->input;
8886   u32 sw_if_index;
8887   u8 sw_if_index_set = 0;
8888   u64 new_local_cookie = 0;
8889   u64 new_remote_cookie = 0;
8890   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
8891   f64 timeout;
8892
8893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8894     {
8895       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8896         sw_if_index_set = 1;
8897       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8898         sw_if_index_set = 1;
8899       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
8900         ;
8901       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
8902         ;
8903       else
8904         break;
8905     }
8906
8907   if (sw_if_index_set == 0)
8908     {
8909       errmsg ("missing interface name or sw_if_index\n");
8910       return -99;
8911     }
8912
8913   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
8914
8915   mp->sw_if_index = ntohl (sw_if_index);
8916   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
8917   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
8918
8919   S;
8920   W;
8921   /* NOTREACHED */
8922   return 0;
8923 }
8924
8925 static int
8926 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
8927 {
8928   unformat_input_t *i = vam->input;
8929   vl_api_l2tpv3_interface_enable_disable_t *mp;
8930   f64 timeout;
8931   u32 sw_if_index;
8932   u8 sw_if_index_set = 0;
8933   u8 enable_disable = 1;
8934
8935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8936     {
8937       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8938         sw_if_index_set = 1;
8939       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8940         sw_if_index_set = 1;
8941       else if (unformat (i, "enable"))
8942         enable_disable = 1;
8943       else if (unformat (i, "disable"))
8944         enable_disable = 0;
8945       else
8946         break;
8947     }
8948
8949   if (sw_if_index_set == 0)
8950     {
8951       errmsg ("missing interface name or sw_if_index\n");
8952       return -99;
8953     }
8954
8955   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
8956
8957   mp->sw_if_index = ntohl (sw_if_index);
8958   mp->enable_disable = enable_disable;
8959
8960   S;
8961   W;
8962   /* NOTREACHED */
8963   return 0;
8964 }
8965
8966 static int
8967 api_l2tpv3_set_lookup_key (vat_main_t * vam)
8968 {
8969   unformat_input_t *i = vam->input;
8970   vl_api_l2tpv3_set_lookup_key_t *mp;
8971   f64 timeout;
8972   u8 key = ~0;
8973
8974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8975     {
8976       if (unformat (i, "lookup_v6_src"))
8977         key = L2T_LOOKUP_SRC_ADDRESS;
8978       else if (unformat (i, "lookup_v6_dst"))
8979         key = L2T_LOOKUP_DST_ADDRESS;
8980       else if (unformat (i, "lookup_session_id"))
8981         key = L2T_LOOKUP_SESSION_ID;
8982       else
8983         break;
8984     }
8985
8986   if (key == (u8) ~ 0)
8987     {
8988       errmsg ("l2tp session lookup key unset\n");
8989       return -99;
8990     }
8991
8992   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
8993
8994   mp->key = key;
8995
8996   S;
8997   W;
8998   /* NOTREACHED */
8999   return 0;
9000 }
9001
9002 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9003   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9004 {
9005   vat_main_t *vam = &vat_main;
9006
9007   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9008            format_ip6_address, mp->our_address,
9009            format_ip6_address, mp->client_address,
9010            clib_net_to_host_u32 (mp->sw_if_index));
9011
9012   fformat (vam->ofp,
9013            "   local cookies %016llx %016llx remote cookie %016llx\n",
9014            clib_net_to_host_u64 (mp->local_cookie[0]),
9015            clib_net_to_host_u64 (mp->local_cookie[1]),
9016            clib_net_to_host_u64 (mp->remote_cookie));
9017
9018   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9019            clib_net_to_host_u32 (mp->local_session_id),
9020            clib_net_to_host_u32 (mp->remote_session_id));
9021
9022   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9023            mp->l2_sublayer_present ? "preset" : "absent");
9024
9025 }
9026
9027 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9028   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9029 {
9030   vat_main_t *vam = &vat_main;
9031   vat_json_node_t *node = NULL;
9032   struct in6_addr addr;
9033
9034   if (VAT_JSON_ARRAY != vam->json_tree.type)
9035     {
9036       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9037       vat_json_init_array (&vam->json_tree);
9038     }
9039   node = vat_json_array_add (&vam->json_tree);
9040
9041   vat_json_init_object (node);
9042
9043   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9044   vat_json_object_add_ip6 (node, "our_address", addr);
9045   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9046   vat_json_object_add_ip6 (node, "client_address", addr);
9047
9048   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9049   vat_json_init_array (lc);
9050   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9051   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9052   vat_json_object_add_uint (node, "remote_cookie",
9053                             clib_net_to_host_u64 (mp->remote_cookie));
9054
9055   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9056   vat_json_object_add_uint (node, "local_session_id",
9057                             clib_net_to_host_u32 (mp->local_session_id));
9058   vat_json_object_add_uint (node, "remote_session_id",
9059                             clib_net_to_host_u32 (mp->remote_session_id));
9060   vat_json_object_add_string_copy (node, "l2_sublayer",
9061                                    mp->l2_sublayer_present ? (u8 *) "present"
9062                                    : (u8 *) "absent");
9063 }
9064
9065 static int
9066 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9067 {
9068   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9069   f64 timeout;
9070
9071   /* Get list of l2tpv3-tunnel interfaces */
9072   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9073   S;
9074
9075   /* Use a control ping for synchronization */
9076   {
9077     vl_api_control_ping_t *mp;
9078     M (CONTROL_PING, control_ping);
9079     S;
9080   }
9081   W;
9082 }
9083
9084
9085 static void vl_api_sw_interface_tap_details_t_handler
9086   (vl_api_sw_interface_tap_details_t * mp)
9087 {
9088   vat_main_t *vam = &vat_main;
9089
9090   fformat (vam->ofp, "%-16s %d\n",
9091            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9092 }
9093
9094 static void vl_api_sw_interface_tap_details_t_handler_json
9095   (vl_api_sw_interface_tap_details_t * mp)
9096 {
9097   vat_main_t *vam = &vat_main;
9098   vat_json_node_t *node = NULL;
9099
9100   if (VAT_JSON_ARRAY != vam->json_tree.type)
9101     {
9102       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9103       vat_json_init_array (&vam->json_tree);
9104     }
9105   node = vat_json_array_add (&vam->json_tree);
9106
9107   vat_json_init_object (node);
9108   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9109   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9110 }
9111
9112 static int
9113 api_sw_interface_tap_dump (vat_main_t * vam)
9114 {
9115   vl_api_sw_interface_tap_dump_t *mp;
9116   f64 timeout;
9117
9118   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9119   /* Get list of tap interfaces */
9120   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9121   S;
9122
9123   /* Use a control ping for synchronization */
9124   {
9125     vl_api_control_ping_t *mp;
9126     M (CONTROL_PING, control_ping);
9127     S;
9128   }
9129   W;
9130 }
9131
9132 static uword unformat_vxlan_decap_next
9133   (unformat_input_t * input, va_list * args)
9134 {
9135   u32 *result = va_arg (*args, u32 *);
9136   u32 tmp;
9137
9138   if (unformat (input, "drop"))
9139     *result = VXLAN_INPUT_NEXT_DROP;
9140   else if (unformat (input, "ip4"))
9141     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9142   else if (unformat (input, "ip6"))
9143     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9144   else if (unformat (input, "l2"))
9145     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9146   else if (unformat (input, "%d", &tmp))
9147     *result = tmp;
9148   else
9149     return 0;
9150   return 1;
9151 }
9152
9153 static int
9154 api_vxlan_add_del_tunnel (vat_main_t * vam)
9155 {
9156   unformat_input_t *line_input = vam->input;
9157   vl_api_vxlan_add_del_tunnel_t *mp;
9158   f64 timeout;
9159   ip4_address_t src4, dst4;
9160   ip6_address_t src6, dst6;
9161   u8 is_add = 1;
9162   u8 ipv4_set = 0, ipv6_set = 0;
9163   u8 src_set = 0;
9164   u8 dst_set = 0;
9165   u32 encap_vrf_id = 0;
9166   u32 decap_next_index = ~0;
9167   u32 vni = 0;
9168
9169   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9170     {
9171       if (unformat (line_input, "del"))
9172         is_add = 0;
9173       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9174         {
9175           ipv4_set = 1;
9176           src_set = 1;
9177         }
9178       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9179         {
9180           ipv4_set = 1;
9181           dst_set = 1;
9182         }
9183       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9184         {
9185           ipv6_set = 1;
9186           src_set = 1;
9187         }
9188       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9189         {
9190           ipv6_set = 1;
9191           dst_set = 1;
9192         }
9193       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9194         ;
9195       else if (unformat (line_input, "decap-next %U",
9196                          unformat_vxlan_decap_next, &decap_next_index))
9197         ;
9198       else if (unformat (line_input, "vni %d", &vni))
9199         ;
9200       else
9201         {
9202           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9203           return -99;
9204         }
9205     }
9206
9207   if (src_set == 0)
9208     {
9209       errmsg ("tunnel src address not specified\n");
9210       return -99;
9211     }
9212   if (dst_set == 0)
9213     {
9214       errmsg ("tunnel dst address not specified\n");
9215       return -99;
9216     }
9217
9218   if (ipv4_set && ipv6_set)
9219     {
9220       errmsg ("both IPv4 and IPv6 addresses specified");
9221       return -99;
9222     }
9223
9224   if ((vni == 0) || (vni >> 24))
9225     {
9226       errmsg ("vni not specified or out of range\n");
9227       return -99;
9228     }
9229
9230   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9231
9232   if (ipv6_set)
9233     {
9234       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9235       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9236     }
9237   else
9238     {
9239       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9240       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9241     }
9242   mp->encap_vrf_id = ntohl (encap_vrf_id);
9243   mp->decap_next_index = ntohl (decap_next_index);
9244   mp->vni = ntohl (vni);
9245   mp->is_add = is_add;
9246   mp->is_ipv6 = ipv6_set;
9247
9248   S;
9249   W;
9250   /* NOTREACHED */
9251   return 0;
9252 }
9253
9254 static void vl_api_vxlan_tunnel_details_t_handler
9255   (vl_api_vxlan_tunnel_details_t * mp)
9256 {
9257   vat_main_t *vam = &vat_main;
9258
9259   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9260            ntohl (mp->sw_if_index),
9261            format_ip46_address, &(mp->src_address[0]),
9262            IP46_TYPE_ANY,
9263            format_ip46_address, &(mp->dst_address[0]),
9264            IP46_TYPE_ANY,
9265            ntohl (mp->encap_vrf_id),
9266            ntohl (mp->decap_next_index), ntohl (mp->vni));
9267 }
9268
9269 static void vl_api_vxlan_tunnel_details_t_handler_json
9270   (vl_api_vxlan_tunnel_details_t * mp)
9271 {
9272   vat_main_t *vam = &vat_main;
9273   vat_json_node_t *node = NULL;
9274   struct in_addr ip4;
9275   struct in6_addr ip6;
9276
9277   if (VAT_JSON_ARRAY != vam->json_tree.type)
9278     {
9279       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9280       vat_json_init_array (&vam->json_tree);
9281     }
9282   node = vat_json_array_add (&vam->json_tree);
9283
9284   vat_json_init_object (node);
9285   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9286   if (mp->is_ipv6)
9287     {
9288       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9289       vat_json_object_add_ip6 (node, "src_address", ip6);
9290       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9291       vat_json_object_add_ip6 (node, "dst_address", ip6);
9292     }
9293   else
9294     {
9295       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9296       vat_json_object_add_ip4 (node, "src_address", ip4);
9297       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9298       vat_json_object_add_ip4 (node, "dst_address", ip4);
9299     }
9300   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9301   vat_json_object_add_uint (node, "decap_next_index",
9302                             ntohl (mp->decap_next_index));
9303   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9304   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9305 }
9306
9307 static int
9308 api_vxlan_tunnel_dump (vat_main_t * vam)
9309 {
9310   unformat_input_t *i = vam->input;
9311   vl_api_vxlan_tunnel_dump_t *mp;
9312   f64 timeout;
9313   u32 sw_if_index;
9314   u8 sw_if_index_set = 0;
9315
9316   /* Parse args required to build the message */
9317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9318     {
9319       if (unformat (i, "sw_if_index %d", &sw_if_index))
9320         sw_if_index_set = 1;
9321       else
9322         break;
9323     }
9324
9325   if (sw_if_index_set == 0)
9326     {
9327       sw_if_index = ~0;
9328     }
9329
9330   if (!vam->json_output)
9331     {
9332       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9333                "sw_if_index", "src_address", "dst_address",
9334                "encap_vrf_id", "decap_next_index", "vni");
9335     }
9336
9337   /* Get list of vxlan-tunnel interfaces */
9338   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9339
9340   mp->sw_if_index = htonl (sw_if_index);
9341
9342   S;
9343
9344   /* Use a control ping for synchronization */
9345   {
9346     vl_api_control_ping_t *mp;
9347     M (CONTROL_PING, control_ping);
9348     S;
9349   }
9350   W;
9351 }
9352
9353 static int
9354 api_gre_add_del_tunnel (vat_main_t * vam)
9355 {
9356   unformat_input_t *line_input = vam->input;
9357   vl_api_gre_add_del_tunnel_t *mp;
9358   f64 timeout;
9359   ip4_address_t src4, dst4;
9360   u8 is_add = 1;
9361   u8 src_set = 0;
9362   u8 dst_set = 0;
9363   u32 outer_fib_id = 0;
9364
9365   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9366     {
9367       if (unformat (line_input, "del"))
9368         is_add = 0;
9369       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9370         src_set = 1;
9371       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9372         dst_set = 1;
9373       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9374         ;
9375       else
9376         {
9377           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9378           return -99;
9379         }
9380     }
9381
9382   if (src_set == 0)
9383     {
9384       errmsg ("tunnel src address not specified\n");
9385       return -99;
9386     }
9387   if (dst_set == 0)
9388     {
9389       errmsg ("tunnel dst address not specified\n");
9390       return -99;
9391     }
9392
9393
9394   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9395
9396   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9397   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9398   mp->outer_fib_id = ntohl (outer_fib_id);
9399   mp->is_add = is_add;
9400
9401   S;
9402   W;
9403   /* NOTREACHED */
9404   return 0;
9405 }
9406
9407 static void vl_api_gre_tunnel_details_t_handler
9408   (vl_api_gre_tunnel_details_t * mp)
9409 {
9410   vat_main_t *vam = &vat_main;
9411
9412   fformat (vam->ofp, "%11d%15U%15U%14d\n",
9413            ntohl (mp->sw_if_index),
9414            format_ip4_address, &mp->src_address,
9415            format_ip4_address, &mp->dst_address, ntohl (mp->outer_fib_id));
9416 }
9417
9418 static void vl_api_gre_tunnel_details_t_handler_json
9419   (vl_api_gre_tunnel_details_t * mp)
9420 {
9421   vat_main_t *vam = &vat_main;
9422   vat_json_node_t *node = NULL;
9423   struct in_addr ip4;
9424
9425   if (VAT_JSON_ARRAY != vam->json_tree.type)
9426     {
9427       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9428       vat_json_init_array (&vam->json_tree);
9429     }
9430   node = vat_json_array_add (&vam->json_tree);
9431
9432   vat_json_init_object (node);
9433   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9434   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9435   vat_json_object_add_ip4 (node, "src_address", ip4);
9436   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9437   vat_json_object_add_ip4 (node, "dst_address", ip4);
9438   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9439 }
9440
9441 static int
9442 api_gre_tunnel_dump (vat_main_t * vam)
9443 {
9444   unformat_input_t *i = vam->input;
9445   vl_api_gre_tunnel_dump_t *mp;
9446   f64 timeout;
9447   u32 sw_if_index;
9448   u8 sw_if_index_set = 0;
9449
9450   /* Parse args required to build the message */
9451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9452     {
9453       if (unformat (i, "sw_if_index %d", &sw_if_index))
9454         sw_if_index_set = 1;
9455       else
9456         break;
9457     }
9458
9459   if (sw_if_index_set == 0)
9460     {
9461       sw_if_index = ~0;
9462     }
9463
9464   if (!vam->json_output)
9465     {
9466       fformat (vam->ofp, "%11s%15s%15s%14s\n",
9467                "sw_if_index", "src_address", "dst_address", "outer_fib_id");
9468     }
9469
9470   /* Get list of gre-tunnel interfaces */
9471   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9472
9473   mp->sw_if_index = htonl (sw_if_index);
9474
9475   S;
9476
9477   /* Use a control ping for synchronization */
9478   {
9479     vl_api_control_ping_t *mp;
9480     M (CONTROL_PING, control_ping);
9481     S;
9482   }
9483   W;
9484 }
9485
9486 static int
9487 api_l2_fib_clear_table (vat_main_t * vam)
9488 {
9489 //  unformat_input_t * i = vam->input;
9490   vl_api_l2_fib_clear_table_t *mp;
9491   f64 timeout;
9492
9493   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9494
9495   S;
9496   W;
9497   /* NOTREACHED */
9498   return 0;
9499 }
9500
9501 static int
9502 api_l2_interface_efp_filter (vat_main_t * vam)
9503 {
9504   unformat_input_t *i = vam->input;
9505   vl_api_l2_interface_efp_filter_t *mp;
9506   f64 timeout;
9507   u32 sw_if_index;
9508   u8 enable = 1;
9509   u8 sw_if_index_set = 0;
9510
9511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9512     {
9513       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9514         sw_if_index_set = 1;
9515       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9516         sw_if_index_set = 1;
9517       else if (unformat (i, "enable"))
9518         enable = 1;
9519       else if (unformat (i, "disable"))
9520         enable = 0;
9521       else
9522         {
9523           clib_warning ("parse error '%U'", format_unformat_error, i);
9524           return -99;
9525         }
9526     }
9527
9528   if (sw_if_index_set == 0)
9529     {
9530       errmsg ("missing sw_if_index\n");
9531       return -99;
9532     }
9533
9534   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9535
9536   mp->sw_if_index = ntohl (sw_if_index);
9537   mp->enable_disable = enable;
9538
9539   S;
9540   W;
9541   /* NOTREACHED */
9542   return 0;
9543 }
9544
9545 #define foreach_vtr_op                          \
9546 _("disable",  L2_VTR_DISABLED)                  \
9547 _("push-1",  L2_VTR_PUSH_1)                     \
9548 _("push-2",  L2_VTR_PUSH_2)                     \
9549 _("pop-1",  L2_VTR_POP_1)                       \
9550 _("pop-2",  L2_VTR_POP_2)                       \
9551 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9552 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9553 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9554 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9555
9556 static int
9557 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9558 {
9559   unformat_input_t *i = vam->input;
9560   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9561   f64 timeout;
9562   u32 sw_if_index;
9563   u8 sw_if_index_set = 0;
9564   u8 vtr_op_set = 0;
9565   u32 vtr_op = 0;
9566   u32 push_dot1q = 1;
9567   u32 tag1 = ~0;
9568   u32 tag2 = ~0;
9569
9570   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9571     {
9572       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9573         sw_if_index_set = 1;
9574       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9575         sw_if_index_set = 1;
9576       else if (unformat (i, "vtr_op %d", &vtr_op))
9577         vtr_op_set = 1;
9578 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9579       foreach_vtr_op
9580 #undef _
9581         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9582         ;
9583       else if (unformat (i, "tag1 %d", &tag1))
9584         ;
9585       else if (unformat (i, "tag2 %d", &tag2))
9586         ;
9587       else
9588         {
9589           clib_warning ("parse error '%U'", format_unformat_error, i);
9590           return -99;
9591         }
9592     }
9593
9594   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9595     {
9596       errmsg ("missing vtr operation or sw_if_index\n");
9597       return -99;
9598     }
9599
9600   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9601     mp->sw_if_index = ntohl (sw_if_index);
9602   mp->vtr_op = ntohl (vtr_op);
9603   mp->push_dot1q = ntohl (push_dot1q);
9604   mp->tag1 = ntohl (tag1);
9605   mp->tag2 = ntohl (tag2);
9606
9607   S;
9608   W;
9609   /* NOTREACHED */
9610   return 0;
9611 }
9612
9613 static int
9614 api_create_vhost_user_if (vat_main_t * vam)
9615 {
9616   unformat_input_t *i = vam->input;
9617   vl_api_create_vhost_user_if_t *mp;
9618   f64 timeout;
9619   u8 *file_name;
9620   u8 is_server = 0;
9621   u8 file_name_set = 0;
9622   u32 custom_dev_instance = ~0;
9623   u8 hwaddr[6];
9624   u8 use_custom_mac = 0;
9625
9626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9627     {
9628       if (unformat (i, "socket %s", &file_name))
9629         {
9630           file_name_set = 1;
9631         }
9632       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9633         ;
9634       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9635         use_custom_mac = 1;
9636       else if (unformat (i, "server"))
9637         is_server = 1;
9638       else
9639         break;
9640     }
9641
9642   if (file_name_set == 0)
9643     {
9644       errmsg ("missing socket file name\n");
9645       return -99;
9646     }
9647
9648   if (vec_len (file_name) > 255)
9649     {
9650       errmsg ("socket file name too long\n");
9651       return -99;
9652     }
9653   vec_add1 (file_name, 0);
9654
9655   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
9656
9657   mp->is_server = is_server;
9658   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9659   vec_free (file_name);
9660   if (custom_dev_instance != ~0)
9661     {
9662       mp->renumber = 1;
9663       mp->custom_dev_instance = ntohl (custom_dev_instance);
9664     }
9665   mp->use_custom_mac = use_custom_mac;
9666   clib_memcpy (mp->mac_address, hwaddr, 6);
9667
9668   S;
9669   W;
9670   /* NOTREACHED */
9671   return 0;
9672 }
9673
9674 static int
9675 api_modify_vhost_user_if (vat_main_t * vam)
9676 {
9677   unformat_input_t *i = vam->input;
9678   vl_api_modify_vhost_user_if_t *mp;
9679   f64 timeout;
9680   u8 *file_name;
9681   u8 is_server = 0;
9682   u8 file_name_set = 0;
9683   u32 custom_dev_instance = ~0;
9684   u8 sw_if_index_set = 0;
9685   u32 sw_if_index = (u32) ~ 0;
9686
9687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9688     {
9689       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9690         sw_if_index_set = 1;
9691       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9692         sw_if_index_set = 1;
9693       else if (unformat (i, "socket %s", &file_name))
9694         {
9695           file_name_set = 1;
9696         }
9697       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9698         ;
9699       else if (unformat (i, "server"))
9700         is_server = 1;
9701       else
9702         break;
9703     }
9704
9705   if (sw_if_index_set == 0)
9706     {
9707       errmsg ("missing sw_if_index or interface name\n");
9708       return -99;
9709     }
9710
9711   if (file_name_set == 0)
9712     {
9713       errmsg ("missing socket file name\n");
9714       return -99;
9715     }
9716
9717   if (vec_len (file_name) > 255)
9718     {
9719       errmsg ("socket file name too long\n");
9720       return -99;
9721     }
9722   vec_add1 (file_name, 0);
9723
9724   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
9725
9726   mp->sw_if_index = ntohl (sw_if_index);
9727   mp->is_server = is_server;
9728   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9729   vec_free (file_name);
9730   if (custom_dev_instance != ~0)
9731     {
9732       mp->renumber = 1;
9733       mp->custom_dev_instance = ntohl (custom_dev_instance);
9734     }
9735
9736   S;
9737   W;
9738   /* NOTREACHED */
9739   return 0;
9740 }
9741
9742 static int
9743 api_delete_vhost_user_if (vat_main_t * vam)
9744 {
9745   unformat_input_t *i = vam->input;
9746   vl_api_delete_vhost_user_if_t *mp;
9747   f64 timeout;
9748   u32 sw_if_index = ~0;
9749   u8 sw_if_index_set = 0;
9750
9751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9752     {
9753       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9754         sw_if_index_set = 1;
9755       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9756         sw_if_index_set = 1;
9757       else
9758         break;
9759     }
9760
9761   if (sw_if_index_set == 0)
9762     {
9763       errmsg ("missing sw_if_index or interface name\n");
9764       return -99;
9765     }
9766
9767
9768   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
9769
9770   mp->sw_if_index = ntohl (sw_if_index);
9771
9772   S;
9773   W;
9774   /* NOTREACHED */
9775   return 0;
9776 }
9777
9778 static void vl_api_sw_interface_vhost_user_details_t_handler
9779   (vl_api_sw_interface_vhost_user_details_t * mp)
9780 {
9781   vat_main_t *vam = &vat_main;
9782
9783   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
9784            (char *) mp->interface_name,
9785            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
9786            clib_net_to_host_u64 (mp->features), mp->is_server,
9787            ntohl (mp->num_regions), (char *) mp->sock_filename);
9788   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
9789 }
9790
9791 static void vl_api_sw_interface_vhost_user_details_t_handler_json
9792   (vl_api_sw_interface_vhost_user_details_t * mp)
9793 {
9794   vat_main_t *vam = &vat_main;
9795   vat_json_node_t *node = NULL;
9796
9797   if (VAT_JSON_ARRAY != vam->json_tree.type)
9798     {
9799       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9800       vat_json_init_array (&vam->json_tree);
9801     }
9802   node = vat_json_array_add (&vam->json_tree);
9803
9804   vat_json_init_object (node);
9805   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9806   vat_json_object_add_string_copy (node, "interface_name",
9807                                    mp->interface_name);
9808   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
9809                             ntohl (mp->virtio_net_hdr_sz));
9810   vat_json_object_add_uint (node, "features",
9811                             clib_net_to_host_u64 (mp->features));
9812   vat_json_object_add_uint (node, "is_server", mp->is_server);
9813   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
9814   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
9815   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
9816 }
9817
9818 static int
9819 api_sw_interface_vhost_user_dump (vat_main_t * vam)
9820 {
9821   vl_api_sw_interface_vhost_user_dump_t *mp;
9822   f64 timeout;
9823   fformat (vam->ofp,
9824            "Interface name           idx hdr_sz features server regions filename\n");
9825
9826   /* Get list of vhost-user interfaces */
9827   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
9828   S;
9829
9830   /* Use a control ping for synchronization */
9831   {
9832     vl_api_control_ping_t *mp;
9833     M (CONTROL_PING, control_ping);
9834     S;
9835   }
9836   W;
9837 }
9838
9839 static int
9840 api_show_version (vat_main_t * vam)
9841 {
9842   vl_api_show_version_t *mp;
9843   f64 timeout;
9844
9845   M (SHOW_VERSION, show_version);
9846
9847   S;
9848   W;
9849   /* NOTREACHED */
9850   return 0;
9851 }
9852
9853
9854 static int
9855 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
9856 {
9857   unformat_input_t *line_input = vam->input;
9858   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
9859   f64 timeout;
9860   ip4_address_t local4, remote4;
9861   ip6_address_t local6, remote6;
9862   u8 is_add = 1;
9863   u8 ipv4_set = 0, ipv6_set = 0;
9864   u8 local_set = 0;
9865   u8 remote_set = 0;
9866   u32 encap_vrf_id = 0;
9867   u32 decap_vrf_id = 0;
9868   u8 protocol = ~0;
9869   u32 vni;
9870   u8 vni_set = 0;
9871
9872   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9873     {
9874       if (unformat (line_input, "del"))
9875         is_add = 0;
9876       else if (unformat (line_input, "local %U",
9877                          unformat_ip4_address, &local4))
9878         {
9879           local_set = 1;
9880           ipv4_set = 1;
9881         }
9882       else if (unformat (line_input, "remote %U",
9883                          unformat_ip4_address, &remote4))
9884         {
9885           remote_set = 1;
9886           ipv4_set = 1;
9887         }
9888       else if (unformat (line_input, "local %U",
9889                          unformat_ip6_address, &local6))
9890         {
9891           local_set = 1;
9892           ipv6_set = 1;
9893         }
9894       else if (unformat (line_input, "remote %U",
9895                          unformat_ip6_address, &remote6))
9896         {
9897           remote_set = 1;
9898           ipv6_set = 1;
9899         }
9900       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9901         ;
9902       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
9903         ;
9904       else if (unformat (line_input, "vni %d", &vni))
9905         vni_set = 1;
9906       else if (unformat (line_input, "next-ip4"))
9907         protocol = 1;
9908       else if (unformat (line_input, "next-ip6"))
9909         protocol = 2;
9910       else if (unformat (line_input, "next-ethernet"))
9911         protocol = 3;
9912       else if (unformat (line_input, "next-nsh"))
9913         protocol = 4;
9914       else
9915         {
9916           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9917           return -99;
9918         }
9919     }
9920
9921   if (local_set == 0)
9922     {
9923       errmsg ("tunnel local address not specified\n");
9924       return -99;
9925     }
9926   if (remote_set == 0)
9927     {
9928       errmsg ("tunnel remote address not specified\n");
9929       return -99;
9930     }
9931   if (ipv4_set && ipv6_set)
9932     {
9933       errmsg ("both IPv4 and IPv6 addresses specified");
9934       return -99;
9935     }
9936
9937   if (vni_set == 0)
9938     {
9939       errmsg ("vni not specified\n");
9940       return -99;
9941     }
9942
9943   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
9944
9945
9946   if (ipv6_set)
9947     {
9948       clib_memcpy (&mp->local, &local6, sizeof (local6));
9949       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
9950     }
9951   else
9952     {
9953       clib_memcpy (&mp->local, &local4, sizeof (local4));
9954       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
9955     }
9956
9957   mp->encap_vrf_id = ntohl (encap_vrf_id);
9958   mp->decap_vrf_id = ntohl (decap_vrf_id);
9959   mp->protocol = ntohl (protocol);
9960   mp->vni = ntohl (vni);
9961   mp->is_add = is_add;
9962   mp->is_ipv6 = ipv6_set;
9963
9964   S;
9965   W;
9966   /* NOTREACHED */
9967   return 0;
9968 }
9969
9970 static void vl_api_vxlan_gpe_tunnel_details_t_handler
9971   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9972 {
9973   vat_main_t *vam = &vat_main;
9974
9975   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
9976            ntohl (mp->sw_if_index),
9977            format_ip46_address, &(mp->local[0]),
9978            format_ip46_address, &(mp->remote[0]),
9979            ntohl (mp->vni),
9980            ntohl (mp->protocol),
9981            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
9982 }
9983
9984 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
9985   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9986 {
9987   vat_main_t *vam = &vat_main;
9988   vat_json_node_t *node = NULL;
9989   struct in_addr ip4;
9990   struct in6_addr ip6;
9991
9992   if (VAT_JSON_ARRAY != vam->json_tree.type)
9993     {
9994       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9995       vat_json_init_array (&vam->json_tree);
9996     }
9997   node = vat_json_array_add (&vam->json_tree);
9998
9999   vat_json_init_object (node);
10000   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10001   if (mp->is_ipv6)
10002     {
10003       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10004       vat_json_object_add_ip6 (node, "local", ip6);
10005       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10006       vat_json_object_add_ip6 (node, "remote", ip6);
10007     }
10008   else
10009     {
10010       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10011       vat_json_object_add_ip4 (node, "local", ip4);
10012       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10013       vat_json_object_add_ip4 (node, "remote", ip4);
10014     }
10015   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10016   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10017   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10018   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10019   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10020 }
10021
10022 static int
10023 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10024 {
10025   unformat_input_t *i = vam->input;
10026   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10027   f64 timeout;
10028   u32 sw_if_index;
10029   u8 sw_if_index_set = 0;
10030
10031   /* Parse args required to build the message */
10032   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10033     {
10034       if (unformat (i, "sw_if_index %d", &sw_if_index))
10035         sw_if_index_set = 1;
10036       else
10037         break;
10038     }
10039
10040   if (sw_if_index_set == 0)
10041     {
10042       sw_if_index = ~0;
10043     }
10044
10045   if (!vam->json_output)
10046     {
10047       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10048                "sw_if_index", "local", "remote", "vni",
10049                "protocol", "encap_vrf_id", "decap_vrf_id");
10050     }
10051
10052   /* Get list of vxlan-tunnel interfaces */
10053   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10054
10055   mp->sw_if_index = htonl (sw_if_index);
10056
10057   S;
10058
10059   /* Use a control ping for synchronization */
10060   {
10061     vl_api_control_ping_t *mp;
10062     M (CONTROL_PING, control_ping);
10063     S;
10064   }
10065   W;
10066 }
10067
10068 u8 *
10069 format_l2_fib_mac_address (u8 * s, va_list * args)
10070 {
10071   u8 *a = va_arg (*args, u8 *);
10072
10073   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10074                  a[2], a[3], a[4], a[5], a[6], a[7]);
10075 }
10076
10077 static void vl_api_l2_fib_table_entry_t_handler
10078   (vl_api_l2_fib_table_entry_t * mp)
10079 {
10080   vat_main_t *vam = &vat_main;
10081
10082   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10083            "       %d       %d     %d\n",
10084            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10085            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10086            mp->bvi_mac);
10087 }
10088
10089 static void vl_api_l2_fib_table_entry_t_handler_json
10090   (vl_api_l2_fib_table_entry_t * mp)
10091 {
10092   vat_main_t *vam = &vat_main;
10093   vat_json_node_t *node = NULL;
10094
10095   if (VAT_JSON_ARRAY != vam->json_tree.type)
10096     {
10097       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10098       vat_json_init_array (&vam->json_tree);
10099     }
10100   node = vat_json_array_add (&vam->json_tree);
10101
10102   vat_json_init_object (node);
10103   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10104   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10105   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10106   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10107   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10108   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10109 }
10110
10111 static int
10112 api_l2_fib_table_dump (vat_main_t * vam)
10113 {
10114   unformat_input_t *i = vam->input;
10115   vl_api_l2_fib_table_dump_t *mp;
10116   f64 timeout;
10117   u32 bd_id;
10118   u8 bd_id_set = 0;
10119
10120   /* Parse args required to build the message */
10121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10122     {
10123       if (unformat (i, "bd_id %d", &bd_id))
10124         bd_id_set = 1;
10125       else
10126         break;
10127     }
10128
10129   if (bd_id_set == 0)
10130     {
10131       errmsg ("missing bridge domain\n");
10132       return -99;
10133     }
10134
10135   fformat (vam->ofp,
10136            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10137
10138   /* Get list of l2 fib entries */
10139   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10140
10141   mp->bd_id = ntohl (bd_id);
10142   S;
10143
10144   /* Use a control ping for synchronization */
10145   {
10146     vl_api_control_ping_t *mp;
10147     M (CONTROL_PING, control_ping);
10148     S;
10149   }
10150   W;
10151 }
10152
10153
10154 static int
10155 api_interface_name_renumber (vat_main_t * vam)
10156 {
10157   unformat_input_t *line_input = vam->input;
10158   vl_api_interface_name_renumber_t *mp;
10159   u32 sw_if_index = ~0;
10160   f64 timeout;
10161   u32 new_show_dev_instance = ~0;
10162
10163   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10164     {
10165       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10166                     &sw_if_index))
10167         ;
10168       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10169         ;
10170       else if (unformat (line_input, "new_show_dev_instance %d",
10171                          &new_show_dev_instance))
10172         ;
10173       else
10174         break;
10175     }
10176
10177   if (sw_if_index == ~0)
10178     {
10179       errmsg ("missing interface name or sw_if_index\n");
10180       return -99;
10181     }
10182
10183   if (new_show_dev_instance == ~0)
10184     {
10185       errmsg ("missing new_show_dev_instance\n");
10186       return -99;
10187     }
10188
10189   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10190
10191   mp->sw_if_index = ntohl (sw_if_index);
10192   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10193
10194   S;
10195   W;
10196 }
10197
10198 static int
10199 api_want_ip4_arp_events (vat_main_t * vam)
10200 {
10201   unformat_input_t *line_input = vam->input;
10202   vl_api_want_ip4_arp_events_t *mp;
10203   f64 timeout;
10204   ip4_address_t address;
10205   int address_set = 0;
10206   u32 enable_disable = 1;
10207
10208   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10209     {
10210       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10211         address_set = 1;
10212       else if (unformat (line_input, "del"))
10213         enable_disable = 0;
10214       else
10215         break;
10216     }
10217
10218   if (address_set == 0)
10219     {
10220       errmsg ("missing addresses\n");
10221       return -99;
10222     }
10223
10224   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10225   mp->enable_disable = enable_disable;
10226   mp->pid = getpid ();
10227   mp->address = address.as_u32;
10228
10229   S;
10230   W;
10231 }
10232
10233 static int
10234 api_want_ip6_nd_events (vat_main_t * vam)
10235 {
10236   unformat_input_t *line_input = vam->input;
10237   vl_api_want_ip6_nd_events_t *mp;
10238   f64 timeout;
10239   ip6_address_t address;
10240   int address_set = 0;
10241   u32 enable_disable = 1;
10242
10243   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10244     {
10245       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
10246         address_set = 1;
10247       else if (unformat (line_input, "del"))
10248         enable_disable = 0;
10249       else
10250         break;
10251     }
10252
10253   if (address_set == 0)
10254     {
10255       errmsg ("missing addresses\n");
10256       return -99;
10257     }
10258
10259   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
10260   mp->enable_disable = enable_disable;
10261   mp->pid = getpid ();
10262   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
10263
10264   S;
10265   W;
10266 }
10267
10268 static int
10269 api_input_acl_set_interface (vat_main_t * vam)
10270 {
10271   unformat_input_t *i = vam->input;
10272   vl_api_input_acl_set_interface_t *mp;
10273   f64 timeout;
10274   u32 sw_if_index;
10275   int sw_if_index_set;
10276   u32 ip4_table_index = ~0;
10277   u32 ip6_table_index = ~0;
10278   u32 l2_table_index = ~0;
10279   u8 is_add = 1;
10280
10281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10282     {
10283       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10284         sw_if_index_set = 1;
10285       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10286         sw_if_index_set = 1;
10287       else if (unformat (i, "del"))
10288         is_add = 0;
10289       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10290         ;
10291       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10292         ;
10293       else if (unformat (i, "l2-table %d", &l2_table_index))
10294         ;
10295       else
10296         {
10297           clib_warning ("parse error '%U'", format_unformat_error, i);
10298           return -99;
10299         }
10300     }
10301
10302   if (sw_if_index_set == 0)
10303     {
10304       errmsg ("missing interface name or sw_if_index\n");
10305       return -99;
10306     }
10307
10308   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10309
10310   mp->sw_if_index = ntohl (sw_if_index);
10311   mp->ip4_table_index = ntohl (ip4_table_index);
10312   mp->ip6_table_index = ntohl (ip6_table_index);
10313   mp->l2_table_index = ntohl (l2_table_index);
10314   mp->is_add = is_add;
10315
10316   S;
10317   W;
10318   /* NOTREACHED */
10319   return 0;
10320 }
10321
10322 static int
10323 api_ip_address_dump (vat_main_t * vam)
10324 {
10325   unformat_input_t *i = vam->input;
10326   vl_api_ip_address_dump_t *mp;
10327   u32 sw_if_index = ~0;
10328   u8 sw_if_index_set = 0;
10329   u8 ipv4_set = 0;
10330   u8 ipv6_set = 0;
10331   f64 timeout;
10332
10333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10334     {
10335       if (unformat (i, "sw_if_index %d", &sw_if_index))
10336         sw_if_index_set = 1;
10337       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10338         sw_if_index_set = 1;
10339       else if (unformat (i, "ipv4"))
10340         ipv4_set = 1;
10341       else if (unformat (i, "ipv6"))
10342         ipv6_set = 1;
10343       else
10344         break;
10345     }
10346
10347   if (ipv4_set && ipv6_set)
10348     {
10349       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10350       return -99;
10351     }
10352
10353   if ((!ipv4_set) && (!ipv6_set))
10354     {
10355       errmsg ("no ipv4 nor ipv6 flag set\n");
10356       return -99;
10357     }
10358
10359   if (sw_if_index_set == 0)
10360     {
10361       errmsg ("missing interface name or sw_if_index\n");
10362       return -99;
10363     }
10364
10365   vam->current_sw_if_index = sw_if_index;
10366   vam->is_ipv6 = ipv6_set;
10367
10368   M (IP_ADDRESS_DUMP, ip_address_dump);
10369   mp->sw_if_index = ntohl (sw_if_index);
10370   mp->is_ipv6 = ipv6_set;
10371   S;
10372
10373   /* Use a control ping for synchronization */
10374   {
10375     vl_api_control_ping_t *mp;
10376     M (CONTROL_PING, control_ping);
10377     S;
10378   }
10379   W;
10380 }
10381
10382 static int
10383 api_ip_dump (vat_main_t * vam)
10384 {
10385   vl_api_ip_dump_t *mp;
10386   unformat_input_t *in = vam->input;
10387   int ipv4_set = 0;
10388   int ipv6_set = 0;
10389   int is_ipv6;
10390   f64 timeout;
10391   int i;
10392
10393   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10394     {
10395       if (unformat (in, "ipv4"))
10396         ipv4_set = 1;
10397       else if (unformat (in, "ipv6"))
10398         ipv6_set = 1;
10399       else
10400         break;
10401     }
10402
10403   if (ipv4_set && ipv6_set)
10404     {
10405       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10406       return -99;
10407     }
10408
10409   if ((!ipv4_set) && (!ipv6_set))
10410     {
10411       errmsg ("no ipv4 nor ipv6 flag set\n");
10412       return -99;
10413     }
10414
10415   is_ipv6 = ipv6_set;
10416   vam->is_ipv6 = is_ipv6;
10417
10418   /* free old data */
10419   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10420     {
10421       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10422     }
10423   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10424
10425   M (IP_DUMP, ip_dump);
10426   mp->is_ipv6 = ipv6_set;
10427   S;
10428
10429   /* Use a control ping for synchronization */
10430   {
10431     vl_api_control_ping_t *mp;
10432     M (CONTROL_PING, control_ping);
10433     S;
10434   }
10435   W;
10436 }
10437
10438 static int
10439 api_ipsec_spd_add_del (vat_main_t * vam)
10440 {
10441 #if DPDK > 0
10442   unformat_input_t *i = vam->input;
10443   vl_api_ipsec_spd_add_del_t *mp;
10444   f64 timeout;
10445   u32 spd_id = ~0;
10446   u8 is_add = 1;
10447
10448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10449     {
10450       if (unformat (i, "spd_id %d", &spd_id))
10451         ;
10452       else if (unformat (i, "del"))
10453         is_add = 0;
10454       else
10455         {
10456           clib_warning ("parse error '%U'", format_unformat_error, i);
10457           return -99;
10458         }
10459     }
10460   if (spd_id == ~0)
10461     {
10462       errmsg ("spd_id must be set\n");
10463       return -99;
10464     }
10465
10466   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10467
10468   mp->spd_id = ntohl (spd_id);
10469   mp->is_add = is_add;
10470
10471   S;
10472   W;
10473   /* NOTREACHED */
10474   return 0;
10475 #else
10476   clib_warning ("unsupported (no dpdk)");
10477   return -99;
10478 #endif
10479 }
10480
10481 static int
10482 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10483 {
10484 #if DPDK > 0
10485   unformat_input_t *i = vam->input;
10486   vl_api_ipsec_interface_add_del_spd_t *mp;
10487   f64 timeout;
10488   u32 sw_if_index;
10489   u8 sw_if_index_set = 0;
10490   u32 spd_id = (u32) ~ 0;
10491   u8 is_add = 1;
10492
10493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10494     {
10495       if (unformat (i, "del"))
10496         is_add = 0;
10497       else if (unformat (i, "spd_id %d", &spd_id))
10498         ;
10499       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10500         sw_if_index_set = 1;
10501       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10502         sw_if_index_set = 1;
10503       else
10504         {
10505           clib_warning ("parse error '%U'", format_unformat_error, i);
10506           return -99;
10507         }
10508
10509     }
10510
10511   if (spd_id == (u32) ~ 0)
10512     {
10513       errmsg ("spd_id must be set\n");
10514       return -99;
10515     }
10516
10517   if (sw_if_index_set == 0)
10518     {
10519       errmsg ("missing interface name or sw_if_index\n");
10520       return -99;
10521     }
10522
10523   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10524
10525   mp->spd_id = ntohl (spd_id);
10526   mp->sw_if_index = ntohl (sw_if_index);
10527   mp->is_add = is_add;
10528
10529   S;
10530   W;
10531   /* NOTREACHED */
10532   return 0;
10533 #else
10534   clib_warning ("unsupported (no dpdk)");
10535   return -99;
10536 #endif
10537 }
10538
10539 static int
10540 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10541 {
10542 #if DPDK > 0
10543   unformat_input_t *i = vam->input;
10544   vl_api_ipsec_spd_add_del_entry_t *mp;
10545   f64 timeout;
10546   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10547   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10548   i32 priority = 0;
10549   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10550   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10551   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10552   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10553
10554   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10555   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10556   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10557   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10558   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10559   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10560
10561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10562     {
10563       if (unformat (i, "del"))
10564         is_add = 0;
10565       if (unformat (i, "outbound"))
10566         is_outbound = 1;
10567       if (unformat (i, "inbound"))
10568         is_outbound = 0;
10569       else if (unformat (i, "spd_id %d", &spd_id))
10570         ;
10571       else if (unformat (i, "sa_id %d", &sa_id))
10572         ;
10573       else if (unformat (i, "priority %d", &priority))
10574         ;
10575       else if (unformat (i, "protocol %d", &protocol))
10576         ;
10577       else if (unformat (i, "lport_start %d", &lport_start))
10578         ;
10579       else if (unformat (i, "lport_stop %d", &lport_stop))
10580         ;
10581       else if (unformat (i, "rport_start %d", &rport_start))
10582         ;
10583       else if (unformat (i, "rport_stop %d", &rport_stop))
10584         ;
10585       else
10586         if (unformat
10587             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10588         {
10589           is_ipv6 = 0;
10590           is_ip_any = 0;
10591         }
10592       else
10593         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10594         {
10595           is_ipv6 = 0;
10596           is_ip_any = 0;
10597         }
10598       else
10599         if (unformat
10600             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10601         {
10602           is_ipv6 = 0;
10603           is_ip_any = 0;
10604         }
10605       else
10606         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
10607         {
10608           is_ipv6 = 0;
10609           is_ip_any = 0;
10610         }
10611       else
10612         if (unformat
10613             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
10614         {
10615           is_ipv6 = 1;
10616           is_ip_any = 0;
10617         }
10618       else
10619         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
10620         {
10621           is_ipv6 = 1;
10622           is_ip_any = 0;
10623         }
10624       else
10625         if (unformat
10626             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
10627         {
10628           is_ipv6 = 1;
10629           is_ip_any = 0;
10630         }
10631       else
10632         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
10633         {
10634           is_ipv6 = 1;
10635           is_ip_any = 0;
10636         }
10637       else
10638         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10639         {
10640           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10641             {
10642               clib_warning ("unsupported action: 'resolve'");
10643               return -99;
10644             }
10645         }
10646       else
10647         {
10648           clib_warning ("parse error '%U'", format_unformat_error, i);
10649           return -99;
10650         }
10651
10652     }
10653
10654   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
10655
10656   mp->spd_id = ntohl (spd_id);
10657   mp->priority = ntohl (priority);
10658   mp->is_outbound = is_outbound;
10659
10660   mp->is_ipv6 = is_ipv6;
10661   if (is_ipv6 || is_ip_any)
10662     {
10663       clib_memcpy (mp->remote_address_start, &raddr6_start,
10664                    sizeof (ip6_address_t));
10665       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
10666                    sizeof (ip6_address_t));
10667       clib_memcpy (mp->local_address_start, &laddr6_start,
10668                    sizeof (ip6_address_t));
10669       clib_memcpy (mp->local_address_stop, &laddr6_stop,
10670                    sizeof (ip6_address_t));
10671     }
10672   else
10673     {
10674       clib_memcpy (mp->remote_address_start, &raddr4_start,
10675                    sizeof (ip4_address_t));
10676       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
10677                    sizeof (ip4_address_t));
10678       clib_memcpy (mp->local_address_start, &laddr4_start,
10679                    sizeof (ip4_address_t));
10680       clib_memcpy (mp->local_address_stop, &laddr4_stop,
10681                    sizeof (ip4_address_t));
10682     }
10683   mp->protocol = (u8) protocol;
10684   mp->local_port_start = ntohs ((u16) lport_start);
10685   mp->local_port_stop = ntohs ((u16) lport_stop);
10686   mp->remote_port_start = ntohs ((u16) rport_start);
10687   mp->remote_port_stop = ntohs ((u16) rport_stop);
10688   mp->policy = (u8) policy;
10689   mp->sa_id = ntohl (sa_id);
10690   mp->is_add = is_add;
10691   mp->is_ip_any = is_ip_any;
10692   S;
10693   W;
10694   /* NOTREACHED */
10695   return 0;
10696 #else
10697   clib_warning ("unsupported (no dpdk)");
10698   return -99;
10699 #endif
10700 }
10701
10702 static int
10703 api_ipsec_sad_add_del_entry (vat_main_t * vam)
10704 {
10705 #if DPDK > 0
10706   unformat_input_t *i = vam->input;
10707   vl_api_ipsec_sad_add_del_entry_t *mp;
10708   f64 timeout;
10709   u32 sad_id = 0, spi = 0;
10710   u8 *ck = 0, *ik = 0;
10711   u8 is_add = 1;
10712
10713   u8 protocol = IPSEC_PROTOCOL_AH;
10714   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
10715   u32 crypto_alg = 0, integ_alg = 0;
10716   ip4_address_t tun_src4;
10717   ip4_address_t tun_dst4;
10718   ip6_address_t tun_src6;
10719   ip6_address_t tun_dst6;
10720
10721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10722     {
10723       if (unformat (i, "del"))
10724         is_add = 0;
10725       else if (unformat (i, "sad_id %d", &sad_id))
10726         ;
10727       else if (unformat (i, "spi %d", &spi))
10728         ;
10729       else if (unformat (i, "esp"))
10730         protocol = IPSEC_PROTOCOL_ESP;
10731       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
10732         {
10733           is_tunnel = 1;
10734           is_tunnel_ipv6 = 0;
10735         }
10736       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
10737         {
10738           is_tunnel = 1;
10739           is_tunnel_ipv6 = 0;
10740         }
10741       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
10742         {
10743           is_tunnel = 1;
10744           is_tunnel_ipv6 = 1;
10745         }
10746       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
10747         {
10748           is_tunnel = 1;
10749           is_tunnel_ipv6 = 1;
10750         }
10751       else
10752         if (unformat
10753             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
10754         {
10755           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
10756               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
10757             {
10758               clib_warning ("unsupported crypto-alg: '%U'",
10759                             format_ipsec_crypto_alg, crypto_alg);
10760               return -99;
10761             }
10762         }
10763       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10764         ;
10765       else
10766         if (unformat
10767             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
10768         {
10769           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
10770               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
10771             {
10772               clib_warning ("unsupported integ-alg: '%U'",
10773                             format_ipsec_integ_alg, integ_alg);
10774               return -99;
10775             }
10776         }
10777       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10778         ;
10779       else
10780         {
10781           clib_warning ("parse error '%U'", format_unformat_error, i);
10782           return -99;
10783         }
10784
10785     }
10786
10787   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
10788
10789   mp->sad_id = ntohl (sad_id);
10790   mp->is_add = is_add;
10791   mp->protocol = protocol;
10792   mp->spi = ntohl (spi);
10793   mp->is_tunnel = is_tunnel;
10794   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
10795   mp->crypto_algorithm = crypto_alg;
10796   mp->integrity_algorithm = integ_alg;
10797   mp->crypto_key_length = vec_len (ck);
10798   mp->integrity_key_length = vec_len (ik);
10799
10800   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10801     mp->crypto_key_length = sizeof (mp->crypto_key);
10802
10803   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10804     mp->integrity_key_length = sizeof (mp->integrity_key);
10805
10806   if (ck)
10807     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10808   if (ik)
10809     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10810
10811   if (is_tunnel)
10812     {
10813       if (is_tunnel_ipv6)
10814         {
10815           clib_memcpy (mp->tunnel_src_address, &tun_src6,
10816                        sizeof (ip6_address_t));
10817           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
10818                        sizeof (ip6_address_t));
10819         }
10820       else
10821         {
10822           clib_memcpy (mp->tunnel_src_address, &tun_src4,
10823                        sizeof (ip4_address_t));
10824           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
10825                        sizeof (ip4_address_t));
10826         }
10827     }
10828
10829   S;
10830   W;
10831   /* NOTREACHED */
10832   return 0;
10833 #else
10834   clib_warning ("unsupported (no dpdk)");
10835   return -99;
10836 #endif
10837 }
10838
10839 static int
10840 api_ipsec_sa_set_key (vat_main_t * vam)
10841 {
10842 #if DPDK > 0
10843   unformat_input_t *i = vam->input;
10844   vl_api_ipsec_sa_set_key_t *mp;
10845   f64 timeout;
10846   u32 sa_id;
10847   u8 *ck = 0, *ik = 0;
10848
10849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10850     {
10851       if (unformat (i, "sa_id %d", &sa_id))
10852         ;
10853       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10854         ;
10855       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10856         ;
10857       else
10858         {
10859           clib_warning ("parse error '%U'", format_unformat_error, i);
10860           return -99;
10861         }
10862     }
10863
10864   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
10865
10866   mp->sa_id = ntohl (sa_id);
10867   mp->crypto_key_length = vec_len (ck);
10868   mp->integrity_key_length = vec_len (ik);
10869
10870   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10871     mp->crypto_key_length = sizeof (mp->crypto_key);
10872
10873   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10874     mp->integrity_key_length = sizeof (mp->integrity_key);
10875
10876   if (ck)
10877     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10878   if (ik)
10879     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10880
10881   S;
10882   W;
10883   /* NOTREACHED */
10884   return 0;
10885 #else
10886   clib_warning ("unsupported (no dpdk)");
10887   return -99;
10888 #endif
10889 }
10890
10891 static int
10892 api_ikev2_profile_add_del (vat_main_t * vam)
10893 {
10894 #if DPDK > 0
10895   unformat_input_t *i = vam->input;
10896   vl_api_ikev2_profile_add_del_t *mp;
10897   f64 timeout;
10898   u8 is_add = 1;
10899   u8 *name = 0;
10900
10901   const char *valid_chars = "a-zA-Z0-9_";
10902
10903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10904     {
10905       if (unformat (i, "del"))
10906         is_add = 0;
10907       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10908         vec_add1 (name, 0);
10909       else
10910         {
10911           errmsg ("parse error '%U'", format_unformat_error, i);
10912           return -99;
10913         }
10914     }
10915
10916   if (!vec_len (name))
10917     {
10918       errmsg ("profile name must be specified");
10919       return -99;
10920     }
10921
10922   if (vec_len (name) > 64)
10923     {
10924       errmsg ("profile name too long");
10925       return -99;
10926     }
10927
10928   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
10929
10930   clib_memcpy (mp->name, name, vec_len (name));
10931   mp->is_add = is_add;
10932   vec_free (name);
10933
10934   S;
10935   W;
10936   /* NOTREACHED */
10937   return 0;
10938 #else
10939   clib_warning ("unsupported (no dpdk)");
10940   return -99;
10941 #endif
10942 }
10943
10944 static int
10945 api_ikev2_profile_set_auth (vat_main_t * vam)
10946 {
10947 #if DPDK > 0
10948   unformat_input_t *i = vam->input;
10949   vl_api_ikev2_profile_set_auth_t *mp;
10950   f64 timeout;
10951   u8 *name = 0;
10952   u8 *data = 0;
10953   u32 auth_method = 0;
10954   u8 is_hex = 0;
10955
10956   const char *valid_chars = "a-zA-Z0-9_";
10957
10958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10959     {
10960       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10961         vec_add1 (name, 0);
10962       else if (unformat (i, "auth_method %U",
10963                          unformat_ikev2_auth_method, &auth_method))
10964         ;
10965       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
10966         is_hex = 1;
10967       else if (unformat (i, "auth_data %v", &data))
10968         ;
10969       else
10970         {
10971           errmsg ("parse error '%U'", format_unformat_error, i);
10972           return -99;
10973         }
10974     }
10975
10976   if (!vec_len (name))
10977     {
10978       errmsg ("profile name must be specified");
10979       return -99;
10980     }
10981
10982   if (vec_len (name) > 64)
10983     {
10984       errmsg ("profile name too long");
10985       return -99;
10986     }
10987
10988   if (!vec_len (data))
10989     {
10990       errmsg ("auth_data must be specified");
10991       return -99;
10992     }
10993
10994   if (!auth_method)
10995     {
10996       errmsg ("auth_method must be specified");
10997       return -99;
10998     }
10999
11000   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11001
11002   mp->is_hex = is_hex;
11003   mp->auth_method = (u8) auth_method;
11004   mp->data_len = vec_len (data);
11005   clib_memcpy (mp->name, name, vec_len (name));
11006   clib_memcpy (mp->data, data, vec_len (data));
11007   vec_free (name);
11008   vec_free (data);
11009
11010   S;
11011   W;
11012   /* NOTREACHED */
11013   return 0;
11014 #else
11015   clib_warning ("unsupported (no dpdk)");
11016   return -99;
11017 #endif
11018 }
11019
11020 static int
11021 api_ikev2_profile_set_id (vat_main_t * vam)
11022 {
11023 #if DPDK > 0
11024   unformat_input_t *i = vam->input;
11025   vl_api_ikev2_profile_set_id_t *mp;
11026   f64 timeout;
11027   u8 *name = 0;
11028   u8 *data = 0;
11029   u8 is_local = 0;
11030   u32 id_type = 0;
11031   ip4_address_t ip4;
11032
11033   const char *valid_chars = "a-zA-Z0-9_";
11034
11035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11036     {
11037       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11038         vec_add1 (name, 0);
11039       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11040         ;
11041       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11042         {
11043           data = vec_new (u8, 4);
11044           clib_memcpy (data, ip4.as_u8, 4);
11045         }
11046       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11047         ;
11048       else if (unformat (i, "id_data %v", &data))
11049         ;
11050       else if (unformat (i, "local"))
11051         is_local = 1;
11052       else if (unformat (i, "remote"))
11053         is_local = 0;
11054       else
11055         {
11056           errmsg ("parse error '%U'", format_unformat_error, i);
11057           return -99;
11058         }
11059     }
11060
11061   if (!vec_len (name))
11062     {
11063       errmsg ("profile name must be specified");
11064       return -99;
11065     }
11066
11067   if (vec_len (name) > 64)
11068     {
11069       errmsg ("profile name too long");
11070       return -99;
11071     }
11072
11073   if (!vec_len (data))
11074     {
11075       errmsg ("id_data must be specified");
11076       return -99;
11077     }
11078
11079   if (!id_type)
11080     {
11081       errmsg ("id_type must be specified");
11082       return -99;
11083     }
11084
11085   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11086
11087   mp->is_local = is_local;
11088   mp->id_type = (u8) id_type;
11089   mp->data_len = vec_len (data);
11090   clib_memcpy (mp->name, name, vec_len (name));
11091   clib_memcpy (mp->data, data, vec_len (data));
11092   vec_free (name);
11093   vec_free (data);
11094
11095   S;
11096   W;
11097   /* NOTREACHED */
11098   return 0;
11099 #else
11100   clib_warning ("unsupported (no dpdk)");
11101   return -99;
11102 #endif
11103 }
11104
11105 static int
11106 api_ikev2_profile_set_ts (vat_main_t * vam)
11107 {
11108 #if DPDK > 0
11109   unformat_input_t *i = vam->input;
11110   vl_api_ikev2_profile_set_ts_t *mp;
11111   f64 timeout;
11112   u8 *name = 0;
11113   u8 is_local = 0;
11114   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11115   ip4_address_t start_addr, end_addr;
11116
11117   const char *valid_chars = "a-zA-Z0-9_";
11118
11119   start_addr.as_u32 = 0;
11120   end_addr.as_u32 = (u32) ~ 0;
11121
11122   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11123     {
11124       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11125         vec_add1 (name, 0);
11126       else if (unformat (i, "protocol %d", &proto))
11127         ;
11128       else if (unformat (i, "start_port %d", &start_port))
11129         ;
11130       else if (unformat (i, "end_port %d", &end_port))
11131         ;
11132       else
11133         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11134         ;
11135       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11136         ;
11137       else if (unformat (i, "local"))
11138         is_local = 1;
11139       else if (unformat (i, "remote"))
11140         is_local = 0;
11141       else
11142         {
11143           errmsg ("parse error '%U'", format_unformat_error, i);
11144           return -99;
11145         }
11146     }
11147
11148   if (!vec_len (name))
11149     {
11150       errmsg ("profile name must be specified");
11151       return -99;
11152     }
11153
11154   if (vec_len (name) > 64)
11155     {
11156       errmsg ("profile name too long");
11157       return -99;
11158     }
11159
11160   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11161
11162   mp->is_local = is_local;
11163   mp->proto = (u8) proto;
11164   mp->start_port = (u16) start_port;
11165   mp->end_port = (u16) end_port;
11166   mp->start_addr = start_addr.as_u32;
11167   mp->end_addr = end_addr.as_u32;
11168   clib_memcpy (mp->name, name, vec_len (name));
11169   vec_free (name);
11170
11171   S;
11172   W;
11173   /* NOTREACHED */
11174   return 0;
11175 #else
11176   clib_warning ("unsupported (no dpdk)");
11177   return -99;
11178 #endif
11179 }
11180
11181 static int
11182 api_ikev2_set_local_key (vat_main_t * vam)
11183 {
11184 #if DPDK > 0
11185   unformat_input_t *i = vam->input;
11186   vl_api_ikev2_set_local_key_t *mp;
11187   f64 timeout;
11188   u8 *file = 0;
11189
11190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11191     {
11192       if (unformat (i, "file %v", &file))
11193         vec_add1 (file, 0);
11194       else
11195         {
11196           errmsg ("parse error '%U'", format_unformat_error, i);
11197           return -99;
11198         }
11199     }
11200
11201   if (!vec_len (file))
11202     {
11203       errmsg ("RSA key file must be specified");
11204       return -99;
11205     }
11206
11207   if (vec_len (file) > 256)
11208     {
11209       errmsg ("file name too long");
11210       return -99;
11211     }
11212
11213   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11214
11215   clib_memcpy (mp->key_file, file, vec_len (file));
11216   vec_free (file);
11217
11218   S;
11219   W;
11220   /* NOTREACHED */
11221   return 0;
11222 #else
11223   clib_warning ("unsupported (no dpdk)");
11224   return -99;
11225 #endif
11226 }
11227
11228 /*
11229  * MAP
11230  */
11231 static int
11232 api_map_add_domain (vat_main_t * vam)
11233 {
11234   unformat_input_t *i = vam->input;
11235   vl_api_map_add_domain_t *mp;
11236   f64 timeout;
11237
11238   ip4_address_t ip4_prefix;
11239   ip6_address_t ip6_prefix;
11240   ip6_address_t ip6_src;
11241   u32 num_m_args = 0;
11242   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11243     0, psid_length = 0;
11244   u8 is_translation = 0;
11245   u32 mtu = 0;
11246   u32 ip6_src_len = 128;
11247
11248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11249     {
11250       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11251                     &ip4_prefix, &ip4_prefix_len))
11252         num_m_args++;
11253       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11254                          &ip6_prefix, &ip6_prefix_len))
11255         num_m_args++;
11256       else
11257         if (unformat
11258             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11259              &ip6_src_len))
11260         num_m_args++;
11261       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11262         num_m_args++;
11263       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11264         num_m_args++;
11265       else if (unformat (i, "psid-offset %d", &psid_offset))
11266         num_m_args++;
11267       else if (unformat (i, "psid-len %d", &psid_length))
11268         num_m_args++;
11269       else if (unformat (i, "mtu %d", &mtu))
11270         num_m_args++;
11271       else if (unformat (i, "map-t"))
11272         is_translation = 1;
11273       else
11274         {
11275           clib_warning ("parse error '%U'", format_unformat_error, i);
11276           return -99;
11277         }
11278     }
11279
11280   if (num_m_args < 3)
11281     {
11282       errmsg ("mandatory argument(s) missing\n");
11283       return -99;
11284     }
11285
11286   /* Construct the API message */
11287   M (MAP_ADD_DOMAIN, map_add_domain);
11288
11289   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11290   mp->ip4_prefix_len = ip4_prefix_len;
11291
11292   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11293   mp->ip6_prefix_len = ip6_prefix_len;
11294
11295   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11296   mp->ip6_src_prefix_len = ip6_src_len;
11297
11298   mp->ea_bits_len = ea_bits_len;
11299   mp->psid_offset = psid_offset;
11300   mp->psid_length = psid_length;
11301   mp->is_translation = is_translation;
11302   mp->mtu = htons (mtu);
11303
11304   /* send it... */
11305   S;
11306
11307   /* Wait for a reply, return good/bad news  */
11308   W;
11309 }
11310
11311 static int
11312 api_map_del_domain (vat_main_t * vam)
11313 {
11314   unformat_input_t *i = vam->input;
11315   vl_api_map_del_domain_t *mp;
11316   f64 timeout;
11317
11318   u32 num_m_args = 0;
11319   u32 index;
11320
11321   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11322     {
11323       if (unformat (i, "index %d", &index))
11324         num_m_args++;
11325       else
11326         {
11327           clib_warning ("parse error '%U'", format_unformat_error, i);
11328           return -99;
11329         }
11330     }
11331
11332   if (num_m_args != 1)
11333     {
11334       errmsg ("mandatory argument(s) missing\n");
11335       return -99;
11336     }
11337
11338   /* Construct the API message */
11339   M (MAP_DEL_DOMAIN, map_del_domain);
11340
11341   mp->index = ntohl (index);
11342
11343   /* send it... */
11344   S;
11345
11346   /* Wait for a reply, return good/bad news  */
11347   W;
11348 }
11349
11350 static int
11351 api_map_add_del_rule (vat_main_t * vam)
11352 {
11353   unformat_input_t *i = vam->input;
11354   vl_api_map_add_del_rule_t *mp;
11355   f64 timeout;
11356   u8 is_add = 1;
11357   ip6_address_t ip6_dst;
11358   u32 num_m_args = 0, index, psid = 0;
11359
11360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11361     {
11362       if (unformat (i, "index %d", &index))
11363         num_m_args++;
11364       else if (unformat (i, "psid %d", &psid))
11365         num_m_args++;
11366       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11367         num_m_args++;
11368       else if (unformat (i, "del"))
11369         {
11370           is_add = 0;
11371         }
11372       else
11373         {
11374           clib_warning ("parse error '%U'", format_unformat_error, i);
11375           return -99;
11376         }
11377     }
11378
11379   /* Construct the API message */
11380   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11381
11382   mp->index = ntohl (index);
11383   mp->is_add = is_add;
11384   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11385   mp->psid = ntohs (psid);
11386
11387   /* send it... */
11388   S;
11389
11390   /* Wait for a reply, return good/bad news  */
11391   W;
11392 }
11393
11394 static int
11395 api_map_domain_dump (vat_main_t * vam)
11396 {
11397   vl_api_map_domain_dump_t *mp;
11398   f64 timeout;
11399
11400   /* Construct the API message */
11401   M (MAP_DOMAIN_DUMP, map_domain_dump);
11402
11403   /* send it... */
11404   S;
11405
11406   /* Use a control ping for synchronization */
11407   {
11408     vl_api_control_ping_t *mp;
11409     M (CONTROL_PING, control_ping);
11410     S;
11411   }
11412   W;
11413 }
11414
11415 static int
11416 api_map_rule_dump (vat_main_t * vam)
11417 {
11418   unformat_input_t *i = vam->input;
11419   vl_api_map_rule_dump_t *mp;
11420   f64 timeout;
11421   u32 domain_index = ~0;
11422
11423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11424     {
11425       if (unformat (i, "index %u", &domain_index))
11426         ;
11427       else
11428         break;
11429     }
11430
11431   if (domain_index == ~0)
11432     {
11433       clib_warning ("parse error: domain index expected");
11434       return -99;
11435     }
11436
11437   /* Construct the API message */
11438   M (MAP_RULE_DUMP, map_rule_dump);
11439
11440   mp->domain_index = htonl (domain_index);
11441
11442   /* send it... */
11443   S;
11444
11445   /* Use a control ping for synchronization */
11446   {
11447     vl_api_control_ping_t *mp;
11448     M (CONTROL_PING, control_ping);
11449     S;
11450   }
11451   W;
11452 }
11453
11454 static void vl_api_map_add_domain_reply_t_handler
11455   (vl_api_map_add_domain_reply_t * mp)
11456 {
11457   vat_main_t *vam = &vat_main;
11458   i32 retval = ntohl (mp->retval);
11459
11460   if (vam->async_mode)
11461     {
11462       vam->async_errors += (retval < 0);
11463     }
11464   else
11465     {
11466       vam->retval = retval;
11467       vam->result_ready = 1;
11468     }
11469 }
11470
11471 static void vl_api_map_add_domain_reply_t_handler_json
11472   (vl_api_map_add_domain_reply_t * mp)
11473 {
11474   vat_main_t *vam = &vat_main;
11475   vat_json_node_t node;
11476
11477   vat_json_init_object (&node);
11478   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11479   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11480
11481   vat_json_print (vam->ofp, &node);
11482   vat_json_free (&node);
11483
11484   vam->retval = ntohl (mp->retval);
11485   vam->result_ready = 1;
11486 }
11487
11488 static int
11489 api_get_first_msg_id (vat_main_t * vam)
11490 {
11491   vl_api_get_first_msg_id_t *mp;
11492   f64 timeout;
11493   unformat_input_t *i = vam->input;
11494   u8 *name;
11495   u8 name_set = 0;
11496
11497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11498     {
11499       if (unformat (i, "client %s", &name))
11500         name_set = 1;
11501       else
11502         break;
11503     }
11504
11505   if (name_set == 0)
11506     {
11507       errmsg ("missing client name\n");
11508       return -99;
11509     }
11510   vec_add1 (name, 0);
11511
11512   if (vec_len (name) > 63)
11513     {
11514       errmsg ("client name too long\n");
11515       return -99;
11516     }
11517
11518   M (GET_FIRST_MSG_ID, get_first_msg_id);
11519   clib_memcpy (mp->name, name, vec_len (name));
11520   S;
11521   W;
11522   /* NOTREACHED */
11523   return 0;
11524 }
11525
11526 static int
11527 api_cop_interface_enable_disable (vat_main_t * vam)
11528 {
11529   unformat_input_t *line_input = vam->input;
11530   vl_api_cop_interface_enable_disable_t *mp;
11531   f64 timeout;
11532   u32 sw_if_index = ~0;
11533   u8 enable_disable = 1;
11534
11535   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11536     {
11537       if (unformat (line_input, "disable"))
11538         enable_disable = 0;
11539       if (unformat (line_input, "enable"))
11540         enable_disable = 1;
11541       else if (unformat (line_input, "%U", unformat_sw_if_index,
11542                          vam, &sw_if_index))
11543         ;
11544       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11545         ;
11546       else
11547         break;
11548     }
11549
11550   if (sw_if_index == ~0)
11551     {
11552       errmsg ("missing interface name or sw_if_index\n");
11553       return -99;
11554     }
11555
11556   /* Construct the API message */
11557   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11558   mp->sw_if_index = ntohl (sw_if_index);
11559   mp->enable_disable = enable_disable;
11560
11561   /* send it... */
11562   S;
11563   /* Wait for the reply */
11564   W;
11565 }
11566
11567 static int
11568 api_cop_whitelist_enable_disable (vat_main_t * vam)
11569 {
11570   unformat_input_t *line_input = vam->input;
11571   vl_api_cop_whitelist_enable_disable_t *mp;
11572   f64 timeout;
11573   u32 sw_if_index = ~0;
11574   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11575   u32 fib_id = 0;
11576
11577   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11578     {
11579       if (unformat (line_input, "ip4"))
11580         ip4 = 1;
11581       else if (unformat (line_input, "ip6"))
11582         ip6 = 1;
11583       else if (unformat (line_input, "default"))
11584         default_cop = 1;
11585       else if (unformat (line_input, "%U", unformat_sw_if_index,
11586                          vam, &sw_if_index))
11587         ;
11588       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11589         ;
11590       else if (unformat (line_input, "fib-id %d", &fib_id))
11591         ;
11592       else
11593         break;
11594     }
11595
11596   if (sw_if_index == ~0)
11597     {
11598       errmsg ("missing interface name or sw_if_index\n");
11599       return -99;
11600     }
11601
11602   /* Construct the API message */
11603   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
11604   mp->sw_if_index = ntohl (sw_if_index);
11605   mp->fib_id = ntohl (fib_id);
11606   mp->ip4 = ip4;
11607   mp->ip6 = ip6;
11608   mp->default_cop = default_cop;
11609
11610   /* send it... */
11611   S;
11612   /* Wait for the reply */
11613   W;
11614 }
11615
11616 static int
11617 api_get_node_graph (vat_main_t * vam)
11618 {
11619   vl_api_get_node_graph_t *mp;
11620   f64 timeout;
11621
11622   M (GET_NODE_GRAPH, get_node_graph);
11623
11624   /* send it... */
11625   S;
11626   /* Wait for the reply */
11627   W;
11628 }
11629
11630 /* *INDENT-OFF* */
11631 /** Used for parsing LISP eids */
11632 typedef CLIB_PACKED(struct{
11633   u8 addr[16];   /**< eid address */
11634   u32 len;       /**< prefix length if IP */
11635   u8 type;      /**< type of eid */
11636 }) lisp_eid_vat_t;
11637 /* *INDENT-ON* */
11638
11639 static uword
11640 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
11641 {
11642   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
11643
11644   memset (a, 0, sizeof (a[0]));
11645
11646   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
11647     {
11648       a->type = 0;              /* ipv4 type */
11649     }
11650   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
11651     {
11652       a->type = 1;              /* ipv6 type */
11653     }
11654   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
11655     {
11656       a->type = 2;              /* mac type */
11657     }
11658   else
11659     {
11660       return 0;
11661     }
11662
11663   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
11664     {
11665       return 0;
11666     }
11667
11668   return 1;
11669 }
11670
11671 static int
11672 lisp_eid_size_vat (u8 type)
11673 {
11674   switch (type)
11675     {
11676     case 0:
11677       return 4;
11678     case 1:
11679       return 16;
11680     case 2:
11681       return 6;
11682     }
11683   return 0;
11684 }
11685
11686 static void
11687 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
11688 {
11689   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
11690 }
11691
11692 /* *INDENT-OFF* */
11693 /** Used for transferring locators via VPP API */
11694 typedef CLIB_PACKED(struct
11695 {
11696   u32 sw_if_index; /**< locator sw_if_index */
11697   u8 priority; /**< locator priority */
11698   u8 weight;   /**< locator weight */
11699 }) ls_locator_t;
11700 /* *INDENT-ON* */
11701
11702 static int
11703 api_lisp_add_del_locator_set (vat_main_t * vam)
11704 {
11705   unformat_input_t *input = vam->input;
11706   vl_api_lisp_add_del_locator_set_t *mp;
11707   f64 timeout = ~0;
11708   u8 is_add = 1;
11709   u8 *locator_set_name = NULL;
11710   u8 locator_set_name_set = 0;
11711   ls_locator_t locator, *locators = 0;
11712   u32 sw_if_index, priority, weight;
11713
11714   /* Parse args required to build the message */
11715   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11716     {
11717       if (unformat (input, "del"))
11718         {
11719           is_add = 0;
11720         }
11721       else if (unformat (input, "locator-set %s", &locator_set_name))
11722         {
11723           locator_set_name_set = 1;
11724         }
11725       else if (unformat (input, "sw_if_index %u p %u w %u",
11726                          &sw_if_index, &priority, &weight))
11727         {
11728           locator.sw_if_index = htonl (sw_if_index);
11729           locator.priority = priority;
11730           locator.weight = weight;
11731           vec_add1 (locators, locator);
11732         }
11733       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
11734                          vam, &sw_if_index, &priority, &weight))
11735         {
11736           locator.sw_if_index = htonl (sw_if_index);
11737           locator.priority = priority;
11738           locator.weight = weight;
11739           vec_add1 (locators, locator);
11740         }
11741       else
11742         break;
11743     }
11744
11745   if (locator_set_name_set == 0)
11746     {
11747       errmsg ("missing locator-set name");
11748       vec_free (locators);
11749       return -99;
11750     }
11751
11752   if (vec_len (locator_set_name) > 64)
11753     {
11754       errmsg ("locator-set name too long\n");
11755       vec_free (locator_set_name);
11756       vec_free (locators);
11757       return -99;
11758     }
11759   vec_add1 (locator_set_name, 0);
11760
11761   /* Construct the API message */
11762   M (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
11763
11764   mp->is_add = is_add;
11765   clib_memcpy (mp->locator_set_name, locator_set_name,
11766                vec_len (locator_set_name));
11767   vec_free (locator_set_name);
11768
11769   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
11770   if (locators)
11771     clib_memcpy (mp->locators, locators,
11772                  (sizeof (ls_locator_t) * vec_len (locators)));
11773   vec_free (locators);
11774
11775   /* send it... */
11776   S;
11777
11778   /* Wait for a reply... */
11779   W;
11780
11781   /* NOTREACHED */
11782   return 0;
11783 }
11784
11785 static int
11786 api_lisp_add_del_locator (vat_main_t * vam)
11787 {
11788   unformat_input_t *input = vam->input;
11789   vl_api_lisp_add_del_locator_t *mp;
11790   f64 timeout = ~0;
11791   u32 tmp_if_index = ~0;
11792   u32 sw_if_index = ~0;
11793   u8 sw_if_index_set = 0;
11794   u8 sw_if_index_if_name_set = 0;
11795   u32 priority = ~0;
11796   u8 priority_set = 0;
11797   u32 weight = ~0;
11798   u8 weight_set = 0;
11799   u8 is_add = 1;
11800   u8 *locator_set_name = NULL;
11801   u8 locator_set_name_set = 0;
11802
11803   /* Parse args required to build the message */
11804   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11805     {
11806       if (unformat (input, "del"))
11807         {
11808           is_add = 0;
11809         }
11810       else if (unformat (input, "locator-set %s", &locator_set_name))
11811         {
11812           locator_set_name_set = 1;
11813         }
11814       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
11815                          &tmp_if_index))
11816         {
11817           sw_if_index_if_name_set = 1;
11818           sw_if_index = tmp_if_index;
11819         }
11820       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
11821         {
11822           sw_if_index_set = 1;
11823           sw_if_index = tmp_if_index;
11824         }
11825       else if (unformat (input, "p %d", &priority))
11826         {
11827           priority_set = 1;
11828         }
11829       else if (unformat (input, "w %d", &weight))
11830         {
11831           weight_set = 1;
11832         }
11833       else
11834         break;
11835     }
11836
11837   if (locator_set_name_set == 0)
11838     {
11839       errmsg ("missing locator-set name");
11840       return -99;
11841     }
11842
11843   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
11844     {
11845       errmsg ("missing sw_if_index");
11846       vec_free (locator_set_name);
11847       return -99;
11848     }
11849
11850   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
11851     {
11852       errmsg ("cannot use both params interface name and sw_if_index");
11853       vec_free (locator_set_name);
11854       return -99;
11855     }
11856
11857   if (priority_set == 0)
11858     {
11859       errmsg ("missing locator-set priority\n");
11860       vec_free (locator_set_name);
11861       return -99;
11862     }
11863
11864   if (weight_set == 0)
11865     {
11866       errmsg ("missing locator-set weight\n");
11867       vec_free (locator_set_name);
11868       return -99;
11869     }
11870
11871   if (vec_len (locator_set_name) > 64)
11872     {
11873       errmsg ("locator-set name too long\n");
11874       vec_free (locator_set_name);
11875       return -99;
11876     }
11877   vec_add1 (locator_set_name, 0);
11878
11879   /* Construct the API message */
11880   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
11881
11882   mp->is_add = is_add;
11883   mp->sw_if_index = ntohl (sw_if_index);
11884   mp->priority = priority;
11885   mp->weight = weight;
11886   clib_memcpy (mp->locator_set_name, locator_set_name,
11887                vec_len (locator_set_name));
11888   vec_free (locator_set_name);
11889
11890   /* send it... */
11891   S;
11892
11893   /* Wait for a reply... */
11894   W;
11895
11896   /* NOTREACHED */
11897   return 0;
11898 }
11899
11900 static int
11901 api_lisp_add_del_local_eid (vat_main_t * vam)
11902 {
11903   unformat_input_t *input = vam->input;
11904   vl_api_lisp_add_del_local_eid_t *mp;
11905   f64 timeout = ~0;
11906   u8 is_add = 1;
11907   u8 eid_set = 0;
11908   lisp_eid_vat_t _eid, *eid = &_eid;
11909   u8 *locator_set_name = 0;
11910   u8 locator_set_name_set = 0;
11911   u32 vni = 0;
11912
11913   /* Parse args required to build the message */
11914   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11915     {
11916       if (unformat (input, "del"))
11917         {
11918           is_add = 0;
11919         }
11920       else if (unformat (input, "vni %d", &vni))
11921         {
11922           ;
11923         }
11924       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
11925         {
11926           eid_set = 1;
11927         }
11928       else if (unformat (input, "locator-set %s", &locator_set_name))
11929         {
11930           locator_set_name_set = 1;
11931         }
11932       else
11933         break;
11934     }
11935
11936   if (locator_set_name_set == 0)
11937     {
11938       errmsg ("missing locator-set name\n");
11939       return -99;
11940     }
11941
11942   if (0 == eid_set)
11943     {
11944       errmsg ("EID address not set!");
11945       vec_free (locator_set_name);
11946       return -99;
11947     }
11948
11949   if (vec_len (locator_set_name) > 64)
11950     {
11951       errmsg ("locator-set name too long\n");
11952       vec_free (locator_set_name);
11953       return -99;
11954     }
11955   vec_add1 (locator_set_name, 0);
11956
11957   /* Construct the API message */
11958   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
11959
11960   mp->is_add = is_add;
11961   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
11962   mp->eid_type = eid->type;
11963   mp->prefix_len = eid->len;
11964   mp->vni = clib_host_to_net_u32 (vni);
11965   clib_memcpy (mp->locator_set_name, locator_set_name,
11966                vec_len (locator_set_name));
11967
11968   vec_free (locator_set_name);
11969
11970   /* send it... */
11971   S;
11972
11973   /* Wait for a reply... */
11974   W;
11975
11976   /* NOTREACHED */
11977   return 0;
11978 }
11979
11980 /* *INDENT-OFF* */
11981 /** Used for transferring locators via VPP API */
11982 typedef CLIB_PACKED(struct
11983 {
11984   u8 is_ip4; /**< is locator an IPv4 address? */
11985   u8 priority; /**< locator priority */
11986   u8 weight;   /**< locator weight */
11987   u8 addr[16]; /**< IPv4/IPv6 address */
11988 }) rloc_t;
11989 /* *INDENT-ON* */
11990
11991 static int
11992 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
11993 {
11994   unformat_input_t *input = vam->input;
11995   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
11996   f64 timeout = ~0;
11997   u8 is_add = 1;
11998   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
11999   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12000   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12001   u32 action = ~0, p, w;
12002   ip4_address_t rmt_rloc4, lcl_rloc4;
12003   ip6_address_t rmt_rloc6, lcl_rloc6;
12004   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12005
12006   memset (&rloc, 0, sizeof (rloc));
12007
12008   /* Parse args required to build the message */
12009   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12010     {
12011       if (unformat (input, "del"))
12012         {
12013           is_add = 0;
12014         }
12015       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12016         {
12017           rmt_eid_set = 1;
12018         }
12019       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12020         {
12021           lcl_eid_set = 1;
12022         }
12023       else if (unformat (input, "p %d w %d", &p, &w))
12024         {
12025           if (!curr_rloc)
12026             {
12027               errmsg ("No RLOC configured for setting priority/weight!");
12028               return -99;
12029             }
12030           curr_rloc->priority = p;
12031           curr_rloc->weight = w;
12032         }
12033       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12034                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12035         {
12036           rloc.is_ip4 = 1;
12037
12038           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12039           rloc.priority = rloc.weight = 0;
12040           vec_add1 (lcl_locs, rloc);
12041
12042           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12043           vec_add1 (rmt_locs, rloc);
12044           /* priority and weight saved in rmt loc */
12045           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12046         }
12047       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12048                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12049         {
12050           rloc.is_ip4 = 0;
12051           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12052           rloc.priority = rloc.weight = 0;
12053           vec_add1 (lcl_locs, rloc);
12054
12055           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12056           vec_add1 (rmt_locs, rloc);
12057           /* priority and weight saved in rmt loc */
12058           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12059         }
12060       else if (unformat (input, "action %d", &action))
12061         {
12062           ;
12063         }
12064       else
12065         {
12066           clib_warning ("parse error '%U'", format_unformat_error, input);
12067           return -99;
12068         }
12069     }
12070
12071   if (!rmt_eid_set)
12072     {
12073       errmsg ("remote eid addresses not set\n");
12074       return -99;
12075     }
12076
12077   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12078     {
12079       errmsg ("eid types don't match\n");
12080       return -99;
12081     }
12082
12083   if (0 == rmt_locs && (u32) ~ 0 == action)
12084     {
12085       errmsg ("action not set for negative mapping\n");
12086       return -99;
12087     }
12088
12089   /* Construct the API message */
12090   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12091
12092   mp->is_add = is_add;
12093   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12094   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12095   mp->eid_type = rmt_eid->type;
12096   mp->rmt_len = rmt_eid->len;
12097   mp->lcl_len = lcl_eid->len;
12098   mp->action = action;
12099
12100   if (0 != rmt_locs && 0 != lcl_locs)
12101     {
12102       mp->loc_num = vec_len (rmt_locs);
12103       clib_memcpy (mp->lcl_locs, lcl_locs,
12104                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12105       clib_memcpy (mp->rmt_locs, rmt_locs,
12106                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12107     }
12108   vec_free (lcl_locs);
12109   vec_free (rmt_locs);
12110
12111   /* send it... */
12112   S;
12113
12114   /* Wait for a reply... */
12115   W;
12116
12117   /* NOTREACHED */
12118   return 0;
12119 }
12120
12121 static int
12122 api_lisp_add_del_map_resolver (vat_main_t * vam)
12123 {
12124   unformat_input_t *input = vam->input;
12125   vl_api_lisp_add_del_map_resolver_t *mp;
12126   f64 timeout = ~0;
12127   u8 is_add = 1;
12128   u8 ipv4_set = 0;
12129   u8 ipv6_set = 0;
12130   ip4_address_t ipv4;
12131   ip6_address_t ipv6;
12132
12133   /* Parse args required to build the message */
12134   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12135     {
12136       if (unformat (input, "del"))
12137         {
12138           is_add = 0;
12139         }
12140       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12141         {
12142           ipv4_set = 1;
12143         }
12144       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12145         {
12146           ipv6_set = 1;
12147         }
12148       else
12149         break;
12150     }
12151
12152   if (ipv4_set && ipv6_set)
12153     {
12154       errmsg ("both eid v4 and v6 addresses set\n");
12155       return -99;
12156     }
12157
12158   if (!ipv4_set && !ipv6_set)
12159     {
12160       errmsg ("eid addresses not set\n");
12161       return -99;
12162     }
12163
12164   /* Construct the API message */
12165   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12166
12167   mp->is_add = is_add;
12168   if (ipv6_set)
12169     {
12170       mp->is_ipv6 = 1;
12171       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12172     }
12173   else
12174     {
12175       mp->is_ipv6 = 0;
12176       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12177     }
12178
12179   /* send it... */
12180   S;
12181
12182   /* Wait for a reply... */
12183   W;
12184
12185   /* NOTREACHED */
12186   return 0;
12187 }
12188
12189 static int
12190 api_lisp_gpe_enable_disable (vat_main_t * vam)
12191 {
12192   unformat_input_t *input = vam->input;
12193   vl_api_lisp_gpe_enable_disable_t *mp;
12194   f64 timeout = ~0;
12195   u8 is_set = 0;
12196   u8 is_en = 1;
12197
12198   /* Parse args required to build the message */
12199   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12200     {
12201       if (unformat (input, "enable"))
12202         {
12203           is_set = 1;
12204           is_en = 1;
12205         }
12206       else if (unformat (input, "disable"))
12207         {
12208           is_set = 1;
12209           is_en = 0;
12210         }
12211       else
12212         break;
12213     }
12214
12215   if (is_set == 0)
12216     {
12217       errmsg ("Value not set\n");
12218       return -99;
12219     }
12220
12221   /* Construct the API message */
12222   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12223
12224   mp->is_en = is_en;
12225
12226   /* send it... */
12227   S;
12228
12229   /* Wait for a reply... */
12230   W;
12231
12232   /* NOTREACHED */
12233   return 0;
12234 }
12235
12236 static int
12237 api_lisp_enable_disable (vat_main_t * vam)
12238 {
12239   unformat_input_t *input = vam->input;
12240   vl_api_lisp_enable_disable_t *mp;
12241   f64 timeout = ~0;
12242   u8 is_set = 0;
12243   u8 is_en = 0;
12244
12245   /* Parse args required to build the message */
12246   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12247     {
12248       if (unformat (input, "enable"))
12249         {
12250           is_set = 1;
12251           is_en = 1;
12252         }
12253       else if (unformat (input, "disable"))
12254         {
12255           is_set = 1;
12256         }
12257       else
12258         break;
12259     }
12260
12261   if (!is_set)
12262     {
12263       errmsg ("Value not set\n");
12264       return -99;
12265     }
12266
12267   /* Construct the API message */
12268   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12269
12270   mp->is_en = is_en;
12271
12272   /* send it... */
12273   S;
12274
12275   /* Wait for a reply... */
12276   W;
12277
12278   /* NOTREACHED */
12279   return 0;
12280 }
12281
12282 /**
12283  * Enable/disable LISP proxy ITR.
12284  *
12285  * @param vam vpp API test context
12286  * @return return code
12287  */
12288 static int
12289 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12290 {
12291   f64 timeout = ~0;
12292   u8 ls_name_set = 0;
12293   unformat_input_t *input = vam->input;
12294   vl_api_lisp_pitr_set_locator_set_t *mp;
12295   u8 is_add = 1;
12296   u8 *ls_name = 0;
12297
12298   /* Parse args required to build the message */
12299   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12300     {
12301       if (unformat (input, "del"))
12302         is_add = 0;
12303       else if (unformat (input, "locator-set %s", &ls_name))
12304         ls_name_set = 1;
12305       else
12306         {
12307           errmsg ("parse error '%U'", format_unformat_error, input);
12308           return -99;
12309         }
12310     }
12311
12312   if (!ls_name_set)
12313     {
12314       errmsg ("locator-set name not set!");
12315       return -99;
12316     }
12317
12318   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12319
12320   mp->is_add = is_add;
12321   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12322   vec_free (ls_name);
12323
12324   /* send */
12325   S;
12326
12327   /* wait for reply */
12328   W;
12329
12330   /* notreached */
12331   return 0;
12332 }
12333
12334 static int
12335 api_show_lisp_pitr (vat_main_t * vam)
12336 {
12337   vl_api_show_lisp_pitr_t *mp;
12338   f64 timeout = ~0;
12339
12340   if (!vam->json_output)
12341     {
12342       fformat (vam->ofp, "%=20s\n", "lisp status:");
12343     }
12344
12345   M (SHOW_LISP_PITR, show_lisp_pitr);
12346   /* send it... */
12347   S;
12348
12349   /* Wait for a reply... */
12350   W;
12351
12352   /* NOTREACHED */
12353   return 0;
12354 }
12355
12356 /**
12357  * Add/delete mapping between vni and vrf
12358  */
12359 static int
12360 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12361 {
12362   f64 timeout = ~0;
12363   unformat_input_t *input = vam->input;
12364   vl_api_lisp_eid_table_add_del_map_t *mp;
12365   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12366   u32 vni, vrf, bd_index;
12367
12368   /* Parse args required to build the message */
12369   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12370     {
12371       if (unformat (input, "del"))
12372         is_add = 0;
12373       else if (unformat (input, "vrf %d", &vrf))
12374         vrf_set = 1;
12375       else if (unformat (input, "bd_index %d", &bd_index))
12376         bd_index_set = 1;
12377       else if (unformat (input, "vni %d", &vni))
12378         vni_set = 1;
12379       else
12380         break;
12381     }
12382
12383   if (!vni_set || (!vrf_set && !bd_index_set))
12384     {
12385       errmsg ("missing arguments!");
12386       return -99;
12387     }
12388
12389   if (vrf_set && bd_index_set)
12390     {
12391       errmsg ("error: both vrf and bd entered!");
12392       return -99;
12393     }
12394
12395   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12396
12397   mp->is_add = is_add;
12398   mp->vni = htonl (vni);
12399   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
12400   mp->is_l2 = bd_index_set;
12401
12402   /* send */
12403   S;
12404
12405   /* wait for reply */
12406   W;
12407
12408   /* notreached */
12409   return 0;
12410 }
12411
12412 /**
12413  * Add/del remote mapping to/from LISP control plane
12414  *
12415  * @param vam vpp API test context
12416  * @return return code
12417  */
12418 static int
12419 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12420 {
12421   unformat_input_t *input = vam->input;
12422   vl_api_lisp_add_del_remote_mapping_t *mp;
12423   f64 timeout = ~0;
12424   u32 vni = 0;
12425   //TODO: seid need remove
12426   lisp_eid_vat_t _eid, *eid = &_eid;
12427   lisp_eid_vat_t _seid, *seid = &_seid;
12428   u8 is_add = 1, del_all = 0, eid_set = 0;
12429   u32 action = ~0, p, w;
12430   ip4_address_t rloc4;
12431   ip6_address_t rloc6;
12432   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12433
12434   memset (&rloc, 0, sizeof (rloc));
12435
12436   /* Parse args required to build the message */
12437   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12438     {
12439       if (unformat (input, "del-all"))
12440         {
12441           del_all = 1;
12442         }
12443       else if (unformat (input, "del"))
12444         {
12445           is_add = 0;
12446         }
12447       else if (unformat (input, "add"))
12448         {
12449           is_add = 1;
12450         }
12451       else if (unformat (input, "deid %U", unformat_lisp_eid_vat, eid))
12452         {
12453           eid_set = 1;
12454         }
12455       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, &seid))
12456         {
12457           //TODO: Need remove, but first must be remove from CSIT test
12458         }
12459       else if (unformat (input, "vni %d", &vni))
12460         {
12461           ;
12462         }
12463       else if (unformat (input, "p %d w %d", &p, &w))
12464         {
12465           if (!curr_rloc)
12466             {
12467               errmsg ("No RLOC configured for setting priority/weight!");
12468               return -99;
12469             }
12470           curr_rloc->priority = p;
12471           curr_rloc->weight = w;
12472         }
12473       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12474         {
12475           rloc.is_ip4 = 1;
12476           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12477           vec_add1 (rlocs, rloc);
12478           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12479         }
12480       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12481         {
12482           rloc.is_ip4 = 0;
12483           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12484           vec_add1 (rlocs, rloc);
12485           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12486         }
12487       else if (unformat (input, "action %d", &action))
12488         {
12489           ;
12490         }
12491       else
12492         {
12493           clib_warning ("parse error '%U'", format_unformat_error, input);
12494           return -99;
12495         }
12496     }
12497
12498   if (0 == eid_set)
12499     {
12500       errmsg ("missing params!");
12501       return -99;
12502     }
12503
12504   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12505     {
12506       errmsg ("no action set for negative map-reply!");
12507       return -99;
12508     }
12509
12510   M (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
12511   mp->is_add = is_add;
12512   mp->vni = htonl (vni);
12513   mp->action = (u8) action;
12514   mp->eid_len = eid->len;
12515   mp->del_all = del_all;
12516   mp->eid_type = eid->type;
12517   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12518
12519   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
12520   clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
12521   vec_free (rlocs);
12522
12523   /* send it... */
12524   S;
12525
12526   /* Wait for a reply... */
12527   W;
12528
12529   /* NOTREACHED */
12530   return 0;
12531 }
12532
12533 /**
12534  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
12535  * forwarding entries in data-plane accordingly.
12536  *
12537  * @param vam vpp API test context
12538  * @return return code
12539  */
12540 static int
12541 api_lisp_add_del_adjacency (vat_main_t * vam)
12542 {
12543   unformat_input_t *input = vam->input;
12544   vl_api_lisp_add_del_adjacency_t *mp;
12545   f64 timeout = ~0;
12546   u32 vni = 0;
12547   ip4_address_t seid4, deid4;
12548   ip6_address_t seid6, deid6;
12549   u8 deid_mac[6] = { 0 };
12550   u8 seid_mac[6] = { 0 };
12551   u8 deid_type, seid_type;
12552   u32 seid_len = 0, deid_len = 0, len;
12553   u8 is_add = 1;
12554
12555   seid_type = deid_type = (u8) ~ 0;
12556
12557   /* Parse args required to build the message */
12558   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12559     {
12560       if (unformat (input, "del"))
12561         {
12562           is_add = 0;
12563         }
12564       else if (unformat (input, "add"))
12565         {
12566           is_add = 1;
12567         }
12568       else if (unformat (input, "deid %U/%d", unformat_ip4_address,
12569                          &deid4, &len))
12570         {
12571           deid_type = 0;        /* ipv4 */
12572           deid_len = len;
12573         }
12574       else if (unformat (input, "deid %U/%d", unformat_ip6_address,
12575                          &deid6, &len))
12576         {
12577           deid_type = 1;        /* ipv6 */
12578           deid_len = len;
12579         }
12580       else if (unformat (input, "deid %U", unformat_ethernet_address,
12581                          deid_mac))
12582         {
12583           deid_type = 2;        /* mac */
12584         }
12585       else if (unformat (input, "seid %U/%d", unformat_ip4_address,
12586                          &seid4, &len))
12587         {
12588           seid_type = 0;        /* ipv4 */
12589           seid_len = len;
12590         }
12591       else if (unformat (input, "seid %U/%d", unformat_ip6_address,
12592                          &seid6, &len))
12593         {
12594           seid_type = 1;        /* ipv6 */
12595           seid_len = len;
12596         }
12597       else if (unformat (input, "seid %U", unformat_ethernet_address,
12598                          seid_mac))
12599         {
12600           seid_type = 2;        /* mac */
12601         }
12602       else if (unformat (input, "vni %d", &vni))
12603         {
12604           ;
12605         }
12606       else
12607         {
12608           errmsg ("parse error '%U'", format_unformat_error, input);
12609           return -99;
12610         }
12611     }
12612
12613   if ((u8) ~ 0 == deid_type)
12614     {
12615       errmsg ("missing params!");
12616       return -99;
12617     }
12618
12619   if (seid_type != deid_type)
12620     {
12621       errmsg ("source and destination EIDs are of different types!");
12622       return -99;
12623     }
12624
12625   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
12626   mp->is_add = is_add;
12627   mp->vni = htonl (vni);
12628   mp->seid_len = seid_len;
12629   mp->deid_len = deid_len;
12630   mp->eid_type = deid_type;
12631
12632   switch (mp->eid_type)
12633     {
12634     case 0:
12635       clib_memcpy (mp->seid, &seid4, sizeof (seid4));
12636       clib_memcpy (mp->deid, &deid4, sizeof (deid4));
12637       break;
12638     case 1:
12639       clib_memcpy (mp->seid, &seid6, sizeof (seid6));
12640       clib_memcpy (mp->deid, &deid6, sizeof (deid6));
12641       break;
12642     case 2:
12643       clib_memcpy (mp->seid, seid_mac, 6);
12644       clib_memcpy (mp->deid, deid_mac, 6);
12645       break;
12646     default:
12647       errmsg ("unknown EID type %d!", mp->eid_type);
12648       return 0;
12649     }
12650
12651   /* send it... */
12652   S;
12653
12654   /* Wait for a reply... */
12655   W;
12656
12657   /* NOTREACHED */
12658   return 0;
12659 }
12660
12661 static int
12662 api_lisp_gpe_add_del_iface (vat_main_t * vam)
12663 {
12664   unformat_input_t *input = vam->input;
12665   vl_api_lisp_gpe_add_del_iface_t *mp;
12666   f64 timeout = ~0;
12667   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
12668   u32 dp_table = 0, vni = 0;
12669
12670   /* Parse args required to build the message */
12671   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12672     {
12673       if (unformat (input, "up"))
12674         {
12675           action_set = 1;
12676           is_add = 1;
12677         }
12678       else if (unformat (input, "down"))
12679         {
12680           action_set = 1;
12681           is_add = 0;
12682         }
12683       else if (unformat (input, "table_id %d", &dp_table))
12684         {
12685           dp_table_set = 1;
12686         }
12687       else if (unformat (input, "bd_id %d", &dp_table))
12688         {
12689           dp_table_set = 1;
12690           is_l2 = 1;
12691         }
12692       else if (unformat (input, "vni %d", &vni))
12693         {
12694           vni_set = 1;
12695         }
12696       else
12697         break;
12698     }
12699
12700   if (action_set == 0)
12701     {
12702       errmsg ("Action not set\n");
12703       return -99;
12704     }
12705   if (dp_table_set == 0 || vni_set == 0)
12706     {
12707       errmsg ("vni and dp_table must be set\n");
12708       return -99;
12709     }
12710
12711   /* Construct the API message */
12712   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
12713
12714   mp->is_add = is_add;
12715   mp->dp_table = dp_table;
12716   mp->is_l2 = is_l2;
12717   mp->vni = vni;
12718
12719   /* send it... */
12720   S;
12721
12722   /* Wait for a reply... */
12723   W;
12724
12725   /* NOTREACHED */
12726   return 0;
12727 }
12728
12729 /**
12730  * Add/del map request itr rlocs from LISP control plane and updates
12731  *
12732  * @param vam vpp API test context
12733  * @return return code
12734  */
12735 static int
12736 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
12737 {
12738   unformat_input_t *input = vam->input;
12739   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
12740   f64 timeout = ~0;
12741   u8 *locator_set_name = 0;
12742   u8 locator_set_name_set = 0;
12743   u8 is_add = 1;
12744
12745   /* Parse args required to build the message */
12746   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12747     {
12748       if (unformat (input, "del"))
12749         {
12750           is_add = 0;
12751         }
12752       else if (unformat (input, "%_%v%_", &locator_set_name))
12753         {
12754           locator_set_name_set = 1;
12755         }
12756       else
12757         {
12758           clib_warning ("parse error '%U'", format_unformat_error, input);
12759           return -99;
12760         }
12761     }
12762
12763   if (is_add && !locator_set_name_set)
12764     {
12765       errmsg ("itr-rloc is not set!");
12766       return -99;
12767     }
12768
12769   if (is_add && vec_len (locator_set_name) > 64)
12770     {
12771       errmsg ("itr-rloc locator-set name too long\n");
12772       vec_free (locator_set_name);
12773       return -99;
12774     }
12775
12776   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
12777   mp->is_add = is_add;
12778   if (is_add)
12779     {
12780       clib_memcpy (mp->locator_set_name, locator_set_name,
12781                    vec_len (locator_set_name));
12782     }
12783   else
12784     {
12785       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
12786     }
12787   vec_free (locator_set_name);
12788
12789   /* send it... */
12790   S;
12791
12792   /* Wait for a reply... */
12793   W;
12794
12795   /* NOTREACHED */
12796   return 0;
12797 }
12798
12799 static int
12800 lisp_locator_dump_send_msg (vat_main_t * vam, u32 locator_set_index,
12801                             u8 filter)
12802 {
12803   vl_api_lisp_locator_dump_t *mp;
12804   f64 timeout = ~0;
12805
12806   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
12807
12808   mp->locator_set_index = htonl (locator_set_index);
12809   mp->filter = filter;
12810
12811   /* send it... */
12812   S;
12813
12814   /* Use a control ping for synchronization */
12815   {
12816     vl_api_noprint_control_ping_t *mp;
12817     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12818     S;
12819   }
12820   /* Wait for a reply... */
12821   W;
12822 }
12823
12824 static inline void
12825 clean_locator_set_message (vat_main_t * vam)
12826 {
12827   locator_set_msg_t *ls = 0;
12828
12829   vec_foreach (ls, vam->locator_set_msg)
12830   {
12831     vec_free (ls->locator_set_name);
12832   }
12833
12834   vec_free (vam->locator_set_msg);
12835 }
12836
12837 static int
12838 print_locator_in_locator_set (vat_main_t * vam, u8 filter)
12839 {
12840   locator_set_msg_t *ls;
12841   locator_msg_t *loc;
12842   u8 *tmp_str = 0;
12843   int i = 0, ret = 0;
12844
12845   vec_foreach (ls, vam->locator_set_msg)
12846   {
12847     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12848     if (ret)
12849       {
12850         vec_free (vam->locator_msg);
12851         clean_locator_set_message (vam);
12852         return ret;
12853       }
12854
12855     tmp_str = format (0, "%=20s%=16d%s", ls->locator_set_name,
12856                       ls->locator_set_index,
12857                       vec_len (vam->locator_msg) ? "" : "\n");
12858     i = 0;
12859     vec_foreach (loc, vam->locator_msg)
12860     {
12861       if (i)
12862         {
12863           tmp_str = format (tmp_str, "%=37s", " ");
12864         }
12865       if (loc->local)
12866         {
12867           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
12868                             loc->sw_if_index, loc->priority, loc->weight);
12869         }
12870       else
12871         {
12872           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
12873                             loc->is_ipv6 ? format_ip6_address :
12874                             format_ip4_address,
12875                             loc->ip_address, loc->priority, loc->weight);
12876         }
12877       i++;
12878     }
12879
12880     fformat (vam->ofp, "%s", tmp_str);
12881     vec_free (tmp_str);
12882     vec_free (vam->locator_msg);
12883   }
12884
12885   clean_locator_set_message (vam);
12886
12887   return ret;
12888 }
12889
12890 static int
12891 json_locator_in_locator_set (vat_main_t * vam, u8 filter)
12892 {
12893   locator_set_msg_t *ls;
12894   locator_msg_t *loc;
12895   vat_json_node_t *node = NULL;
12896   vat_json_node_t *locator_array;
12897   vat_json_node_t *locator;
12898   struct in6_addr ip6;
12899   struct in_addr ip4;
12900   int ret = 0;
12901
12902   if (!vec_len (vam->locator_set_msg))
12903     {
12904       /* just print [] */
12905       vat_json_init_array (&vam->json_tree);
12906       vat_json_print (vam->ofp, &vam->json_tree);
12907       vam->json_tree.type = VAT_JSON_NONE;
12908       return ret;
12909     }
12910
12911   if (VAT_JSON_ARRAY != vam->json_tree.type)
12912     {
12913       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12914       vat_json_init_array (&vam->json_tree);
12915     }
12916
12917   vec_foreach (ls, vam->locator_set_msg)
12918   {
12919     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12920     if (ret)
12921       {
12922         vec_free (ls->locator_set_name);
12923         vec_free (vam->locator_msg);
12924         vec_free (vam->locator_set_msg);
12925         vat_json_free (&vam->json_tree);
12926         vam->json_tree.type = VAT_JSON_NONE;
12927         return ret;
12928       }
12929
12930     node = vat_json_array_add (&vam->json_tree);
12931     vat_json_init_object (node);
12932
12933     vat_json_object_add_uint (node, "locator-set-index",
12934                               ls->locator_set_index);
12935     vat_json_object_add_string_copy (node, "locator-set",
12936                                      ls->locator_set_name);
12937     locator_array = vat_json_object_add_list (node, "locator");
12938     vec_foreach (loc, vam->locator_msg)
12939     {
12940       locator = vat_json_array_add (locator_array);
12941       vat_json_init_object (locator);
12942       if (loc->local)
12943         {
12944           vat_json_object_add_uint (locator, "locator-index",
12945                                     loc->sw_if_index);
12946         }
12947       else
12948         {
12949           if (loc->is_ipv6)
12950             {
12951               clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
12952               vat_json_object_add_ip6 (locator, "locator", ip6);
12953             }
12954           else
12955             {
12956               clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
12957               vat_json_object_add_ip4 (locator, "locator", ip4);
12958             }
12959         }
12960       vat_json_object_add_uint (locator, "priority", loc->priority);
12961       vat_json_object_add_uint (locator, "weight", loc->weight);
12962     }
12963
12964     vec_free (ls->locator_set_name);
12965     vec_free (vam->locator_msg);
12966   }
12967
12968   vat_json_print (vam->ofp, &vam->json_tree);
12969   vat_json_free (&vam->json_tree);
12970   vam->json_tree.type = VAT_JSON_NONE;
12971
12972   vec_free (vam->locator_set_msg);
12973
12974   return ret;
12975 }
12976
12977 static int
12978 get_locator_set_index_from_msg (vat_main_t * vam, u8 * locator_set,
12979                                 u32 * locator_set_index)
12980 {
12981   locator_set_msg_t *ls;
12982   int ret = 0;
12983
12984   *locator_set_index = ~0;
12985
12986   if (!vec_len (vam->locator_set_msg))
12987     {
12988       return ret;
12989     }
12990
12991   vec_foreach (ls, vam->locator_set_msg)
12992   {
12993     if (!strcmp ((char *) locator_set, (char *) ls->locator_set_name))
12994       {
12995         *locator_set_index = ls->locator_set_index;
12996         vec_free (vam->locator_set_msg);
12997         return ret;
12998       }
12999   }
13000
13001   vec_free (vam->locator_set_msg);
13002
13003   return ret;
13004 }
13005
13006 static int
13007 get_locator_set_index (vat_main_t * vam, u8 * locator_set,
13008                        u32 * locator_set_index)
13009 {
13010   vl_api_lisp_locator_set_dump_t *mp;
13011   f64 timeout = ~0;
13012
13013   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13014   /* send it... */
13015   S;
13016
13017   /* Use a control ping for synchronization */
13018   {
13019     vl_api_noprint_control_ping_t *mp;
13020     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13021     S;
13022   }
13023
13024   vam->noprint_msg = 1;
13025   /* Wait for a reply... */
13026   /* *INDENT-OFF* */
13027   W_L
13028   ({
13029     get_locator_set_index_from_msg (vam, locator_set, locator_set_index);
13030     vam->noprint_msg = 0;
13031   });
13032   /* *INDENT-ON* */
13033
13034   /* NOTREACHED */
13035   return 0;
13036 }
13037
13038 static inline int
13039 lisp_locator_dump (vat_main_t * vam, u32 locator_set_index, u8 * locator_set,
13040                    u8 filter)
13041 {
13042   int ret = 0;
13043
13044   ASSERT (vam);
13045
13046   if (!vam->json_output)
13047     {
13048       fformat (vam->ofp, "%=20s%=16s%=16s\n",
13049                "locator", "priority", "weight");
13050     }
13051
13052   if (locator_set)
13053     {
13054       ret = get_locator_set_index (vam, locator_set, &locator_set_index);
13055     }
13056
13057   if (!ret && ~0 == locator_set_index)
13058     {
13059       return -99;
13060     }
13061
13062   ret = lisp_locator_dump_send_msg (vam, locator_set_index, filter);
13063
13064   return ret;
13065 }
13066
13067 static int
13068 lisp_locator_set_dump (vat_main_t * vam, u8 filter)
13069 {
13070   vl_api_lisp_locator_set_dump_t *mp;
13071   f64 timeout = ~0;
13072
13073   if (!vam->json_output)
13074     {
13075       fformat (vam->ofp, "%=20s%=16s%=16s%=16s%=16s\n",
13076                "locator-set", "locator-set-index", "locator", "priority",
13077                "weight");
13078     }
13079
13080   vam->noprint_msg = 1;
13081
13082   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13083
13084   mp->filter = filter;
13085
13086   /* send it... */
13087   S;
13088
13089   /* Use a control ping for synchronization */
13090   {
13091     vl_api_noprint_control_ping_t *mp;
13092     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13093     S;
13094   }
13095
13096   /* Wait for a reply... */
13097   /* *INDENT-OFF* */
13098   W_L
13099   ({
13100     if (vam->noprint_msg)
13101       {
13102         if (!vam->json_output)
13103           {
13104             print_locator_in_locator_set(vam, filter);
13105           }
13106         else
13107           {
13108             json_locator_in_locator_set(vam, filter);
13109           }
13110       }
13111     vam->noprint_msg = 0;
13112   });
13113   /* *INDENT-ON* */
13114
13115   /* NOTREACHED */
13116   return 0;
13117 }
13118
13119 static int
13120 api_lisp_locator_set_dump (vat_main_t * vam)
13121 {
13122   unformat_input_t *input = vam->input;
13123   vam->noprint_msg = 0;
13124   u32 locator_set_index = ~0;
13125   u8 locator_set_index_set = 0;
13126   u8 *locator_set = 0;
13127   u8 locator_set_set = 0;
13128   u8 filter = 0;
13129   int ret = 0;
13130
13131   /* Parse args required to build the message */
13132   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13133     {
13134       if (unformat (input, "locator-set-index %u", &locator_set_index))
13135         {
13136           locator_set_index_set = 1;
13137         }
13138       else if (unformat (input, "locator-set %s", &locator_set))
13139         {
13140           locator_set_set = 1;
13141         }
13142       else if (unformat (input, "local"))
13143         {
13144           filter = 1;
13145         }
13146       else if (unformat (input, "remote"))
13147         {
13148           filter = 2;
13149         }
13150       else
13151         {
13152           break;
13153         }
13154     }
13155
13156   if (locator_set_index_set && locator_set_set)
13157     {
13158       errmsg ("use only input parameter!\n");
13159       return -99;
13160     }
13161
13162   if (locator_set_index_set || locator_set_set)
13163     {
13164       ret = lisp_locator_dump (vam, locator_set_index, locator_set, filter);
13165     }
13166   else
13167     {
13168       ret = lisp_locator_set_dump (vam, filter);
13169     }
13170
13171   vec_free (locator_set);
13172
13173   return ret;
13174 }
13175
13176 static int
13177 api_lisp_eid_table_map_dump (vat_main_t * vam)
13178 {
13179   u8 is_l2 = 0;
13180   u8 mode_set = 0;
13181   unformat_input_t *input = vam->input;
13182   vl_api_lisp_eid_table_map_dump_t *mp;
13183   f64 timeout = ~0;
13184
13185   /* Parse args required to build the message */
13186   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13187     {
13188       if (unformat (input, "l2"))
13189         {
13190           is_l2 = 1;
13191           mode_set = 1;
13192         }
13193       else if (unformat (input, "l3"))
13194         {
13195           is_l2 = 0;
13196           mode_set = 1;
13197         }
13198       else
13199         {
13200           errmsg ("parse error '%U'", format_unformat_error, input);
13201           return -99;
13202         }
13203     }
13204
13205   if (!mode_set)
13206     {
13207       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13208       return -99;
13209     }
13210
13211   if (!vam->json_output)
13212     {
13213       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13214     }
13215
13216   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13217   mp->is_l2 = is_l2;
13218
13219   /* send it... */
13220   S;
13221
13222   /* Use a control ping for synchronization */
13223   {
13224     vl_api_control_ping_t *mp;
13225     M (CONTROL_PING, control_ping);
13226     S;
13227   }
13228   /* Wait for a reply... */
13229   W;
13230
13231   /* NOTREACHED */
13232   return 0;
13233 }
13234
13235 static int
13236 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13237 {
13238   vl_api_lisp_eid_table_vni_dump_t *mp;
13239   f64 timeout = ~0;
13240
13241   if (!vam->json_output)
13242     {
13243       fformat (vam->ofp, "VNI\n");
13244     }
13245
13246   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13247
13248   /* send it... */
13249   S;
13250
13251   /* Use a control ping for synchronization */
13252   {
13253     vl_api_control_ping_t *mp;
13254     M (CONTROL_PING, control_ping);
13255     S;
13256   }
13257   /* Wait for a reply... */
13258   W;
13259
13260   /* NOTREACHED */
13261   return 0;
13262 }
13263
13264 static int
13265 get_locator_set (vat_main_t * vam)
13266 {
13267   vl_api_lisp_locator_set_dump_t *mp;
13268   f64 timeout = ~0;
13269
13270   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13271   /* send it... */
13272   S;
13273
13274   /* Use a control ping for synchronization */
13275   {
13276     vl_api_noprint_control_ping_t *mp;
13277     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13278     S;
13279   }
13280
13281   /* Wait for a reply... */
13282   W;
13283
13284   /* NOTREACHED */
13285   return 0;
13286 }
13287
13288 static inline u8 *
13289 format_eid_for_eid_table (vat_main_t * vam, u8 * str, eid_table_t * eid_table,
13290                           int *ret)
13291 {
13292   u8 *(*format_eid) (u8 *, va_list *) = 0;
13293
13294   ASSERT (vam != NULL);
13295   ASSERT (eid_table != NULL);
13296
13297   if (ret)
13298     {
13299       *ret = 0;
13300     }
13301
13302   switch (eid_table->eid_type)
13303     {
13304     case 0:
13305     case 1:
13306       format_eid = (eid_table->eid_type ? format_ip6_address :
13307                     format_ip4_address);
13308       str = format (0, "[%d] %U/%d", eid_table->vni,
13309                     format_eid, eid_table->eid, eid_table->eid_prefix_len);
13310       break;
13311     case 2:
13312       str = format (0, "[%d] %U", eid_table->vni,
13313                     format_ethernet_address, eid_table->eid);
13314       break;
13315     default:
13316       errmsg ("unknown EID type %d!", eid_table->eid_type);
13317       if (ret)
13318         {
13319           *ret = -99;
13320         }
13321       return 0;
13322     }
13323
13324   return str;
13325 }
13326
13327 static inline u8 *
13328 format_locator_set_for_eid_table (vat_main_t * vam, u8 * str,
13329                                   eid_table_t * eid_table)
13330 {
13331   locator_set_msg_t *ls = 0;
13332
13333   ASSERT (vam != NULL);
13334   ASSERT (eid_table != NULL);
13335
13336   if (eid_table->is_local)
13337     {
13338       vec_foreach (ls, vam->locator_set_msg)
13339       {
13340         if (ls->locator_set_index == eid_table->locator_set_index)
13341           {
13342             str = format (0, "local(%s)", ls->locator_set_name);
13343             return str;
13344           }
13345       }
13346
13347       str = format (0, "local(N/A)");
13348     }
13349   else
13350     {
13351       str = format (0, "remote");
13352     }
13353
13354   return str;
13355 }
13356
13357 static inline u8 *
13358 format_locator_for_eid_table (vat_main_t * vam, u8 * str,
13359                               eid_table_t * eid_table)
13360 {
13361   locator_msg_t *loc = 0;
13362   int first_line = 1;
13363
13364   ASSERT (vam != NULL);
13365   ASSERT (eid_table != NULL);
13366
13367   if (~0 == eid_table->locator_set_index)
13368     {
13369       return format (0, "action: %d\n", eid_table->action);
13370     }
13371
13372   vec_foreach (loc, vam->locator_msg)
13373   {
13374     if (!first_line)
13375       {
13376         if (loc->local)
13377           {
13378             str = format (str, "%-55s%-d\n", " ", loc->sw_if_index);
13379           }
13380         else
13381           {
13382             str = format (str, "%=55s%-U\n", " ",
13383                           loc->is_ipv6 ? format_ip6_address :
13384                           format_ip4_address, loc->ip_address);
13385           }
13386
13387         continue;
13388       }
13389
13390     if (loc->local)
13391       {
13392         str = format (str, "%-30d%-20u%-u\n", loc->sw_if_index,
13393                       eid_table->ttl, eid_table->authoritative);
13394       }
13395     else
13396       {
13397         str = format (str, "%-30U%-20u%-u\n",
13398                       loc->is_ipv6 ? format_ip6_address :
13399                       format_ip4_address,
13400                       loc->ip_address, eid_table->ttl,
13401                       eid_table->authoritative);
13402       }
13403     first_line = 0;
13404   }
13405
13406   return str;
13407 }
13408
13409 static int
13410 print_lisp_eid_table_dump (vat_main_t * vam)
13411 {
13412   eid_table_t *eid_table = 0;
13413   u8 *tmp_str = 0, *tmp_str2 = 0;
13414   int ret = 0;
13415
13416   ASSERT (vam != NULL);
13417
13418   ret = get_locator_set (vam);
13419   if (ret)
13420     {
13421       vec_free (vam->eid_tables);
13422       return ret;
13423     }
13424
13425   fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type", "locators",
13426            "ttl", "authoritative");
13427
13428   vec_foreach (eid_table, vam->eid_tables)
13429   {
13430     if (~0 != eid_table->locator_set_index)
13431       {
13432         ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index,
13433                                           0);
13434         if (ret)
13435           {
13436             vec_free (vam->locator_msg);
13437             clean_locator_set_message (vam);
13438             vec_free (vam->eid_tables);
13439             return ret;
13440           }
13441       }
13442
13443     tmp_str2 = format_eid_for_eid_table (vam, tmp_str2, eid_table, &ret);
13444     if (ret)
13445       {
13446         vec_free (vam->locator_msg);
13447         clean_locator_set_message (vam);
13448         vec_free (vam->eid_tables);
13449         return ret;
13450       }
13451
13452     tmp_str = format (0, "%-35s", tmp_str2);
13453     vec_free (tmp_str2);
13454
13455     tmp_str2 = format_locator_set_for_eid_table (vam, tmp_str2, eid_table);
13456     tmp_str = format (tmp_str, "%-20s", tmp_str2);
13457     vec_free (tmp_str2);
13458
13459     tmp_str2 = format_locator_for_eid_table (vam, tmp_str2, eid_table);
13460     tmp_str = format (tmp_str, "%-s", tmp_str2);
13461     vec_free (tmp_str2);
13462
13463     fformat (vam->ofp, "%s", tmp_str);
13464     vec_free (tmp_str);
13465     vec_free (vam->locator_msg);
13466   }
13467
13468   clean_locator_set_message (vam);
13469   vec_free (vam->eid_tables);
13470
13471   return ret;
13472 }
13473
13474 static inline void
13475 json_locator_set_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13476                                 eid_table_t * eid_table)
13477 {
13478   locator_set_msg_t *ls = 0;
13479   u8 *s = 0;
13480
13481   ASSERT (vam != NULL);
13482   ASSERT (node != NULL);
13483   ASSERT (eid_table != NULL);
13484
13485   if (eid_table->is_local)
13486     {
13487       vec_foreach (ls, vam->locator_set_msg)
13488       {
13489         if (ls->locator_set_index == eid_table->locator_set_index)
13490           {
13491             vat_json_object_add_string_copy (node, "locator-set",
13492                                              ls->locator_set_name);
13493             return;
13494           }
13495       }
13496
13497       s = format (0, "N/A");
13498       vec_add1 (s, 0);
13499       vat_json_object_add_string_copy (node, "locator-set", s);
13500       vec_free (s);
13501     }
13502   else
13503     {
13504       s = format (0, "remote");
13505       vec_add1 (s, 0);
13506       vat_json_object_add_string_copy (node, "locator-set", s);
13507       vec_free (s);
13508     }
13509 }
13510
13511 static inline int
13512 json_eid_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13513                         eid_table_t * eid_table)
13514 {
13515   u8 *s = 0;
13516   struct in6_addr ip6;
13517   struct in_addr ip4;
13518
13519   ASSERT (vam != NULL);
13520   ASSERT (node != NULL);
13521   ASSERT (eid_table != NULL);
13522
13523   switch (eid_table->eid_type)
13524     {
13525     case 0:
13526       clib_memcpy (&ip4, eid_table->eid, sizeof (ip4));
13527       vat_json_object_add_ip4 (node, "eid", ip4);
13528       vat_json_object_add_uint (node, "eid-prefix-len",
13529                                 eid_table->eid_prefix_len);
13530       break;
13531     case 1:
13532       clib_memcpy (&ip6, eid_table->eid, sizeof (ip6));
13533       vat_json_object_add_ip6 (node, "eid", ip6);
13534       vat_json_object_add_uint (node, "eid-prefix-len",
13535                                 eid_table->eid_prefix_len);
13536       break;
13537     case 2:
13538       s = format (0, "%U", format_ethernet_address, eid_table->eid);
13539       vec_add1 (s, 0);
13540       vat_json_object_add_string_copy (node, "eid", s);
13541       vec_free (s);
13542       break;
13543     default:
13544       errmsg ("unknown EID type %d!", eid_table->eid_type);
13545       return -99;
13546     }
13547
13548   return 0;
13549 }
13550
13551 static inline void
13552 json_locator_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13553                             eid_table_t * eid_table)
13554 {
13555   locator_msg_t *loc = 0;
13556   vat_json_node_t *locator_array = 0;
13557   vat_json_node_t *locator = 0;
13558   struct in6_addr ip6;
13559   struct in_addr ip4;
13560
13561   ASSERT (vam != NULL);
13562   ASSERT (node != NULL);
13563   ASSERT (eid_table != NULL);
13564
13565   locator_array = vat_json_object_add_list (node, "locator");
13566   vec_foreach (loc, vam->locator_msg)
13567   {
13568     locator = vat_json_array_add (locator_array);
13569     vat_json_init_object (locator);
13570     if (loc->local)
13571       {
13572         vat_json_object_add_uint (locator, "locator-index", loc->sw_if_index);
13573       }
13574     else
13575       {
13576         if (loc->is_ipv6)
13577           {
13578             clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
13579             vat_json_object_add_ip6 (locator, "locator", ip6);
13580           }
13581         else
13582           {
13583             clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
13584             vat_json_object_add_ip4 (locator, "locator", ip4);
13585           }
13586       }
13587   }
13588 }
13589
13590 static int
13591 json_lisp_eid_table_dump (vat_main_t * vam)
13592 {
13593   eid_table_t *eid_table;
13594   vat_json_node_t *node = 0;
13595   int ret = 0;
13596
13597   ASSERT (vam != NULL);
13598
13599   ret = get_locator_set (vam);
13600   if (ret)
13601     {
13602       vec_free (vam->eid_tables);
13603       return ret;
13604     }
13605
13606   if (!vec_len (vam->eid_tables))
13607     {
13608       /* just print [] */
13609       vat_json_init_array (&vam->json_tree);
13610       vat_json_print (vam->ofp, &vam->json_tree);
13611       vam->json_tree.type = VAT_JSON_NONE;
13612       return ret;
13613     }
13614
13615   if (VAT_JSON_ARRAY != vam->json_tree.type)
13616     {
13617       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13618       vat_json_init_array (&vam->json_tree);
13619     }
13620
13621   vec_foreach (eid_table, vam->eid_tables)
13622   {
13623     ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index, 0);
13624     if (ret)
13625       {
13626         vec_free (vam->locator_msg);
13627         vec_free (vam->eid_tables);
13628         clean_locator_set_message (vam);
13629         vat_json_free (&vam->json_tree);
13630         vam->json_tree.type = VAT_JSON_NONE;
13631         return ret;
13632       }
13633
13634     node = vat_json_array_add (&vam->json_tree);
13635     vat_json_init_object (node);
13636
13637     vat_json_object_add_uint (node, "vni", eid_table->vni);
13638
13639     json_locator_set_for_eid_table (vam, node, eid_table);
13640     ret = json_eid_for_eid_table (vam, node, eid_table);
13641     if (ret)
13642       {
13643         vec_free (vam->locator_msg);
13644         vec_free (vam->eid_tables);
13645         clean_locator_set_message (vam);
13646         vat_json_free (&vam->json_tree);
13647         vam->json_tree.type = VAT_JSON_NONE;
13648         return ret;
13649       }
13650
13651     json_locator_for_eid_table (vam, node, eid_table);
13652
13653     vat_json_object_add_uint (node, "ttl", eid_table->ttl);
13654     vat_json_object_add_uint (node, "authoritative",
13655                               eid_table->authoritative);
13656
13657     vec_free (vam->locator_msg);
13658   }
13659
13660   vat_json_print (vam->ofp, &vam->json_tree);
13661   vat_json_free (&vam->json_tree);
13662   vam->json_tree.type = VAT_JSON_NONE;
13663
13664   clean_locator_set_message (vam);
13665   vec_free (vam->eid_tables);
13666
13667   return ret;
13668 }
13669
13670 static int
13671 api_lisp_eid_table_dump (vat_main_t * vam)
13672 {
13673   unformat_input_t *i = vam->input;
13674   vl_api_lisp_eid_table_dump_t *mp;
13675   f64 timeout = ~0;
13676   struct in_addr ip4;
13677   struct in6_addr ip6;
13678   u8 mac[6];
13679   u8 eid_type = ~0, eid_set = 0;
13680   u32 prefix_length = ~0, t, vni = 0;
13681   u8 filter = 0;
13682
13683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13684     {
13685       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13686         {
13687           eid_set = 1;
13688           eid_type = 0;
13689           prefix_length = t;
13690         }
13691       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13692         {
13693           eid_set = 1;
13694           eid_type = 1;
13695           prefix_length = t;
13696         }
13697       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13698         {
13699           eid_set = 1;
13700           eid_type = 2;
13701         }
13702       else if (unformat (i, "vni %d", &t))
13703         {
13704           vni = t;
13705         }
13706       else if (unformat (i, "local"))
13707         {
13708           filter = 1;
13709         }
13710       else if (unformat (i, "remote"))
13711         {
13712           filter = 2;
13713         }
13714       else
13715         {
13716           errmsg ("parse error '%U'", format_unformat_error, i);
13717           return -99;
13718         }
13719     }
13720
13721   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13722
13723   mp->filter = filter;
13724   if (eid_set)
13725     {
13726       mp->eid_set = 1;
13727       mp->vni = htonl (vni);
13728       mp->eid_type = eid_type;
13729       switch (eid_type)
13730         {
13731         case 0:
13732           mp->prefix_length = prefix_length;
13733           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13734           break;
13735         case 1:
13736           mp->prefix_length = prefix_length;
13737           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13738           break;
13739         case 2:
13740           clib_memcpy (mp->eid, mac, sizeof (mac));
13741           break;
13742         default:
13743           errmsg ("unknown EID type %d!", eid_type);
13744           return -99;
13745         }
13746     }
13747
13748   vam->noprint_msg = 1;
13749
13750   /* send it... */
13751   S;
13752
13753   /* Use a control ping for synchronization */
13754   {
13755     vl_api_noprint_control_ping_t *mp;
13756     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13757     S;
13758   }
13759
13760   /* Wait for a reply... */
13761   /* *INDENT-OFF* */
13762   W_L
13763   ({
13764     if (vam->noprint_msg)
13765       {
13766         if (!vam->json_output)
13767           {
13768             vam->retval = print_lisp_eid_table_dump(vam);
13769           }
13770         else
13771           {
13772             vam->retval = json_lisp_eid_table_dump(vam);
13773           }
13774       }
13775     vam->noprint_msg = 0;
13776   });
13777   /* *INDENT-ON* */
13778
13779   /* NOTREACHED */
13780   return 0;
13781 }
13782
13783 static int
13784 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13785 {
13786   vl_api_lisp_gpe_tunnel_dump_t *mp;
13787   f64 timeout = ~0;
13788
13789   if (!vam->json_output)
13790     {
13791       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13792                "%=16s%=16s%=16s%=16s%=16s\n",
13793                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13794                "Decap next", "Lisp version", "Flags", "Next protocol",
13795                "ver_res", "res", "iid");
13796     }
13797
13798   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13799   /* send it... */
13800   S;
13801
13802   /* Use a control ping for synchronization */
13803   {
13804     vl_api_control_ping_t *mp;
13805     M (CONTROL_PING, control_ping);
13806     S;
13807   }
13808   /* Wait for a reply... */
13809   W;
13810
13811   /* NOTREACHED */
13812   return 0;
13813 }
13814
13815 static int
13816 api_lisp_map_resolver_dump (vat_main_t * vam)
13817 {
13818   vl_api_lisp_map_resolver_dump_t *mp;
13819   f64 timeout = ~0;
13820
13821   if (!vam->json_output)
13822     {
13823       fformat (vam->ofp, "%=20s\n", "Map resolver");
13824     }
13825
13826   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13827   /* send it... */
13828   S;
13829
13830   /* Use a control ping for synchronization */
13831   {
13832     vl_api_control_ping_t *mp;
13833     M (CONTROL_PING, control_ping);
13834     S;
13835   }
13836   /* Wait for a reply... */
13837   W;
13838
13839   /* NOTREACHED */
13840   return 0;
13841 }
13842
13843 static int
13844 api_show_lisp_status (vat_main_t * vam)
13845 {
13846   vl_api_show_lisp_status_t *mp;
13847   f64 timeout = ~0;
13848
13849   if (!vam->json_output)
13850     {
13851       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13852     }
13853
13854   M (SHOW_LISP_STATUS, show_lisp_status);
13855   /* send it... */
13856   S;
13857   /* Wait for a reply... */
13858   W;
13859
13860   /* NOTREACHED */
13861   return 0;
13862 }
13863
13864 static int
13865 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13866 {
13867   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13868   f64 timeout = ~0;
13869
13870   if (!vam->json_output)
13871     {
13872       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13873     }
13874
13875   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13876   /* send it... */
13877   S;
13878   /* Wait for a reply... */
13879   W;
13880
13881   /* NOTREACHED */
13882   return 0;
13883 }
13884
13885 static int
13886 api_af_packet_create (vat_main_t * vam)
13887 {
13888   unformat_input_t *i = vam->input;
13889   vl_api_af_packet_create_t *mp;
13890   f64 timeout;
13891   u8 *host_if_name = 0;
13892   u8 hw_addr[6];
13893   u8 random_hw_addr = 1;
13894
13895   memset (hw_addr, 0, sizeof (hw_addr));
13896
13897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13898     {
13899       if (unformat (i, "name %s", &host_if_name))
13900         vec_add1 (host_if_name, 0);
13901       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13902         random_hw_addr = 0;
13903       else
13904         break;
13905     }
13906
13907   if (!vec_len (host_if_name))
13908     {
13909       errmsg ("host-interface name must be specified");
13910       return -99;
13911     }
13912
13913   if (vec_len (host_if_name) > 64)
13914     {
13915       errmsg ("host-interface name too long");
13916       return -99;
13917     }
13918
13919   M (AF_PACKET_CREATE, af_packet_create);
13920
13921   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13922   clib_memcpy (mp->hw_addr, hw_addr, 6);
13923   mp->use_random_hw_addr = random_hw_addr;
13924   vec_free (host_if_name);
13925
13926   S;
13927   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
13928   /* NOTREACHED */
13929   return 0;
13930 }
13931
13932 static int
13933 api_af_packet_delete (vat_main_t * vam)
13934 {
13935   unformat_input_t *i = vam->input;
13936   vl_api_af_packet_delete_t *mp;
13937   f64 timeout;
13938   u8 *host_if_name = 0;
13939
13940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13941     {
13942       if (unformat (i, "name %s", &host_if_name))
13943         vec_add1 (host_if_name, 0);
13944       else
13945         break;
13946     }
13947
13948   if (!vec_len (host_if_name))
13949     {
13950       errmsg ("host-interface name must be specified");
13951       return -99;
13952     }
13953
13954   if (vec_len (host_if_name) > 64)
13955     {
13956       errmsg ("host-interface name too long");
13957       return -99;
13958     }
13959
13960   M (AF_PACKET_DELETE, af_packet_delete);
13961
13962   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13963   vec_free (host_if_name);
13964
13965   S;
13966   W;
13967   /* NOTREACHED */
13968   return 0;
13969 }
13970
13971 static int
13972 api_policer_add_del (vat_main_t * vam)
13973 {
13974   unformat_input_t *i = vam->input;
13975   vl_api_policer_add_del_t *mp;
13976   f64 timeout;
13977   u8 is_add = 1;
13978   u8 *name = 0;
13979   u32 cir = 0;
13980   u32 eir = 0;
13981   u64 cb = 0;
13982   u64 eb = 0;
13983   u8 rate_type = 0;
13984   u8 round_type = 0;
13985   u8 type = 0;
13986   u8 color_aware = 0;
13987   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
13988
13989   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
13990   conform_action.dscp = 0;
13991   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
13992   exceed_action.dscp = 0;
13993   violate_action.action_type = SSE2_QOS_ACTION_DROP;
13994   violate_action.dscp = 0;
13995
13996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13997     {
13998       if (unformat (i, "del"))
13999         is_add = 0;
14000       else if (unformat (i, "name %s", &name))
14001         vec_add1 (name, 0);
14002       else if (unformat (i, "cir %u", &cir))
14003         ;
14004       else if (unformat (i, "eir %u", &eir))
14005         ;
14006       else if (unformat (i, "cb %u", &cb))
14007         ;
14008       else if (unformat (i, "eb %u", &eb))
14009         ;
14010       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14011                          &rate_type))
14012         ;
14013       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14014                          &round_type))
14015         ;
14016       else if (unformat (i, "type %U", unformat_policer_type, &type))
14017         ;
14018       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14019                          &conform_action))
14020         ;
14021       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14022                          &exceed_action))
14023         ;
14024       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14025                          &violate_action))
14026         ;
14027       else if (unformat (i, "color-aware"))
14028         color_aware = 1;
14029       else
14030         break;
14031     }
14032
14033   if (!vec_len (name))
14034     {
14035       errmsg ("policer name must be specified");
14036       return -99;
14037     }
14038
14039   if (vec_len (name) > 64)
14040     {
14041       errmsg ("policer name too long");
14042       return -99;
14043     }
14044
14045   M (POLICER_ADD_DEL, policer_add_del);
14046
14047   clib_memcpy (mp->name, name, vec_len (name));
14048   vec_free (name);
14049   mp->is_add = is_add;
14050   mp->cir = cir;
14051   mp->eir = eir;
14052   mp->cb = cb;
14053   mp->eb = eb;
14054   mp->rate_type = rate_type;
14055   mp->round_type = round_type;
14056   mp->type = type;
14057   mp->conform_action_type = conform_action.action_type;
14058   mp->conform_dscp = conform_action.dscp;
14059   mp->exceed_action_type = exceed_action.action_type;
14060   mp->exceed_dscp = exceed_action.dscp;
14061   mp->violate_action_type = violate_action.action_type;
14062   mp->violate_dscp = violate_action.dscp;
14063   mp->color_aware = color_aware;
14064
14065   S;
14066   W;
14067   /* NOTREACHED */
14068   return 0;
14069 }
14070
14071 static int
14072 api_policer_dump (vat_main_t * vam)
14073 {
14074   unformat_input_t *i = vam->input;
14075   vl_api_policer_dump_t *mp;
14076   f64 timeout = ~0;
14077   u8 *match_name = 0;
14078   u8 match_name_valid = 0;
14079
14080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14081     {
14082       if (unformat (i, "name %s", &match_name))
14083         {
14084           vec_add1 (match_name, 0);
14085           match_name_valid = 1;
14086         }
14087       else
14088         break;
14089     }
14090
14091   M (POLICER_DUMP, policer_dump);
14092   mp->match_name_valid = match_name_valid;
14093   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14094   vec_free (match_name);
14095   /* send it... */
14096   S;
14097
14098   /* Use a control ping for synchronization */
14099   {
14100     vl_api_control_ping_t *mp;
14101     M (CONTROL_PING, control_ping);
14102     S;
14103   }
14104   /* Wait for a reply... */
14105   W;
14106
14107   /* NOTREACHED */
14108   return 0;
14109 }
14110
14111 static int
14112 api_policer_classify_set_interface (vat_main_t * vam)
14113 {
14114   unformat_input_t *i = vam->input;
14115   vl_api_policer_classify_set_interface_t *mp;
14116   f64 timeout;
14117   u32 sw_if_index;
14118   int sw_if_index_set;
14119   u32 ip4_table_index = ~0;
14120   u32 ip6_table_index = ~0;
14121   u32 l2_table_index = ~0;
14122   u8 is_add = 1;
14123
14124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14125     {
14126       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14127         sw_if_index_set = 1;
14128       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14129         sw_if_index_set = 1;
14130       else if (unformat (i, "del"))
14131         is_add = 0;
14132       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14133         ;
14134       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14135         ;
14136       else if (unformat (i, "l2-table %d", &l2_table_index))
14137         ;
14138       else
14139         {
14140           clib_warning ("parse error '%U'", format_unformat_error, i);
14141           return -99;
14142         }
14143     }
14144
14145   if (sw_if_index_set == 0)
14146     {
14147       errmsg ("missing interface name or sw_if_index\n");
14148       return -99;
14149     }
14150
14151   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14152
14153   mp->sw_if_index = ntohl (sw_if_index);
14154   mp->ip4_table_index = ntohl (ip4_table_index);
14155   mp->ip6_table_index = ntohl (ip6_table_index);
14156   mp->l2_table_index = ntohl (l2_table_index);
14157   mp->is_add = is_add;
14158
14159   S;
14160   W;
14161   /* NOTREACHED */
14162   return 0;
14163 }
14164
14165 static int
14166 api_policer_classify_dump (vat_main_t * vam)
14167 {
14168   unformat_input_t *i = vam->input;
14169   vl_api_policer_classify_dump_t *mp;
14170   f64 timeout = ~0;
14171   u8 type = POLICER_CLASSIFY_N_TABLES;
14172
14173   if (unformat (i, "type %U", unformat_classify_table_type, &type))
14174     ;
14175   else
14176     {
14177       errmsg ("classify table type must be specified\n");
14178       return -99;
14179     }
14180
14181   if (!vam->json_output)
14182     {
14183       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14184     }
14185
14186   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14187   mp->type = type;
14188   /* send it... */
14189   S;
14190
14191   /* Use a control ping for synchronization */
14192   {
14193     vl_api_control_ping_t *mp;
14194     M (CONTROL_PING, control_ping);
14195     S;
14196   }
14197   /* Wait for a reply... */
14198   W;
14199
14200   /* NOTREACHED */
14201   return 0;
14202 }
14203
14204 static int
14205 api_netmap_create (vat_main_t * vam)
14206 {
14207   unformat_input_t *i = vam->input;
14208   vl_api_netmap_create_t *mp;
14209   f64 timeout;
14210   u8 *if_name = 0;
14211   u8 hw_addr[6];
14212   u8 random_hw_addr = 1;
14213   u8 is_pipe = 0;
14214   u8 is_master = 0;
14215
14216   memset (hw_addr, 0, sizeof (hw_addr));
14217
14218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14219     {
14220       if (unformat (i, "name %s", &if_name))
14221         vec_add1 (if_name, 0);
14222       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14223         random_hw_addr = 0;
14224       else if (unformat (i, "pipe"))
14225         is_pipe = 1;
14226       else if (unformat (i, "master"))
14227         is_master = 1;
14228       else if (unformat (i, "slave"))
14229         is_master = 0;
14230       else
14231         break;
14232     }
14233
14234   if (!vec_len (if_name))
14235     {
14236       errmsg ("interface name must be specified");
14237       return -99;
14238     }
14239
14240   if (vec_len (if_name) > 64)
14241     {
14242       errmsg ("interface name too long");
14243       return -99;
14244     }
14245
14246   M (NETMAP_CREATE, netmap_create);
14247
14248   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14249   clib_memcpy (mp->hw_addr, hw_addr, 6);
14250   mp->use_random_hw_addr = random_hw_addr;
14251   mp->is_pipe = is_pipe;
14252   mp->is_master = is_master;
14253   vec_free (if_name);
14254
14255   S;
14256   W;
14257   /* NOTREACHED */
14258   return 0;
14259 }
14260
14261 static int
14262 api_netmap_delete (vat_main_t * vam)
14263 {
14264   unformat_input_t *i = vam->input;
14265   vl_api_netmap_delete_t *mp;
14266   f64 timeout;
14267   u8 *if_name = 0;
14268
14269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14270     {
14271       if (unformat (i, "name %s", &if_name))
14272         vec_add1 (if_name, 0);
14273       else
14274         break;
14275     }
14276
14277   if (!vec_len (if_name))
14278     {
14279       errmsg ("interface name must be specified");
14280       return -99;
14281     }
14282
14283   if (vec_len (if_name) > 64)
14284     {
14285       errmsg ("interface name too long");
14286       return -99;
14287     }
14288
14289   M (NETMAP_DELETE, netmap_delete);
14290
14291   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14292   vec_free (if_name);
14293
14294   S;
14295   W;
14296   /* NOTREACHED */
14297   return 0;
14298 }
14299
14300 static void vl_api_mpls_gre_tunnel_details_t_handler
14301   (vl_api_mpls_gre_tunnel_details_t * mp)
14302 {
14303   vat_main_t *vam = &vat_main;
14304   i32 i;
14305   i32 len = ntohl (mp->nlabels);
14306
14307   if (mp->l2_only == 0)
14308     {
14309       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14310                ntohl (mp->tunnel_index),
14311                format_ip4_address, &mp->tunnel_src,
14312                format_ip4_address, &mp->tunnel_dst,
14313                format_ip4_address, &mp->intfc_address,
14314                ntohl (mp->mask_width));
14315       for (i = 0; i < len; i++)
14316         {
14317           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14318         }
14319       fformat (vam->ofp, "\n");
14320       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14321                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14322     }
14323   else
14324     {
14325       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14326                ntohl (mp->tunnel_index),
14327                format_ip4_address, &mp->tunnel_src,
14328                format_ip4_address, &mp->tunnel_dst,
14329                format_ip4_address, &mp->intfc_address);
14330       for (i = 0; i < len; i++)
14331         {
14332           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14333         }
14334       fformat (vam->ofp, "\n");
14335       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14336                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14337     }
14338 }
14339
14340 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14341   (vl_api_mpls_gre_tunnel_details_t * mp)
14342 {
14343   vat_main_t *vam = &vat_main;
14344   vat_json_node_t *node = NULL;
14345   struct in_addr ip4;
14346   i32 i;
14347   i32 len = ntohl (mp->nlabels);
14348
14349   if (VAT_JSON_ARRAY != vam->json_tree.type)
14350     {
14351       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14352       vat_json_init_array (&vam->json_tree);
14353     }
14354   node = vat_json_array_add (&vam->json_tree);
14355
14356   vat_json_init_object (node);
14357   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14358   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14359   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14360   vat_json_object_add_uint (node, "inner_fib_index",
14361                             ntohl (mp->inner_fib_index));
14362   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14363   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14364   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14365   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14366   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14367   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14368   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14369   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14370   vat_json_object_add_uint (node, "outer_fib_index",
14371                             ntohl (mp->outer_fib_index));
14372   vat_json_object_add_uint (node, "label_count", len);
14373   for (i = 0; i < len; i++)
14374     {
14375       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14376     }
14377 }
14378
14379 static int
14380 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14381 {
14382   vl_api_mpls_gre_tunnel_dump_t *mp;
14383   f64 timeout;
14384   i32 index = -1;
14385
14386   /* Parse args required to build the message */
14387   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14388     {
14389       if (!unformat (vam->input, "tunnel_index %d", &index))
14390         {
14391           index = -1;
14392           break;
14393         }
14394     }
14395
14396   fformat (vam->ofp, "  tunnel_index %d\n", index);
14397
14398   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14399   mp->tunnel_index = htonl (index);
14400   S;
14401
14402   /* Use a control ping for synchronization */
14403   {
14404     vl_api_control_ping_t *mp;
14405     M (CONTROL_PING, control_ping);
14406     S;
14407   }
14408   W;
14409 }
14410
14411 static void vl_api_mpls_eth_tunnel_details_t_handler
14412   (vl_api_mpls_eth_tunnel_details_t * mp)
14413 {
14414   vat_main_t *vam = &vat_main;
14415   i32 i;
14416   i32 len = ntohl (mp->nlabels);
14417
14418   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14419            ntohl (mp->tunnel_index),
14420            format_ethernet_address, &mp->tunnel_dst_mac,
14421            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14422   for (i = 0; i < len; i++)
14423     {
14424       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14425     }
14426   fformat (vam->ofp, "\n");
14427   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14428            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14429 }
14430
14431 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14432   (vl_api_mpls_eth_tunnel_details_t * mp)
14433 {
14434   vat_main_t *vam = &vat_main;
14435   vat_json_node_t *node = NULL;
14436   struct in_addr ip4;
14437   i32 i;
14438   i32 len = ntohl (mp->nlabels);
14439
14440   if (VAT_JSON_ARRAY != vam->json_tree.type)
14441     {
14442       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14443       vat_json_init_array (&vam->json_tree);
14444     }
14445   node = vat_json_array_add (&vam->json_tree);
14446
14447   vat_json_init_object (node);
14448   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14449   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14450   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14451   vat_json_object_add_uint (node, "inner_fib_index",
14452                             ntohl (mp->inner_fib_index));
14453   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14454   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14455   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14456   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14457   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14458                                    format (0, "%U", format_ethernet_address,
14459                                            &mp->tunnel_dst_mac));
14460   vat_json_object_add_uint (node, "tx_sw_if_index",
14461                             ntohl (mp->tx_sw_if_index));
14462   vat_json_object_add_uint (node, "label_count", len);
14463   for (i = 0; i < len; i++)
14464     {
14465       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14466     }
14467 }
14468
14469 static int
14470 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14471 {
14472   vl_api_mpls_eth_tunnel_dump_t *mp;
14473   f64 timeout;
14474   i32 index = -1;
14475
14476   /* Parse args required to build the message */
14477   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14478     {
14479       if (!unformat (vam->input, "tunnel_index %d", &index))
14480         {
14481           index = -1;
14482           break;
14483         }
14484     }
14485
14486   fformat (vam->ofp, "  tunnel_index %d\n", index);
14487
14488   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14489   mp->tunnel_index = htonl (index);
14490   S;
14491
14492   /* Use a control ping for synchronization */
14493   {
14494     vl_api_control_ping_t *mp;
14495     M (CONTROL_PING, control_ping);
14496     S;
14497   }
14498   W;
14499 }
14500
14501 static void vl_api_mpls_fib_encap_details_t_handler
14502   (vl_api_mpls_fib_encap_details_t * mp)
14503 {
14504   vat_main_t *vam = &vat_main;
14505   i32 i;
14506   i32 len = ntohl (mp->nlabels);
14507
14508   fformat (vam->ofp, "table %d, dest %U, label ",
14509            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14510   for (i = 0; i < len; i++)
14511     {
14512       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14513     }
14514   fformat (vam->ofp, "\n");
14515 }
14516
14517 static void vl_api_mpls_fib_encap_details_t_handler_json
14518   (vl_api_mpls_fib_encap_details_t * mp)
14519 {
14520   vat_main_t *vam = &vat_main;
14521   vat_json_node_t *node = NULL;
14522   i32 i;
14523   i32 len = ntohl (mp->nlabels);
14524   struct in_addr ip4;
14525
14526   if (VAT_JSON_ARRAY != vam->json_tree.type)
14527     {
14528       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14529       vat_json_init_array (&vam->json_tree);
14530     }
14531   node = vat_json_array_add (&vam->json_tree);
14532
14533   vat_json_init_object (node);
14534   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14535   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14536   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14537   vat_json_object_add_ip4 (node, "dest", ip4);
14538   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14539   vat_json_object_add_uint (node, "label_count", len);
14540   for (i = 0; i < len; i++)
14541     {
14542       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14543     }
14544 }
14545
14546 static int
14547 api_mpls_fib_encap_dump (vat_main_t * vam)
14548 {
14549   vl_api_mpls_fib_encap_dump_t *mp;
14550   f64 timeout;
14551
14552   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14553   S;
14554
14555   /* Use a control ping for synchronization */
14556   {
14557     vl_api_control_ping_t *mp;
14558     M (CONTROL_PING, control_ping);
14559     S;
14560   }
14561   W;
14562 }
14563
14564 static void vl_api_mpls_fib_decap_details_t_handler
14565   (vl_api_mpls_fib_decap_details_t * mp)
14566 {
14567   vat_main_t *vam = &vat_main;
14568
14569   fformat (vam->ofp,
14570            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14571            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14572            ntohl (mp->label), ntohl (mp->s_bit));
14573 }
14574
14575 static void vl_api_mpls_fib_decap_details_t_handler_json
14576   (vl_api_mpls_fib_decap_details_t * mp)
14577 {
14578   vat_main_t *vam = &vat_main;
14579   vat_json_node_t *node = NULL;
14580   struct in_addr ip4;
14581
14582   if (VAT_JSON_ARRAY != vam->json_tree.type)
14583     {
14584       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14585       vat_json_init_array (&vam->json_tree);
14586     }
14587   node = vat_json_array_add (&vam->json_tree);
14588
14589   vat_json_init_object (node);
14590   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14591   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14592   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14593   vat_json_object_add_ip4 (node, "dest", ip4);
14594   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14595   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14596   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14597   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14598   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14599 }
14600
14601 static int
14602 api_mpls_fib_decap_dump (vat_main_t * vam)
14603 {
14604   vl_api_mpls_fib_decap_dump_t *mp;
14605   f64 timeout;
14606
14607   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14608   S;
14609
14610   /* Use a control ping for synchronization */
14611   {
14612     vl_api_control_ping_t *mp;
14613     M (CONTROL_PING, control_ping);
14614     S;
14615   }
14616   W;
14617 }
14618
14619 int
14620 api_classify_table_ids (vat_main_t * vam)
14621 {
14622   vl_api_classify_table_ids_t *mp;
14623   f64 timeout;
14624
14625   /* Construct the API message */
14626   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14627   mp->context = 0;
14628
14629   S;
14630   W;
14631   /* NOTREACHED */
14632   return 0;
14633 }
14634
14635 int
14636 api_classify_table_by_interface (vat_main_t * vam)
14637 {
14638   unformat_input_t *input = vam->input;
14639   vl_api_classify_table_by_interface_t *mp;
14640   f64 timeout;
14641
14642   u32 sw_if_index = ~0;
14643   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14644     {
14645       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14646         ;
14647       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14648         ;
14649       else
14650         break;
14651     }
14652   if (sw_if_index == ~0)
14653     {
14654       errmsg ("missing interface name or sw_if_index\n");
14655       return -99;
14656     }
14657
14658   /* Construct the API message */
14659   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14660   mp->context = 0;
14661   mp->sw_if_index = ntohl (sw_if_index);
14662
14663   S;
14664   W;
14665   /* NOTREACHED */
14666   return 0;
14667 }
14668
14669 int
14670 api_classify_table_info (vat_main_t * vam)
14671 {
14672   unformat_input_t *input = vam->input;
14673   vl_api_classify_table_info_t *mp;
14674   f64 timeout;
14675
14676   u32 table_id = ~0;
14677   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14678     {
14679       if (unformat (input, "table_id %d", &table_id))
14680         ;
14681       else
14682         break;
14683     }
14684   if (table_id == ~0)
14685     {
14686       errmsg ("missing table id\n");
14687       return -99;
14688     }
14689
14690   /* Construct the API message */
14691   M (CLASSIFY_TABLE_INFO, classify_table_info);
14692   mp->context = 0;
14693   mp->table_id = ntohl (table_id);
14694
14695   S;
14696   W;
14697   /* NOTREACHED */
14698   return 0;
14699 }
14700
14701 int
14702 api_classify_session_dump (vat_main_t * vam)
14703 {
14704   unformat_input_t *input = vam->input;
14705   vl_api_classify_session_dump_t *mp;
14706   f64 timeout;
14707
14708   u32 table_id = ~0;
14709   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14710     {
14711       if (unformat (input, "table_id %d", &table_id))
14712         ;
14713       else
14714         break;
14715     }
14716   if (table_id == ~0)
14717     {
14718       errmsg ("missing table id\n");
14719       return -99;
14720     }
14721
14722   /* Construct the API message */
14723   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14724   mp->context = 0;
14725   mp->table_id = ntohl (table_id);
14726   S;
14727
14728   /* Use a control ping for synchronization */
14729   {
14730     vl_api_control_ping_t *mp;
14731     M (CONTROL_PING, control_ping);
14732     S;
14733   }
14734   W;
14735   /* NOTREACHED */
14736   return 0;
14737 }
14738
14739 static void
14740 vl_api_ipfix_details_t_handler (vl_api_ipfix_details_t * mp)
14741 {
14742   vat_main_t *vam = &vat_main;
14743
14744   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14745            "src_address %U, fib_index %u, path_mtu %u, "
14746            "template_interval %u\n",
14747            format_ip4_address, mp->collector_address,
14748            ntohs (mp->collector_port),
14749            format_ip4_address, mp->src_address,
14750            ntohl (mp->fib_index),
14751            ntohl (mp->path_mtu), ntohl (mp->template_interval));
14752
14753   vam->retval = 0;
14754   vam->result_ready = 1;
14755 }
14756
14757 static void
14758 vl_api_ipfix_details_t_handler_json (vl_api_ipfix_details_t * mp)
14759 {
14760   vat_main_t *vam = &vat_main;
14761   vat_json_node_t node;
14762   struct in_addr collector_address;
14763   struct in_addr src_address;
14764
14765   vat_json_init_object (&node);
14766   clib_memcpy (&collector_address, &mp->collector_address,
14767                sizeof (collector_address));
14768   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14769   vat_json_object_add_uint (&node, "collector_port",
14770                             ntohs (mp->collector_port));
14771   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14772   vat_json_object_add_ip4 (&node, "src_address", src_address);
14773   vat_json_object_add_uint (&node, "fib_index", ntohl (mp->fib_index));
14774   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14775   vat_json_object_add_uint (&node, "template_interval",
14776                             ntohl (mp->template_interval));
14777
14778   vat_json_print (vam->ofp, &node);
14779   vat_json_free (&node);
14780   vam->retval = 0;
14781   vam->result_ready = 1;
14782 }
14783
14784 int
14785 api_ipfix_dump (vat_main_t * vam)
14786 {
14787   vl_api_ipfix_dump_t *mp;
14788   f64 timeout;
14789
14790   /* Construct the API message */
14791   M (IPFIX_DUMP, ipfix_dump);
14792   mp->context = 0;
14793
14794   S;
14795   W;
14796   /* NOTREACHED */
14797   return 0;
14798 }
14799
14800 int
14801 api_pg_create_interface (vat_main_t * vam)
14802 {
14803   unformat_input_t *input = vam->input;
14804   vl_api_pg_create_interface_t *mp;
14805   f64 timeout;
14806
14807   u32 if_id = ~0;
14808   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14809     {
14810       if (unformat (input, "if_id %d", &if_id))
14811         ;
14812       else
14813         break;
14814     }
14815   if (if_id == ~0)
14816     {
14817       errmsg ("missing pg interface index\n");
14818       return -99;
14819     }
14820
14821   /* Construct the API message */
14822   M (PG_CREATE_INTERFACE, pg_create_interface);
14823   mp->context = 0;
14824   mp->interface_id = ntohl (if_id);
14825
14826   S;
14827   W;
14828   /* NOTREACHED */
14829   return 0;
14830 }
14831
14832 int
14833 api_pg_capture (vat_main_t * vam)
14834 {
14835   unformat_input_t *input = vam->input;
14836   vl_api_pg_capture_t *mp;
14837   f64 timeout;
14838
14839   u32 if_id = ~0;
14840   u8 enable = 1;
14841   u32 count = 1;
14842   u8 pcap_file_set = 0;
14843   u8 *pcap_file = 0;
14844   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14845     {
14846       if (unformat (input, "if_id %d", &if_id))
14847         ;
14848       else if (unformat (input, "pcap %s", &pcap_file))
14849         pcap_file_set = 1;
14850       else if (unformat (input, "count %d", &count))
14851         ;
14852       else if (unformat (input, "disable"))
14853         enable = 0;
14854       else
14855         break;
14856     }
14857   if (if_id == ~0)
14858     {
14859       errmsg ("missing pg interface index\n");
14860       return -99;
14861     }
14862   if (pcap_file_set > 0)
14863     {
14864       if (vec_len (pcap_file) > 255)
14865         {
14866           errmsg ("pcap file name is too long\n");
14867           return -99;
14868         }
14869     }
14870
14871   u32 name_len = vec_len (pcap_file);
14872   /* Construct the API message */
14873   M (PG_CAPTURE, pg_capture);
14874   mp->context = 0;
14875   mp->interface_id = ntohl (if_id);
14876   mp->is_enabled = enable;
14877   mp->count = ntohl (count);
14878   mp->pcap_name_length = ntohl (name_len);
14879   if (pcap_file_set != 0)
14880     {
14881       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14882     }
14883   vec_free (pcap_file);
14884
14885   S;
14886   W;
14887   /* NOTREACHED */
14888   return 0;
14889 }
14890
14891 int
14892 api_pg_enable_disable (vat_main_t * vam)
14893 {
14894   unformat_input_t *input = vam->input;
14895   vl_api_pg_enable_disable_t *mp;
14896   f64 timeout;
14897
14898   u8 enable = 1;
14899   u8 stream_name_set = 0;
14900   u8 *stream_name = 0;
14901   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14902     {
14903       if (unformat (input, "stream %s", &stream_name))
14904         stream_name_set = 1;
14905       else if (unformat (input, "disable"))
14906         enable = 0;
14907       else
14908         break;
14909     }
14910
14911   if (stream_name_set > 0)
14912     {
14913       if (vec_len (stream_name) > 255)
14914         {
14915           errmsg ("stream name too long\n");
14916           return -99;
14917         }
14918     }
14919
14920   u32 name_len = vec_len (stream_name);
14921   /* Construct the API message */
14922   M (PG_ENABLE_DISABLE, pg_enable_disable);
14923   mp->context = 0;
14924   mp->is_enabled = enable;
14925   if (stream_name_set != 0)
14926     {
14927       mp->stream_name_length = ntohl (name_len);
14928       clib_memcpy (mp->stream_name, stream_name, name_len);
14929     }
14930   vec_free (stream_name);
14931
14932   S;
14933   W;
14934   /* NOTREACHED */
14935   return 0;
14936 }
14937
14938 int
14939 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
14940 {
14941   unformat_input_t *input = vam->input;
14942   vl_api_ip_source_and_port_range_check_add_del_t *mp;
14943   f64 timeout;
14944
14945   u16 *low_ports = 0;
14946   u16 *high_ports = 0;
14947   u16 this_low;
14948   u16 this_hi;
14949   ip4_address_t ip4_addr;
14950   ip6_address_t ip6_addr;
14951   u32 length;
14952   u32 tmp, tmp2;
14953   u8 prefix_set = 0;
14954   u32 vrf_id = ~0;
14955   u8 is_add = 1;
14956   u8 is_ipv6 = 0;
14957
14958   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14959     {
14960       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
14961         {
14962           prefix_set = 1;
14963         }
14964       else
14965         if (unformat
14966             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
14967         {
14968           prefix_set = 1;
14969           is_ipv6 = 1;
14970         }
14971       else if (unformat (input, "vrf %d", &vrf_id))
14972         ;
14973       else if (unformat (input, "del"))
14974         is_add = 0;
14975       else if (unformat (input, "port %d", &tmp))
14976         {
14977           if (tmp == 0 || tmp > 65535)
14978             {
14979               errmsg ("port %d out of range", tmp);
14980               return -99;
14981             }
14982           this_low = tmp;
14983           this_hi = this_low + 1;
14984           vec_add1 (low_ports, this_low);
14985           vec_add1 (high_ports, this_hi);
14986         }
14987       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
14988         {
14989           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
14990             {
14991               errmsg ("incorrect range parameters\n");
14992               return -99;
14993             }
14994           this_low = tmp;
14995           /* Note: in debug CLI +1 is added to high before
14996              passing to real fn that does "the work"
14997              (ip_source_and_port_range_check_add_del).
14998              This fn is a wrapper around the binary API fn a
14999              control plane will call, which expects this increment
15000              to have occurred. Hence letting the binary API control
15001              plane fn do the increment for consistency between VAT
15002              and other control planes.
15003            */
15004           this_hi = tmp2;
15005           vec_add1 (low_ports, this_low);
15006           vec_add1 (high_ports, this_hi);
15007         }
15008       else
15009         break;
15010     }
15011
15012   if (prefix_set == 0)
15013     {
15014       errmsg ("<address>/<mask> not specified\n");
15015       return -99;
15016     }
15017
15018   if (vrf_id == ~0)
15019     {
15020       errmsg ("VRF ID required, not specified\n");
15021       return -99;
15022     }
15023
15024   if (vrf_id == 0)
15025     {
15026       errmsg
15027         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15028       return -99;
15029     }
15030
15031   if (vec_len (low_ports) == 0)
15032     {
15033       errmsg ("At least one port or port range required\n");
15034       return -99;
15035     }
15036
15037   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15038      ip_source_and_port_range_check_add_del);
15039
15040   mp->is_add = is_add;
15041
15042   if (is_ipv6)
15043     {
15044       mp->is_ipv6 = 1;
15045       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15046     }
15047   else
15048     {
15049       mp->is_ipv6 = 0;
15050       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15051     }
15052
15053   mp->mask_length = length;
15054   mp->number_of_ranges = vec_len (low_ports);
15055
15056   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15057   vec_free (low_ports);
15058
15059   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15060   vec_free (high_ports);
15061
15062   mp->vrf_id = ntohl (vrf_id);
15063
15064   S;
15065   W;
15066   /* NOTREACHED */
15067   return 0;
15068 }
15069
15070 int
15071 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15072 {
15073   unformat_input_t *input = vam->input;
15074   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15075   f64 timeout;
15076   u32 sw_if_index = ~0;
15077   int vrf_set = 0;
15078   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15079   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15080   u8 is_add = 1;
15081
15082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15083     {
15084       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15085         ;
15086       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15087         ;
15088       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15089         vrf_set = 1;
15090       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15091         vrf_set = 1;
15092       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15093         vrf_set = 1;
15094       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15095         vrf_set = 1;
15096       else if (unformat (input, "del"))
15097         is_add = 0;
15098       else
15099         break;
15100     }
15101
15102   if (sw_if_index == ~0)
15103     {
15104       errmsg ("Interface required but not specified\n");
15105       return -99;
15106     }
15107
15108   if (vrf_set == 0)
15109     {
15110       errmsg ("VRF ID required but not specified\n");
15111       return -99;
15112     }
15113
15114   if (tcp_out_vrf_id == 0
15115       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15116     {
15117       errmsg
15118         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15119       return -99;
15120     }
15121
15122   /* Construct the API message */
15123   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15124      ip_source_and_port_range_check_interface_add_del);
15125
15126   mp->sw_if_index = ntohl (sw_if_index);
15127   mp->is_add = is_add;
15128   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15129   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15130   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15131   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15132
15133   /* send it... */
15134   S;
15135
15136   /* Wait for a reply... */
15137   W;
15138 }
15139
15140 static int
15141 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15142 {
15143   unformat_input_t *i = vam->input;
15144   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15145   f64 timeout;
15146   u32 local_sa_id = 0;
15147   u32 remote_sa_id = 0;
15148   ip4_address_t src_address;
15149   ip4_address_t dst_address;
15150   u8 is_add = 1;
15151
15152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15153     {
15154       if (unformat (i, "local_sa %d", &local_sa_id))
15155         ;
15156       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15157         ;
15158       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15159         ;
15160       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15161         ;
15162       else if (unformat (i, "del"))
15163         is_add = 0;
15164       else
15165         {
15166           clib_warning ("parse error '%U'", format_unformat_error, i);
15167           return -99;
15168         }
15169     }
15170
15171   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15172
15173   mp->local_sa_id = ntohl (local_sa_id);
15174   mp->remote_sa_id = ntohl (remote_sa_id);
15175   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15176   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15177   mp->is_add = is_add;
15178
15179   S;
15180   W;
15181   /* NOTREACHED */
15182   return 0;
15183 }
15184
15185 static void vl_api_ipsec_gre_tunnel_details_t_handler
15186   (vl_api_ipsec_gre_tunnel_details_t * mp)
15187 {
15188   vat_main_t *vam = &vat_main;
15189
15190   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15191            ntohl (mp->sw_if_index),
15192            format_ip4_address, &mp->src_address,
15193            format_ip4_address, &mp->dst_address,
15194            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15195 }
15196
15197 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15198   (vl_api_ipsec_gre_tunnel_details_t * mp)
15199 {
15200   vat_main_t *vam = &vat_main;
15201   vat_json_node_t *node = NULL;
15202   struct in_addr ip4;
15203
15204   if (VAT_JSON_ARRAY != vam->json_tree.type)
15205     {
15206       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15207       vat_json_init_array (&vam->json_tree);
15208     }
15209   node = vat_json_array_add (&vam->json_tree);
15210
15211   vat_json_init_object (node);
15212   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15213   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15214   vat_json_object_add_ip4 (node, "src_address", ip4);
15215   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15216   vat_json_object_add_ip4 (node, "dst_address", ip4);
15217   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15218   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15219 }
15220
15221 static int
15222 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15223 {
15224   unformat_input_t *i = vam->input;
15225   vl_api_ipsec_gre_tunnel_dump_t *mp;
15226   f64 timeout;
15227   u32 sw_if_index;
15228   u8 sw_if_index_set = 0;
15229
15230   /* Parse args required to build the message */
15231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15232     {
15233       if (unformat (i, "sw_if_index %d", &sw_if_index))
15234         sw_if_index_set = 1;
15235       else
15236         break;
15237     }
15238
15239   if (sw_if_index_set == 0)
15240     {
15241       sw_if_index = ~0;
15242     }
15243
15244   if (!vam->json_output)
15245     {
15246       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15247                "sw_if_index", "src_address", "dst_address",
15248                "local_sa_id", "remote_sa_id");
15249     }
15250
15251   /* Get list of gre-tunnel interfaces */
15252   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15253
15254   mp->sw_if_index = htonl (sw_if_index);
15255
15256   S;
15257
15258   /* Use a control ping for synchronization */
15259   {
15260     vl_api_control_ping_t *mp;
15261     M (CONTROL_PING, control_ping);
15262     S;
15263   }
15264   W;
15265 }
15266
15267 static int
15268 api_delete_subif (vat_main_t * vam)
15269 {
15270   unformat_input_t *i = vam->input;
15271   vl_api_delete_subif_t *mp;
15272   f64 timeout;
15273   u32 sw_if_index = ~0;
15274
15275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15276     {
15277       if (unformat (i, "sw_if_index %d", &sw_if_index))
15278         ;
15279       else
15280         break;
15281     }
15282
15283   if (sw_if_index == ~0)
15284     {
15285       errmsg ("missing sw_if_index\n");
15286       return -99;
15287     }
15288
15289   /* Construct the API message */
15290   M (DELETE_SUBIF, delete_subif);
15291   mp->sw_if_index = ntohl (sw_if_index);
15292
15293   S;
15294   W;
15295 }
15296
15297 static int
15298 q_or_quit (vat_main_t * vam)
15299 {
15300   longjmp (vam->jump_buf, 1);
15301   return 0;                     /* not so much */
15302 }
15303
15304 static int
15305 q (vat_main_t * vam)
15306 {
15307   return q_or_quit (vam);
15308 }
15309
15310 static int
15311 quit (vat_main_t * vam)
15312 {
15313   return q_or_quit (vam);
15314 }
15315
15316 static int
15317 comment (vat_main_t * vam)
15318 {
15319   return 0;
15320 }
15321
15322 static int
15323 cmd_cmp (void *a1, void *a2)
15324 {
15325   u8 **c1 = a1;
15326   u8 **c2 = a2;
15327
15328   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15329 }
15330
15331 static int
15332 help (vat_main_t * vam)
15333 {
15334   u8 **cmds = 0;
15335   u8 *name = 0;
15336   hash_pair_t *p;
15337   unformat_input_t *i = vam->input;
15338   int j;
15339
15340   if (unformat (i, "%s", &name))
15341     {
15342       uword *hs;
15343
15344       vec_add1 (name, 0);
15345
15346       hs = hash_get_mem (vam->help_by_name, name);
15347       if (hs)
15348         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15349       else
15350         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15351       vec_free (name);
15352       return 0;
15353     }
15354
15355   fformat (vam->ofp, "Help is available for the following:\n");
15356
15357     /* *INDENT-OFF* */
15358     hash_foreach_pair (p, vam->function_by_name,
15359     ({
15360       vec_add1 (cmds, (u8 *)(p->key));
15361     }));
15362     /* *INDENT-ON* */
15363
15364   vec_sort_with_function (cmds, cmd_cmp);
15365
15366   for (j = 0; j < vec_len (cmds); j++)
15367     fformat (vam->ofp, "%s\n", cmds[j]);
15368
15369   vec_free (cmds);
15370   return 0;
15371 }
15372
15373 static int
15374 set (vat_main_t * vam)
15375 {
15376   u8 *name = 0, *value = 0;
15377   unformat_input_t *i = vam->input;
15378
15379   if (unformat (i, "%s", &name))
15380     {
15381       /* The input buffer is a vector, not a string. */
15382       value = vec_dup (i->buffer);
15383       vec_delete (value, i->index, 0);
15384       /* Almost certainly has a trailing newline */
15385       if (value[vec_len (value) - 1] == '\n')
15386         value[vec_len (value) - 1] = 0;
15387       /* Make sure it's a proper string, one way or the other */
15388       vec_add1 (value, 0);
15389       (void) clib_macro_set_value (&vam->macro_main,
15390                                    (char *) name, (char *) value);
15391     }
15392   else
15393     errmsg ("usage: set <name> <value>\n");
15394
15395   vec_free (name);
15396   vec_free (value);
15397   return 0;
15398 }
15399
15400 static int
15401 unset (vat_main_t * vam)
15402 {
15403   u8 *name = 0;
15404
15405   if (unformat (vam->input, "%s", &name))
15406     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15407       errmsg ("unset: %s wasn't set\n", name);
15408   vec_free (name);
15409   return 0;
15410 }
15411
15412 typedef struct
15413 {
15414   u8 *name;
15415   u8 *value;
15416 } macro_sort_t;
15417
15418
15419 static int
15420 macro_sort_cmp (void *a1, void *a2)
15421 {
15422   macro_sort_t *s1 = a1;
15423   macro_sort_t *s2 = a2;
15424
15425   return strcmp ((char *) (s1->name), (char *) (s2->name));
15426 }
15427
15428 static int
15429 dump_macro_table (vat_main_t * vam)
15430 {
15431   macro_sort_t *sort_me = 0, *sm;
15432   int i;
15433   hash_pair_t *p;
15434
15435     /* *INDENT-OFF* */
15436     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15437     ({
15438       vec_add2 (sort_me, sm, 1);
15439       sm->name = (u8 *)(p->key);
15440       sm->value = (u8 *) (p->value[0]);
15441     }));
15442     /* *INDENT-ON* */
15443
15444   vec_sort_with_function (sort_me, macro_sort_cmp);
15445
15446   if (vec_len (sort_me))
15447     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15448   else
15449     fformat (vam->ofp, "The macro table is empty...\n");
15450
15451   for (i = 0; i < vec_len (sort_me); i++)
15452     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15453   return 0;
15454 }
15455
15456 static int
15457 dump_node_table (vat_main_t * vam)
15458 {
15459   int i, j;
15460   vlib_node_t *node, *next_node;
15461
15462   if (vec_len (vam->graph_nodes) == 0)
15463     {
15464       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15465       return 0;
15466     }
15467
15468   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15469     {
15470       node = vam->graph_nodes[i];
15471       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15472       for (j = 0; j < vec_len (node->next_nodes); j++)
15473         {
15474           if (node->next_nodes[j] != ~0)
15475             {
15476               next_node = vam->graph_nodes[node->next_nodes[j]];
15477               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15478             }
15479         }
15480     }
15481   return 0;
15482 }
15483
15484 static int
15485 search_node_table (vat_main_t * vam)
15486 {
15487   unformat_input_t *line_input = vam->input;
15488   u8 *node_to_find;
15489   int j;
15490   vlib_node_t *node, *next_node;
15491   uword *p;
15492
15493   if (vam->graph_node_index_by_name == 0)
15494     {
15495       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15496       return 0;
15497     }
15498
15499   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15500     {
15501       if (unformat (line_input, "%s", &node_to_find))
15502         {
15503           vec_add1 (node_to_find, 0);
15504           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15505           if (p == 0)
15506             {
15507               fformat (vam->ofp, "%s not found...\n", node_to_find);
15508               goto out;
15509             }
15510           node = vam->graph_nodes[p[0]];
15511           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15512           for (j = 0; j < vec_len (node->next_nodes); j++)
15513             {
15514               if (node->next_nodes[j] != ~0)
15515                 {
15516                   next_node = vam->graph_nodes[node->next_nodes[j]];
15517                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15518                 }
15519             }
15520         }
15521
15522       else
15523         {
15524           clib_warning ("parse error '%U'", format_unformat_error,
15525                         line_input);
15526           return -99;
15527         }
15528
15529     out:
15530       vec_free (node_to_find);
15531
15532     }
15533
15534   return 0;
15535 }
15536
15537
15538 static int
15539 script (vat_main_t * vam)
15540 {
15541   u8 *s = 0;
15542   char *save_current_file;
15543   unformat_input_t save_input;
15544   jmp_buf save_jump_buf;
15545   u32 save_line_number;
15546
15547   FILE *new_fp, *save_ifp;
15548
15549   if (unformat (vam->input, "%s", &s))
15550     {
15551       new_fp = fopen ((char *) s, "r");
15552       if (new_fp == 0)
15553         {
15554           errmsg ("Couldn't open script file %s\n", s);
15555           vec_free (s);
15556           return -99;
15557         }
15558     }
15559   else
15560     {
15561       errmsg ("Missing script name\n");
15562       return -99;
15563     }
15564
15565   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15566   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15567   save_ifp = vam->ifp;
15568   save_line_number = vam->input_line_number;
15569   save_current_file = (char *) vam->current_file;
15570
15571   vam->input_line_number = 0;
15572   vam->ifp = new_fp;
15573   vam->current_file = s;
15574   do_one_file (vam);
15575
15576   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15577   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15578   vam->ifp = save_ifp;
15579   vam->input_line_number = save_line_number;
15580   vam->current_file = (u8 *) save_current_file;
15581   vec_free (s);
15582
15583   return 0;
15584 }
15585
15586 static int
15587 echo (vat_main_t * vam)
15588 {
15589   fformat (vam->ofp, "%v", vam->input->buffer);
15590   return 0;
15591 }
15592
15593 /* List of API message constructors, CLI names map to api_xxx */
15594 #define foreach_vpe_api_msg                                             \
15595 _(create_loopback,"[mac <mac-addr>]")                                   \
15596 _(sw_interface_dump,"")                                                 \
15597 _(sw_interface_set_flags,                                               \
15598   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15599 _(sw_interface_add_del_address,                                         \
15600   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15601 _(sw_interface_set_table,                                               \
15602   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15603 _(sw_interface_set_vpath,                                               \
15604   "<intfc> | sw_if_index <id> enable | disable")                        \
15605 _(sw_interface_set_l2_xconnect,                                         \
15606   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15607   "enable | disable")                                                   \
15608 _(sw_interface_set_l2_bridge,                                           \
15609   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15610   "[shg <split-horizon-group>] [bvi]\n"                                 \
15611   "enable | disable")                                                   \
15612 _(bridge_domain_add_del,                                                \
15613   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15614 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15615 _(l2fib_add_del,                                                        \
15616   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15617 _(l2_flags,                                                             \
15618   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15619 _(bridge_flags,                                                         \
15620   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15621 _(tap_connect,                                                          \
15622   "tapname <name> mac <mac-addr> | random-mac")                         \
15623 _(tap_modify,                                                           \
15624   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15625 _(tap_delete,                                                           \
15626   "<vpp-if-name> | sw_if_index <id>")                                   \
15627 _(sw_interface_tap_dump, "")                                            \
15628 _(ip_add_del_route,                                                     \
15629   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15630   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15631   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15632   "[multipath] [count <n>]")                                            \
15633 _(proxy_arp_add_del,                                                    \
15634   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15635 _(proxy_arp_intfc_enable_disable,                                       \
15636   "<intfc> | sw_if_index <id> enable | disable")                        \
15637 _(mpls_add_del_encap,                                                   \
15638   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15639 _(mpls_add_del_decap,                                                   \
15640   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15641 _(mpls_gre_add_del_tunnel,                                              \
15642   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15643   "adj <ip4-address>/<mask-width> [del]")                               \
15644 _(sw_interface_set_unnumbered,                                          \
15645   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15646 _(ip_neighbor_add_del,                                                  \
15647   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15648   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15649 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15650 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15651 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15652   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15653   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15654   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15655 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15656 _(reset_fib, "vrf <n> [ipv6]")                                          \
15657 _(dhcp_proxy_config,                                                    \
15658   "svr <v46-address> src <v46-address>\n"                               \
15659    "insert-cid <n> [del]")                                              \
15660 _(dhcp_proxy_config_2,                                                  \
15661   "svr <v46-address> src <v46-address>\n"                               \
15662    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15663 _(dhcp_proxy_set_vss,                                                   \
15664   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15665 _(dhcp_client_config,                                                   \
15666   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15667 _(set_ip_flow_hash,                                                     \
15668   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15669 _(sw_interface_ip6_enable_disable,                                      \
15670   "<intfc> | sw_if_index <id> enable | disable")                        \
15671 _(sw_interface_ip6_set_link_local_address,                              \
15672   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15673 _(sw_interface_ip6nd_ra_prefix,                                         \
15674   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15675   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15676   "[nolink] [isno]")                                                    \
15677 _(sw_interface_ip6nd_ra_config,                                         \
15678   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15679   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15680   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15681 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15682 _(l2_patch_add_del,                                                     \
15683   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15684   "enable | disable")                                                   \
15685 _(mpls_ethernet_add_del_tunnel,                                         \
15686   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15687   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15688 _(mpls_ethernet_add_del_tunnel_2,                                       \
15689   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15690   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15691 _(sr_tunnel_add_del,                                                    \
15692   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15693   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15694   "[policy <policy_name>]")                                             \
15695 _(sr_policy_add_del,                                                    \
15696   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15697 _(sr_multicast_map_add_del,                                             \
15698   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15699 _(classify_add_del_table,                                               \
15700   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15701   "[del] mask <mask-value>\n"                                           \
15702   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15703 _(classify_add_del_session,                                             \
15704   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15705   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15706   "  [l3 [ip4|ip6]]")                                                   \
15707 _(classify_set_interface_ip_table,                                      \
15708   "<intfc> | sw_if_index <nn> table <nn>")                              \
15709 _(classify_set_interface_l2_tables,                                     \
15710   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15711   "  [other-table <nn>]")                                               \
15712 _(get_node_index, "node <node-name")                                    \
15713 _(add_node_next, "node <node-name> next <next-node-name>")              \
15714 _(l2tpv3_create_tunnel,                                                 \
15715   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15716   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15717   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15718 _(l2tpv3_set_tunnel_cookies,                                            \
15719   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15720   "[new_remote_cookie <nn>]\n")                                         \
15721 _(l2tpv3_interface_enable_disable,                                      \
15722   "<intfc> | sw_if_index <nn> enable | disable")                        \
15723 _(l2tpv3_set_lookup_key,                                                \
15724   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15725 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15726 _(vxlan_add_del_tunnel,                                                 \
15727   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15728   " [decap-next l2|ip4|ip6] [del]")                                     \
15729 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15730 _(gre_add_del_tunnel,                                                   \
15731   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n")          \
15732 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15733 _(l2_fib_clear_table, "")                                               \
15734 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15735 _(l2_interface_vlan_tag_rewrite,                                        \
15736   "<intfc> | sw_if_index <nn> \n"                                       \
15737   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15738   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15739 _(create_vhost_user_if,                                                 \
15740         "socket <filename> [server] [renumber <dev_instance>] "         \
15741         "[mac <mac_address>]")                                          \
15742 _(modify_vhost_user_if,                                                 \
15743         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15744         "[server] [renumber <dev_instance>]")                           \
15745 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15746 _(sw_interface_vhost_user_dump, "")                                     \
15747 _(show_version, "")                                                     \
15748 _(vxlan_gpe_add_del_tunnel,                                             \
15749   "local <addr> remote <addr> vni <nn>\n"                               \
15750     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15751   "[next-ethernet] [next-nsh]\n")                                       \
15752 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15753 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15754 _(interface_name_renumber,                                              \
15755   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15756 _(input_acl_set_interface,                                              \
15757   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15758   "  [l2-table <nn>] [del]")                                            \
15759 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15760 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
15761 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15762 _(ip_dump, "ipv4 | ipv6")                                               \
15763 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15764 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15765   "  spid_id <n> ")                                                     \
15766 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15767   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15768   "  integ_alg <alg> integ_key <hex>")                                  \
15769 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15770   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15771   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15772   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15773 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15774 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15775 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15776   "(auth_data 0x<data> | auth_data <data>)")                            \
15777 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15778   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15779 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15780   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15781   "(local|remote)")                                                     \
15782 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15783 _(delete_loopback,"sw_if_index <nn>")                                   \
15784 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15785 _(map_add_domain,                                                       \
15786   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15787   "ip6-src <ip6addr> "                                                  \
15788   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15789 _(map_del_domain, "index <n>")                                          \
15790 _(map_add_del_rule,                                                     \
15791   "index <n> psid <n> dst <ip6addr> [del]")                             \
15792 _(map_domain_dump, "")                                                  \
15793 _(map_rule_dump, "index <map-domain>")                                  \
15794 _(want_interface_events,  "enable|disable")                             \
15795 _(want_stats,"enable|disable")                                          \
15796 _(get_first_msg_id, "client <name>")                                    \
15797 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15798 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15799   "fib-id <nn> [ip4][ip6][default]")                                    \
15800 _(get_node_graph, " ")                                                  \
15801 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15802 _(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> "     \
15803   "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> "       \
15804   "app-data <app_data in hex> [pow] [ppc <encap|decap>]")               \
15805 _(trace_profile_apply, "id <nn> <ip6-address>/<width>"                  \
15806   " vrf_id <nn>  add | pop | none")                                     \
15807 _(trace_profile_del, "")                                                \
15808 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
15809                             " sw_if_index <sw_if_index> p <priority> "  \
15810                             "w <weight>] [del]")                        \
15811 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
15812                         "iface <intf> | sw_if_index <sw_if_index> "     \
15813                         "p <priority> w <weight> [del]")                \
15814 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
15815                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
15816                           "locator-set <locator_name> [del]")           \
15817 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
15818   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
15819 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
15820 _(lisp_gpe_enable_disable, "enable|disable")                            \
15821 _(lisp_enable_disable, "enable|disable")                                \
15822 _(lisp_gpe_add_del_iface, "up|down")                                    \
15823 _(lisp_add_del_remote_mapping, "add|del vni <vni> deid <dest-eid> "     \
15824                                "rloc <locator> p <prio> "               \
15825                                "w <weight> [rloc <loc> ... ] "          \
15826                                "action <action> [del-all]")             \
15827 _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
15828                           "<src-eid> rloc <locator> p <prio> w <weight>"\
15829                           "[rloc <loc> ... ] action <action>")          \
15830 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
15831 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
15832 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
15833 _(lisp_locator_set_dump, "[locator-set-index <ls-index> | "             \
15834                          "locator-set <loc-set-name>] [local | remote]")\
15835 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
15836                        "[local] | [remote]")                            \
15837 _(lisp_eid_table_vni_dump, "")                                          \
15838 _(lisp_eid_table_map_dump, "l2|l3")                                     \
15839 _(lisp_gpe_tunnel_dump, "")                                             \
15840 _(lisp_map_resolver_dump, "")                                           \
15841 _(show_lisp_status, "")                                                 \
15842 _(lisp_get_map_request_itr_rlocs, "")                                   \
15843 _(show_lisp_pitr, "")                                                   \
15844 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15845 _(af_packet_delete, "name <host interface name>")                       \
15846 _(policer_add_del, "name <policer name> <params> [del]")                \
15847 _(policer_dump, "[name <policer name>]")                                \
15848 _(policer_classify_set_interface,                                       \
15849   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15850   "  [l2-table <nn>] [del]")                                            \
15851 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15852 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
15853     "[master|slave]")                                                   \
15854 _(netmap_delete, "name <interface name>")                               \
15855 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15856 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15857 _(mpls_fib_encap_dump, "")                                              \
15858 _(mpls_fib_decap_dump, "")                                              \
15859 _(classify_table_ids, "")                                               \
15860 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15861 _(classify_table_info, "table_id <nn>")                                 \
15862 _(classify_session_dump, "table_id <nn>")                               \
15863 _(ipfix_enable, "collector_address <ip4> [collector_port <nn>] "        \
15864                 "src_address <ip4> [fib_id <nn>] [path_mtu <nn>] "      \
15865                 "[template_interval <nn>]")                             \
15866 _(ipfix_dump, "")                                                       \
15867 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15868 _(pg_create_interface, "if_id <nn>")                                    \
15869 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15870 _(pg_enable_disable, "[stream <id>] disable")                           \
15871 _(ip_source_and_port_range_check_add_del,                               \
15872   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15873 _(ip_source_and_port_range_check_interface_add_del,                     \
15874   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15875   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15876 _(ipsec_gre_add_del_tunnel,                                             \
15877   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
15878 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
15879 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")
15880
15881 /* List of command functions, CLI names map directly to functions */
15882 #define foreach_cli_function                                    \
15883 _(comment, "usage: comment <ignore-rest-of-line>")              \
15884 _(dump_interface_table, "usage: dump_interface_table")          \
15885 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15886 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15887 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15888 _(dump_stats_table, "usage: dump_stats_table")                  \
15889 _(dump_macro_table, "usage: dump_macro_table ")                 \
15890 _(dump_node_table, "usage: dump_node_table")                    \
15891 _(echo, "usage: echo <message>")                                \
15892 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15893 _(help, "usage: help")                                          \
15894 _(q, "usage: quit")                                             \
15895 _(quit, "usage: quit")                                          \
15896 _(search_node_table, "usage: search_node_table <name>...")      \
15897 _(set, "usage: set <variable-name> <value>")                    \
15898 _(script, "usage: script <file-name>")                          \
15899 _(unset, "usage: unset <variable-name>")
15900
15901 #define _(N,n)                                  \
15902     static void vl_api_##n##_t_handler_uni      \
15903     (vl_api_##n##_t * mp)                       \
15904     {                                           \
15905         vat_main_t * vam = &vat_main;           \
15906         if (vam->json_output) {                 \
15907             vl_api_##n##_t_handler_json(mp);    \
15908         } else {                                \
15909             vl_api_##n##_t_handler(mp);         \
15910         }                                       \
15911     }
15912 foreach_vpe_api_reply_msg;
15913 #undef _
15914
15915 void
15916 vat_api_hookup (vat_main_t * vam)
15917 {
15918 #define _(N,n)                                                  \
15919     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15920                            vl_api_##n##_t_handler_uni,          \
15921                            vl_noop_handler,                     \
15922                            vl_api_##n##_t_endian,               \
15923                            vl_api_##n##_t_print,                \
15924                            sizeof(vl_api_##n##_t), 1);
15925   foreach_vpe_api_reply_msg;
15926 #undef _
15927
15928   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
15929
15930   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15931
15932   vam->function_by_name = hash_create_string (0, sizeof (uword));
15933
15934   vam->help_by_name = hash_create_string (0, sizeof (uword));
15935
15936   /* API messages we can send */
15937 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15938   foreach_vpe_api_msg;
15939 #undef _
15940
15941   /* Help strings */
15942 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15943   foreach_vpe_api_msg;
15944 #undef _
15945
15946   /* CLI functions */
15947 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15948   foreach_cli_function;
15949 #undef _
15950
15951   /* Help strings */
15952 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15953   foreach_cli_function;
15954 #undef _
15955 }
15956
15957 #undef vl_api_version
15958 #define vl_api_version(n,v) static u32 vpe_api_version = v;
15959 #include <vpp-api/vpe.api.h>
15960 #undef vl_api_version
15961
15962 void
15963 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
15964 {
15965   /*
15966    * Send the main API signature in slot 0. This bit of code must
15967    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
15968    */
15969   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
15970 }
15971
15972 /*
15973  * fd.io coding-style-patch-verification: ON
15974  *
15975  * Local Variables:
15976  * eval: (c-set-style "gnu")
15977  * End:
15978  */