Add in-message cli_request/cli_reply API
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/mpls-gre/mpls.h>
39 #if DPDK > 0
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #else
43 #include <inttypes.h>
44 #endif
45 #include <vnet/map/map.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52
53 #include "vat/json_format.h"
54
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248 #if DPDK > 0
249   u32 *r = va_arg (*args, u32 *);
250
251   if (0);
252 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
253   foreach_ipsec_policy_action
254 #undef _
255     else
256     return 0;
257   return 1;
258 #else
259   return 0;
260 #endif
261 }
262
263 uword
264 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
265 {
266 #if DPDK > 0
267   u32 *r = va_arg (*args, u32 *);
268
269   if (0);
270 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
271   foreach_ipsec_crypto_alg
272 #undef _
273     else
274     return 0;
275   return 1;
276 #else
277   return 0;
278 #endif
279 }
280
281 u8 *
282 format_ipsec_crypto_alg (u8 * s, va_list * args)
283 {
284 #if DPDK > 0
285   u32 i = va_arg (*args, u32);
286   u8 *t = 0;
287
288   switch (i)
289     {
290 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
291       foreach_ipsec_crypto_alg
292 #undef _
293     default:
294       return format (s, "unknown");
295     }
296   return format (s, "%s", t);
297 #else
298   return format (s, "Unimplemented");
299 #endif
300 }
301
302 uword
303 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
304 {
305 #if DPDK > 0
306   u32 *r = va_arg (*args, u32 *);
307
308   if (0);
309 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
310   foreach_ipsec_integ_alg
311 #undef _
312     else
313     return 0;
314   return 1;
315 #else
316   return 0;
317 #endif
318 }
319
320 u8 *
321 format_ipsec_integ_alg (u8 * s, va_list * args)
322 {
323 #if DPDK > 0
324   u32 i = va_arg (*args, u32);
325   u8 *t = 0;
326
327   switch (i)
328     {
329 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
330       foreach_ipsec_integ_alg
331 #undef _
332     default:
333       return format (s, "unknown");
334     }
335   return format (s, "%s", t);
336 #else
337   return format (s, "Unsupported");
338 #endif
339 }
340
341 uword
342 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
343 {
344 #if DPDK > 0
345   u32 *r = va_arg (*args, u32 *);
346
347   if (0);
348 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
349   foreach_ikev2_auth_method
350 #undef _
351     else
352     return 0;
353   return 1;
354 #else
355   return 0;
356 #endif
357 }
358
359 uword
360 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
361 {
362 #if DPDK > 0
363   u32 *r = va_arg (*args, u32 *);
364
365   if (0);
366 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
367   foreach_ikev2_id_type
368 #undef _
369     else
370     return 0;
371   return 1;
372 #else
373   return 0;
374 #endif
375 }
376
377 uword
378 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
379 {
380   u8 *r = va_arg (*args, u8 *);
381
382   if (unformat (input, "kbps"))
383     *r = SSE2_QOS_RATE_KBPS;
384   else if (unformat (input, "pps"))
385     *r = SSE2_QOS_RATE_PPS;
386   else
387     return 0;
388   return 1;
389 }
390
391 uword
392 unformat_policer_round_type (unformat_input_t * input, va_list * args)
393 {
394   u8 *r = va_arg (*args, u8 *);
395
396   if (unformat (input, "closest"))
397     *r = SSE2_QOS_ROUND_TO_CLOSEST;
398   else if (unformat (input, "up"))
399     *r = SSE2_QOS_ROUND_TO_UP;
400   else if (unformat (input, "down"))
401     *r = SSE2_QOS_ROUND_TO_DOWN;
402   else
403     return 0;
404   return 1;
405 }
406
407 uword
408 unformat_policer_type (unformat_input_t * input, va_list * args)
409 {
410   u8 *r = va_arg (*args, u8 *);
411
412   if (unformat (input, "1r2c"))
413     *r = SSE2_QOS_POLICER_TYPE_1R2C;
414   else if (unformat (input, "1r3c"))
415     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
416   else if (unformat (input, "2r3c-2698"))
417     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
418   else if (unformat (input, "2r3c-4115"))
419     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
420   else if (unformat (input, "2r3c-mef5cf1"))
421     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
422   else
423     return 0;
424   return 1;
425 }
426
427 uword
428 unformat_dscp (unformat_input_t * input, va_list * va)
429 {
430   u8 *r = va_arg (*va, u8 *);
431
432   if (0);
433 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
434   foreach_vnet_dscp
435 #undef _
436     else
437     return 0;
438   return 1;
439 }
440
441 uword
442 unformat_policer_action_type (unformat_input_t * input, va_list * va)
443 {
444   sse2_qos_pol_action_params_st *a
445     = va_arg (*va, sse2_qos_pol_action_params_st *);
446
447   if (unformat (input, "drop"))
448     a->action_type = SSE2_QOS_ACTION_DROP;
449   else if (unformat (input, "transmit"))
450     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
451   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
452     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
453   else
454     return 0;
455   return 1;
456 }
457
458 uword
459 unformat_classify_table_type (unformat_input_t * input, va_list * va)
460 {
461   u32 *r = va_arg (*va, u32 *);
462   u32 tid;
463
464   if (unformat (input, "ip4"))
465     tid = POLICER_CLASSIFY_TABLE_IP4;
466   else if (unformat (input, "ip6"))
467     tid = POLICER_CLASSIFY_TABLE_IP6;
468   else if (unformat (input, "l2"))
469     tid = POLICER_CLASSIFY_TABLE_L2;
470   else
471     return 0;
472
473   *r = tid;
474   return 1;
475 }
476
477 u8 *
478 format_ip4_address (u8 * s, va_list * args)
479 {
480   u8 *a = va_arg (*args, u8 *);
481   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
482 }
483
484 u8 *
485 format_ip6_address (u8 * s, va_list * args)
486 {
487   ip6_address_t *a = va_arg (*args, ip6_address_t *);
488   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
489
490   i_max_n_zero = ARRAY_LEN (a->as_u16);
491   max_n_zeros = 0;
492   i_first_zero = i_max_n_zero;
493   n_zeros = 0;
494   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
495     {
496       u32 is_zero = a->as_u16[i] == 0;
497       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
498         {
499           i_first_zero = i;
500           n_zeros = 0;
501         }
502       n_zeros += is_zero;
503       if ((!is_zero && n_zeros > max_n_zeros)
504           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
505         {
506           i_max_n_zero = i_first_zero;
507           max_n_zeros = n_zeros;
508           i_first_zero = ARRAY_LEN (a->as_u16);
509           n_zeros = 0;
510         }
511     }
512
513   last_double_colon = 0;
514   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
515     {
516       if (i == i_max_n_zero && max_n_zeros > 1)
517         {
518           s = format (s, "::");
519           i += max_n_zeros - 1;
520           last_double_colon = 1;
521         }
522       else
523         {
524           s = format (s, "%s%x",
525                       (last_double_colon || i == 0) ? "" : ":",
526                       clib_net_to_host_u16 (a->as_u16[i]));
527           last_double_colon = 0;
528         }
529     }
530
531   return s;
532 }
533
534 /* Format an IP46 address. */
535 u8 *
536 format_ip46_address (u8 * s, va_list * args)
537 {
538   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
539   ip46_type_t type = va_arg (*args, ip46_type_t);
540   int is_ip4 = 1;
541
542   switch (type)
543     {
544     case IP46_TYPE_ANY:
545       is_ip4 = ip46_address_is_ip4 (ip46);
546       break;
547     case IP46_TYPE_IP4:
548       is_ip4 = 1;
549       break;
550     case IP46_TYPE_IP6:
551       is_ip4 = 0;
552       break;
553     }
554
555   return is_ip4 ?
556     format (s, "%U", format_ip4_address, &ip46->ip4) :
557     format (s, "%U", format_ip6_address, &ip46->ip6);
558 }
559
560 u8 *
561 format_ethernet_address (u8 * s, va_list * args)
562 {
563   u8 *a = va_arg (*args, u8 *);
564
565   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
566                  a[0], a[1], a[2], a[3], a[4], a[5]);
567 }
568
569 void
570 increment_v4_address (ip4_address_t * a)
571 {
572   u32 v;
573
574   v = ntohl (a->as_u32) + 1;
575   a->as_u32 = ntohl (v);
576 }
577
578 void
579 increment_v6_address (ip6_address_t * a)
580 {
581   u64 v0, v1;
582
583   v0 = clib_net_to_host_u64 (a->as_u64[0]);
584   v1 = clib_net_to_host_u64 (a->as_u64[1]);
585
586   v1 += 1;
587   if (v1 == 0)
588     v0 += 1;
589   a->as_u64[0] = clib_net_to_host_u64 (v0);
590   a->as_u64[1] = clib_net_to_host_u64 (v1);
591 }
592
593 void
594 increment_mac_address (u64 * mac)
595 {
596   u64 tmp = *mac;
597
598   tmp = clib_net_to_host_u64 (tmp);
599   tmp += 1 << 16;               /* skip unused (least significant) octets */
600   tmp = clib_host_to_net_u64 (tmp);
601   *mac = tmp;
602 }
603
604 static void vl_api_create_loopback_reply_t_handler
605   (vl_api_create_loopback_reply_t * mp)
606 {
607   vat_main_t *vam = &vat_main;
608   i32 retval = ntohl (mp->retval);
609
610   vam->retval = retval;
611   vam->regenerate_interface_table = 1;
612   vam->sw_if_index = ntohl (mp->sw_if_index);
613   vam->result_ready = 1;
614 }
615
616 static void vl_api_create_loopback_reply_t_handler_json
617   (vl_api_create_loopback_reply_t * mp)
618 {
619   vat_main_t *vam = &vat_main;
620   vat_json_node_t node;
621
622   vat_json_init_object (&node);
623   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
624   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
625
626   vat_json_print (vam->ofp, &node);
627   vat_json_free (&node);
628   vam->retval = ntohl (mp->retval);
629   vam->result_ready = 1;
630 }
631
632 static void vl_api_af_packet_create_reply_t_handler
633   (vl_api_af_packet_create_reply_t * mp)
634 {
635   vat_main_t *vam = &vat_main;
636   i32 retval = ntohl (mp->retval);
637
638   vam->retval = retval;
639   vam->regenerate_interface_table = 1;
640   vam->sw_if_index = ntohl (mp->sw_if_index);
641   vam->result_ready = 1;
642 }
643
644 static void vl_api_af_packet_create_reply_t_handler_json
645   (vl_api_af_packet_create_reply_t * mp)
646 {
647   vat_main_t *vam = &vat_main;
648   vat_json_node_t node;
649
650   vat_json_init_object (&node);
651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
652   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
653
654   vat_json_print (vam->ofp, &node);
655   vat_json_free (&node);
656
657   vam->retval = ntohl (mp->retval);
658   vam->result_ready = 1;
659 }
660
661 static void vl_api_create_vlan_subif_reply_t_handler
662   (vl_api_create_vlan_subif_reply_t * mp)
663 {
664   vat_main_t *vam = &vat_main;
665   i32 retval = ntohl (mp->retval);
666
667   vam->retval = retval;
668   vam->regenerate_interface_table = 1;
669   vam->sw_if_index = ntohl (mp->sw_if_index);
670   vam->result_ready = 1;
671 }
672
673 static void vl_api_create_vlan_subif_reply_t_handler_json
674   (vl_api_create_vlan_subif_reply_t * mp)
675 {
676   vat_main_t *vam = &vat_main;
677   vat_json_node_t node;
678
679   vat_json_init_object (&node);
680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
681   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
682
683   vat_json_print (vam->ofp, &node);
684   vat_json_free (&node);
685
686   vam->retval = ntohl (mp->retval);
687   vam->result_ready = 1;
688 }
689
690 static void vl_api_create_subif_reply_t_handler
691   (vl_api_create_subif_reply_t * mp)
692 {
693   vat_main_t *vam = &vat_main;
694   i32 retval = ntohl (mp->retval);
695
696   vam->retval = retval;
697   vam->regenerate_interface_table = 1;
698   vam->sw_if_index = ntohl (mp->sw_if_index);
699   vam->result_ready = 1;
700 }
701
702 static void vl_api_create_subif_reply_t_handler_json
703   (vl_api_create_subif_reply_t * mp)
704 {
705   vat_main_t *vam = &vat_main;
706   vat_json_node_t node;
707
708   vat_json_init_object (&node);
709   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
710   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
711
712   vat_json_print (vam->ofp, &node);
713   vat_json_free (&node);
714
715   vam->retval = ntohl (mp->retval);
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   i32 retval = ntohl (mp->retval);
724
725   vam->retval = retval;
726   vam->regenerate_interface_table = 1;
727   vam->result_ready = 1;
728 }
729
730 static void vl_api_interface_name_renumber_reply_t_handler_json
731   (vl_api_interface_name_renumber_reply_t * mp)
732 {
733   vat_main_t *vam = &vat_main;
734   vat_json_node_t node;
735
736   vat_json_init_object (&node);
737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
738
739   vat_json_print (vam->ofp, &node);
740   vat_json_free (&node);
741
742   vam->retval = ntohl (mp->retval);
743   vam->result_ready = 1;
744 }
745
746 /*
747  * Special-case: build the interface table, maintain
748  * the next loopback sw_if_index vbl.
749  */
750 static void vl_api_sw_interface_details_t_handler
751   (vl_api_sw_interface_details_t * mp)
752 {
753   vat_main_t *vam = &vat_main;
754   u8 *s = format (0, "%s%c", mp->interface_name, 0);
755
756   hash_set_mem (vam->sw_if_index_by_interface_name, s,
757                 ntohl (mp->sw_if_index));
758
759   /* In sub interface case, fill the sub interface table entry */
760   if (mp->sw_if_index != mp->sup_sw_if_index)
761     {
762       sw_interface_subif_t *sub = NULL;
763
764       vec_add2 (vam->sw_if_subif_table, sub, 1);
765
766       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
767       strncpy ((char *) sub->interface_name, (char *) s,
768                vec_len (sub->interface_name));
769       sub->sw_if_index = ntohl (mp->sw_if_index);
770       sub->sub_id = ntohl (mp->sub_id);
771
772       sub->sub_dot1ad = mp->sub_dot1ad;
773       sub->sub_number_of_tags = mp->sub_number_of_tags;
774       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
775       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
776       sub->sub_exact_match = mp->sub_exact_match;
777       sub->sub_default = mp->sub_default;
778       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
779       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
780
781       /* vlan tag rewrite */
782       sub->vtr_op = ntohl (mp->vtr_op);
783       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
784       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
785       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
786     }
787 }
788
789 static void vl_api_sw_interface_details_t_handler_json
790   (vl_api_sw_interface_details_t * mp)
791 {
792   vat_main_t *vam = &vat_main;
793   vat_json_node_t *node = NULL;
794
795   if (VAT_JSON_ARRAY != vam->json_tree.type)
796     {
797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
798       vat_json_init_array (&vam->json_tree);
799     }
800   node = vat_json_array_add (&vam->json_tree);
801
802   vat_json_init_object (node);
803   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
804   vat_json_object_add_uint (node, "sup_sw_if_index",
805                             ntohl (mp->sup_sw_if_index));
806   vat_json_object_add_uint (node, "l2_address_length",
807                             ntohl (mp->l2_address_length));
808   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
809                              sizeof (mp->l2_address));
810   vat_json_object_add_string_copy (node, "interface_name",
811                                    mp->interface_name);
812   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
813   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
814   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
815   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
816   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
817   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
818   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
819   vat_json_object_add_uint (node, "sub_number_of_tags",
820                             mp->sub_number_of_tags);
821   vat_json_object_add_uint (node, "sub_outer_vlan_id",
822                             ntohs (mp->sub_outer_vlan_id));
823   vat_json_object_add_uint (node, "sub_inner_vlan_id",
824                             ntohs (mp->sub_inner_vlan_id));
825   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
826   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
827   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
828                             mp->sub_outer_vlan_id_any);
829   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
830                             mp->sub_inner_vlan_id_any);
831   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
832   vat_json_object_add_uint (node, "vtr_push_dot1q",
833                             ntohl (mp->vtr_push_dot1q));
834   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
835   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   vat_main_t *vam = &vat_main;
842   if (vam->interface_event_display)
843     errmsg ("interface flags: sw_if_index %d %s %s\n",
844             ntohl (mp->sw_if_index),
845             mp->admin_up_down ? "admin-up" : "admin-down",
846             mp->link_up_down ? "link-up" : "link-down");
847 }
848
849 static void vl_api_sw_interface_set_flags_t_handler_json
850   (vl_api_sw_interface_set_flags_t * mp)
851 {
852   /* JSON output not supported */
853 }
854
855 static void
856 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->shmem_result = (u8 *) mp->reply_in_shmem;
863   vam->result_ready = 1;
864 }
865
866 static void
867 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
868 {
869   vat_main_t *vam = &vat_main;
870   vat_json_node_t node;
871   api_main_t *am = &api_main;
872   void *oldheap;
873   u8 *reply;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "reply_in_shmem",
878                             ntohl (mp->reply_in_shmem));
879   /* Toss the shared-memory original... */
880   pthread_mutex_lock (&am->vlib_rp->mutex);
881   oldheap = svm_push_data_heap (am->vlib_rp);
882
883   reply = (u8 *) (mp->reply_in_shmem);
884   vec_free (reply);
885
886   svm_pop_heap (oldheap);
887   pthread_mutex_unlock (&am->vlib_rp->mutex);
888
889   vat_json_print (vam->ofp, &node);
890   vat_json_free (&node);
891
892   vam->retval = ntohl (mp->retval);
893   vam->result_ready = 1;
894 }
895
896 static void
897 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   i32 retval = ntohl (mp->retval);
901
902   vam->retval = retval;
903   vam->cmd_reply = mp->reply;
904   vam->result_ready = 1;
905 }
906
907 static void
908 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
909 {
910   vat_main_t *vam = &vat_main;
911   vat_json_node_t node;
912
913   vat_json_init_object (&node);
914   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
915   vat_json_object_add_string_copy (&node, "reply", mp->reply);
916
917   vat_json_print (vam->ofp, &node);
918   vat_json_free (&node);
919
920   vam->retval = ntohl (mp->retval);
921   vam->result_ready = 1;
922 }
923
924 static void vl_api_classify_add_del_table_reply_t_handler
925   (vl_api_classify_add_del_table_reply_t * mp)
926 {
927   vat_main_t *vam = &vat_main;
928   i32 retval = ntohl (mp->retval);
929   if (vam->async_mode)
930     {
931       vam->async_errors += (retval < 0);
932     }
933   else
934     {
935       vam->retval = retval;
936       if (retval == 0 &&
937           ((mp->new_table_index != 0xFFFFFFFF) ||
938            (mp->skip_n_vectors != 0xFFFFFFFF) ||
939            (mp->match_n_vectors != 0xFFFFFFFF)))
940         /*
941          * Note: this is just barely thread-safe, depends on
942          * the main thread spinning waiting for an answer...
943          */
944         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
945                 ntohl (mp->new_table_index),
946                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
947       vam->result_ready = 1;
948     }
949 }
950
951 static void vl_api_classify_add_del_table_reply_t_handler_json
952   (vl_api_classify_add_del_table_reply_t * mp)
953 {
954   vat_main_t *vam = &vat_main;
955   vat_json_node_t node;
956
957   vat_json_init_object (&node);
958   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
959   vat_json_object_add_uint (&node, "new_table_index",
960                             ntohl (mp->new_table_index));
961   vat_json_object_add_uint (&node, "skip_n_vectors",
962                             ntohl (mp->skip_n_vectors));
963   vat_json_object_add_uint (&node, "match_n_vectors",
964                             ntohl (mp->match_n_vectors));
965
966   vat_json_print (vam->ofp, &node);
967   vat_json_free (&node);
968
969   vam->retval = ntohl (mp->retval);
970   vam->result_ready = 1;
971 }
972
973 static void vl_api_get_node_index_reply_t_handler
974   (vl_api_get_node_index_reply_t * mp)
975 {
976   vat_main_t *vam = &vat_main;
977   i32 retval = ntohl (mp->retval);
978   if (vam->async_mode)
979     {
980       vam->async_errors += (retval < 0);
981     }
982   else
983     {
984       vam->retval = retval;
985       if (retval == 0)
986         errmsg ("node index %d\n", ntohl (mp->node_index));
987       vam->result_ready = 1;
988     }
989 }
990
991 static void vl_api_get_node_index_reply_t_handler_json
992   (vl_api_get_node_index_reply_t * mp)
993 {
994   vat_main_t *vam = &vat_main;
995   vat_json_node_t node;
996
997   vat_json_init_object (&node);
998   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
999   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1000
1001   vat_json_print (vam->ofp, &node);
1002   vat_json_free (&node);
1003
1004   vam->retval = ntohl (mp->retval);
1005   vam->result_ready = 1;
1006 }
1007
1008 static void vl_api_get_next_index_reply_t_handler
1009   (vl_api_get_next_index_reply_t * mp)
1010 {
1011   vat_main_t *vam = &vat_main;
1012   i32 retval = ntohl (mp->retval);
1013   if (vam->async_mode)
1014     {
1015       vam->async_errors += (retval < 0);
1016     }
1017   else
1018     {
1019       vam->retval = retval;
1020       if (retval == 0)
1021         errmsg ("next node index %d\n", ntohl (mp->next_index));
1022       vam->result_ready = 1;
1023     }
1024 }
1025
1026 static void vl_api_get_next_index_reply_t_handler_json
1027   (vl_api_get_next_index_reply_t * mp)
1028 {
1029   vat_main_t *vam = &vat_main;
1030   vat_json_node_t node;
1031
1032   vat_json_init_object (&node);
1033   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1034   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1035
1036   vat_json_print (vam->ofp, &node);
1037   vat_json_free (&node);
1038
1039   vam->retval = ntohl (mp->retval);
1040   vam->result_ready = 1;
1041 }
1042
1043 static void vl_api_add_node_next_reply_t_handler
1044   (vl_api_add_node_next_reply_t * mp)
1045 {
1046   vat_main_t *vam = &vat_main;
1047   i32 retval = ntohl (mp->retval);
1048   if (vam->async_mode)
1049     {
1050       vam->async_errors += (retval < 0);
1051     }
1052   else
1053     {
1054       vam->retval = retval;
1055       if (retval == 0)
1056         errmsg ("next index %d\n", ntohl (mp->next_index));
1057       vam->result_ready = 1;
1058     }
1059 }
1060
1061 static void vl_api_add_node_next_reply_t_handler_json
1062   (vl_api_add_node_next_reply_t * mp)
1063 {
1064   vat_main_t *vam = &vat_main;
1065   vat_json_node_t node;
1066
1067   vat_json_init_object (&node);
1068   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1069   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1070
1071   vat_json_print (vam->ofp, &node);
1072   vat_json_free (&node);
1073
1074   vam->retval = ntohl (mp->retval);
1075   vam->result_ready = 1;
1076 }
1077
1078 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1079   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1080 {
1081   vat_main_t *vam = &vat_main;
1082   i32 retval = ntohl (mp->retval);
1083   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1084
1085   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1086     {
1087       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1088     }
1089   vam->retval = retval;
1090   vam->result_ready = 1;
1091 }
1092
1093 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1094   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1095 {
1096   vat_main_t *vam = &vat_main;
1097   vat_json_node_t node;
1098
1099   vat_json_init_object (&node);
1100   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1101   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1102                             ntohl (mp->tunnel_sw_if_index));
1103
1104   vat_json_print (vam->ofp, &node);
1105   vat_json_free (&node);
1106
1107   vam->retval = ntohl (mp->retval);
1108   vam->result_ready = 1;
1109 }
1110
1111
1112 static void vl_api_show_version_reply_t_handler
1113   (vl_api_show_version_reply_t * mp)
1114 {
1115   vat_main_t *vam = &vat_main;
1116   i32 retval = ntohl (mp->retval);
1117
1118   if (retval >= 0)
1119     {
1120       errmsg ("        program: %s\n", mp->program);
1121       errmsg ("        version: %s\n", mp->version);
1122       errmsg ("     build date: %s\n", mp->build_date);
1123       errmsg ("build directory: %s\n", mp->build_directory);
1124     }
1125   vam->retval = retval;
1126   vam->result_ready = 1;
1127 }
1128
1129 static void vl_api_show_version_reply_t_handler_json
1130   (vl_api_show_version_reply_t * mp)
1131 {
1132   vat_main_t *vam = &vat_main;
1133   vat_json_node_t node;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_string_copy (&node, "program", mp->program);
1138   vat_json_object_add_string_copy (&node, "version", mp->version);
1139   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1140   vat_json_object_add_string_copy (&node, "build_directory",
1141                                    mp->build_directory);
1142
1143   vat_json_print (vam->ofp, &node);
1144   vat_json_free (&node);
1145
1146   vam->retval = ntohl (mp->retval);
1147   vam->result_ready = 1;
1148 }
1149
1150 static void
1151 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1152 {
1153   vat_main_t *vam = &vat_main;
1154   errmsg ("arp event: address %U new mac %U sw_if_index %d\n",
1155           format_ip4_address, &mp->address,
1156           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1157 }
1158
1159 static void
1160 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1161 {
1162   /* JSON output not supported */
1163 }
1164
1165 static void
1166 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1167 {
1168   vat_main_t *vam = &vat_main;
1169   errmsg ("ip6 nd event: address %U new mac %U sw_if_index %d\n",
1170           format_ip6_address, mp->address,
1171           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1172 }
1173
1174 static void
1175 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1176 {
1177   /* JSON output not supported */
1178 }
1179
1180 /*
1181  * Special-case: build the bridge domain table, maintain
1182  * the next bd id vbl.
1183  */
1184 static void vl_api_bridge_domain_details_t_handler
1185   (vl_api_bridge_domain_details_t * mp)
1186 {
1187   vat_main_t *vam = &vat_main;
1188   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1189
1190   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1191            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1192
1193   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1194            ntohl (mp->bd_id), mp->learn, mp->forward,
1195            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1196
1197   if (n_sw_ifs)
1198     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1199              "Interface Name");
1200 }
1201
1202 static void vl_api_bridge_domain_details_t_handler_json
1203   (vl_api_bridge_domain_details_t * mp)
1204 {
1205   vat_main_t *vam = &vat_main;
1206   vat_json_node_t *node, *array = NULL;
1207
1208   if (VAT_JSON_ARRAY != vam->json_tree.type)
1209     {
1210       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1211       vat_json_init_array (&vam->json_tree);
1212     }
1213   node = vat_json_array_add (&vam->json_tree);
1214
1215   vat_json_init_object (node);
1216   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1217   vat_json_object_add_uint (node, "flood", mp->flood);
1218   vat_json_object_add_uint (node, "forward", mp->forward);
1219   vat_json_object_add_uint (node, "learn", mp->learn);
1220   vat_json_object_add_uint (node, "bvi_sw_if_index",
1221                             ntohl (mp->bvi_sw_if_index));
1222   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1223   array = vat_json_object_add (node, "sw_if");
1224   vat_json_init_array (array);
1225 }
1226
1227 /*
1228  * Special-case: build the bridge domain sw if table.
1229  */
1230 static void vl_api_bridge_domain_sw_if_details_t_handler
1231   (vl_api_bridge_domain_sw_if_details_t * mp)
1232 {
1233   vat_main_t *vam = &vat_main;
1234   hash_pair_t *p;
1235   u8 *sw_if_name = 0;
1236   u32 sw_if_index;
1237
1238   sw_if_index = ntohl (mp->sw_if_index);
1239   /* *INDENT-OFF* */
1240   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1241   ({
1242     if ((u32) p->value[0] == sw_if_index)
1243       {
1244         sw_if_name = (u8 *)(p->key);
1245         break;
1246       }
1247   }));
1248   /* *INDENT-ON* */
1249
1250   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1251            mp->shg, sw_if_name ? (char *) sw_if_name :
1252            "sw_if_index not found!");
1253 }
1254
1255 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1256   (vl_api_bridge_domain_sw_if_details_t * mp)
1257 {
1258   vat_main_t *vam = &vat_main;
1259   vat_json_node_t *node = NULL;
1260   uword last_index = 0;
1261
1262   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1263   ASSERT (vec_len (vam->json_tree.array) >= 1);
1264   last_index = vec_len (vam->json_tree.array) - 1;
1265   node = &vam->json_tree.array[last_index];
1266   node = vat_json_object_get_element (node, "sw_if");
1267   ASSERT (NULL != node);
1268   node = vat_json_array_add (node);
1269
1270   vat_json_init_object (node);
1271   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1272   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1273   vat_json_object_add_uint (node, "shg", mp->shg);
1274 }
1275
1276 static void vl_api_control_ping_reply_t_handler
1277   (vl_api_control_ping_reply_t * mp)
1278 {
1279   vat_main_t *vam = &vat_main;
1280   i32 retval = ntohl (mp->retval);
1281   if (vam->async_mode)
1282     {
1283       vam->async_errors += (retval < 0);
1284     }
1285   else
1286     {
1287       vam->retval = retval;
1288       vam->result_ready = 1;
1289     }
1290 }
1291
1292 static void vl_api_control_ping_reply_t_handler_json
1293   (vl_api_control_ping_reply_t * mp)
1294 {
1295   vat_main_t *vam = &vat_main;
1296   i32 retval = ntohl (mp->retval);
1297
1298   if (VAT_JSON_NONE != vam->json_tree.type)
1299     {
1300       vat_json_print (vam->ofp, &vam->json_tree);
1301       vat_json_free (&vam->json_tree);
1302       vam->json_tree.type = VAT_JSON_NONE;
1303     }
1304   else
1305     {
1306       /* just print [] */
1307       vat_json_init_array (&vam->json_tree);
1308       vat_json_print (vam->ofp, &vam->json_tree);
1309       vam->json_tree.type = VAT_JSON_NONE;
1310     }
1311
1312   vam->retval = retval;
1313   vam->result_ready = 1;
1314 }
1315
1316 static void vl_api_noprint_control_ping_reply_t_handler
1317   (vl_api_noprint_control_ping_reply_t * mp)
1318 {
1319   vat_main_t *vam = &vat_main;
1320   i32 retval = ntohl (mp->retval);
1321   if (vam->async_mode)
1322     {
1323       vam->async_errors += (retval < 0);
1324     }
1325   else
1326     {
1327       vam->retval = retval;
1328       vam->result_ready = 1;
1329     }
1330 }
1331
1332 static void vl_api_noprint_control_ping_reply_t_handler_json
1333   (vl_api_noprint_control_ping_reply_t * mp)
1334 {
1335   vat_main_t *vam = &vat_main;
1336   i32 retval = ntohl (mp->retval);
1337
1338   if (vam->noprint_msg)
1339     {
1340       vam->retval = retval;
1341       vam->result_ready = 1;
1342       return;
1343     }
1344
1345   if (VAT_JSON_NONE != vam->json_tree.type)
1346     {
1347       vat_json_print (vam->ofp, &vam->json_tree);
1348       vat_json_free (&vam->json_tree);
1349       vam->json_tree.type = VAT_JSON_NONE;
1350     }
1351   else
1352     {
1353       /* just print [] */
1354       vat_json_init_array (&vam->json_tree);
1355       vat_json_print (vam->ofp, &vam->json_tree);
1356       vam->json_tree.type = VAT_JSON_NONE;
1357     }
1358
1359   vam->retval = retval;
1360   vam->result_ready = 1;
1361 }
1362
1363 static void
1364 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1365 {
1366   vat_main_t *vam = &vat_main;
1367   i32 retval = ntohl (mp->retval);
1368   if (vam->async_mode)
1369     {
1370       vam->async_errors += (retval < 0);
1371     }
1372   else
1373     {
1374       vam->retval = retval;
1375       vam->result_ready = 1;
1376     }
1377 }
1378
1379 static void vl_api_l2_flags_reply_t_handler_json
1380   (vl_api_l2_flags_reply_t * mp)
1381 {
1382   vat_main_t *vam = &vat_main;
1383   vat_json_node_t node;
1384
1385   vat_json_init_object (&node);
1386   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1387   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1388                             ntohl (mp->resulting_feature_bitmap));
1389
1390   vat_json_print (vam->ofp, &node);
1391   vat_json_free (&node);
1392
1393   vam->retval = ntohl (mp->retval);
1394   vam->result_ready = 1;
1395 }
1396
1397 static void vl_api_bridge_flags_reply_t_handler
1398   (vl_api_bridge_flags_reply_t * mp)
1399 {
1400   vat_main_t *vam = &vat_main;
1401   i32 retval = ntohl (mp->retval);
1402   if (vam->async_mode)
1403     {
1404       vam->async_errors += (retval < 0);
1405     }
1406   else
1407     {
1408       vam->retval = retval;
1409       vam->result_ready = 1;
1410     }
1411 }
1412
1413 static void vl_api_bridge_flags_reply_t_handler_json
1414   (vl_api_bridge_flags_reply_t * mp)
1415 {
1416   vat_main_t *vam = &vat_main;
1417   vat_json_node_t node;
1418
1419   vat_json_init_object (&node);
1420   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1421   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1422                             ntohl (mp->resulting_feature_bitmap));
1423
1424   vat_json_print (vam->ofp, &node);
1425   vat_json_free (&node);
1426
1427   vam->retval = ntohl (mp->retval);
1428   vam->result_ready = 1;
1429 }
1430
1431 static void vl_api_tap_connect_reply_t_handler
1432   (vl_api_tap_connect_reply_t * mp)
1433 {
1434   vat_main_t *vam = &vat_main;
1435   i32 retval = ntohl (mp->retval);
1436   if (vam->async_mode)
1437     {
1438       vam->async_errors += (retval < 0);
1439     }
1440   else
1441     {
1442       vam->retval = retval;
1443       vam->sw_if_index = ntohl (mp->sw_if_index);
1444       vam->result_ready = 1;
1445     }
1446
1447 }
1448
1449 static void vl_api_tap_connect_reply_t_handler_json
1450   (vl_api_tap_connect_reply_t * mp)
1451 {
1452   vat_main_t *vam = &vat_main;
1453   vat_json_node_t node;
1454
1455   vat_json_init_object (&node);
1456   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1457   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1458
1459   vat_json_print (vam->ofp, &node);
1460   vat_json_free (&node);
1461
1462   vam->retval = ntohl (mp->retval);
1463   vam->result_ready = 1;
1464
1465 }
1466
1467 static void
1468 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1469 {
1470   vat_main_t *vam = &vat_main;
1471   i32 retval = ntohl (mp->retval);
1472   if (vam->async_mode)
1473     {
1474       vam->async_errors += (retval < 0);
1475     }
1476   else
1477     {
1478       vam->retval = retval;
1479       vam->sw_if_index = ntohl (mp->sw_if_index);
1480       vam->result_ready = 1;
1481     }
1482 }
1483
1484 static void vl_api_tap_modify_reply_t_handler_json
1485   (vl_api_tap_modify_reply_t * mp)
1486 {
1487   vat_main_t *vam = &vat_main;
1488   vat_json_node_t node;
1489
1490   vat_json_init_object (&node);
1491   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1492   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1493
1494   vat_json_print (vam->ofp, &node);
1495   vat_json_free (&node);
1496
1497   vam->retval = ntohl (mp->retval);
1498   vam->result_ready = 1;
1499 }
1500
1501 static void
1502 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1503 {
1504   vat_main_t *vam = &vat_main;
1505   i32 retval = ntohl (mp->retval);
1506   if (vam->async_mode)
1507     {
1508       vam->async_errors += (retval < 0);
1509     }
1510   else
1511     {
1512       vam->retval = retval;
1513       vam->result_ready = 1;
1514     }
1515 }
1516
1517 static void vl_api_tap_delete_reply_t_handler_json
1518   (vl_api_tap_delete_reply_t * mp)
1519 {
1520   vat_main_t *vam = &vat_main;
1521   vat_json_node_t node;
1522
1523   vat_json_init_object (&node);
1524   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1525
1526   vat_json_print (vam->ofp, &node);
1527   vat_json_free (&node);
1528
1529   vam->retval = ntohl (mp->retval);
1530   vam->result_ready = 1;
1531 }
1532
1533 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1534   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1535 {
1536   vat_main_t *vam = &vat_main;
1537   i32 retval = ntohl (mp->retval);
1538   if (vam->async_mode)
1539     {
1540       vam->async_errors += (retval < 0);
1541     }
1542   else
1543     {
1544       vam->retval = retval;
1545       vam->result_ready = 1;
1546     }
1547 }
1548
1549 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1550   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1551 {
1552   vat_main_t *vam = &vat_main;
1553   vat_json_node_t node;
1554
1555   vat_json_init_object (&node);
1556   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1557   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1558                             ntohl (mp->tunnel_sw_if_index));
1559
1560   vat_json_print (vam->ofp, &node);
1561   vat_json_free (&node);
1562
1563   vam->retval = ntohl (mp->retval);
1564   vam->result_ready = 1;
1565 }
1566
1567 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1568   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1569 {
1570   vat_main_t *vam = &vat_main;
1571   i32 retval = ntohl (mp->retval);
1572   if (vam->async_mode)
1573     {
1574       vam->async_errors += (retval < 0);
1575     }
1576   else
1577     {
1578       vam->retval = retval;
1579       vam->sw_if_index = ntohl (mp->sw_if_index);
1580       vam->result_ready = 1;
1581     }
1582 }
1583
1584 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1585   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1586 {
1587   vat_main_t *vam = &vat_main;
1588   vat_json_node_t node;
1589
1590   vat_json_init_object (&node);
1591   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1592   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1593
1594   vat_json_print (vam->ofp, &node);
1595   vat_json_free (&node);
1596
1597   vam->retval = ntohl (mp->retval);
1598   vam->result_ready = 1;
1599 }
1600
1601
1602 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1603   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1604 {
1605   vat_main_t *vam = &vat_main;
1606   i32 retval = ntohl (mp->retval);
1607   if (vam->async_mode)
1608     {
1609       vam->async_errors += (retval < 0);
1610     }
1611   else
1612     {
1613       vam->retval = retval;
1614       vam->result_ready = 1;
1615     }
1616 }
1617
1618 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1619   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1620 {
1621   vat_main_t *vam = &vat_main;
1622   vat_json_node_t node;
1623
1624   vat_json_init_object (&node);
1625   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1626   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1627
1628   vat_json_print (vam->ofp, &node);
1629   vat_json_free (&node);
1630
1631   vam->retval = ntohl (mp->retval);
1632   vam->result_ready = 1;
1633 }
1634
1635 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1636   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1637 {
1638   vat_main_t *vam = &vat_main;
1639   i32 retval = ntohl (mp->retval);
1640   if (vam->async_mode)
1641     {
1642       vam->async_errors += (retval < 0);
1643     }
1644   else
1645     {
1646       vam->retval = retval;
1647       vam->sw_if_index = ntohl (mp->sw_if_index);
1648       vam->result_ready = 1;
1649     }
1650 }
1651
1652 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1653   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1654 {
1655   vat_main_t *vam = &vat_main;
1656   vat_json_node_t node;
1657
1658   vat_json_init_object (&node);
1659   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1660   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1661
1662   vat_json_print (vam->ofp, &node);
1663   vat_json_free (&node);
1664
1665   vam->retval = ntohl (mp->retval);
1666   vam->result_ready = 1;
1667 }
1668
1669 static void vl_api_gre_add_del_tunnel_reply_t_handler
1670   (vl_api_gre_add_del_tunnel_reply_t * mp)
1671 {
1672   vat_main_t *vam = &vat_main;
1673   i32 retval = ntohl (mp->retval);
1674   if (vam->async_mode)
1675     {
1676       vam->async_errors += (retval < 0);
1677     }
1678   else
1679     {
1680       vam->retval = retval;
1681       vam->sw_if_index = ntohl (mp->sw_if_index);
1682       vam->result_ready = 1;
1683     }
1684 }
1685
1686 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1687   (vl_api_gre_add_del_tunnel_reply_t * mp)
1688 {
1689   vat_main_t *vam = &vat_main;
1690   vat_json_node_t node;
1691
1692   vat_json_init_object (&node);
1693   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1694   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1695
1696   vat_json_print (vam->ofp, &node);
1697   vat_json_free (&node);
1698
1699   vam->retval = ntohl (mp->retval);
1700   vam->result_ready = 1;
1701 }
1702
1703 static void vl_api_create_vhost_user_if_reply_t_handler
1704   (vl_api_create_vhost_user_if_reply_t * mp)
1705 {
1706   vat_main_t *vam = &vat_main;
1707   i32 retval = ntohl (mp->retval);
1708   if (vam->async_mode)
1709     {
1710       vam->async_errors += (retval < 0);
1711     }
1712   else
1713     {
1714       vam->retval = retval;
1715       vam->sw_if_index = ntohl (mp->sw_if_index);
1716       vam->result_ready = 1;
1717     }
1718 }
1719
1720 static void vl_api_create_vhost_user_if_reply_t_handler_json
1721   (vl_api_create_vhost_user_if_reply_t * mp)
1722 {
1723   vat_main_t *vam = &vat_main;
1724   vat_json_node_t node;
1725
1726   vat_json_init_object (&node);
1727   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1728   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1729
1730   vat_json_print (vam->ofp, &node);
1731   vat_json_free (&node);
1732
1733   vam->retval = ntohl (mp->retval);
1734   vam->result_ready = 1;
1735 }
1736
1737 static void vl_api_ip_address_details_t_handler
1738   (vl_api_ip_address_details_t * mp)
1739 {
1740   vat_main_t *vam = &vat_main;
1741   static ip_address_details_t empty_ip_address_details = { {0} };
1742   ip_address_details_t *address = NULL;
1743   ip_details_t *current_ip_details = NULL;
1744   ip_details_t *details = NULL;
1745
1746   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1747
1748   if (!details || vam->current_sw_if_index >= vec_len (details)
1749       || !details[vam->current_sw_if_index].present)
1750     {
1751       errmsg ("ip address details arrived but not stored\n");
1752       errmsg ("ip_dump should be called first\n");
1753       return;
1754     }
1755
1756   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1757
1758 #define addresses (current_ip_details->addr)
1759
1760   vec_validate_init_empty (addresses, vec_len (addresses),
1761                            empty_ip_address_details);
1762
1763   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1764
1765   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1766   address->prefix_length = mp->prefix_length;
1767 #undef addresses
1768 }
1769
1770 static void vl_api_ip_address_details_t_handler_json
1771   (vl_api_ip_address_details_t * mp)
1772 {
1773   vat_main_t *vam = &vat_main;
1774   vat_json_node_t *node = NULL;
1775   struct in6_addr ip6;
1776   struct in_addr ip4;
1777
1778   if (VAT_JSON_ARRAY != vam->json_tree.type)
1779     {
1780       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1781       vat_json_init_array (&vam->json_tree);
1782     }
1783   node = vat_json_array_add (&vam->json_tree);
1784
1785   vat_json_init_object (node);
1786   if (vam->is_ipv6)
1787     {
1788       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1789       vat_json_object_add_ip6 (node, "ip", ip6);
1790     }
1791   else
1792     {
1793       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1794       vat_json_object_add_ip4 (node, "ip", ip4);
1795     }
1796   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1797 }
1798
1799 static void
1800 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1801 {
1802   vat_main_t *vam = &vat_main;
1803   static ip_details_t empty_ip_details = { 0 };
1804   ip_details_t *ip = NULL;
1805   u32 sw_if_index = ~0;
1806
1807   sw_if_index = ntohl (mp->sw_if_index);
1808
1809   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1810                            sw_if_index, empty_ip_details);
1811
1812   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1813                          sw_if_index);
1814
1815   ip->present = 1;
1816 }
1817
1818 static void
1819 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1820 {
1821   vat_main_t *vam = &vat_main;
1822
1823   if (VAT_JSON_ARRAY != vam->json_tree.type)
1824     {
1825       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1826       vat_json_init_array (&vam->json_tree);
1827     }
1828   vat_json_array_add_uint (&vam->json_tree,
1829                            clib_net_to_host_u32 (mp->sw_if_index));
1830 }
1831
1832 static void vl_api_map_domain_details_t_handler_json
1833   (vl_api_map_domain_details_t * mp)
1834 {
1835   vat_json_node_t *node = NULL;
1836   vat_main_t *vam = &vat_main;
1837   struct in6_addr ip6;
1838   struct in_addr ip4;
1839
1840   if (VAT_JSON_ARRAY != vam->json_tree.type)
1841     {
1842       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1843       vat_json_init_array (&vam->json_tree);
1844     }
1845
1846   node = vat_json_array_add (&vam->json_tree);
1847   vat_json_init_object (node);
1848
1849   vat_json_object_add_uint (node, "domain_index",
1850                             clib_net_to_host_u32 (mp->domain_index));
1851   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1852   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1853   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1854   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1855   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1856   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1857   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1858   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1859   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1860   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1861   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1862   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1863   vat_json_object_add_uint (node, "flags", mp->flags);
1864   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1865   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1866 }
1867
1868 static void vl_api_map_domain_details_t_handler
1869   (vl_api_map_domain_details_t * mp)
1870 {
1871   vat_main_t *vam = &vat_main;
1872
1873   if (mp->is_translation)
1874     {
1875       fformat (vam->ofp,
1876                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1877                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1878                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1879                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1880                clib_net_to_host_u32 (mp->domain_index));
1881     }
1882   else
1883     {
1884       fformat (vam->ofp,
1885                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1886                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1887                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1888                format_ip6_address, mp->ip6_src,
1889                clib_net_to_host_u32 (mp->domain_index));
1890     }
1891   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1892            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1893            mp->is_translation ? "map-t" : "");
1894 }
1895
1896 static void vl_api_map_rule_details_t_handler_json
1897   (vl_api_map_rule_details_t * mp)
1898 {
1899   struct in6_addr ip6;
1900   vat_json_node_t *node = NULL;
1901   vat_main_t *vam = &vat_main;
1902
1903   if (VAT_JSON_ARRAY != vam->json_tree.type)
1904     {
1905       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1906       vat_json_init_array (&vam->json_tree);
1907     }
1908
1909   node = vat_json_array_add (&vam->json_tree);
1910   vat_json_init_object (node);
1911
1912   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1913   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1914   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1915 }
1916
1917 static void
1918 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1919 {
1920   vat_main_t *vam = &vat_main;
1921   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1922            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1923 }
1924
1925 static void
1926 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1927 {
1928   vat_main_t *vam = &vat_main;
1929   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1930           "router_addr %U host_mac %U\n",
1931           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1932           format_ip4_address, &mp->host_address,
1933           format_ip4_address, &mp->router_address,
1934           format_ethernet_address, mp->host_mac);
1935 }
1936
1937 static void vl_api_dhcp_compl_event_t_handler_json
1938   (vl_api_dhcp_compl_event_t * mp)
1939 {
1940   /* JSON output not supported */
1941 }
1942
1943 static void
1944 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1945                               u32 counter)
1946 {
1947   vat_main_t *vam = &vat_main;
1948   static u64 default_counter = 0;
1949
1950   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1951                            NULL);
1952   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1953                            sw_if_index, default_counter);
1954   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1955 }
1956
1957 static void
1958 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1959                                 interface_counter_t counter)
1960 {
1961   vat_main_t *vam = &vat_main;
1962   static interface_counter_t default_counter = { 0, };
1963
1964   vec_validate_init_empty (vam->combined_interface_counters,
1965                            vnet_counter_type, NULL);
1966   vec_validate_init_empty (vam->combined_interface_counters
1967                            [vnet_counter_type], sw_if_index, default_counter);
1968   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1969 }
1970
1971 static void vl_api_vnet_interface_counters_t_handler
1972   (vl_api_vnet_interface_counters_t * mp)
1973 {
1974   /* not supported */
1975 }
1976
1977 static void vl_api_vnet_interface_counters_t_handler_json
1978   (vl_api_vnet_interface_counters_t * mp)
1979 {
1980   interface_counter_t counter;
1981   vlib_counter_t *v;
1982   u64 *v_packets;
1983   u64 packets;
1984   u32 count;
1985   u32 first_sw_if_index;
1986   int i;
1987
1988   count = ntohl (mp->count);
1989   first_sw_if_index = ntohl (mp->first_sw_if_index);
1990
1991   if (!mp->is_combined)
1992     {
1993       v_packets = (u64 *) & mp->data;
1994       for (i = 0; i < count; i++)
1995         {
1996           packets =
1997             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1998           set_simple_interface_counter (mp->vnet_counter_type,
1999                                         first_sw_if_index + i, packets);
2000           v_packets++;
2001         }
2002     }
2003   else
2004     {
2005       v = (vlib_counter_t *) & mp->data;
2006       for (i = 0; i < count; i++)
2007         {
2008           counter.packets =
2009             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
2010           counter.bytes =
2011             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
2012           set_combined_interface_counter (mp->vnet_counter_type,
2013                                           first_sw_if_index + i, counter);
2014           v++;
2015         }
2016     }
2017 }
2018
2019 static u32
2020 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2021 {
2022   vat_main_t *vam = &vat_main;
2023   u32 i;
2024
2025   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
2026     {
2027       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
2028         {
2029           return i;
2030         }
2031     }
2032   return ~0;
2033 }
2034
2035 static u32
2036 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
2037 {
2038   vat_main_t *vam = &vat_main;
2039   u32 i;
2040
2041   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
2042     {
2043       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2044         {
2045           return i;
2046         }
2047     }
2048   return ~0;
2049 }
2050
2051 static void vl_api_vnet_ip4_fib_counters_t_handler
2052   (vl_api_vnet_ip4_fib_counters_t * mp)
2053 {
2054   /* not supported */
2055 }
2056
2057 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2058   (vl_api_vnet_ip4_fib_counters_t * mp)
2059 {
2060   vat_main_t *vam = &vat_main;
2061   vl_api_ip4_fib_counter_t *v;
2062   ip4_fib_counter_t *counter;
2063   struct in_addr ip4;
2064   u32 vrf_id;
2065   u32 vrf_index;
2066   u32 count;
2067   int i;
2068
2069   vrf_id = ntohl (mp->vrf_id);
2070   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2071   if (~0 == vrf_index)
2072     {
2073       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2074       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2075       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2076       vec_validate (vam->ip4_fib_counters, vrf_index);
2077       vam->ip4_fib_counters[vrf_index] = NULL;
2078     }
2079
2080   vec_free (vam->ip4_fib_counters[vrf_index]);
2081   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2082   count = ntohl (mp->count);
2083   for (i = 0; i < count; i++)
2084     {
2085       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2086       counter = &vam->ip4_fib_counters[vrf_index][i];
2087       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2088       counter->address = ip4;
2089       counter->address_length = v->address_length;
2090       counter->packets = clib_net_to_host_u64 (v->packets);
2091       counter->bytes = clib_net_to_host_u64 (v->bytes);
2092       v++;
2093     }
2094 }
2095
2096 static void vl_api_vnet_ip6_fib_counters_t_handler
2097   (vl_api_vnet_ip6_fib_counters_t * mp)
2098 {
2099   /* not supported */
2100 }
2101
2102 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2103   (vl_api_vnet_ip6_fib_counters_t * mp)
2104 {
2105   vat_main_t *vam = &vat_main;
2106   vl_api_ip6_fib_counter_t *v;
2107   ip6_fib_counter_t *counter;
2108   struct in6_addr ip6;
2109   u32 vrf_id;
2110   u32 vrf_index;
2111   u32 count;
2112   int i;
2113
2114   vrf_id = ntohl (mp->vrf_id);
2115   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2116   if (~0 == vrf_index)
2117     {
2118       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2119       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2120       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2121       vec_validate (vam->ip6_fib_counters, vrf_index);
2122       vam->ip6_fib_counters[vrf_index] = NULL;
2123     }
2124
2125   vec_free (vam->ip6_fib_counters[vrf_index]);
2126   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2127   count = ntohl (mp->count);
2128   for (i = 0; i < count; i++)
2129     {
2130       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2131       counter = &vam->ip6_fib_counters[vrf_index][i];
2132       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2133       counter->address = ip6;
2134       counter->address_length = v->address_length;
2135       counter->packets = clib_net_to_host_u64 (v->packets);
2136       counter->bytes = clib_net_to_host_u64 (v->bytes);
2137       v++;
2138     }
2139 }
2140
2141 static void vl_api_get_first_msg_id_reply_t_handler
2142   (vl_api_get_first_msg_id_reply_t * mp)
2143 {
2144   vat_main_t *vam = &vat_main;
2145   i32 retval = ntohl (mp->retval);
2146
2147   if (vam->async_mode)
2148     {
2149       vam->async_errors += (retval < 0);
2150     }
2151   else
2152     {
2153       vam->retval = retval;
2154       vam->result_ready = 1;
2155     }
2156   if (retval >= 0)
2157     {
2158       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2159     }
2160 }
2161
2162 static void vl_api_get_first_msg_id_reply_t_handler_json
2163   (vl_api_get_first_msg_id_reply_t * mp)
2164 {
2165   vat_main_t *vam = &vat_main;
2166   vat_json_node_t node;
2167
2168   vat_json_init_object (&node);
2169   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2170   vat_json_object_add_uint (&node, "first_msg_id",
2171                             (uint) ntohs (mp->first_msg_id));
2172
2173   vat_json_print (vam->ofp, &node);
2174   vat_json_free (&node);
2175
2176   vam->retval = ntohl (mp->retval);
2177   vam->result_ready = 1;
2178 }
2179
2180 static void vl_api_get_node_graph_reply_t_handler
2181   (vl_api_get_node_graph_reply_t * mp)
2182 {
2183   vat_main_t *vam = &vat_main;
2184   api_main_t *am = &api_main;
2185   i32 retval = ntohl (mp->retval);
2186   u8 *pvt_copy, *reply;
2187   void *oldheap;
2188   vlib_node_t *node;
2189   int i;
2190
2191   if (vam->async_mode)
2192     {
2193       vam->async_errors += (retval < 0);
2194     }
2195   else
2196     {
2197       vam->retval = retval;
2198       vam->result_ready = 1;
2199     }
2200
2201   /* "Should never happen..." */
2202   if (retval != 0)
2203     return;
2204
2205   reply = (u8 *) (mp->reply_in_shmem);
2206   pvt_copy = vec_dup (reply);
2207
2208   /* Toss the shared-memory original... */
2209   pthread_mutex_lock (&am->vlib_rp->mutex);
2210   oldheap = svm_push_data_heap (am->vlib_rp);
2211
2212   vec_free (reply);
2213
2214   svm_pop_heap (oldheap);
2215   pthread_mutex_unlock (&am->vlib_rp->mutex);
2216
2217   if (vam->graph_nodes)
2218     {
2219       hash_free (vam->graph_node_index_by_name);
2220
2221       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2222         {
2223           node = vam->graph_nodes[i];
2224           vec_free (node->name);
2225           vec_free (node->next_nodes);
2226           vec_free (node);
2227         }
2228       vec_free (vam->graph_nodes);
2229     }
2230
2231   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2232   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2233   vec_free (pvt_copy);
2234
2235   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2236     {
2237       node = vam->graph_nodes[i];
2238       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2239     }
2240 }
2241
2242 static void vl_api_get_node_graph_reply_t_handler_json
2243   (vl_api_get_node_graph_reply_t * mp)
2244 {
2245   vat_main_t *vam = &vat_main;
2246   api_main_t *am = &api_main;
2247   void *oldheap;
2248   vat_json_node_t node;
2249   u8 *reply;
2250
2251   /* $$$$ make this real? */
2252   vat_json_init_object (&node);
2253   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2254   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2255
2256   reply = (u8 *) (mp->reply_in_shmem);
2257
2258   /* Toss the shared-memory original... */
2259   pthread_mutex_lock (&am->vlib_rp->mutex);
2260   oldheap = svm_push_data_heap (am->vlib_rp);
2261
2262   vec_free (reply);
2263
2264   svm_pop_heap (oldheap);
2265   pthread_mutex_unlock (&am->vlib_rp->mutex);
2266
2267   vat_json_print (vam->ofp, &node);
2268   vat_json_free (&node);
2269
2270   vam->retval = ntohl (mp->retval);
2271   vam->result_ready = 1;
2272 }
2273
2274 static void
2275 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2276 {
2277   vat_main_t *vam = &vat_main;
2278   locator_msg_t loc;
2279   u8 *tmp_str = 0;
2280
2281   memset (&loc, 0, sizeof (loc));
2282   if (vam->noprint_msg)
2283     {
2284       loc.local = mp->local;
2285       loc.priority = mp->priority;
2286       loc.weight = mp->weight;
2287       if (loc.local)
2288         {
2289           loc.sw_if_index = ntohl (mp->sw_if_index);
2290         }
2291       else
2292         {
2293           loc.is_ipv6 = mp->is_ipv6;
2294           clib_memcpy (loc.ip_address, mp->ip_address,
2295                        sizeof (loc.ip_address));
2296         }
2297       vec_add1 (vam->locator_msg, loc);
2298     }
2299   else
2300     {
2301       if (mp->local)
2302         {
2303           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
2304                             ntohl (mp->sw_if_index),
2305                             mp->priority, mp->weight);
2306         }
2307       else
2308         {
2309           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
2310                             mp->is_ipv6 ? format_ip6_address :
2311                             format_ip4_address,
2312                             mp->ip_address, mp->priority, mp->weight);
2313         }
2314
2315       fformat (vam->ofp, "%s", tmp_str);
2316
2317       vec_free (tmp_str);
2318     }
2319 }
2320
2321 static void
2322 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2323                                             mp)
2324 {
2325   vat_main_t *vam = &vat_main;
2326   vat_json_node_t *node = NULL;
2327   locator_msg_t loc;
2328   struct in6_addr ip6;
2329   struct in_addr ip4;
2330
2331   memset (&loc, 0, sizeof (loc));
2332   if (vam->noprint_msg)
2333     {
2334       loc.local = mp->local;
2335       loc.priority = mp->priority;
2336       loc.weight = mp->weight;
2337       if (loc.local)
2338         {
2339           loc.sw_if_index = ntohl (mp->sw_if_index);
2340         }
2341       else
2342         {
2343           loc.is_ipv6 = mp->is_ipv6;
2344           clib_memcpy (loc.ip_address, mp->ip_address,
2345                        sizeof (loc.ip_address));
2346         }
2347       vec_add1 (vam->locator_msg, loc);
2348       return;
2349     }
2350
2351   if (VAT_JSON_ARRAY != vam->json_tree.type)
2352     {
2353       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2354       vat_json_init_array (&vam->json_tree);
2355     }
2356   node = vat_json_array_add (&vam->json_tree);
2357
2358   vat_json_init_object (node);
2359
2360   if (mp->local)
2361     {
2362       vat_json_object_add_uint (node, "locator_index",
2363                                 ntohl (mp->sw_if_index));
2364     }
2365   else
2366     {
2367       if (mp->is_ipv6)
2368         {
2369           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2370           vat_json_object_add_ip6 (node, "locator", ip6);
2371         }
2372       else
2373         {
2374           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2375           vat_json_object_add_ip4 (node, "locator", ip4);
2376         }
2377     }
2378   vat_json_object_add_uint (node, "priority", mp->priority);
2379   vat_json_object_add_uint (node, "weight", mp->weight);
2380 }
2381
2382 static void
2383 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2384                                            mp)
2385 {
2386   vat_main_t *vam = &vat_main;
2387   locator_set_msg_t ls;
2388
2389   ls.locator_set_index = ntohl (mp->locator_set_index);
2390   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2391   vec_add1 (vam->locator_set_msg, ls);
2392 }
2393
2394 static void
2395   vl_api_lisp_locator_set_details_t_handler_json
2396   (vl_api_lisp_locator_set_details_t * mp)
2397 {
2398   vat_main_t *vam = &vat_main;
2399   locator_set_msg_t ls;
2400
2401   ls.locator_set_index = ntohl (mp->locator_set_index);
2402   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2403   vec_add1 (vam->locator_set_msg, ls);
2404 }
2405
2406 static void
2407 add_lisp_eid_table_entry (vat_main_t * vam,
2408                           vl_api_lisp_eid_table_details_t * mp)
2409 {
2410   eid_table_t eid_table;
2411
2412   memset (&eid_table, 0, sizeof (eid_table));
2413   eid_table.is_local = mp->is_local;
2414   eid_table.locator_set_index = clib_net_to_host_u32 (mp->locator_set_index);
2415   eid_table.eid_type = mp->eid_type;
2416   eid_table.vni = clib_net_to_host_u32 (mp->vni);
2417   eid_table.eid_prefix_len = mp->eid_prefix_len;
2418   eid_table.ttl = clib_net_to_host_u32 (mp->ttl);
2419   eid_table.action = mp->action;
2420   eid_table.authoritative = mp->authoritative;
2421   clib_memcpy (eid_table.eid, mp->eid, sizeof (eid_table.eid));
2422   vec_add1 (vam->eid_tables, eid_table);
2423 }
2424
2425 static void
2426 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2427 {
2428   vat_main_t *vam = &vat_main;
2429   add_lisp_eid_table_entry (vam, mp);
2430 }
2431
2432 static void
2433 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2434                                               * mp)
2435 {
2436   vat_main_t *vam = &vat_main;
2437   add_lisp_eid_table_entry (vam, mp);
2438 }
2439
2440 static void
2441   vl_api_lisp_eid_table_map_details_t_handler
2442   (vl_api_lisp_eid_table_map_details_t * mp)
2443 {
2444   vat_main_t *vam = &vat_main;
2445
2446   u8 *line = format (0, "%=10d%=10d",
2447                      clib_net_to_host_u32 (mp->vni),
2448                      clib_net_to_host_u32 (mp->dp_table));
2449   fformat (vam->ofp, "%v\n", line);
2450   vec_free (line);
2451 }
2452
2453 static void
2454   vl_api_lisp_eid_table_map_details_t_handler_json
2455   (vl_api_lisp_eid_table_map_details_t * mp)
2456 {
2457   vat_main_t *vam = &vat_main;
2458   vat_json_node_t *node = NULL;
2459
2460   if (VAT_JSON_ARRAY != vam->json_tree.type)
2461     {
2462       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2463       vat_json_init_array (&vam->json_tree);
2464     }
2465   node = vat_json_array_add (&vam->json_tree);
2466   vat_json_init_object (node);
2467   vat_json_object_add_uint (node, "dp_table",
2468                             clib_net_to_host_u32 (mp->dp_table));
2469   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2470 }
2471
2472 static void
2473   vl_api_lisp_eid_table_vni_details_t_handler
2474   (vl_api_lisp_eid_table_vni_details_t * mp)
2475 {
2476   vat_main_t *vam = &vat_main;
2477
2478   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2479   fformat (vam->ofp, "%v\n", line);
2480   vec_free (line);
2481 }
2482
2483 static void
2484   vl_api_lisp_eid_table_vni_details_t_handler_json
2485   (vl_api_lisp_eid_table_vni_details_t * mp)
2486 {
2487   vat_main_t *vam = &vat_main;
2488   vat_json_node_t *node = NULL;
2489
2490   if (VAT_JSON_ARRAY != vam->json_tree.type)
2491     {
2492       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2493       vat_json_init_array (&vam->json_tree);
2494     }
2495   node = vat_json_array_add (&vam->json_tree);
2496   vat_json_init_object (node);
2497   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2498 }
2499
2500 static u8 *
2501 format_decap_next (u8 * s, va_list * args)
2502 {
2503   u32 next_index = va_arg (*args, u32);
2504
2505   switch (next_index)
2506     {
2507     case LISP_GPE_INPUT_NEXT_DROP:
2508       return format (s, "drop");
2509     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2510       return format (s, "ip4");
2511     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2512       return format (s, "ip6");
2513     default:
2514       return format (s, "unknown %d", next_index);
2515     }
2516   return s;
2517 }
2518
2519 static void
2520 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2521                                           mp)
2522 {
2523   vat_main_t *vam = &vat_main;
2524   u8 *iid_str;
2525   u8 *flag_str = NULL;
2526
2527   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2528
2529 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2530   foreach_lisp_gpe_flag_bit;
2531 #undef _
2532
2533   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2534            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2535            mp->tunnels,
2536            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2537            mp->source_ip,
2538            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2539            mp->destination_ip,
2540            ntohl (mp->encap_fib_id),
2541            ntohl (mp->decap_fib_id),
2542            format_decap_next, ntohl (mp->dcap_next),
2543            mp->ver_res >> 6,
2544            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2545
2546   vec_free (iid_str);
2547 }
2548
2549 static void
2550   vl_api_lisp_gpe_tunnel_details_t_handler_json
2551   (vl_api_lisp_gpe_tunnel_details_t * mp)
2552 {
2553   vat_main_t *vam = &vat_main;
2554   vat_json_node_t *node = NULL;
2555   struct in6_addr ip6;
2556   struct in_addr ip4;
2557   u8 *next_decap_str;
2558
2559   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2560
2561   if (VAT_JSON_ARRAY != vam->json_tree.type)
2562     {
2563       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2564       vat_json_init_array (&vam->json_tree);
2565     }
2566   node = vat_json_array_add (&vam->json_tree);
2567
2568   vat_json_init_object (node);
2569   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2570   if (mp->is_ipv6)
2571     {
2572       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2573       vat_json_object_add_ip6 (node, "source address", ip6);
2574       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2575       vat_json_object_add_ip6 (node, "destination address", ip6);
2576     }
2577   else
2578     {
2579       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2580       vat_json_object_add_ip4 (node, "source address", ip4);
2581       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2582       vat_json_object_add_ip4 (node, "destination address", ip4);
2583     }
2584   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2585   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2586   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2587   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2588   vat_json_object_add_uint (node, "flags", mp->flags);
2589   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2590   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2591   vat_json_object_add_uint (node, "res", mp->res);
2592   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2593
2594   vec_free (next_decap_str);
2595 }
2596
2597 static void
2598 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2599                                             * mp)
2600 {
2601   vat_main_t *vam = &vat_main;
2602
2603   fformat (vam->ofp, "%=20U\n",
2604            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2605            mp->ip_address);
2606 }
2607
2608 static void
2609   vl_api_lisp_map_resolver_details_t_handler_json
2610   (vl_api_lisp_map_resolver_details_t * mp)
2611 {
2612   vat_main_t *vam = &vat_main;
2613   vat_json_node_t *node = NULL;
2614   struct in6_addr ip6;
2615   struct in_addr ip4;
2616
2617   if (VAT_JSON_ARRAY != vam->json_tree.type)
2618     {
2619       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2620       vat_json_init_array (&vam->json_tree);
2621     }
2622   node = vat_json_array_add (&vam->json_tree);
2623
2624   vat_json_init_object (node);
2625   if (mp->is_ipv6)
2626     {
2627       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2628       vat_json_object_add_ip6 (node, "map resolver", ip6);
2629     }
2630   else
2631     {
2632       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2633       vat_json_object_add_ip4 (node, "map resolver", ip4);
2634     }
2635 }
2636
2637 static void
2638   vl_api_show_lisp_status_reply_t_handler
2639   (vl_api_show_lisp_status_reply_t * mp)
2640 {
2641   vat_main_t *vam = &vat_main;
2642   i32 retval = ntohl (mp->retval);
2643
2644   if (0 <= retval)
2645     {
2646       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2647                mp->feature_status ? "enabled" : "disabled",
2648                mp->gpe_status ? "enabled" : "disabled");
2649     }
2650
2651   vam->retval = retval;
2652   vam->result_ready = 1;
2653 }
2654
2655 static void
2656   vl_api_show_lisp_status_reply_t_handler_json
2657   (vl_api_show_lisp_status_reply_t * mp)
2658 {
2659   vat_main_t *vam = &vat_main;
2660   vat_json_node_t node;
2661   u8 *gpe_status = NULL;
2662   u8 *feature_status = NULL;
2663
2664   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2665   feature_status = format (0, "%s",
2666                            mp->feature_status ? "enabled" : "disabled");
2667   vec_add1 (gpe_status, 0);
2668   vec_add1 (feature_status, 0);
2669
2670   vat_json_init_object (&node);
2671   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2672   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2673
2674   vec_free (gpe_status);
2675   vec_free (feature_status);
2676
2677   vat_json_print (vam->ofp, &node);
2678   vat_json_free (&node);
2679
2680   vam->retval = ntohl (mp->retval);
2681   vam->result_ready = 1;
2682 }
2683
2684 static void
2685   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2686   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2687 {
2688   vat_main_t *vam = &vat_main;
2689   i32 retval = ntohl (mp->retval);
2690
2691   if (retval >= 0)
2692     {
2693       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2694     }
2695
2696   vam->retval = retval;
2697   vam->result_ready = 1;
2698 }
2699
2700 static void
2701   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2702   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2703 {
2704   vat_main_t *vam = &vat_main;
2705   vat_json_node_t *node = NULL;
2706
2707   if (VAT_JSON_ARRAY != vam->json_tree.type)
2708     {
2709       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2710       vat_json_init_array (&vam->json_tree);
2711     }
2712   node = vat_json_array_add (&vam->json_tree);
2713
2714   vat_json_init_object (node);
2715   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2716
2717   vat_json_print (vam->ofp, node);
2718   vat_json_free (node);
2719
2720   vam->retval = ntohl (mp->retval);
2721   vam->result_ready = 1;
2722 }
2723
2724 static void
2725 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2726 {
2727   vat_main_t *vam = &vat_main;
2728   i32 retval = ntohl (mp->retval);
2729
2730   if (0 <= retval)
2731     {
2732       fformat (vam->ofp, "%-20s%-16s\n",
2733                mp->status ? "enabled" : "disabled",
2734                mp->status ? (char *) mp->locator_set_name : "");
2735     }
2736
2737   vam->retval = retval;
2738   vam->result_ready = 1;
2739 }
2740
2741 static void
2742 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2743                                             mp)
2744 {
2745   vat_main_t *vam = &vat_main;
2746   vat_json_node_t node;
2747   u8 *status = 0;
2748
2749   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2750   vec_add1 (status, 0);
2751
2752   vat_json_init_object (&node);
2753   vat_json_object_add_string_copy (&node, "status", status);
2754   if (mp->status)
2755     {
2756       vat_json_object_add_string_copy (&node, "locator_set",
2757                                        mp->locator_set_name);
2758     }
2759
2760   vec_free (status);
2761
2762   vat_json_print (vam->ofp, &node);
2763   vat_json_free (&node);
2764
2765   vam->retval = ntohl (mp->retval);
2766   vam->result_ready = 1;
2767 }
2768
2769 static u8 *
2770 format_policer_type (u8 * s, va_list * va)
2771 {
2772   u32 i = va_arg (*va, u32);
2773
2774   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2775     s = format (s, "1r2c");
2776   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2777     s = format (s, "1r3c");
2778   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2779     s = format (s, "2r3c-2698");
2780   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2781     s = format (s, "2r3c-4115");
2782   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2783     s = format (s, "2r3c-mef5cf1");
2784   else
2785     s = format (s, "ILLEGAL");
2786   return s;
2787 }
2788
2789 static u8 *
2790 format_policer_rate_type (u8 * s, va_list * va)
2791 {
2792   u32 i = va_arg (*va, u32);
2793
2794   if (i == SSE2_QOS_RATE_KBPS)
2795     s = format (s, "kbps");
2796   else if (i == SSE2_QOS_RATE_PPS)
2797     s = format (s, "pps");
2798   else
2799     s = format (s, "ILLEGAL");
2800   return s;
2801 }
2802
2803 static u8 *
2804 format_policer_round_type (u8 * s, va_list * va)
2805 {
2806   u32 i = va_arg (*va, u32);
2807
2808   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2809     s = format (s, "closest");
2810   else if (i == SSE2_QOS_ROUND_TO_UP)
2811     s = format (s, "up");
2812   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2813     s = format (s, "down");
2814   else
2815     s = format (s, "ILLEGAL");
2816   return s;
2817 }
2818
2819 static u8 *
2820 format_policer_action_type (u8 * s, va_list * va)
2821 {
2822   u32 i = va_arg (*va, u32);
2823
2824   if (i == SSE2_QOS_ACTION_DROP)
2825     s = format (s, "drop");
2826   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2827     s = format (s, "transmit");
2828   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2829     s = format (s, "mark-and-transmit");
2830   else
2831     s = format (s, "ILLEGAL");
2832   return s;
2833 }
2834
2835 static u8 *
2836 format_dscp (u8 * s, va_list * va)
2837 {
2838   u32 i = va_arg (*va, u32);
2839   char *t = 0;
2840
2841   switch (i)
2842     {
2843 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2844       foreach_vnet_dscp
2845 #undef _
2846     default:
2847       return format (s, "ILLEGAL");
2848     }
2849   s = format (s, "%s", t);
2850   return s;
2851 }
2852
2853 static void
2854 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2855 {
2856   vat_main_t *vam = &vat_main;
2857   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2858
2859   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2860     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2861   else
2862     conform_dscp_str = format (0, "");
2863
2864   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2865     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2866   else
2867     exceed_dscp_str = format (0, "");
2868
2869   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2870     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2871   else
2872     violate_dscp_str = format (0, "");
2873
2874   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2875            "rate type %U, round type %U, %s rate, %s color-aware, "
2876            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2877            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2878            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2879            mp->name,
2880            format_policer_type, mp->type,
2881            ntohl (mp->cir),
2882            ntohl (mp->eir),
2883            clib_net_to_host_u64 (mp->cb),
2884            clib_net_to_host_u64 (mp->eb),
2885            format_policer_rate_type, mp->rate_type,
2886            format_policer_round_type, mp->round_type,
2887            mp->single_rate ? "single" : "dual",
2888            mp->color_aware ? "is" : "not",
2889            ntohl (mp->cir_tokens_per_period),
2890            ntohl (mp->pir_tokens_per_period),
2891            ntohl (mp->scale),
2892            ntohl (mp->current_limit),
2893            ntohl (mp->current_bucket),
2894            ntohl (mp->extended_limit),
2895            ntohl (mp->extended_bucket),
2896            clib_net_to_host_u64 (mp->last_update_time),
2897            format_policer_action_type, mp->conform_action_type,
2898            conform_dscp_str,
2899            format_policer_action_type, mp->exceed_action_type,
2900            exceed_dscp_str,
2901            format_policer_action_type, mp->violate_action_type,
2902            violate_dscp_str);
2903
2904   vec_free (conform_dscp_str);
2905   vec_free (exceed_dscp_str);
2906   vec_free (violate_dscp_str);
2907 }
2908
2909 static void vl_api_policer_details_t_handler_json
2910   (vl_api_policer_details_t * mp)
2911 {
2912   vat_main_t *vam = &vat_main;
2913   vat_json_node_t *node;
2914   u8 *rate_type_str, *round_type_str, *type_str;
2915   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2916
2917   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2918   round_type_str =
2919     format (0, "%U", format_policer_round_type, mp->round_type);
2920   type_str = format (0, "%U", format_policer_type, mp->type);
2921   conform_action_str = format (0, "%U", format_policer_action_type,
2922                                mp->conform_action_type);
2923   exceed_action_str = format (0, "%U", format_policer_action_type,
2924                               mp->exceed_action_type);
2925   violate_action_str = format (0, "%U", format_policer_action_type,
2926                                mp->violate_action_type);
2927
2928   if (VAT_JSON_ARRAY != vam->json_tree.type)
2929     {
2930       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2931       vat_json_init_array (&vam->json_tree);
2932     }
2933   node = vat_json_array_add (&vam->json_tree);
2934
2935   vat_json_init_object (node);
2936   vat_json_object_add_string_copy (node, "name", mp->name);
2937   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2938   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2939   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
2940   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
2941   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2942   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2943   vat_json_object_add_string_copy (node, "type", type_str);
2944   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2945   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2946   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2947   vat_json_object_add_uint (node, "cir_tokens_per_period",
2948                             ntohl (mp->cir_tokens_per_period));
2949   vat_json_object_add_uint (node, "eir_tokens_per_period",
2950                             ntohl (mp->pir_tokens_per_period));
2951   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2952   vat_json_object_add_uint (node, "current_bucket",
2953                             ntohl (mp->current_bucket));
2954   vat_json_object_add_uint (node, "extended_limit",
2955                             ntohl (mp->extended_limit));
2956   vat_json_object_add_uint (node, "extended_bucket",
2957                             ntohl (mp->extended_bucket));
2958   vat_json_object_add_uint (node, "last_update_time",
2959                             ntohl (mp->last_update_time));
2960   vat_json_object_add_string_copy (node, "conform_action",
2961                                    conform_action_str);
2962   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2963     {
2964       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2965       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2966       vec_free (dscp_str);
2967     }
2968   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2969   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2970     {
2971       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2972       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2973       vec_free (dscp_str);
2974     }
2975   vat_json_object_add_string_copy (node, "violate_action",
2976                                    violate_action_str);
2977   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2978     {
2979       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2980       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2981       vec_free (dscp_str);
2982     }
2983
2984   vec_free (rate_type_str);
2985   vec_free (round_type_str);
2986   vec_free (type_str);
2987   vec_free (conform_action_str);
2988   vec_free (exceed_action_str);
2989   vec_free (violate_action_str);
2990 }
2991
2992 static void
2993 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2994                                            mp)
2995 {
2996   vat_main_t *vam = &vat_main;
2997   int i, count = ntohl (mp->count);
2998
2999   if (count > 0)
3000     fformat (vam->ofp, "classify table ids (%d) : ", count);
3001   for (i = 0; i < count; i++)
3002     {
3003       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3004       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3005     }
3006   vam->retval = ntohl (mp->retval);
3007   vam->result_ready = 1;
3008 }
3009
3010 static void
3011   vl_api_classify_table_ids_reply_t_handler_json
3012   (vl_api_classify_table_ids_reply_t * mp)
3013 {
3014   vat_main_t *vam = &vat_main;
3015   int i, count = ntohl (mp->count);
3016
3017   if (count > 0)
3018     {
3019       vat_json_node_t node;
3020
3021       vat_json_init_object (&node);
3022       for (i = 0; i < count; i++)
3023         {
3024           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3025         }
3026       vat_json_print (vam->ofp, &node);
3027       vat_json_free (&node);
3028     }
3029   vam->retval = ntohl (mp->retval);
3030   vam->result_ready = 1;
3031 }
3032
3033 static void
3034   vl_api_classify_table_by_interface_reply_t_handler
3035   (vl_api_classify_table_by_interface_reply_t * mp)
3036 {
3037   vat_main_t *vam = &vat_main;
3038   u32 table_id;
3039
3040   table_id = ntohl (mp->l2_table_id);
3041   if (table_id != ~0)
3042     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3043   else
3044     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3045   table_id = ntohl (mp->ip4_table_id);
3046   if (table_id != ~0)
3047     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3048   else
3049     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3050   table_id = ntohl (mp->ip6_table_id);
3051   if (table_id != ~0)
3052     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3053   else
3054     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3055   vam->retval = ntohl (mp->retval);
3056   vam->result_ready = 1;
3057 }
3058
3059 static void
3060   vl_api_classify_table_by_interface_reply_t_handler_json
3061   (vl_api_classify_table_by_interface_reply_t * mp)
3062 {
3063   vat_main_t *vam = &vat_main;
3064   vat_json_node_t node;
3065
3066   vat_json_init_object (&node);
3067
3068   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3069   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3070   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3071
3072   vat_json_print (vam->ofp, &node);
3073   vat_json_free (&node);
3074
3075   vam->retval = ntohl (mp->retval);
3076   vam->result_ready = 1;
3077 }
3078
3079 static void vl_api_policer_add_del_reply_t_handler
3080   (vl_api_policer_add_del_reply_t * mp)
3081 {
3082   vat_main_t *vam = &vat_main;
3083   i32 retval = ntohl (mp->retval);
3084   if (vam->async_mode)
3085     {
3086       vam->async_errors += (retval < 0);
3087     }
3088   else
3089     {
3090       vam->retval = retval;
3091       vam->result_ready = 1;
3092       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3093         /*
3094          * Note: this is just barely thread-safe, depends on
3095          * the main thread spinning waiting for an answer...
3096          */
3097         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3098     }
3099 }
3100
3101 static void vl_api_policer_add_del_reply_t_handler_json
3102   (vl_api_policer_add_del_reply_t * mp)
3103 {
3104   vat_main_t *vam = &vat_main;
3105   vat_json_node_t node;
3106
3107   vat_json_init_object (&node);
3108   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3109   vat_json_object_add_uint (&node, "policer_index",
3110                             ntohl (mp->policer_index));
3111
3112   vat_json_print (vam->ofp, &node);
3113   vat_json_free (&node);
3114
3115   vam->retval = ntohl (mp->retval);
3116   vam->result_ready = 1;
3117 }
3118
3119 /* Format hex dump. */
3120 u8 *
3121 format_hex_bytes (u8 * s, va_list * va)
3122 {
3123   u8 *bytes = va_arg (*va, u8 *);
3124   int n_bytes = va_arg (*va, int);
3125   uword i;
3126
3127   /* Print short or long form depending on byte count. */
3128   uword short_form = n_bytes <= 32;
3129   uword indent = format_get_indent (s);
3130
3131   if (n_bytes == 0)
3132     return s;
3133
3134   for (i = 0; i < n_bytes; i++)
3135     {
3136       if (!short_form && (i % 32) == 0)
3137         s = format (s, "%08x: ", i);
3138       s = format (s, "%02x", bytes[i]);
3139       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3140         s = format (s, "\n%U", format_white_space, indent);
3141     }
3142
3143   return s;
3144 }
3145
3146 static void
3147 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3148                                             * mp)
3149 {
3150   vat_main_t *vam = &vat_main;
3151   i32 retval = ntohl (mp->retval);
3152   if (retval == 0)
3153     {
3154       fformat (vam->ofp, "classify table info :\n");
3155       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3156                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3157                ntohl (mp->miss_next_index));
3158       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3159                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3160                ntohl (mp->match_n_vectors));
3161       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3162                ntohl (mp->mask_length));
3163     }
3164   vam->retval = retval;
3165   vam->result_ready = 1;
3166 }
3167
3168 static void
3169   vl_api_classify_table_info_reply_t_handler_json
3170   (vl_api_classify_table_info_reply_t * mp)
3171 {
3172   vat_main_t *vam = &vat_main;
3173   vat_json_node_t node;
3174
3175   i32 retval = ntohl (mp->retval);
3176   if (retval == 0)
3177     {
3178       vat_json_init_object (&node);
3179
3180       vat_json_object_add_int (&node, "sessions",
3181                                ntohl (mp->active_sessions));
3182       vat_json_object_add_int (&node, "nexttbl",
3183                                ntohl (mp->next_table_index));
3184       vat_json_object_add_int (&node, "nextnode",
3185                                ntohl (mp->miss_next_index));
3186       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3187       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3188       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3189       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3190                       ntohl (mp->mask_length), 0);
3191       vat_json_object_add_string_copy (&node, "mask", s);
3192
3193       vat_json_print (vam->ofp, &node);
3194       vat_json_free (&node);
3195     }
3196   vam->retval = ntohl (mp->retval);
3197   vam->result_ready = 1;
3198 }
3199
3200 static void
3201 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3202                                            mp)
3203 {
3204   vat_main_t *vam = &vat_main;
3205
3206   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3207            ntohl (mp->hit_next_index), ntohl (mp->advance),
3208            ntohl (mp->opaque_index));
3209   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3210            ntohl (mp->match_length));
3211 }
3212
3213 static void
3214   vl_api_classify_session_details_t_handler_json
3215   (vl_api_classify_session_details_t * mp)
3216 {
3217   vat_main_t *vam = &vat_main;
3218   vat_json_node_t *node = NULL;
3219
3220   if (VAT_JSON_ARRAY != vam->json_tree.type)
3221     {
3222       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3223       vat_json_init_array (&vam->json_tree);
3224     }
3225   node = vat_json_array_add (&vam->json_tree);
3226
3227   vat_json_init_object (node);
3228   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3229   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3230   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3231   u8 *s =
3232     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3233             0);
3234   vat_json_object_add_string_copy (node, "match", s);
3235 }
3236
3237 static void vl_api_pg_create_interface_reply_t_handler
3238   (vl_api_pg_create_interface_reply_t * mp)
3239 {
3240   vat_main_t *vam = &vat_main;
3241
3242   vam->retval = ntohl (mp->retval);
3243   vam->result_ready = 1;
3244 }
3245
3246 static void vl_api_pg_create_interface_reply_t_handler_json
3247   (vl_api_pg_create_interface_reply_t * mp)
3248 {
3249   vat_main_t *vam = &vat_main;
3250   vat_json_node_t node;
3251
3252   i32 retval = ntohl (mp->retval);
3253   if (retval == 0)
3254     {
3255       vat_json_init_object (&node);
3256
3257       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3258
3259       vat_json_print (vam->ofp, &node);
3260       vat_json_free (&node);
3261     }
3262   vam->retval = ntohl (mp->retval);
3263   vam->result_ready = 1;
3264 }
3265
3266 static void vl_api_policer_classify_details_t_handler
3267   (vl_api_policer_classify_details_t * mp)
3268 {
3269   vat_main_t *vam = &vat_main;
3270
3271   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3272            ntohl (mp->table_index));
3273 }
3274
3275 static void vl_api_policer_classify_details_t_handler_json
3276   (vl_api_policer_classify_details_t * mp)
3277 {
3278   vat_main_t *vam = &vat_main;
3279   vat_json_node_t *node;
3280
3281   if (VAT_JSON_ARRAY != vam->json_tree.type)
3282     {
3283       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3284       vat_json_init_array (&vam->json_tree);
3285     }
3286   node = vat_json_array_add (&vam->json_tree);
3287
3288   vat_json_init_object (node);
3289   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3290   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3291 }
3292
3293 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3294   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3295 {
3296   vat_main_t *vam = &vat_main;
3297   i32 retval = ntohl (mp->retval);
3298   if (vam->async_mode)
3299     {
3300       vam->async_errors += (retval < 0);
3301     }
3302   else
3303     {
3304       vam->retval = retval;
3305       vam->sw_if_index = ntohl (mp->sw_if_index);
3306       vam->result_ready = 1;
3307     }
3308 }
3309
3310 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3311   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3312 {
3313   vat_main_t *vam = &vat_main;
3314   vat_json_node_t node;
3315
3316   vat_json_init_object (&node);
3317   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3318   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3319
3320   vat_json_print (vam->ofp, &node);
3321   vat_json_free (&node);
3322
3323   vam->retval = ntohl (mp->retval);
3324   vam->result_ready = 1;
3325 }
3326
3327 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3328 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3329 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3330 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3331
3332 /*
3333  * Generate boilerplate reply handlers, which
3334  * dig the return value out of the xxx_reply_t API message,
3335  * stick it into vam->retval, and set vam->result_ready
3336  *
3337  * Could also do this by pointing N message decode slots at
3338  * a single function, but that could break in subtle ways.
3339  */
3340
3341 #define foreach_standard_reply_retval_handler           \
3342 _(sw_interface_set_flags_reply)                         \
3343 _(sw_interface_add_del_address_reply)                   \
3344 _(sw_interface_set_table_reply)                         \
3345 _(sw_interface_set_vpath_reply)                         \
3346 _(sw_interface_set_l2_bridge_reply)                     \
3347 _(bridge_domain_add_del_reply)                          \
3348 _(sw_interface_set_l2_xconnect_reply)                   \
3349 _(l2fib_add_del_reply)                                  \
3350 _(ip_add_del_route_reply)                               \
3351 _(proxy_arp_add_del_reply)                              \
3352 _(proxy_arp_intfc_enable_disable_reply)                 \
3353 _(mpls_add_del_encap_reply)                             \
3354 _(mpls_add_del_decap_reply)                             \
3355 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3356 _(sw_interface_set_unnumbered_reply)                    \
3357 _(ip_neighbor_add_del_reply)                            \
3358 _(reset_vrf_reply)                                      \
3359 _(oam_add_del_reply)                                    \
3360 _(reset_fib_reply)                                      \
3361 _(dhcp_proxy_config_reply)                              \
3362 _(dhcp_proxy_config_2_reply)                            \
3363 _(dhcp_proxy_set_vss_reply)                             \
3364 _(dhcp_client_config_reply)                             \
3365 _(set_ip_flow_hash_reply)                               \
3366 _(sw_interface_ip6_enable_disable_reply)                \
3367 _(sw_interface_ip6_set_link_local_address_reply)        \
3368 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3369 _(sw_interface_ip6nd_ra_config_reply)                   \
3370 _(set_arp_neighbor_limit_reply)                         \
3371 _(l2_patch_add_del_reply)                               \
3372 _(sr_tunnel_add_del_reply)                              \
3373 _(sr_policy_add_del_reply)                              \
3374 _(sr_multicast_map_add_del_reply)                       \
3375 _(classify_add_del_session_reply)                       \
3376 _(classify_set_interface_ip_table_reply)                \
3377 _(classify_set_interface_l2_tables_reply)               \
3378 _(l2tpv3_set_tunnel_cookies_reply)                      \
3379 _(l2tpv3_interface_enable_disable_reply)                \
3380 _(l2tpv3_set_lookup_key_reply)                          \
3381 _(l2_fib_clear_table_reply)                             \
3382 _(l2_interface_efp_filter_reply)                        \
3383 _(l2_interface_vlan_tag_rewrite_reply)                  \
3384 _(modify_vhost_user_if_reply)                           \
3385 _(delete_vhost_user_if_reply)                           \
3386 _(want_ip4_arp_events_reply)                            \
3387 _(want_ip6_nd_events_reply)                             \
3388 _(input_acl_set_interface_reply)                        \
3389 _(ipsec_spd_add_del_reply)                              \
3390 _(ipsec_interface_add_del_spd_reply)                    \
3391 _(ipsec_spd_add_del_entry_reply)                        \
3392 _(ipsec_sad_add_del_entry_reply)                        \
3393 _(ipsec_sa_set_key_reply)                               \
3394 _(ikev2_profile_add_del_reply)                          \
3395 _(ikev2_profile_set_auth_reply)                         \
3396 _(ikev2_profile_set_id_reply)                           \
3397 _(ikev2_profile_set_ts_reply)                           \
3398 _(ikev2_set_local_key_reply)                            \
3399 _(delete_loopback_reply)                                \
3400 _(bd_ip_mac_add_del_reply)                              \
3401 _(map_del_domain_reply)                                 \
3402 _(map_add_del_rule_reply)                               \
3403 _(want_interface_events_reply)                          \
3404 _(want_stats_reply)                                     \
3405 _(cop_interface_enable_disable_reply)                   \
3406 _(cop_whitelist_enable_disable_reply)                   \
3407 _(sw_interface_clear_stats_reply)                       \
3408 _(trace_profile_add_reply)                              \
3409 _(trace_profile_apply_reply)                            \
3410 _(trace_profile_del_reply)                              \
3411 _(lisp_add_del_locator_reply)                           \
3412 _(lisp_add_del_local_eid_reply)                         \
3413 _(lisp_add_del_remote_mapping_reply)                    \
3414 _(lisp_add_del_adjacency_reply)                         \
3415 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3416 _(lisp_add_del_map_resolver_reply)                      \
3417 _(lisp_gpe_enable_disable_reply)                        \
3418 _(lisp_gpe_add_del_iface_reply)                         \
3419 _(lisp_enable_disable_reply)                            \
3420 _(lisp_pitr_set_locator_set_reply)                      \
3421 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3422 _(lisp_eid_table_add_del_map_reply)                     \
3423 _(vxlan_gpe_add_del_tunnel_reply)                       \
3424 _(af_packet_delete_reply)                               \
3425 _(policer_classify_set_interface_reply)                 \
3426 _(netmap_create_reply)                                  \
3427 _(netmap_delete_reply)                                  \
3428 _(ipfix_enable_reply)                                   \
3429 _(pg_capture_reply)                                     \
3430 _(pg_enable_disable_reply)                              \
3431 _(ip_source_and_port_range_check_add_del_reply)         \
3432 _(ip_source_and_port_range_check_interface_add_del_reply)\
3433 _(delete_subif_reply)
3434
3435 #define _(n)                                    \
3436     static void vl_api_##n##_t_handler          \
3437     (vl_api_##n##_t * mp)                       \
3438     {                                           \
3439         vat_main_t * vam = &vat_main;           \
3440         i32 retval = ntohl(mp->retval);         \
3441         if (vam->async_mode) {                  \
3442             vam->async_errors += (retval < 0);  \
3443         } else {                                \
3444             vam->retval = retval;               \
3445             vam->result_ready = 1;              \
3446         }                                       \
3447     }
3448 foreach_standard_reply_retval_handler;
3449 #undef _
3450
3451 #define _(n)                                    \
3452     static void vl_api_##n##_t_handler_json     \
3453     (vl_api_##n##_t * mp)                       \
3454     {                                           \
3455         vat_main_t * vam = &vat_main;           \
3456         vat_json_node_t node;                   \
3457         vat_json_init_object(&node);            \
3458         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3459         vat_json_print(vam->ofp, &node);        \
3460         vam->retval = ntohl(mp->retval);        \
3461         vam->result_ready = 1;                  \
3462     }
3463 foreach_standard_reply_retval_handler;
3464 #undef _
3465
3466 /*
3467  * Table of message reply handlers, must include boilerplate handlers
3468  * we just generated
3469  */
3470
3471 #define foreach_vpe_api_reply_msg                                       \
3472 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3473 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3474 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3475 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3476 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3477 _(NOPRINT_CONTROL_PING_REPLY, noprint_control_ping_reply)               \
3478 _(CLI_REPLY, cli_reply)                                                 \
3479 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3480 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3481   sw_interface_add_del_address_reply)                                   \
3482 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3483 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3484 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3485   sw_interface_set_l2_xconnect_reply)                                   \
3486 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3487   sw_interface_set_l2_bridge_reply)                                     \
3488 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3489 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3490 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3491 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3492 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3493 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3494 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3495 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3496 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3497 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3498 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3499 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3500 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3501   proxy_arp_intfc_enable_disable_reply)                                 \
3502 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3503 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3504 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3505 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3506   mpls_ethernet_add_del_tunnel_reply)                                   \
3507 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3508   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3509 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3510   sw_interface_set_unnumbered_reply)                                    \
3511 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3512 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3513 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3514 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3515 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3516 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3517 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3518 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3519 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3520 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3521 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3522 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3523   sw_interface_ip6_enable_disable_reply)                                \
3524 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3525   sw_interface_ip6_set_link_local_address_reply)                        \
3526 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3527   sw_interface_ip6nd_ra_prefix_reply)                                   \
3528 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3529   sw_interface_ip6nd_ra_config_reply)                                   \
3530 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3531 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3532 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3533 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3534 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3535 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3536 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3537 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3538 classify_set_interface_ip_table_reply)                                  \
3539 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3540   classify_set_interface_l2_tables_reply)                               \
3541 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3542 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3543 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3544 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3545 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3546   l2tpv3_interface_enable_disable_reply)                                \
3547 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3548 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3549 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3550 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3551 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3552 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3553 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3554 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3555 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3556 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3557 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3558 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3559 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3560 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3561 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3562 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3563 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3564 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3565 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3566 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3567 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3568 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3569 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3570 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3571 _(IP_DETAILS, ip_details)                                               \
3572 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3573 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3574 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3575 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3576 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3577 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3578 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3579 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3580 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3581 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3582 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3583 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3584 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3585 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3586 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3587 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3588 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3589 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3590 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3591 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3592 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3593 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3594 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3595 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3596 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3597 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3598 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3599 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3600 _(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply)                   \
3601 _(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply)               \
3602 _(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply)                     \
3603 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3604 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3605 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3606 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3607 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3608 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3609 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3610 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3611 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3612 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3613 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3614 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3615 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3616 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3617 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3618 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3619 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3620 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3621 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3622 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3623 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3624   lisp_add_del_map_request_itr_rlocs_reply)                             \
3625 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3626   lisp_get_map_request_itr_rlocs_reply)                                 \
3627 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3628 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3629 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3630 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3631 _(POLICER_DETAILS, policer_details)                                     \
3632 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3633 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3634 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3635 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3636 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3637 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3638 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3639 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3640 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3641 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3642 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3643 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3644 _(IPFIX_ENABLE_REPLY, ipfix_enable_reply)                               \
3645 _(IPFIX_DETAILS, ipfix_details)                                         \
3646 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3647 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3648 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3649 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3650 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3651  ip_source_and_port_range_check_add_del_reply)                          \
3652 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3653  ip_source_and_port_range_check_interface_add_del_reply)                \
3654 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3655 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3656 _(DELETE_SUBIF_REPLY, delete_subif_reply)
3657
3658 /* M: construct, but don't yet send a message */
3659
3660 #define M(T,t)                                  \
3661 do {                                            \
3662     vam->result_ready = 0;                      \
3663     mp = vl_msg_api_alloc(sizeof(*mp));         \
3664     memset (mp, 0, sizeof (*mp));               \
3665     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3666     mp->client_index = vam->my_client_index;    \
3667 } while(0);
3668
3669 #define M2(T,t,n)                               \
3670 do {                                            \
3671     vam->result_ready = 0;                      \
3672     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3673     memset (mp, 0, sizeof (*mp));               \
3674     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3675     mp->client_index = vam->my_client_index;    \
3676 } while(0);
3677
3678
3679 /* S: send a message */
3680 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3681
3682 /* W: wait for results, with timeout */
3683 #define W                                       \
3684 do {                                            \
3685     timeout = vat_time_now (vam) + 1.0;         \
3686                                                 \
3687     while (vat_time_now (vam) < timeout) {      \
3688         if (vam->result_ready == 1) {           \
3689             return (vam->retval);               \
3690         }                                       \
3691     }                                           \
3692     return -99;                                 \
3693 } while(0);
3694
3695 /* W2: wait for results, with timeout */
3696 #define W2(body)                                \
3697 do {                                            \
3698     timeout = vat_time_now (vam) + 1.0;         \
3699                                                 \
3700     while (vat_time_now (vam) < timeout) {      \
3701         if (vam->result_ready == 1) {           \
3702           (body);                               \
3703           return (vam->retval);                 \
3704         }                                       \
3705     }                                           \
3706     return -99;                                 \
3707 } while(0);
3708
3709 /* W_L: wait for results, with timeout */
3710 #define W_L(body)                               \
3711 do {                                            \
3712     timeout = vat_time_now (vam) + 1.0;         \
3713                                                 \
3714     while (vat_time_now (vam) < timeout) {      \
3715         if (vam->result_ready == 1) {           \
3716           (body);                               \
3717           return (vam->retval);                 \
3718         }                                       \
3719     }                                           \
3720     vam->noprint_msg = 0;     \
3721     return -99;                                 \
3722 } while(0);
3723
3724 typedef struct
3725 {
3726   u8 *name;
3727   u32 value;
3728 } name_sort_t;
3729
3730
3731 #define STR_VTR_OP_CASE(op)     \
3732     case L2_VTR_ ## op:         \
3733         return "" # op;
3734
3735 static const char *
3736 str_vtr_op (u32 vtr_op)
3737 {
3738   switch (vtr_op)
3739     {
3740       STR_VTR_OP_CASE (DISABLED);
3741       STR_VTR_OP_CASE (PUSH_1);
3742       STR_VTR_OP_CASE (PUSH_2);
3743       STR_VTR_OP_CASE (POP_1);
3744       STR_VTR_OP_CASE (POP_2);
3745       STR_VTR_OP_CASE (TRANSLATE_1_1);
3746       STR_VTR_OP_CASE (TRANSLATE_1_2);
3747       STR_VTR_OP_CASE (TRANSLATE_2_1);
3748       STR_VTR_OP_CASE (TRANSLATE_2_2);
3749     }
3750
3751   return "UNKNOWN";
3752 }
3753
3754 static int
3755 dump_sub_interface_table (vat_main_t * vam)
3756 {
3757   const sw_interface_subif_t *sub = NULL;
3758
3759   if (vam->json_output)
3760     {
3761       clib_warning
3762         ("JSON output supported only for VPE API calls and dump_stats_table");
3763       return -99;
3764     }
3765
3766   fformat (vam->ofp,
3767            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3768            "Interface", "sw_if_index",
3769            "sub id", "dot1ad", "tags", "outer id",
3770            "inner id", "exact", "default", "outer any", "inner any");
3771
3772   vec_foreach (sub, vam->sw_if_subif_table)
3773   {
3774     fformat (vam->ofp,
3775              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3776              sub->interface_name,
3777              sub->sw_if_index,
3778              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3779              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3780              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3781              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3782     if (sub->vtr_op != L2_VTR_DISABLED)
3783       {
3784         fformat (vam->ofp,
3785                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3786                  "tag1: %d tag2: %d ]\n",
3787                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3788                  sub->vtr_tag1, sub->vtr_tag2);
3789       }
3790   }
3791
3792   return 0;
3793 }
3794
3795 static int
3796 name_sort_cmp (void *a1, void *a2)
3797 {
3798   name_sort_t *n1 = a1;
3799   name_sort_t *n2 = a2;
3800
3801   return strcmp ((char *) n1->name, (char *) n2->name);
3802 }
3803
3804 static int
3805 dump_interface_table (vat_main_t * vam)
3806 {
3807   hash_pair_t *p;
3808   name_sort_t *nses = 0, *ns;
3809
3810   if (vam->json_output)
3811     {
3812       clib_warning
3813         ("JSON output supported only for VPE API calls and dump_stats_table");
3814       return -99;
3815     }
3816
3817   /* *INDENT-OFF* */
3818   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3819   ({
3820     vec_add2 (nses, ns, 1);
3821     ns->name = (u8 *)(p->key);
3822     ns->value = (u32) p->value[0];
3823   }));
3824   /* *INDENT-ON* */
3825
3826   vec_sort_with_function (nses, name_sort_cmp);
3827
3828   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3829   vec_foreach (ns, nses)
3830   {
3831     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3832   }
3833   vec_free (nses);
3834   return 0;
3835 }
3836
3837 static int
3838 dump_ip_table (vat_main_t * vam, int is_ipv6)
3839 {
3840   const ip_details_t *det = NULL;
3841   const ip_address_details_t *address = NULL;
3842   u32 i = ~0;
3843
3844   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3845
3846   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3847   {
3848     i++;
3849     if (!det->present)
3850       {
3851         continue;
3852       }
3853     fformat (vam->ofp, "%-12d\n", i);
3854     fformat (vam->ofp,
3855              "            %-30s%-13s\n", "Address", "Prefix length");
3856     if (!det->addr)
3857       {
3858         continue;
3859       }
3860     vec_foreach (address, det->addr)
3861     {
3862       fformat (vam->ofp,
3863                "            %-30U%-13d\n",
3864                is_ipv6 ? format_ip6_address : format_ip4_address,
3865                address->ip, address->prefix_length);
3866     }
3867   }
3868
3869   return 0;
3870 }
3871
3872 static int
3873 dump_ipv4_table (vat_main_t * vam)
3874 {
3875   if (vam->json_output)
3876     {
3877       clib_warning
3878         ("JSON output supported only for VPE API calls and dump_stats_table");
3879       return -99;
3880     }
3881
3882   return dump_ip_table (vam, 0);
3883 }
3884
3885 static int
3886 dump_ipv6_table (vat_main_t * vam)
3887 {
3888   if (vam->json_output)
3889     {
3890       clib_warning
3891         ("JSON output supported only for VPE API calls and dump_stats_table");
3892       return -99;
3893     }
3894
3895   return dump_ip_table (vam, 1);
3896 }
3897
3898 static char *
3899 counter_type_to_str (u8 counter_type, u8 is_combined)
3900 {
3901   if (!is_combined)
3902     {
3903       switch (counter_type)
3904         {
3905         case VNET_INTERFACE_COUNTER_DROP:
3906           return "drop";
3907         case VNET_INTERFACE_COUNTER_PUNT:
3908           return "punt";
3909         case VNET_INTERFACE_COUNTER_IP4:
3910           return "ip4";
3911         case VNET_INTERFACE_COUNTER_IP6:
3912           return "ip6";
3913         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3914           return "rx-no-buf";
3915         case VNET_INTERFACE_COUNTER_RX_MISS:
3916           return "rx-miss";
3917         case VNET_INTERFACE_COUNTER_RX_ERROR:
3918           return "rx-error";
3919         case VNET_INTERFACE_COUNTER_TX_ERROR:
3920           return "tx-error";
3921         default:
3922           return "INVALID-COUNTER-TYPE";
3923         }
3924     }
3925   else
3926     {
3927       switch (counter_type)
3928         {
3929         case VNET_INTERFACE_COUNTER_RX:
3930           return "rx";
3931         case VNET_INTERFACE_COUNTER_TX:
3932           return "tx";
3933         default:
3934           return "INVALID-COUNTER-TYPE";
3935         }
3936     }
3937 }
3938
3939 static int
3940 dump_stats_table (vat_main_t * vam)
3941 {
3942   vat_json_node_t node;
3943   vat_json_node_t *msg_array;
3944   vat_json_node_t *msg;
3945   vat_json_node_t *counter_array;
3946   vat_json_node_t *counter;
3947   interface_counter_t c;
3948   u64 packets;
3949   ip4_fib_counter_t *c4;
3950   ip6_fib_counter_t *c6;
3951   int i, j;
3952
3953   if (!vam->json_output)
3954     {
3955       clib_warning ("dump_stats_table supported only in JSON format");
3956       return -99;
3957     }
3958
3959   vat_json_init_object (&node);
3960
3961   /* interface counters */
3962   msg_array = vat_json_object_add (&node, "interface_counters");
3963   vat_json_init_array (msg_array);
3964   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
3965     {
3966       msg = vat_json_array_add (msg_array);
3967       vat_json_init_object (msg);
3968       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3969                                        (u8 *) counter_type_to_str (i, 0));
3970       vat_json_object_add_int (msg, "is_combined", 0);
3971       counter_array = vat_json_object_add (msg, "data");
3972       vat_json_init_array (counter_array);
3973       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
3974         {
3975           packets = vam->simple_interface_counters[i][j];
3976           vat_json_array_add_uint (counter_array, packets);
3977         }
3978     }
3979   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
3980     {
3981       msg = vat_json_array_add (msg_array);
3982       vat_json_init_object (msg);
3983       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3984                                        (u8 *) counter_type_to_str (i, 1));
3985       vat_json_object_add_int (msg, "is_combined", 1);
3986       counter_array = vat_json_object_add (msg, "data");
3987       vat_json_init_array (counter_array);
3988       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
3989         {
3990           c = vam->combined_interface_counters[i][j];
3991           counter = vat_json_array_add (counter_array);
3992           vat_json_init_object (counter);
3993           vat_json_object_add_uint (counter, "packets", c.packets);
3994           vat_json_object_add_uint (counter, "bytes", c.bytes);
3995         }
3996     }
3997
3998   /* ip4 fib counters */
3999   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4000   vat_json_init_array (msg_array);
4001   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4002     {
4003       msg = vat_json_array_add (msg_array);
4004       vat_json_init_object (msg);
4005       vat_json_object_add_uint (msg, "vrf_id",
4006                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4007       counter_array = vat_json_object_add (msg, "c");
4008       vat_json_init_array (counter_array);
4009       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4010         {
4011           counter = vat_json_array_add (counter_array);
4012           vat_json_init_object (counter);
4013           c4 = &vam->ip4_fib_counters[i][j];
4014           vat_json_object_add_ip4 (counter, "address", c4->address);
4015           vat_json_object_add_uint (counter, "address_length",
4016                                     c4->address_length);
4017           vat_json_object_add_uint (counter, "packets", c4->packets);
4018           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4019         }
4020     }
4021
4022   /* ip6 fib counters */
4023   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4024   vat_json_init_array (msg_array);
4025   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4026     {
4027       msg = vat_json_array_add (msg_array);
4028       vat_json_init_object (msg);
4029       vat_json_object_add_uint (msg, "vrf_id",
4030                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4031       counter_array = vat_json_object_add (msg, "c");
4032       vat_json_init_array (counter_array);
4033       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4034         {
4035           counter = vat_json_array_add (counter_array);
4036           vat_json_init_object (counter);
4037           c6 = &vam->ip6_fib_counters[i][j];
4038           vat_json_object_add_ip6 (counter, "address", c6->address);
4039           vat_json_object_add_uint (counter, "address_length",
4040                                     c6->address_length);
4041           vat_json_object_add_uint (counter, "packets", c6->packets);
4042           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4043         }
4044     }
4045
4046   vat_json_print (vam->ofp, &node);
4047   vat_json_free (&node);
4048
4049   return 0;
4050 }
4051
4052 int
4053 exec (vat_main_t * vam)
4054 {
4055   api_main_t *am = &api_main;
4056   vl_api_cli_request_t *mp;
4057   f64 timeout;
4058   void *oldheap;
4059   u8 *cmd = 0;
4060   unformat_input_t *i = vam->input;
4061
4062   if (vec_len (i->buffer) == 0)
4063     return -1;
4064
4065   if (vam->exec_mode == 0 && unformat (i, "mode"))
4066     {
4067       vam->exec_mode = 1;
4068       return 0;
4069     }
4070   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4071     {
4072       vam->exec_mode = 0;
4073       return 0;
4074     }
4075
4076
4077   M (CLI_REQUEST, cli_request);
4078
4079   /*
4080    * Copy cmd into shared memory.
4081    * In order for the CLI command to work, it
4082    * must be a vector ending in \n, not a C-string ending
4083    * in \n\0.
4084    */
4085   pthread_mutex_lock (&am->vlib_rp->mutex);
4086   oldheap = svm_push_data_heap (am->vlib_rp);
4087
4088   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4089   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4090
4091   svm_pop_heap (oldheap);
4092   pthread_mutex_unlock (&am->vlib_rp->mutex);
4093
4094   mp->cmd_in_shmem = (u64) cmd;
4095   S;
4096   timeout = vat_time_now (vam) + 10.0;
4097
4098   while (vat_time_now (vam) < timeout)
4099     {
4100       if (vam->result_ready == 1)
4101         {
4102           u8 *free_me;
4103           if (vam->shmem_result != NULL)
4104             fformat (vam->ofp, "%s", vam->shmem_result);
4105           pthread_mutex_lock (&am->vlib_rp->mutex);
4106           oldheap = svm_push_data_heap (am->vlib_rp);
4107
4108           free_me = (u8 *) vam->shmem_result;
4109           vec_free (free_me);
4110
4111           svm_pop_heap (oldheap);
4112           pthread_mutex_unlock (&am->vlib_rp->mutex);
4113           return 0;
4114         }
4115     }
4116   return -99;
4117 }
4118
4119 /*
4120  * Future replacement of exec() that passes CLI buffers directly in
4121  * the API messages instead of an additional shared memory area.
4122  */
4123 static int
4124 exec_inband (vat_main_t * vam)
4125 {
4126   vl_api_cli_inband_t *mp;
4127   f64 timeout;
4128   unformat_input_t *i = vam->input;
4129
4130   if (vec_len (i->buffer) == 0)
4131     return -1;
4132
4133   if (vam->exec_mode == 0 && unformat (i, "mode"))
4134     {
4135       vam->exec_mode = 1;
4136       return 0;
4137     }
4138   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4139     {
4140       vam->exec_mode = 0;
4141       return 0;
4142     }
4143
4144   /*
4145    * In order for the CLI command to work, it
4146    * must be a vector ending in \n, not a C-string ending
4147    * in \n\0.
4148    */
4149   u32 len = vec_len (vam->input->buffer);
4150   M2 (CLI_INBAND, cli_inband, len);
4151   clib_memcpy (mp->cmd, vam->input->buffer, len);
4152   mp->length = htonl (len);
4153
4154   S;
4155   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4156 }
4157
4158 static int
4159 api_create_loopback (vat_main_t * vam)
4160 {
4161   unformat_input_t *i = vam->input;
4162   vl_api_create_loopback_t *mp;
4163   f64 timeout;
4164   u8 mac_address[6];
4165   u8 mac_set = 0;
4166
4167   memset (mac_address, 0, sizeof (mac_address));
4168
4169   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4170     {
4171       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4172         mac_set = 1;
4173       else
4174         break;
4175     }
4176
4177   /* Construct the API message */
4178   M (CREATE_LOOPBACK, create_loopback);
4179   if (mac_set)
4180     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4181
4182   S;
4183   W;
4184 }
4185
4186 static int
4187 api_delete_loopback (vat_main_t * vam)
4188 {
4189   unformat_input_t *i = vam->input;
4190   vl_api_delete_loopback_t *mp;
4191   f64 timeout;
4192   u32 sw_if_index = ~0;
4193
4194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4195     {
4196       if (unformat (i, "sw_if_index %d", &sw_if_index))
4197         ;
4198       else
4199         break;
4200     }
4201
4202   if (sw_if_index == ~0)
4203     {
4204       errmsg ("missing sw_if_index\n");
4205       return -99;
4206     }
4207
4208   /* Construct the API message */
4209   M (DELETE_LOOPBACK, delete_loopback);
4210   mp->sw_if_index = ntohl (sw_if_index);
4211
4212   S;
4213   W;
4214 }
4215
4216 static int
4217 api_want_stats (vat_main_t * vam)
4218 {
4219   unformat_input_t *i = vam->input;
4220   vl_api_want_stats_t *mp;
4221   f64 timeout;
4222   int enable = -1;
4223
4224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4225     {
4226       if (unformat (i, "enable"))
4227         enable = 1;
4228       else if (unformat (i, "disable"))
4229         enable = 0;
4230       else
4231         break;
4232     }
4233
4234   if (enable == -1)
4235     {
4236       errmsg ("missing enable|disable\n");
4237       return -99;
4238     }
4239
4240   M (WANT_STATS, want_stats);
4241   mp->enable_disable = enable;
4242
4243   S;
4244   W;
4245 }
4246
4247 static int
4248 api_want_interface_events (vat_main_t * vam)
4249 {
4250   unformat_input_t *i = vam->input;
4251   vl_api_want_interface_events_t *mp;
4252   f64 timeout;
4253   int enable = -1;
4254
4255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4256     {
4257       if (unformat (i, "enable"))
4258         enable = 1;
4259       else if (unformat (i, "disable"))
4260         enable = 0;
4261       else
4262         break;
4263     }
4264
4265   if (enable == -1)
4266     {
4267       errmsg ("missing enable|disable\n");
4268       return -99;
4269     }
4270
4271   M (WANT_INTERFACE_EVENTS, want_interface_events);
4272   mp->enable_disable = enable;
4273
4274   vam->interface_event_display = enable;
4275
4276   S;
4277   W;
4278 }
4279
4280
4281 /* Note: non-static, called once to set up the initial intfc table */
4282 int
4283 api_sw_interface_dump (vat_main_t * vam)
4284 {
4285   vl_api_sw_interface_dump_t *mp;
4286   f64 timeout;
4287   hash_pair_t *p;
4288   name_sort_t *nses = 0, *ns;
4289   sw_interface_subif_t *sub = NULL;
4290
4291   /* Toss the old name table */
4292   /* *INDENT-OFF* */
4293   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4294   ({
4295     vec_add2 (nses, ns, 1);
4296     ns->name = (u8 *)(p->key);
4297     ns->value = (u32) p->value[0];
4298   }));
4299   /* *INDENT-ON* */
4300
4301   hash_free (vam->sw_if_index_by_interface_name);
4302
4303   vec_foreach (ns, nses) vec_free (ns->name);
4304
4305   vec_free (nses);
4306
4307   vec_foreach (sub, vam->sw_if_subif_table)
4308   {
4309     vec_free (sub->interface_name);
4310   }
4311   vec_free (vam->sw_if_subif_table);
4312
4313   /* recreate the interface name hash table */
4314   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4315
4316   /* Get list of ethernets */
4317   M (SW_INTERFACE_DUMP, sw_interface_dump);
4318   mp->name_filter_valid = 1;
4319   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4320   S;
4321
4322   /* and local / loopback interfaces */
4323   M (SW_INTERFACE_DUMP, sw_interface_dump);
4324   mp->name_filter_valid = 1;
4325   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4326   S;
4327
4328
4329   /* and vxlan-gpe tunnel interfaces */
4330   M (SW_INTERFACE_DUMP, sw_interface_dump);
4331   mp->name_filter_valid = 1;
4332   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4333            sizeof (mp->name_filter) - 1);
4334   S;
4335
4336   /* and vxlan tunnel interfaces */
4337   M (SW_INTERFACE_DUMP, sw_interface_dump);
4338   mp->name_filter_valid = 1;
4339   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4340   S;
4341
4342   /* and host (af_packet) interfaces */
4343   M (SW_INTERFACE_DUMP, sw_interface_dump);
4344   mp->name_filter_valid = 1;
4345   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4346   S;
4347
4348   /* and l2tpv3 tunnel interfaces */
4349   M (SW_INTERFACE_DUMP, sw_interface_dump);
4350   mp->name_filter_valid = 1;
4351   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4352            sizeof (mp->name_filter) - 1);
4353   S;
4354
4355   /* and GRE tunnel interfaces */
4356   M (SW_INTERFACE_DUMP, sw_interface_dump);
4357   mp->name_filter_valid = 1;
4358   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4359   S;
4360
4361   /* Use a control ping for synchronization */
4362   {
4363     vl_api_control_ping_t *mp;
4364     M (CONTROL_PING, control_ping);
4365     S;
4366   }
4367   W;
4368 }
4369
4370 static int
4371 api_sw_interface_set_flags (vat_main_t * vam)
4372 {
4373   unformat_input_t *i = vam->input;
4374   vl_api_sw_interface_set_flags_t *mp;
4375   f64 timeout;
4376   u32 sw_if_index;
4377   u8 sw_if_index_set = 0;
4378   u8 admin_up = 0, link_up = 0;
4379
4380   /* Parse args required to build the message */
4381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4382     {
4383       if (unformat (i, "admin-up"))
4384         admin_up = 1;
4385       else if (unformat (i, "admin-down"))
4386         admin_up = 0;
4387       else if (unformat (i, "link-up"))
4388         link_up = 1;
4389       else if (unformat (i, "link-down"))
4390         link_up = 0;
4391       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4392         sw_if_index_set = 1;
4393       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4394         sw_if_index_set = 1;
4395       else
4396         break;
4397     }
4398
4399   if (sw_if_index_set == 0)
4400     {
4401       errmsg ("missing interface name or sw_if_index\n");
4402       return -99;
4403     }
4404
4405   /* Construct the API message */
4406   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4407   mp->sw_if_index = ntohl (sw_if_index);
4408   mp->admin_up_down = admin_up;
4409   mp->link_up_down = link_up;
4410
4411   /* send it... */
4412   S;
4413
4414   /* Wait for a reply, return the good/bad news... */
4415   W;
4416 }
4417
4418 static int
4419 api_sw_interface_clear_stats (vat_main_t * vam)
4420 {
4421   unformat_input_t *i = vam->input;
4422   vl_api_sw_interface_clear_stats_t *mp;
4423   f64 timeout;
4424   u32 sw_if_index;
4425   u8 sw_if_index_set = 0;
4426
4427   /* Parse args required to build the message */
4428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4429     {
4430       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4431         sw_if_index_set = 1;
4432       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4433         sw_if_index_set = 1;
4434       else
4435         break;
4436     }
4437
4438   /* Construct the API message */
4439   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4440
4441   if (sw_if_index_set == 1)
4442     mp->sw_if_index = ntohl (sw_if_index);
4443   else
4444     mp->sw_if_index = ~0;
4445
4446   /* send it... */
4447   S;
4448
4449   /* Wait for a reply, return the good/bad news... */
4450   W;
4451 }
4452
4453 static int
4454 api_sw_interface_add_del_address (vat_main_t * vam)
4455 {
4456   unformat_input_t *i = vam->input;
4457   vl_api_sw_interface_add_del_address_t *mp;
4458   f64 timeout;
4459   u32 sw_if_index;
4460   u8 sw_if_index_set = 0;
4461   u8 is_add = 1, del_all = 0;
4462   u32 address_length = 0;
4463   u8 v4_address_set = 0;
4464   u8 v6_address_set = 0;
4465   ip4_address_t v4address;
4466   ip6_address_t v6address;
4467
4468   /* Parse args required to build the message */
4469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4470     {
4471       if (unformat (i, "del-all"))
4472         del_all = 1;
4473       else if (unformat (i, "del"))
4474         is_add = 0;
4475       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4476         sw_if_index_set = 1;
4477       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4478         sw_if_index_set = 1;
4479       else if (unformat (i, "%U/%d",
4480                          unformat_ip4_address, &v4address, &address_length))
4481         v4_address_set = 1;
4482       else if (unformat (i, "%U/%d",
4483                          unformat_ip6_address, &v6address, &address_length))
4484         v6_address_set = 1;
4485       else
4486         break;
4487     }
4488
4489   if (sw_if_index_set == 0)
4490     {
4491       errmsg ("missing interface name or sw_if_index\n");
4492       return -99;
4493     }
4494   if (v4_address_set && v6_address_set)
4495     {
4496       errmsg ("both v4 and v6 addresses set\n");
4497       return -99;
4498     }
4499   if (!v4_address_set && !v6_address_set && !del_all)
4500     {
4501       errmsg ("no addresses set\n");
4502       return -99;
4503     }
4504
4505   /* Construct the API message */
4506   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4507
4508   mp->sw_if_index = ntohl (sw_if_index);
4509   mp->is_add = is_add;
4510   mp->del_all = del_all;
4511   if (v6_address_set)
4512     {
4513       mp->is_ipv6 = 1;
4514       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4515     }
4516   else
4517     {
4518       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4519     }
4520   mp->address_length = address_length;
4521
4522   /* send it... */
4523   S;
4524
4525   /* Wait for a reply, return good/bad news  */
4526   W;
4527 }
4528
4529 static int
4530 api_sw_interface_set_table (vat_main_t * vam)
4531 {
4532   unformat_input_t *i = vam->input;
4533   vl_api_sw_interface_set_table_t *mp;
4534   f64 timeout;
4535   u32 sw_if_index, vrf_id = 0;
4536   u8 sw_if_index_set = 0;
4537   u8 is_ipv6 = 0;
4538
4539   /* Parse args required to build the message */
4540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4541     {
4542       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4543         sw_if_index_set = 1;
4544       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4545         sw_if_index_set = 1;
4546       else if (unformat (i, "vrf %d", &vrf_id))
4547         ;
4548       else if (unformat (i, "ipv6"))
4549         is_ipv6 = 1;
4550       else
4551         break;
4552     }
4553
4554   if (sw_if_index_set == 0)
4555     {
4556       errmsg ("missing interface name or sw_if_index\n");
4557       return -99;
4558     }
4559
4560   /* Construct the API message */
4561   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4562
4563   mp->sw_if_index = ntohl (sw_if_index);
4564   mp->is_ipv6 = is_ipv6;
4565   mp->vrf_id = ntohl (vrf_id);
4566
4567   /* send it... */
4568   S;
4569
4570   /* Wait for a reply... */
4571   W;
4572 }
4573
4574 static int
4575 api_sw_interface_set_vpath (vat_main_t * vam)
4576 {
4577   unformat_input_t *i = vam->input;
4578   vl_api_sw_interface_set_vpath_t *mp;
4579   f64 timeout;
4580   u32 sw_if_index = 0;
4581   u8 sw_if_index_set = 0;
4582   u8 is_enable = 0;
4583
4584   /* Parse args required to build the message */
4585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4586     {
4587       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4588         sw_if_index_set = 1;
4589       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4590         sw_if_index_set = 1;
4591       else if (unformat (i, "enable"))
4592         is_enable = 1;
4593       else if (unformat (i, "disable"))
4594         is_enable = 0;
4595       else
4596         break;
4597     }
4598
4599   if (sw_if_index_set == 0)
4600     {
4601       errmsg ("missing interface name or sw_if_index\n");
4602       return -99;
4603     }
4604
4605   /* Construct the API message */
4606   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4607
4608   mp->sw_if_index = ntohl (sw_if_index);
4609   mp->enable = is_enable;
4610
4611   /* send it... */
4612   S;
4613
4614   /* Wait for a reply... */
4615   W;
4616 }
4617
4618 static int
4619 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4620 {
4621   unformat_input_t *i = vam->input;
4622   vl_api_sw_interface_set_l2_xconnect_t *mp;
4623   f64 timeout;
4624   u32 rx_sw_if_index;
4625   u8 rx_sw_if_index_set = 0;
4626   u32 tx_sw_if_index;
4627   u8 tx_sw_if_index_set = 0;
4628   u8 enable = 1;
4629
4630   /* Parse args required to build the message */
4631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4632     {
4633       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4634         rx_sw_if_index_set = 1;
4635       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4636         tx_sw_if_index_set = 1;
4637       else if (unformat (i, "rx"))
4638         {
4639           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4640             {
4641               if (unformat (i, "%U", unformat_sw_if_index, vam,
4642                             &rx_sw_if_index))
4643                 rx_sw_if_index_set = 1;
4644             }
4645           else
4646             break;
4647         }
4648       else if (unformat (i, "tx"))
4649         {
4650           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4651             {
4652               if (unformat (i, "%U", unformat_sw_if_index, vam,
4653                             &tx_sw_if_index))
4654                 tx_sw_if_index_set = 1;
4655             }
4656           else
4657             break;
4658         }
4659       else if (unformat (i, "enable"))
4660         enable = 1;
4661       else if (unformat (i, "disable"))
4662         enable = 0;
4663       else
4664         break;
4665     }
4666
4667   if (rx_sw_if_index_set == 0)
4668     {
4669       errmsg ("missing rx interface name or rx_sw_if_index\n");
4670       return -99;
4671     }
4672
4673   if (enable && (tx_sw_if_index_set == 0))
4674     {
4675       errmsg ("missing tx interface name or tx_sw_if_index\n");
4676       return -99;
4677     }
4678
4679   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4680
4681   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4682   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4683   mp->enable = enable;
4684
4685   S;
4686   W;
4687   /* NOTREACHED */
4688   return 0;
4689 }
4690
4691 static int
4692 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4693 {
4694   unformat_input_t *i = vam->input;
4695   vl_api_sw_interface_set_l2_bridge_t *mp;
4696   f64 timeout;
4697   u32 rx_sw_if_index;
4698   u8 rx_sw_if_index_set = 0;
4699   u32 bd_id;
4700   u8 bd_id_set = 0;
4701   u8 bvi = 0;
4702   u32 shg = 0;
4703   u8 enable = 1;
4704
4705   /* Parse args required to build the message */
4706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4707     {
4708       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4709         rx_sw_if_index_set = 1;
4710       else if (unformat (i, "bd_id %d", &bd_id))
4711         bd_id_set = 1;
4712       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
4713         rx_sw_if_index_set = 1;
4714       else if (unformat (i, "shg %d", &shg))
4715         ;
4716       else if (unformat (i, "bvi"))
4717         bvi = 1;
4718       else if (unformat (i, "enable"))
4719         enable = 1;
4720       else if (unformat (i, "disable"))
4721         enable = 0;
4722       else
4723         break;
4724     }
4725
4726   if (rx_sw_if_index_set == 0)
4727     {
4728       errmsg ("missing rx interface name or sw_if_index\n");
4729       return -99;
4730     }
4731
4732   if (enable && (bd_id_set == 0))
4733     {
4734       errmsg ("missing bridge domain\n");
4735       return -99;
4736     }
4737
4738   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4739
4740   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4741   mp->bd_id = ntohl (bd_id);
4742   mp->shg = (u8) shg;
4743   mp->bvi = bvi;
4744   mp->enable = enable;
4745
4746   S;
4747   W;
4748   /* NOTREACHED */
4749   return 0;
4750 }
4751
4752 static int
4753 api_bridge_domain_dump (vat_main_t * vam)
4754 {
4755   unformat_input_t *i = vam->input;
4756   vl_api_bridge_domain_dump_t *mp;
4757   f64 timeout;
4758   u32 bd_id = ~0;
4759
4760   /* Parse args required to build the message */
4761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4762     {
4763       if (unformat (i, "bd_id %d", &bd_id))
4764         ;
4765       else
4766         break;
4767     }
4768
4769   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4770   mp->bd_id = ntohl (bd_id);
4771   S;
4772
4773   /* Use a control ping for synchronization */
4774   {
4775     vl_api_control_ping_t *mp;
4776     M (CONTROL_PING, control_ping);
4777     S;
4778   }
4779
4780   W;
4781   /* NOTREACHED */
4782   return 0;
4783 }
4784
4785 static int
4786 api_bridge_domain_add_del (vat_main_t * vam)
4787 {
4788   unformat_input_t *i = vam->input;
4789   vl_api_bridge_domain_add_del_t *mp;
4790   f64 timeout;
4791   u32 bd_id = ~0;
4792   u8 is_add = 1;
4793   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4794
4795   /* Parse args required to build the message */
4796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4797     {
4798       if (unformat (i, "bd_id %d", &bd_id))
4799         ;
4800       else if (unformat (i, "flood %d", &flood))
4801         ;
4802       else if (unformat (i, "uu-flood %d", &uu_flood))
4803         ;
4804       else if (unformat (i, "forward %d", &forward))
4805         ;
4806       else if (unformat (i, "learn %d", &learn))
4807         ;
4808       else if (unformat (i, "arp-term %d", &arp_term))
4809         ;
4810       else if (unformat (i, "del"))
4811         {
4812           is_add = 0;
4813           flood = uu_flood = forward = learn = 0;
4814         }
4815       else
4816         break;
4817     }
4818
4819   if (bd_id == ~0)
4820     {
4821       errmsg ("missing bridge domain\n");
4822       return -99;
4823     }
4824
4825   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4826
4827   mp->bd_id = ntohl (bd_id);
4828   mp->flood = flood;
4829   mp->uu_flood = uu_flood;
4830   mp->forward = forward;
4831   mp->learn = learn;
4832   mp->arp_term = arp_term;
4833   mp->is_add = is_add;
4834
4835   S;
4836   W;
4837   /* NOTREACHED */
4838   return 0;
4839 }
4840
4841 static int
4842 api_l2fib_add_del (vat_main_t * vam)
4843 {
4844   unformat_input_t *i = vam->input;
4845   vl_api_l2fib_add_del_t *mp;
4846   f64 timeout;
4847   u64 mac = 0;
4848   u8 mac_set = 0;
4849   u32 bd_id;
4850   u8 bd_id_set = 0;
4851   u32 sw_if_index;
4852   u8 sw_if_index_set = 0;
4853   u8 is_add = 1;
4854   u8 static_mac = 0;
4855   u8 filter_mac = 0;
4856   u8 bvi_mac = 0;
4857   int count = 1;
4858   f64 before = 0;
4859   int j;
4860
4861   /* Parse args required to build the message */
4862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4863     {
4864       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4865         mac_set = 1;
4866       else if (unformat (i, "bd_id %d", &bd_id))
4867         bd_id_set = 1;
4868       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4869         sw_if_index_set = 1;
4870       else if (unformat (i, "sw_if"))
4871         {
4872           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4873             {
4874               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4875                 sw_if_index_set = 1;
4876             }
4877           else
4878             break;
4879         }
4880       else if (unformat (i, "static"))
4881         static_mac = 1;
4882       else if (unformat (i, "filter"))
4883         {
4884           filter_mac = 1;
4885           static_mac = 1;
4886         }
4887       else if (unformat (i, "bvi"))
4888         {
4889           bvi_mac = 1;
4890           static_mac = 1;
4891         }
4892       else if (unformat (i, "del"))
4893         is_add = 0;
4894       else if (unformat (i, "count %d", &count))
4895         ;
4896       else
4897         break;
4898     }
4899
4900   if (mac_set == 0)
4901     {
4902       errmsg ("missing mac address\n");
4903       return -99;
4904     }
4905
4906   if (bd_id_set == 0)
4907     {
4908       errmsg ("missing bridge domain\n");
4909       return -99;
4910     }
4911
4912   if (is_add && (sw_if_index_set == 0))
4913     {
4914       errmsg ("missing interface name or sw_if_index\n");
4915       return -99;
4916     }
4917
4918   if (count > 1)
4919     {
4920       /* Turn on async mode */
4921       vam->async_mode = 1;
4922       vam->async_errors = 0;
4923       before = vat_time_now (vam);
4924     }
4925
4926   for (j = 0; j < count; j++)
4927     {
4928       M (L2FIB_ADD_DEL, l2fib_add_del);
4929
4930       mp->mac = mac;
4931       mp->bd_id = ntohl (bd_id);
4932       mp->is_add = is_add;
4933
4934       if (is_add)
4935         {
4936           mp->sw_if_index = ntohl (sw_if_index);
4937           mp->static_mac = static_mac;
4938           mp->filter_mac = filter_mac;
4939           mp->bvi_mac = bvi_mac;
4940         }
4941       increment_mac_address (&mac);
4942       /* send it... */
4943       S;
4944     }
4945
4946   if (count > 1)
4947     {
4948       vl_api_control_ping_t *mp;
4949       f64 after;
4950
4951       /* Shut off async mode */
4952       vam->async_mode = 0;
4953
4954       M (CONTROL_PING, control_ping);
4955       S;
4956
4957       timeout = vat_time_now (vam) + 1.0;
4958       while (vat_time_now (vam) < timeout)
4959         if (vam->result_ready == 1)
4960           goto out;
4961       vam->retval = -99;
4962
4963     out:
4964       if (vam->retval == -99)
4965         errmsg ("timeout\n");
4966
4967       if (vam->async_errors > 0)
4968         {
4969           errmsg ("%d asynchronous errors\n", vam->async_errors);
4970           vam->retval = -98;
4971         }
4972       vam->async_errors = 0;
4973       after = vat_time_now (vam);
4974
4975       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4976                count, after - before, count / (after - before));
4977     }
4978   else
4979     {
4980       /* Wait for a reply... */
4981       W;
4982     }
4983   /* Return the good/bad news */
4984   return (vam->retval);
4985 }
4986
4987 static int
4988 api_l2_flags (vat_main_t * vam)
4989 {
4990   unformat_input_t *i = vam->input;
4991   vl_api_l2_flags_t *mp;
4992   f64 timeout;
4993   u32 sw_if_index;
4994   u32 feature_bitmap = 0;
4995   u8 sw_if_index_set = 0;
4996
4997   /* Parse args required to build the message */
4998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4999     {
5000       if (unformat (i, "sw_if_index %d", &sw_if_index))
5001         sw_if_index_set = 1;
5002       else if (unformat (i, "sw_if"))
5003         {
5004           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5005             {
5006               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5007                 sw_if_index_set = 1;
5008             }
5009           else
5010             break;
5011         }
5012       else if (unformat (i, "learn"))
5013         feature_bitmap |= L2INPUT_FEAT_LEARN;
5014       else if (unformat (i, "forward"))
5015         feature_bitmap |= L2INPUT_FEAT_FWD;
5016       else if (unformat (i, "flood"))
5017         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5018       else if (unformat (i, "uu-flood"))
5019         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5020       else
5021         break;
5022     }
5023
5024   if (sw_if_index_set == 0)
5025     {
5026       errmsg ("missing interface name or sw_if_index\n");
5027       return -99;
5028     }
5029
5030   M (L2_FLAGS, l2_flags);
5031
5032   mp->sw_if_index = ntohl (sw_if_index);
5033   mp->feature_bitmap = ntohl (feature_bitmap);
5034
5035   S;
5036   W;
5037   /* NOTREACHED */
5038   return 0;
5039 }
5040
5041 static int
5042 api_bridge_flags (vat_main_t * vam)
5043 {
5044   unformat_input_t *i = vam->input;
5045   vl_api_bridge_flags_t *mp;
5046   f64 timeout;
5047   u32 bd_id;
5048   u8 bd_id_set = 0;
5049   u8 is_set = 1;
5050   u32 flags = 0;
5051
5052   /* Parse args required to build the message */
5053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5054     {
5055       if (unformat (i, "bd_id %d", &bd_id))
5056         bd_id_set = 1;
5057       else if (unformat (i, "learn"))
5058         flags |= L2_LEARN;
5059       else if (unformat (i, "forward"))
5060         flags |= L2_FWD;
5061       else if (unformat (i, "flood"))
5062         flags |= L2_FLOOD;
5063       else if (unformat (i, "uu-flood"))
5064         flags |= L2_UU_FLOOD;
5065       else if (unformat (i, "arp-term"))
5066         flags |= L2_ARP_TERM;
5067       else if (unformat (i, "off"))
5068         is_set = 0;
5069       else if (unformat (i, "disable"))
5070         is_set = 0;
5071       else
5072         break;
5073     }
5074
5075   if (bd_id_set == 0)
5076     {
5077       errmsg ("missing bridge domain\n");
5078       return -99;
5079     }
5080
5081   M (BRIDGE_FLAGS, bridge_flags);
5082
5083   mp->bd_id = ntohl (bd_id);
5084   mp->feature_bitmap = ntohl (flags);
5085   mp->is_set = is_set;
5086
5087   S;
5088   W;
5089   /* NOTREACHED */
5090   return 0;
5091 }
5092
5093 static int
5094 api_bd_ip_mac_add_del (vat_main_t * vam)
5095 {
5096   unformat_input_t *i = vam->input;
5097   vl_api_bd_ip_mac_add_del_t *mp;
5098   f64 timeout;
5099   u32 bd_id;
5100   u8 is_ipv6 = 0;
5101   u8 is_add = 1;
5102   u8 bd_id_set = 0;
5103   u8 ip_set = 0;
5104   u8 mac_set = 0;
5105   ip4_address_t v4addr;
5106   ip6_address_t v6addr;
5107   u8 macaddr[6];
5108
5109
5110   /* Parse args required to build the message */
5111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5112     {
5113       if (unformat (i, "bd_id %d", &bd_id))
5114         {
5115           bd_id_set++;
5116         }
5117       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5118         {
5119           ip_set++;
5120         }
5121       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5122         {
5123           ip_set++;
5124           is_ipv6++;
5125         }
5126       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5127         {
5128           mac_set++;
5129         }
5130       else if (unformat (i, "del"))
5131         is_add = 0;
5132       else
5133         break;
5134     }
5135
5136   if (bd_id_set == 0)
5137     {
5138       errmsg ("missing bridge domain\n");
5139       return -99;
5140     }
5141   else if (ip_set == 0)
5142     {
5143       errmsg ("missing IP address\n");
5144       return -99;
5145     }
5146   else if (mac_set == 0)
5147     {
5148       errmsg ("missing MAC address\n");
5149       return -99;
5150     }
5151
5152   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5153
5154   mp->bd_id = ntohl (bd_id);
5155   mp->is_ipv6 = is_ipv6;
5156   mp->is_add = is_add;
5157   if (is_ipv6)
5158     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5159   else
5160     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5161   clib_memcpy (mp->mac_address, macaddr, 6);
5162   S;
5163   W;
5164   /* NOTREACHED */
5165   return 0;
5166 }
5167
5168 static int
5169 api_tap_connect (vat_main_t * vam)
5170 {
5171   unformat_input_t *i = vam->input;
5172   vl_api_tap_connect_t *mp;
5173   f64 timeout;
5174   u8 mac_address[6];
5175   u8 random_mac = 1;
5176   u8 name_set = 0;
5177   u8 *tap_name;
5178
5179   memset (mac_address, 0, sizeof (mac_address));
5180
5181   /* Parse args required to build the message */
5182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5183     {
5184       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5185         {
5186           random_mac = 0;
5187         }
5188       else if (unformat (i, "random-mac"))
5189         random_mac = 1;
5190       else if (unformat (i, "tapname %s", &tap_name))
5191         name_set = 1;
5192       else
5193         break;
5194     }
5195
5196   if (name_set == 0)
5197     {
5198       errmsg ("missing tap name\n");
5199       return -99;
5200     }
5201   if (vec_len (tap_name) > 63)
5202     {
5203       errmsg ("tap name too long\n");
5204     }
5205   vec_add1 (tap_name, 0);
5206
5207   /* Construct the API message */
5208   M (TAP_CONNECT, tap_connect);
5209
5210   mp->use_random_mac = random_mac;
5211   clib_memcpy (mp->mac_address, mac_address, 6);
5212   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5213   vec_free (tap_name);
5214
5215   /* send it... */
5216   S;
5217
5218   /* Wait for a reply... */
5219   W;
5220 }
5221
5222 static int
5223 api_tap_modify (vat_main_t * vam)
5224 {
5225   unformat_input_t *i = vam->input;
5226   vl_api_tap_modify_t *mp;
5227   f64 timeout;
5228   u8 mac_address[6];
5229   u8 random_mac = 1;
5230   u8 name_set = 0;
5231   u8 *tap_name;
5232   u32 sw_if_index = ~0;
5233   u8 sw_if_index_set = 0;
5234
5235   memset (mac_address, 0, sizeof (mac_address));
5236
5237   /* Parse args required to build the message */
5238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5239     {
5240       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5241         sw_if_index_set = 1;
5242       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5243         sw_if_index_set = 1;
5244       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5245         {
5246           random_mac = 0;
5247         }
5248       else if (unformat (i, "random-mac"))
5249         random_mac = 1;
5250       else if (unformat (i, "tapname %s", &tap_name))
5251         name_set = 1;
5252       else
5253         break;
5254     }
5255
5256   if (sw_if_index_set == 0)
5257     {
5258       errmsg ("missing vpp interface name");
5259       return -99;
5260     }
5261   if (name_set == 0)
5262     {
5263       errmsg ("missing tap name\n");
5264       return -99;
5265     }
5266   if (vec_len (tap_name) > 63)
5267     {
5268       errmsg ("tap name too long\n");
5269     }
5270   vec_add1 (tap_name, 0);
5271
5272   /* Construct the API message */
5273   M (TAP_MODIFY, tap_modify);
5274
5275   mp->use_random_mac = random_mac;
5276   mp->sw_if_index = ntohl (sw_if_index);
5277   clib_memcpy (mp->mac_address, mac_address, 6);
5278   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5279   vec_free (tap_name);
5280
5281   /* send it... */
5282   S;
5283
5284   /* Wait for a reply... */
5285   W;
5286 }
5287
5288 static int
5289 api_tap_delete (vat_main_t * vam)
5290 {
5291   unformat_input_t *i = vam->input;
5292   vl_api_tap_delete_t *mp;
5293   f64 timeout;
5294   u32 sw_if_index = ~0;
5295   u8 sw_if_index_set = 0;
5296
5297   /* Parse args required to build the message */
5298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5299     {
5300       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5301         sw_if_index_set = 1;
5302       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5303         sw_if_index_set = 1;
5304       else
5305         break;
5306     }
5307
5308   if (sw_if_index_set == 0)
5309     {
5310       errmsg ("missing vpp interface name");
5311       return -99;
5312     }
5313
5314   /* Construct the API message */
5315   M (TAP_DELETE, tap_delete);
5316
5317   mp->sw_if_index = ntohl (sw_if_index);
5318
5319   /* send it... */
5320   S;
5321
5322   /* Wait for a reply... */
5323   W;
5324 }
5325
5326 static int
5327 api_ip_add_del_route (vat_main_t * vam)
5328 {
5329   unformat_input_t *i = vam->input;
5330   vl_api_ip_add_del_route_t *mp;
5331   f64 timeout;
5332   u32 sw_if_index = ~0, vrf_id = 0;
5333   u8 sw_if_index_set = 0;
5334   u8 is_ipv6 = 0;
5335   u8 is_local = 0, is_drop = 0;
5336   u8 create_vrf_if_needed = 0;
5337   u8 is_add = 1;
5338   u8 next_hop_weight = 1;
5339   u8 not_last = 0;
5340   u8 is_multipath = 0;
5341   u8 address_set = 0;
5342   u8 address_length_set = 0;
5343   u32 lookup_in_vrf = 0;
5344   u32 resolve_attempts = 0;
5345   u32 dst_address_length = 0;
5346   u8 next_hop_set = 0;
5347   ip4_address_t v4_dst_address, v4_next_hop_address;
5348   ip6_address_t v6_dst_address, v6_next_hop_address;
5349   int count = 1;
5350   int j;
5351   f64 before = 0;
5352   u32 random_add_del = 0;
5353   u32 *random_vector = 0;
5354   uword *random_hash;
5355   u32 random_seed = 0xdeaddabe;
5356   u32 classify_table_index = ~0;
5357   u8 is_classify = 0;
5358
5359   /* Parse args required to build the message */
5360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5361     {
5362       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5363         sw_if_index_set = 1;
5364       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5365         sw_if_index_set = 1;
5366       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5367         {
5368           address_set = 1;
5369           is_ipv6 = 0;
5370         }
5371       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5372         {
5373           address_set = 1;
5374           is_ipv6 = 1;
5375         }
5376       else if (unformat (i, "/%d", &dst_address_length))
5377         {
5378           address_length_set = 1;
5379         }
5380
5381       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5382                                          &v4_next_hop_address))
5383         {
5384           next_hop_set = 1;
5385         }
5386       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5387                                          &v6_next_hop_address))
5388         {
5389           next_hop_set = 1;
5390         }
5391       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5392         ;
5393       else if (unformat (i, "weight %d", &next_hop_weight))
5394         ;
5395       else if (unformat (i, "drop"))
5396         {
5397           is_drop = 1;
5398         }
5399       else if (unformat (i, "local"))
5400         {
5401           is_local = 1;
5402         }
5403       else if (unformat (i, "classify %d", &classify_table_index))
5404         {
5405           is_classify = 1;
5406         }
5407       else if (unformat (i, "del"))
5408         is_add = 0;
5409       else if (unformat (i, "add"))
5410         is_add = 1;
5411       else if (unformat (i, "not-last"))
5412         not_last = 1;
5413       else if (unformat (i, "multipath"))
5414         is_multipath = 1;
5415       else if (unformat (i, "vrf %d", &vrf_id))
5416         ;
5417       else if (unformat (i, "create-vrf"))
5418         create_vrf_if_needed = 1;
5419       else if (unformat (i, "count %d", &count))
5420         ;
5421       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5422         ;
5423       else if (unformat (i, "random"))
5424         random_add_del = 1;
5425       else if (unformat (i, "seed %d", &random_seed))
5426         ;
5427       else
5428         {
5429           clib_warning ("parse error '%U'", format_unformat_error, i);
5430           return -99;
5431         }
5432     }
5433
5434   if (resolve_attempts > 0 && sw_if_index_set == 0)
5435     {
5436       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5437       return -99;
5438     }
5439
5440   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5441     {
5442       errmsg ("next hop / local / drop / classify not set\n");
5443       return -99;
5444     }
5445
5446   if (address_set == 0)
5447     {
5448       errmsg ("missing addresses\n");
5449       return -99;
5450     }
5451
5452   if (address_length_set == 0)
5453     {
5454       errmsg ("missing address length\n");
5455       return -99;
5456     }
5457
5458   /* Generate a pile of unique, random routes */
5459   if (random_add_del)
5460     {
5461       u32 this_random_address;
5462       random_hash = hash_create (count, sizeof (uword));
5463
5464       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5465       for (j = 0; j <= count; j++)
5466         {
5467           do
5468             {
5469               this_random_address = random_u32 (&random_seed);
5470               this_random_address =
5471                 clib_host_to_net_u32 (this_random_address);
5472             }
5473           while (hash_get (random_hash, this_random_address));
5474           vec_add1 (random_vector, this_random_address);
5475           hash_set (random_hash, this_random_address, 1);
5476         }
5477       hash_free (random_hash);
5478       v4_dst_address.as_u32 = random_vector[0];
5479     }
5480
5481   if (count > 1)
5482     {
5483       /* Turn on async mode */
5484       vam->async_mode = 1;
5485       vam->async_errors = 0;
5486       before = vat_time_now (vam);
5487     }
5488
5489   for (j = 0; j < count; j++)
5490     {
5491       /* Construct the API message */
5492       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5493
5494       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5495       mp->vrf_id = ntohl (vrf_id);
5496       if (resolve_attempts > 0)
5497         {
5498           mp->resolve_attempts = ntohl (resolve_attempts);
5499           mp->resolve_if_needed = 1;
5500         }
5501       mp->create_vrf_if_needed = create_vrf_if_needed;
5502
5503       mp->is_add = is_add;
5504       mp->is_drop = is_drop;
5505       mp->is_ipv6 = is_ipv6;
5506       mp->is_local = is_local;
5507       mp->is_classify = is_classify;
5508       mp->is_multipath = is_multipath;
5509       mp->not_last = not_last;
5510       mp->next_hop_weight = next_hop_weight;
5511       mp->dst_address_length = dst_address_length;
5512       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5513       mp->classify_table_index = ntohl (classify_table_index);
5514
5515       if (is_ipv6)
5516         {
5517           clib_memcpy (mp->dst_address, &v6_dst_address,
5518                        sizeof (v6_dst_address));
5519           if (next_hop_set)
5520             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5521                          sizeof (v6_next_hop_address));
5522           increment_v6_address (&v6_dst_address);
5523         }
5524       else
5525         {
5526           clib_memcpy (mp->dst_address, &v4_dst_address,
5527                        sizeof (v4_dst_address));
5528           if (next_hop_set)
5529             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5530                          sizeof (v4_next_hop_address));
5531           if (random_add_del)
5532             v4_dst_address.as_u32 = random_vector[j + 1];
5533           else
5534             increment_v4_address (&v4_dst_address);
5535         }
5536       /* send it... */
5537       S;
5538     }
5539
5540   /* When testing multiple add/del ops, use a control-ping to sync */
5541   if (count > 1)
5542     {
5543       vl_api_control_ping_t *mp;
5544       f64 after;
5545
5546       /* Shut off async mode */
5547       vam->async_mode = 0;
5548
5549       M (CONTROL_PING, control_ping);
5550       S;
5551
5552       timeout = vat_time_now (vam) + 1.0;
5553       while (vat_time_now (vam) < timeout)
5554         if (vam->result_ready == 1)
5555           goto out;
5556       vam->retval = -99;
5557
5558     out:
5559       if (vam->retval == -99)
5560         errmsg ("timeout\n");
5561
5562       if (vam->async_errors > 0)
5563         {
5564           errmsg ("%d asynchronous errors\n", vam->async_errors);
5565           vam->retval = -98;
5566         }
5567       vam->async_errors = 0;
5568       after = vat_time_now (vam);
5569
5570       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5571                count, after - before, count / (after - before));
5572     }
5573   else
5574     {
5575       /* Wait for a reply... */
5576       W;
5577     }
5578
5579   /* Return the good/bad news */
5580   return (vam->retval);
5581 }
5582
5583 static int
5584 api_proxy_arp_add_del (vat_main_t * vam)
5585 {
5586   unformat_input_t *i = vam->input;
5587   vl_api_proxy_arp_add_del_t *mp;
5588   f64 timeout;
5589   u32 vrf_id = 0;
5590   u8 is_add = 1;
5591   ip4_address_t lo, hi;
5592   u8 range_set = 0;
5593
5594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5595     {
5596       if (unformat (i, "vrf %d", &vrf_id))
5597         ;
5598       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5599                          unformat_ip4_address, &hi))
5600         range_set = 1;
5601       else if (unformat (i, "del"))
5602         is_add = 0;
5603       else
5604         {
5605           clib_warning ("parse error '%U'", format_unformat_error, i);
5606           return -99;
5607         }
5608     }
5609
5610   if (range_set == 0)
5611     {
5612       errmsg ("address range not set\n");
5613       return -99;
5614     }
5615
5616   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5617
5618   mp->vrf_id = ntohl (vrf_id);
5619   mp->is_add = is_add;
5620   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5621   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5622
5623   S;
5624   W;
5625   /* NOTREACHED */
5626   return 0;
5627 }
5628
5629 static int
5630 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5631 {
5632   unformat_input_t *i = vam->input;
5633   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5634   f64 timeout;
5635   u32 sw_if_index;
5636   u8 enable = 1;
5637   u8 sw_if_index_set = 0;
5638
5639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5640     {
5641       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5642         sw_if_index_set = 1;
5643       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5644         sw_if_index_set = 1;
5645       else if (unformat (i, "enable"))
5646         enable = 1;
5647       else if (unformat (i, "disable"))
5648         enable = 0;
5649       else
5650         {
5651           clib_warning ("parse error '%U'", format_unformat_error, i);
5652           return -99;
5653         }
5654     }
5655
5656   if (sw_if_index_set == 0)
5657     {
5658       errmsg ("missing interface name or sw_if_index\n");
5659       return -99;
5660     }
5661
5662   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5663
5664   mp->sw_if_index = ntohl (sw_if_index);
5665   mp->enable_disable = enable;
5666
5667   S;
5668   W;
5669   /* NOTREACHED */
5670   return 0;
5671 }
5672
5673 static int
5674 api_mpls_add_del_decap (vat_main_t * vam)
5675 {
5676   unformat_input_t *i = vam->input;
5677   vl_api_mpls_add_del_decap_t *mp;
5678   f64 timeout;
5679   u32 rx_vrf_id = 0;
5680   u32 tx_vrf_id = 0;
5681   u32 label = 0;
5682   u8 is_add = 1;
5683   u8 s_bit = 1;
5684   u32 next_index = 1;
5685
5686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5687     {
5688       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5689         ;
5690       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5691         ;
5692       else if (unformat (i, "label %d", &label))
5693         ;
5694       else if (unformat (i, "next-index %d", &next_index))
5695         ;
5696       else if (unformat (i, "del"))
5697         is_add = 0;
5698       else if (unformat (i, "s-bit-clear"))
5699         s_bit = 0;
5700       else
5701         {
5702           clib_warning ("parse error '%U'", format_unformat_error, i);
5703           return -99;
5704         }
5705     }
5706
5707   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5708
5709   mp->rx_vrf_id = ntohl (rx_vrf_id);
5710   mp->tx_vrf_id = ntohl (tx_vrf_id);
5711   mp->label = ntohl (label);
5712   mp->next_index = ntohl (next_index);
5713   mp->s_bit = s_bit;
5714   mp->is_add = is_add;
5715
5716   S;
5717   W;
5718   /* NOTREACHED */
5719   return 0;
5720 }
5721
5722 static int
5723 api_mpls_add_del_encap (vat_main_t * vam)
5724 {
5725   unformat_input_t *i = vam->input;
5726   vl_api_mpls_add_del_encap_t *mp;
5727   f64 timeout;
5728   u32 vrf_id = 0;
5729   u32 *labels = 0;
5730   u32 label;
5731   ip4_address_t dst_address;
5732   u8 is_add = 1;
5733
5734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5735     {
5736       if (unformat (i, "vrf %d", &vrf_id))
5737         ;
5738       else if (unformat (i, "label %d", &label))
5739         vec_add1 (labels, ntohl (label));
5740       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5741         ;
5742       else if (unformat (i, "del"))
5743         is_add = 0;
5744       else
5745         {
5746           clib_warning ("parse error '%U'", format_unformat_error, i);
5747           return -99;
5748         }
5749     }
5750
5751   if (vec_len (labels) == 0)
5752     {
5753       errmsg ("missing encap label stack\n");
5754       return -99;
5755     }
5756
5757   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
5758       sizeof (u32) * vec_len (labels));
5759
5760   mp->vrf_id = ntohl (vrf_id);
5761   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5762   mp->is_add = is_add;
5763   mp->nlabels = vec_len (labels);
5764   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
5765
5766   vec_free (labels);
5767
5768   S;
5769   W;
5770   /* NOTREACHED */
5771   return 0;
5772 }
5773
5774 static int
5775 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5776 {
5777   unformat_input_t *i = vam->input;
5778   vl_api_mpls_gre_add_del_tunnel_t *mp;
5779   f64 timeout;
5780   u32 inner_vrf_id = 0;
5781   u32 outer_vrf_id = 0;
5782   ip4_address_t src_address;
5783   ip4_address_t dst_address;
5784   ip4_address_t intfc_address;
5785   u32 tmp;
5786   u8 intfc_address_length = 0;
5787   u8 is_add = 1;
5788   u8 l2_only = 0;
5789
5790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5791     {
5792       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5793         ;
5794       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5795         ;
5796       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5797         ;
5798       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5799         ;
5800       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5801                          &intfc_address, &tmp))
5802         intfc_address_length = tmp;
5803       else if (unformat (i, "l2-only"))
5804         l2_only = 1;
5805       else if (unformat (i, "del"))
5806         is_add = 0;
5807       else
5808         {
5809           clib_warning ("parse error '%U'", format_unformat_error, i);
5810           return -99;
5811         }
5812     }
5813
5814   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5815
5816   mp->inner_vrf_id = ntohl (inner_vrf_id);
5817   mp->outer_vrf_id = ntohl (outer_vrf_id);
5818   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
5819   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5820   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
5821   mp->intfc_address_length = intfc_address_length;
5822   mp->l2_only = l2_only;
5823   mp->is_add = is_add;
5824
5825   S;
5826   W;
5827   /* NOTREACHED */
5828   return 0;
5829 }
5830
5831 static int
5832 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5833 {
5834   unformat_input_t *i = vam->input;
5835   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5836   f64 timeout;
5837   u32 inner_vrf_id = 0;
5838   ip4_address_t intfc_address;
5839   u8 dst_mac_address[6];
5840   int dst_set = 1;
5841   u32 tmp;
5842   u8 intfc_address_length = 0;
5843   u8 is_add = 1;
5844   u8 l2_only = 0;
5845   u32 tx_sw_if_index;
5846   int tx_sw_if_index_set = 0;
5847
5848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5849     {
5850       if (unformat (i, "vrf %d", &inner_vrf_id))
5851         ;
5852       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5853                          &intfc_address, &tmp))
5854         intfc_address_length = tmp;
5855       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
5856         tx_sw_if_index_set = 1;
5857       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5858         tx_sw_if_index_set = 1;
5859       else if (unformat (i, "dst %U", unformat_ethernet_address,
5860                          dst_mac_address))
5861         dst_set = 1;
5862       else if (unformat (i, "l2-only"))
5863         l2_only = 1;
5864       else if (unformat (i, "del"))
5865         is_add = 0;
5866       else
5867         {
5868           clib_warning ("parse error '%U'", format_unformat_error, i);
5869           return -99;
5870         }
5871     }
5872
5873   if (!dst_set)
5874     {
5875       errmsg ("dst (mac address) not set\n");
5876       return -99;
5877     }
5878   if (!tx_sw_if_index_set)
5879     {
5880       errmsg ("tx-intfc not set\n");
5881       return -99;
5882     }
5883
5884   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5885
5886   mp->vrf_id = ntohl (inner_vrf_id);
5887   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
5888   mp->adj_address_length = intfc_address_length;
5889   clib_memcpy (mp->dst_mac_address, dst_mac_address,
5890                sizeof (dst_mac_address));
5891   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5892   mp->l2_only = l2_only;
5893   mp->is_add = is_add;
5894
5895   S;
5896   W;
5897   /* NOTREACHED */
5898   return 0;
5899 }
5900
5901 static int
5902 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5903 {
5904   unformat_input_t *i = vam->input;
5905   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5906   f64 timeout;
5907   u32 inner_vrf_id = 0;
5908   u32 outer_vrf_id = 0;
5909   ip4_address_t adj_address;
5910   int adj_address_set = 0;
5911   ip4_address_t next_hop_address;
5912   int next_hop_address_set = 0;
5913   u32 tmp;
5914   u8 adj_address_length = 0;
5915   u8 l2_only = 0;
5916   u8 is_add = 1;
5917   u32 resolve_attempts = 5;
5918   u8 resolve_if_needed = 1;
5919
5920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5921     {
5922       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5923         ;
5924       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5925         ;
5926       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5927                          &adj_address, &tmp))
5928         {
5929           adj_address_length = tmp;
5930           adj_address_set = 1;
5931         }
5932       else if (unformat (i, "next-hop %U", unformat_ip4_address,
5933                          &next_hop_address))
5934         next_hop_address_set = 1;
5935       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5936         ;
5937       else if (unformat (i, "resolve-if-needed %d", &tmp))
5938         resolve_if_needed = tmp;
5939       else if (unformat (i, "l2-only"))
5940         l2_only = 1;
5941       else if (unformat (i, "del"))
5942         is_add = 0;
5943       else
5944         {
5945           clib_warning ("parse error '%U'", format_unformat_error, i);
5946           return -99;
5947         }
5948     }
5949
5950   if (!adj_address_set)
5951     {
5952       errmsg ("adjacency address/mask not set\n");
5953       return -99;
5954     }
5955   if (!next_hop_address_set)
5956     {
5957       errmsg ("ip4 next hop address (in outer fib) not set\n");
5958       return -99;
5959     }
5960
5961   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
5962
5963   mp->inner_vrf_id = ntohl (inner_vrf_id);
5964   mp->outer_vrf_id = ntohl (outer_vrf_id);
5965   mp->resolve_attempts = ntohl (resolve_attempts);
5966   mp->resolve_if_needed = resolve_if_needed;
5967   mp->is_add = is_add;
5968   mp->l2_only = l2_only;
5969   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
5970   mp->adj_address_length = adj_address_length;
5971   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
5972                sizeof (next_hop_address));
5973
5974   S;
5975   W;
5976   /* NOTREACHED */
5977   return 0;
5978 }
5979
5980 static int
5981 api_sw_interface_set_unnumbered (vat_main_t * vam)
5982 {
5983   unformat_input_t *i = vam->input;
5984   vl_api_sw_interface_set_unnumbered_t *mp;
5985   f64 timeout;
5986   u32 sw_if_index;
5987   u32 unnum_sw_index = ~0;
5988   u8 is_add = 1;
5989   u8 sw_if_index_set = 0;
5990
5991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5992     {
5993       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5994         sw_if_index_set = 1;
5995       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5996         sw_if_index_set = 1;
5997       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
5998         ;
5999       else if (unformat (i, "del"))
6000         is_add = 0;
6001       else
6002         {
6003           clib_warning ("parse error '%U'", format_unformat_error, i);
6004           return -99;
6005         }
6006     }
6007
6008   if (sw_if_index_set == 0)
6009     {
6010       errmsg ("missing interface name or sw_if_index\n");
6011       return -99;
6012     }
6013
6014   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6015
6016   mp->sw_if_index = ntohl (sw_if_index);
6017   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6018   mp->is_add = is_add;
6019
6020   S;
6021   W;
6022   /* NOTREACHED */
6023   return 0;
6024 }
6025
6026 static int
6027 api_ip_neighbor_add_del (vat_main_t * vam)
6028 {
6029   unformat_input_t *i = vam->input;
6030   vl_api_ip_neighbor_add_del_t *mp;
6031   f64 timeout;
6032   u32 sw_if_index;
6033   u8 sw_if_index_set = 0;
6034   u32 vrf_id = 0;
6035   u8 is_add = 1;
6036   u8 is_static = 0;
6037   u8 mac_address[6];
6038   u8 mac_set = 0;
6039   u8 v4_address_set = 0;
6040   u8 v6_address_set = 0;
6041   ip4_address_t v4address;
6042   ip6_address_t v6address;
6043
6044   memset (mac_address, 0, sizeof (mac_address));
6045
6046   /* Parse args required to build the message */
6047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6048     {
6049       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6050         {
6051           mac_set = 1;
6052         }
6053       else if (unformat (i, "del"))
6054         is_add = 0;
6055       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6056         sw_if_index_set = 1;
6057       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6058         sw_if_index_set = 1;
6059       else if (unformat (i, "is_static"))
6060         is_static = 1;
6061       else if (unformat (i, "vrf %d", &vrf_id))
6062         ;
6063       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6064         v4_address_set = 1;
6065       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6066         v6_address_set = 1;
6067       else
6068         {
6069           clib_warning ("parse error '%U'", format_unformat_error, i);
6070           return -99;
6071         }
6072     }
6073
6074   if (sw_if_index_set == 0)
6075     {
6076       errmsg ("missing interface name or sw_if_index\n");
6077       return -99;
6078     }
6079   if (v4_address_set && v6_address_set)
6080     {
6081       errmsg ("both v4 and v6 addresses set\n");
6082       return -99;
6083     }
6084   if (!v4_address_set && !v6_address_set)
6085     {
6086       errmsg ("no address set\n");
6087       return -99;
6088     }
6089
6090   /* Construct the API message */
6091   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6092
6093   mp->sw_if_index = ntohl (sw_if_index);
6094   mp->is_add = is_add;
6095   mp->vrf_id = ntohl (vrf_id);
6096   mp->is_static = is_static;
6097   if (mac_set)
6098     clib_memcpy (mp->mac_address, mac_address, 6);
6099   if (v6_address_set)
6100     {
6101       mp->is_ipv6 = 1;
6102       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6103     }
6104   else
6105     {
6106       /* mp->is_ipv6 = 0; via memset in M macro above */
6107       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6108     }
6109
6110   /* send it... */
6111   S;
6112
6113   /* Wait for a reply, return good/bad news  */
6114   W;
6115
6116   /* NOTREACHED */
6117   return 0;
6118 }
6119
6120 static int
6121 api_reset_vrf (vat_main_t * vam)
6122 {
6123   unformat_input_t *i = vam->input;
6124   vl_api_reset_vrf_t *mp;
6125   f64 timeout;
6126   u32 vrf_id = 0;
6127   u8 is_ipv6 = 0;
6128   u8 vrf_id_set = 0;
6129
6130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6131     {
6132       if (unformat (i, "vrf %d", &vrf_id))
6133         vrf_id_set = 1;
6134       else if (unformat (i, "ipv6"))
6135         is_ipv6 = 1;
6136       else
6137         {
6138           clib_warning ("parse error '%U'", format_unformat_error, i);
6139           return -99;
6140         }
6141     }
6142
6143   if (vrf_id_set == 0)
6144     {
6145       errmsg ("missing vrf id\n");
6146       return -99;
6147     }
6148
6149   M (RESET_VRF, reset_vrf);
6150
6151   mp->vrf_id = ntohl (vrf_id);
6152   mp->is_ipv6 = is_ipv6;
6153
6154   S;
6155   W;
6156   /* NOTREACHED */
6157   return 0;
6158 }
6159
6160 static int
6161 api_create_vlan_subif (vat_main_t * vam)
6162 {
6163   unformat_input_t *i = vam->input;
6164   vl_api_create_vlan_subif_t *mp;
6165   f64 timeout;
6166   u32 sw_if_index;
6167   u8 sw_if_index_set = 0;
6168   u32 vlan_id;
6169   u8 vlan_id_set = 0;
6170
6171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6172     {
6173       if (unformat (i, "sw_if_index %d", &sw_if_index))
6174         sw_if_index_set = 1;
6175       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6176         sw_if_index_set = 1;
6177       else if (unformat (i, "vlan %d", &vlan_id))
6178         vlan_id_set = 1;
6179       else
6180         {
6181           clib_warning ("parse error '%U'", format_unformat_error, i);
6182           return -99;
6183         }
6184     }
6185
6186   if (sw_if_index_set == 0)
6187     {
6188       errmsg ("missing interface name or sw_if_index\n");
6189       return -99;
6190     }
6191
6192   if (vlan_id_set == 0)
6193     {
6194       errmsg ("missing vlan_id\n");
6195       return -99;
6196     }
6197   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6198
6199   mp->sw_if_index = ntohl (sw_if_index);
6200   mp->vlan_id = ntohl (vlan_id);
6201
6202   S;
6203   W;
6204   /* NOTREACHED */
6205   return 0;
6206 }
6207
6208 #define foreach_create_subif_bit                \
6209 _(no_tags)                                      \
6210 _(one_tag)                                      \
6211 _(two_tags)                                     \
6212 _(dot1ad)                                       \
6213 _(exact_match)                                  \
6214 _(default_sub)                                  \
6215 _(outer_vlan_id_any)                            \
6216 _(inner_vlan_id_any)
6217
6218 static int
6219 api_create_subif (vat_main_t * vam)
6220 {
6221   unformat_input_t *i = vam->input;
6222   vl_api_create_subif_t *mp;
6223   f64 timeout;
6224   u32 sw_if_index;
6225   u8 sw_if_index_set = 0;
6226   u32 sub_id;
6227   u8 sub_id_set = 0;
6228   u32 no_tags = 0;
6229   u32 one_tag = 0;
6230   u32 two_tags = 0;
6231   u32 dot1ad = 0;
6232   u32 exact_match = 0;
6233   u32 default_sub = 0;
6234   u32 outer_vlan_id_any = 0;
6235   u32 inner_vlan_id_any = 0;
6236   u32 tmp;
6237   u16 outer_vlan_id = 0;
6238   u16 inner_vlan_id = 0;
6239
6240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6241     {
6242       if (unformat (i, "sw_if_index %d", &sw_if_index))
6243         sw_if_index_set = 1;
6244       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6245         sw_if_index_set = 1;
6246       else if (unformat (i, "sub_id %d", &sub_id))
6247         sub_id_set = 1;
6248       else if (unformat (i, "outer_vlan_id %d", &tmp))
6249         outer_vlan_id = tmp;
6250       else if (unformat (i, "inner_vlan_id %d", &tmp))
6251         inner_vlan_id = tmp;
6252
6253 #define _(a) else if (unformat (i, #a)) a = 1 ;
6254       foreach_create_subif_bit
6255 #undef _
6256         else
6257         {
6258           clib_warning ("parse error '%U'", format_unformat_error, i);
6259           return -99;
6260         }
6261     }
6262
6263   if (sw_if_index_set == 0)
6264     {
6265       errmsg ("missing interface name or sw_if_index\n");
6266       return -99;
6267     }
6268
6269   if (sub_id_set == 0)
6270     {
6271       errmsg ("missing sub_id\n");
6272       return -99;
6273     }
6274   M (CREATE_SUBIF, create_subif);
6275
6276   mp->sw_if_index = ntohl (sw_if_index);
6277   mp->sub_id = ntohl (sub_id);
6278
6279 #define _(a) mp->a = a;
6280   foreach_create_subif_bit;
6281 #undef _
6282
6283   mp->outer_vlan_id = ntohs (outer_vlan_id);
6284   mp->inner_vlan_id = ntohs (inner_vlan_id);
6285
6286   S;
6287   W;
6288   /* NOTREACHED */
6289   return 0;
6290 }
6291
6292 static int
6293 api_oam_add_del (vat_main_t * vam)
6294 {
6295   unformat_input_t *i = vam->input;
6296   vl_api_oam_add_del_t *mp;
6297   f64 timeout;
6298   u32 vrf_id = 0;
6299   u8 is_add = 1;
6300   ip4_address_t src, dst;
6301   u8 src_set = 0;
6302   u8 dst_set = 0;
6303
6304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6305     {
6306       if (unformat (i, "vrf %d", &vrf_id))
6307         ;
6308       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6309         src_set = 1;
6310       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6311         dst_set = 1;
6312       else if (unformat (i, "del"))
6313         is_add = 0;
6314       else
6315         {
6316           clib_warning ("parse error '%U'", format_unformat_error, i);
6317           return -99;
6318         }
6319     }
6320
6321   if (src_set == 0)
6322     {
6323       errmsg ("missing src addr\n");
6324       return -99;
6325     }
6326
6327   if (dst_set == 0)
6328     {
6329       errmsg ("missing dst addr\n");
6330       return -99;
6331     }
6332
6333   M (OAM_ADD_DEL, oam_add_del);
6334
6335   mp->vrf_id = ntohl (vrf_id);
6336   mp->is_add = is_add;
6337   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6338   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6339
6340   S;
6341   W;
6342   /* NOTREACHED */
6343   return 0;
6344 }
6345
6346 static int
6347 api_reset_fib (vat_main_t * vam)
6348 {
6349   unformat_input_t *i = vam->input;
6350   vl_api_reset_fib_t *mp;
6351   f64 timeout;
6352   u32 vrf_id = 0;
6353   u8 is_ipv6 = 0;
6354   u8 vrf_id_set = 0;
6355
6356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6357     {
6358       if (unformat (i, "vrf %d", &vrf_id))
6359         vrf_id_set = 1;
6360       else if (unformat (i, "ipv6"))
6361         is_ipv6 = 1;
6362       else
6363         {
6364           clib_warning ("parse error '%U'", format_unformat_error, i);
6365           return -99;
6366         }
6367     }
6368
6369   if (vrf_id_set == 0)
6370     {
6371       errmsg ("missing vrf id\n");
6372       return -99;
6373     }
6374
6375   M (RESET_FIB, reset_fib);
6376
6377   mp->vrf_id = ntohl (vrf_id);
6378   mp->is_ipv6 = is_ipv6;
6379
6380   S;
6381   W;
6382   /* NOTREACHED */
6383   return 0;
6384 }
6385
6386 static int
6387 api_dhcp_proxy_config (vat_main_t * vam)
6388 {
6389   unformat_input_t *i = vam->input;
6390   vl_api_dhcp_proxy_config_t *mp;
6391   f64 timeout;
6392   u32 vrf_id = 0;
6393   u8 is_add = 1;
6394   u8 insert_cid = 1;
6395   u8 v4_address_set = 0;
6396   u8 v6_address_set = 0;
6397   ip4_address_t v4address;
6398   ip6_address_t v6address;
6399   u8 v4_src_address_set = 0;
6400   u8 v6_src_address_set = 0;
6401   ip4_address_t v4srcaddress;
6402   ip6_address_t v6srcaddress;
6403
6404   /* Parse args required to build the message */
6405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6406     {
6407       if (unformat (i, "del"))
6408         is_add = 0;
6409       else if (unformat (i, "vrf %d", &vrf_id))
6410         ;
6411       else if (unformat (i, "insert-cid %d", &insert_cid))
6412         ;
6413       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6414         v4_address_set = 1;
6415       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6416         v6_address_set = 1;
6417       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6418         v4_src_address_set = 1;
6419       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6420         v6_src_address_set = 1;
6421       else
6422         break;
6423     }
6424
6425   if (v4_address_set && v6_address_set)
6426     {
6427       errmsg ("both v4 and v6 server addresses set\n");
6428       return -99;
6429     }
6430   if (!v4_address_set && !v6_address_set)
6431     {
6432       errmsg ("no server addresses set\n");
6433       return -99;
6434     }
6435
6436   if (v4_src_address_set && v6_src_address_set)
6437     {
6438       errmsg ("both v4 and v6  src addresses set\n");
6439       return -99;
6440     }
6441   if (!v4_src_address_set && !v6_src_address_set)
6442     {
6443       errmsg ("no src addresses set\n");
6444       return -99;
6445     }
6446
6447   if (!(v4_src_address_set && v4_address_set) &&
6448       !(v6_src_address_set && v6_address_set))
6449     {
6450       errmsg ("no matching server and src addresses set\n");
6451       return -99;
6452     }
6453
6454   /* Construct the API message */
6455   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6456
6457   mp->insert_circuit_id = insert_cid;
6458   mp->is_add = is_add;
6459   mp->vrf_id = ntohl (vrf_id);
6460   if (v6_address_set)
6461     {
6462       mp->is_ipv6 = 1;
6463       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6464       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6465     }
6466   else
6467     {
6468       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6469       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6470     }
6471
6472   /* send it... */
6473   S;
6474
6475   /* Wait for a reply, return good/bad news  */
6476   W;
6477   /* NOTREACHED */
6478   return 0;
6479 }
6480
6481 static int
6482 api_dhcp_proxy_config_2 (vat_main_t * vam)
6483 {
6484   unformat_input_t *i = vam->input;
6485   vl_api_dhcp_proxy_config_2_t *mp;
6486   f64 timeout;
6487   u32 rx_vrf_id = 0;
6488   u32 server_vrf_id = 0;
6489   u8 is_add = 1;
6490   u8 insert_cid = 1;
6491   u8 v4_address_set = 0;
6492   u8 v6_address_set = 0;
6493   ip4_address_t v4address;
6494   ip6_address_t v6address;
6495   u8 v4_src_address_set = 0;
6496   u8 v6_src_address_set = 0;
6497   ip4_address_t v4srcaddress;
6498   ip6_address_t v6srcaddress;
6499
6500   /* Parse args required to build the message */
6501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6502     {
6503       if (unformat (i, "del"))
6504         is_add = 0;
6505       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6506         ;
6507       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6508         ;
6509       else if (unformat (i, "insert-cid %d", &insert_cid))
6510         ;
6511       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6512         v4_address_set = 1;
6513       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6514         v6_address_set = 1;
6515       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6516         v4_src_address_set = 1;
6517       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6518         v6_src_address_set = 1;
6519       else
6520         break;
6521     }
6522
6523   if (v4_address_set && v6_address_set)
6524     {
6525       errmsg ("both v4 and v6 server addresses set\n");
6526       return -99;
6527     }
6528   if (!v4_address_set && !v6_address_set)
6529     {
6530       errmsg ("no server addresses set\n");
6531       return -99;
6532     }
6533
6534   if (v4_src_address_set && v6_src_address_set)
6535     {
6536       errmsg ("both v4 and v6  src addresses set\n");
6537       return -99;
6538     }
6539   if (!v4_src_address_set && !v6_src_address_set)
6540     {
6541       errmsg ("no src addresses set\n");
6542       return -99;
6543     }
6544
6545   if (!(v4_src_address_set && v4_address_set) &&
6546       !(v6_src_address_set && v6_address_set))
6547     {
6548       errmsg ("no matching server and src addresses set\n");
6549       return -99;
6550     }
6551
6552   /* Construct the API message */
6553   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6554
6555   mp->insert_circuit_id = insert_cid;
6556   mp->is_add = is_add;
6557   mp->rx_vrf_id = ntohl (rx_vrf_id);
6558   mp->server_vrf_id = ntohl (server_vrf_id);
6559   if (v6_address_set)
6560     {
6561       mp->is_ipv6 = 1;
6562       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6563       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6564     }
6565   else
6566     {
6567       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6568       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6569     }
6570
6571   /* send it... */
6572   S;
6573
6574   /* Wait for a reply, return good/bad news  */
6575   W;
6576   /* NOTREACHED */
6577   return 0;
6578 }
6579
6580 static int
6581 api_dhcp_proxy_set_vss (vat_main_t * vam)
6582 {
6583   unformat_input_t *i = vam->input;
6584   vl_api_dhcp_proxy_set_vss_t *mp;
6585   f64 timeout;
6586   u8 is_ipv6 = 0;
6587   u8 is_add = 1;
6588   u32 tbl_id;
6589   u8 tbl_id_set = 0;
6590   u32 oui;
6591   u8 oui_set = 0;
6592   u32 fib_id;
6593   u8 fib_id_set = 0;
6594
6595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6596     {
6597       if (unformat (i, "tbl_id %d", &tbl_id))
6598         tbl_id_set = 1;
6599       if (unformat (i, "fib_id %d", &fib_id))
6600         fib_id_set = 1;
6601       if (unformat (i, "oui %d", &oui))
6602         oui_set = 1;
6603       else if (unformat (i, "ipv6"))
6604         is_ipv6 = 1;
6605       else if (unformat (i, "del"))
6606         is_add = 0;
6607       else
6608         {
6609           clib_warning ("parse error '%U'", format_unformat_error, i);
6610           return -99;
6611         }
6612     }
6613
6614   if (tbl_id_set == 0)
6615     {
6616       errmsg ("missing tbl id\n");
6617       return -99;
6618     }
6619
6620   if (fib_id_set == 0)
6621     {
6622       errmsg ("missing fib id\n");
6623       return -99;
6624     }
6625   if (oui_set == 0)
6626     {
6627       errmsg ("missing oui\n");
6628       return -99;
6629     }
6630
6631   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6632   mp->tbl_id = ntohl (tbl_id);
6633   mp->fib_id = ntohl (fib_id);
6634   mp->oui = ntohl (oui);
6635   mp->is_ipv6 = is_ipv6;
6636   mp->is_add = is_add;
6637
6638   S;
6639   W;
6640   /* NOTREACHED */
6641   return 0;
6642 }
6643
6644 static int
6645 api_dhcp_client_config (vat_main_t * vam)
6646 {
6647   unformat_input_t *i = vam->input;
6648   vl_api_dhcp_client_config_t *mp;
6649   f64 timeout;
6650   u32 sw_if_index;
6651   u8 sw_if_index_set = 0;
6652   u8 is_add = 1;
6653   u8 *hostname = 0;
6654   u8 disable_event = 0;
6655
6656   /* Parse args required to build the message */
6657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6658     {
6659       if (unformat (i, "del"))
6660         is_add = 0;
6661       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6662         sw_if_index_set = 1;
6663       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6664         sw_if_index_set = 1;
6665       else if (unformat (i, "hostname %s", &hostname))
6666         ;
6667       else if (unformat (i, "disable_event"))
6668         disable_event = 1;
6669       else
6670         break;
6671     }
6672
6673   if (sw_if_index_set == 0)
6674     {
6675       errmsg ("missing interface name or sw_if_index\n");
6676       return -99;
6677     }
6678
6679   if (vec_len (hostname) > 63)
6680     {
6681       errmsg ("hostname too long\n");
6682     }
6683   vec_add1 (hostname, 0);
6684
6685   /* Construct the API message */
6686   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6687
6688   mp->sw_if_index = ntohl (sw_if_index);
6689   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6690   vec_free (hostname);
6691   mp->is_add = is_add;
6692   mp->want_dhcp_event = disable_event ? 0 : 1;
6693   mp->pid = getpid ();
6694
6695   /* send it... */
6696   S;
6697
6698   /* Wait for a reply, return good/bad news  */
6699   W;
6700   /* NOTREACHED */
6701   return 0;
6702 }
6703
6704 static int
6705 api_set_ip_flow_hash (vat_main_t * vam)
6706 {
6707   unformat_input_t *i = vam->input;
6708   vl_api_set_ip_flow_hash_t *mp;
6709   f64 timeout;
6710   u32 vrf_id = 0;
6711   u8 is_ipv6 = 0;
6712   u8 vrf_id_set = 0;
6713   u8 src = 0;
6714   u8 dst = 0;
6715   u8 sport = 0;
6716   u8 dport = 0;
6717   u8 proto = 0;
6718   u8 reverse = 0;
6719
6720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6721     {
6722       if (unformat (i, "vrf %d", &vrf_id))
6723         vrf_id_set = 1;
6724       else if (unformat (i, "ipv6"))
6725         is_ipv6 = 1;
6726       else if (unformat (i, "src"))
6727         src = 1;
6728       else if (unformat (i, "dst"))
6729         dst = 1;
6730       else if (unformat (i, "sport"))
6731         sport = 1;
6732       else if (unformat (i, "dport"))
6733         dport = 1;
6734       else if (unformat (i, "proto"))
6735         proto = 1;
6736       else if (unformat (i, "reverse"))
6737         reverse = 1;
6738
6739       else
6740         {
6741           clib_warning ("parse error '%U'", format_unformat_error, i);
6742           return -99;
6743         }
6744     }
6745
6746   if (vrf_id_set == 0)
6747     {
6748       errmsg ("missing vrf id\n");
6749       return -99;
6750     }
6751
6752   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
6753   mp->src = src;
6754   mp->dst = dst;
6755   mp->sport = sport;
6756   mp->dport = dport;
6757   mp->proto = proto;
6758   mp->reverse = reverse;
6759   mp->vrf_id = ntohl (vrf_id);
6760   mp->is_ipv6 = is_ipv6;
6761
6762   S;
6763   W;
6764   /* NOTREACHED */
6765   return 0;
6766 }
6767
6768 static int
6769 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6770 {
6771   unformat_input_t *i = vam->input;
6772   vl_api_sw_interface_ip6_enable_disable_t *mp;
6773   f64 timeout;
6774   u32 sw_if_index;
6775   u8 sw_if_index_set = 0;
6776   u8 enable = 0;
6777
6778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6779     {
6780       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6781         sw_if_index_set = 1;
6782       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6783         sw_if_index_set = 1;
6784       else if (unformat (i, "enable"))
6785         enable = 1;
6786       else if (unformat (i, "disable"))
6787         enable = 0;
6788       else
6789         {
6790           clib_warning ("parse error '%U'", format_unformat_error, i);
6791           return -99;
6792         }
6793     }
6794
6795   if (sw_if_index_set == 0)
6796     {
6797       errmsg ("missing interface name or sw_if_index\n");
6798       return -99;
6799     }
6800
6801   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6802
6803   mp->sw_if_index = ntohl (sw_if_index);
6804   mp->enable = enable;
6805
6806   S;
6807   W;
6808   /* NOTREACHED */
6809   return 0;
6810 }
6811
6812 static int
6813 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6814 {
6815   unformat_input_t *i = vam->input;
6816   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6817   f64 timeout;
6818   u32 sw_if_index;
6819   u8 sw_if_index_set = 0;
6820   u32 address_length = 0;
6821   u8 v6_address_set = 0;
6822   ip6_address_t v6address;
6823
6824   /* Parse args required to build the message */
6825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6826     {
6827       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6828         sw_if_index_set = 1;
6829       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6830         sw_if_index_set = 1;
6831       else if (unformat (i, "%U/%d",
6832                          unformat_ip6_address, &v6address, &address_length))
6833         v6_address_set = 1;
6834       else
6835         break;
6836     }
6837
6838   if (sw_if_index_set == 0)
6839     {
6840       errmsg ("missing interface name or sw_if_index\n");
6841       return -99;
6842     }
6843   if (!v6_address_set)
6844     {
6845       errmsg ("no address set\n");
6846       return -99;
6847     }
6848
6849   /* Construct the API message */
6850   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
6851      sw_interface_ip6_set_link_local_address);
6852
6853   mp->sw_if_index = ntohl (sw_if_index);
6854   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6855   mp->address_length = address_length;
6856
6857   /* send it... */
6858   S;
6859
6860   /* Wait for a reply, return good/bad news  */
6861   W;
6862
6863   /* NOTREACHED */
6864   return 0;
6865 }
6866
6867
6868 static int
6869 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6870 {
6871   unformat_input_t *i = vam->input;
6872   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6873   f64 timeout;
6874   u32 sw_if_index;
6875   u8 sw_if_index_set = 0;
6876   u32 address_length = 0;
6877   u8 v6_address_set = 0;
6878   ip6_address_t v6address;
6879   u8 use_default = 0;
6880   u8 no_advertise = 0;
6881   u8 off_link = 0;
6882   u8 no_autoconfig = 0;
6883   u8 no_onlink = 0;
6884   u8 is_no = 0;
6885   u32 val_lifetime = 0;
6886   u32 pref_lifetime = 0;
6887
6888   /* Parse args required to build the message */
6889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6890     {
6891       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6892         sw_if_index_set = 1;
6893       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6894         sw_if_index_set = 1;
6895       else if (unformat (i, "%U/%d",
6896                          unformat_ip6_address, &v6address, &address_length))
6897         v6_address_set = 1;
6898       else if (unformat (i, "val_life %d", &val_lifetime))
6899         ;
6900       else if (unformat (i, "pref_life %d", &pref_lifetime))
6901         ;
6902       else if (unformat (i, "def"))
6903         use_default = 1;
6904       else if (unformat (i, "noadv"))
6905         no_advertise = 1;
6906       else if (unformat (i, "offl"))
6907         off_link = 1;
6908       else if (unformat (i, "noauto"))
6909         no_autoconfig = 1;
6910       else if (unformat (i, "nolink"))
6911         no_onlink = 1;
6912       else if (unformat (i, "isno"))
6913         is_no = 1;
6914       else
6915         {
6916           clib_warning ("parse error '%U'", format_unformat_error, i);
6917           return -99;
6918         }
6919     }
6920
6921   if (sw_if_index_set == 0)
6922     {
6923       errmsg ("missing interface name or sw_if_index\n");
6924       return -99;
6925     }
6926   if (!v6_address_set)
6927     {
6928       errmsg ("no address set\n");
6929       return -99;
6930     }
6931
6932   /* Construct the API message */
6933   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6934
6935   mp->sw_if_index = ntohl (sw_if_index);
6936   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6937   mp->address_length = address_length;
6938   mp->use_default = use_default;
6939   mp->no_advertise = no_advertise;
6940   mp->off_link = off_link;
6941   mp->no_autoconfig = no_autoconfig;
6942   mp->no_onlink = no_onlink;
6943   mp->is_no = is_no;
6944   mp->val_lifetime = ntohl (val_lifetime);
6945   mp->pref_lifetime = ntohl (pref_lifetime);
6946
6947   /* send it... */
6948   S;
6949
6950   /* Wait for a reply, return good/bad news  */
6951   W;
6952
6953   /* NOTREACHED */
6954   return 0;
6955 }
6956
6957 static int
6958 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
6959 {
6960   unformat_input_t *i = vam->input;
6961   vl_api_sw_interface_ip6nd_ra_config_t *mp;
6962   f64 timeout;
6963   u32 sw_if_index;
6964   u8 sw_if_index_set = 0;
6965   u8 suppress = 0;
6966   u8 managed = 0;
6967   u8 other = 0;
6968   u8 ll_option = 0;
6969   u8 send_unicast = 0;
6970   u8 cease = 0;
6971   u8 is_no = 0;
6972   u8 default_router = 0;
6973   u32 max_interval = 0;
6974   u32 min_interval = 0;
6975   u32 lifetime = 0;
6976   u32 initial_count = 0;
6977   u32 initial_interval = 0;
6978
6979
6980   /* Parse args required to build the message */
6981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6982     {
6983       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6984         sw_if_index_set = 1;
6985       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6986         sw_if_index_set = 1;
6987       else if (unformat (i, "maxint %d", &max_interval))
6988         ;
6989       else if (unformat (i, "minint %d", &min_interval))
6990         ;
6991       else if (unformat (i, "life %d", &lifetime))
6992         ;
6993       else if (unformat (i, "count %d", &initial_count))
6994         ;
6995       else if (unformat (i, "interval %d", &initial_interval))
6996         ;
6997       else if (unformat (i, "suppress") || unformat (i, "surpress"))
6998         suppress = 1;
6999       else if (unformat (i, "managed"))
7000         managed = 1;
7001       else if (unformat (i, "other"))
7002         other = 1;
7003       else if (unformat (i, "ll"))
7004         ll_option = 1;
7005       else if (unformat (i, "send"))
7006         send_unicast = 1;
7007       else if (unformat (i, "cease"))
7008         cease = 1;
7009       else if (unformat (i, "isno"))
7010         is_no = 1;
7011       else if (unformat (i, "def"))
7012         default_router = 1;
7013       else
7014         {
7015           clib_warning ("parse error '%U'", format_unformat_error, i);
7016           return -99;
7017         }
7018     }
7019
7020   if (sw_if_index_set == 0)
7021     {
7022       errmsg ("missing interface name or sw_if_index\n");
7023       return -99;
7024     }
7025
7026   /* Construct the API message */
7027   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7028
7029   mp->sw_if_index = ntohl (sw_if_index);
7030   mp->max_interval = ntohl (max_interval);
7031   mp->min_interval = ntohl (min_interval);
7032   mp->lifetime = ntohl (lifetime);
7033   mp->initial_count = ntohl (initial_count);
7034   mp->initial_interval = ntohl (initial_interval);
7035   mp->suppress = suppress;
7036   mp->managed = managed;
7037   mp->other = other;
7038   mp->ll_option = ll_option;
7039   mp->send_unicast = send_unicast;
7040   mp->cease = cease;
7041   mp->is_no = is_no;
7042   mp->default_router = default_router;
7043
7044   /* send it... */
7045   S;
7046
7047   /* Wait for a reply, return good/bad news  */
7048   W;
7049
7050   /* NOTREACHED */
7051   return 0;
7052 }
7053
7054 static int
7055 api_set_arp_neighbor_limit (vat_main_t * vam)
7056 {
7057   unformat_input_t *i = vam->input;
7058   vl_api_set_arp_neighbor_limit_t *mp;
7059   f64 timeout;
7060   u32 arp_nbr_limit;
7061   u8 limit_set = 0;
7062   u8 is_ipv6 = 0;
7063
7064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7065     {
7066       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7067         limit_set = 1;
7068       else if (unformat (i, "ipv6"))
7069         is_ipv6 = 1;
7070       else
7071         {
7072           clib_warning ("parse error '%U'", format_unformat_error, i);
7073           return -99;
7074         }
7075     }
7076
7077   if (limit_set == 0)
7078     {
7079       errmsg ("missing limit value\n");
7080       return -99;
7081     }
7082
7083   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7084
7085   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7086   mp->is_ipv6 = is_ipv6;
7087
7088   S;
7089   W;
7090   /* NOTREACHED */
7091   return 0;
7092 }
7093
7094 static int
7095 api_l2_patch_add_del (vat_main_t * vam)
7096 {
7097   unformat_input_t *i = vam->input;
7098   vl_api_l2_patch_add_del_t *mp;
7099   f64 timeout;
7100   u32 rx_sw_if_index;
7101   u8 rx_sw_if_index_set = 0;
7102   u32 tx_sw_if_index;
7103   u8 tx_sw_if_index_set = 0;
7104   u8 is_add = 1;
7105
7106   /* Parse args required to build the message */
7107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7108     {
7109       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7110         rx_sw_if_index_set = 1;
7111       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7112         tx_sw_if_index_set = 1;
7113       else if (unformat (i, "rx"))
7114         {
7115           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7116             {
7117               if (unformat (i, "%U", unformat_sw_if_index, vam,
7118                             &rx_sw_if_index))
7119                 rx_sw_if_index_set = 1;
7120             }
7121           else
7122             break;
7123         }
7124       else if (unformat (i, "tx"))
7125         {
7126           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7127             {
7128               if (unformat (i, "%U", unformat_sw_if_index, vam,
7129                             &tx_sw_if_index))
7130                 tx_sw_if_index_set = 1;
7131             }
7132           else
7133             break;
7134         }
7135       else if (unformat (i, "del"))
7136         is_add = 0;
7137       else
7138         break;
7139     }
7140
7141   if (rx_sw_if_index_set == 0)
7142     {
7143       errmsg ("missing rx interface name or rx_sw_if_index\n");
7144       return -99;
7145     }
7146
7147   if (tx_sw_if_index_set == 0)
7148     {
7149       errmsg ("missing tx interface name or tx_sw_if_index\n");
7150       return -99;
7151     }
7152
7153   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7154
7155   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7156   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7157   mp->is_add = is_add;
7158
7159   S;
7160   W;
7161   /* NOTREACHED */
7162   return 0;
7163 }
7164
7165 static int
7166 api_trace_profile_add (vat_main_t * vam)
7167 {
7168   unformat_input_t *input = vam->input;
7169   vl_api_trace_profile_add_t *mp;
7170   f64 timeout;
7171   u32 id = 0;
7172   u32 trace_option_elts = 0;
7173   u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
7174   int has_pow_option = 0;
7175   int has_ppc_option = 0;
7176
7177   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7178     {
7179       if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
7180                     "trace-tsp %d node-id 0x%x app-data 0x%x",
7181                     &id, &trace_type, &trace_option_elts, &trace_tsp,
7182                     &node_id, &app_data))
7183         ;
7184       else if (unformat (input, "pow"))
7185         has_pow_option = 1;
7186       else if (unformat (input, "ppc encap"))
7187         has_ppc_option = PPC_ENCAP;
7188       else if (unformat (input, "ppc decap"))
7189         has_ppc_option = PPC_DECAP;
7190       else if (unformat (input, "ppc none"))
7191         has_ppc_option = PPC_NONE;
7192       else
7193         break;
7194     }
7195   M (TRACE_PROFILE_ADD, trace_profile_add);
7196   mp->id = htons (id);
7197   mp->trace_type = trace_type;
7198   mp->trace_num_elt = trace_option_elts;
7199   mp->trace_ppc = has_ppc_option;
7200   mp->trace_app_data = htonl (app_data);
7201   mp->pow_enable = has_pow_option;
7202   mp->trace_tsp = trace_tsp;
7203   mp->node_id = htonl (node_id);
7204
7205   S;
7206   W;
7207
7208   return (0);
7209
7210 }
7211
7212 static int
7213 api_trace_profile_apply (vat_main_t * vam)
7214 {
7215   unformat_input_t *input = vam->input;
7216   vl_api_trace_profile_apply_t *mp;
7217   f64 timeout;
7218   ip6_address_t addr;
7219   u32 mask_width = ~0;
7220   int is_add = 0;
7221   int is_pop = 0;
7222   int is_none = 0;
7223   u32 vrf_id = 0;
7224   u32 id = 0;
7225
7226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7227     {
7228       if (unformat (input, "%U/%d", unformat_ip6_address, &addr, &mask_width))
7229         ;
7230       else if (unformat (input, "id %d", &id))
7231         ;
7232       else if (unformat (input, "vrf-id %d", &vrf_id))
7233         ;
7234       else if (unformat (input, "add"))
7235         is_add = 1;
7236       else if (unformat (input, "pop"))
7237         is_pop = 1;
7238       else if (unformat (input, "none"))
7239         is_none = 1;
7240       else
7241         break;
7242     }
7243
7244   if ((is_add + is_pop + is_none) != 1)
7245     {
7246       errmsg ("One of (add, pop, none) required");
7247       return -99;
7248     }
7249   if (mask_width == ~0)
7250     {
7251       errmsg ("<address>/<mask-width> required");
7252       return -99;
7253     }
7254   M (TRACE_PROFILE_APPLY, trace_profile_apply);
7255   clib_memcpy (mp->dest_ipv6, &addr, sizeof (mp->dest_ipv6));
7256   mp->id = htons (id);
7257   mp->prefix_length = htonl (mask_width);
7258   mp->vrf_id = htonl (vrf_id);
7259   if (is_add)
7260     mp->trace_op = IOAM_HBYH_ADD;
7261   else if (is_pop)
7262     mp->trace_op = IOAM_HBYH_POP;
7263   else
7264     mp->trace_op = IOAM_HBYH_MOD;
7265
7266   if (is_none)
7267     mp->enable = 0;
7268   else
7269     mp->enable = 1;
7270
7271   S;
7272   W;
7273
7274   return 0;
7275 }
7276
7277 static int
7278 api_trace_profile_del (vat_main_t * vam)
7279 {
7280   vl_api_trace_profile_del_t *mp;
7281   f64 timeout;
7282
7283   M (TRACE_PROFILE_DEL, trace_profile_del);
7284   S;
7285   W;
7286   return 0;
7287 }
7288
7289 static int
7290 api_sr_tunnel_add_del (vat_main_t * vam)
7291 {
7292   unformat_input_t *i = vam->input;
7293   vl_api_sr_tunnel_add_del_t *mp;
7294   f64 timeout;
7295   int is_del = 0;
7296   int pl_index;
7297   ip6_address_t src_address;
7298   int src_address_set = 0;
7299   ip6_address_t dst_address;
7300   u32 dst_mask_width;
7301   int dst_address_set = 0;
7302   u16 flags = 0;
7303   u32 rx_table_id = 0;
7304   u32 tx_table_id = 0;
7305   ip6_address_t *segments = 0;
7306   ip6_address_t *this_seg;
7307   ip6_address_t *tags = 0;
7308   ip6_address_t *this_tag;
7309   ip6_address_t next_address, tag;
7310   u8 *name = 0;
7311   u8 *policy_name = 0;
7312
7313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7314     {
7315       if (unformat (i, "del"))
7316         is_del = 1;
7317       else if (unformat (i, "name %s", &name))
7318         ;
7319       else if (unformat (i, "policy %s", &policy_name))
7320         ;
7321       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7322         ;
7323       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7324         ;
7325       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7326         src_address_set = 1;
7327       else if (unformat (i, "dst %U/%d",
7328                          unformat_ip6_address, &dst_address, &dst_mask_width))
7329         dst_address_set = 1;
7330       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7331         {
7332           vec_add2 (segments, this_seg, 1);
7333           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7334                        sizeof (*this_seg));
7335         }
7336       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7337         {
7338           vec_add2 (tags, this_tag, 1);
7339           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7340         }
7341       else if (unformat (i, "clean"))
7342         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7343       else if (unformat (i, "protected"))
7344         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7345       else if (unformat (i, "InPE %d", &pl_index))
7346         {
7347           if (pl_index <= 0 || pl_index > 4)
7348             {
7349             pl_index_range_error:
7350               errmsg ("pl index %d out of range\n", pl_index);
7351               return -99;
7352             }
7353           flags |=
7354             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7355         }
7356       else if (unformat (i, "EgPE %d", &pl_index))
7357         {
7358           if (pl_index <= 0 || pl_index > 4)
7359             goto pl_index_range_error;
7360           flags |=
7361             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7362         }
7363       else if (unformat (i, "OrgSrc %d", &pl_index))
7364         {
7365           if (pl_index <= 0 || pl_index > 4)
7366             goto pl_index_range_error;
7367           flags |=
7368             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7369         }
7370       else
7371         break;
7372     }
7373
7374   if (!src_address_set)
7375     {
7376       errmsg ("src address required\n");
7377       return -99;
7378     }
7379
7380   if (!dst_address_set)
7381     {
7382       errmsg ("dst address required\n");
7383       return -99;
7384     }
7385
7386   if (!segments)
7387     {
7388       errmsg ("at least one sr segment required\n");
7389       return -99;
7390     }
7391
7392   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7393       vec_len (segments) * sizeof (ip6_address_t)
7394       + vec_len (tags) * sizeof (ip6_address_t));
7395
7396   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7397   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7398   mp->dst_mask_width = dst_mask_width;
7399   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7400   mp->n_segments = vec_len (segments);
7401   mp->n_tags = vec_len (tags);
7402   mp->is_add = is_del == 0;
7403   clib_memcpy (mp->segs_and_tags, segments,
7404                vec_len (segments) * sizeof (ip6_address_t));
7405   clib_memcpy (mp->segs_and_tags +
7406                vec_len (segments) * sizeof (ip6_address_t), tags,
7407                vec_len (tags) * sizeof (ip6_address_t));
7408
7409   mp->outer_vrf_id = ntohl (rx_table_id);
7410   mp->inner_vrf_id = ntohl (tx_table_id);
7411   memcpy (mp->name, name, vec_len (name));
7412   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7413
7414   vec_free (segments);
7415   vec_free (tags);
7416
7417   S;
7418   W;
7419   /* NOTREACHED */
7420 }
7421
7422 static int
7423 api_sr_policy_add_del (vat_main_t * vam)
7424 {
7425   unformat_input_t *input = vam->input;
7426   vl_api_sr_policy_add_del_t *mp;
7427   f64 timeout;
7428   int is_del = 0;
7429   u8 *name = 0;
7430   u8 *tunnel_name = 0;
7431   u8 **tunnel_names = 0;
7432
7433   int name_set = 0;
7434   int tunnel_set = 0;
7435   int j = 0;
7436   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7437   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7438
7439   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7440     {
7441       if (unformat (input, "del"))
7442         is_del = 1;
7443       else if (unformat (input, "name %s", &name))
7444         name_set = 1;
7445       else if (unformat (input, "tunnel %s", &tunnel_name))
7446         {
7447           if (tunnel_name)
7448             {
7449               vec_add1 (tunnel_names, tunnel_name);
7450               /* For serializer:
7451                  - length = #bytes to store in serial vector
7452                  - +1 = byte to store that length
7453                */
7454               tunnel_names_length += (vec_len (tunnel_name) + 1);
7455               tunnel_set = 1;
7456               tunnel_name = 0;
7457             }
7458         }
7459       else
7460         break;
7461     }
7462
7463   if (!name_set)
7464     {
7465       errmsg ("policy name required\n");
7466       return -99;
7467     }
7468
7469   if ((!tunnel_set) && (!is_del))
7470     {
7471       errmsg ("tunnel name required\n");
7472       return -99;
7473     }
7474
7475   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7476
7477
7478
7479   mp->is_add = !is_del;
7480
7481   memcpy (mp->name, name, vec_len (name));
7482   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7483   u8 *serial_orig = 0;
7484   vec_validate (serial_orig, tunnel_names_length);
7485   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7486   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7487
7488   for (j = 0; j < vec_len (tunnel_names); j++)
7489     {
7490       tun_name_len = vec_len (tunnel_names[j]);
7491       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7492       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7493       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7494       serial_orig += tun_name_len;      // Advance past the copy
7495     }
7496   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7497
7498   vec_free (tunnel_names);
7499   vec_free (tunnel_name);
7500
7501   S;
7502   W;
7503   /* NOTREACHED */
7504 }
7505
7506 static int
7507 api_sr_multicast_map_add_del (vat_main_t * vam)
7508 {
7509   unformat_input_t *input = vam->input;
7510   vl_api_sr_multicast_map_add_del_t *mp;
7511   f64 timeout;
7512   int is_del = 0;
7513   ip6_address_t multicast_address;
7514   u8 *policy_name = 0;
7515   int multicast_address_set = 0;
7516
7517   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7518     {
7519       if (unformat (input, "del"))
7520         is_del = 1;
7521       else
7522         if (unformat
7523             (input, "address %U", unformat_ip6_address, &multicast_address))
7524         multicast_address_set = 1;
7525       else if (unformat (input, "sr-policy %s", &policy_name))
7526         ;
7527       else
7528         break;
7529     }
7530
7531   if (!is_del && !policy_name)
7532     {
7533       errmsg ("sr-policy name required\n");
7534       return -99;
7535     }
7536
7537
7538   if (!multicast_address_set)
7539     {
7540       errmsg ("address required\n");
7541       return -99;
7542     }
7543
7544   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7545
7546   mp->is_add = !is_del;
7547   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7548   clib_memcpy (mp->multicast_address, &multicast_address,
7549                sizeof (mp->multicast_address));
7550
7551
7552   vec_free (policy_name);
7553
7554   S;
7555   W;
7556   /* NOTREACHED */
7557 }
7558
7559
7560 #define foreach_ip4_proto_field                 \
7561 _(src_address)                                  \
7562 _(dst_address)                                  \
7563 _(tos)                                          \
7564 _(length)                                       \
7565 _(fragment_id)                                  \
7566 _(ttl)                                          \
7567 _(protocol)                                     \
7568 _(checksum)
7569
7570 uword
7571 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7572 {
7573   u8 **maskp = va_arg (*args, u8 **);
7574   u8 *mask = 0;
7575   u8 found_something = 0;
7576   ip4_header_t *ip;
7577
7578 #define _(a) u8 a=0;
7579   foreach_ip4_proto_field;
7580 #undef _
7581   u8 version = 0;
7582   u8 hdr_length = 0;
7583
7584
7585   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7586     {
7587       if (unformat (input, "version"))
7588         version = 1;
7589       else if (unformat (input, "hdr_length"))
7590         hdr_length = 1;
7591       else if (unformat (input, "src"))
7592         src_address = 1;
7593       else if (unformat (input, "dst"))
7594         dst_address = 1;
7595       else if (unformat (input, "proto"))
7596         protocol = 1;
7597
7598 #define _(a) else if (unformat (input, #a)) a=1;
7599       foreach_ip4_proto_field
7600 #undef _
7601         else
7602         break;
7603     }
7604
7605 #define _(a) found_something += a;
7606   foreach_ip4_proto_field;
7607 #undef _
7608
7609   if (found_something == 0)
7610     return 0;
7611
7612   vec_validate (mask, sizeof (*ip) - 1);
7613
7614   ip = (ip4_header_t *) mask;
7615
7616 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7617   foreach_ip4_proto_field;
7618 #undef _
7619
7620   ip->ip_version_and_header_length = 0;
7621
7622   if (version)
7623     ip->ip_version_and_header_length |= 0xF0;
7624
7625   if (hdr_length)
7626     ip->ip_version_and_header_length |= 0x0F;
7627
7628   *maskp = mask;
7629   return 1;
7630 }
7631
7632 #define foreach_ip6_proto_field                 \
7633 _(src_address)                                  \
7634 _(dst_address)                                  \
7635 _(payload_length)                               \
7636 _(hop_limit)                                    \
7637 _(protocol)
7638
7639 uword
7640 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7641 {
7642   u8 **maskp = va_arg (*args, u8 **);
7643   u8 *mask = 0;
7644   u8 found_something = 0;
7645   ip6_header_t *ip;
7646   u32 ip_version_traffic_class_and_flow_label;
7647
7648 #define _(a) u8 a=0;
7649   foreach_ip6_proto_field;
7650 #undef _
7651   u8 version = 0;
7652   u8 traffic_class = 0;
7653   u8 flow_label = 0;
7654
7655   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7656     {
7657       if (unformat (input, "version"))
7658         version = 1;
7659       else if (unformat (input, "traffic-class"))
7660         traffic_class = 1;
7661       else if (unformat (input, "flow-label"))
7662         flow_label = 1;
7663       else if (unformat (input, "src"))
7664         src_address = 1;
7665       else if (unformat (input, "dst"))
7666         dst_address = 1;
7667       else if (unformat (input, "proto"))
7668         protocol = 1;
7669
7670 #define _(a) else if (unformat (input, #a)) a=1;
7671       foreach_ip6_proto_field
7672 #undef _
7673         else
7674         break;
7675     }
7676
7677 #define _(a) found_something += a;
7678   foreach_ip6_proto_field;
7679 #undef _
7680
7681   if (found_something == 0)
7682     return 0;
7683
7684   vec_validate (mask, sizeof (*ip) - 1);
7685
7686   ip = (ip6_header_t *) mask;
7687
7688 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7689   foreach_ip6_proto_field;
7690 #undef _
7691
7692   ip_version_traffic_class_and_flow_label = 0;
7693
7694   if (version)
7695     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7696
7697   if (traffic_class)
7698     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7699
7700   if (flow_label)
7701     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7702
7703   ip->ip_version_traffic_class_and_flow_label =
7704     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7705
7706   *maskp = mask;
7707   return 1;
7708 }
7709
7710 uword
7711 unformat_l3_mask (unformat_input_t * input, va_list * args)
7712 {
7713   u8 **maskp = va_arg (*args, u8 **);
7714
7715   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7716     {
7717       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7718         return 1;
7719       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7720         return 1;
7721       else
7722         break;
7723     }
7724   return 0;
7725 }
7726
7727 uword
7728 unformat_l2_mask (unformat_input_t * input, va_list * args)
7729 {
7730   u8 **maskp = va_arg (*args, u8 **);
7731   u8 *mask = 0;
7732   u8 src = 0;
7733   u8 dst = 0;
7734   u8 proto = 0;
7735   u8 tag1 = 0;
7736   u8 tag2 = 0;
7737   u8 ignore_tag1 = 0;
7738   u8 ignore_tag2 = 0;
7739   u8 cos1 = 0;
7740   u8 cos2 = 0;
7741   u8 dot1q = 0;
7742   u8 dot1ad = 0;
7743   int len = 14;
7744
7745   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7746     {
7747       if (unformat (input, "src"))
7748         src = 1;
7749       else if (unformat (input, "dst"))
7750         dst = 1;
7751       else if (unformat (input, "proto"))
7752         proto = 1;
7753       else if (unformat (input, "tag1"))
7754         tag1 = 1;
7755       else if (unformat (input, "tag2"))
7756         tag2 = 1;
7757       else if (unformat (input, "ignore-tag1"))
7758         ignore_tag1 = 1;
7759       else if (unformat (input, "ignore-tag2"))
7760         ignore_tag2 = 1;
7761       else if (unformat (input, "cos1"))
7762         cos1 = 1;
7763       else if (unformat (input, "cos2"))
7764         cos2 = 1;
7765       else if (unformat (input, "dot1q"))
7766         dot1q = 1;
7767       else if (unformat (input, "dot1ad"))
7768         dot1ad = 1;
7769       else
7770         break;
7771     }
7772   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7773        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7774     return 0;
7775
7776   if (tag1 || ignore_tag1 || cos1 || dot1q)
7777     len = 18;
7778   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7779     len = 22;
7780
7781   vec_validate (mask, len - 1);
7782
7783   if (dst)
7784     memset (mask, 0xff, 6);
7785
7786   if (src)
7787     memset (mask + 6, 0xff, 6);
7788
7789   if (tag2 || dot1ad)
7790     {
7791       /* inner vlan tag */
7792       if (tag2)
7793         {
7794           mask[19] = 0xff;
7795           mask[18] = 0x0f;
7796         }
7797       if (cos2)
7798         mask[18] |= 0xe0;
7799       if (proto)
7800         mask[21] = mask[20] = 0xff;
7801       if (tag1)
7802         {
7803           mask[15] = 0xff;
7804           mask[14] = 0x0f;
7805         }
7806       if (cos1)
7807         mask[14] |= 0xe0;
7808       *maskp = mask;
7809       return 1;
7810     }
7811   if (tag1 | dot1q)
7812     {
7813       if (tag1)
7814         {
7815           mask[15] = 0xff;
7816           mask[14] = 0x0f;
7817         }
7818       if (cos1)
7819         mask[14] |= 0xe0;
7820       if (proto)
7821         mask[16] = mask[17] = 0xff;
7822
7823       *maskp = mask;
7824       return 1;
7825     }
7826   if (cos2)
7827     mask[18] |= 0xe0;
7828   if (cos1)
7829     mask[14] |= 0xe0;
7830   if (proto)
7831     mask[12] = mask[13] = 0xff;
7832
7833   *maskp = mask;
7834   return 1;
7835 }
7836
7837 uword
7838 unformat_classify_mask (unformat_input_t * input, va_list * args)
7839 {
7840   u8 **maskp = va_arg (*args, u8 **);
7841   u32 *skipp = va_arg (*args, u32 *);
7842   u32 *matchp = va_arg (*args, u32 *);
7843   u32 match;
7844   u8 *mask = 0;
7845   u8 *l2 = 0;
7846   u8 *l3 = 0;
7847   int i;
7848
7849   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7850     {
7851       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7852         ;
7853       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7854         ;
7855       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7856         ;
7857       else
7858         break;
7859     }
7860
7861   if (mask || l2 || l3)
7862     {
7863       if (l2 || l3)
7864         {
7865           /* "With a free Ethernet header in every package" */
7866           if (l2 == 0)
7867             vec_validate (l2, 13);
7868           mask = l2;
7869           if (vec_len (l3))
7870             {
7871               vec_append (mask, l3);
7872               vec_free (l3);
7873             }
7874         }
7875
7876       /* Scan forward looking for the first significant mask octet */
7877       for (i = 0; i < vec_len (mask); i++)
7878         if (mask[i])
7879           break;
7880
7881       /* compute (skip, match) params */
7882       *skipp = i / sizeof (u32x4);
7883       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7884
7885       /* Pad mask to an even multiple of the vector size */
7886       while (vec_len (mask) % sizeof (u32x4))
7887         vec_add1 (mask, 0);
7888
7889       match = vec_len (mask) / sizeof (u32x4);
7890
7891       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7892         {
7893           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7894           if (*tmp || *(tmp + 1))
7895             break;
7896           match--;
7897         }
7898       if (match == 0)
7899         clib_warning ("BUG: match 0");
7900
7901       _vec_len (mask) = match * sizeof (u32x4);
7902
7903       *matchp = match;
7904       *maskp = mask;
7905
7906       return 1;
7907     }
7908
7909   return 0;
7910 }
7911
7912 #define foreach_l2_next                         \
7913 _(drop, DROP)                                   \
7914 _(ethernet, ETHERNET_INPUT)                     \
7915 _(ip4, IP4_INPUT)                               \
7916 _(ip6, IP6_INPUT)
7917
7918 uword
7919 unformat_l2_next_index (unformat_input_t * input, va_list * args)
7920 {
7921   u32 *miss_next_indexp = va_arg (*args, u32 *);
7922   u32 next_index = 0;
7923   u32 tmp;
7924
7925 #define _(n,N) \
7926   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
7927   foreach_l2_next;
7928 #undef _
7929
7930   if (unformat (input, "%d", &tmp))
7931     {
7932       next_index = tmp;
7933       goto out;
7934     }
7935
7936   return 0;
7937
7938 out:
7939   *miss_next_indexp = next_index;
7940   return 1;
7941 }
7942
7943 #define foreach_ip_next                         \
7944 _(miss, MISS)                                   \
7945 _(drop, DROP)                                   \
7946 _(local, LOCAL)                                 \
7947 _(rewrite, REWRITE)
7948
7949 uword
7950 unformat_ip_next_index (unformat_input_t * input, va_list * args)
7951 {
7952   u32 *miss_next_indexp = va_arg (*args, u32 *);
7953   u32 next_index = 0;
7954   u32 tmp;
7955
7956 #define _(n,N) \
7957   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7958   foreach_ip_next;
7959 #undef _
7960
7961   if (unformat (input, "%d", &tmp))
7962     {
7963       next_index = tmp;
7964       goto out;
7965     }
7966
7967   return 0;
7968
7969 out:
7970   *miss_next_indexp = next_index;
7971   return 1;
7972 }
7973
7974 #define foreach_acl_next                        \
7975 _(deny, DENY)
7976
7977 uword
7978 unformat_acl_next_index (unformat_input_t * input, va_list * args)
7979 {
7980   u32 *miss_next_indexp = va_arg (*args, u32 *);
7981   u32 next_index = 0;
7982   u32 tmp;
7983
7984 #define _(n,N) \
7985   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7986   foreach_acl_next;
7987 #undef _
7988
7989   if (unformat (input, "permit"))
7990     {
7991       next_index = ~0;
7992       goto out;
7993     }
7994   else if (unformat (input, "%d", &tmp))
7995     {
7996       next_index = tmp;
7997       goto out;
7998     }
7999
8000   return 0;
8001
8002 out:
8003   *miss_next_indexp = next_index;
8004   return 1;
8005 }
8006
8007 uword
8008 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8009 {
8010   u32 *r = va_arg (*args, u32 *);
8011
8012   if (unformat (input, "conform-color"))
8013     *r = POLICE_CONFORM;
8014   else if (unformat (input, "exceed-color"))
8015     *r = POLICE_EXCEED;
8016   else
8017     return 0;
8018
8019   return 1;
8020 }
8021
8022 static int
8023 api_classify_add_del_table (vat_main_t * vam)
8024 {
8025   unformat_input_t *i = vam->input;
8026   vl_api_classify_add_del_table_t *mp;
8027
8028   u32 nbuckets = 2;
8029   u32 skip = ~0;
8030   u32 match = ~0;
8031   int is_add = 1;
8032   u32 table_index = ~0;
8033   u32 next_table_index = ~0;
8034   u32 miss_next_index = ~0;
8035   u32 memory_size = 32 << 20;
8036   u8 *mask = 0;
8037   f64 timeout;
8038
8039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8040     {
8041       if (unformat (i, "del"))
8042         is_add = 0;
8043       else if (unformat (i, "buckets %d", &nbuckets))
8044         ;
8045       else if (unformat (i, "memory_size %d", &memory_size))
8046         ;
8047       else if (unformat (i, "skip %d", &skip))
8048         ;
8049       else if (unformat (i, "match %d", &match))
8050         ;
8051       else if (unformat (i, "table %d", &table_index))
8052         ;
8053       else if (unformat (i, "mask %U", unformat_classify_mask,
8054                          &mask, &skip, &match))
8055         ;
8056       else if (unformat (i, "next-table %d", &next_table_index))
8057         ;
8058       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8059                          &miss_next_index))
8060         ;
8061       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8062                          &miss_next_index))
8063         ;
8064       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8065                          &miss_next_index))
8066         ;
8067       else
8068         break;
8069     }
8070
8071   if (is_add && mask == 0)
8072     {
8073       errmsg ("Mask required\n");
8074       return -99;
8075     }
8076
8077   if (is_add && skip == ~0)
8078     {
8079       errmsg ("skip count required\n");
8080       return -99;
8081     }
8082
8083   if (is_add && match == ~0)
8084     {
8085       errmsg ("match count required\n");
8086       return -99;
8087     }
8088
8089   if (!is_add && table_index == ~0)
8090     {
8091       errmsg ("table index required for delete\n");
8092       return -99;
8093     }
8094
8095   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8096
8097   mp->is_add = is_add;
8098   mp->table_index = ntohl (table_index);
8099   mp->nbuckets = ntohl (nbuckets);
8100   mp->memory_size = ntohl (memory_size);
8101   mp->skip_n_vectors = ntohl (skip);
8102   mp->match_n_vectors = ntohl (match);
8103   mp->next_table_index = ntohl (next_table_index);
8104   mp->miss_next_index = ntohl (miss_next_index);
8105   clib_memcpy (mp->mask, mask, vec_len (mask));
8106
8107   vec_free (mask);
8108
8109   S;
8110   W;
8111   /* NOTREACHED */
8112 }
8113
8114 uword
8115 unformat_ip4_match (unformat_input_t * input, va_list * args)
8116 {
8117   u8 **matchp = va_arg (*args, u8 **);
8118   u8 *match = 0;
8119   ip4_header_t *ip;
8120   int version = 0;
8121   u32 version_val;
8122   int hdr_length = 0;
8123   u32 hdr_length_val;
8124   int src = 0, dst = 0;
8125   ip4_address_t src_val, dst_val;
8126   int proto = 0;
8127   u32 proto_val;
8128   int tos = 0;
8129   u32 tos_val;
8130   int length = 0;
8131   u32 length_val;
8132   int fragment_id = 0;
8133   u32 fragment_id_val;
8134   int ttl = 0;
8135   int ttl_val;
8136   int checksum = 0;
8137   u32 checksum_val;
8138
8139   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8140     {
8141       if (unformat (input, "version %d", &version_val))
8142         version = 1;
8143       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8144         hdr_length = 1;
8145       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8146         src = 1;
8147       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8148         dst = 1;
8149       else if (unformat (input, "proto %d", &proto_val))
8150         proto = 1;
8151       else if (unformat (input, "tos %d", &tos_val))
8152         tos = 1;
8153       else if (unformat (input, "length %d", &length_val))
8154         length = 1;
8155       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8156         fragment_id = 1;
8157       else if (unformat (input, "ttl %d", &ttl_val))
8158         ttl = 1;
8159       else if (unformat (input, "checksum %d", &checksum_val))
8160         checksum = 1;
8161       else
8162         break;
8163     }
8164
8165   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8166       + ttl + checksum == 0)
8167     return 0;
8168
8169   /*
8170    * Aligned because we use the real comparison functions
8171    */
8172   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8173
8174   ip = (ip4_header_t *) match;
8175
8176   /* These are realistically matched in practice */
8177   if (src)
8178     ip->src_address.as_u32 = src_val.as_u32;
8179
8180   if (dst)
8181     ip->dst_address.as_u32 = dst_val.as_u32;
8182
8183   if (proto)
8184     ip->protocol = proto_val;
8185
8186
8187   /* These are not, but they're included for completeness */
8188   if (version)
8189     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8190
8191   if (hdr_length)
8192     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8193
8194   if (tos)
8195     ip->tos = tos_val;
8196
8197   if (length)
8198     ip->length = length_val;
8199
8200   if (ttl)
8201     ip->ttl = ttl_val;
8202
8203   if (checksum)
8204     ip->checksum = checksum_val;
8205
8206   *matchp = match;
8207   return 1;
8208 }
8209
8210 uword
8211 unformat_ip6_match (unformat_input_t * input, va_list * args)
8212 {
8213   u8 **matchp = va_arg (*args, u8 **);
8214   u8 *match = 0;
8215   ip6_header_t *ip;
8216   int version = 0;
8217   u32 version_val;
8218   u8 traffic_class = 0;
8219   u32 traffic_class_val = 0;
8220   u8 flow_label = 0;
8221   u8 flow_label_val;
8222   int src = 0, dst = 0;
8223   ip6_address_t src_val, dst_val;
8224   int proto = 0;
8225   u32 proto_val;
8226   int payload_length = 0;
8227   u32 payload_length_val;
8228   int hop_limit = 0;
8229   int hop_limit_val;
8230   u32 ip_version_traffic_class_and_flow_label;
8231
8232   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8233     {
8234       if (unformat (input, "version %d", &version_val))
8235         version = 1;
8236       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8237         traffic_class = 1;
8238       else if (unformat (input, "flow_label %d", &flow_label_val))
8239         flow_label = 1;
8240       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8241         src = 1;
8242       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8243         dst = 1;
8244       else if (unformat (input, "proto %d", &proto_val))
8245         proto = 1;
8246       else if (unformat (input, "payload_length %d", &payload_length_val))
8247         payload_length = 1;
8248       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8249         hop_limit = 1;
8250       else
8251         break;
8252     }
8253
8254   if (version + traffic_class + flow_label + src + dst + proto +
8255       payload_length + hop_limit == 0)
8256     return 0;
8257
8258   /*
8259    * Aligned because we use the real comparison functions
8260    */
8261   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8262
8263   ip = (ip6_header_t *) match;
8264
8265   if (src)
8266     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8267
8268   if (dst)
8269     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8270
8271   if (proto)
8272     ip->protocol = proto_val;
8273
8274   ip_version_traffic_class_and_flow_label = 0;
8275
8276   if (version)
8277     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8278
8279   if (traffic_class)
8280     ip_version_traffic_class_and_flow_label |=
8281       (traffic_class_val & 0xFF) << 20;
8282
8283   if (flow_label)
8284     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8285
8286   ip->ip_version_traffic_class_and_flow_label =
8287     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8288
8289   if (payload_length)
8290     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8291
8292   if (hop_limit)
8293     ip->hop_limit = hop_limit_val;
8294
8295   *matchp = match;
8296   return 1;
8297 }
8298
8299 uword
8300 unformat_l3_match (unformat_input_t * input, va_list * args)
8301 {
8302   u8 **matchp = va_arg (*args, u8 **);
8303
8304   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8305     {
8306       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8307         return 1;
8308       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8309         return 1;
8310       else
8311         break;
8312     }
8313   return 0;
8314 }
8315
8316 uword
8317 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8318 {
8319   u8 *tagp = va_arg (*args, u8 *);
8320   u32 tag;
8321
8322   if (unformat (input, "%d", &tag))
8323     {
8324       tagp[0] = (tag >> 8) & 0x0F;
8325       tagp[1] = tag & 0xFF;
8326       return 1;
8327     }
8328
8329   return 0;
8330 }
8331
8332 uword
8333 unformat_l2_match (unformat_input_t * input, va_list * args)
8334 {
8335   u8 **matchp = va_arg (*args, u8 **);
8336   u8 *match = 0;
8337   u8 src = 0;
8338   u8 src_val[6];
8339   u8 dst = 0;
8340   u8 dst_val[6];
8341   u8 proto = 0;
8342   u16 proto_val;
8343   u8 tag1 = 0;
8344   u8 tag1_val[2];
8345   u8 tag2 = 0;
8346   u8 tag2_val[2];
8347   int len = 14;
8348   u8 ignore_tag1 = 0;
8349   u8 ignore_tag2 = 0;
8350   u8 cos1 = 0;
8351   u8 cos2 = 0;
8352   u32 cos1_val = 0;
8353   u32 cos2_val = 0;
8354
8355   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8356     {
8357       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8358         src = 1;
8359       else
8360         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8361         dst = 1;
8362       else if (unformat (input, "proto %U",
8363                          unformat_ethernet_type_host_byte_order, &proto_val))
8364         proto = 1;
8365       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8366         tag1 = 1;
8367       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8368         tag2 = 1;
8369       else if (unformat (input, "ignore-tag1"))
8370         ignore_tag1 = 1;
8371       else if (unformat (input, "ignore-tag2"))
8372         ignore_tag2 = 1;
8373       else if (unformat (input, "cos1 %d", &cos1_val))
8374         cos1 = 1;
8375       else if (unformat (input, "cos2 %d", &cos2_val))
8376         cos2 = 1;
8377       else
8378         break;
8379     }
8380   if ((src + dst + proto + tag1 + tag2 +
8381        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8382     return 0;
8383
8384   if (tag1 || ignore_tag1 || cos1)
8385     len = 18;
8386   if (tag2 || ignore_tag2 || cos2)
8387     len = 22;
8388
8389   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8390
8391   if (dst)
8392     clib_memcpy (match, dst_val, 6);
8393
8394   if (src)
8395     clib_memcpy (match + 6, src_val, 6);
8396
8397   if (tag2)
8398     {
8399       /* inner vlan tag */
8400       match[19] = tag2_val[1];
8401       match[18] = tag2_val[0];
8402       if (cos2)
8403         match[18] |= (cos2_val & 0x7) << 5;
8404       if (proto)
8405         {
8406           match[21] = proto_val & 0xff;
8407           match[20] = proto_val >> 8;
8408         }
8409       if (tag1)
8410         {
8411           match[15] = tag1_val[1];
8412           match[14] = tag1_val[0];
8413         }
8414       if (cos1)
8415         match[14] |= (cos1_val & 0x7) << 5;
8416       *matchp = match;
8417       return 1;
8418     }
8419   if (tag1)
8420     {
8421       match[15] = tag1_val[1];
8422       match[14] = tag1_val[0];
8423       if (proto)
8424         {
8425           match[17] = proto_val & 0xff;
8426           match[16] = proto_val >> 8;
8427         }
8428       if (cos1)
8429         match[14] |= (cos1_val & 0x7) << 5;
8430
8431       *matchp = match;
8432       return 1;
8433     }
8434   if (cos2)
8435     match[18] |= (cos2_val & 0x7) << 5;
8436   if (cos1)
8437     match[14] |= (cos1_val & 0x7) << 5;
8438   if (proto)
8439     {
8440       match[13] = proto_val & 0xff;
8441       match[12] = proto_val >> 8;
8442     }
8443
8444   *matchp = match;
8445   return 1;
8446 }
8447
8448
8449 uword
8450 unformat_classify_match (unformat_input_t * input, va_list * args)
8451 {
8452   u8 **matchp = va_arg (*args, u8 **);
8453   u32 skip_n_vectors = va_arg (*args, u32);
8454   u32 match_n_vectors = va_arg (*args, u32);
8455
8456   u8 *match = 0;
8457   u8 *l2 = 0;
8458   u8 *l3 = 0;
8459
8460   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8461     {
8462       if (unformat (input, "hex %U", unformat_hex_string, &match))
8463         ;
8464       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8465         ;
8466       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8467         ;
8468       else
8469         break;
8470     }
8471
8472   if (match || l2 || l3)
8473     {
8474       if (l2 || l3)
8475         {
8476           /* "Win a free Ethernet header in every packet" */
8477           if (l2 == 0)
8478             vec_validate_aligned (l2, 13, sizeof (u32x4));
8479           match = l2;
8480           if (vec_len (l3))
8481             {
8482               vec_append_aligned (match, l3, sizeof (u32x4));
8483               vec_free (l3);
8484             }
8485         }
8486
8487       /* Make sure the vector is big enough even if key is all 0's */
8488       vec_validate_aligned
8489         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8490          sizeof (u32x4));
8491
8492       /* Set size, include skipped vectors */
8493       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8494
8495       *matchp = match;
8496
8497       return 1;
8498     }
8499
8500   return 0;
8501 }
8502
8503 static int
8504 api_classify_add_del_session (vat_main_t * vam)
8505 {
8506   unformat_input_t *i = vam->input;
8507   vl_api_classify_add_del_session_t *mp;
8508   int is_add = 1;
8509   u32 table_index = ~0;
8510   u32 hit_next_index = ~0;
8511   u32 opaque_index = ~0;
8512   u8 *match = 0;
8513   i32 advance = 0;
8514   f64 timeout;
8515   u32 skip_n_vectors = 0;
8516   u32 match_n_vectors = 0;
8517
8518   /*
8519    * Warning: you have to supply skip_n and match_n
8520    * because the API client cant simply look at the classify
8521    * table object.
8522    */
8523
8524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8525     {
8526       if (unformat (i, "del"))
8527         is_add = 0;
8528       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8529                          &hit_next_index))
8530         ;
8531       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8532                          &hit_next_index))
8533         ;
8534       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8535                          &hit_next_index))
8536         ;
8537       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8538         ;
8539       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8540         ;
8541       else if (unformat (i, "opaque-index %d", &opaque_index))
8542         ;
8543       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8544         ;
8545       else if (unformat (i, "match_n %d", &match_n_vectors))
8546         ;
8547       else if (unformat (i, "match %U", unformat_classify_match,
8548                          &match, skip_n_vectors, match_n_vectors))
8549         ;
8550       else if (unformat (i, "advance %d", &advance))
8551         ;
8552       else if (unformat (i, "table-index %d", &table_index))
8553         ;
8554       else
8555         break;
8556     }
8557
8558   if (table_index == ~0)
8559     {
8560       errmsg ("Table index required\n");
8561       return -99;
8562     }
8563
8564   if (is_add && match == 0)
8565     {
8566       errmsg ("Match value required\n");
8567       return -99;
8568     }
8569
8570   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8571
8572   mp->is_add = is_add;
8573   mp->table_index = ntohl (table_index);
8574   mp->hit_next_index = ntohl (hit_next_index);
8575   mp->opaque_index = ntohl (opaque_index);
8576   mp->advance = ntohl (advance);
8577   clib_memcpy (mp->match, match, vec_len (match));
8578   vec_free (match);
8579
8580   S;
8581   W;
8582   /* NOTREACHED */
8583 }
8584
8585 static int
8586 api_classify_set_interface_ip_table (vat_main_t * vam)
8587 {
8588   unformat_input_t *i = vam->input;
8589   vl_api_classify_set_interface_ip_table_t *mp;
8590   f64 timeout;
8591   u32 sw_if_index;
8592   int sw_if_index_set;
8593   u32 table_index = ~0;
8594   u8 is_ipv6 = 0;
8595
8596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8597     {
8598       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8599         sw_if_index_set = 1;
8600       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8601         sw_if_index_set = 1;
8602       else if (unformat (i, "table %d", &table_index))
8603         ;
8604       else
8605         {
8606           clib_warning ("parse error '%U'", format_unformat_error, i);
8607           return -99;
8608         }
8609     }
8610
8611   if (sw_if_index_set == 0)
8612     {
8613       errmsg ("missing interface name or sw_if_index\n");
8614       return -99;
8615     }
8616
8617
8618   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8619
8620   mp->sw_if_index = ntohl (sw_if_index);
8621   mp->table_index = ntohl (table_index);
8622   mp->is_ipv6 = is_ipv6;
8623
8624   S;
8625   W;
8626   /* NOTREACHED */
8627   return 0;
8628 }
8629
8630 static int
8631 api_classify_set_interface_l2_tables (vat_main_t * vam)
8632 {
8633   unformat_input_t *i = vam->input;
8634   vl_api_classify_set_interface_l2_tables_t *mp;
8635   f64 timeout;
8636   u32 sw_if_index;
8637   int sw_if_index_set;
8638   u32 ip4_table_index = ~0;
8639   u32 ip6_table_index = ~0;
8640   u32 other_table_index = ~0;
8641   u32 is_input = 1;
8642
8643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8644     {
8645       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8646         sw_if_index_set = 1;
8647       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8648         sw_if_index_set = 1;
8649       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8650         ;
8651       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8652         ;
8653       else if (unformat (i, "other-table %d", &other_table_index))
8654         ;
8655       else if (unformat (i, "is-input %d", &is_input))
8656         ;
8657       else
8658         {
8659           clib_warning ("parse error '%U'", format_unformat_error, i);
8660           return -99;
8661         }
8662     }
8663
8664   if (sw_if_index_set == 0)
8665     {
8666       errmsg ("missing interface name or sw_if_index\n");
8667       return -99;
8668     }
8669
8670
8671   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8672
8673   mp->sw_if_index = ntohl (sw_if_index);
8674   mp->ip4_table_index = ntohl (ip4_table_index);
8675   mp->ip6_table_index = ntohl (ip6_table_index);
8676   mp->other_table_index = ntohl (other_table_index);
8677   mp->is_input = (u8) is_input;
8678
8679   S;
8680   W;
8681   /* NOTREACHED */
8682   return 0;
8683 }
8684
8685 static int
8686 api_ipfix_enable (vat_main_t * vam)
8687 {
8688   unformat_input_t *i = vam->input;
8689   vl_api_ipfix_enable_t *mp;
8690   ip4_address_t collector_address;
8691   u8 collector_address_set = 0;
8692   u32 collector_port = ~0;
8693   ip4_address_t src_address;
8694   u8 src_address_set = 0;
8695   u32 vrf_id = ~0;
8696   u32 path_mtu = ~0;
8697   u32 template_interval = ~0;
8698   f64 timeout;
8699
8700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8701     {
8702       if (unformat (i, "collector_address %U", unformat_ip4_address,
8703                     &collector_address))
8704         collector_address_set = 1;
8705       else if (unformat (i, "collector_port %d", &collector_port))
8706         ;
8707       else if (unformat (i, "src_address %U", unformat_ip4_address,
8708                          &src_address))
8709         src_address_set = 1;
8710       else if (unformat (i, "vrf_id %d", &vrf_id))
8711         ;
8712       else if (unformat (i, "path_mtu %d", &path_mtu))
8713         ;
8714       else if (unformat (i, "template_interval %d", &template_interval))
8715         ;
8716       else
8717         break;
8718     }
8719
8720   if (collector_address_set == 0)
8721     {
8722       errmsg ("collector_address required\n");
8723       return -99;
8724     }
8725
8726   if (src_address_set == 0)
8727     {
8728       errmsg ("src_address required\n");
8729       return -99;
8730     }
8731
8732   M (IPFIX_ENABLE, ipfix_enable);
8733
8734   memcpy (mp->collector_address, collector_address.data,
8735           sizeof (collector_address.data));
8736   mp->collector_port = htons ((u16) collector_port);
8737   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8738   mp->vrf_id = htonl (vrf_id);
8739   mp->path_mtu = htonl (path_mtu);
8740   mp->template_interval = htonl (template_interval);
8741
8742   S;
8743   W;
8744   /* NOTREACHED */
8745 }
8746
8747 static int
8748 api_get_node_index (vat_main_t * vam)
8749 {
8750   unformat_input_t *i = vam->input;
8751   vl_api_get_node_index_t *mp;
8752   f64 timeout;
8753   u8 *name = 0;
8754
8755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8756     {
8757       if (unformat (i, "node %s", &name))
8758         ;
8759       else
8760         break;
8761     }
8762   if (name == 0)
8763     {
8764       errmsg ("node name required\n");
8765       return -99;
8766     }
8767   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8768     {
8769       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8770       return -99;
8771     }
8772
8773   M (GET_NODE_INDEX, get_node_index);
8774   clib_memcpy (mp->node_name, name, vec_len (name));
8775   vec_free (name);
8776
8777   S;
8778   W;
8779   /* NOTREACHED */
8780   return 0;
8781 }
8782
8783 static int
8784 api_get_next_index (vat_main_t * vam)
8785 {
8786   unformat_input_t *i = vam->input;
8787   vl_api_get_next_index_t *mp;
8788   f64 timeout;
8789   u8 *node_name = 0, *next_node_name = 0;
8790
8791   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8792     {
8793       if (unformat (i, "node-name %s", &node_name))
8794         ;
8795       else if (unformat (i, "next-node-name %s", &next_node_name))
8796         break;
8797     }
8798
8799   if (node_name == 0)
8800     {
8801       errmsg ("node name required\n");
8802       return -99;
8803     }
8804   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
8805     {
8806       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8807       return -99;
8808     }
8809
8810   if (next_node_name == 0)
8811     {
8812       errmsg ("next node name required\n");
8813       return -99;
8814     }
8815   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
8816     {
8817       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
8818       return -99;
8819     }
8820
8821   M (GET_NEXT_INDEX, get_next_index);
8822   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
8823   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
8824   vec_free (node_name);
8825   vec_free (next_node_name);
8826
8827   S;
8828   W;
8829   /* NOTREACHED */
8830   return 0;
8831 }
8832
8833 static int
8834 api_add_node_next (vat_main_t * vam)
8835 {
8836   unformat_input_t *i = vam->input;
8837   vl_api_add_node_next_t *mp;
8838   f64 timeout;
8839   u8 *name = 0;
8840   u8 *next = 0;
8841
8842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8843     {
8844       if (unformat (i, "node %s", &name))
8845         ;
8846       else if (unformat (i, "next %s", &next))
8847         ;
8848       else
8849         break;
8850     }
8851   if (name == 0)
8852     {
8853       errmsg ("node name required\n");
8854       return -99;
8855     }
8856   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8857     {
8858       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8859       return -99;
8860     }
8861   if (next == 0)
8862     {
8863       errmsg ("next node required\n");
8864       return -99;
8865     }
8866   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
8867     {
8868       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
8869       return -99;
8870     }
8871
8872   M (ADD_NODE_NEXT, add_node_next);
8873   clib_memcpy (mp->node_name, name, vec_len (name));
8874   clib_memcpy (mp->next_name, next, vec_len (next));
8875   vec_free (name);
8876   vec_free (next);
8877
8878   S;
8879   W;
8880   /* NOTREACHED */
8881   return 0;
8882 }
8883
8884 static int
8885 api_l2tpv3_create_tunnel (vat_main_t * vam)
8886 {
8887   unformat_input_t *i = vam->input;
8888   ip6_address_t client_address, our_address;
8889   int client_address_set = 0;
8890   int our_address_set = 0;
8891   u32 local_session_id = 0;
8892   u32 remote_session_id = 0;
8893   u64 local_cookie = 0;
8894   u64 remote_cookie = 0;
8895   u8 l2_sublayer_present = 0;
8896   vl_api_l2tpv3_create_tunnel_t *mp;
8897   f64 timeout;
8898
8899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8900     {
8901       if (unformat (i, "client_address %U", unformat_ip6_address,
8902                     &client_address))
8903         client_address_set = 1;
8904       else if (unformat (i, "our_address %U", unformat_ip6_address,
8905                          &our_address))
8906         our_address_set = 1;
8907       else if (unformat (i, "local_session_id %d", &local_session_id))
8908         ;
8909       else if (unformat (i, "remote_session_id %d", &remote_session_id))
8910         ;
8911       else if (unformat (i, "local_cookie %lld", &local_cookie))
8912         ;
8913       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8914         ;
8915       else if (unformat (i, "l2-sublayer-present"))
8916         l2_sublayer_present = 1;
8917       else
8918         break;
8919     }
8920
8921   if (client_address_set == 0)
8922     {
8923       errmsg ("client_address required\n");
8924       return -99;
8925     }
8926
8927   if (our_address_set == 0)
8928     {
8929       errmsg ("our_address required\n");
8930       return -99;
8931     }
8932
8933   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
8934
8935   clib_memcpy (mp->client_address, client_address.as_u8,
8936                sizeof (mp->client_address));
8937
8938   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
8939
8940   mp->local_session_id = ntohl (local_session_id);
8941   mp->remote_session_id = ntohl (remote_session_id);
8942   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
8943   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
8944   mp->l2_sublayer_present = l2_sublayer_present;
8945   mp->is_ipv6 = 1;
8946
8947   S;
8948   W;
8949   /* NOTREACHED */
8950   return 0;
8951 }
8952
8953 static int
8954 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
8955 {
8956   unformat_input_t *i = vam->input;
8957   u32 sw_if_index;
8958   u8 sw_if_index_set = 0;
8959   u64 new_local_cookie = 0;
8960   u64 new_remote_cookie = 0;
8961   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
8962   f64 timeout;
8963
8964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8965     {
8966       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8967         sw_if_index_set = 1;
8968       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8969         sw_if_index_set = 1;
8970       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
8971         ;
8972       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
8973         ;
8974       else
8975         break;
8976     }
8977
8978   if (sw_if_index_set == 0)
8979     {
8980       errmsg ("missing interface name or sw_if_index\n");
8981       return -99;
8982     }
8983
8984   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
8985
8986   mp->sw_if_index = ntohl (sw_if_index);
8987   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
8988   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
8989
8990   S;
8991   W;
8992   /* NOTREACHED */
8993   return 0;
8994 }
8995
8996 static int
8997 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
8998 {
8999   unformat_input_t *i = vam->input;
9000   vl_api_l2tpv3_interface_enable_disable_t *mp;
9001   f64 timeout;
9002   u32 sw_if_index;
9003   u8 sw_if_index_set = 0;
9004   u8 enable_disable = 1;
9005
9006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9007     {
9008       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9009         sw_if_index_set = 1;
9010       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9011         sw_if_index_set = 1;
9012       else if (unformat (i, "enable"))
9013         enable_disable = 1;
9014       else if (unformat (i, "disable"))
9015         enable_disable = 0;
9016       else
9017         break;
9018     }
9019
9020   if (sw_if_index_set == 0)
9021     {
9022       errmsg ("missing interface name or sw_if_index\n");
9023       return -99;
9024     }
9025
9026   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9027
9028   mp->sw_if_index = ntohl (sw_if_index);
9029   mp->enable_disable = enable_disable;
9030
9031   S;
9032   W;
9033   /* NOTREACHED */
9034   return 0;
9035 }
9036
9037 static int
9038 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9039 {
9040   unformat_input_t *i = vam->input;
9041   vl_api_l2tpv3_set_lookup_key_t *mp;
9042   f64 timeout;
9043   u8 key = ~0;
9044
9045   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9046     {
9047       if (unformat (i, "lookup_v6_src"))
9048         key = L2T_LOOKUP_SRC_ADDRESS;
9049       else if (unformat (i, "lookup_v6_dst"))
9050         key = L2T_LOOKUP_DST_ADDRESS;
9051       else if (unformat (i, "lookup_session_id"))
9052         key = L2T_LOOKUP_SESSION_ID;
9053       else
9054         break;
9055     }
9056
9057   if (key == (u8) ~ 0)
9058     {
9059       errmsg ("l2tp session lookup key unset\n");
9060       return -99;
9061     }
9062
9063   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9064
9065   mp->key = key;
9066
9067   S;
9068   W;
9069   /* NOTREACHED */
9070   return 0;
9071 }
9072
9073 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9074   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9075 {
9076   vat_main_t *vam = &vat_main;
9077
9078   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9079            format_ip6_address, mp->our_address,
9080            format_ip6_address, mp->client_address,
9081            clib_net_to_host_u32 (mp->sw_if_index));
9082
9083   fformat (vam->ofp,
9084            "   local cookies %016llx %016llx remote cookie %016llx\n",
9085            clib_net_to_host_u64 (mp->local_cookie[0]),
9086            clib_net_to_host_u64 (mp->local_cookie[1]),
9087            clib_net_to_host_u64 (mp->remote_cookie));
9088
9089   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9090            clib_net_to_host_u32 (mp->local_session_id),
9091            clib_net_to_host_u32 (mp->remote_session_id));
9092
9093   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9094            mp->l2_sublayer_present ? "preset" : "absent");
9095
9096 }
9097
9098 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9099   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9100 {
9101   vat_main_t *vam = &vat_main;
9102   vat_json_node_t *node = NULL;
9103   struct in6_addr addr;
9104
9105   if (VAT_JSON_ARRAY != vam->json_tree.type)
9106     {
9107       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9108       vat_json_init_array (&vam->json_tree);
9109     }
9110   node = vat_json_array_add (&vam->json_tree);
9111
9112   vat_json_init_object (node);
9113
9114   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9115   vat_json_object_add_ip6 (node, "our_address", addr);
9116   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9117   vat_json_object_add_ip6 (node, "client_address", addr);
9118
9119   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9120   vat_json_init_array (lc);
9121   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9122   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9123   vat_json_object_add_uint (node, "remote_cookie",
9124                             clib_net_to_host_u64 (mp->remote_cookie));
9125
9126   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9127   vat_json_object_add_uint (node, "local_session_id",
9128                             clib_net_to_host_u32 (mp->local_session_id));
9129   vat_json_object_add_uint (node, "remote_session_id",
9130                             clib_net_to_host_u32 (mp->remote_session_id));
9131   vat_json_object_add_string_copy (node, "l2_sublayer",
9132                                    mp->l2_sublayer_present ? (u8 *) "present"
9133                                    : (u8 *) "absent");
9134 }
9135
9136 static int
9137 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9138 {
9139   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9140   f64 timeout;
9141
9142   /* Get list of l2tpv3-tunnel interfaces */
9143   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9144   S;
9145
9146   /* Use a control ping for synchronization */
9147   {
9148     vl_api_control_ping_t *mp;
9149     M (CONTROL_PING, control_ping);
9150     S;
9151   }
9152   W;
9153 }
9154
9155
9156 static void vl_api_sw_interface_tap_details_t_handler
9157   (vl_api_sw_interface_tap_details_t * mp)
9158 {
9159   vat_main_t *vam = &vat_main;
9160
9161   fformat (vam->ofp, "%-16s %d\n",
9162            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9163 }
9164
9165 static void vl_api_sw_interface_tap_details_t_handler_json
9166   (vl_api_sw_interface_tap_details_t * mp)
9167 {
9168   vat_main_t *vam = &vat_main;
9169   vat_json_node_t *node = NULL;
9170
9171   if (VAT_JSON_ARRAY != vam->json_tree.type)
9172     {
9173       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9174       vat_json_init_array (&vam->json_tree);
9175     }
9176   node = vat_json_array_add (&vam->json_tree);
9177
9178   vat_json_init_object (node);
9179   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9180   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9181 }
9182
9183 static int
9184 api_sw_interface_tap_dump (vat_main_t * vam)
9185 {
9186   vl_api_sw_interface_tap_dump_t *mp;
9187   f64 timeout;
9188
9189   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9190   /* Get list of tap interfaces */
9191   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9192   S;
9193
9194   /* Use a control ping for synchronization */
9195   {
9196     vl_api_control_ping_t *mp;
9197     M (CONTROL_PING, control_ping);
9198     S;
9199   }
9200   W;
9201 }
9202
9203 static uword unformat_vxlan_decap_next
9204   (unformat_input_t * input, va_list * args)
9205 {
9206   u32 *result = va_arg (*args, u32 *);
9207   u32 tmp;
9208
9209   if (unformat (input, "drop"))
9210     *result = VXLAN_INPUT_NEXT_DROP;
9211   else if (unformat (input, "ip4"))
9212     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9213   else if (unformat (input, "ip6"))
9214     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9215   else if (unformat (input, "l2"))
9216     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9217   else if (unformat (input, "%d", &tmp))
9218     *result = tmp;
9219   else
9220     return 0;
9221   return 1;
9222 }
9223
9224 static int
9225 api_vxlan_add_del_tunnel (vat_main_t * vam)
9226 {
9227   unformat_input_t *line_input = vam->input;
9228   vl_api_vxlan_add_del_tunnel_t *mp;
9229   f64 timeout;
9230   ip4_address_t src4, dst4;
9231   ip6_address_t src6, dst6;
9232   u8 is_add = 1;
9233   u8 ipv4_set = 0, ipv6_set = 0;
9234   u8 src_set = 0;
9235   u8 dst_set = 0;
9236   u32 encap_vrf_id = 0;
9237   u32 decap_next_index = ~0;
9238   u32 vni = 0;
9239
9240   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9241     {
9242       if (unformat (line_input, "del"))
9243         is_add = 0;
9244       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9245         {
9246           ipv4_set = 1;
9247           src_set = 1;
9248         }
9249       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9250         {
9251           ipv4_set = 1;
9252           dst_set = 1;
9253         }
9254       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9255         {
9256           ipv6_set = 1;
9257           src_set = 1;
9258         }
9259       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9260         {
9261           ipv6_set = 1;
9262           dst_set = 1;
9263         }
9264       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9265         ;
9266       else if (unformat (line_input, "decap-next %U",
9267                          unformat_vxlan_decap_next, &decap_next_index))
9268         ;
9269       else if (unformat (line_input, "vni %d", &vni))
9270         ;
9271       else
9272         {
9273           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9274           return -99;
9275         }
9276     }
9277
9278   if (src_set == 0)
9279     {
9280       errmsg ("tunnel src address not specified\n");
9281       return -99;
9282     }
9283   if (dst_set == 0)
9284     {
9285       errmsg ("tunnel dst address not specified\n");
9286       return -99;
9287     }
9288
9289   if (ipv4_set && ipv6_set)
9290     {
9291       errmsg ("both IPv4 and IPv6 addresses specified");
9292       return -99;
9293     }
9294
9295   if ((vni == 0) || (vni >> 24))
9296     {
9297       errmsg ("vni not specified or out of range\n");
9298       return -99;
9299     }
9300
9301   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9302
9303   if (ipv6_set)
9304     {
9305       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9306       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9307     }
9308   else
9309     {
9310       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9311       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9312     }
9313   mp->encap_vrf_id = ntohl (encap_vrf_id);
9314   mp->decap_next_index = ntohl (decap_next_index);
9315   mp->vni = ntohl (vni);
9316   mp->is_add = is_add;
9317   mp->is_ipv6 = ipv6_set;
9318
9319   S;
9320   W;
9321   /* NOTREACHED */
9322   return 0;
9323 }
9324
9325 static void vl_api_vxlan_tunnel_details_t_handler
9326   (vl_api_vxlan_tunnel_details_t * mp)
9327 {
9328   vat_main_t *vam = &vat_main;
9329
9330   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9331            ntohl (mp->sw_if_index),
9332            format_ip46_address, &(mp->src_address[0]),
9333            IP46_TYPE_ANY,
9334            format_ip46_address, &(mp->dst_address[0]),
9335            IP46_TYPE_ANY,
9336            ntohl (mp->encap_vrf_id),
9337            ntohl (mp->decap_next_index), ntohl (mp->vni));
9338 }
9339
9340 static void vl_api_vxlan_tunnel_details_t_handler_json
9341   (vl_api_vxlan_tunnel_details_t * mp)
9342 {
9343   vat_main_t *vam = &vat_main;
9344   vat_json_node_t *node = NULL;
9345   struct in_addr ip4;
9346   struct in6_addr ip6;
9347
9348   if (VAT_JSON_ARRAY != vam->json_tree.type)
9349     {
9350       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9351       vat_json_init_array (&vam->json_tree);
9352     }
9353   node = vat_json_array_add (&vam->json_tree);
9354
9355   vat_json_init_object (node);
9356   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9357   if (mp->is_ipv6)
9358     {
9359       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9360       vat_json_object_add_ip6 (node, "src_address", ip6);
9361       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9362       vat_json_object_add_ip6 (node, "dst_address", ip6);
9363     }
9364   else
9365     {
9366       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9367       vat_json_object_add_ip4 (node, "src_address", ip4);
9368       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9369       vat_json_object_add_ip4 (node, "dst_address", ip4);
9370     }
9371   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9372   vat_json_object_add_uint (node, "decap_next_index",
9373                             ntohl (mp->decap_next_index));
9374   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9375   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9376 }
9377
9378 static int
9379 api_vxlan_tunnel_dump (vat_main_t * vam)
9380 {
9381   unformat_input_t *i = vam->input;
9382   vl_api_vxlan_tunnel_dump_t *mp;
9383   f64 timeout;
9384   u32 sw_if_index;
9385   u8 sw_if_index_set = 0;
9386
9387   /* Parse args required to build the message */
9388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9389     {
9390       if (unformat (i, "sw_if_index %d", &sw_if_index))
9391         sw_if_index_set = 1;
9392       else
9393         break;
9394     }
9395
9396   if (sw_if_index_set == 0)
9397     {
9398       sw_if_index = ~0;
9399     }
9400
9401   if (!vam->json_output)
9402     {
9403       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9404                "sw_if_index", "src_address", "dst_address",
9405                "encap_vrf_id", "decap_next_index", "vni");
9406     }
9407
9408   /* Get list of vxlan-tunnel interfaces */
9409   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9410
9411   mp->sw_if_index = htonl (sw_if_index);
9412
9413   S;
9414
9415   /* Use a control ping for synchronization */
9416   {
9417     vl_api_control_ping_t *mp;
9418     M (CONTROL_PING, control_ping);
9419     S;
9420   }
9421   W;
9422 }
9423
9424 static int
9425 api_gre_add_del_tunnel (vat_main_t * vam)
9426 {
9427   unformat_input_t *line_input = vam->input;
9428   vl_api_gre_add_del_tunnel_t *mp;
9429   f64 timeout;
9430   ip4_address_t src4, dst4;
9431   u8 is_add = 1;
9432   u8 src_set = 0;
9433   u8 dst_set = 0;
9434   u32 outer_fib_id = 0;
9435
9436   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9437     {
9438       if (unformat (line_input, "del"))
9439         is_add = 0;
9440       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9441         src_set = 1;
9442       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9443         dst_set = 1;
9444       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9445         ;
9446       else
9447         {
9448           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9449           return -99;
9450         }
9451     }
9452
9453   if (src_set == 0)
9454     {
9455       errmsg ("tunnel src address not specified\n");
9456       return -99;
9457     }
9458   if (dst_set == 0)
9459     {
9460       errmsg ("tunnel dst address not specified\n");
9461       return -99;
9462     }
9463
9464
9465   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9466
9467   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9468   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9469   mp->outer_fib_id = ntohl (outer_fib_id);
9470   mp->is_add = is_add;
9471
9472   S;
9473   W;
9474   /* NOTREACHED */
9475   return 0;
9476 }
9477
9478 static void vl_api_gre_tunnel_details_t_handler
9479   (vl_api_gre_tunnel_details_t * mp)
9480 {
9481   vat_main_t *vam = &vat_main;
9482
9483   fformat (vam->ofp, "%11d%15U%15U%14d\n",
9484            ntohl (mp->sw_if_index),
9485            format_ip4_address, &mp->src_address,
9486            format_ip4_address, &mp->dst_address, ntohl (mp->outer_fib_id));
9487 }
9488
9489 static void vl_api_gre_tunnel_details_t_handler_json
9490   (vl_api_gre_tunnel_details_t * mp)
9491 {
9492   vat_main_t *vam = &vat_main;
9493   vat_json_node_t *node = NULL;
9494   struct in_addr ip4;
9495
9496   if (VAT_JSON_ARRAY != vam->json_tree.type)
9497     {
9498       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9499       vat_json_init_array (&vam->json_tree);
9500     }
9501   node = vat_json_array_add (&vam->json_tree);
9502
9503   vat_json_init_object (node);
9504   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9505   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9506   vat_json_object_add_ip4 (node, "src_address", ip4);
9507   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9508   vat_json_object_add_ip4 (node, "dst_address", ip4);
9509   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9510 }
9511
9512 static int
9513 api_gre_tunnel_dump (vat_main_t * vam)
9514 {
9515   unformat_input_t *i = vam->input;
9516   vl_api_gre_tunnel_dump_t *mp;
9517   f64 timeout;
9518   u32 sw_if_index;
9519   u8 sw_if_index_set = 0;
9520
9521   /* Parse args required to build the message */
9522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9523     {
9524       if (unformat (i, "sw_if_index %d", &sw_if_index))
9525         sw_if_index_set = 1;
9526       else
9527         break;
9528     }
9529
9530   if (sw_if_index_set == 0)
9531     {
9532       sw_if_index = ~0;
9533     }
9534
9535   if (!vam->json_output)
9536     {
9537       fformat (vam->ofp, "%11s%15s%15s%14s\n",
9538                "sw_if_index", "src_address", "dst_address", "outer_fib_id");
9539     }
9540
9541   /* Get list of gre-tunnel interfaces */
9542   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9543
9544   mp->sw_if_index = htonl (sw_if_index);
9545
9546   S;
9547
9548   /* Use a control ping for synchronization */
9549   {
9550     vl_api_control_ping_t *mp;
9551     M (CONTROL_PING, control_ping);
9552     S;
9553   }
9554   W;
9555 }
9556
9557 static int
9558 api_l2_fib_clear_table (vat_main_t * vam)
9559 {
9560 //  unformat_input_t * i = vam->input;
9561   vl_api_l2_fib_clear_table_t *mp;
9562   f64 timeout;
9563
9564   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9565
9566   S;
9567   W;
9568   /* NOTREACHED */
9569   return 0;
9570 }
9571
9572 static int
9573 api_l2_interface_efp_filter (vat_main_t * vam)
9574 {
9575   unformat_input_t *i = vam->input;
9576   vl_api_l2_interface_efp_filter_t *mp;
9577   f64 timeout;
9578   u32 sw_if_index;
9579   u8 enable = 1;
9580   u8 sw_if_index_set = 0;
9581
9582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9583     {
9584       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9585         sw_if_index_set = 1;
9586       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9587         sw_if_index_set = 1;
9588       else if (unformat (i, "enable"))
9589         enable = 1;
9590       else if (unformat (i, "disable"))
9591         enable = 0;
9592       else
9593         {
9594           clib_warning ("parse error '%U'", format_unformat_error, i);
9595           return -99;
9596         }
9597     }
9598
9599   if (sw_if_index_set == 0)
9600     {
9601       errmsg ("missing sw_if_index\n");
9602       return -99;
9603     }
9604
9605   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9606
9607   mp->sw_if_index = ntohl (sw_if_index);
9608   mp->enable_disable = enable;
9609
9610   S;
9611   W;
9612   /* NOTREACHED */
9613   return 0;
9614 }
9615
9616 #define foreach_vtr_op                          \
9617 _("disable",  L2_VTR_DISABLED)                  \
9618 _("push-1",  L2_VTR_PUSH_1)                     \
9619 _("push-2",  L2_VTR_PUSH_2)                     \
9620 _("pop-1",  L2_VTR_POP_1)                       \
9621 _("pop-2",  L2_VTR_POP_2)                       \
9622 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9623 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9624 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9625 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9626
9627 static int
9628 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9629 {
9630   unformat_input_t *i = vam->input;
9631   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9632   f64 timeout;
9633   u32 sw_if_index;
9634   u8 sw_if_index_set = 0;
9635   u8 vtr_op_set = 0;
9636   u32 vtr_op = 0;
9637   u32 push_dot1q = 1;
9638   u32 tag1 = ~0;
9639   u32 tag2 = ~0;
9640
9641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9642     {
9643       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9644         sw_if_index_set = 1;
9645       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9646         sw_if_index_set = 1;
9647       else if (unformat (i, "vtr_op %d", &vtr_op))
9648         vtr_op_set = 1;
9649 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9650       foreach_vtr_op
9651 #undef _
9652         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9653         ;
9654       else if (unformat (i, "tag1 %d", &tag1))
9655         ;
9656       else if (unformat (i, "tag2 %d", &tag2))
9657         ;
9658       else
9659         {
9660           clib_warning ("parse error '%U'", format_unformat_error, i);
9661           return -99;
9662         }
9663     }
9664
9665   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9666     {
9667       errmsg ("missing vtr operation or sw_if_index\n");
9668       return -99;
9669     }
9670
9671   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9672     mp->sw_if_index = ntohl (sw_if_index);
9673   mp->vtr_op = ntohl (vtr_op);
9674   mp->push_dot1q = ntohl (push_dot1q);
9675   mp->tag1 = ntohl (tag1);
9676   mp->tag2 = ntohl (tag2);
9677
9678   S;
9679   W;
9680   /* NOTREACHED */
9681   return 0;
9682 }
9683
9684 static int
9685 api_create_vhost_user_if (vat_main_t * vam)
9686 {
9687   unformat_input_t *i = vam->input;
9688   vl_api_create_vhost_user_if_t *mp;
9689   f64 timeout;
9690   u8 *file_name;
9691   u8 is_server = 0;
9692   u8 file_name_set = 0;
9693   u32 custom_dev_instance = ~0;
9694   u8 hwaddr[6];
9695   u8 use_custom_mac = 0;
9696
9697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9698     {
9699       if (unformat (i, "socket %s", &file_name))
9700         {
9701           file_name_set = 1;
9702         }
9703       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9704         ;
9705       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9706         use_custom_mac = 1;
9707       else if (unformat (i, "server"))
9708         is_server = 1;
9709       else
9710         break;
9711     }
9712
9713   if (file_name_set == 0)
9714     {
9715       errmsg ("missing socket file name\n");
9716       return -99;
9717     }
9718
9719   if (vec_len (file_name) > 255)
9720     {
9721       errmsg ("socket file name too long\n");
9722       return -99;
9723     }
9724   vec_add1 (file_name, 0);
9725
9726   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
9727
9728   mp->is_server = is_server;
9729   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9730   vec_free (file_name);
9731   if (custom_dev_instance != ~0)
9732     {
9733       mp->renumber = 1;
9734       mp->custom_dev_instance = ntohl (custom_dev_instance);
9735     }
9736   mp->use_custom_mac = use_custom_mac;
9737   clib_memcpy (mp->mac_address, hwaddr, 6);
9738
9739   S;
9740   W;
9741   /* NOTREACHED */
9742   return 0;
9743 }
9744
9745 static int
9746 api_modify_vhost_user_if (vat_main_t * vam)
9747 {
9748   unformat_input_t *i = vam->input;
9749   vl_api_modify_vhost_user_if_t *mp;
9750   f64 timeout;
9751   u8 *file_name;
9752   u8 is_server = 0;
9753   u8 file_name_set = 0;
9754   u32 custom_dev_instance = ~0;
9755   u8 sw_if_index_set = 0;
9756   u32 sw_if_index = (u32) ~ 0;
9757
9758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9759     {
9760       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9761         sw_if_index_set = 1;
9762       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9763         sw_if_index_set = 1;
9764       else if (unformat (i, "socket %s", &file_name))
9765         {
9766           file_name_set = 1;
9767         }
9768       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9769         ;
9770       else if (unformat (i, "server"))
9771         is_server = 1;
9772       else
9773         break;
9774     }
9775
9776   if (sw_if_index_set == 0)
9777     {
9778       errmsg ("missing sw_if_index or interface name\n");
9779       return -99;
9780     }
9781
9782   if (file_name_set == 0)
9783     {
9784       errmsg ("missing socket file name\n");
9785       return -99;
9786     }
9787
9788   if (vec_len (file_name) > 255)
9789     {
9790       errmsg ("socket file name too long\n");
9791       return -99;
9792     }
9793   vec_add1 (file_name, 0);
9794
9795   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
9796
9797   mp->sw_if_index = ntohl (sw_if_index);
9798   mp->is_server = is_server;
9799   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9800   vec_free (file_name);
9801   if (custom_dev_instance != ~0)
9802     {
9803       mp->renumber = 1;
9804       mp->custom_dev_instance = ntohl (custom_dev_instance);
9805     }
9806
9807   S;
9808   W;
9809   /* NOTREACHED */
9810   return 0;
9811 }
9812
9813 static int
9814 api_delete_vhost_user_if (vat_main_t * vam)
9815 {
9816   unformat_input_t *i = vam->input;
9817   vl_api_delete_vhost_user_if_t *mp;
9818   f64 timeout;
9819   u32 sw_if_index = ~0;
9820   u8 sw_if_index_set = 0;
9821
9822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9823     {
9824       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9825         sw_if_index_set = 1;
9826       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9827         sw_if_index_set = 1;
9828       else
9829         break;
9830     }
9831
9832   if (sw_if_index_set == 0)
9833     {
9834       errmsg ("missing sw_if_index or interface name\n");
9835       return -99;
9836     }
9837
9838
9839   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
9840
9841   mp->sw_if_index = ntohl (sw_if_index);
9842
9843   S;
9844   W;
9845   /* NOTREACHED */
9846   return 0;
9847 }
9848
9849 static void vl_api_sw_interface_vhost_user_details_t_handler
9850   (vl_api_sw_interface_vhost_user_details_t * mp)
9851 {
9852   vat_main_t *vam = &vat_main;
9853
9854   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
9855            (char *) mp->interface_name,
9856            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
9857            clib_net_to_host_u64 (mp->features), mp->is_server,
9858            ntohl (mp->num_regions), (char *) mp->sock_filename);
9859   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
9860 }
9861
9862 static void vl_api_sw_interface_vhost_user_details_t_handler_json
9863   (vl_api_sw_interface_vhost_user_details_t * mp)
9864 {
9865   vat_main_t *vam = &vat_main;
9866   vat_json_node_t *node = NULL;
9867
9868   if (VAT_JSON_ARRAY != vam->json_tree.type)
9869     {
9870       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9871       vat_json_init_array (&vam->json_tree);
9872     }
9873   node = vat_json_array_add (&vam->json_tree);
9874
9875   vat_json_init_object (node);
9876   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9877   vat_json_object_add_string_copy (node, "interface_name",
9878                                    mp->interface_name);
9879   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
9880                             ntohl (mp->virtio_net_hdr_sz));
9881   vat_json_object_add_uint (node, "features",
9882                             clib_net_to_host_u64 (mp->features));
9883   vat_json_object_add_uint (node, "is_server", mp->is_server);
9884   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
9885   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
9886   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
9887 }
9888
9889 static int
9890 api_sw_interface_vhost_user_dump (vat_main_t * vam)
9891 {
9892   vl_api_sw_interface_vhost_user_dump_t *mp;
9893   f64 timeout;
9894   fformat (vam->ofp,
9895            "Interface name           idx hdr_sz features server regions filename\n");
9896
9897   /* Get list of vhost-user interfaces */
9898   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
9899   S;
9900
9901   /* Use a control ping for synchronization */
9902   {
9903     vl_api_control_ping_t *mp;
9904     M (CONTROL_PING, control_ping);
9905     S;
9906   }
9907   W;
9908 }
9909
9910 static int
9911 api_show_version (vat_main_t * vam)
9912 {
9913   vl_api_show_version_t *mp;
9914   f64 timeout;
9915
9916   M (SHOW_VERSION, show_version);
9917
9918   S;
9919   W;
9920   /* NOTREACHED */
9921   return 0;
9922 }
9923
9924
9925 static int
9926 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
9927 {
9928   unformat_input_t *line_input = vam->input;
9929   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
9930   f64 timeout;
9931   ip4_address_t local4, remote4;
9932   ip6_address_t local6, remote6;
9933   u8 is_add = 1;
9934   u8 ipv4_set = 0, ipv6_set = 0;
9935   u8 local_set = 0;
9936   u8 remote_set = 0;
9937   u32 encap_vrf_id = 0;
9938   u32 decap_vrf_id = 0;
9939   u8 protocol = ~0;
9940   u32 vni;
9941   u8 vni_set = 0;
9942
9943   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9944     {
9945       if (unformat (line_input, "del"))
9946         is_add = 0;
9947       else if (unformat (line_input, "local %U",
9948                          unformat_ip4_address, &local4))
9949         {
9950           local_set = 1;
9951           ipv4_set = 1;
9952         }
9953       else if (unformat (line_input, "remote %U",
9954                          unformat_ip4_address, &remote4))
9955         {
9956           remote_set = 1;
9957           ipv4_set = 1;
9958         }
9959       else if (unformat (line_input, "local %U",
9960                          unformat_ip6_address, &local6))
9961         {
9962           local_set = 1;
9963           ipv6_set = 1;
9964         }
9965       else if (unformat (line_input, "remote %U",
9966                          unformat_ip6_address, &remote6))
9967         {
9968           remote_set = 1;
9969           ipv6_set = 1;
9970         }
9971       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9972         ;
9973       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
9974         ;
9975       else if (unformat (line_input, "vni %d", &vni))
9976         vni_set = 1;
9977       else if (unformat (line_input, "next-ip4"))
9978         protocol = 1;
9979       else if (unformat (line_input, "next-ip6"))
9980         protocol = 2;
9981       else if (unformat (line_input, "next-ethernet"))
9982         protocol = 3;
9983       else if (unformat (line_input, "next-nsh"))
9984         protocol = 4;
9985       else
9986         {
9987           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9988           return -99;
9989         }
9990     }
9991
9992   if (local_set == 0)
9993     {
9994       errmsg ("tunnel local address not specified\n");
9995       return -99;
9996     }
9997   if (remote_set == 0)
9998     {
9999       errmsg ("tunnel remote address not specified\n");
10000       return -99;
10001     }
10002   if (ipv4_set && ipv6_set)
10003     {
10004       errmsg ("both IPv4 and IPv6 addresses specified");
10005       return -99;
10006     }
10007
10008   if (vni_set == 0)
10009     {
10010       errmsg ("vni not specified\n");
10011       return -99;
10012     }
10013
10014   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10015
10016
10017   if (ipv6_set)
10018     {
10019       clib_memcpy (&mp->local, &local6, sizeof (local6));
10020       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10021     }
10022   else
10023     {
10024       clib_memcpy (&mp->local, &local4, sizeof (local4));
10025       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10026     }
10027
10028   mp->encap_vrf_id = ntohl (encap_vrf_id);
10029   mp->decap_vrf_id = ntohl (decap_vrf_id);
10030   mp->protocol = ntohl (protocol);
10031   mp->vni = ntohl (vni);
10032   mp->is_add = is_add;
10033   mp->is_ipv6 = ipv6_set;
10034
10035   S;
10036   W;
10037   /* NOTREACHED */
10038   return 0;
10039 }
10040
10041 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10042   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10043 {
10044   vat_main_t *vam = &vat_main;
10045
10046   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10047            ntohl (mp->sw_if_index),
10048            format_ip46_address, &(mp->local[0]),
10049            format_ip46_address, &(mp->remote[0]),
10050            ntohl (mp->vni),
10051            ntohl (mp->protocol),
10052            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10053 }
10054
10055 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10056   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10057 {
10058   vat_main_t *vam = &vat_main;
10059   vat_json_node_t *node = NULL;
10060   struct in_addr ip4;
10061   struct in6_addr ip6;
10062
10063   if (VAT_JSON_ARRAY != vam->json_tree.type)
10064     {
10065       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10066       vat_json_init_array (&vam->json_tree);
10067     }
10068   node = vat_json_array_add (&vam->json_tree);
10069
10070   vat_json_init_object (node);
10071   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10072   if (mp->is_ipv6)
10073     {
10074       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10075       vat_json_object_add_ip6 (node, "local", ip6);
10076       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10077       vat_json_object_add_ip6 (node, "remote", ip6);
10078     }
10079   else
10080     {
10081       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10082       vat_json_object_add_ip4 (node, "local", ip4);
10083       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10084       vat_json_object_add_ip4 (node, "remote", ip4);
10085     }
10086   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10087   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10088   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10089   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10090   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10091 }
10092
10093 static int
10094 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10095 {
10096   unformat_input_t *i = vam->input;
10097   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10098   f64 timeout;
10099   u32 sw_if_index;
10100   u8 sw_if_index_set = 0;
10101
10102   /* Parse args required to build the message */
10103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10104     {
10105       if (unformat (i, "sw_if_index %d", &sw_if_index))
10106         sw_if_index_set = 1;
10107       else
10108         break;
10109     }
10110
10111   if (sw_if_index_set == 0)
10112     {
10113       sw_if_index = ~0;
10114     }
10115
10116   if (!vam->json_output)
10117     {
10118       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10119                "sw_if_index", "local", "remote", "vni",
10120                "protocol", "encap_vrf_id", "decap_vrf_id");
10121     }
10122
10123   /* Get list of vxlan-tunnel interfaces */
10124   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10125
10126   mp->sw_if_index = htonl (sw_if_index);
10127
10128   S;
10129
10130   /* Use a control ping for synchronization */
10131   {
10132     vl_api_control_ping_t *mp;
10133     M (CONTROL_PING, control_ping);
10134     S;
10135   }
10136   W;
10137 }
10138
10139 u8 *
10140 format_l2_fib_mac_address (u8 * s, va_list * args)
10141 {
10142   u8 *a = va_arg (*args, u8 *);
10143
10144   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10145                  a[2], a[3], a[4], a[5], a[6], a[7]);
10146 }
10147
10148 static void vl_api_l2_fib_table_entry_t_handler
10149   (vl_api_l2_fib_table_entry_t * mp)
10150 {
10151   vat_main_t *vam = &vat_main;
10152
10153   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10154            "       %d       %d     %d\n",
10155            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10156            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10157            mp->bvi_mac);
10158 }
10159
10160 static void vl_api_l2_fib_table_entry_t_handler_json
10161   (vl_api_l2_fib_table_entry_t * mp)
10162 {
10163   vat_main_t *vam = &vat_main;
10164   vat_json_node_t *node = NULL;
10165
10166   if (VAT_JSON_ARRAY != vam->json_tree.type)
10167     {
10168       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10169       vat_json_init_array (&vam->json_tree);
10170     }
10171   node = vat_json_array_add (&vam->json_tree);
10172
10173   vat_json_init_object (node);
10174   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10175   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10176   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10177   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10178   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10179   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10180 }
10181
10182 static int
10183 api_l2_fib_table_dump (vat_main_t * vam)
10184 {
10185   unformat_input_t *i = vam->input;
10186   vl_api_l2_fib_table_dump_t *mp;
10187   f64 timeout;
10188   u32 bd_id;
10189   u8 bd_id_set = 0;
10190
10191   /* Parse args required to build the message */
10192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10193     {
10194       if (unformat (i, "bd_id %d", &bd_id))
10195         bd_id_set = 1;
10196       else
10197         break;
10198     }
10199
10200   if (bd_id_set == 0)
10201     {
10202       errmsg ("missing bridge domain\n");
10203       return -99;
10204     }
10205
10206   fformat (vam->ofp,
10207            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10208
10209   /* Get list of l2 fib entries */
10210   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10211
10212   mp->bd_id = ntohl (bd_id);
10213   S;
10214
10215   /* Use a control ping for synchronization */
10216   {
10217     vl_api_control_ping_t *mp;
10218     M (CONTROL_PING, control_ping);
10219     S;
10220   }
10221   W;
10222 }
10223
10224
10225 static int
10226 api_interface_name_renumber (vat_main_t * vam)
10227 {
10228   unformat_input_t *line_input = vam->input;
10229   vl_api_interface_name_renumber_t *mp;
10230   u32 sw_if_index = ~0;
10231   f64 timeout;
10232   u32 new_show_dev_instance = ~0;
10233
10234   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10235     {
10236       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10237                     &sw_if_index))
10238         ;
10239       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10240         ;
10241       else if (unformat (line_input, "new_show_dev_instance %d",
10242                          &new_show_dev_instance))
10243         ;
10244       else
10245         break;
10246     }
10247
10248   if (sw_if_index == ~0)
10249     {
10250       errmsg ("missing interface name or sw_if_index\n");
10251       return -99;
10252     }
10253
10254   if (new_show_dev_instance == ~0)
10255     {
10256       errmsg ("missing new_show_dev_instance\n");
10257       return -99;
10258     }
10259
10260   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10261
10262   mp->sw_if_index = ntohl (sw_if_index);
10263   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10264
10265   S;
10266   W;
10267 }
10268
10269 static int
10270 api_want_ip4_arp_events (vat_main_t * vam)
10271 {
10272   unformat_input_t *line_input = vam->input;
10273   vl_api_want_ip4_arp_events_t *mp;
10274   f64 timeout;
10275   ip4_address_t address;
10276   int address_set = 0;
10277   u32 enable_disable = 1;
10278
10279   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10280     {
10281       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10282         address_set = 1;
10283       else if (unformat (line_input, "del"))
10284         enable_disable = 0;
10285       else
10286         break;
10287     }
10288
10289   if (address_set == 0)
10290     {
10291       errmsg ("missing addresses\n");
10292       return -99;
10293     }
10294
10295   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10296   mp->enable_disable = enable_disable;
10297   mp->pid = getpid ();
10298   mp->address = address.as_u32;
10299
10300   S;
10301   W;
10302 }
10303
10304 static int
10305 api_want_ip6_nd_events (vat_main_t * vam)
10306 {
10307   unformat_input_t *line_input = vam->input;
10308   vl_api_want_ip6_nd_events_t *mp;
10309   f64 timeout;
10310   ip6_address_t address;
10311   int address_set = 0;
10312   u32 enable_disable = 1;
10313
10314   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10315     {
10316       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
10317         address_set = 1;
10318       else if (unformat (line_input, "del"))
10319         enable_disable = 0;
10320       else
10321         break;
10322     }
10323
10324   if (address_set == 0)
10325     {
10326       errmsg ("missing addresses\n");
10327       return -99;
10328     }
10329
10330   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
10331   mp->enable_disable = enable_disable;
10332   mp->pid = getpid ();
10333   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
10334
10335   S;
10336   W;
10337 }
10338
10339 static int
10340 api_input_acl_set_interface (vat_main_t * vam)
10341 {
10342   unformat_input_t *i = vam->input;
10343   vl_api_input_acl_set_interface_t *mp;
10344   f64 timeout;
10345   u32 sw_if_index;
10346   int sw_if_index_set;
10347   u32 ip4_table_index = ~0;
10348   u32 ip6_table_index = ~0;
10349   u32 l2_table_index = ~0;
10350   u8 is_add = 1;
10351
10352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10353     {
10354       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10355         sw_if_index_set = 1;
10356       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10357         sw_if_index_set = 1;
10358       else if (unformat (i, "del"))
10359         is_add = 0;
10360       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10361         ;
10362       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10363         ;
10364       else if (unformat (i, "l2-table %d", &l2_table_index))
10365         ;
10366       else
10367         {
10368           clib_warning ("parse error '%U'", format_unformat_error, i);
10369           return -99;
10370         }
10371     }
10372
10373   if (sw_if_index_set == 0)
10374     {
10375       errmsg ("missing interface name or sw_if_index\n");
10376       return -99;
10377     }
10378
10379   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10380
10381   mp->sw_if_index = ntohl (sw_if_index);
10382   mp->ip4_table_index = ntohl (ip4_table_index);
10383   mp->ip6_table_index = ntohl (ip6_table_index);
10384   mp->l2_table_index = ntohl (l2_table_index);
10385   mp->is_add = is_add;
10386
10387   S;
10388   W;
10389   /* NOTREACHED */
10390   return 0;
10391 }
10392
10393 static int
10394 api_ip_address_dump (vat_main_t * vam)
10395 {
10396   unformat_input_t *i = vam->input;
10397   vl_api_ip_address_dump_t *mp;
10398   u32 sw_if_index = ~0;
10399   u8 sw_if_index_set = 0;
10400   u8 ipv4_set = 0;
10401   u8 ipv6_set = 0;
10402   f64 timeout;
10403
10404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10405     {
10406       if (unformat (i, "sw_if_index %d", &sw_if_index))
10407         sw_if_index_set = 1;
10408       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10409         sw_if_index_set = 1;
10410       else if (unformat (i, "ipv4"))
10411         ipv4_set = 1;
10412       else if (unformat (i, "ipv6"))
10413         ipv6_set = 1;
10414       else
10415         break;
10416     }
10417
10418   if (ipv4_set && ipv6_set)
10419     {
10420       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10421       return -99;
10422     }
10423
10424   if ((!ipv4_set) && (!ipv6_set))
10425     {
10426       errmsg ("no ipv4 nor ipv6 flag set\n");
10427       return -99;
10428     }
10429
10430   if (sw_if_index_set == 0)
10431     {
10432       errmsg ("missing interface name or sw_if_index\n");
10433       return -99;
10434     }
10435
10436   vam->current_sw_if_index = sw_if_index;
10437   vam->is_ipv6 = ipv6_set;
10438
10439   M (IP_ADDRESS_DUMP, ip_address_dump);
10440   mp->sw_if_index = ntohl (sw_if_index);
10441   mp->is_ipv6 = ipv6_set;
10442   S;
10443
10444   /* Use a control ping for synchronization */
10445   {
10446     vl_api_control_ping_t *mp;
10447     M (CONTROL_PING, control_ping);
10448     S;
10449   }
10450   W;
10451 }
10452
10453 static int
10454 api_ip_dump (vat_main_t * vam)
10455 {
10456   vl_api_ip_dump_t *mp;
10457   unformat_input_t *in = vam->input;
10458   int ipv4_set = 0;
10459   int ipv6_set = 0;
10460   int is_ipv6;
10461   f64 timeout;
10462   int i;
10463
10464   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10465     {
10466       if (unformat (in, "ipv4"))
10467         ipv4_set = 1;
10468       else if (unformat (in, "ipv6"))
10469         ipv6_set = 1;
10470       else
10471         break;
10472     }
10473
10474   if (ipv4_set && ipv6_set)
10475     {
10476       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10477       return -99;
10478     }
10479
10480   if ((!ipv4_set) && (!ipv6_set))
10481     {
10482       errmsg ("no ipv4 nor ipv6 flag set\n");
10483       return -99;
10484     }
10485
10486   is_ipv6 = ipv6_set;
10487   vam->is_ipv6 = is_ipv6;
10488
10489   /* free old data */
10490   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10491     {
10492       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10493     }
10494   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10495
10496   M (IP_DUMP, ip_dump);
10497   mp->is_ipv6 = ipv6_set;
10498   S;
10499
10500   /* Use a control ping for synchronization */
10501   {
10502     vl_api_control_ping_t *mp;
10503     M (CONTROL_PING, control_ping);
10504     S;
10505   }
10506   W;
10507 }
10508
10509 static int
10510 api_ipsec_spd_add_del (vat_main_t * vam)
10511 {
10512 #if DPDK > 0
10513   unformat_input_t *i = vam->input;
10514   vl_api_ipsec_spd_add_del_t *mp;
10515   f64 timeout;
10516   u32 spd_id = ~0;
10517   u8 is_add = 1;
10518
10519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10520     {
10521       if (unformat (i, "spd_id %d", &spd_id))
10522         ;
10523       else if (unformat (i, "del"))
10524         is_add = 0;
10525       else
10526         {
10527           clib_warning ("parse error '%U'", format_unformat_error, i);
10528           return -99;
10529         }
10530     }
10531   if (spd_id == ~0)
10532     {
10533       errmsg ("spd_id must be set\n");
10534       return -99;
10535     }
10536
10537   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10538
10539   mp->spd_id = ntohl (spd_id);
10540   mp->is_add = is_add;
10541
10542   S;
10543   W;
10544   /* NOTREACHED */
10545   return 0;
10546 #else
10547   clib_warning ("unsupported (no dpdk)");
10548   return -99;
10549 #endif
10550 }
10551
10552 static int
10553 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10554 {
10555 #if DPDK > 0
10556   unformat_input_t *i = vam->input;
10557   vl_api_ipsec_interface_add_del_spd_t *mp;
10558   f64 timeout;
10559   u32 sw_if_index;
10560   u8 sw_if_index_set = 0;
10561   u32 spd_id = (u32) ~ 0;
10562   u8 is_add = 1;
10563
10564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10565     {
10566       if (unformat (i, "del"))
10567         is_add = 0;
10568       else if (unformat (i, "spd_id %d", &spd_id))
10569         ;
10570       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10571         sw_if_index_set = 1;
10572       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10573         sw_if_index_set = 1;
10574       else
10575         {
10576           clib_warning ("parse error '%U'", format_unformat_error, i);
10577           return -99;
10578         }
10579
10580     }
10581
10582   if (spd_id == (u32) ~ 0)
10583     {
10584       errmsg ("spd_id must be set\n");
10585       return -99;
10586     }
10587
10588   if (sw_if_index_set == 0)
10589     {
10590       errmsg ("missing interface name or sw_if_index\n");
10591       return -99;
10592     }
10593
10594   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10595
10596   mp->spd_id = ntohl (spd_id);
10597   mp->sw_if_index = ntohl (sw_if_index);
10598   mp->is_add = is_add;
10599
10600   S;
10601   W;
10602   /* NOTREACHED */
10603   return 0;
10604 #else
10605   clib_warning ("unsupported (no dpdk)");
10606   return -99;
10607 #endif
10608 }
10609
10610 static int
10611 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10612 {
10613 #if DPDK > 0
10614   unformat_input_t *i = vam->input;
10615   vl_api_ipsec_spd_add_del_entry_t *mp;
10616   f64 timeout;
10617   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10618   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10619   i32 priority = 0;
10620   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10621   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10622   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10623   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10624
10625   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10626   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10627   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10628   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10629   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10630   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10631
10632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10633     {
10634       if (unformat (i, "del"))
10635         is_add = 0;
10636       if (unformat (i, "outbound"))
10637         is_outbound = 1;
10638       if (unformat (i, "inbound"))
10639         is_outbound = 0;
10640       else if (unformat (i, "spd_id %d", &spd_id))
10641         ;
10642       else if (unformat (i, "sa_id %d", &sa_id))
10643         ;
10644       else if (unformat (i, "priority %d", &priority))
10645         ;
10646       else if (unformat (i, "protocol %d", &protocol))
10647         ;
10648       else if (unformat (i, "lport_start %d", &lport_start))
10649         ;
10650       else if (unformat (i, "lport_stop %d", &lport_stop))
10651         ;
10652       else if (unformat (i, "rport_start %d", &rport_start))
10653         ;
10654       else if (unformat (i, "rport_stop %d", &rport_stop))
10655         ;
10656       else
10657         if (unformat
10658             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10659         {
10660           is_ipv6 = 0;
10661           is_ip_any = 0;
10662         }
10663       else
10664         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10665         {
10666           is_ipv6 = 0;
10667           is_ip_any = 0;
10668         }
10669       else
10670         if (unformat
10671             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10672         {
10673           is_ipv6 = 0;
10674           is_ip_any = 0;
10675         }
10676       else
10677         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
10678         {
10679           is_ipv6 = 0;
10680           is_ip_any = 0;
10681         }
10682       else
10683         if (unformat
10684             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
10685         {
10686           is_ipv6 = 1;
10687           is_ip_any = 0;
10688         }
10689       else
10690         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
10691         {
10692           is_ipv6 = 1;
10693           is_ip_any = 0;
10694         }
10695       else
10696         if (unformat
10697             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
10698         {
10699           is_ipv6 = 1;
10700           is_ip_any = 0;
10701         }
10702       else
10703         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
10704         {
10705           is_ipv6 = 1;
10706           is_ip_any = 0;
10707         }
10708       else
10709         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10710         {
10711           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10712             {
10713               clib_warning ("unsupported action: 'resolve'");
10714               return -99;
10715             }
10716         }
10717       else
10718         {
10719           clib_warning ("parse error '%U'", format_unformat_error, i);
10720           return -99;
10721         }
10722
10723     }
10724
10725   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
10726
10727   mp->spd_id = ntohl (spd_id);
10728   mp->priority = ntohl (priority);
10729   mp->is_outbound = is_outbound;
10730
10731   mp->is_ipv6 = is_ipv6;
10732   if (is_ipv6 || is_ip_any)
10733     {
10734       clib_memcpy (mp->remote_address_start, &raddr6_start,
10735                    sizeof (ip6_address_t));
10736       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
10737                    sizeof (ip6_address_t));
10738       clib_memcpy (mp->local_address_start, &laddr6_start,
10739                    sizeof (ip6_address_t));
10740       clib_memcpy (mp->local_address_stop, &laddr6_stop,
10741                    sizeof (ip6_address_t));
10742     }
10743   else
10744     {
10745       clib_memcpy (mp->remote_address_start, &raddr4_start,
10746                    sizeof (ip4_address_t));
10747       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
10748                    sizeof (ip4_address_t));
10749       clib_memcpy (mp->local_address_start, &laddr4_start,
10750                    sizeof (ip4_address_t));
10751       clib_memcpy (mp->local_address_stop, &laddr4_stop,
10752                    sizeof (ip4_address_t));
10753     }
10754   mp->protocol = (u8) protocol;
10755   mp->local_port_start = ntohs ((u16) lport_start);
10756   mp->local_port_stop = ntohs ((u16) lport_stop);
10757   mp->remote_port_start = ntohs ((u16) rport_start);
10758   mp->remote_port_stop = ntohs ((u16) rport_stop);
10759   mp->policy = (u8) policy;
10760   mp->sa_id = ntohl (sa_id);
10761   mp->is_add = is_add;
10762   mp->is_ip_any = is_ip_any;
10763   S;
10764   W;
10765   /* NOTREACHED */
10766   return 0;
10767 #else
10768   clib_warning ("unsupported (no dpdk)");
10769   return -99;
10770 #endif
10771 }
10772
10773 static int
10774 api_ipsec_sad_add_del_entry (vat_main_t * vam)
10775 {
10776 #if DPDK > 0
10777   unformat_input_t *i = vam->input;
10778   vl_api_ipsec_sad_add_del_entry_t *mp;
10779   f64 timeout;
10780   u32 sad_id = 0, spi = 0;
10781   u8 *ck = 0, *ik = 0;
10782   u8 is_add = 1;
10783
10784   u8 protocol = IPSEC_PROTOCOL_AH;
10785   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
10786   u32 crypto_alg = 0, integ_alg = 0;
10787   ip4_address_t tun_src4;
10788   ip4_address_t tun_dst4;
10789   ip6_address_t tun_src6;
10790   ip6_address_t tun_dst6;
10791
10792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10793     {
10794       if (unformat (i, "del"))
10795         is_add = 0;
10796       else if (unformat (i, "sad_id %d", &sad_id))
10797         ;
10798       else if (unformat (i, "spi %d", &spi))
10799         ;
10800       else if (unformat (i, "esp"))
10801         protocol = IPSEC_PROTOCOL_ESP;
10802       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
10803         {
10804           is_tunnel = 1;
10805           is_tunnel_ipv6 = 0;
10806         }
10807       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
10808         {
10809           is_tunnel = 1;
10810           is_tunnel_ipv6 = 0;
10811         }
10812       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
10813         {
10814           is_tunnel = 1;
10815           is_tunnel_ipv6 = 1;
10816         }
10817       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
10818         {
10819           is_tunnel = 1;
10820           is_tunnel_ipv6 = 1;
10821         }
10822       else
10823         if (unformat
10824             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
10825         {
10826           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
10827               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
10828             {
10829               clib_warning ("unsupported crypto-alg: '%U'",
10830                             format_ipsec_crypto_alg, crypto_alg);
10831               return -99;
10832             }
10833         }
10834       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10835         ;
10836       else
10837         if (unformat
10838             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
10839         {
10840           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
10841               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
10842             {
10843               clib_warning ("unsupported integ-alg: '%U'",
10844                             format_ipsec_integ_alg, integ_alg);
10845               return -99;
10846             }
10847         }
10848       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10849         ;
10850       else
10851         {
10852           clib_warning ("parse error '%U'", format_unformat_error, i);
10853           return -99;
10854         }
10855
10856     }
10857
10858   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
10859
10860   mp->sad_id = ntohl (sad_id);
10861   mp->is_add = is_add;
10862   mp->protocol = protocol;
10863   mp->spi = ntohl (spi);
10864   mp->is_tunnel = is_tunnel;
10865   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
10866   mp->crypto_algorithm = crypto_alg;
10867   mp->integrity_algorithm = integ_alg;
10868   mp->crypto_key_length = vec_len (ck);
10869   mp->integrity_key_length = vec_len (ik);
10870
10871   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10872     mp->crypto_key_length = sizeof (mp->crypto_key);
10873
10874   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10875     mp->integrity_key_length = sizeof (mp->integrity_key);
10876
10877   if (ck)
10878     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10879   if (ik)
10880     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10881
10882   if (is_tunnel)
10883     {
10884       if (is_tunnel_ipv6)
10885         {
10886           clib_memcpy (mp->tunnel_src_address, &tun_src6,
10887                        sizeof (ip6_address_t));
10888           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
10889                        sizeof (ip6_address_t));
10890         }
10891       else
10892         {
10893           clib_memcpy (mp->tunnel_src_address, &tun_src4,
10894                        sizeof (ip4_address_t));
10895           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
10896                        sizeof (ip4_address_t));
10897         }
10898     }
10899
10900   S;
10901   W;
10902   /* NOTREACHED */
10903   return 0;
10904 #else
10905   clib_warning ("unsupported (no dpdk)");
10906   return -99;
10907 #endif
10908 }
10909
10910 static int
10911 api_ipsec_sa_set_key (vat_main_t * vam)
10912 {
10913 #if DPDK > 0
10914   unformat_input_t *i = vam->input;
10915   vl_api_ipsec_sa_set_key_t *mp;
10916   f64 timeout;
10917   u32 sa_id;
10918   u8 *ck = 0, *ik = 0;
10919
10920   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10921     {
10922       if (unformat (i, "sa_id %d", &sa_id))
10923         ;
10924       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10925         ;
10926       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10927         ;
10928       else
10929         {
10930           clib_warning ("parse error '%U'", format_unformat_error, i);
10931           return -99;
10932         }
10933     }
10934
10935   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
10936
10937   mp->sa_id = ntohl (sa_id);
10938   mp->crypto_key_length = vec_len (ck);
10939   mp->integrity_key_length = vec_len (ik);
10940
10941   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10942     mp->crypto_key_length = sizeof (mp->crypto_key);
10943
10944   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10945     mp->integrity_key_length = sizeof (mp->integrity_key);
10946
10947   if (ck)
10948     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10949   if (ik)
10950     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10951
10952   S;
10953   W;
10954   /* NOTREACHED */
10955   return 0;
10956 #else
10957   clib_warning ("unsupported (no dpdk)");
10958   return -99;
10959 #endif
10960 }
10961
10962 static int
10963 api_ikev2_profile_add_del (vat_main_t * vam)
10964 {
10965 #if DPDK > 0
10966   unformat_input_t *i = vam->input;
10967   vl_api_ikev2_profile_add_del_t *mp;
10968   f64 timeout;
10969   u8 is_add = 1;
10970   u8 *name = 0;
10971
10972   const char *valid_chars = "a-zA-Z0-9_";
10973
10974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10975     {
10976       if (unformat (i, "del"))
10977         is_add = 0;
10978       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10979         vec_add1 (name, 0);
10980       else
10981         {
10982           errmsg ("parse error '%U'", format_unformat_error, i);
10983           return -99;
10984         }
10985     }
10986
10987   if (!vec_len (name))
10988     {
10989       errmsg ("profile name must be specified");
10990       return -99;
10991     }
10992
10993   if (vec_len (name) > 64)
10994     {
10995       errmsg ("profile name too long");
10996       return -99;
10997     }
10998
10999   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11000
11001   clib_memcpy (mp->name, name, vec_len (name));
11002   mp->is_add = is_add;
11003   vec_free (name);
11004
11005   S;
11006   W;
11007   /* NOTREACHED */
11008   return 0;
11009 #else
11010   clib_warning ("unsupported (no dpdk)");
11011   return -99;
11012 #endif
11013 }
11014
11015 static int
11016 api_ikev2_profile_set_auth (vat_main_t * vam)
11017 {
11018 #if DPDK > 0
11019   unformat_input_t *i = vam->input;
11020   vl_api_ikev2_profile_set_auth_t *mp;
11021   f64 timeout;
11022   u8 *name = 0;
11023   u8 *data = 0;
11024   u32 auth_method = 0;
11025   u8 is_hex = 0;
11026
11027   const char *valid_chars = "a-zA-Z0-9_";
11028
11029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11030     {
11031       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11032         vec_add1 (name, 0);
11033       else if (unformat (i, "auth_method %U",
11034                          unformat_ikev2_auth_method, &auth_method))
11035         ;
11036       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11037         is_hex = 1;
11038       else if (unformat (i, "auth_data %v", &data))
11039         ;
11040       else
11041         {
11042           errmsg ("parse error '%U'", format_unformat_error, i);
11043           return -99;
11044         }
11045     }
11046
11047   if (!vec_len (name))
11048     {
11049       errmsg ("profile name must be specified");
11050       return -99;
11051     }
11052
11053   if (vec_len (name) > 64)
11054     {
11055       errmsg ("profile name too long");
11056       return -99;
11057     }
11058
11059   if (!vec_len (data))
11060     {
11061       errmsg ("auth_data must be specified");
11062       return -99;
11063     }
11064
11065   if (!auth_method)
11066     {
11067       errmsg ("auth_method must be specified");
11068       return -99;
11069     }
11070
11071   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11072
11073   mp->is_hex = is_hex;
11074   mp->auth_method = (u8) auth_method;
11075   mp->data_len = vec_len (data);
11076   clib_memcpy (mp->name, name, vec_len (name));
11077   clib_memcpy (mp->data, data, vec_len (data));
11078   vec_free (name);
11079   vec_free (data);
11080
11081   S;
11082   W;
11083   /* NOTREACHED */
11084   return 0;
11085 #else
11086   clib_warning ("unsupported (no dpdk)");
11087   return -99;
11088 #endif
11089 }
11090
11091 static int
11092 api_ikev2_profile_set_id (vat_main_t * vam)
11093 {
11094 #if DPDK > 0
11095   unformat_input_t *i = vam->input;
11096   vl_api_ikev2_profile_set_id_t *mp;
11097   f64 timeout;
11098   u8 *name = 0;
11099   u8 *data = 0;
11100   u8 is_local = 0;
11101   u32 id_type = 0;
11102   ip4_address_t ip4;
11103
11104   const char *valid_chars = "a-zA-Z0-9_";
11105
11106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11107     {
11108       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11109         vec_add1 (name, 0);
11110       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11111         ;
11112       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11113         {
11114           data = vec_new (u8, 4);
11115           clib_memcpy (data, ip4.as_u8, 4);
11116         }
11117       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11118         ;
11119       else if (unformat (i, "id_data %v", &data))
11120         ;
11121       else if (unformat (i, "local"))
11122         is_local = 1;
11123       else if (unformat (i, "remote"))
11124         is_local = 0;
11125       else
11126         {
11127           errmsg ("parse error '%U'", format_unformat_error, i);
11128           return -99;
11129         }
11130     }
11131
11132   if (!vec_len (name))
11133     {
11134       errmsg ("profile name must be specified");
11135       return -99;
11136     }
11137
11138   if (vec_len (name) > 64)
11139     {
11140       errmsg ("profile name too long");
11141       return -99;
11142     }
11143
11144   if (!vec_len (data))
11145     {
11146       errmsg ("id_data must be specified");
11147       return -99;
11148     }
11149
11150   if (!id_type)
11151     {
11152       errmsg ("id_type must be specified");
11153       return -99;
11154     }
11155
11156   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11157
11158   mp->is_local = is_local;
11159   mp->id_type = (u8) id_type;
11160   mp->data_len = vec_len (data);
11161   clib_memcpy (mp->name, name, vec_len (name));
11162   clib_memcpy (mp->data, data, vec_len (data));
11163   vec_free (name);
11164   vec_free (data);
11165
11166   S;
11167   W;
11168   /* NOTREACHED */
11169   return 0;
11170 #else
11171   clib_warning ("unsupported (no dpdk)");
11172   return -99;
11173 #endif
11174 }
11175
11176 static int
11177 api_ikev2_profile_set_ts (vat_main_t * vam)
11178 {
11179 #if DPDK > 0
11180   unformat_input_t *i = vam->input;
11181   vl_api_ikev2_profile_set_ts_t *mp;
11182   f64 timeout;
11183   u8 *name = 0;
11184   u8 is_local = 0;
11185   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11186   ip4_address_t start_addr, end_addr;
11187
11188   const char *valid_chars = "a-zA-Z0-9_";
11189
11190   start_addr.as_u32 = 0;
11191   end_addr.as_u32 = (u32) ~ 0;
11192
11193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11194     {
11195       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11196         vec_add1 (name, 0);
11197       else if (unformat (i, "protocol %d", &proto))
11198         ;
11199       else if (unformat (i, "start_port %d", &start_port))
11200         ;
11201       else if (unformat (i, "end_port %d", &end_port))
11202         ;
11203       else
11204         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11205         ;
11206       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11207         ;
11208       else if (unformat (i, "local"))
11209         is_local = 1;
11210       else if (unformat (i, "remote"))
11211         is_local = 0;
11212       else
11213         {
11214           errmsg ("parse error '%U'", format_unformat_error, i);
11215           return -99;
11216         }
11217     }
11218
11219   if (!vec_len (name))
11220     {
11221       errmsg ("profile name must be specified");
11222       return -99;
11223     }
11224
11225   if (vec_len (name) > 64)
11226     {
11227       errmsg ("profile name too long");
11228       return -99;
11229     }
11230
11231   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11232
11233   mp->is_local = is_local;
11234   mp->proto = (u8) proto;
11235   mp->start_port = (u16) start_port;
11236   mp->end_port = (u16) end_port;
11237   mp->start_addr = start_addr.as_u32;
11238   mp->end_addr = end_addr.as_u32;
11239   clib_memcpy (mp->name, name, vec_len (name));
11240   vec_free (name);
11241
11242   S;
11243   W;
11244   /* NOTREACHED */
11245   return 0;
11246 #else
11247   clib_warning ("unsupported (no dpdk)");
11248   return -99;
11249 #endif
11250 }
11251
11252 static int
11253 api_ikev2_set_local_key (vat_main_t * vam)
11254 {
11255 #if DPDK > 0
11256   unformat_input_t *i = vam->input;
11257   vl_api_ikev2_set_local_key_t *mp;
11258   f64 timeout;
11259   u8 *file = 0;
11260
11261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11262     {
11263       if (unformat (i, "file %v", &file))
11264         vec_add1 (file, 0);
11265       else
11266         {
11267           errmsg ("parse error '%U'", format_unformat_error, i);
11268           return -99;
11269         }
11270     }
11271
11272   if (!vec_len (file))
11273     {
11274       errmsg ("RSA key file must be specified");
11275       return -99;
11276     }
11277
11278   if (vec_len (file) > 256)
11279     {
11280       errmsg ("file name too long");
11281       return -99;
11282     }
11283
11284   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11285
11286   clib_memcpy (mp->key_file, file, vec_len (file));
11287   vec_free (file);
11288
11289   S;
11290   W;
11291   /* NOTREACHED */
11292   return 0;
11293 #else
11294   clib_warning ("unsupported (no dpdk)");
11295   return -99;
11296 #endif
11297 }
11298
11299 /*
11300  * MAP
11301  */
11302 static int
11303 api_map_add_domain (vat_main_t * vam)
11304 {
11305   unformat_input_t *i = vam->input;
11306   vl_api_map_add_domain_t *mp;
11307   f64 timeout;
11308
11309   ip4_address_t ip4_prefix;
11310   ip6_address_t ip6_prefix;
11311   ip6_address_t ip6_src;
11312   u32 num_m_args = 0;
11313   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11314     0, psid_length = 0;
11315   u8 is_translation = 0;
11316   u32 mtu = 0;
11317   u32 ip6_src_len = 128;
11318
11319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11320     {
11321       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11322                     &ip4_prefix, &ip4_prefix_len))
11323         num_m_args++;
11324       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11325                          &ip6_prefix, &ip6_prefix_len))
11326         num_m_args++;
11327       else
11328         if (unformat
11329             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11330              &ip6_src_len))
11331         num_m_args++;
11332       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11333         num_m_args++;
11334       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11335         num_m_args++;
11336       else if (unformat (i, "psid-offset %d", &psid_offset))
11337         num_m_args++;
11338       else if (unformat (i, "psid-len %d", &psid_length))
11339         num_m_args++;
11340       else if (unformat (i, "mtu %d", &mtu))
11341         num_m_args++;
11342       else if (unformat (i, "map-t"))
11343         is_translation = 1;
11344       else
11345         {
11346           clib_warning ("parse error '%U'", format_unformat_error, i);
11347           return -99;
11348         }
11349     }
11350
11351   if (num_m_args < 3)
11352     {
11353       errmsg ("mandatory argument(s) missing\n");
11354       return -99;
11355     }
11356
11357   /* Construct the API message */
11358   M (MAP_ADD_DOMAIN, map_add_domain);
11359
11360   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11361   mp->ip4_prefix_len = ip4_prefix_len;
11362
11363   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11364   mp->ip6_prefix_len = ip6_prefix_len;
11365
11366   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11367   mp->ip6_src_prefix_len = ip6_src_len;
11368
11369   mp->ea_bits_len = ea_bits_len;
11370   mp->psid_offset = psid_offset;
11371   mp->psid_length = psid_length;
11372   mp->is_translation = is_translation;
11373   mp->mtu = htons (mtu);
11374
11375   /* send it... */
11376   S;
11377
11378   /* Wait for a reply, return good/bad news  */
11379   W;
11380 }
11381
11382 static int
11383 api_map_del_domain (vat_main_t * vam)
11384 {
11385   unformat_input_t *i = vam->input;
11386   vl_api_map_del_domain_t *mp;
11387   f64 timeout;
11388
11389   u32 num_m_args = 0;
11390   u32 index;
11391
11392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11393     {
11394       if (unformat (i, "index %d", &index))
11395         num_m_args++;
11396       else
11397         {
11398           clib_warning ("parse error '%U'", format_unformat_error, i);
11399           return -99;
11400         }
11401     }
11402
11403   if (num_m_args != 1)
11404     {
11405       errmsg ("mandatory argument(s) missing\n");
11406       return -99;
11407     }
11408
11409   /* Construct the API message */
11410   M (MAP_DEL_DOMAIN, map_del_domain);
11411
11412   mp->index = ntohl (index);
11413
11414   /* send it... */
11415   S;
11416
11417   /* Wait for a reply, return good/bad news  */
11418   W;
11419 }
11420
11421 static int
11422 api_map_add_del_rule (vat_main_t * vam)
11423 {
11424   unformat_input_t *i = vam->input;
11425   vl_api_map_add_del_rule_t *mp;
11426   f64 timeout;
11427   u8 is_add = 1;
11428   ip6_address_t ip6_dst;
11429   u32 num_m_args = 0, index, psid = 0;
11430
11431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11432     {
11433       if (unformat (i, "index %d", &index))
11434         num_m_args++;
11435       else if (unformat (i, "psid %d", &psid))
11436         num_m_args++;
11437       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11438         num_m_args++;
11439       else if (unformat (i, "del"))
11440         {
11441           is_add = 0;
11442         }
11443       else
11444         {
11445           clib_warning ("parse error '%U'", format_unformat_error, i);
11446           return -99;
11447         }
11448     }
11449
11450   /* Construct the API message */
11451   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11452
11453   mp->index = ntohl (index);
11454   mp->is_add = is_add;
11455   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11456   mp->psid = ntohs (psid);
11457
11458   /* send it... */
11459   S;
11460
11461   /* Wait for a reply, return good/bad news  */
11462   W;
11463 }
11464
11465 static int
11466 api_map_domain_dump (vat_main_t * vam)
11467 {
11468   vl_api_map_domain_dump_t *mp;
11469   f64 timeout;
11470
11471   /* Construct the API message */
11472   M (MAP_DOMAIN_DUMP, map_domain_dump);
11473
11474   /* send it... */
11475   S;
11476
11477   /* Use a control ping for synchronization */
11478   {
11479     vl_api_control_ping_t *mp;
11480     M (CONTROL_PING, control_ping);
11481     S;
11482   }
11483   W;
11484 }
11485
11486 static int
11487 api_map_rule_dump (vat_main_t * vam)
11488 {
11489   unformat_input_t *i = vam->input;
11490   vl_api_map_rule_dump_t *mp;
11491   f64 timeout;
11492   u32 domain_index = ~0;
11493
11494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11495     {
11496       if (unformat (i, "index %u", &domain_index))
11497         ;
11498       else
11499         break;
11500     }
11501
11502   if (domain_index == ~0)
11503     {
11504       clib_warning ("parse error: domain index expected");
11505       return -99;
11506     }
11507
11508   /* Construct the API message */
11509   M (MAP_RULE_DUMP, map_rule_dump);
11510
11511   mp->domain_index = htonl (domain_index);
11512
11513   /* send it... */
11514   S;
11515
11516   /* Use a control ping for synchronization */
11517   {
11518     vl_api_control_ping_t *mp;
11519     M (CONTROL_PING, control_ping);
11520     S;
11521   }
11522   W;
11523 }
11524
11525 static void vl_api_map_add_domain_reply_t_handler
11526   (vl_api_map_add_domain_reply_t * mp)
11527 {
11528   vat_main_t *vam = &vat_main;
11529   i32 retval = ntohl (mp->retval);
11530
11531   if (vam->async_mode)
11532     {
11533       vam->async_errors += (retval < 0);
11534     }
11535   else
11536     {
11537       vam->retval = retval;
11538       vam->result_ready = 1;
11539     }
11540 }
11541
11542 static void vl_api_map_add_domain_reply_t_handler_json
11543   (vl_api_map_add_domain_reply_t * mp)
11544 {
11545   vat_main_t *vam = &vat_main;
11546   vat_json_node_t node;
11547
11548   vat_json_init_object (&node);
11549   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11550   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11551
11552   vat_json_print (vam->ofp, &node);
11553   vat_json_free (&node);
11554
11555   vam->retval = ntohl (mp->retval);
11556   vam->result_ready = 1;
11557 }
11558
11559 static int
11560 api_get_first_msg_id (vat_main_t * vam)
11561 {
11562   vl_api_get_first_msg_id_t *mp;
11563   f64 timeout;
11564   unformat_input_t *i = vam->input;
11565   u8 *name;
11566   u8 name_set = 0;
11567
11568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11569     {
11570       if (unformat (i, "client %s", &name))
11571         name_set = 1;
11572       else
11573         break;
11574     }
11575
11576   if (name_set == 0)
11577     {
11578       errmsg ("missing client name\n");
11579       return -99;
11580     }
11581   vec_add1 (name, 0);
11582
11583   if (vec_len (name) > 63)
11584     {
11585       errmsg ("client name too long\n");
11586       return -99;
11587     }
11588
11589   M (GET_FIRST_MSG_ID, get_first_msg_id);
11590   clib_memcpy (mp->name, name, vec_len (name));
11591   S;
11592   W;
11593   /* NOTREACHED */
11594   return 0;
11595 }
11596
11597 static int
11598 api_cop_interface_enable_disable (vat_main_t * vam)
11599 {
11600   unformat_input_t *line_input = vam->input;
11601   vl_api_cop_interface_enable_disable_t *mp;
11602   f64 timeout;
11603   u32 sw_if_index = ~0;
11604   u8 enable_disable = 1;
11605
11606   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11607     {
11608       if (unformat (line_input, "disable"))
11609         enable_disable = 0;
11610       if (unformat (line_input, "enable"))
11611         enable_disable = 1;
11612       else if (unformat (line_input, "%U", unformat_sw_if_index,
11613                          vam, &sw_if_index))
11614         ;
11615       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11616         ;
11617       else
11618         break;
11619     }
11620
11621   if (sw_if_index == ~0)
11622     {
11623       errmsg ("missing interface name or sw_if_index\n");
11624       return -99;
11625     }
11626
11627   /* Construct the API message */
11628   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11629   mp->sw_if_index = ntohl (sw_if_index);
11630   mp->enable_disable = enable_disable;
11631
11632   /* send it... */
11633   S;
11634   /* Wait for the reply */
11635   W;
11636 }
11637
11638 static int
11639 api_cop_whitelist_enable_disable (vat_main_t * vam)
11640 {
11641   unformat_input_t *line_input = vam->input;
11642   vl_api_cop_whitelist_enable_disable_t *mp;
11643   f64 timeout;
11644   u32 sw_if_index = ~0;
11645   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11646   u32 fib_id = 0;
11647
11648   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11649     {
11650       if (unformat (line_input, "ip4"))
11651         ip4 = 1;
11652       else if (unformat (line_input, "ip6"))
11653         ip6 = 1;
11654       else if (unformat (line_input, "default"))
11655         default_cop = 1;
11656       else if (unformat (line_input, "%U", unformat_sw_if_index,
11657                          vam, &sw_if_index))
11658         ;
11659       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11660         ;
11661       else if (unformat (line_input, "fib-id %d", &fib_id))
11662         ;
11663       else
11664         break;
11665     }
11666
11667   if (sw_if_index == ~0)
11668     {
11669       errmsg ("missing interface name or sw_if_index\n");
11670       return -99;
11671     }
11672
11673   /* Construct the API message */
11674   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
11675   mp->sw_if_index = ntohl (sw_if_index);
11676   mp->fib_id = ntohl (fib_id);
11677   mp->ip4 = ip4;
11678   mp->ip6 = ip6;
11679   mp->default_cop = default_cop;
11680
11681   /* send it... */
11682   S;
11683   /* Wait for the reply */
11684   W;
11685 }
11686
11687 static int
11688 api_get_node_graph (vat_main_t * vam)
11689 {
11690   vl_api_get_node_graph_t *mp;
11691   f64 timeout;
11692
11693   M (GET_NODE_GRAPH, get_node_graph);
11694
11695   /* send it... */
11696   S;
11697   /* Wait for the reply */
11698   W;
11699 }
11700
11701 /* *INDENT-OFF* */
11702 /** Used for parsing LISP eids */
11703 typedef CLIB_PACKED(struct{
11704   u8 addr[16];   /**< eid address */
11705   u32 len;       /**< prefix length if IP */
11706   u8 type;      /**< type of eid */
11707 }) lisp_eid_vat_t;
11708 /* *INDENT-ON* */
11709
11710 static uword
11711 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
11712 {
11713   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
11714
11715   memset (a, 0, sizeof (a[0]));
11716
11717   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
11718     {
11719       a->type = 0;              /* ipv4 type */
11720     }
11721   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
11722     {
11723       a->type = 1;              /* ipv6 type */
11724     }
11725   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
11726     {
11727       a->type = 2;              /* mac type */
11728     }
11729   else
11730     {
11731       return 0;
11732     }
11733
11734   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
11735     {
11736       return 0;
11737     }
11738
11739   return 1;
11740 }
11741
11742 static int
11743 lisp_eid_size_vat (u8 type)
11744 {
11745   switch (type)
11746     {
11747     case 0:
11748       return 4;
11749     case 1:
11750       return 16;
11751     case 2:
11752       return 6;
11753     }
11754   return 0;
11755 }
11756
11757 static void
11758 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
11759 {
11760   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
11761 }
11762
11763 /* *INDENT-OFF* */
11764 /** Used for transferring locators via VPP API */
11765 typedef CLIB_PACKED(struct
11766 {
11767   u32 sw_if_index; /**< locator sw_if_index */
11768   u8 priority; /**< locator priority */
11769   u8 weight;   /**< locator weight */
11770 }) ls_locator_t;
11771 /* *INDENT-ON* */
11772
11773 static int
11774 api_lisp_add_del_locator_set (vat_main_t * vam)
11775 {
11776   unformat_input_t *input = vam->input;
11777   vl_api_lisp_add_del_locator_set_t *mp;
11778   f64 timeout = ~0;
11779   u8 is_add = 1;
11780   u8 *locator_set_name = NULL;
11781   u8 locator_set_name_set = 0;
11782   ls_locator_t locator, *locators = 0;
11783   u32 sw_if_index, priority, weight;
11784
11785   /* Parse args required to build the message */
11786   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11787     {
11788       if (unformat (input, "del"))
11789         {
11790           is_add = 0;
11791         }
11792       else if (unformat (input, "locator-set %s", &locator_set_name))
11793         {
11794           locator_set_name_set = 1;
11795         }
11796       else if (unformat (input, "sw_if_index %u p %u w %u",
11797                          &sw_if_index, &priority, &weight))
11798         {
11799           locator.sw_if_index = htonl (sw_if_index);
11800           locator.priority = priority;
11801           locator.weight = weight;
11802           vec_add1 (locators, locator);
11803         }
11804       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
11805                          vam, &sw_if_index, &priority, &weight))
11806         {
11807           locator.sw_if_index = htonl (sw_if_index);
11808           locator.priority = priority;
11809           locator.weight = weight;
11810           vec_add1 (locators, locator);
11811         }
11812       else
11813         break;
11814     }
11815
11816   if (locator_set_name_set == 0)
11817     {
11818       errmsg ("missing locator-set name");
11819       vec_free (locators);
11820       return -99;
11821     }
11822
11823   if (vec_len (locator_set_name) > 64)
11824     {
11825       errmsg ("locator-set name too long\n");
11826       vec_free (locator_set_name);
11827       vec_free (locators);
11828       return -99;
11829     }
11830   vec_add1 (locator_set_name, 0);
11831
11832   /* Construct the API message */
11833   M (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
11834
11835   mp->is_add = is_add;
11836   clib_memcpy (mp->locator_set_name, locator_set_name,
11837                vec_len (locator_set_name));
11838   vec_free (locator_set_name);
11839
11840   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
11841   if (locators)
11842     clib_memcpy (mp->locators, locators,
11843                  (sizeof (ls_locator_t) * vec_len (locators)));
11844   vec_free (locators);
11845
11846   /* send it... */
11847   S;
11848
11849   /* Wait for a reply... */
11850   W;
11851
11852   /* NOTREACHED */
11853   return 0;
11854 }
11855
11856 static int
11857 api_lisp_add_del_locator (vat_main_t * vam)
11858 {
11859   unformat_input_t *input = vam->input;
11860   vl_api_lisp_add_del_locator_t *mp;
11861   f64 timeout = ~0;
11862   u32 tmp_if_index = ~0;
11863   u32 sw_if_index = ~0;
11864   u8 sw_if_index_set = 0;
11865   u8 sw_if_index_if_name_set = 0;
11866   u32 priority = ~0;
11867   u8 priority_set = 0;
11868   u32 weight = ~0;
11869   u8 weight_set = 0;
11870   u8 is_add = 1;
11871   u8 *locator_set_name = NULL;
11872   u8 locator_set_name_set = 0;
11873
11874   /* Parse args required to build the message */
11875   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11876     {
11877       if (unformat (input, "del"))
11878         {
11879           is_add = 0;
11880         }
11881       else if (unformat (input, "locator-set %s", &locator_set_name))
11882         {
11883           locator_set_name_set = 1;
11884         }
11885       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
11886                          &tmp_if_index))
11887         {
11888           sw_if_index_if_name_set = 1;
11889           sw_if_index = tmp_if_index;
11890         }
11891       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
11892         {
11893           sw_if_index_set = 1;
11894           sw_if_index = tmp_if_index;
11895         }
11896       else if (unformat (input, "p %d", &priority))
11897         {
11898           priority_set = 1;
11899         }
11900       else if (unformat (input, "w %d", &weight))
11901         {
11902           weight_set = 1;
11903         }
11904       else
11905         break;
11906     }
11907
11908   if (locator_set_name_set == 0)
11909     {
11910       errmsg ("missing locator-set name");
11911       return -99;
11912     }
11913
11914   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
11915     {
11916       errmsg ("missing sw_if_index");
11917       vec_free (locator_set_name);
11918       return -99;
11919     }
11920
11921   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
11922     {
11923       errmsg ("cannot use both params interface name and sw_if_index");
11924       vec_free (locator_set_name);
11925       return -99;
11926     }
11927
11928   if (priority_set == 0)
11929     {
11930       errmsg ("missing locator-set priority\n");
11931       vec_free (locator_set_name);
11932       return -99;
11933     }
11934
11935   if (weight_set == 0)
11936     {
11937       errmsg ("missing locator-set weight\n");
11938       vec_free (locator_set_name);
11939       return -99;
11940     }
11941
11942   if (vec_len (locator_set_name) > 64)
11943     {
11944       errmsg ("locator-set name too long\n");
11945       vec_free (locator_set_name);
11946       return -99;
11947     }
11948   vec_add1 (locator_set_name, 0);
11949
11950   /* Construct the API message */
11951   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
11952
11953   mp->is_add = is_add;
11954   mp->sw_if_index = ntohl (sw_if_index);
11955   mp->priority = priority;
11956   mp->weight = weight;
11957   clib_memcpy (mp->locator_set_name, locator_set_name,
11958                vec_len (locator_set_name));
11959   vec_free (locator_set_name);
11960
11961   /* send it... */
11962   S;
11963
11964   /* Wait for a reply... */
11965   W;
11966
11967   /* NOTREACHED */
11968   return 0;
11969 }
11970
11971 static int
11972 api_lisp_add_del_local_eid (vat_main_t * vam)
11973 {
11974   unformat_input_t *input = vam->input;
11975   vl_api_lisp_add_del_local_eid_t *mp;
11976   f64 timeout = ~0;
11977   u8 is_add = 1;
11978   u8 eid_set = 0;
11979   lisp_eid_vat_t _eid, *eid = &_eid;
11980   u8 *locator_set_name = 0;
11981   u8 locator_set_name_set = 0;
11982   u32 vni = 0;
11983
11984   /* Parse args required to build the message */
11985   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11986     {
11987       if (unformat (input, "del"))
11988         {
11989           is_add = 0;
11990         }
11991       else if (unformat (input, "vni %d", &vni))
11992         {
11993           ;
11994         }
11995       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
11996         {
11997           eid_set = 1;
11998         }
11999       else if (unformat (input, "locator-set %s", &locator_set_name))
12000         {
12001           locator_set_name_set = 1;
12002         }
12003       else
12004         break;
12005     }
12006
12007   if (locator_set_name_set == 0)
12008     {
12009       errmsg ("missing locator-set name\n");
12010       return -99;
12011     }
12012
12013   if (0 == eid_set)
12014     {
12015       errmsg ("EID address not set!");
12016       vec_free (locator_set_name);
12017       return -99;
12018     }
12019
12020   if (vec_len (locator_set_name) > 64)
12021     {
12022       errmsg ("locator-set name too long\n");
12023       vec_free (locator_set_name);
12024       return -99;
12025     }
12026   vec_add1 (locator_set_name, 0);
12027
12028   /* Construct the API message */
12029   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12030
12031   mp->is_add = is_add;
12032   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12033   mp->eid_type = eid->type;
12034   mp->prefix_len = eid->len;
12035   mp->vni = clib_host_to_net_u32 (vni);
12036   clib_memcpy (mp->locator_set_name, locator_set_name,
12037                vec_len (locator_set_name));
12038
12039   vec_free (locator_set_name);
12040
12041   /* send it... */
12042   S;
12043
12044   /* Wait for a reply... */
12045   W;
12046
12047   /* NOTREACHED */
12048   return 0;
12049 }
12050
12051 /* *INDENT-OFF* */
12052 /** Used for transferring locators via VPP API */
12053 typedef CLIB_PACKED(struct
12054 {
12055   u8 is_ip4; /**< is locator an IPv4 address? */
12056   u8 priority; /**< locator priority */
12057   u8 weight;   /**< locator weight */
12058   u8 addr[16]; /**< IPv4/IPv6 address */
12059 }) rloc_t;
12060 /* *INDENT-ON* */
12061
12062 static int
12063 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12064 {
12065   unformat_input_t *input = vam->input;
12066   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12067   f64 timeout = ~0;
12068   u8 is_add = 1;
12069   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12070   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12071   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12072   u32 action = ~0, p, w;
12073   ip4_address_t rmt_rloc4, lcl_rloc4;
12074   ip6_address_t rmt_rloc6, lcl_rloc6;
12075   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12076
12077   memset (&rloc, 0, sizeof (rloc));
12078
12079   /* Parse args required to build the message */
12080   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12081     {
12082       if (unformat (input, "del"))
12083         {
12084           is_add = 0;
12085         }
12086       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12087         {
12088           rmt_eid_set = 1;
12089         }
12090       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12091         {
12092           lcl_eid_set = 1;
12093         }
12094       else if (unformat (input, "p %d w %d", &p, &w))
12095         {
12096           if (!curr_rloc)
12097             {
12098               errmsg ("No RLOC configured for setting priority/weight!");
12099               return -99;
12100             }
12101           curr_rloc->priority = p;
12102           curr_rloc->weight = w;
12103         }
12104       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12105                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12106         {
12107           rloc.is_ip4 = 1;
12108
12109           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12110           rloc.priority = rloc.weight = 0;
12111           vec_add1 (lcl_locs, rloc);
12112
12113           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12114           vec_add1 (rmt_locs, rloc);
12115           /* priority and weight saved in rmt loc */
12116           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12117         }
12118       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12119                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12120         {
12121           rloc.is_ip4 = 0;
12122           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12123           rloc.priority = rloc.weight = 0;
12124           vec_add1 (lcl_locs, rloc);
12125
12126           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12127           vec_add1 (rmt_locs, rloc);
12128           /* priority and weight saved in rmt loc */
12129           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12130         }
12131       else if (unformat (input, "action %d", &action))
12132         {
12133           ;
12134         }
12135       else
12136         {
12137           clib_warning ("parse error '%U'", format_unformat_error, input);
12138           return -99;
12139         }
12140     }
12141
12142   if (!rmt_eid_set)
12143     {
12144       errmsg ("remote eid addresses not set\n");
12145       return -99;
12146     }
12147
12148   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12149     {
12150       errmsg ("eid types don't match\n");
12151       return -99;
12152     }
12153
12154   if (0 == rmt_locs && (u32) ~ 0 == action)
12155     {
12156       errmsg ("action not set for negative mapping\n");
12157       return -99;
12158     }
12159
12160   /* Construct the API message */
12161   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12162
12163   mp->is_add = is_add;
12164   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12165   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12166   mp->eid_type = rmt_eid->type;
12167   mp->rmt_len = rmt_eid->len;
12168   mp->lcl_len = lcl_eid->len;
12169   mp->action = action;
12170
12171   if (0 != rmt_locs && 0 != lcl_locs)
12172     {
12173       mp->loc_num = vec_len (rmt_locs);
12174       clib_memcpy (mp->lcl_locs, lcl_locs,
12175                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12176       clib_memcpy (mp->rmt_locs, rmt_locs,
12177                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12178     }
12179   vec_free (lcl_locs);
12180   vec_free (rmt_locs);
12181
12182   /* send it... */
12183   S;
12184
12185   /* Wait for a reply... */
12186   W;
12187
12188   /* NOTREACHED */
12189   return 0;
12190 }
12191
12192 static int
12193 api_lisp_add_del_map_resolver (vat_main_t * vam)
12194 {
12195   unformat_input_t *input = vam->input;
12196   vl_api_lisp_add_del_map_resolver_t *mp;
12197   f64 timeout = ~0;
12198   u8 is_add = 1;
12199   u8 ipv4_set = 0;
12200   u8 ipv6_set = 0;
12201   ip4_address_t ipv4;
12202   ip6_address_t ipv6;
12203
12204   /* Parse args required to build the message */
12205   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12206     {
12207       if (unformat (input, "del"))
12208         {
12209           is_add = 0;
12210         }
12211       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12212         {
12213           ipv4_set = 1;
12214         }
12215       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12216         {
12217           ipv6_set = 1;
12218         }
12219       else
12220         break;
12221     }
12222
12223   if (ipv4_set && ipv6_set)
12224     {
12225       errmsg ("both eid v4 and v6 addresses set\n");
12226       return -99;
12227     }
12228
12229   if (!ipv4_set && !ipv6_set)
12230     {
12231       errmsg ("eid addresses not set\n");
12232       return -99;
12233     }
12234
12235   /* Construct the API message */
12236   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12237
12238   mp->is_add = is_add;
12239   if (ipv6_set)
12240     {
12241       mp->is_ipv6 = 1;
12242       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12243     }
12244   else
12245     {
12246       mp->is_ipv6 = 0;
12247       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12248     }
12249
12250   /* send it... */
12251   S;
12252
12253   /* Wait for a reply... */
12254   W;
12255
12256   /* NOTREACHED */
12257   return 0;
12258 }
12259
12260 static int
12261 api_lisp_gpe_enable_disable (vat_main_t * vam)
12262 {
12263   unformat_input_t *input = vam->input;
12264   vl_api_lisp_gpe_enable_disable_t *mp;
12265   f64 timeout = ~0;
12266   u8 is_set = 0;
12267   u8 is_en = 1;
12268
12269   /* Parse args required to build the message */
12270   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12271     {
12272       if (unformat (input, "enable"))
12273         {
12274           is_set = 1;
12275           is_en = 1;
12276         }
12277       else if (unformat (input, "disable"))
12278         {
12279           is_set = 1;
12280           is_en = 0;
12281         }
12282       else
12283         break;
12284     }
12285
12286   if (is_set == 0)
12287     {
12288       errmsg ("Value not set\n");
12289       return -99;
12290     }
12291
12292   /* Construct the API message */
12293   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12294
12295   mp->is_en = is_en;
12296
12297   /* send it... */
12298   S;
12299
12300   /* Wait for a reply... */
12301   W;
12302
12303   /* NOTREACHED */
12304   return 0;
12305 }
12306
12307 static int
12308 api_lisp_enable_disable (vat_main_t * vam)
12309 {
12310   unformat_input_t *input = vam->input;
12311   vl_api_lisp_enable_disable_t *mp;
12312   f64 timeout = ~0;
12313   u8 is_set = 0;
12314   u8 is_en = 0;
12315
12316   /* Parse args required to build the message */
12317   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12318     {
12319       if (unformat (input, "enable"))
12320         {
12321           is_set = 1;
12322           is_en = 1;
12323         }
12324       else if (unformat (input, "disable"))
12325         {
12326           is_set = 1;
12327         }
12328       else
12329         break;
12330     }
12331
12332   if (!is_set)
12333     {
12334       errmsg ("Value not set\n");
12335       return -99;
12336     }
12337
12338   /* Construct the API message */
12339   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12340
12341   mp->is_en = is_en;
12342
12343   /* send it... */
12344   S;
12345
12346   /* Wait for a reply... */
12347   W;
12348
12349   /* NOTREACHED */
12350   return 0;
12351 }
12352
12353 /**
12354  * Enable/disable LISP proxy ITR.
12355  *
12356  * @param vam vpp API test context
12357  * @return return code
12358  */
12359 static int
12360 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12361 {
12362   f64 timeout = ~0;
12363   u8 ls_name_set = 0;
12364   unformat_input_t *input = vam->input;
12365   vl_api_lisp_pitr_set_locator_set_t *mp;
12366   u8 is_add = 1;
12367   u8 *ls_name = 0;
12368
12369   /* Parse args required to build the message */
12370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12371     {
12372       if (unformat (input, "del"))
12373         is_add = 0;
12374       else if (unformat (input, "locator-set %s", &ls_name))
12375         ls_name_set = 1;
12376       else
12377         {
12378           errmsg ("parse error '%U'", format_unformat_error, input);
12379           return -99;
12380         }
12381     }
12382
12383   if (!ls_name_set)
12384     {
12385       errmsg ("locator-set name not set!");
12386       return -99;
12387     }
12388
12389   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12390
12391   mp->is_add = is_add;
12392   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12393   vec_free (ls_name);
12394
12395   /* send */
12396   S;
12397
12398   /* wait for reply */
12399   W;
12400
12401   /* notreached */
12402   return 0;
12403 }
12404
12405 static int
12406 api_show_lisp_pitr (vat_main_t * vam)
12407 {
12408   vl_api_show_lisp_pitr_t *mp;
12409   f64 timeout = ~0;
12410
12411   if (!vam->json_output)
12412     {
12413       fformat (vam->ofp, "%=20s\n", "lisp status:");
12414     }
12415
12416   M (SHOW_LISP_PITR, show_lisp_pitr);
12417   /* send it... */
12418   S;
12419
12420   /* Wait for a reply... */
12421   W;
12422
12423   /* NOTREACHED */
12424   return 0;
12425 }
12426
12427 /**
12428  * Add/delete mapping between vni and vrf
12429  */
12430 static int
12431 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12432 {
12433   f64 timeout = ~0;
12434   unformat_input_t *input = vam->input;
12435   vl_api_lisp_eid_table_add_del_map_t *mp;
12436   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12437   u32 vni, vrf, bd_index;
12438
12439   /* Parse args required to build the message */
12440   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12441     {
12442       if (unformat (input, "del"))
12443         is_add = 0;
12444       else if (unformat (input, "vrf %d", &vrf))
12445         vrf_set = 1;
12446       else if (unformat (input, "bd_index %d", &bd_index))
12447         bd_index_set = 1;
12448       else if (unformat (input, "vni %d", &vni))
12449         vni_set = 1;
12450       else
12451         break;
12452     }
12453
12454   if (!vni_set || (!vrf_set && !bd_index_set))
12455     {
12456       errmsg ("missing arguments!");
12457       return -99;
12458     }
12459
12460   if (vrf_set && bd_index_set)
12461     {
12462       errmsg ("error: both vrf and bd entered!");
12463       return -99;
12464     }
12465
12466   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12467
12468   mp->is_add = is_add;
12469   mp->vni = htonl (vni);
12470   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
12471   mp->is_l2 = bd_index_set;
12472
12473   /* send */
12474   S;
12475
12476   /* wait for reply */
12477   W;
12478
12479   /* notreached */
12480   return 0;
12481 }
12482
12483 /**
12484  * Add/del remote mapping to/from LISP control plane
12485  *
12486  * @param vam vpp API test context
12487  * @return return code
12488  */
12489 static int
12490 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12491 {
12492   unformat_input_t *input = vam->input;
12493   vl_api_lisp_add_del_remote_mapping_t *mp;
12494   f64 timeout = ~0;
12495   u32 vni = 0;
12496   //TODO: seid need remove
12497   lisp_eid_vat_t _eid, *eid = &_eid;
12498   lisp_eid_vat_t _seid, *seid = &_seid;
12499   u8 is_add = 1, del_all = 0, eid_set = 0;
12500   u32 action = ~0, p, w;
12501   ip4_address_t rloc4;
12502   ip6_address_t rloc6;
12503   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12504
12505   memset (&rloc, 0, sizeof (rloc));
12506
12507   /* Parse args required to build the message */
12508   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12509     {
12510       if (unformat (input, "del-all"))
12511         {
12512           del_all = 1;
12513         }
12514       else if (unformat (input, "del"))
12515         {
12516           is_add = 0;
12517         }
12518       else if (unformat (input, "add"))
12519         {
12520           is_add = 1;
12521         }
12522       else if (unformat (input, "deid %U", unformat_lisp_eid_vat, eid))
12523         {
12524           eid_set = 1;
12525         }
12526       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, &seid))
12527         {
12528           //TODO: Need remove, but first must be remove from CSIT test
12529         }
12530       else if (unformat (input, "vni %d", &vni))
12531         {
12532           ;
12533         }
12534       else if (unformat (input, "p %d w %d", &p, &w))
12535         {
12536           if (!curr_rloc)
12537             {
12538               errmsg ("No RLOC configured for setting priority/weight!");
12539               return -99;
12540             }
12541           curr_rloc->priority = p;
12542           curr_rloc->weight = w;
12543         }
12544       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12545         {
12546           rloc.is_ip4 = 1;
12547           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12548           vec_add1 (rlocs, rloc);
12549           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12550         }
12551       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12552         {
12553           rloc.is_ip4 = 0;
12554           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12555           vec_add1 (rlocs, rloc);
12556           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12557         }
12558       else if (unformat (input, "action %d", &action))
12559         {
12560           ;
12561         }
12562       else
12563         {
12564           clib_warning ("parse error '%U'", format_unformat_error, input);
12565           return -99;
12566         }
12567     }
12568
12569   if (0 == eid_set)
12570     {
12571       errmsg ("missing params!");
12572       return -99;
12573     }
12574
12575   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12576     {
12577       errmsg ("no action set for negative map-reply!");
12578       return -99;
12579     }
12580
12581   M (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
12582   mp->is_add = is_add;
12583   mp->vni = htonl (vni);
12584   mp->action = (u8) action;
12585   mp->eid_len = eid->len;
12586   mp->del_all = del_all;
12587   mp->eid_type = eid->type;
12588   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12589
12590   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
12591   clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
12592   vec_free (rlocs);
12593
12594   /* send it... */
12595   S;
12596
12597   /* Wait for a reply... */
12598   W;
12599
12600   /* NOTREACHED */
12601   return 0;
12602 }
12603
12604 /**
12605  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
12606  * forwarding entries in data-plane accordingly.
12607  *
12608  * @param vam vpp API test context
12609  * @return return code
12610  */
12611 static int
12612 api_lisp_add_del_adjacency (vat_main_t * vam)
12613 {
12614   unformat_input_t *input = vam->input;
12615   vl_api_lisp_add_del_adjacency_t *mp;
12616   f64 timeout = ~0;
12617   u32 vni = 0;
12618   ip4_address_t seid4, deid4;
12619   ip6_address_t seid6, deid6;
12620   u8 deid_mac[6] = { 0 };
12621   u8 seid_mac[6] = { 0 };
12622   u8 deid_type, seid_type;
12623   u32 seid_len = 0, deid_len = 0, len;
12624   u8 is_add = 1;
12625
12626   seid_type = deid_type = (u8) ~ 0;
12627
12628   /* Parse args required to build the message */
12629   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12630     {
12631       if (unformat (input, "del"))
12632         {
12633           is_add = 0;
12634         }
12635       else if (unformat (input, "add"))
12636         {
12637           is_add = 1;
12638         }
12639       else if (unformat (input, "deid %U/%d", unformat_ip4_address,
12640                          &deid4, &len))
12641         {
12642           deid_type = 0;        /* ipv4 */
12643           deid_len = len;
12644         }
12645       else if (unformat (input, "deid %U/%d", unformat_ip6_address,
12646                          &deid6, &len))
12647         {
12648           deid_type = 1;        /* ipv6 */
12649           deid_len = len;
12650         }
12651       else if (unformat (input, "deid %U", unformat_ethernet_address,
12652                          deid_mac))
12653         {
12654           deid_type = 2;        /* mac */
12655         }
12656       else if (unformat (input, "seid %U/%d", unformat_ip4_address,
12657                          &seid4, &len))
12658         {
12659           seid_type = 0;        /* ipv4 */
12660           seid_len = len;
12661         }
12662       else if (unformat (input, "seid %U/%d", unformat_ip6_address,
12663                          &seid6, &len))
12664         {
12665           seid_type = 1;        /* ipv6 */
12666           seid_len = len;
12667         }
12668       else if (unformat (input, "seid %U", unformat_ethernet_address,
12669                          seid_mac))
12670         {
12671           seid_type = 2;        /* mac */
12672         }
12673       else if (unformat (input, "vni %d", &vni))
12674         {
12675           ;
12676         }
12677       else
12678         {
12679           errmsg ("parse error '%U'", format_unformat_error, input);
12680           return -99;
12681         }
12682     }
12683
12684   if ((u8) ~ 0 == deid_type)
12685     {
12686       errmsg ("missing params!");
12687       return -99;
12688     }
12689
12690   if (seid_type != deid_type)
12691     {
12692       errmsg ("source and destination EIDs are of different types!");
12693       return -99;
12694     }
12695
12696   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
12697   mp->is_add = is_add;
12698   mp->vni = htonl (vni);
12699   mp->seid_len = seid_len;
12700   mp->deid_len = deid_len;
12701   mp->eid_type = deid_type;
12702
12703   switch (mp->eid_type)
12704     {
12705     case 0:
12706       clib_memcpy (mp->seid, &seid4, sizeof (seid4));
12707       clib_memcpy (mp->deid, &deid4, sizeof (deid4));
12708       break;
12709     case 1:
12710       clib_memcpy (mp->seid, &seid6, sizeof (seid6));
12711       clib_memcpy (mp->deid, &deid6, sizeof (deid6));
12712       break;
12713     case 2:
12714       clib_memcpy (mp->seid, seid_mac, 6);
12715       clib_memcpy (mp->deid, deid_mac, 6);
12716       break;
12717     default:
12718       errmsg ("unknown EID type %d!", mp->eid_type);
12719       return 0;
12720     }
12721
12722   /* send it... */
12723   S;
12724
12725   /* Wait for a reply... */
12726   W;
12727
12728   /* NOTREACHED */
12729   return 0;
12730 }
12731
12732 static int
12733 api_lisp_gpe_add_del_iface (vat_main_t * vam)
12734 {
12735   unformat_input_t *input = vam->input;
12736   vl_api_lisp_gpe_add_del_iface_t *mp;
12737   f64 timeout = ~0;
12738   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
12739   u32 dp_table = 0, vni = 0;
12740
12741   /* Parse args required to build the message */
12742   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12743     {
12744       if (unformat (input, "up"))
12745         {
12746           action_set = 1;
12747           is_add = 1;
12748         }
12749       else if (unformat (input, "down"))
12750         {
12751           action_set = 1;
12752           is_add = 0;
12753         }
12754       else if (unformat (input, "table_id %d", &dp_table))
12755         {
12756           dp_table_set = 1;
12757         }
12758       else if (unformat (input, "bd_id %d", &dp_table))
12759         {
12760           dp_table_set = 1;
12761           is_l2 = 1;
12762         }
12763       else if (unformat (input, "vni %d", &vni))
12764         {
12765           vni_set = 1;
12766         }
12767       else
12768         break;
12769     }
12770
12771   if (action_set == 0)
12772     {
12773       errmsg ("Action not set\n");
12774       return -99;
12775     }
12776   if (dp_table_set == 0 || vni_set == 0)
12777     {
12778       errmsg ("vni and dp_table must be set\n");
12779       return -99;
12780     }
12781
12782   /* Construct the API message */
12783   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
12784
12785   mp->is_add = is_add;
12786   mp->dp_table = dp_table;
12787   mp->is_l2 = is_l2;
12788   mp->vni = vni;
12789
12790   /* send it... */
12791   S;
12792
12793   /* Wait for a reply... */
12794   W;
12795
12796   /* NOTREACHED */
12797   return 0;
12798 }
12799
12800 /**
12801  * Add/del map request itr rlocs from LISP control plane and updates
12802  *
12803  * @param vam vpp API test context
12804  * @return return code
12805  */
12806 static int
12807 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
12808 {
12809   unformat_input_t *input = vam->input;
12810   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
12811   f64 timeout = ~0;
12812   u8 *locator_set_name = 0;
12813   u8 locator_set_name_set = 0;
12814   u8 is_add = 1;
12815
12816   /* Parse args required to build the message */
12817   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12818     {
12819       if (unformat (input, "del"))
12820         {
12821           is_add = 0;
12822         }
12823       else if (unformat (input, "%_%v%_", &locator_set_name))
12824         {
12825           locator_set_name_set = 1;
12826         }
12827       else
12828         {
12829           clib_warning ("parse error '%U'", format_unformat_error, input);
12830           return -99;
12831         }
12832     }
12833
12834   if (is_add && !locator_set_name_set)
12835     {
12836       errmsg ("itr-rloc is not set!");
12837       return -99;
12838     }
12839
12840   if (is_add && vec_len (locator_set_name) > 64)
12841     {
12842       errmsg ("itr-rloc locator-set name too long\n");
12843       vec_free (locator_set_name);
12844       return -99;
12845     }
12846
12847   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
12848   mp->is_add = is_add;
12849   if (is_add)
12850     {
12851       clib_memcpy (mp->locator_set_name, locator_set_name,
12852                    vec_len (locator_set_name));
12853     }
12854   else
12855     {
12856       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
12857     }
12858   vec_free (locator_set_name);
12859
12860   /* send it... */
12861   S;
12862
12863   /* Wait for a reply... */
12864   W;
12865
12866   /* NOTREACHED */
12867   return 0;
12868 }
12869
12870 static int
12871 lisp_locator_dump_send_msg (vat_main_t * vam, u32 locator_set_index,
12872                             u8 filter)
12873 {
12874   vl_api_lisp_locator_dump_t *mp;
12875   f64 timeout = ~0;
12876
12877   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
12878
12879   mp->locator_set_index = htonl (locator_set_index);
12880   mp->filter = filter;
12881
12882   /* send it... */
12883   S;
12884
12885   /* Use a control ping for synchronization */
12886   {
12887     vl_api_noprint_control_ping_t *mp;
12888     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12889     S;
12890   }
12891   /* Wait for a reply... */
12892   W;
12893 }
12894
12895 static inline void
12896 clean_locator_set_message (vat_main_t * vam)
12897 {
12898   locator_set_msg_t *ls = 0;
12899
12900   vec_foreach (ls, vam->locator_set_msg)
12901   {
12902     vec_free (ls->locator_set_name);
12903   }
12904
12905   vec_free (vam->locator_set_msg);
12906 }
12907
12908 static int
12909 print_locator_in_locator_set (vat_main_t * vam, u8 filter)
12910 {
12911   locator_set_msg_t *ls;
12912   locator_msg_t *loc;
12913   u8 *tmp_str = 0;
12914   int i = 0, ret = 0;
12915
12916   vec_foreach (ls, vam->locator_set_msg)
12917   {
12918     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12919     if (ret)
12920       {
12921         vec_free (vam->locator_msg);
12922         clean_locator_set_message (vam);
12923         return ret;
12924       }
12925
12926     tmp_str = format (0, "%=20s%=16d%s", ls->locator_set_name,
12927                       ls->locator_set_index,
12928                       vec_len (vam->locator_msg) ? "" : "\n");
12929     i = 0;
12930     vec_foreach (loc, vam->locator_msg)
12931     {
12932       if (i)
12933         {
12934           tmp_str = format (tmp_str, "%=37s", " ");
12935         }
12936       if (loc->local)
12937         {
12938           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
12939                             loc->sw_if_index, loc->priority, loc->weight);
12940         }
12941       else
12942         {
12943           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
12944                             loc->is_ipv6 ? format_ip6_address :
12945                             format_ip4_address,
12946                             loc->ip_address, loc->priority, loc->weight);
12947         }
12948       i++;
12949     }
12950
12951     fformat (vam->ofp, "%s", tmp_str);
12952     vec_free (tmp_str);
12953     vec_free (vam->locator_msg);
12954   }
12955
12956   clean_locator_set_message (vam);
12957
12958   return ret;
12959 }
12960
12961 static int
12962 json_locator_in_locator_set (vat_main_t * vam, u8 filter)
12963 {
12964   locator_set_msg_t *ls;
12965   locator_msg_t *loc;
12966   vat_json_node_t *node = NULL;
12967   vat_json_node_t *locator_array;
12968   vat_json_node_t *locator;
12969   struct in6_addr ip6;
12970   struct in_addr ip4;
12971   int ret = 0;
12972
12973   if (!vec_len (vam->locator_set_msg))
12974     {
12975       /* just print [] */
12976       vat_json_init_array (&vam->json_tree);
12977       vat_json_print (vam->ofp, &vam->json_tree);
12978       vam->json_tree.type = VAT_JSON_NONE;
12979       return ret;
12980     }
12981
12982   if (VAT_JSON_ARRAY != vam->json_tree.type)
12983     {
12984       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12985       vat_json_init_array (&vam->json_tree);
12986     }
12987
12988   vec_foreach (ls, vam->locator_set_msg)
12989   {
12990     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12991     if (ret)
12992       {
12993         vec_free (ls->locator_set_name);
12994         vec_free (vam->locator_msg);
12995         vec_free (vam->locator_set_msg);
12996         vat_json_free (&vam->json_tree);
12997         vam->json_tree.type = VAT_JSON_NONE;
12998         return ret;
12999       }
13000
13001     node = vat_json_array_add (&vam->json_tree);
13002     vat_json_init_object (node);
13003
13004     vat_json_object_add_uint (node, "locator-set-index",
13005                               ls->locator_set_index);
13006     vat_json_object_add_string_copy (node, "locator-set",
13007                                      ls->locator_set_name);
13008     locator_array = vat_json_object_add_list (node, "locator");
13009     vec_foreach (loc, vam->locator_msg)
13010     {
13011       locator = vat_json_array_add (locator_array);
13012       vat_json_init_object (locator);
13013       if (loc->local)
13014         {
13015           vat_json_object_add_uint (locator, "locator-index",
13016                                     loc->sw_if_index);
13017         }
13018       else
13019         {
13020           if (loc->is_ipv6)
13021             {
13022               clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
13023               vat_json_object_add_ip6 (locator, "locator", ip6);
13024             }
13025           else
13026             {
13027               clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
13028               vat_json_object_add_ip4 (locator, "locator", ip4);
13029             }
13030         }
13031       vat_json_object_add_uint (locator, "priority", loc->priority);
13032       vat_json_object_add_uint (locator, "weight", loc->weight);
13033     }
13034
13035     vec_free (ls->locator_set_name);
13036     vec_free (vam->locator_msg);
13037   }
13038
13039   vat_json_print (vam->ofp, &vam->json_tree);
13040   vat_json_free (&vam->json_tree);
13041   vam->json_tree.type = VAT_JSON_NONE;
13042
13043   vec_free (vam->locator_set_msg);
13044
13045   return ret;
13046 }
13047
13048 static int
13049 get_locator_set_index_from_msg (vat_main_t * vam, u8 * locator_set,
13050                                 u32 * locator_set_index)
13051 {
13052   locator_set_msg_t *ls;
13053   int ret = 0;
13054
13055   *locator_set_index = ~0;
13056
13057   if (!vec_len (vam->locator_set_msg))
13058     {
13059       return ret;
13060     }
13061
13062   vec_foreach (ls, vam->locator_set_msg)
13063   {
13064     if (!strcmp ((char *) locator_set, (char *) ls->locator_set_name))
13065       {
13066         *locator_set_index = ls->locator_set_index;
13067         vec_free (vam->locator_set_msg);
13068         return ret;
13069       }
13070   }
13071
13072   vec_free (vam->locator_set_msg);
13073
13074   return ret;
13075 }
13076
13077 static int
13078 get_locator_set_index (vat_main_t * vam, u8 * locator_set,
13079                        u32 * locator_set_index)
13080 {
13081   vl_api_lisp_locator_set_dump_t *mp;
13082   f64 timeout = ~0;
13083
13084   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13085   /* send it... */
13086   S;
13087
13088   /* Use a control ping for synchronization */
13089   {
13090     vl_api_noprint_control_ping_t *mp;
13091     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13092     S;
13093   }
13094
13095   vam->noprint_msg = 1;
13096   /* Wait for a reply... */
13097   /* *INDENT-OFF* */
13098   W_L
13099   ({
13100     get_locator_set_index_from_msg (vam, locator_set, locator_set_index);
13101     vam->noprint_msg = 0;
13102   });
13103   /* *INDENT-ON* */
13104
13105   /* NOTREACHED */
13106   return 0;
13107 }
13108
13109 static inline int
13110 lisp_locator_dump (vat_main_t * vam, u32 locator_set_index, u8 * locator_set,
13111                    u8 filter)
13112 {
13113   int ret = 0;
13114
13115   ASSERT (vam);
13116
13117   if (!vam->json_output)
13118     {
13119       fformat (vam->ofp, "%=20s%=16s%=16s\n",
13120                "locator", "priority", "weight");
13121     }
13122
13123   if (locator_set)
13124     {
13125       ret = get_locator_set_index (vam, locator_set, &locator_set_index);
13126     }
13127
13128   if (!ret && ~0 == locator_set_index)
13129     {
13130       return -99;
13131     }
13132
13133   ret = lisp_locator_dump_send_msg (vam, locator_set_index, filter);
13134
13135   return ret;
13136 }
13137
13138 static int
13139 lisp_locator_set_dump (vat_main_t * vam, u8 filter)
13140 {
13141   vl_api_lisp_locator_set_dump_t *mp;
13142   f64 timeout = ~0;
13143
13144   if (!vam->json_output)
13145     {
13146       fformat (vam->ofp, "%=20s%=16s%=16s%=16s%=16s\n",
13147                "locator-set", "locator-set-index", "locator", "priority",
13148                "weight");
13149     }
13150
13151   vam->noprint_msg = 1;
13152
13153   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13154
13155   mp->filter = filter;
13156
13157   /* send it... */
13158   S;
13159
13160   /* Use a control ping for synchronization */
13161   {
13162     vl_api_noprint_control_ping_t *mp;
13163     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13164     S;
13165   }
13166
13167   /* Wait for a reply... */
13168   /* *INDENT-OFF* */
13169   W_L
13170   ({
13171     if (vam->noprint_msg)
13172       {
13173         if (!vam->json_output)
13174           {
13175             print_locator_in_locator_set(vam, filter);
13176           }
13177         else
13178           {
13179             json_locator_in_locator_set(vam, filter);
13180           }
13181       }
13182     vam->noprint_msg = 0;
13183   });
13184   /* *INDENT-ON* */
13185
13186   /* NOTREACHED */
13187   return 0;
13188 }
13189
13190 static int
13191 api_lisp_locator_set_dump (vat_main_t * vam)
13192 {
13193   unformat_input_t *input = vam->input;
13194   vam->noprint_msg = 0;
13195   u32 locator_set_index = ~0;
13196   u8 locator_set_index_set = 0;
13197   u8 *locator_set = 0;
13198   u8 locator_set_set = 0;
13199   u8 filter = 0;
13200   int ret = 0;
13201
13202   /* Parse args required to build the message */
13203   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13204     {
13205       if (unformat (input, "locator-set-index %u", &locator_set_index))
13206         {
13207           locator_set_index_set = 1;
13208         }
13209       else if (unformat (input, "locator-set %s", &locator_set))
13210         {
13211           locator_set_set = 1;
13212         }
13213       else if (unformat (input, "local"))
13214         {
13215           filter = 1;
13216         }
13217       else if (unformat (input, "remote"))
13218         {
13219           filter = 2;
13220         }
13221       else
13222         {
13223           break;
13224         }
13225     }
13226
13227   if (locator_set_index_set && locator_set_set)
13228     {
13229       errmsg ("use only input parameter!\n");
13230       return -99;
13231     }
13232
13233   if (locator_set_index_set || locator_set_set)
13234     {
13235       ret = lisp_locator_dump (vam, locator_set_index, locator_set, filter);
13236     }
13237   else
13238     {
13239       ret = lisp_locator_set_dump (vam, filter);
13240     }
13241
13242   vec_free (locator_set);
13243
13244   return ret;
13245 }
13246
13247 static int
13248 api_lisp_eid_table_map_dump (vat_main_t * vam)
13249 {
13250   u8 is_l2 = 0;
13251   u8 mode_set = 0;
13252   unformat_input_t *input = vam->input;
13253   vl_api_lisp_eid_table_map_dump_t *mp;
13254   f64 timeout = ~0;
13255
13256   /* Parse args required to build the message */
13257   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13258     {
13259       if (unformat (input, "l2"))
13260         {
13261           is_l2 = 1;
13262           mode_set = 1;
13263         }
13264       else if (unformat (input, "l3"))
13265         {
13266           is_l2 = 0;
13267           mode_set = 1;
13268         }
13269       else
13270         {
13271           errmsg ("parse error '%U'", format_unformat_error, input);
13272           return -99;
13273         }
13274     }
13275
13276   if (!mode_set)
13277     {
13278       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13279       return -99;
13280     }
13281
13282   if (!vam->json_output)
13283     {
13284       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13285     }
13286
13287   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13288   mp->is_l2 = is_l2;
13289
13290   /* send it... */
13291   S;
13292
13293   /* Use a control ping for synchronization */
13294   {
13295     vl_api_control_ping_t *mp;
13296     M (CONTROL_PING, control_ping);
13297     S;
13298   }
13299   /* Wait for a reply... */
13300   W;
13301
13302   /* NOTREACHED */
13303   return 0;
13304 }
13305
13306 static int
13307 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13308 {
13309   vl_api_lisp_eid_table_vni_dump_t *mp;
13310   f64 timeout = ~0;
13311
13312   if (!vam->json_output)
13313     {
13314       fformat (vam->ofp, "VNI\n");
13315     }
13316
13317   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13318
13319   /* send it... */
13320   S;
13321
13322   /* Use a control ping for synchronization */
13323   {
13324     vl_api_control_ping_t *mp;
13325     M (CONTROL_PING, control_ping);
13326     S;
13327   }
13328   /* Wait for a reply... */
13329   W;
13330
13331   /* NOTREACHED */
13332   return 0;
13333 }
13334
13335 static int
13336 get_locator_set (vat_main_t * vam)
13337 {
13338   vl_api_lisp_locator_set_dump_t *mp;
13339   f64 timeout = ~0;
13340
13341   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13342   /* send it... */
13343   S;
13344
13345   /* Use a control ping for synchronization */
13346   {
13347     vl_api_noprint_control_ping_t *mp;
13348     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13349     S;
13350   }
13351
13352   /* Wait for a reply... */
13353   W;
13354
13355   /* NOTREACHED */
13356   return 0;
13357 }
13358
13359 static inline u8 *
13360 format_eid_for_eid_table (vat_main_t * vam, u8 * str, eid_table_t * eid_table,
13361                           int *ret)
13362 {
13363   u8 *(*format_eid) (u8 *, va_list *) = 0;
13364
13365   ASSERT (vam != NULL);
13366   ASSERT (eid_table != NULL);
13367
13368   if (ret)
13369     {
13370       *ret = 0;
13371     }
13372
13373   switch (eid_table->eid_type)
13374     {
13375     case 0:
13376     case 1:
13377       format_eid = (eid_table->eid_type ? format_ip6_address :
13378                     format_ip4_address);
13379       str = format (0, "[%d] %U/%d", eid_table->vni,
13380                     format_eid, eid_table->eid, eid_table->eid_prefix_len);
13381       break;
13382     case 2:
13383       str = format (0, "[%d] %U", eid_table->vni,
13384                     format_ethernet_address, eid_table->eid);
13385       break;
13386     default:
13387       errmsg ("unknown EID type %d!", eid_table->eid_type);
13388       if (ret)
13389         {
13390           *ret = -99;
13391         }
13392       return 0;
13393     }
13394
13395   return str;
13396 }
13397
13398 static inline u8 *
13399 format_locator_set_for_eid_table (vat_main_t * vam, u8 * str,
13400                                   eid_table_t * eid_table)
13401 {
13402   locator_set_msg_t *ls = 0;
13403
13404   ASSERT (vam != NULL);
13405   ASSERT (eid_table != NULL);
13406
13407   if (eid_table->is_local)
13408     {
13409       vec_foreach (ls, vam->locator_set_msg)
13410       {
13411         if (ls->locator_set_index == eid_table->locator_set_index)
13412           {
13413             str = format (0, "local(%s)", ls->locator_set_name);
13414             return str;
13415           }
13416       }
13417
13418       str = format (0, "local(N/A)");
13419     }
13420   else
13421     {
13422       str = format (0, "remote");
13423     }
13424
13425   return str;
13426 }
13427
13428 static inline u8 *
13429 format_locator_for_eid_table (vat_main_t * vam, u8 * str,
13430                               eid_table_t * eid_table)
13431 {
13432   locator_msg_t *loc = 0;
13433   int first_line = 1;
13434
13435   ASSERT (vam != NULL);
13436   ASSERT (eid_table != NULL);
13437
13438   if (~0 == eid_table->locator_set_index)
13439     {
13440       return format (0, "action: %d\n", eid_table->action);
13441     }
13442
13443   vec_foreach (loc, vam->locator_msg)
13444   {
13445     if (!first_line)
13446       {
13447         if (loc->local)
13448           {
13449             str = format (str, "%-55s%-d\n", " ", loc->sw_if_index);
13450           }
13451         else
13452           {
13453             str = format (str, "%=55s%-U\n", " ",
13454                           loc->is_ipv6 ? format_ip6_address :
13455                           format_ip4_address, loc->ip_address);
13456           }
13457
13458         continue;
13459       }
13460
13461     if (loc->local)
13462       {
13463         str = format (str, "%-30d%-20u%-u\n", loc->sw_if_index,
13464                       eid_table->ttl, eid_table->authoritative);
13465       }
13466     else
13467       {
13468         str = format (str, "%-30U%-20u%-u\n",
13469                       loc->is_ipv6 ? format_ip6_address :
13470                       format_ip4_address,
13471                       loc->ip_address, eid_table->ttl,
13472                       eid_table->authoritative);
13473       }
13474     first_line = 0;
13475   }
13476
13477   return str;
13478 }
13479
13480 static int
13481 print_lisp_eid_table_dump (vat_main_t * vam)
13482 {
13483   eid_table_t *eid_table = 0;
13484   u8 *tmp_str = 0, *tmp_str2 = 0;
13485   int ret = 0;
13486
13487   ASSERT (vam != NULL);
13488
13489   ret = get_locator_set (vam);
13490   if (ret)
13491     {
13492       vec_free (vam->eid_tables);
13493       return ret;
13494     }
13495
13496   fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type", "locators",
13497            "ttl", "authoritative");
13498
13499   vec_foreach (eid_table, vam->eid_tables)
13500   {
13501     if (~0 != eid_table->locator_set_index)
13502       {
13503         ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index,
13504                                           0);
13505         if (ret)
13506           {
13507             vec_free (vam->locator_msg);
13508             clean_locator_set_message (vam);
13509             vec_free (vam->eid_tables);
13510             return ret;
13511           }
13512       }
13513
13514     tmp_str2 = format_eid_for_eid_table (vam, tmp_str2, eid_table, &ret);
13515     if (ret)
13516       {
13517         vec_free (vam->locator_msg);
13518         clean_locator_set_message (vam);
13519         vec_free (vam->eid_tables);
13520         return ret;
13521       }
13522
13523     tmp_str = format (0, "%-35s", tmp_str2);
13524     vec_free (tmp_str2);
13525
13526     tmp_str2 = format_locator_set_for_eid_table (vam, tmp_str2, eid_table);
13527     tmp_str = format (tmp_str, "%-20s", tmp_str2);
13528     vec_free (tmp_str2);
13529
13530     tmp_str2 = format_locator_for_eid_table (vam, tmp_str2, eid_table);
13531     tmp_str = format (tmp_str, "%-s", tmp_str2);
13532     vec_free (tmp_str2);
13533
13534     fformat (vam->ofp, "%s", tmp_str);
13535     vec_free (tmp_str);
13536     vec_free (vam->locator_msg);
13537   }
13538
13539   clean_locator_set_message (vam);
13540   vec_free (vam->eid_tables);
13541
13542   return ret;
13543 }
13544
13545 static inline void
13546 json_locator_set_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13547                                 eid_table_t * eid_table)
13548 {
13549   locator_set_msg_t *ls = 0;
13550   u8 *s = 0;
13551
13552   ASSERT (vam != NULL);
13553   ASSERT (node != NULL);
13554   ASSERT (eid_table != NULL);
13555
13556   if (eid_table->is_local)
13557     {
13558       vec_foreach (ls, vam->locator_set_msg)
13559       {
13560         if (ls->locator_set_index == eid_table->locator_set_index)
13561           {
13562             vat_json_object_add_string_copy (node, "locator-set",
13563                                              ls->locator_set_name);
13564             return;
13565           }
13566       }
13567
13568       s = format (0, "N/A");
13569       vec_add1 (s, 0);
13570       vat_json_object_add_string_copy (node, "locator-set", s);
13571       vec_free (s);
13572     }
13573   else
13574     {
13575       s = format (0, "remote");
13576       vec_add1 (s, 0);
13577       vat_json_object_add_string_copy (node, "locator-set", s);
13578       vec_free (s);
13579     }
13580 }
13581
13582 static inline int
13583 json_eid_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13584                         eid_table_t * eid_table)
13585 {
13586   u8 *s = 0;
13587   struct in6_addr ip6;
13588   struct in_addr ip4;
13589
13590   ASSERT (vam != NULL);
13591   ASSERT (node != NULL);
13592   ASSERT (eid_table != NULL);
13593
13594   switch (eid_table->eid_type)
13595     {
13596     case 0:
13597       clib_memcpy (&ip4, eid_table->eid, sizeof (ip4));
13598       vat_json_object_add_ip4 (node, "eid", ip4);
13599       vat_json_object_add_uint (node, "eid-prefix-len",
13600                                 eid_table->eid_prefix_len);
13601       break;
13602     case 1:
13603       clib_memcpy (&ip6, eid_table->eid, sizeof (ip6));
13604       vat_json_object_add_ip6 (node, "eid", ip6);
13605       vat_json_object_add_uint (node, "eid-prefix-len",
13606                                 eid_table->eid_prefix_len);
13607       break;
13608     case 2:
13609       s = format (0, "%U", format_ethernet_address, eid_table->eid);
13610       vec_add1 (s, 0);
13611       vat_json_object_add_string_copy (node, "eid", s);
13612       vec_free (s);
13613       break;
13614     default:
13615       errmsg ("unknown EID type %d!", eid_table->eid_type);
13616       return -99;
13617     }
13618
13619   return 0;
13620 }
13621
13622 static inline void
13623 json_locator_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13624                             eid_table_t * eid_table)
13625 {
13626   locator_msg_t *loc = 0;
13627   vat_json_node_t *locator_array = 0;
13628   vat_json_node_t *locator = 0;
13629   struct in6_addr ip6;
13630   struct in_addr ip4;
13631
13632   ASSERT (vam != NULL);
13633   ASSERT (node != NULL);
13634   ASSERT (eid_table != NULL);
13635
13636   locator_array = vat_json_object_add_list (node, "locator");
13637   vec_foreach (loc, vam->locator_msg)
13638   {
13639     locator = vat_json_array_add (locator_array);
13640     vat_json_init_object (locator);
13641     if (loc->local)
13642       {
13643         vat_json_object_add_uint (locator, "locator-index", loc->sw_if_index);
13644       }
13645     else
13646       {
13647         if (loc->is_ipv6)
13648           {
13649             clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
13650             vat_json_object_add_ip6 (locator, "locator", ip6);
13651           }
13652         else
13653           {
13654             clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
13655             vat_json_object_add_ip4 (locator, "locator", ip4);
13656           }
13657       }
13658   }
13659 }
13660
13661 static int
13662 json_lisp_eid_table_dump (vat_main_t * vam)
13663 {
13664   eid_table_t *eid_table;
13665   vat_json_node_t *node = 0;
13666   int ret = 0;
13667
13668   ASSERT (vam != NULL);
13669
13670   ret = get_locator_set (vam);
13671   if (ret)
13672     {
13673       vec_free (vam->eid_tables);
13674       return ret;
13675     }
13676
13677   if (!vec_len (vam->eid_tables))
13678     {
13679       /* just print [] */
13680       vat_json_init_array (&vam->json_tree);
13681       vat_json_print (vam->ofp, &vam->json_tree);
13682       vam->json_tree.type = VAT_JSON_NONE;
13683       return ret;
13684     }
13685
13686   if (VAT_JSON_ARRAY != vam->json_tree.type)
13687     {
13688       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13689       vat_json_init_array (&vam->json_tree);
13690     }
13691
13692   vec_foreach (eid_table, vam->eid_tables)
13693   {
13694     ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index, 0);
13695     if (ret)
13696       {
13697         vec_free (vam->locator_msg);
13698         vec_free (vam->eid_tables);
13699         clean_locator_set_message (vam);
13700         vat_json_free (&vam->json_tree);
13701         vam->json_tree.type = VAT_JSON_NONE;
13702         return ret;
13703       }
13704
13705     node = vat_json_array_add (&vam->json_tree);
13706     vat_json_init_object (node);
13707
13708     vat_json_object_add_uint (node, "vni", eid_table->vni);
13709
13710     json_locator_set_for_eid_table (vam, node, eid_table);
13711     ret = json_eid_for_eid_table (vam, node, eid_table);
13712     if (ret)
13713       {
13714         vec_free (vam->locator_msg);
13715         vec_free (vam->eid_tables);
13716         clean_locator_set_message (vam);
13717         vat_json_free (&vam->json_tree);
13718         vam->json_tree.type = VAT_JSON_NONE;
13719         return ret;
13720       }
13721
13722     json_locator_for_eid_table (vam, node, eid_table);
13723
13724     vat_json_object_add_uint (node, "ttl", eid_table->ttl);
13725     vat_json_object_add_uint (node, "authoritative",
13726                               eid_table->authoritative);
13727
13728     vec_free (vam->locator_msg);
13729   }
13730
13731   vat_json_print (vam->ofp, &vam->json_tree);
13732   vat_json_free (&vam->json_tree);
13733   vam->json_tree.type = VAT_JSON_NONE;
13734
13735   clean_locator_set_message (vam);
13736   vec_free (vam->eid_tables);
13737
13738   return ret;
13739 }
13740
13741 static int
13742 api_lisp_eid_table_dump (vat_main_t * vam)
13743 {
13744   unformat_input_t *i = vam->input;
13745   vl_api_lisp_eid_table_dump_t *mp;
13746   f64 timeout = ~0;
13747   struct in_addr ip4;
13748   struct in6_addr ip6;
13749   u8 mac[6];
13750   u8 eid_type = ~0, eid_set = 0;
13751   u32 prefix_length = ~0, t, vni = 0;
13752   u8 filter = 0;
13753
13754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13755     {
13756       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13757         {
13758           eid_set = 1;
13759           eid_type = 0;
13760           prefix_length = t;
13761         }
13762       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13763         {
13764           eid_set = 1;
13765           eid_type = 1;
13766           prefix_length = t;
13767         }
13768       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13769         {
13770           eid_set = 1;
13771           eid_type = 2;
13772         }
13773       else if (unformat (i, "vni %d", &t))
13774         {
13775           vni = t;
13776         }
13777       else if (unformat (i, "local"))
13778         {
13779           filter = 1;
13780         }
13781       else if (unformat (i, "remote"))
13782         {
13783           filter = 2;
13784         }
13785       else
13786         {
13787           errmsg ("parse error '%U'", format_unformat_error, i);
13788           return -99;
13789         }
13790     }
13791
13792   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13793
13794   mp->filter = filter;
13795   if (eid_set)
13796     {
13797       mp->eid_set = 1;
13798       mp->vni = htonl (vni);
13799       mp->eid_type = eid_type;
13800       switch (eid_type)
13801         {
13802         case 0:
13803           mp->prefix_length = prefix_length;
13804           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13805           break;
13806         case 1:
13807           mp->prefix_length = prefix_length;
13808           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13809           break;
13810         case 2:
13811           clib_memcpy (mp->eid, mac, sizeof (mac));
13812           break;
13813         default:
13814           errmsg ("unknown EID type %d!", eid_type);
13815           return -99;
13816         }
13817     }
13818
13819   vam->noprint_msg = 1;
13820
13821   /* send it... */
13822   S;
13823
13824   /* Use a control ping for synchronization */
13825   {
13826     vl_api_noprint_control_ping_t *mp;
13827     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13828     S;
13829   }
13830
13831   /* Wait for a reply... */
13832   /* *INDENT-OFF* */
13833   W_L
13834   ({
13835     if (vam->noprint_msg)
13836       {
13837         if (!vam->json_output)
13838           {
13839             vam->retval = print_lisp_eid_table_dump(vam);
13840           }
13841         else
13842           {
13843             vam->retval = json_lisp_eid_table_dump(vam);
13844           }
13845       }
13846     vam->noprint_msg = 0;
13847   });
13848   /* *INDENT-ON* */
13849
13850   /* NOTREACHED */
13851   return 0;
13852 }
13853
13854 static int
13855 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13856 {
13857   vl_api_lisp_gpe_tunnel_dump_t *mp;
13858   f64 timeout = ~0;
13859
13860   if (!vam->json_output)
13861     {
13862       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13863                "%=16s%=16s%=16s%=16s%=16s\n",
13864                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13865                "Decap next", "Lisp version", "Flags", "Next protocol",
13866                "ver_res", "res", "iid");
13867     }
13868
13869   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13870   /* send it... */
13871   S;
13872
13873   /* Use a control ping for synchronization */
13874   {
13875     vl_api_control_ping_t *mp;
13876     M (CONTROL_PING, control_ping);
13877     S;
13878   }
13879   /* Wait for a reply... */
13880   W;
13881
13882   /* NOTREACHED */
13883   return 0;
13884 }
13885
13886 static int
13887 api_lisp_map_resolver_dump (vat_main_t * vam)
13888 {
13889   vl_api_lisp_map_resolver_dump_t *mp;
13890   f64 timeout = ~0;
13891
13892   if (!vam->json_output)
13893     {
13894       fformat (vam->ofp, "%=20s\n", "Map resolver");
13895     }
13896
13897   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13898   /* send it... */
13899   S;
13900
13901   /* Use a control ping for synchronization */
13902   {
13903     vl_api_control_ping_t *mp;
13904     M (CONTROL_PING, control_ping);
13905     S;
13906   }
13907   /* Wait for a reply... */
13908   W;
13909
13910   /* NOTREACHED */
13911   return 0;
13912 }
13913
13914 static int
13915 api_show_lisp_status (vat_main_t * vam)
13916 {
13917   vl_api_show_lisp_status_t *mp;
13918   f64 timeout = ~0;
13919
13920   if (!vam->json_output)
13921     {
13922       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13923     }
13924
13925   M (SHOW_LISP_STATUS, show_lisp_status);
13926   /* send it... */
13927   S;
13928   /* Wait for a reply... */
13929   W;
13930
13931   /* NOTREACHED */
13932   return 0;
13933 }
13934
13935 static int
13936 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13937 {
13938   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13939   f64 timeout = ~0;
13940
13941   if (!vam->json_output)
13942     {
13943       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13944     }
13945
13946   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13947   /* send it... */
13948   S;
13949   /* Wait for a reply... */
13950   W;
13951
13952   /* NOTREACHED */
13953   return 0;
13954 }
13955
13956 static int
13957 api_af_packet_create (vat_main_t * vam)
13958 {
13959   unformat_input_t *i = vam->input;
13960   vl_api_af_packet_create_t *mp;
13961   f64 timeout;
13962   u8 *host_if_name = 0;
13963   u8 hw_addr[6];
13964   u8 random_hw_addr = 1;
13965
13966   memset (hw_addr, 0, sizeof (hw_addr));
13967
13968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13969     {
13970       if (unformat (i, "name %s", &host_if_name))
13971         vec_add1 (host_if_name, 0);
13972       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13973         random_hw_addr = 0;
13974       else
13975         break;
13976     }
13977
13978   if (!vec_len (host_if_name))
13979     {
13980       errmsg ("host-interface name must be specified");
13981       return -99;
13982     }
13983
13984   if (vec_len (host_if_name) > 64)
13985     {
13986       errmsg ("host-interface name too long");
13987       return -99;
13988     }
13989
13990   M (AF_PACKET_CREATE, af_packet_create);
13991
13992   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13993   clib_memcpy (mp->hw_addr, hw_addr, 6);
13994   mp->use_random_hw_addr = random_hw_addr;
13995   vec_free (host_if_name);
13996
13997   S;
13998   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
13999   /* NOTREACHED */
14000   return 0;
14001 }
14002
14003 static int
14004 api_af_packet_delete (vat_main_t * vam)
14005 {
14006   unformat_input_t *i = vam->input;
14007   vl_api_af_packet_delete_t *mp;
14008   f64 timeout;
14009   u8 *host_if_name = 0;
14010
14011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14012     {
14013       if (unformat (i, "name %s", &host_if_name))
14014         vec_add1 (host_if_name, 0);
14015       else
14016         break;
14017     }
14018
14019   if (!vec_len (host_if_name))
14020     {
14021       errmsg ("host-interface name must be specified");
14022       return -99;
14023     }
14024
14025   if (vec_len (host_if_name) > 64)
14026     {
14027       errmsg ("host-interface name too long");
14028       return -99;
14029     }
14030
14031   M (AF_PACKET_DELETE, af_packet_delete);
14032
14033   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14034   vec_free (host_if_name);
14035
14036   S;
14037   W;
14038   /* NOTREACHED */
14039   return 0;
14040 }
14041
14042 static int
14043 api_policer_add_del (vat_main_t * vam)
14044 {
14045   unformat_input_t *i = vam->input;
14046   vl_api_policer_add_del_t *mp;
14047   f64 timeout;
14048   u8 is_add = 1;
14049   u8 *name = 0;
14050   u32 cir = 0;
14051   u32 eir = 0;
14052   u64 cb = 0;
14053   u64 eb = 0;
14054   u8 rate_type = 0;
14055   u8 round_type = 0;
14056   u8 type = 0;
14057   u8 color_aware = 0;
14058   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14059
14060   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14061   conform_action.dscp = 0;
14062   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14063   exceed_action.dscp = 0;
14064   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14065   violate_action.dscp = 0;
14066
14067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14068     {
14069       if (unformat (i, "del"))
14070         is_add = 0;
14071       else if (unformat (i, "name %s", &name))
14072         vec_add1 (name, 0);
14073       else if (unformat (i, "cir %u", &cir))
14074         ;
14075       else if (unformat (i, "eir %u", &eir))
14076         ;
14077       else if (unformat (i, "cb %u", &cb))
14078         ;
14079       else if (unformat (i, "eb %u", &eb))
14080         ;
14081       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14082                          &rate_type))
14083         ;
14084       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14085                          &round_type))
14086         ;
14087       else if (unformat (i, "type %U", unformat_policer_type, &type))
14088         ;
14089       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14090                          &conform_action))
14091         ;
14092       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14093                          &exceed_action))
14094         ;
14095       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14096                          &violate_action))
14097         ;
14098       else if (unformat (i, "color-aware"))
14099         color_aware = 1;
14100       else
14101         break;
14102     }
14103
14104   if (!vec_len (name))
14105     {
14106       errmsg ("policer name must be specified");
14107       return -99;
14108     }
14109
14110   if (vec_len (name) > 64)
14111     {
14112       errmsg ("policer name too long");
14113       return -99;
14114     }
14115
14116   M (POLICER_ADD_DEL, policer_add_del);
14117
14118   clib_memcpy (mp->name, name, vec_len (name));
14119   vec_free (name);
14120   mp->is_add = is_add;
14121   mp->cir = cir;
14122   mp->eir = eir;
14123   mp->cb = cb;
14124   mp->eb = eb;
14125   mp->rate_type = rate_type;
14126   mp->round_type = round_type;
14127   mp->type = type;
14128   mp->conform_action_type = conform_action.action_type;
14129   mp->conform_dscp = conform_action.dscp;
14130   mp->exceed_action_type = exceed_action.action_type;
14131   mp->exceed_dscp = exceed_action.dscp;
14132   mp->violate_action_type = violate_action.action_type;
14133   mp->violate_dscp = violate_action.dscp;
14134   mp->color_aware = color_aware;
14135
14136   S;
14137   W;
14138   /* NOTREACHED */
14139   return 0;
14140 }
14141
14142 static int
14143 api_policer_dump (vat_main_t * vam)
14144 {
14145   unformat_input_t *i = vam->input;
14146   vl_api_policer_dump_t *mp;
14147   f64 timeout = ~0;
14148   u8 *match_name = 0;
14149   u8 match_name_valid = 0;
14150
14151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14152     {
14153       if (unformat (i, "name %s", &match_name))
14154         {
14155           vec_add1 (match_name, 0);
14156           match_name_valid = 1;
14157         }
14158       else
14159         break;
14160     }
14161
14162   M (POLICER_DUMP, policer_dump);
14163   mp->match_name_valid = match_name_valid;
14164   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14165   vec_free (match_name);
14166   /* send it... */
14167   S;
14168
14169   /* Use a control ping for synchronization */
14170   {
14171     vl_api_control_ping_t *mp;
14172     M (CONTROL_PING, control_ping);
14173     S;
14174   }
14175   /* Wait for a reply... */
14176   W;
14177
14178   /* NOTREACHED */
14179   return 0;
14180 }
14181
14182 static int
14183 api_policer_classify_set_interface (vat_main_t * vam)
14184 {
14185   unformat_input_t *i = vam->input;
14186   vl_api_policer_classify_set_interface_t *mp;
14187   f64 timeout;
14188   u32 sw_if_index;
14189   int sw_if_index_set;
14190   u32 ip4_table_index = ~0;
14191   u32 ip6_table_index = ~0;
14192   u32 l2_table_index = ~0;
14193   u8 is_add = 1;
14194
14195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14196     {
14197       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14198         sw_if_index_set = 1;
14199       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14200         sw_if_index_set = 1;
14201       else if (unformat (i, "del"))
14202         is_add = 0;
14203       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14204         ;
14205       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14206         ;
14207       else if (unformat (i, "l2-table %d", &l2_table_index))
14208         ;
14209       else
14210         {
14211           clib_warning ("parse error '%U'", format_unformat_error, i);
14212           return -99;
14213         }
14214     }
14215
14216   if (sw_if_index_set == 0)
14217     {
14218       errmsg ("missing interface name or sw_if_index\n");
14219       return -99;
14220     }
14221
14222   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14223
14224   mp->sw_if_index = ntohl (sw_if_index);
14225   mp->ip4_table_index = ntohl (ip4_table_index);
14226   mp->ip6_table_index = ntohl (ip6_table_index);
14227   mp->l2_table_index = ntohl (l2_table_index);
14228   mp->is_add = is_add;
14229
14230   S;
14231   W;
14232   /* NOTREACHED */
14233   return 0;
14234 }
14235
14236 static int
14237 api_policer_classify_dump (vat_main_t * vam)
14238 {
14239   unformat_input_t *i = vam->input;
14240   vl_api_policer_classify_dump_t *mp;
14241   f64 timeout = ~0;
14242   u8 type = POLICER_CLASSIFY_N_TABLES;
14243
14244   if (unformat (i, "type %U", unformat_classify_table_type, &type))
14245     ;
14246   else
14247     {
14248       errmsg ("classify table type must be specified\n");
14249       return -99;
14250     }
14251
14252   if (!vam->json_output)
14253     {
14254       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14255     }
14256
14257   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14258   mp->type = type;
14259   /* send it... */
14260   S;
14261
14262   /* Use a control ping for synchronization */
14263   {
14264     vl_api_control_ping_t *mp;
14265     M (CONTROL_PING, control_ping);
14266     S;
14267   }
14268   /* Wait for a reply... */
14269   W;
14270
14271   /* NOTREACHED */
14272   return 0;
14273 }
14274
14275 static int
14276 api_netmap_create (vat_main_t * vam)
14277 {
14278   unformat_input_t *i = vam->input;
14279   vl_api_netmap_create_t *mp;
14280   f64 timeout;
14281   u8 *if_name = 0;
14282   u8 hw_addr[6];
14283   u8 random_hw_addr = 1;
14284   u8 is_pipe = 0;
14285   u8 is_master = 0;
14286
14287   memset (hw_addr, 0, sizeof (hw_addr));
14288
14289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14290     {
14291       if (unformat (i, "name %s", &if_name))
14292         vec_add1 (if_name, 0);
14293       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14294         random_hw_addr = 0;
14295       else if (unformat (i, "pipe"))
14296         is_pipe = 1;
14297       else if (unformat (i, "master"))
14298         is_master = 1;
14299       else if (unformat (i, "slave"))
14300         is_master = 0;
14301       else
14302         break;
14303     }
14304
14305   if (!vec_len (if_name))
14306     {
14307       errmsg ("interface name must be specified");
14308       return -99;
14309     }
14310
14311   if (vec_len (if_name) > 64)
14312     {
14313       errmsg ("interface name too long");
14314       return -99;
14315     }
14316
14317   M (NETMAP_CREATE, netmap_create);
14318
14319   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14320   clib_memcpy (mp->hw_addr, hw_addr, 6);
14321   mp->use_random_hw_addr = random_hw_addr;
14322   mp->is_pipe = is_pipe;
14323   mp->is_master = is_master;
14324   vec_free (if_name);
14325
14326   S;
14327   W;
14328   /* NOTREACHED */
14329   return 0;
14330 }
14331
14332 static int
14333 api_netmap_delete (vat_main_t * vam)
14334 {
14335   unformat_input_t *i = vam->input;
14336   vl_api_netmap_delete_t *mp;
14337   f64 timeout;
14338   u8 *if_name = 0;
14339
14340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14341     {
14342       if (unformat (i, "name %s", &if_name))
14343         vec_add1 (if_name, 0);
14344       else
14345         break;
14346     }
14347
14348   if (!vec_len (if_name))
14349     {
14350       errmsg ("interface name must be specified");
14351       return -99;
14352     }
14353
14354   if (vec_len (if_name) > 64)
14355     {
14356       errmsg ("interface name too long");
14357       return -99;
14358     }
14359
14360   M (NETMAP_DELETE, netmap_delete);
14361
14362   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14363   vec_free (if_name);
14364
14365   S;
14366   W;
14367   /* NOTREACHED */
14368   return 0;
14369 }
14370
14371 static void vl_api_mpls_gre_tunnel_details_t_handler
14372   (vl_api_mpls_gre_tunnel_details_t * mp)
14373 {
14374   vat_main_t *vam = &vat_main;
14375   i32 i;
14376   i32 len = ntohl (mp->nlabels);
14377
14378   if (mp->l2_only == 0)
14379     {
14380       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14381                ntohl (mp->tunnel_index),
14382                format_ip4_address, &mp->tunnel_src,
14383                format_ip4_address, &mp->tunnel_dst,
14384                format_ip4_address, &mp->intfc_address,
14385                ntohl (mp->mask_width));
14386       for (i = 0; i < len; i++)
14387         {
14388           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14389         }
14390       fformat (vam->ofp, "\n");
14391       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14392                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14393     }
14394   else
14395     {
14396       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14397                ntohl (mp->tunnel_index),
14398                format_ip4_address, &mp->tunnel_src,
14399                format_ip4_address, &mp->tunnel_dst,
14400                format_ip4_address, &mp->intfc_address);
14401       for (i = 0; i < len; i++)
14402         {
14403           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14404         }
14405       fformat (vam->ofp, "\n");
14406       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14407                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14408     }
14409 }
14410
14411 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14412   (vl_api_mpls_gre_tunnel_details_t * mp)
14413 {
14414   vat_main_t *vam = &vat_main;
14415   vat_json_node_t *node = NULL;
14416   struct in_addr ip4;
14417   i32 i;
14418   i32 len = ntohl (mp->nlabels);
14419
14420   if (VAT_JSON_ARRAY != vam->json_tree.type)
14421     {
14422       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14423       vat_json_init_array (&vam->json_tree);
14424     }
14425   node = vat_json_array_add (&vam->json_tree);
14426
14427   vat_json_init_object (node);
14428   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14429   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14430   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14431   vat_json_object_add_uint (node, "inner_fib_index",
14432                             ntohl (mp->inner_fib_index));
14433   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14434   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14435   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14436   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14437   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14438   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14439   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14440   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14441   vat_json_object_add_uint (node, "outer_fib_index",
14442                             ntohl (mp->outer_fib_index));
14443   vat_json_object_add_uint (node, "label_count", len);
14444   for (i = 0; i < len; i++)
14445     {
14446       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14447     }
14448 }
14449
14450 static int
14451 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14452 {
14453   vl_api_mpls_gre_tunnel_dump_t *mp;
14454   f64 timeout;
14455   i32 index = -1;
14456
14457   /* Parse args required to build the message */
14458   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14459     {
14460       if (!unformat (vam->input, "tunnel_index %d", &index))
14461         {
14462           index = -1;
14463           break;
14464         }
14465     }
14466
14467   fformat (vam->ofp, "  tunnel_index %d\n", index);
14468
14469   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14470   mp->tunnel_index = htonl (index);
14471   S;
14472
14473   /* Use a control ping for synchronization */
14474   {
14475     vl_api_control_ping_t *mp;
14476     M (CONTROL_PING, control_ping);
14477     S;
14478   }
14479   W;
14480 }
14481
14482 static void vl_api_mpls_eth_tunnel_details_t_handler
14483   (vl_api_mpls_eth_tunnel_details_t * mp)
14484 {
14485   vat_main_t *vam = &vat_main;
14486   i32 i;
14487   i32 len = ntohl (mp->nlabels);
14488
14489   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14490            ntohl (mp->tunnel_index),
14491            format_ethernet_address, &mp->tunnel_dst_mac,
14492            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14493   for (i = 0; i < len; i++)
14494     {
14495       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14496     }
14497   fformat (vam->ofp, "\n");
14498   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14499            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14500 }
14501
14502 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14503   (vl_api_mpls_eth_tunnel_details_t * mp)
14504 {
14505   vat_main_t *vam = &vat_main;
14506   vat_json_node_t *node = NULL;
14507   struct in_addr ip4;
14508   i32 i;
14509   i32 len = ntohl (mp->nlabels);
14510
14511   if (VAT_JSON_ARRAY != vam->json_tree.type)
14512     {
14513       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14514       vat_json_init_array (&vam->json_tree);
14515     }
14516   node = vat_json_array_add (&vam->json_tree);
14517
14518   vat_json_init_object (node);
14519   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14520   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14521   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14522   vat_json_object_add_uint (node, "inner_fib_index",
14523                             ntohl (mp->inner_fib_index));
14524   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14525   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14526   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14527   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14528   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14529                                    format (0, "%U", format_ethernet_address,
14530                                            &mp->tunnel_dst_mac));
14531   vat_json_object_add_uint (node, "tx_sw_if_index",
14532                             ntohl (mp->tx_sw_if_index));
14533   vat_json_object_add_uint (node, "label_count", len);
14534   for (i = 0; i < len; i++)
14535     {
14536       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14537     }
14538 }
14539
14540 static int
14541 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14542 {
14543   vl_api_mpls_eth_tunnel_dump_t *mp;
14544   f64 timeout;
14545   i32 index = -1;
14546
14547   /* Parse args required to build the message */
14548   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14549     {
14550       if (!unformat (vam->input, "tunnel_index %d", &index))
14551         {
14552           index = -1;
14553           break;
14554         }
14555     }
14556
14557   fformat (vam->ofp, "  tunnel_index %d\n", index);
14558
14559   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14560   mp->tunnel_index = htonl (index);
14561   S;
14562
14563   /* Use a control ping for synchronization */
14564   {
14565     vl_api_control_ping_t *mp;
14566     M (CONTROL_PING, control_ping);
14567     S;
14568   }
14569   W;
14570 }
14571
14572 static void vl_api_mpls_fib_encap_details_t_handler
14573   (vl_api_mpls_fib_encap_details_t * mp)
14574 {
14575   vat_main_t *vam = &vat_main;
14576   i32 i;
14577   i32 len = ntohl (mp->nlabels);
14578
14579   fformat (vam->ofp, "table %d, dest %U, label ",
14580            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14581   for (i = 0; i < len; i++)
14582     {
14583       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14584     }
14585   fformat (vam->ofp, "\n");
14586 }
14587
14588 static void vl_api_mpls_fib_encap_details_t_handler_json
14589   (vl_api_mpls_fib_encap_details_t * mp)
14590 {
14591   vat_main_t *vam = &vat_main;
14592   vat_json_node_t *node = NULL;
14593   i32 i;
14594   i32 len = ntohl (mp->nlabels);
14595   struct in_addr ip4;
14596
14597   if (VAT_JSON_ARRAY != vam->json_tree.type)
14598     {
14599       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14600       vat_json_init_array (&vam->json_tree);
14601     }
14602   node = vat_json_array_add (&vam->json_tree);
14603
14604   vat_json_init_object (node);
14605   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14606   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14607   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14608   vat_json_object_add_ip4 (node, "dest", ip4);
14609   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14610   vat_json_object_add_uint (node, "label_count", len);
14611   for (i = 0; i < len; i++)
14612     {
14613       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14614     }
14615 }
14616
14617 static int
14618 api_mpls_fib_encap_dump (vat_main_t * vam)
14619 {
14620   vl_api_mpls_fib_encap_dump_t *mp;
14621   f64 timeout;
14622
14623   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14624   S;
14625
14626   /* Use a control ping for synchronization */
14627   {
14628     vl_api_control_ping_t *mp;
14629     M (CONTROL_PING, control_ping);
14630     S;
14631   }
14632   W;
14633 }
14634
14635 static void vl_api_mpls_fib_decap_details_t_handler
14636   (vl_api_mpls_fib_decap_details_t * mp)
14637 {
14638   vat_main_t *vam = &vat_main;
14639
14640   fformat (vam->ofp,
14641            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14642            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14643            ntohl (mp->label), ntohl (mp->s_bit));
14644 }
14645
14646 static void vl_api_mpls_fib_decap_details_t_handler_json
14647   (vl_api_mpls_fib_decap_details_t * mp)
14648 {
14649   vat_main_t *vam = &vat_main;
14650   vat_json_node_t *node = NULL;
14651   struct in_addr ip4;
14652
14653   if (VAT_JSON_ARRAY != vam->json_tree.type)
14654     {
14655       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14656       vat_json_init_array (&vam->json_tree);
14657     }
14658   node = vat_json_array_add (&vam->json_tree);
14659
14660   vat_json_init_object (node);
14661   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14662   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14663   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14664   vat_json_object_add_ip4 (node, "dest", ip4);
14665   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14666   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14667   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14668   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14669   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14670 }
14671
14672 static int
14673 api_mpls_fib_decap_dump (vat_main_t * vam)
14674 {
14675   vl_api_mpls_fib_decap_dump_t *mp;
14676   f64 timeout;
14677
14678   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14679   S;
14680
14681   /* Use a control ping for synchronization */
14682   {
14683     vl_api_control_ping_t *mp;
14684     M (CONTROL_PING, control_ping);
14685     S;
14686   }
14687   W;
14688 }
14689
14690 int
14691 api_classify_table_ids (vat_main_t * vam)
14692 {
14693   vl_api_classify_table_ids_t *mp;
14694   f64 timeout;
14695
14696   /* Construct the API message */
14697   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14698   mp->context = 0;
14699
14700   S;
14701   W;
14702   /* NOTREACHED */
14703   return 0;
14704 }
14705
14706 int
14707 api_classify_table_by_interface (vat_main_t * vam)
14708 {
14709   unformat_input_t *input = vam->input;
14710   vl_api_classify_table_by_interface_t *mp;
14711   f64 timeout;
14712
14713   u32 sw_if_index = ~0;
14714   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14715     {
14716       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14717         ;
14718       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14719         ;
14720       else
14721         break;
14722     }
14723   if (sw_if_index == ~0)
14724     {
14725       errmsg ("missing interface name or sw_if_index\n");
14726       return -99;
14727     }
14728
14729   /* Construct the API message */
14730   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14731   mp->context = 0;
14732   mp->sw_if_index = ntohl (sw_if_index);
14733
14734   S;
14735   W;
14736   /* NOTREACHED */
14737   return 0;
14738 }
14739
14740 int
14741 api_classify_table_info (vat_main_t * vam)
14742 {
14743   unformat_input_t *input = vam->input;
14744   vl_api_classify_table_info_t *mp;
14745   f64 timeout;
14746
14747   u32 table_id = ~0;
14748   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14749     {
14750       if (unformat (input, "table_id %d", &table_id))
14751         ;
14752       else
14753         break;
14754     }
14755   if (table_id == ~0)
14756     {
14757       errmsg ("missing table id\n");
14758       return -99;
14759     }
14760
14761   /* Construct the API message */
14762   M (CLASSIFY_TABLE_INFO, classify_table_info);
14763   mp->context = 0;
14764   mp->table_id = ntohl (table_id);
14765
14766   S;
14767   W;
14768   /* NOTREACHED */
14769   return 0;
14770 }
14771
14772 int
14773 api_classify_session_dump (vat_main_t * vam)
14774 {
14775   unformat_input_t *input = vam->input;
14776   vl_api_classify_session_dump_t *mp;
14777   f64 timeout;
14778
14779   u32 table_id = ~0;
14780   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14781     {
14782       if (unformat (input, "table_id %d", &table_id))
14783         ;
14784       else
14785         break;
14786     }
14787   if (table_id == ~0)
14788     {
14789       errmsg ("missing table id\n");
14790       return -99;
14791     }
14792
14793   /* Construct the API message */
14794   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14795   mp->context = 0;
14796   mp->table_id = ntohl (table_id);
14797   S;
14798
14799   /* Use a control ping for synchronization */
14800   {
14801     vl_api_control_ping_t *mp;
14802     M (CONTROL_PING, control_ping);
14803     S;
14804   }
14805   W;
14806   /* NOTREACHED */
14807   return 0;
14808 }
14809
14810 static void
14811 vl_api_ipfix_details_t_handler (vl_api_ipfix_details_t * mp)
14812 {
14813   vat_main_t *vam = &vat_main;
14814
14815   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14816            "src_address %U, fib_index %u, path_mtu %u, "
14817            "template_interval %u\n",
14818            format_ip4_address, mp->collector_address,
14819            ntohs (mp->collector_port),
14820            format_ip4_address, mp->src_address,
14821            ntohl (mp->fib_index),
14822            ntohl (mp->path_mtu), ntohl (mp->template_interval));
14823
14824   vam->retval = 0;
14825   vam->result_ready = 1;
14826 }
14827
14828 static void
14829 vl_api_ipfix_details_t_handler_json (vl_api_ipfix_details_t * mp)
14830 {
14831   vat_main_t *vam = &vat_main;
14832   vat_json_node_t node;
14833   struct in_addr collector_address;
14834   struct in_addr src_address;
14835
14836   vat_json_init_object (&node);
14837   clib_memcpy (&collector_address, &mp->collector_address,
14838                sizeof (collector_address));
14839   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14840   vat_json_object_add_uint (&node, "collector_port",
14841                             ntohs (mp->collector_port));
14842   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14843   vat_json_object_add_ip4 (&node, "src_address", src_address);
14844   vat_json_object_add_uint (&node, "fib_index", ntohl (mp->fib_index));
14845   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14846   vat_json_object_add_uint (&node, "template_interval",
14847                             ntohl (mp->template_interval));
14848
14849   vat_json_print (vam->ofp, &node);
14850   vat_json_free (&node);
14851   vam->retval = 0;
14852   vam->result_ready = 1;
14853 }
14854
14855 int
14856 api_ipfix_dump (vat_main_t * vam)
14857 {
14858   vl_api_ipfix_dump_t *mp;
14859   f64 timeout;
14860
14861   /* Construct the API message */
14862   M (IPFIX_DUMP, ipfix_dump);
14863   mp->context = 0;
14864
14865   S;
14866   W;
14867   /* NOTREACHED */
14868   return 0;
14869 }
14870
14871 int
14872 api_pg_create_interface (vat_main_t * vam)
14873 {
14874   unformat_input_t *input = vam->input;
14875   vl_api_pg_create_interface_t *mp;
14876   f64 timeout;
14877
14878   u32 if_id = ~0;
14879   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14880     {
14881       if (unformat (input, "if_id %d", &if_id))
14882         ;
14883       else
14884         break;
14885     }
14886   if (if_id == ~0)
14887     {
14888       errmsg ("missing pg interface index\n");
14889       return -99;
14890     }
14891
14892   /* Construct the API message */
14893   M (PG_CREATE_INTERFACE, pg_create_interface);
14894   mp->context = 0;
14895   mp->interface_id = ntohl (if_id);
14896
14897   S;
14898   W;
14899   /* NOTREACHED */
14900   return 0;
14901 }
14902
14903 int
14904 api_pg_capture (vat_main_t * vam)
14905 {
14906   unformat_input_t *input = vam->input;
14907   vl_api_pg_capture_t *mp;
14908   f64 timeout;
14909
14910   u32 if_id = ~0;
14911   u8 enable = 1;
14912   u32 count = 1;
14913   u8 pcap_file_set = 0;
14914   u8 *pcap_file = 0;
14915   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14916     {
14917       if (unformat (input, "if_id %d", &if_id))
14918         ;
14919       else if (unformat (input, "pcap %s", &pcap_file))
14920         pcap_file_set = 1;
14921       else if (unformat (input, "count %d", &count))
14922         ;
14923       else if (unformat (input, "disable"))
14924         enable = 0;
14925       else
14926         break;
14927     }
14928   if (if_id == ~0)
14929     {
14930       errmsg ("missing pg interface index\n");
14931       return -99;
14932     }
14933   if (pcap_file_set > 0)
14934     {
14935       if (vec_len (pcap_file) > 255)
14936         {
14937           errmsg ("pcap file name is too long\n");
14938           return -99;
14939         }
14940     }
14941
14942   u32 name_len = vec_len (pcap_file);
14943   /* Construct the API message */
14944   M (PG_CAPTURE, pg_capture);
14945   mp->context = 0;
14946   mp->interface_id = ntohl (if_id);
14947   mp->is_enabled = enable;
14948   mp->count = ntohl (count);
14949   mp->pcap_name_length = ntohl (name_len);
14950   if (pcap_file_set != 0)
14951     {
14952       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14953     }
14954   vec_free (pcap_file);
14955
14956   S;
14957   W;
14958   /* NOTREACHED */
14959   return 0;
14960 }
14961
14962 int
14963 api_pg_enable_disable (vat_main_t * vam)
14964 {
14965   unformat_input_t *input = vam->input;
14966   vl_api_pg_enable_disable_t *mp;
14967   f64 timeout;
14968
14969   u8 enable = 1;
14970   u8 stream_name_set = 0;
14971   u8 *stream_name = 0;
14972   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14973     {
14974       if (unformat (input, "stream %s", &stream_name))
14975         stream_name_set = 1;
14976       else if (unformat (input, "disable"))
14977         enable = 0;
14978       else
14979         break;
14980     }
14981
14982   if (stream_name_set > 0)
14983     {
14984       if (vec_len (stream_name) > 255)
14985         {
14986           errmsg ("stream name too long\n");
14987           return -99;
14988         }
14989     }
14990
14991   u32 name_len = vec_len (stream_name);
14992   /* Construct the API message */
14993   M (PG_ENABLE_DISABLE, pg_enable_disable);
14994   mp->context = 0;
14995   mp->is_enabled = enable;
14996   if (stream_name_set != 0)
14997     {
14998       mp->stream_name_length = ntohl (name_len);
14999       clib_memcpy (mp->stream_name, stream_name, name_len);
15000     }
15001   vec_free (stream_name);
15002
15003   S;
15004   W;
15005   /* NOTREACHED */
15006   return 0;
15007 }
15008
15009 int
15010 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15011 {
15012   unformat_input_t *input = vam->input;
15013   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15014   f64 timeout;
15015
15016   u16 *low_ports = 0;
15017   u16 *high_ports = 0;
15018   u16 this_low;
15019   u16 this_hi;
15020   ip4_address_t ip4_addr;
15021   ip6_address_t ip6_addr;
15022   u32 length;
15023   u32 tmp, tmp2;
15024   u8 prefix_set = 0;
15025   u32 vrf_id = ~0;
15026   u8 is_add = 1;
15027   u8 is_ipv6 = 0;
15028
15029   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15030     {
15031       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15032         {
15033           prefix_set = 1;
15034         }
15035       else
15036         if (unformat
15037             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15038         {
15039           prefix_set = 1;
15040           is_ipv6 = 1;
15041         }
15042       else if (unformat (input, "vrf %d", &vrf_id))
15043         ;
15044       else if (unformat (input, "del"))
15045         is_add = 0;
15046       else if (unformat (input, "port %d", &tmp))
15047         {
15048           if (tmp == 0 || tmp > 65535)
15049             {
15050               errmsg ("port %d out of range", tmp);
15051               return -99;
15052             }
15053           this_low = tmp;
15054           this_hi = this_low + 1;
15055           vec_add1 (low_ports, this_low);
15056           vec_add1 (high_ports, this_hi);
15057         }
15058       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15059         {
15060           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15061             {
15062               errmsg ("incorrect range parameters\n");
15063               return -99;
15064             }
15065           this_low = tmp;
15066           /* Note: in debug CLI +1 is added to high before
15067              passing to real fn that does "the work"
15068              (ip_source_and_port_range_check_add_del).
15069              This fn is a wrapper around the binary API fn a
15070              control plane will call, which expects this increment
15071              to have occurred. Hence letting the binary API control
15072              plane fn do the increment for consistency between VAT
15073              and other control planes.
15074            */
15075           this_hi = tmp2;
15076           vec_add1 (low_ports, this_low);
15077           vec_add1 (high_ports, this_hi);
15078         }
15079       else
15080         break;
15081     }
15082
15083   if (prefix_set == 0)
15084     {
15085       errmsg ("<address>/<mask> not specified\n");
15086       return -99;
15087     }
15088
15089   if (vrf_id == ~0)
15090     {
15091       errmsg ("VRF ID required, not specified\n");
15092       return -99;
15093     }
15094
15095   if (vrf_id == 0)
15096     {
15097       errmsg
15098         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15099       return -99;
15100     }
15101
15102   if (vec_len (low_ports) == 0)
15103     {
15104       errmsg ("At least one port or port range required\n");
15105       return -99;
15106     }
15107
15108   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15109      ip_source_and_port_range_check_add_del);
15110
15111   mp->is_add = is_add;
15112
15113   if (is_ipv6)
15114     {
15115       mp->is_ipv6 = 1;
15116       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15117     }
15118   else
15119     {
15120       mp->is_ipv6 = 0;
15121       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15122     }
15123
15124   mp->mask_length = length;
15125   mp->number_of_ranges = vec_len (low_ports);
15126
15127   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15128   vec_free (low_ports);
15129
15130   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15131   vec_free (high_ports);
15132
15133   mp->vrf_id = ntohl (vrf_id);
15134
15135   S;
15136   W;
15137   /* NOTREACHED */
15138   return 0;
15139 }
15140
15141 int
15142 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15143 {
15144   unformat_input_t *input = vam->input;
15145   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15146   f64 timeout;
15147   u32 sw_if_index = ~0;
15148   int vrf_set = 0;
15149   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15150   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15151   u8 is_add = 1;
15152
15153   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15154     {
15155       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15156         ;
15157       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15158         ;
15159       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15160         vrf_set = 1;
15161       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15162         vrf_set = 1;
15163       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15164         vrf_set = 1;
15165       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15166         vrf_set = 1;
15167       else if (unformat (input, "del"))
15168         is_add = 0;
15169       else
15170         break;
15171     }
15172
15173   if (sw_if_index == ~0)
15174     {
15175       errmsg ("Interface required but not specified\n");
15176       return -99;
15177     }
15178
15179   if (vrf_set == 0)
15180     {
15181       errmsg ("VRF ID required but not specified\n");
15182       return -99;
15183     }
15184
15185   if (tcp_out_vrf_id == 0
15186       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15187     {
15188       errmsg
15189         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15190       return -99;
15191     }
15192
15193   /* Construct the API message */
15194   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15195      ip_source_and_port_range_check_interface_add_del);
15196
15197   mp->sw_if_index = ntohl (sw_if_index);
15198   mp->is_add = is_add;
15199   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15200   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15201   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15202   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15203
15204   /* send it... */
15205   S;
15206
15207   /* Wait for a reply... */
15208   W;
15209 }
15210
15211 static int
15212 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15213 {
15214   unformat_input_t *i = vam->input;
15215   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15216   f64 timeout;
15217   u32 local_sa_id = 0;
15218   u32 remote_sa_id = 0;
15219   ip4_address_t src_address;
15220   ip4_address_t dst_address;
15221   u8 is_add = 1;
15222
15223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15224     {
15225       if (unformat (i, "local_sa %d", &local_sa_id))
15226         ;
15227       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15228         ;
15229       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15230         ;
15231       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15232         ;
15233       else if (unformat (i, "del"))
15234         is_add = 0;
15235       else
15236         {
15237           clib_warning ("parse error '%U'", format_unformat_error, i);
15238           return -99;
15239         }
15240     }
15241
15242   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15243
15244   mp->local_sa_id = ntohl (local_sa_id);
15245   mp->remote_sa_id = ntohl (remote_sa_id);
15246   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15247   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15248   mp->is_add = is_add;
15249
15250   S;
15251   W;
15252   /* NOTREACHED */
15253   return 0;
15254 }
15255
15256 static void vl_api_ipsec_gre_tunnel_details_t_handler
15257   (vl_api_ipsec_gre_tunnel_details_t * mp)
15258 {
15259   vat_main_t *vam = &vat_main;
15260
15261   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15262            ntohl (mp->sw_if_index),
15263            format_ip4_address, &mp->src_address,
15264            format_ip4_address, &mp->dst_address,
15265            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15266 }
15267
15268 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15269   (vl_api_ipsec_gre_tunnel_details_t * mp)
15270 {
15271   vat_main_t *vam = &vat_main;
15272   vat_json_node_t *node = NULL;
15273   struct in_addr ip4;
15274
15275   if (VAT_JSON_ARRAY != vam->json_tree.type)
15276     {
15277       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15278       vat_json_init_array (&vam->json_tree);
15279     }
15280   node = vat_json_array_add (&vam->json_tree);
15281
15282   vat_json_init_object (node);
15283   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15284   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15285   vat_json_object_add_ip4 (node, "src_address", ip4);
15286   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15287   vat_json_object_add_ip4 (node, "dst_address", ip4);
15288   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15289   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15290 }
15291
15292 static int
15293 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15294 {
15295   unformat_input_t *i = vam->input;
15296   vl_api_ipsec_gre_tunnel_dump_t *mp;
15297   f64 timeout;
15298   u32 sw_if_index;
15299   u8 sw_if_index_set = 0;
15300
15301   /* Parse args required to build the message */
15302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15303     {
15304       if (unformat (i, "sw_if_index %d", &sw_if_index))
15305         sw_if_index_set = 1;
15306       else
15307         break;
15308     }
15309
15310   if (sw_if_index_set == 0)
15311     {
15312       sw_if_index = ~0;
15313     }
15314
15315   if (!vam->json_output)
15316     {
15317       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15318                "sw_if_index", "src_address", "dst_address",
15319                "local_sa_id", "remote_sa_id");
15320     }
15321
15322   /* Get list of gre-tunnel interfaces */
15323   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15324
15325   mp->sw_if_index = htonl (sw_if_index);
15326
15327   S;
15328
15329   /* Use a control ping for synchronization */
15330   {
15331     vl_api_control_ping_t *mp;
15332     M (CONTROL_PING, control_ping);
15333     S;
15334   }
15335   W;
15336 }
15337
15338 static int
15339 api_delete_subif (vat_main_t * vam)
15340 {
15341   unformat_input_t *i = vam->input;
15342   vl_api_delete_subif_t *mp;
15343   f64 timeout;
15344   u32 sw_if_index = ~0;
15345
15346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15347     {
15348       if (unformat (i, "sw_if_index %d", &sw_if_index))
15349         ;
15350       else
15351         break;
15352     }
15353
15354   if (sw_if_index == ~0)
15355     {
15356       errmsg ("missing sw_if_index\n");
15357       return -99;
15358     }
15359
15360   /* Construct the API message */
15361   M (DELETE_SUBIF, delete_subif);
15362   mp->sw_if_index = ntohl (sw_if_index);
15363
15364   S;
15365   W;
15366 }
15367
15368 static int
15369 q_or_quit (vat_main_t * vam)
15370 {
15371   longjmp (vam->jump_buf, 1);
15372   return 0;                     /* not so much */
15373 }
15374
15375 static int
15376 q (vat_main_t * vam)
15377 {
15378   return q_or_quit (vam);
15379 }
15380
15381 static int
15382 quit (vat_main_t * vam)
15383 {
15384   return q_or_quit (vam);
15385 }
15386
15387 static int
15388 comment (vat_main_t * vam)
15389 {
15390   return 0;
15391 }
15392
15393 static int
15394 cmd_cmp (void *a1, void *a2)
15395 {
15396   u8 **c1 = a1;
15397   u8 **c2 = a2;
15398
15399   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15400 }
15401
15402 static int
15403 help (vat_main_t * vam)
15404 {
15405   u8 **cmds = 0;
15406   u8 *name = 0;
15407   hash_pair_t *p;
15408   unformat_input_t *i = vam->input;
15409   int j;
15410
15411   if (unformat (i, "%s", &name))
15412     {
15413       uword *hs;
15414
15415       vec_add1 (name, 0);
15416
15417       hs = hash_get_mem (vam->help_by_name, name);
15418       if (hs)
15419         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15420       else
15421         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15422       vec_free (name);
15423       return 0;
15424     }
15425
15426   fformat (vam->ofp, "Help is available for the following:\n");
15427
15428     /* *INDENT-OFF* */
15429     hash_foreach_pair (p, vam->function_by_name,
15430     ({
15431       vec_add1 (cmds, (u8 *)(p->key));
15432     }));
15433     /* *INDENT-ON* */
15434
15435   vec_sort_with_function (cmds, cmd_cmp);
15436
15437   for (j = 0; j < vec_len (cmds); j++)
15438     fformat (vam->ofp, "%s\n", cmds[j]);
15439
15440   vec_free (cmds);
15441   return 0;
15442 }
15443
15444 static int
15445 set (vat_main_t * vam)
15446 {
15447   u8 *name = 0, *value = 0;
15448   unformat_input_t *i = vam->input;
15449
15450   if (unformat (i, "%s", &name))
15451     {
15452       /* The input buffer is a vector, not a string. */
15453       value = vec_dup (i->buffer);
15454       vec_delete (value, i->index, 0);
15455       /* Almost certainly has a trailing newline */
15456       if (value[vec_len (value) - 1] == '\n')
15457         value[vec_len (value) - 1] = 0;
15458       /* Make sure it's a proper string, one way or the other */
15459       vec_add1 (value, 0);
15460       (void) clib_macro_set_value (&vam->macro_main,
15461                                    (char *) name, (char *) value);
15462     }
15463   else
15464     errmsg ("usage: set <name> <value>\n");
15465
15466   vec_free (name);
15467   vec_free (value);
15468   return 0;
15469 }
15470
15471 static int
15472 unset (vat_main_t * vam)
15473 {
15474   u8 *name = 0;
15475
15476   if (unformat (vam->input, "%s", &name))
15477     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15478       errmsg ("unset: %s wasn't set\n", name);
15479   vec_free (name);
15480   return 0;
15481 }
15482
15483 typedef struct
15484 {
15485   u8 *name;
15486   u8 *value;
15487 } macro_sort_t;
15488
15489
15490 static int
15491 macro_sort_cmp (void *a1, void *a2)
15492 {
15493   macro_sort_t *s1 = a1;
15494   macro_sort_t *s2 = a2;
15495
15496   return strcmp ((char *) (s1->name), (char *) (s2->name));
15497 }
15498
15499 static int
15500 dump_macro_table (vat_main_t * vam)
15501 {
15502   macro_sort_t *sort_me = 0, *sm;
15503   int i;
15504   hash_pair_t *p;
15505
15506     /* *INDENT-OFF* */
15507     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15508     ({
15509       vec_add2 (sort_me, sm, 1);
15510       sm->name = (u8 *)(p->key);
15511       sm->value = (u8 *) (p->value[0]);
15512     }));
15513     /* *INDENT-ON* */
15514
15515   vec_sort_with_function (sort_me, macro_sort_cmp);
15516
15517   if (vec_len (sort_me))
15518     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15519   else
15520     fformat (vam->ofp, "The macro table is empty...\n");
15521
15522   for (i = 0; i < vec_len (sort_me); i++)
15523     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15524   return 0;
15525 }
15526
15527 static int
15528 dump_node_table (vat_main_t * vam)
15529 {
15530   int i, j;
15531   vlib_node_t *node, *next_node;
15532
15533   if (vec_len (vam->graph_nodes) == 0)
15534     {
15535       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15536       return 0;
15537     }
15538
15539   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15540     {
15541       node = vam->graph_nodes[i];
15542       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15543       for (j = 0; j < vec_len (node->next_nodes); j++)
15544         {
15545           if (node->next_nodes[j] != ~0)
15546             {
15547               next_node = vam->graph_nodes[node->next_nodes[j]];
15548               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15549             }
15550         }
15551     }
15552   return 0;
15553 }
15554
15555 static int
15556 search_node_table (vat_main_t * vam)
15557 {
15558   unformat_input_t *line_input = vam->input;
15559   u8 *node_to_find;
15560   int j;
15561   vlib_node_t *node, *next_node;
15562   uword *p;
15563
15564   if (vam->graph_node_index_by_name == 0)
15565     {
15566       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15567       return 0;
15568     }
15569
15570   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15571     {
15572       if (unformat (line_input, "%s", &node_to_find))
15573         {
15574           vec_add1 (node_to_find, 0);
15575           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15576           if (p == 0)
15577             {
15578               fformat (vam->ofp, "%s not found...\n", node_to_find);
15579               goto out;
15580             }
15581           node = vam->graph_nodes[p[0]];
15582           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15583           for (j = 0; j < vec_len (node->next_nodes); j++)
15584             {
15585               if (node->next_nodes[j] != ~0)
15586                 {
15587                   next_node = vam->graph_nodes[node->next_nodes[j]];
15588                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15589                 }
15590             }
15591         }
15592
15593       else
15594         {
15595           clib_warning ("parse error '%U'", format_unformat_error,
15596                         line_input);
15597           return -99;
15598         }
15599
15600     out:
15601       vec_free (node_to_find);
15602
15603     }
15604
15605   return 0;
15606 }
15607
15608
15609 static int
15610 script (vat_main_t * vam)
15611 {
15612   u8 *s = 0;
15613   char *save_current_file;
15614   unformat_input_t save_input;
15615   jmp_buf save_jump_buf;
15616   u32 save_line_number;
15617
15618   FILE *new_fp, *save_ifp;
15619
15620   if (unformat (vam->input, "%s", &s))
15621     {
15622       new_fp = fopen ((char *) s, "r");
15623       if (new_fp == 0)
15624         {
15625           errmsg ("Couldn't open script file %s\n", s);
15626           vec_free (s);
15627           return -99;
15628         }
15629     }
15630   else
15631     {
15632       errmsg ("Missing script name\n");
15633       return -99;
15634     }
15635
15636   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15637   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15638   save_ifp = vam->ifp;
15639   save_line_number = vam->input_line_number;
15640   save_current_file = (char *) vam->current_file;
15641
15642   vam->input_line_number = 0;
15643   vam->ifp = new_fp;
15644   vam->current_file = s;
15645   do_one_file (vam);
15646
15647   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15648   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15649   vam->ifp = save_ifp;
15650   vam->input_line_number = save_line_number;
15651   vam->current_file = (u8 *) save_current_file;
15652   vec_free (s);
15653
15654   return 0;
15655 }
15656
15657 static int
15658 echo (vat_main_t * vam)
15659 {
15660   fformat (vam->ofp, "%v", vam->input->buffer);
15661   return 0;
15662 }
15663
15664 /* List of API message constructors, CLI names map to api_xxx */
15665 #define foreach_vpe_api_msg                                             \
15666 _(create_loopback,"[mac <mac-addr>]")                                   \
15667 _(sw_interface_dump,"")                                                 \
15668 _(sw_interface_set_flags,                                               \
15669   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15670 _(sw_interface_add_del_address,                                         \
15671   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15672 _(sw_interface_set_table,                                               \
15673   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15674 _(sw_interface_set_vpath,                                               \
15675   "<intfc> | sw_if_index <id> enable | disable")                        \
15676 _(sw_interface_set_l2_xconnect,                                         \
15677   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15678   "enable | disable")                                                   \
15679 _(sw_interface_set_l2_bridge,                                           \
15680   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15681   "[shg <split-horizon-group>] [bvi]\n"                                 \
15682   "enable | disable")                                                   \
15683 _(bridge_domain_add_del,                                                \
15684   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15685 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15686 _(l2fib_add_del,                                                        \
15687   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15688 _(l2_flags,                                                             \
15689   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15690 _(bridge_flags,                                                         \
15691   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15692 _(tap_connect,                                                          \
15693   "tapname <name> mac <mac-addr> | random-mac")                         \
15694 _(tap_modify,                                                           \
15695   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15696 _(tap_delete,                                                           \
15697   "<vpp-if-name> | sw_if_index <id>")                                   \
15698 _(sw_interface_tap_dump, "")                                            \
15699 _(ip_add_del_route,                                                     \
15700   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15701   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15702   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15703   "[multipath] [count <n>]")                                            \
15704 _(proxy_arp_add_del,                                                    \
15705   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15706 _(proxy_arp_intfc_enable_disable,                                       \
15707   "<intfc> | sw_if_index <id> enable | disable")                        \
15708 _(mpls_add_del_encap,                                                   \
15709   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15710 _(mpls_add_del_decap,                                                   \
15711   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15712 _(mpls_gre_add_del_tunnel,                                              \
15713   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15714   "adj <ip4-address>/<mask-width> [del]")                               \
15715 _(sw_interface_set_unnumbered,                                          \
15716   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15717 _(ip_neighbor_add_del,                                                  \
15718   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15719   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15720 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15721 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15722 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15723   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15724   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15725   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15726 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15727 _(reset_fib, "vrf <n> [ipv6]")                                          \
15728 _(dhcp_proxy_config,                                                    \
15729   "svr <v46-address> src <v46-address>\n"                               \
15730    "insert-cid <n> [del]")                                              \
15731 _(dhcp_proxy_config_2,                                                  \
15732   "svr <v46-address> src <v46-address>\n"                               \
15733    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15734 _(dhcp_proxy_set_vss,                                                   \
15735   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15736 _(dhcp_client_config,                                                   \
15737   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15738 _(set_ip_flow_hash,                                                     \
15739   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15740 _(sw_interface_ip6_enable_disable,                                      \
15741   "<intfc> | sw_if_index <id> enable | disable")                        \
15742 _(sw_interface_ip6_set_link_local_address,                              \
15743   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15744 _(sw_interface_ip6nd_ra_prefix,                                         \
15745   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15746   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15747   "[nolink] [isno]")                                                    \
15748 _(sw_interface_ip6nd_ra_config,                                         \
15749   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15750   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15751   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15752 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15753 _(l2_patch_add_del,                                                     \
15754   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15755   "enable | disable")                                                   \
15756 _(mpls_ethernet_add_del_tunnel,                                         \
15757   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15758   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15759 _(mpls_ethernet_add_del_tunnel_2,                                       \
15760   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15761   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15762 _(sr_tunnel_add_del,                                                    \
15763   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15764   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15765   "[policy <policy_name>]")                                             \
15766 _(sr_policy_add_del,                                                    \
15767   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15768 _(sr_multicast_map_add_del,                                             \
15769   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15770 _(classify_add_del_table,                                               \
15771   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15772   "[del] mask <mask-value>\n"                                           \
15773   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15774 _(classify_add_del_session,                                             \
15775   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15776   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15777   "  [l3 [ip4|ip6]]")                                                   \
15778 _(classify_set_interface_ip_table,                                      \
15779   "<intfc> | sw_if_index <nn> table <nn>")                              \
15780 _(classify_set_interface_l2_tables,                                     \
15781   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15782   "  [other-table <nn>]")                                               \
15783 _(get_node_index, "node <node-name")                                    \
15784 _(add_node_next, "node <node-name> next <next-node-name>")              \
15785 _(l2tpv3_create_tunnel,                                                 \
15786   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15787   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15788   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15789 _(l2tpv3_set_tunnel_cookies,                                            \
15790   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15791   "[new_remote_cookie <nn>]\n")                                         \
15792 _(l2tpv3_interface_enable_disable,                                      \
15793   "<intfc> | sw_if_index <nn> enable | disable")                        \
15794 _(l2tpv3_set_lookup_key,                                                \
15795   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15796 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15797 _(vxlan_add_del_tunnel,                                                 \
15798   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15799   " [decap-next l2|ip4|ip6] [del]")                                     \
15800 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15801 _(gre_add_del_tunnel,                                                   \
15802   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n")          \
15803 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15804 _(l2_fib_clear_table, "")                                               \
15805 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15806 _(l2_interface_vlan_tag_rewrite,                                        \
15807   "<intfc> | sw_if_index <nn> \n"                                       \
15808   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15809   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15810 _(create_vhost_user_if,                                                 \
15811         "socket <filename> [server] [renumber <dev_instance>] "         \
15812         "[mac <mac_address>]")                                          \
15813 _(modify_vhost_user_if,                                                 \
15814         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15815         "[server] [renumber <dev_instance>]")                           \
15816 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15817 _(sw_interface_vhost_user_dump, "")                                     \
15818 _(show_version, "")                                                     \
15819 _(vxlan_gpe_add_del_tunnel,                                             \
15820   "local <addr> remote <addr> vni <nn>\n"                               \
15821     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15822   "[next-ethernet] [next-nsh]\n")                                       \
15823 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15824 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15825 _(interface_name_renumber,                                              \
15826   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15827 _(input_acl_set_interface,                                              \
15828   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15829   "  [l2-table <nn>] [del]")                                            \
15830 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15831 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
15832 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15833 _(ip_dump, "ipv4 | ipv6")                                               \
15834 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15835 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15836   "  spid_id <n> ")                                                     \
15837 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15838   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15839   "  integ_alg <alg> integ_key <hex>")                                  \
15840 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15841   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15842   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15843   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15844 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15845 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15846 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15847   "(auth_data 0x<data> | auth_data <data>)")                            \
15848 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15849   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15850 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15851   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15852   "(local|remote)")                                                     \
15853 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15854 _(delete_loopback,"sw_if_index <nn>")                                   \
15855 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15856 _(map_add_domain,                                                       \
15857   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15858   "ip6-src <ip6addr> "                                                  \
15859   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15860 _(map_del_domain, "index <n>")                                          \
15861 _(map_add_del_rule,                                                     \
15862   "index <n> psid <n> dst <ip6addr> [del]")                             \
15863 _(map_domain_dump, "")                                                  \
15864 _(map_rule_dump, "index <map-domain>")                                  \
15865 _(want_interface_events,  "enable|disable")                             \
15866 _(want_stats,"enable|disable")                                          \
15867 _(get_first_msg_id, "client <name>")                                    \
15868 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15869 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15870   "fib-id <nn> [ip4][ip6][default]")                                    \
15871 _(get_node_graph, " ")                                                  \
15872 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15873 _(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> "     \
15874   "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> "       \
15875   "app-data <app_data in hex> [pow] [ppc <encap|decap>]")               \
15876 _(trace_profile_apply, "id <nn> <ip6-address>/<width>"                  \
15877   " vrf_id <nn>  add | pop | none")                                     \
15878 _(trace_profile_del, "")                                                \
15879 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
15880                             " sw_if_index <sw_if_index> p <priority> "  \
15881                             "w <weight>] [del]")                        \
15882 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
15883                         "iface <intf> | sw_if_index <sw_if_index> "     \
15884                         "p <priority> w <weight> [del]")                \
15885 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
15886                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
15887                           "locator-set <locator_name> [del]")           \
15888 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
15889   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
15890 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
15891 _(lisp_gpe_enable_disable, "enable|disable")                            \
15892 _(lisp_enable_disable, "enable|disable")                                \
15893 _(lisp_gpe_add_del_iface, "up|down")                                    \
15894 _(lisp_add_del_remote_mapping, "add|del vni <vni> deid <dest-eid> "     \
15895                                "rloc <locator> p <prio> "               \
15896                                "w <weight> [rloc <loc> ... ] "          \
15897                                "action <action> [del-all]")             \
15898 _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
15899                           "<src-eid> rloc <locator> p <prio> w <weight>"\
15900                           "[rloc <loc> ... ] action <action>")          \
15901 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
15902 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
15903 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
15904 _(lisp_locator_set_dump, "[locator-set-index <ls-index> | "             \
15905                          "locator-set <loc-set-name>] [local | remote]")\
15906 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
15907                        "[local] | [remote]")                            \
15908 _(lisp_eid_table_vni_dump, "")                                          \
15909 _(lisp_eid_table_map_dump, "l2|l3")                                     \
15910 _(lisp_gpe_tunnel_dump, "")                                             \
15911 _(lisp_map_resolver_dump, "")                                           \
15912 _(show_lisp_status, "")                                                 \
15913 _(lisp_get_map_request_itr_rlocs, "")                                   \
15914 _(show_lisp_pitr, "")                                                   \
15915 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15916 _(af_packet_delete, "name <host interface name>")                       \
15917 _(policer_add_del, "name <policer name> <params> [del]")                \
15918 _(policer_dump, "[name <policer name>]")                                \
15919 _(policer_classify_set_interface,                                       \
15920   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15921   "  [l2-table <nn>] [del]")                                            \
15922 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15923 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
15924     "[master|slave]")                                                   \
15925 _(netmap_delete, "name <interface name>")                               \
15926 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15927 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15928 _(mpls_fib_encap_dump, "")                                              \
15929 _(mpls_fib_decap_dump, "")                                              \
15930 _(classify_table_ids, "")                                               \
15931 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15932 _(classify_table_info, "table_id <nn>")                                 \
15933 _(classify_session_dump, "table_id <nn>")                               \
15934 _(ipfix_enable, "collector_address <ip4> [collector_port <nn>] "        \
15935                 "src_address <ip4> [fib_id <nn>] [path_mtu <nn>] "      \
15936                 "[template_interval <nn>]")                             \
15937 _(ipfix_dump, "")                                                       \
15938 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15939 _(pg_create_interface, "if_id <nn>")                                    \
15940 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15941 _(pg_enable_disable, "[stream <id>] disable")                           \
15942 _(ip_source_and_port_range_check_add_del,                               \
15943   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15944 _(ip_source_and_port_range_check_interface_add_del,                     \
15945   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15946   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15947 _(ipsec_gre_add_del_tunnel,                                             \
15948   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
15949 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
15950 _(delete_subif,"sub_sw_if_index <nn> sub_if_id <nn>")
15951
15952 /* List of command functions, CLI names map directly to functions */
15953 #define foreach_cli_function                                    \
15954 _(comment, "usage: comment <ignore-rest-of-line>")              \
15955 _(dump_interface_table, "usage: dump_interface_table")          \
15956 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15957 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15958 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15959 _(dump_stats_table, "usage: dump_stats_table")                  \
15960 _(dump_macro_table, "usage: dump_macro_table ")                 \
15961 _(dump_node_table, "usage: dump_node_table")                    \
15962 _(echo, "usage: echo <message>")                                \
15963 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15964 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
15965 _(help, "usage: help")                                          \
15966 _(q, "usage: quit")                                             \
15967 _(quit, "usage: quit")                                          \
15968 _(search_node_table, "usage: search_node_table <name>...")      \
15969 _(set, "usage: set <variable-name> <value>")                    \
15970 _(script, "usage: script <file-name>")                          \
15971 _(unset, "usage: unset <variable-name>")
15972
15973 #define _(N,n)                                  \
15974     static void vl_api_##n##_t_handler_uni      \
15975     (vl_api_##n##_t * mp)                       \
15976     {                                           \
15977         vat_main_t * vam = &vat_main;           \
15978         if (vam->json_output) {                 \
15979             vl_api_##n##_t_handler_json(mp);    \
15980         } else {                                \
15981             vl_api_##n##_t_handler(mp);         \
15982         }                                       \
15983     }
15984 foreach_vpe_api_reply_msg;
15985 #undef _
15986
15987 void
15988 vat_api_hookup (vat_main_t * vam)
15989 {
15990 #define _(N,n)                                                  \
15991     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15992                            vl_api_##n##_t_handler_uni,          \
15993                            vl_noop_handler,                     \
15994                            vl_api_##n##_t_endian,               \
15995                            vl_api_##n##_t_print,                \
15996                            sizeof(vl_api_##n##_t), 1);
15997   foreach_vpe_api_reply_msg;
15998 #undef _
15999
16000   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
16001
16002   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
16003
16004   vam->function_by_name = hash_create_string (0, sizeof (uword));
16005
16006   vam->help_by_name = hash_create_string (0, sizeof (uword));
16007
16008   /* API messages we can send */
16009 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
16010   foreach_vpe_api_msg;
16011 #undef _
16012
16013   /* Help strings */
16014 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16015   foreach_vpe_api_msg;
16016 #undef _
16017
16018   /* CLI functions */
16019 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
16020   foreach_cli_function;
16021 #undef _
16022
16023   /* Help strings */
16024 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16025   foreach_cli_function;
16026 #undef _
16027 }
16028
16029 #undef vl_api_version
16030 #define vl_api_version(n,v) static u32 vpe_api_version = v;
16031 #include <vpp-api/vpe.api.h>
16032 #undef vl_api_version
16033
16034 void
16035 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
16036 {
16037   /*
16038    * Send the main API signature in slot 0. This bit of code must
16039    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
16040    */
16041   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
16042 }
16043
16044 /*
16045  * fd.io coding-style-patch-verification: ON
16046  *
16047  * Local Variables:
16048  * eval: (c-set-style "gnu")
16049  * End:
16050  */