fbe4aedbca5a1f0c8bfb054be076d07ddc904ea1
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/mpls-gre/mpls.h>
39 #if DPDK > 0
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #else
43 #include <inttypes.h>
44 #endif
45 #include <vnet/map/map.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/policer/policer.h>
51 #include <vnet/policer/police.h>
52
53 #include "vat/json_format.h"
54
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248 #if DPDK > 0
249   u32 *r = va_arg (*args, u32 *);
250
251   if (0);
252 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
253   foreach_ipsec_policy_action
254 #undef _
255     else
256     return 0;
257   return 1;
258 #else
259   return 0;
260 #endif
261 }
262
263 uword
264 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
265 {
266 #if DPDK > 0
267   u32 *r = va_arg (*args, u32 *);
268
269   if (0);
270 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
271   foreach_ipsec_crypto_alg
272 #undef _
273     else
274     return 0;
275   return 1;
276 #else
277   return 0;
278 #endif
279 }
280
281 u8 *
282 format_ipsec_crypto_alg (u8 * s, va_list * args)
283 {
284 #if DPDK > 0
285   u32 i = va_arg (*args, u32);
286   u8 *t = 0;
287
288   switch (i)
289     {
290 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
291       foreach_ipsec_crypto_alg
292 #undef _
293     default:
294       return format (s, "unknown");
295     }
296   return format (s, "%s", t);
297 #else
298   return format (s, "Unimplemented");
299 #endif
300 }
301
302 uword
303 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
304 {
305 #if DPDK > 0
306   u32 *r = va_arg (*args, u32 *);
307
308   if (0);
309 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
310   foreach_ipsec_integ_alg
311 #undef _
312     else
313     return 0;
314   return 1;
315 #else
316   return 0;
317 #endif
318 }
319
320 u8 *
321 format_ipsec_integ_alg (u8 * s, va_list * args)
322 {
323 #if DPDK > 0
324   u32 i = va_arg (*args, u32);
325   u8 *t = 0;
326
327   switch (i)
328     {
329 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
330       foreach_ipsec_integ_alg
331 #undef _
332     default:
333       return format (s, "unknown");
334     }
335   return format (s, "%s", t);
336 #else
337   return format (s, "Unsupported");
338 #endif
339 }
340
341 uword
342 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
343 {
344 #if DPDK > 0
345   u32 *r = va_arg (*args, u32 *);
346
347   if (0);
348 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
349   foreach_ikev2_auth_method
350 #undef _
351     else
352     return 0;
353   return 1;
354 #else
355   return 0;
356 #endif
357 }
358
359 uword
360 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
361 {
362 #if DPDK > 0
363   u32 *r = va_arg (*args, u32 *);
364
365   if (0);
366 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
367   foreach_ikev2_id_type
368 #undef _
369     else
370     return 0;
371   return 1;
372 #else
373   return 0;
374 #endif
375 }
376
377 uword
378 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
379 {
380   u8 *r = va_arg (*args, u8 *);
381
382   if (unformat (input, "kbps"))
383     *r = SSE2_QOS_RATE_KBPS;
384   else if (unformat (input, "pps"))
385     *r = SSE2_QOS_RATE_PPS;
386   else
387     return 0;
388   return 1;
389 }
390
391 uword
392 unformat_policer_round_type (unformat_input_t * input, va_list * args)
393 {
394   u8 *r = va_arg (*args, u8 *);
395
396   if (unformat (input, "closest"))
397     *r = SSE2_QOS_ROUND_TO_CLOSEST;
398   else if (unformat (input, "up"))
399     *r = SSE2_QOS_ROUND_TO_UP;
400   else if (unformat (input, "down"))
401     *r = SSE2_QOS_ROUND_TO_DOWN;
402   else
403     return 0;
404   return 1;
405 }
406
407 uword
408 unformat_policer_type (unformat_input_t * input, va_list * args)
409 {
410   u8 *r = va_arg (*args, u8 *);
411
412   if (unformat (input, "1r2c"))
413     *r = SSE2_QOS_POLICER_TYPE_1R2C;
414   else if (unformat (input, "1r3c"))
415     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
416   else if (unformat (input, "2r3c-2698"))
417     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
418   else if (unformat (input, "2r3c-4115"))
419     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
420   else if (unformat (input, "2r3c-mef5cf1"))
421     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
422   else
423     return 0;
424   return 1;
425 }
426
427 uword
428 unformat_dscp (unformat_input_t * input, va_list * va)
429 {
430   u8 *r = va_arg (*va, u8 *);
431
432   if (0);
433 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
434   foreach_vnet_dscp
435 #undef _
436     else
437     return 0;
438   return 1;
439 }
440
441 uword
442 unformat_policer_action_type (unformat_input_t * input, va_list * va)
443 {
444   sse2_qos_pol_action_params_st *a
445     = va_arg (*va, sse2_qos_pol_action_params_st *);
446
447   if (unformat (input, "drop"))
448     a->action_type = SSE2_QOS_ACTION_DROP;
449   else if (unformat (input, "transmit"))
450     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
451   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
452     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
453   else
454     return 0;
455   return 1;
456 }
457
458 uword
459 unformat_classify_table_type (unformat_input_t * input, va_list * va)
460 {
461   u32 *r = va_arg (*va, u32 *);
462   u32 tid;
463
464   if (unformat (input, "ip4"))
465     tid = POLICER_CLASSIFY_TABLE_IP4;
466   else if (unformat (input, "ip6"))
467     tid = POLICER_CLASSIFY_TABLE_IP6;
468   else if (unformat (input, "l2"))
469     tid = POLICER_CLASSIFY_TABLE_L2;
470   else
471     return 0;
472
473   *r = tid;
474   return 1;
475 }
476
477 u8 *
478 format_ip4_address (u8 * s, va_list * args)
479 {
480   u8 *a = va_arg (*args, u8 *);
481   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
482 }
483
484 u8 *
485 format_ip6_address (u8 * s, va_list * args)
486 {
487   ip6_address_t *a = va_arg (*args, ip6_address_t *);
488   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
489
490   i_max_n_zero = ARRAY_LEN (a->as_u16);
491   max_n_zeros = 0;
492   i_first_zero = i_max_n_zero;
493   n_zeros = 0;
494   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
495     {
496       u32 is_zero = a->as_u16[i] == 0;
497       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
498         {
499           i_first_zero = i;
500           n_zeros = 0;
501         }
502       n_zeros += is_zero;
503       if ((!is_zero && n_zeros > max_n_zeros)
504           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
505         {
506           i_max_n_zero = i_first_zero;
507           max_n_zeros = n_zeros;
508           i_first_zero = ARRAY_LEN (a->as_u16);
509           n_zeros = 0;
510         }
511     }
512
513   last_double_colon = 0;
514   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
515     {
516       if (i == i_max_n_zero && max_n_zeros > 1)
517         {
518           s = format (s, "::");
519           i += max_n_zeros - 1;
520           last_double_colon = 1;
521         }
522       else
523         {
524           s = format (s, "%s%x",
525                       (last_double_colon || i == 0) ? "" : ":",
526                       clib_net_to_host_u16 (a->as_u16[i]));
527           last_double_colon = 0;
528         }
529     }
530
531   return s;
532 }
533
534 /* Format an IP46 address. */
535 u8 *
536 format_ip46_address (u8 * s, va_list * args)
537 {
538   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
539   ip46_type_t type = va_arg (*args, ip46_type_t);
540   int is_ip4 = 1;
541
542   switch (type)
543     {
544     case IP46_TYPE_ANY:
545       is_ip4 = ip46_address_is_ip4 (ip46);
546       break;
547     case IP46_TYPE_IP4:
548       is_ip4 = 1;
549       break;
550     case IP46_TYPE_IP6:
551       is_ip4 = 0;
552       break;
553     }
554
555   return is_ip4 ?
556     format (s, "%U", format_ip4_address, &ip46->ip4) :
557     format (s, "%U", format_ip6_address, &ip46->ip6);
558 }
559
560 u8 *
561 format_ethernet_address (u8 * s, va_list * args)
562 {
563   u8 *a = va_arg (*args, u8 *);
564
565   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
566                  a[0], a[1], a[2], a[3], a[4], a[5]);
567 }
568
569 void
570 increment_v4_address (ip4_address_t * a)
571 {
572   u32 v;
573
574   v = ntohl (a->as_u32) + 1;
575   a->as_u32 = ntohl (v);
576 }
577
578 void
579 increment_v6_address (ip6_address_t * a)
580 {
581   u64 v0, v1;
582
583   v0 = clib_net_to_host_u64 (a->as_u64[0]);
584   v1 = clib_net_to_host_u64 (a->as_u64[1]);
585
586   v1 += 1;
587   if (v1 == 0)
588     v0 += 1;
589   a->as_u64[0] = clib_net_to_host_u64 (v0);
590   a->as_u64[1] = clib_net_to_host_u64 (v1);
591 }
592
593 void
594 increment_mac_address (u64 * mac)
595 {
596   u64 tmp = *mac;
597
598   tmp = clib_net_to_host_u64 (tmp);
599   tmp += 1 << 16;               /* skip unused (least significant) octets */
600   tmp = clib_host_to_net_u64 (tmp);
601   *mac = tmp;
602 }
603
604 static void vl_api_create_loopback_reply_t_handler
605   (vl_api_create_loopback_reply_t * mp)
606 {
607   vat_main_t *vam = &vat_main;
608   i32 retval = ntohl (mp->retval);
609
610   vam->retval = retval;
611   vam->regenerate_interface_table = 1;
612   vam->sw_if_index = ntohl (mp->sw_if_index);
613   vam->result_ready = 1;
614 }
615
616 static void vl_api_create_loopback_reply_t_handler_json
617   (vl_api_create_loopback_reply_t * mp)
618 {
619   vat_main_t *vam = &vat_main;
620   vat_json_node_t node;
621
622   vat_json_init_object (&node);
623   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
624   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
625
626   vat_json_print (vam->ofp, &node);
627   vat_json_free (&node);
628   vam->retval = ntohl (mp->retval);
629   vam->result_ready = 1;
630 }
631
632 static void vl_api_af_packet_create_reply_t_handler
633   (vl_api_af_packet_create_reply_t * mp)
634 {
635   vat_main_t *vam = &vat_main;
636   i32 retval = ntohl (mp->retval);
637
638   vam->retval = retval;
639   vam->regenerate_interface_table = 1;
640   vam->sw_if_index = ntohl (mp->sw_if_index);
641   vam->result_ready = 1;
642 }
643
644 static void vl_api_af_packet_create_reply_t_handler_json
645   (vl_api_af_packet_create_reply_t * mp)
646 {
647   vat_main_t *vam = &vat_main;
648   vat_json_node_t node;
649
650   vat_json_init_object (&node);
651   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
652   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
653
654   vat_json_print (vam->ofp, &node);
655   vat_json_free (&node);
656
657   vam->retval = ntohl (mp->retval);
658   vam->result_ready = 1;
659 }
660
661 static void vl_api_create_vlan_subif_reply_t_handler
662   (vl_api_create_vlan_subif_reply_t * mp)
663 {
664   vat_main_t *vam = &vat_main;
665   i32 retval = ntohl (mp->retval);
666
667   vam->retval = retval;
668   vam->regenerate_interface_table = 1;
669   vam->sw_if_index = ntohl (mp->sw_if_index);
670   vam->result_ready = 1;
671 }
672
673 static void vl_api_create_vlan_subif_reply_t_handler_json
674   (vl_api_create_vlan_subif_reply_t * mp)
675 {
676   vat_main_t *vam = &vat_main;
677   vat_json_node_t node;
678
679   vat_json_init_object (&node);
680   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
681   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
682
683   vat_json_print (vam->ofp, &node);
684   vat_json_free (&node);
685
686   vam->retval = ntohl (mp->retval);
687   vam->result_ready = 1;
688 }
689
690 static void vl_api_create_subif_reply_t_handler
691   (vl_api_create_subif_reply_t * mp)
692 {
693   vat_main_t *vam = &vat_main;
694   i32 retval = ntohl (mp->retval);
695
696   vam->retval = retval;
697   vam->regenerate_interface_table = 1;
698   vam->sw_if_index = ntohl (mp->sw_if_index);
699   vam->result_ready = 1;
700 }
701
702 static void vl_api_create_subif_reply_t_handler_json
703   (vl_api_create_subif_reply_t * mp)
704 {
705   vat_main_t *vam = &vat_main;
706   vat_json_node_t node;
707
708   vat_json_init_object (&node);
709   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
710   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
711
712   vat_json_print (vam->ofp, &node);
713   vat_json_free (&node);
714
715   vam->retval = ntohl (mp->retval);
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   i32 retval = ntohl (mp->retval);
724
725   vam->retval = retval;
726   vam->regenerate_interface_table = 1;
727   vam->result_ready = 1;
728 }
729
730 static void vl_api_interface_name_renumber_reply_t_handler_json
731   (vl_api_interface_name_renumber_reply_t * mp)
732 {
733   vat_main_t *vam = &vat_main;
734   vat_json_node_t node;
735
736   vat_json_init_object (&node);
737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
738
739   vat_json_print (vam->ofp, &node);
740   vat_json_free (&node);
741
742   vam->retval = ntohl (mp->retval);
743   vam->result_ready = 1;
744 }
745
746 /*
747  * Special-case: build the interface table, maintain
748  * the next loopback sw_if_index vbl.
749  */
750 static void vl_api_sw_interface_details_t_handler
751   (vl_api_sw_interface_details_t * mp)
752 {
753   vat_main_t *vam = &vat_main;
754   u8 *s = format (0, "%s%c", mp->interface_name, 0);
755
756   hash_set_mem (vam->sw_if_index_by_interface_name, s,
757                 ntohl (mp->sw_if_index));
758
759   /* In sub interface case, fill the sub interface table entry */
760   if (mp->sw_if_index != mp->sup_sw_if_index)
761     {
762       sw_interface_subif_t *sub = NULL;
763
764       vec_add2 (vam->sw_if_subif_table, sub, 1);
765
766       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
767       strncpy ((char *) sub->interface_name, (char *) s,
768                vec_len (sub->interface_name));
769       sub->sw_if_index = ntohl (mp->sw_if_index);
770       sub->sub_id = ntohl (mp->sub_id);
771
772       sub->sub_dot1ad = mp->sub_dot1ad;
773       sub->sub_number_of_tags = mp->sub_number_of_tags;
774       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
775       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
776       sub->sub_exact_match = mp->sub_exact_match;
777       sub->sub_default = mp->sub_default;
778       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
779       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
780
781       /* vlan tag rewrite */
782       sub->vtr_op = ntohl (mp->vtr_op);
783       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
784       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
785       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
786     }
787 }
788
789 static void vl_api_sw_interface_details_t_handler_json
790   (vl_api_sw_interface_details_t * mp)
791 {
792   vat_main_t *vam = &vat_main;
793   vat_json_node_t *node = NULL;
794
795   if (VAT_JSON_ARRAY != vam->json_tree.type)
796     {
797       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
798       vat_json_init_array (&vam->json_tree);
799     }
800   node = vat_json_array_add (&vam->json_tree);
801
802   vat_json_init_object (node);
803   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
804   vat_json_object_add_uint (node, "sup_sw_if_index",
805                             ntohl (mp->sup_sw_if_index));
806   vat_json_object_add_uint (node, "l2_address_length",
807                             ntohl (mp->l2_address_length));
808   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
809                              sizeof (mp->l2_address));
810   vat_json_object_add_string_copy (node, "interface_name",
811                                    mp->interface_name);
812   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
813   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
814   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
815   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
816   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
817   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
818   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
819   vat_json_object_add_uint (node, "sub_number_of_tags",
820                             mp->sub_number_of_tags);
821   vat_json_object_add_uint (node, "sub_outer_vlan_id",
822                             ntohs (mp->sub_outer_vlan_id));
823   vat_json_object_add_uint (node, "sub_inner_vlan_id",
824                             ntohs (mp->sub_inner_vlan_id));
825   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
826   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
827   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
828                             mp->sub_outer_vlan_id_any);
829   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
830                             mp->sub_inner_vlan_id_any);
831   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
832   vat_json_object_add_uint (node, "vtr_push_dot1q",
833                             ntohl (mp->vtr_push_dot1q));
834   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
835   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   vat_main_t *vam = &vat_main;
842   if (vam->interface_event_display)
843     errmsg ("interface flags: sw_if_index %d %s %s\n",
844             ntohl (mp->sw_if_index),
845             mp->admin_up_down ? "admin-up" : "admin-down",
846             mp->link_up_down ? "link-up" : "link-down");
847 }
848
849 static void vl_api_sw_interface_set_flags_t_handler_json
850   (vl_api_sw_interface_set_flags_t * mp)
851 {
852   /* JSON output not supported */
853 }
854
855 static void
856 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   i32 retval = ntohl (mp->retval);
860
861   vam->retval = retval;
862   vam->shmem_result = (u8 *) mp->reply_in_shmem;
863   vam->result_ready = 1;
864 }
865
866 static void
867 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
868 {
869   vat_main_t *vam = &vat_main;
870   vat_json_node_t node;
871   api_main_t *am = &api_main;
872   void *oldheap;
873   u8 *reply;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "reply_in_shmem",
878                             ntohl (mp->reply_in_shmem));
879   /* Toss the shared-memory original... */
880   pthread_mutex_lock (&am->vlib_rp->mutex);
881   oldheap = svm_push_data_heap (am->vlib_rp);
882
883   reply = (u8 *) (mp->reply_in_shmem);
884   vec_free (reply);
885
886   svm_pop_heap (oldheap);
887   pthread_mutex_unlock (&am->vlib_rp->mutex);
888
889   vat_json_print (vam->ofp, &node);
890   vat_json_free (&node);
891
892   vam->retval = ntohl (mp->retval);
893   vam->result_ready = 1;
894 }
895
896 static void vl_api_classify_add_del_table_reply_t_handler
897   (vl_api_classify_add_del_table_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   i32 retval = ntohl (mp->retval);
901   if (vam->async_mode)
902     {
903       vam->async_errors += (retval < 0);
904     }
905   else
906     {
907       vam->retval = retval;
908       if (retval == 0 &&
909           ((mp->new_table_index != 0xFFFFFFFF) ||
910            (mp->skip_n_vectors != 0xFFFFFFFF) ||
911            (mp->match_n_vectors != 0xFFFFFFFF)))
912         /*
913          * Note: this is just barely thread-safe, depends on
914          * the main thread spinning waiting for an answer...
915          */
916         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
917                 ntohl (mp->new_table_index),
918                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
919       vam->result_ready = 1;
920     }
921 }
922
923 static void vl_api_classify_add_del_table_reply_t_handler_json
924   (vl_api_classify_add_del_table_reply_t * mp)
925 {
926   vat_main_t *vam = &vat_main;
927   vat_json_node_t node;
928
929   vat_json_init_object (&node);
930   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
931   vat_json_object_add_uint (&node, "new_table_index",
932                             ntohl (mp->new_table_index));
933   vat_json_object_add_uint (&node, "skip_n_vectors",
934                             ntohl (mp->skip_n_vectors));
935   vat_json_object_add_uint (&node, "match_n_vectors",
936                             ntohl (mp->match_n_vectors));
937
938   vat_json_print (vam->ofp, &node);
939   vat_json_free (&node);
940
941   vam->retval = ntohl (mp->retval);
942   vam->result_ready = 1;
943 }
944
945 static void vl_api_get_node_index_reply_t_handler
946   (vl_api_get_node_index_reply_t * mp)
947 {
948   vat_main_t *vam = &vat_main;
949   i32 retval = ntohl (mp->retval);
950   if (vam->async_mode)
951     {
952       vam->async_errors += (retval < 0);
953     }
954   else
955     {
956       vam->retval = retval;
957       if (retval == 0)
958         errmsg ("node index %d\n", ntohl (mp->node_index));
959       vam->result_ready = 1;
960     }
961 }
962
963 static void vl_api_get_node_index_reply_t_handler_json
964   (vl_api_get_node_index_reply_t * mp)
965 {
966   vat_main_t *vam = &vat_main;
967   vat_json_node_t node;
968
969   vat_json_init_object (&node);
970   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
971   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
972
973   vat_json_print (vam->ofp, &node);
974   vat_json_free (&node);
975
976   vam->retval = ntohl (mp->retval);
977   vam->result_ready = 1;
978 }
979
980 static void vl_api_get_next_index_reply_t_handler
981   (vl_api_get_next_index_reply_t * mp)
982 {
983   vat_main_t *vam = &vat_main;
984   i32 retval = ntohl (mp->retval);
985   if (vam->async_mode)
986     {
987       vam->async_errors += (retval < 0);
988     }
989   else
990     {
991       vam->retval = retval;
992       if (retval == 0)
993         errmsg ("next node index %d\n", ntohl (mp->next_index));
994       vam->result_ready = 1;
995     }
996 }
997
998 static void vl_api_get_next_index_reply_t_handler_json
999   (vl_api_get_next_index_reply_t * mp)
1000 {
1001   vat_main_t *vam = &vat_main;
1002   vat_json_node_t node;
1003
1004   vat_json_init_object (&node);
1005   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1006   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1007
1008   vat_json_print (vam->ofp, &node);
1009   vat_json_free (&node);
1010
1011   vam->retval = ntohl (mp->retval);
1012   vam->result_ready = 1;
1013 }
1014
1015 static void vl_api_add_node_next_reply_t_handler
1016   (vl_api_add_node_next_reply_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   i32 retval = ntohl (mp->retval);
1020   if (vam->async_mode)
1021     {
1022       vam->async_errors += (retval < 0);
1023     }
1024   else
1025     {
1026       vam->retval = retval;
1027       if (retval == 0)
1028         errmsg ("next index %d\n", ntohl (mp->next_index));
1029       vam->result_ready = 1;
1030     }
1031 }
1032
1033 static void vl_api_add_node_next_reply_t_handler_json
1034   (vl_api_add_node_next_reply_t * mp)
1035 {
1036   vat_main_t *vam = &vat_main;
1037   vat_json_node_t node;
1038
1039   vat_json_init_object (&node);
1040   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1041   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1042
1043   vat_json_print (vam->ofp, &node);
1044   vat_json_free (&node);
1045
1046   vam->retval = ntohl (mp->retval);
1047   vam->result_ready = 1;
1048 }
1049
1050 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler
1051   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   i32 retval = ntohl (mp->retval);
1055   u32 sw_if_index = ntohl (mp->tunnel_sw_if_index);
1056
1057   if (retval >= 0 && sw_if_index != (u32) ~ 0)
1058     {
1059       errmsg ("tunnel_sw_if_index %d\n", sw_if_index);
1060     }
1061   vam->retval = retval;
1062   vam->result_ready = 1;
1063 }
1064
1065 static void vl_api_mpls_gre_add_del_tunnel_reply_t_handler_json
1066   (vl_api_mpls_gre_add_del_tunnel_reply_t * mp)
1067 {
1068   vat_main_t *vam = &vat_main;
1069   vat_json_node_t node;
1070
1071   vat_json_init_object (&node);
1072   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1073   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1074                             ntohl (mp->tunnel_sw_if_index));
1075
1076   vat_json_print (vam->ofp, &node);
1077   vat_json_free (&node);
1078
1079   vam->retval = ntohl (mp->retval);
1080   vam->result_ready = 1;
1081 }
1082
1083
1084 static void vl_api_show_version_reply_t_handler
1085   (vl_api_show_version_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   i32 retval = ntohl (mp->retval);
1089
1090   if (retval >= 0)
1091     {
1092       errmsg ("        program: %s\n", mp->program);
1093       errmsg ("        version: %s\n", mp->version);
1094       errmsg ("     build date: %s\n", mp->build_date);
1095       errmsg ("build directory: %s\n", mp->build_directory);
1096     }
1097   vam->retval = retval;
1098   vam->result_ready = 1;
1099 }
1100
1101 static void vl_api_show_version_reply_t_handler_json
1102   (vl_api_show_version_reply_t * mp)
1103 {
1104   vat_main_t *vam = &vat_main;
1105   vat_json_node_t node;
1106
1107   vat_json_init_object (&node);
1108   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1109   vat_json_object_add_string_copy (&node, "program", mp->program);
1110   vat_json_object_add_string_copy (&node, "version", mp->version);
1111   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1112   vat_json_object_add_string_copy (&node, "build_directory",
1113                                    mp->build_directory);
1114
1115   vat_json_print (vam->ofp, &node);
1116   vat_json_free (&node);
1117
1118   vam->retval = ntohl (mp->retval);
1119   vam->result_ready = 1;
1120 }
1121
1122 static void
1123 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1124 {
1125   vat_main_t *vam = &vat_main;
1126   errmsg ("arp event: address %U new mac %U sw_if_index %d\n",
1127           format_ip4_address, &mp->address,
1128           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1129 }
1130
1131 static void
1132 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1133 {
1134   /* JSON output not supported */
1135 }
1136
1137 /*
1138  * Special-case: build the bridge domain table, maintain
1139  * the next bd id vbl.
1140  */
1141 static void vl_api_bridge_domain_details_t_handler
1142   (vl_api_bridge_domain_details_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1146
1147   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1148            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1149
1150   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1151            ntohl (mp->bd_id), mp->learn, mp->forward,
1152            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1153
1154   if (n_sw_ifs)
1155     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1156              "Interface Name");
1157 }
1158
1159 static void vl_api_bridge_domain_details_t_handler_json
1160   (vl_api_bridge_domain_details_t * mp)
1161 {
1162   vat_main_t *vam = &vat_main;
1163   vat_json_node_t *node, *array = NULL;
1164
1165   if (VAT_JSON_ARRAY != vam->json_tree.type)
1166     {
1167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1168       vat_json_init_array (&vam->json_tree);
1169     }
1170   node = vat_json_array_add (&vam->json_tree);
1171
1172   vat_json_init_object (node);
1173   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1174   vat_json_object_add_uint (node, "flood", mp->flood);
1175   vat_json_object_add_uint (node, "forward", mp->forward);
1176   vat_json_object_add_uint (node, "learn", mp->learn);
1177   vat_json_object_add_uint (node, "bvi_sw_if_index",
1178                             ntohl (mp->bvi_sw_if_index));
1179   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1180   array = vat_json_object_add (node, "sw_if");
1181   vat_json_init_array (array);
1182 }
1183
1184 /*
1185  * Special-case: build the bridge domain sw if table.
1186  */
1187 static void vl_api_bridge_domain_sw_if_details_t_handler
1188   (vl_api_bridge_domain_sw_if_details_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   hash_pair_t *p;
1192   u8 *sw_if_name = 0;
1193   u32 sw_if_index;
1194
1195   sw_if_index = ntohl (mp->sw_if_index);
1196   /* *INDENT-OFF* */
1197   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1198   ({
1199     if ((u32) p->value[0] == sw_if_index)
1200       {
1201         sw_if_name = (u8 *)(p->key);
1202         break;
1203       }
1204   }));
1205   /* *INDENT-ON* */
1206
1207   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1208            mp->shg, sw_if_name ? (char *) sw_if_name :
1209            "sw_if_index not found!");
1210 }
1211
1212 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1213   (vl_api_bridge_domain_sw_if_details_t * mp)
1214 {
1215   vat_main_t *vam = &vat_main;
1216   vat_json_node_t *node = NULL;
1217   uword last_index = 0;
1218
1219   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1220   ASSERT (vec_len (vam->json_tree.array) >= 1);
1221   last_index = vec_len (vam->json_tree.array) - 1;
1222   node = &vam->json_tree.array[last_index];
1223   node = vat_json_object_get_element (node, "sw_if");
1224   ASSERT (NULL != node);
1225   node = vat_json_array_add (node);
1226
1227   vat_json_init_object (node);
1228   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1230   vat_json_object_add_uint (node, "shg", mp->shg);
1231 }
1232
1233 static void vl_api_control_ping_reply_t_handler
1234   (vl_api_control_ping_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   i32 retval = ntohl (mp->retval);
1238   if (vam->async_mode)
1239     {
1240       vam->async_errors += (retval < 0);
1241     }
1242   else
1243     {
1244       vam->retval = retval;
1245       vam->result_ready = 1;
1246     }
1247 }
1248
1249 static void vl_api_control_ping_reply_t_handler_json
1250   (vl_api_control_ping_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254
1255   if (VAT_JSON_NONE != vam->json_tree.type)
1256     {
1257       vat_json_print (vam->ofp, &vam->json_tree);
1258       vat_json_free (&vam->json_tree);
1259       vam->json_tree.type = VAT_JSON_NONE;
1260     }
1261   else
1262     {
1263       /* just print [] */
1264       vat_json_init_array (&vam->json_tree);
1265       vat_json_print (vam->ofp, &vam->json_tree);
1266       vam->json_tree.type = VAT_JSON_NONE;
1267     }
1268
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void vl_api_noprint_control_ping_reply_t_handler
1274   (vl_api_noprint_control_ping_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278   if (vam->async_mode)
1279     {
1280       vam->async_errors += (retval < 0);
1281     }
1282   else
1283     {
1284       vam->retval = retval;
1285       vam->result_ready = 1;
1286     }
1287 }
1288
1289 static void vl_api_noprint_control_ping_reply_t_handler_json
1290   (vl_api_noprint_control_ping_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   i32 retval = ntohl (mp->retval);
1294
1295   if (vam->noprint_msg)
1296     {
1297       vam->retval = retval;
1298       vam->result_ready = 1;
1299       return;
1300     }
1301
1302   if (VAT_JSON_NONE != vam->json_tree.type)
1303     {
1304       vat_json_print (vam->ofp, &vam->json_tree);
1305       vat_json_free (&vam->json_tree);
1306       vam->json_tree.type = VAT_JSON_NONE;
1307     }
1308   else
1309     {
1310       /* just print [] */
1311       vat_json_init_array (&vam->json_tree);
1312       vat_json_print (vam->ofp, &vam->json_tree);
1313       vam->json_tree.type = VAT_JSON_NONE;
1314     }
1315
1316   vam->retval = retval;
1317   vam->result_ready = 1;
1318 }
1319
1320 static void
1321 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1322 {
1323   vat_main_t *vam = &vat_main;
1324   i32 retval = ntohl (mp->retval);
1325   if (vam->async_mode)
1326     {
1327       vam->async_errors += (retval < 0);
1328     }
1329   else
1330     {
1331       vam->retval = retval;
1332       vam->result_ready = 1;
1333     }
1334 }
1335
1336 static void vl_api_l2_flags_reply_t_handler_json
1337   (vl_api_l2_flags_reply_t * mp)
1338 {
1339   vat_main_t *vam = &vat_main;
1340   vat_json_node_t node;
1341
1342   vat_json_init_object (&node);
1343   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1344   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1345                             ntohl (mp->resulting_feature_bitmap));
1346
1347   vat_json_print (vam->ofp, &node);
1348   vat_json_free (&node);
1349
1350   vam->retval = ntohl (mp->retval);
1351   vam->result_ready = 1;
1352 }
1353
1354 static void vl_api_bridge_flags_reply_t_handler
1355   (vl_api_bridge_flags_reply_t * mp)
1356 {
1357   vat_main_t *vam = &vat_main;
1358   i32 retval = ntohl (mp->retval);
1359   if (vam->async_mode)
1360     {
1361       vam->async_errors += (retval < 0);
1362     }
1363   else
1364     {
1365       vam->retval = retval;
1366       vam->result_ready = 1;
1367     }
1368 }
1369
1370 static void vl_api_bridge_flags_reply_t_handler_json
1371   (vl_api_bridge_flags_reply_t * mp)
1372 {
1373   vat_main_t *vam = &vat_main;
1374   vat_json_node_t node;
1375
1376   vat_json_init_object (&node);
1377   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1378   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1379                             ntohl (mp->resulting_feature_bitmap));
1380
1381   vat_json_print (vam->ofp, &node);
1382   vat_json_free (&node);
1383
1384   vam->retval = ntohl (mp->retval);
1385   vam->result_ready = 1;
1386 }
1387
1388 static void vl_api_tap_connect_reply_t_handler
1389   (vl_api_tap_connect_reply_t * mp)
1390 {
1391   vat_main_t *vam = &vat_main;
1392   i32 retval = ntohl (mp->retval);
1393   if (vam->async_mode)
1394     {
1395       vam->async_errors += (retval < 0);
1396     }
1397   else
1398     {
1399       vam->retval = retval;
1400       vam->sw_if_index = ntohl (mp->sw_if_index);
1401       vam->result_ready = 1;
1402     }
1403
1404 }
1405
1406 static void vl_api_tap_connect_reply_t_handler_json
1407   (vl_api_tap_connect_reply_t * mp)
1408 {
1409   vat_main_t *vam = &vat_main;
1410   vat_json_node_t node;
1411
1412   vat_json_init_object (&node);
1413   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1414   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1415
1416   vat_json_print (vam->ofp, &node);
1417   vat_json_free (&node);
1418
1419   vam->retval = ntohl (mp->retval);
1420   vam->result_ready = 1;
1421
1422 }
1423
1424 static void
1425 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1426 {
1427   vat_main_t *vam = &vat_main;
1428   i32 retval = ntohl (mp->retval);
1429   if (vam->async_mode)
1430     {
1431       vam->async_errors += (retval < 0);
1432     }
1433   else
1434     {
1435       vam->retval = retval;
1436       vam->sw_if_index = ntohl (mp->sw_if_index);
1437       vam->result_ready = 1;
1438     }
1439 }
1440
1441 static void vl_api_tap_modify_reply_t_handler_json
1442   (vl_api_tap_modify_reply_t * mp)
1443 {
1444   vat_main_t *vam = &vat_main;
1445   vat_json_node_t node;
1446
1447   vat_json_init_object (&node);
1448   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1449   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1450
1451   vat_json_print (vam->ofp, &node);
1452   vat_json_free (&node);
1453
1454   vam->retval = ntohl (mp->retval);
1455   vam->result_ready = 1;
1456 }
1457
1458 static void
1459 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1460 {
1461   vat_main_t *vam = &vat_main;
1462   i32 retval = ntohl (mp->retval);
1463   if (vam->async_mode)
1464     {
1465       vam->async_errors += (retval < 0);
1466     }
1467   else
1468     {
1469       vam->retval = retval;
1470       vam->result_ready = 1;
1471     }
1472 }
1473
1474 static void vl_api_tap_delete_reply_t_handler_json
1475   (vl_api_tap_delete_reply_t * mp)
1476 {
1477   vat_main_t *vam = &vat_main;
1478   vat_json_node_t node;
1479
1480   vat_json_init_object (&node);
1481   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1482
1483   vat_json_print (vam->ofp, &node);
1484   vat_json_free (&node);
1485
1486   vam->retval = ntohl (mp->retval);
1487   vam->result_ready = 1;
1488 }
1489
1490 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1491   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1492 {
1493   vat_main_t *vam = &vat_main;
1494   i32 retval = ntohl (mp->retval);
1495   if (vam->async_mode)
1496     {
1497       vam->async_errors += (retval < 0);
1498     }
1499   else
1500     {
1501       vam->retval = retval;
1502       vam->result_ready = 1;
1503     }
1504 }
1505
1506 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1507   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1508 {
1509   vat_main_t *vam = &vat_main;
1510   vat_json_node_t node;
1511
1512   vat_json_init_object (&node);
1513   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1514   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1515                             ntohl (mp->tunnel_sw_if_index));
1516
1517   vat_json_print (vam->ofp, &node);
1518   vat_json_free (&node);
1519
1520   vam->retval = ntohl (mp->retval);
1521   vam->result_ready = 1;
1522 }
1523
1524 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1525   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1526 {
1527   vat_main_t *vam = &vat_main;
1528   i32 retval = ntohl (mp->retval);
1529   if (vam->async_mode)
1530     {
1531       vam->async_errors += (retval < 0);
1532     }
1533   else
1534     {
1535       vam->retval = retval;
1536       vam->sw_if_index = ntohl (mp->sw_if_index);
1537       vam->result_ready = 1;
1538     }
1539 }
1540
1541 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1542   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1543 {
1544   vat_main_t *vam = &vat_main;
1545   vat_json_node_t node;
1546
1547   vat_json_init_object (&node);
1548   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1549   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1550
1551   vat_json_print (vam->ofp, &node);
1552   vat_json_free (&node);
1553
1554   vam->retval = ntohl (mp->retval);
1555   vam->result_ready = 1;
1556 }
1557
1558
1559 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1560   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1561 {
1562   vat_main_t *vam = &vat_main;
1563   i32 retval = ntohl (mp->retval);
1564   if (vam->async_mode)
1565     {
1566       vam->async_errors += (retval < 0);
1567     }
1568   else
1569     {
1570       vam->retval = retval;
1571       vam->result_ready = 1;
1572     }
1573 }
1574
1575 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1576   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1577 {
1578   vat_main_t *vam = &vat_main;
1579   vat_json_node_t node;
1580
1581   vat_json_init_object (&node);
1582   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1583   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1584
1585   vat_json_print (vam->ofp, &node);
1586   vat_json_free (&node);
1587
1588   vam->retval = ntohl (mp->retval);
1589   vam->result_ready = 1;
1590 }
1591
1592 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1593   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1594 {
1595   vat_main_t *vam = &vat_main;
1596   i32 retval = ntohl (mp->retval);
1597   if (vam->async_mode)
1598     {
1599       vam->async_errors += (retval < 0);
1600     }
1601   else
1602     {
1603       vam->retval = retval;
1604       vam->sw_if_index = ntohl (mp->sw_if_index);
1605       vam->result_ready = 1;
1606     }
1607 }
1608
1609 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1610   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1611 {
1612   vat_main_t *vam = &vat_main;
1613   vat_json_node_t node;
1614
1615   vat_json_init_object (&node);
1616   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1617   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1618
1619   vat_json_print (vam->ofp, &node);
1620   vat_json_free (&node);
1621
1622   vam->retval = ntohl (mp->retval);
1623   vam->result_ready = 1;
1624 }
1625
1626 static void vl_api_gre_add_del_tunnel_reply_t_handler
1627   (vl_api_gre_add_del_tunnel_reply_t * mp)
1628 {
1629   vat_main_t *vam = &vat_main;
1630   i32 retval = ntohl (mp->retval);
1631   if (vam->async_mode)
1632     {
1633       vam->async_errors += (retval < 0);
1634     }
1635   else
1636     {
1637       vam->retval = retval;
1638       vam->sw_if_index = ntohl (mp->sw_if_index);
1639       vam->result_ready = 1;
1640     }
1641 }
1642
1643 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1644   (vl_api_gre_add_del_tunnel_reply_t * mp)
1645 {
1646   vat_main_t *vam = &vat_main;
1647   vat_json_node_t node;
1648
1649   vat_json_init_object (&node);
1650   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1651   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1652
1653   vat_json_print (vam->ofp, &node);
1654   vat_json_free (&node);
1655
1656   vam->retval = ntohl (mp->retval);
1657   vam->result_ready = 1;
1658 }
1659
1660 static void vl_api_create_vhost_user_if_reply_t_handler
1661   (vl_api_create_vhost_user_if_reply_t * mp)
1662 {
1663   vat_main_t *vam = &vat_main;
1664   i32 retval = ntohl (mp->retval);
1665   if (vam->async_mode)
1666     {
1667       vam->async_errors += (retval < 0);
1668     }
1669   else
1670     {
1671       vam->retval = retval;
1672       vam->sw_if_index = ntohl (mp->sw_if_index);
1673       vam->result_ready = 1;
1674     }
1675 }
1676
1677 static void vl_api_create_vhost_user_if_reply_t_handler_json
1678   (vl_api_create_vhost_user_if_reply_t * mp)
1679 {
1680   vat_main_t *vam = &vat_main;
1681   vat_json_node_t node;
1682
1683   vat_json_init_object (&node);
1684   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1685   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1686
1687   vat_json_print (vam->ofp, &node);
1688   vat_json_free (&node);
1689
1690   vam->retval = ntohl (mp->retval);
1691   vam->result_ready = 1;
1692 }
1693
1694 static void vl_api_ip_address_details_t_handler
1695   (vl_api_ip_address_details_t * mp)
1696 {
1697   vat_main_t *vam = &vat_main;
1698   static ip_address_details_t empty_ip_address_details = { {0} };
1699   ip_address_details_t *address = NULL;
1700   ip_details_t *current_ip_details = NULL;
1701   ip_details_t *details = NULL;
1702
1703   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1704
1705   if (!details || vam->current_sw_if_index >= vec_len (details)
1706       || !details[vam->current_sw_if_index].present)
1707     {
1708       errmsg ("ip address details arrived but not stored\n");
1709       errmsg ("ip_dump should be called first\n");
1710       return;
1711     }
1712
1713   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1714
1715 #define addresses (current_ip_details->addr)
1716
1717   vec_validate_init_empty (addresses, vec_len (addresses),
1718                            empty_ip_address_details);
1719
1720   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1721
1722   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1723   address->prefix_length = mp->prefix_length;
1724 #undef addresses
1725 }
1726
1727 static void vl_api_ip_address_details_t_handler_json
1728   (vl_api_ip_address_details_t * mp)
1729 {
1730   vat_main_t *vam = &vat_main;
1731   vat_json_node_t *node = NULL;
1732   struct in6_addr ip6;
1733   struct in_addr ip4;
1734
1735   if (VAT_JSON_ARRAY != vam->json_tree.type)
1736     {
1737       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1738       vat_json_init_array (&vam->json_tree);
1739     }
1740   node = vat_json_array_add (&vam->json_tree);
1741
1742   vat_json_init_object (node);
1743   if (vam->is_ipv6)
1744     {
1745       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1746       vat_json_object_add_ip6 (node, "ip", ip6);
1747     }
1748   else
1749     {
1750       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1751       vat_json_object_add_ip4 (node, "ip", ip4);
1752     }
1753   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1754 }
1755
1756 static void
1757 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1758 {
1759   vat_main_t *vam = &vat_main;
1760   static ip_details_t empty_ip_details = { 0 };
1761   ip_details_t *ip = NULL;
1762   u32 sw_if_index = ~0;
1763
1764   sw_if_index = ntohl (mp->sw_if_index);
1765
1766   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1767                            sw_if_index, empty_ip_details);
1768
1769   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1770                          sw_if_index);
1771
1772   ip->present = 1;
1773 }
1774
1775 static void
1776 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1777 {
1778   vat_main_t *vam = &vat_main;
1779
1780   if (VAT_JSON_ARRAY != vam->json_tree.type)
1781     {
1782       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1783       vat_json_init_array (&vam->json_tree);
1784     }
1785   vat_json_array_add_uint (&vam->json_tree,
1786                            clib_net_to_host_u32 (mp->sw_if_index));
1787 }
1788
1789 static void vl_api_map_domain_details_t_handler_json
1790   (vl_api_map_domain_details_t * mp)
1791 {
1792   vat_json_node_t *node = NULL;
1793   vat_main_t *vam = &vat_main;
1794   struct in6_addr ip6;
1795   struct in_addr ip4;
1796
1797   if (VAT_JSON_ARRAY != vam->json_tree.type)
1798     {
1799       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1800       vat_json_init_array (&vam->json_tree);
1801     }
1802
1803   node = vat_json_array_add (&vam->json_tree);
1804   vat_json_init_object (node);
1805
1806   vat_json_object_add_uint (node, "domain_index",
1807                             clib_net_to_host_u32 (mp->domain_index));
1808   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1809   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1810   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1811   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1812   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1813   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1814   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1815   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1816   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1817   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1818   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1819   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1820   vat_json_object_add_uint (node, "flags", mp->flags);
1821   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1822   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1823 }
1824
1825 static void vl_api_map_domain_details_t_handler
1826   (vl_api_map_domain_details_t * mp)
1827 {
1828   vat_main_t *vam = &vat_main;
1829
1830   if (mp->is_translation)
1831     {
1832       fformat (vam->ofp,
1833                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1834                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1835                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1836                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1837                clib_net_to_host_u32 (mp->domain_index));
1838     }
1839   else
1840     {
1841       fformat (vam->ofp,
1842                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1843                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1844                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1845                format_ip6_address, mp->ip6_src,
1846                clib_net_to_host_u32 (mp->domain_index));
1847     }
1848   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1849            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1850            mp->is_translation ? "map-t" : "");
1851 }
1852
1853 static void vl_api_map_rule_details_t_handler_json
1854   (vl_api_map_rule_details_t * mp)
1855 {
1856   struct in6_addr ip6;
1857   vat_json_node_t *node = NULL;
1858   vat_main_t *vam = &vat_main;
1859
1860   if (VAT_JSON_ARRAY != vam->json_tree.type)
1861     {
1862       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1863       vat_json_init_array (&vam->json_tree);
1864     }
1865
1866   node = vat_json_array_add (&vam->json_tree);
1867   vat_json_init_object (node);
1868
1869   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1870   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1871   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1872 }
1873
1874 static void
1875 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1876 {
1877   vat_main_t *vam = &vat_main;
1878   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1879            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1880 }
1881
1882 static void
1883 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1884 {
1885   vat_main_t *vam = &vat_main;
1886   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1887           "router_addr %U host_mac %U\n",
1888           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1889           format_ip4_address, &mp->host_address,
1890           format_ip4_address, &mp->router_address,
1891           format_ethernet_address, mp->host_mac);
1892 }
1893
1894 static void vl_api_dhcp_compl_event_t_handler_json
1895   (vl_api_dhcp_compl_event_t * mp)
1896 {
1897   /* JSON output not supported */
1898 }
1899
1900 static void
1901 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1902                               u32 counter)
1903 {
1904   vat_main_t *vam = &vat_main;
1905   static u64 default_counter = 0;
1906
1907   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1908                            NULL);
1909   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1910                            sw_if_index, default_counter);
1911   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1912 }
1913
1914 static void
1915 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1916                                 interface_counter_t counter)
1917 {
1918   vat_main_t *vam = &vat_main;
1919   static interface_counter_t default_counter = { 0, };
1920
1921   vec_validate_init_empty (vam->combined_interface_counters,
1922                            vnet_counter_type, NULL);
1923   vec_validate_init_empty (vam->combined_interface_counters
1924                            [vnet_counter_type], sw_if_index, default_counter);
1925   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1926 }
1927
1928 static void vl_api_vnet_interface_counters_t_handler
1929   (vl_api_vnet_interface_counters_t * mp)
1930 {
1931   /* not supported */
1932 }
1933
1934 static void vl_api_vnet_interface_counters_t_handler_json
1935   (vl_api_vnet_interface_counters_t * mp)
1936 {
1937   interface_counter_t counter;
1938   vlib_counter_t *v;
1939   u64 *v_packets;
1940   u64 packets;
1941   u32 count;
1942   u32 first_sw_if_index;
1943   int i;
1944
1945   count = ntohl (mp->count);
1946   first_sw_if_index = ntohl (mp->first_sw_if_index);
1947
1948   if (!mp->is_combined)
1949     {
1950       v_packets = (u64 *) & mp->data;
1951       for (i = 0; i < count; i++)
1952         {
1953           packets =
1954             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1955           set_simple_interface_counter (mp->vnet_counter_type,
1956                                         first_sw_if_index + i, packets);
1957           v_packets++;
1958         }
1959     }
1960   else
1961     {
1962       v = (vlib_counter_t *) & mp->data;
1963       for (i = 0; i < count; i++)
1964         {
1965           counter.packets =
1966             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1967           counter.bytes =
1968             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1969           set_combined_interface_counter (mp->vnet_counter_type,
1970                                           first_sw_if_index + i, counter);
1971           v++;
1972         }
1973     }
1974 }
1975
1976 static u32
1977 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1978 {
1979   vat_main_t *vam = &vat_main;
1980   u32 i;
1981
1982   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1983     {
1984       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1985         {
1986           return i;
1987         }
1988     }
1989   return ~0;
1990 }
1991
1992 static u32
1993 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1994 {
1995   vat_main_t *vam = &vat_main;
1996   u32 i;
1997
1998   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1999     {
2000       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
2001         {
2002           return i;
2003         }
2004     }
2005   return ~0;
2006 }
2007
2008 static void vl_api_vnet_ip4_fib_counters_t_handler
2009   (vl_api_vnet_ip4_fib_counters_t * mp)
2010 {
2011   /* not supported */
2012 }
2013
2014 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2015   (vl_api_vnet_ip4_fib_counters_t * mp)
2016 {
2017   vat_main_t *vam = &vat_main;
2018   vl_api_ip4_fib_counter_t *v;
2019   ip4_fib_counter_t *counter;
2020   struct in_addr ip4;
2021   u32 vrf_id;
2022   u32 vrf_index;
2023   u32 count;
2024   int i;
2025
2026   vrf_id = ntohl (mp->vrf_id);
2027   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2028   if (~0 == vrf_index)
2029     {
2030       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2031       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2032       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2033       vec_validate (vam->ip4_fib_counters, vrf_index);
2034       vam->ip4_fib_counters[vrf_index] = NULL;
2035     }
2036
2037   vec_free (vam->ip4_fib_counters[vrf_index]);
2038   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2039   count = ntohl (mp->count);
2040   for (i = 0; i < count; i++)
2041     {
2042       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2043       counter = &vam->ip4_fib_counters[vrf_index][i];
2044       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2045       counter->address = ip4;
2046       counter->address_length = v->address_length;
2047       counter->packets = clib_net_to_host_u64 (v->packets);
2048       counter->bytes = clib_net_to_host_u64 (v->bytes);
2049       v++;
2050     }
2051 }
2052
2053 static void vl_api_vnet_ip6_fib_counters_t_handler
2054   (vl_api_vnet_ip6_fib_counters_t * mp)
2055 {
2056   /* not supported */
2057 }
2058
2059 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2060   (vl_api_vnet_ip6_fib_counters_t * mp)
2061 {
2062   vat_main_t *vam = &vat_main;
2063   vl_api_ip6_fib_counter_t *v;
2064   ip6_fib_counter_t *counter;
2065   struct in6_addr ip6;
2066   u32 vrf_id;
2067   u32 vrf_index;
2068   u32 count;
2069   int i;
2070
2071   vrf_id = ntohl (mp->vrf_id);
2072   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2073   if (~0 == vrf_index)
2074     {
2075       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2076       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2077       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2078       vec_validate (vam->ip6_fib_counters, vrf_index);
2079       vam->ip6_fib_counters[vrf_index] = NULL;
2080     }
2081
2082   vec_free (vam->ip6_fib_counters[vrf_index]);
2083   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2084   count = ntohl (mp->count);
2085   for (i = 0; i < count; i++)
2086     {
2087       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2088       counter = &vam->ip6_fib_counters[vrf_index][i];
2089       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2090       counter->address = ip6;
2091       counter->address_length = v->address_length;
2092       counter->packets = clib_net_to_host_u64 (v->packets);
2093       counter->bytes = clib_net_to_host_u64 (v->bytes);
2094       v++;
2095     }
2096 }
2097
2098 static void vl_api_get_first_msg_id_reply_t_handler
2099   (vl_api_get_first_msg_id_reply_t * mp)
2100 {
2101   vat_main_t *vam = &vat_main;
2102   i32 retval = ntohl (mp->retval);
2103
2104   if (vam->async_mode)
2105     {
2106       vam->async_errors += (retval < 0);
2107     }
2108   else
2109     {
2110       vam->retval = retval;
2111       vam->result_ready = 1;
2112     }
2113   if (retval >= 0)
2114     {
2115       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2116     }
2117 }
2118
2119 static void vl_api_get_first_msg_id_reply_t_handler_json
2120   (vl_api_get_first_msg_id_reply_t * mp)
2121 {
2122   vat_main_t *vam = &vat_main;
2123   vat_json_node_t node;
2124
2125   vat_json_init_object (&node);
2126   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2127   vat_json_object_add_uint (&node, "first_msg_id",
2128                             (uint) ntohs (mp->first_msg_id));
2129
2130   vat_json_print (vam->ofp, &node);
2131   vat_json_free (&node);
2132
2133   vam->retval = ntohl (mp->retval);
2134   vam->result_ready = 1;
2135 }
2136
2137 static void vl_api_get_node_graph_reply_t_handler
2138   (vl_api_get_node_graph_reply_t * mp)
2139 {
2140   vat_main_t *vam = &vat_main;
2141   api_main_t *am = &api_main;
2142   i32 retval = ntohl (mp->retval);
2143   u8 *pvt_copy, *reply;
2144   void *oldheap;
2145   vlib_node_t *node;
2146   int i;
2147
2148   if (vam->async_mode)
2149     {
2150       vam->async_errors += (retval < 0);
2151     }
2152   else
2153     {
2154       vam->retval = retval;
2155       vam->result_ready = 1;
2156     }
2157
2158   /* "Should never happen..." */
2159   if (retval != 0)
2160     return;
2161
2162   reply = (u8 *) (mp->reply_in_shmem);
2163   pvt_copy = vec_dup (reply);
2164
2165   /* Toss the shared-memory original... */
2166   pthread_mutex_lock (&am->vlib_rp->mutex);
2167   oldheap = svm_push_data_heap (am->vlib_rp);
2168
2169   vec_free (reply);
2170
2171   svm_pop_heap (oldheap);
2172   pthread_mutex_unlock (&am->vlib_rp->mutex);
2173
2174   if (vam->graph_nodes)
2175     {
2176       hash_free (vam->graph_node_index_by_name);
2177
2178       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2179         {
2180           node = vam->graph_nodes[i];
2181           vec_free (node->name);
2182           vec_free (node->next_nodes);
2183           vec_free (node);
2184         }
2185       vec_free (vam->graph_nodes);
2186     }
2187
2188   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2189   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2190   vec_free (pvt_copy);
2191
2192   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2193     {
2194       node = vam->graph_nodes[i];
2195       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2196     }
2197 }
2198
2199 static void vl_api_get_node_graph_reply_t_handler_json
2200   (vl_api_get_node_graph_reply_t * mp)
2201 {
2202   vat_main_t *vam = &vat_main;
2203   api_main_t *am = &api_main;
2204   void *oldheap;
2205   vat_json_node_t node;
2206   u8 *reply;
2207
2208   /* $$$$ make this real? */
2209   vat_json_init_object (&node);
2210   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2211   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2212
2213   reply = (u8 *) (mp->reply_in_shmem);
2214
2215   /* Toss the shared-memory original... */
2216   pthread_mutex_lock (&am->vlib_rp->mutex);
2217   oldheap = svm_push_data_heap (am->vlib_rp);
2218
2219   vec_free (reply);
2220
2221   svm_pop_heap (oldheap);
2222   pthread_mutex_unlock (&am->vlib_rp->mutex);
2223
2224   vat_json_print (vam->ofp, &node);
2225   vat_json_free (&node);
2226
2227   vam->retval = ntohl (mp->retval);
2228   vam->result_ready = 1;
2229 }
2230
2231 static void
2232 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2233 {
2234   vat_main_t *vam = &vat_main;
2235   locator_msg_t loc;
2236   u8 *tmp_str = 0;
2237
2238   memset (&loc, 0, sizeof (loc));
2239   if (vam->noprint_msg)
2240     {
2241       loc.local = mp->local;
2242       loc.priority = mp->priority;
2243       loc.weight = mp->weight;
2244       if (loc.local)
2245         {
2246           loc.sw_if_index = ntohl (mp->sw_if_index);
2247         }
2248       else
2249         {
2250           loc.is_ipv6 = mp->is_ipv6;
2251           clib_memcpy (loc.ip_address, mp->ip_address,
2252                        sizeof (loc.ip_address));
2253         }
2254       vec_add1 (vam->locator_msg, loc);
2255     }
2256   else
2257     {
2258       if (mp->local)
2259         {
2260           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
2261                             ntohl (mp->sw_if_index),
2262                             mp->priority, mp->weight);
2263         }
2264       else
2265         {
2266           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
2267                             mp->is_ipv6 ? format_ip6_address :
2268                             format_ip4_address,
2269                             mp->ip_address, mp->priority, mp->weight);
2270         }
2271
2272       fformat (vam->ofp, "%s", tmp_str);
2273
2274       vec_free (tmp_str);
2275     }
2276 }
2277
2278 static void
2279 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2280                                             mp)
2281 {
2282   vat_main_t *vam = &vat_main;
2283   vat_json_node_t *node = NULL;
2284   locator_msg_t loc;
2285   struct in6_addr ip6;
2286   struct in_addr ip4;
2287
2288   memset (&loc, 0, sizeof (loc));
2289   if (vam->noprint_msg)
2290     {
2291       loc.local = mp->local;
2292       loc.priority = mp->priority;
2293       loc.weight = mp->weight;
2294       if (loc.local)
2295         {
2296           loc.sw_if_index = ntohl (mp->sw_if_index);
2297         }
2298       else
2299         {
2300           loc.is_ipv6 = mp->is_ipv6;
2301           clib_memcpy (loc.ip_address, mp->ip_address,
2302                        sizeof (loc.ip_address));
2303         }
2304       vec_add1 (vam->locator_msg, loc);
2305       return;
2306     }
2307
2308   if (VAT_JSON_ARRAY != vam->json_tree.type)
2309     {
2310       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2311       vat_json_init_array (&vam->json_tree);
2312     }
2313   node = vat_json_array_add (&vam->json_tree);
2314
2315   vat_json_init_object (node);
2316
2317   if (mp->local)
2318     {
2319       vat_json_object_add_uint (node, "locator_index",
2320                                 ntohl (mp->sw_if_index));
2321     }
2322   else
2323     {
2324       if (mp->is_ipv6)
2325         {
2326           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2327           vat_json_object_add_ip6 (node, "locator", ip6);
2328         }
2329       else
2330         {
2331           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2332           vat_json_object_add_ip4 (node, "locator", ip4);
2333         }
2334     }
2335   vat_json_object_add_uint (node, "priority", mp->priority);
2336   vat_json_object_add_uint (node, "weight", mp->weight);
2337 }
2338
2339 static void
2340 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2341                                            mp)
2342 {
2343   vat_main_t *vam = &vat_main;
2344   locator_set_msg_t ls;
2345
2346   ls.locator_set_index = ntohl (mp->locator_set_index);
2347   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2348   vec_add1 (vam->locator_set_msg, ls);
2349 }
2350
2351 static void
2352   vl_api_lisp_locator_set_details_t_handler_json
2353   (vl_api_lisp_locator_set_details_t * mp)
2354 {
2355   vat_main_t *vam = &vat_main;
2356   locator_set_msg_t ls;
2357
2358   ls.locator_set_index = ntohl (mp->locator_set_index);
2359   ls.locator_set_name = format (0, "%s", mp->locator_set_name);
2360   vec_add1 (vam->locator_set_msg, ls);
2361 }
2362
2363 static void
2364 add_lisp_eid_table_entry (vat_main_t * vam,
2365                           vl_api_lisp_eid_table_details_t * mp)
2366 {
2367   eid_table_t eid_table;
2368
2369   memset (&eid_table, 0, sizeof (eid_table));
2370   eid_table.is_local = mp->is_local;
2371   eid_table.locator_set_index = clib_net_to_host_u32 (mp->locator_set_index);
2372   eid_table.eid_type = mp->eid_type;
2373   eid_table.vni = clib_net_to_host_u32 (mp->vni);
2374   eid_table.eid_prefix_len = mp->eid_prefix_len;
2375   eid_table.ttl = clib_net_to_host_u32 (mp->ttl);
2376   eid_table.action = mp->action;
2377   eid_table.authoritative = mp->authoritative;
2378   clib_memcpy (eid_table.eid, mp->eid, sizeof (eid_table.eid));
2379   vec_add1 (vam->eid_tables, eid_table);
2380 }
2381
2382 static void
2383 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2384 {
2385   vat_main_t *vam = &vat_main;
2386   add_lisp_eid_table_entry (vam, mp);
2387 }
2388
2389 static void
2390 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2391                                               * mp)
2392 {
2393   vat_main_t *vam = &vat_main;
2394   add_lisp_eid_table_entry (vam, mp);
2395 }
2396
2397 static void
2398   vl_api_lisp_eid_table_map_details_t_handler
2399   (vl_api_lisp_eid_table_map_details_t * mp)
2400 {
2401   vat_main_t *vam = &vat_main;
2402
2403   u8 *line = format (0, "%=10d%=10d",
2404                      clib_net_to_host_u32 (mp->vni),
2405                      clib_net_to_host_u32 (mp->dp_table));
2406   fformat (vam->ofp, "%v\n", line);
2407   vec_free (line);
2408 }
2409
2410 static void
2411   vl_api_lisp_eid_table_map_details_t_handler_json
2412   (vl_api_lisp_eid_table_map_details_t * mp)
2413 {
2414   vat_main_t *vam = &vat_main;
2415   vat_json_node_t *node = NULL;
2416
2417   if (VAT_JSON_ARRAY != vam->json_tree.type)
2418     {
2419       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2420       vat_json_init_array (&vam->json_tree);
2421     }
2422   node = vat_json_array_add (&vam->json_tree);
2423   vat_json_init_object (node);
2424   vat_json_object_add_uint (node, "dp_table",
2425                             clib_net_to_host_u32 (mp->dp_table));
2426   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2427 }
2428
2429 static void
2430   vl_api_lisp_eid_table_vni_details_t_handler
2431   (vl_api_lisp_eid_table_vni_details_t * mp)
2432 {
2433   vat_main_t *vam = &vat_main;
2434
2435   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2436   fformat (vam->ofp, "%v\n", line);
2437   vec_free (line);
2438 }
2439
2440 static void
2441   vl_api_lisp_eid_table_vni_details_t_handler_json
2442   (vl_api_lisp_eid_table_vni_details_t * mp)
2443 {
2444   vat_main_t *vam = &vat_main;
2445   vat_json_node_t *node = NULL;
2446
2447   if (VAT_JSON_ARRAY != vam->json_tree.type)
2448     {
2449       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2450       vat_json_init_array (&vam->json_tree);
2451     }
2452   node = vat_json_array_add (&vam->json_tree);
2453   vat_json_init_object (node);
2454   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2455 }
2456
2457 static u8 *
2458 format_decap_next (u8 * s, va_list * args)
2459 {
2460   u32 next_index = va_arg (*args, u32);
2461
2462   switch (next_index)
2463     {
2464     case LISP_GPE_INPUT_NEXT_DROP:
2465       return format (s, "drop");
2466     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2467       return format (s, "ip4");
2468     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2469       return format (s, "ip6");
2470     default:
2471       return format (s, "unknown %d", next_index);
2472     }
2473   return s;
2474 }
2475
2476 static void
2477 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2478                                           mp)
2479 {
2480   vat_main_t *vam = &vat_main;
2481   u8 *iid_str;
2482   u8 *flag_str = NULL;
2483
2484   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2485
2486 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2487   foreach_lisp_gpe_flag_bit;
2488 #undef _
2489
2490   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2491            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2492            mp->tunnels,
2493            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2494            mp->source_ip,
2495            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2496            mp->destination_ip,
2497            ntohl (mp->encap_fib_id),
2498            ntohl (mp->decap_fib_id),
2499            format_decap_next, ntohl (mp->dcap_next),
2500            mp->ver_res >> 6,
2501            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2502
2503   vec_free (iid_str);
2504 }
2505
2506 static void
2507   vl_api_lisp_gpe_tunnel_details_t_handler_json
2508   (vl_api_lisp_gpe_tunnel_details_t * mp)
2509 {
2510   vat_main_t *vam = &vat_main;
2511   vat_json_node_t *node = NULL;
2512   struct in6_addr ip6;
2513   struct in_addr ip4;
2514   u8 *next_decap_str;
2515
2516   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2517
2518   if (VAT_JSON_ARRAY != vam->json_tree.type)
2519     {
2520       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2521       vat_json_init_array (&vam->json_tree);
2522     }
2523   node = vat_json_array_add (&vam->json_tree);
2524
2525   vat_json_init_object (node);
2526   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2527   if (mp->is_ipv6)
2528     {
2529       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2530       vat_json_object_add_ip6 (node, "source address", ip6);
2531       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2532       vat_json_object_add_ip6 (node, "destination address", ip6);
2533     }
2534   else
2535     {
2536       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2537       vat_json_object_add_ip4 (node, "source address", ip4);
2538       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2539       vat_json_object_add_ip4 (node, "destination address", ip4);
2540     }
2541   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2542   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2543   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2544   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2545   vat_json_object_add_uint (node, "flags", mp->flags);
2546   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2547   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2548   vat_json_object_add_uint (node, "res", mp->res);
2549   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2550
2551   vec_free (next_decap_str);
2552 }
2553
2554 static void
2555 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2556                                             * mp)
2557 {
2558   vat_main_t *vam = &vat_main;
2559
2560   fformat (vam->ofp, "%=20U\n",
2561            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2562            mp->ip_address);
2563 }
2564
2565 static void
2566   vl_api_lisp_map_resolver_details_t_handler_json
2567   (vl_api_lisp_map_resolver_details_t * mp)
2568 {
2569   vat_main_t *vam = &vat_main;
2570   vat_json_node_t *node = NULL;
2571   struct in6_addr ip6;
2572   struct in_addr ip4;
2573
2574   if (VAT_JSON_ARRAY != vam->json_tree.type)
2575     {
2576       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2577       vat_json_init_array (&vam->json_tree);
2578     }
2579   node = vat_json_array_add (&vam->json_tree);
2580
2581   vat_json_init_object (node);
2582   if (mp->is_ipv6)
2583     {
2584       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2585       vat_json_object_add_ip6 (node, "map resolver", ip6);
2586     }
2587   else
2588     {
2589       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2590       vat_json_object_add_ip4 (node, "map resolver", ip4);
2591     }
2592 }
2593
2594 static void
2595   vl_api_show_lisp_status_reply_t_handler
2596   (vl_api_show_lisp_status_reply_t * mp)
2597 {
2598   vat_main_t *vam = &vat_main;
2599   i32 retval = ntohl (mp->retval);
2600
2601   if (0 <= retval)
2602     {
2603       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2604                mp->feature_status ? "enabled" : "disabled",
2605                mp->gpe_status ? "enabled" : "disabled");
2606     }
2607
2608   vam->retval = retval;
2609   vam->result_ready = 1;
2610 }
2611
2612 static void
2613   vl_api_show_lisp_status_reply_t_handler_json
2614   (vl_api_show_lisp_status_reply_t * mp)
2615 {
2616   vat_main_t *vam = &vat_main;
2617   vat_json_node_t node;
2618   u8 *gpe_status = NULL;
2619   u8 *feature_status = NULL;
2620
2621   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2622   feature_status = format (0, "%s",
2623                            mp->feature_status ? "enabled" : "disabled");
2624   vec_add1 (gpe_status, 0);
2625   vec_add1 (feature_status, 0);
2626
2627   vat_json_init_object (&node);
2628   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2629   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2630
2631   vec_free (gpe_status);
2632   vec_free (feature_status);
2633
2634   vat_json_print (vam->ofp, &node);
2635   vat_json_free (&node);
2636
2637   vam->retval = ntohl (mp->retval);
2638   vam->result_ready = 1;
2639 }
2640
2641 static void
2642   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2643   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2644 {
2645   vat_main_t *vam = &vat_main;
2646   i32 retval = ntohl (mp->retval);
2647
2648   if (retval >= 0)
2649     {
2650       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2651     }
2652
2653   vam->retval = retval;
2654   vam->result_ready = 1;
2655 }
2656
2657 static void
2658   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2659   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2660 {
2661   vat_main_t *vam = &vat_main;
2662   vat_json_node_t *node = NULL;
2663
2664   if (VAT_JSON_ARRAY != vam->json_tree.type)
2665     {
2666       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2667       vat_json_init_array (&vam->json_tree);
2668     }
2669   node = vat_json_array_add (&vam->json_tree);
2670
2671   vat_json_init_object (node);
2672   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2673
2674   vat_json_print (vam->ofp, node);
2675   vat_json_free (node);
2676
2677   vam->retval = ntohl (mp->retval);
2678   vam->result_ready = 1;
2679 }
2680
2681 static void
2682 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2683 {
2684   vat_main_t *vam = &vat_main;
2685   i32 retval = ntohl (mp->retval);
2686
2687   if (0 <= retval)
2688     {
2689       fformat (vam->ofp, "%-20s%-16s\n",
2690                mp->status ? "enabled" : "disabled",
2691                mp->status ? (char *) mp->locator_set_name : "");
2692     }
2693
2694   vam->retval = retval;
2695   vam->result_ready = 1;
2696 }
2697
2698 static void
2699 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2700                                             mp)
2701 {
2702   vat_main_t *vam = &vat_main;
2703   vat_json_node_t node;
2704   u8 *status = 0;
2705
2706   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2707   vec_add1 (status, 0);
2708
2709   vat_json_init_object (&node);
2710   vat_json_object_add_string_copy (&node, "status", status);
2711   if (mp->status)
2712     {
2713       vat_json_object_add_string_copy (&node, "locator_set",
2714                                        mp->locator_set_name);
2715     }
2716
2717   vec_free (status);
2718
2719   vat_json_print (vam->ofp, &node);
2720   vat_json_free (&node);
2721
2722   vam->retval = ntohl (mp->retval);
2723   vam->result_ready = 1;
2724 }
2725
2726 static u8 *
2727 format_policer_type (u8 * s, va_list * va)
2728 {
2729   u32 i = va_arg (*va, u32);
2730
2731   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2732     s = format (s, "1r2c");
2733   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2734     s = format (s, "1r3c");
2735   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2736     s = format (s, "2r3c-2698");
2737   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2738     s = format (s, "2r3c-4115");
2739   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2740     s = format (s, "2r3c-mef5cf1");
2741   else
2742     s = format (s, "ILLEGAL");
2743   return s;
2744 }
2745
2746 static u8 *
2747 format_policer_rate_type (u8 * s, va_list * va)
2748 {
2749   u32 i = va_arg (*va, u32);
2750
2751   if (i == SSE2_QOS_RATE_KBPS)
2752     s = format (s, "kbps");
2753   else if (i == SSE2_QOS_RATE_PPS)
2754     s = format (s, "pps");
2755   else
2756     s = format (s, "ILLEGAL");
2757   return s;
2758 }
2759
2760 static u8 *
2761 format_policer_round_type (u8 * s, va_list * va)
2762 {
2763   u32 i = va_arg (*va, u32);
2764
2765   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2766     s = format (s, "closest");
2767   else if (i == SSE2_QOS_ROUND_TO_UP)
2768     s = format (s, "up");
2769   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2770     s = format (s, "down");
2771   else
2772     s = format (s, "ILLEGAL");
2773   return s;
2774 }
2775
2776 static u8 *
2777 format_policer_action_type (u8 * s, va_list * va)
2778 {
2779   u32 i = va_arg (*va, u32);
2780
2781   if (i == SSE2_QOS_ACTION_DROP)
2782     s = format (s, "drop");
2783   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2784     s = format (s, "transmit");
2785   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2786     s = format (s, "mark-and-transmit");
2787   else
2788     s = format (s, "ILLEGAL");
2789   return s;
2790 }
2791
2792 static u8 *
2793 format_dscp (u8 * s, va_list * va)
2794 {
2795   u32 i = va_arg (*va, u32);
2796   char *t = 0;
2797
2798   switch (i)
2799     {
2800 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2801       foreach_vnet_dscp
2802 #undef _
2803     default:
2804       return format (s, "ILLEGAL");
2805     }
2806   s = format (s, "%s", t);
2807   return s;
2808 }
2809
2810 static void
2811 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2812 {
2813   vat_main_t *vam = &vat_main;
2814   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2815
2816   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2817     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2818   else
2819     conform_dscp_str = format (0, "");
2820
2821   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2822     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2823   else
2824     exceed_dscp_str = format (0, "");
2825
2826   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2827     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2828   else
2829     violate_dscp_str = format (0, "");
2830
2831   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2832            "rate type %U, round type %U, %s rate, %s color-aware, "
2833            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2834            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2835            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2836            mp->name,
2837            format_policer_type, mp->type,
2838            ntohl (mp->cir),
2839            ntohl (mp->eir),
2840            clib_net_to_host_u64 (mp->cb),
2841            clib_net_to_host_u64 (mp->eb),
2842            format_policer_rate_type, mp->rate_type,
2843            format_policer_round_type, mp->round_type,
2844            mp->single_rate ? "single" : "dual",
2845            mp->color_aware ? "is" : "not",
2846            ntohl (mp->cir_tokens_per_period),
2847            ntohl (mp->pir_tokens_per_period),
2848            ntohl (mp->scale),
2849            ntohl (mp->current_limit),
2850            ntohl (mp->current_bucket),
2851            ntohl (mp->extended_limit),
2852            ntohl (mp->extended_bucket),
2853            clib_net_to_host_u64 (mp->last_update_time),
2854            format_policer_action_type, mp->conform_action_type,
2855            conform_dscp_str,
2856            format_policer_action_type, mp->exceed_action_type,
2857            exceed_dscp_str,
2858            format_policer_action_type, mp->violate_action_type,
2859            violate_dscp_str);
2860
2861   vec_free (conform_dscp_str);
2862   vec_free (exceed_dscp_str);
2863   vec_free (violate_dscp_str);
2864 }
2865
2866 static void vl_api_policer_details_t_handler_json
2867   (vl_api_policer_details_t * mp)
2868 {
2869   vat_main_t *vam = &vat_main;
2870   vat_json_node_t *node;
2871   u8 *rate_type_str, *round_type_str, *type_str;
2872   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2873
2874   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2875   round_type_str =
2876     format (0, "%U", format_policer_round_type, mp->round_type);
2877   type_str = format (0, "%U", format_policer_type, mp->type);
2878   conform_action_str = format (0, "%U", format_policer_action_type,
2879                                mp->conform_action_type);
2880   exceed_action_str = format (0, "%U", format_policer_action_type,
2881                               mp->exceed_action_type);
2882   violate_action_str = format (0, "%U", format_policer_action_type,
2883                                mp->violate_action_type);
2884
2885   if (VAT_JSON_ARRAY != vam->json_tree.type)
2886     {
2887       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2888       vat_json_init_array (&vam->json_tree);
2889     }
2890   node = vat_json_array_add (&vam->json_tree);
2891
2892   vat_json_init_object (node);
2893   vat_json_object_add_string_copy (node, "name", mp->name);
2894   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2895   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2896   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
2897   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
2898   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2899   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2900   vat_json_object_add_string_copy (node, "type", type_str);
2901   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2902   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2903   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2904   vat_json_object_add_uint (node, "cir_tokens_per_period",
2905                             ntohl (mp->cir_tokens_per_period));
2906   vat_json_object_add_uint (node, "eir_tokens_per_period",
2907                             ntohl (mp->pir_tokens_per_period));
2908   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2909   vat_json_object_add_uint (node, "current_bucket",
2910                             ntohl (mp->current_bucket));
2911   vat_json_object_add_uint (node, "extended_limit",
2912                             ntohl (mp->extended_limit));
2913   vat_json_object_add_uint (node, "extended_bucket",
2914                             ntohl (mp->extended_bucket));
2915   vat_json_object_add_uint (node, "last_update_time",
2916                             ntohl (mp->last_update_time));
2917   vat_json_object_add_string_copy (node, "conform_action",
2918                                    conform_action_str);
2919   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2920     {
2921       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2922       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2923       vec_free (dscp_str);
2924     }
2925   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2926   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2927     {
2928       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2929       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2930       vec_free (dscp_str);
2931     }
2932   vat_json_object_add_string_copy (node, "violate_action",
2933                                    violate_action_str);
2934   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2935     {
2936       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2937       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2938       vec_free (dscp_str);
2939     }
2940
2941   vec_free (rate_type_str);
2942   vec_free (round_type_str);
2943   vec_free (type_str);
2944   vec_free (conform_action_str);
2945   vec_free (exceed_action_str);
2946   vec_free (violate_action_str);
2947 }
2948
2949 static void
2950 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2951                                            mp)
2952 {
2953   vat_main_t *vam = &vat_main;
2954   int i, count = ntohl (mp->count);
2955
2956   if (count > 0)
2957     fformat (vam->ofp, "classify table ids (%d) : ", count);
2958   for (i = 0; i < count; i++)
2959     {
2960       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
2961       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
2962     }
2963   vam->retval = ntohl (mp->retval);
2964   vam->result_ready = 1;
2965 }
2966
2967 static void
2968   vl_api_classify_table_ids_reply_t_handler_json
2969   (vl_api_classify_table_ids_reply_t * mp)
2970 {
2971   vat_main_t *vam = &vat_main;
2972   int i, count = ntohl (mp->count);
2973
2974   if (count > 0)
2975     {
2976       vat_json_node_t node;
2977
2978       vat_json_init_object (&node);
2979       for (i = 0; i < count; i++)
2980         {
2981           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
2982         }
2983       vat_json_print (vam->ofp, &node);
2984       vat_json_free (&node);
2985     }
2986   vam->retval = ntohl (mp->retval);
2987   vam->result_ready = 1;
2988 }
2989
2990 static void
2991   vl_api_classify_table_by_interface_reply_t_handler
2992   (vl_api_classify_table_by_interface_reply_t * mp)
2993 {
2994   vat_main_t *vam = &vat_main;
2995   u32 table_id;
2996
2997   table_id = ntohl (mp->l2_table_id);
2998   if (table_id != ~0)
2999     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3000   else
3001     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3002   table_id = ntohl (mp->ip4_table_id);
3003   if (table_id != ~0)
3004     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3005   else
3006     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3007   table_id = ntohl (mp->ip6_table_id);
3008   if (table_id != ~0)
3009     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3010   else
3011     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3012   vam->retval = ntohl (mp->retval);
3013   vam->result_ready = 1;
3014 }
3015
3016 static void
3017   vl_api_classify_table_by_interface_reply_t_handler_json
3018   (vl_api_classify_table_by_interface_reply_t * mp)
3019 {
3020   vat_main_t *vam = &vat_main;
3021   vat_json_node_t node;
3022
3023   vat_json_init_object (&node);
3024
3025   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3026   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3027   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3028
3029   vat_json_print (vam->ofp, &node);
3030   vat_json_free (&node);
3031
3032   vam->retval = ntohl (mp->retval);
3033   vam->result_ready = 1;
3034 }
3035
3036 static void vl_api_policer_add_del_reply_t_handler
3037   (vl_api_policer_add_del_reply_t * mp)
3038 {
3039   vat_main_t *vam = &vat_main;
3040   i32 retval = ntohl (mp->retval);
3041   if (vam->async_mode)
3042     {
3043       vam->async_errors += (retval < 0);
3044     }
3045   else
3046     {
3047       vam->retval = retval;
3048       vam->result_ready = 1;
3049       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3050         /*
3051          * Note: this is just barely thread-safe, depends on
3052          * the main thread spinning waiting for an answer...
3053          */
3054         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3055     }
3056 }
3057
3058 static void vl_api_policer_add_del_reply_t_handler_json
3059   (vl_api_policer_add_del_reply_t * mp)
3060 {
3061   vat_main_t *vam = &vat_main;
3062   vat_json_node_t node;
3063
3064   vat_json_init_object (&node);
3065   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3066   vat_json_object_add_uint (&node, "policer_index",
3067                             ntohl (mp->policer_index));
3068
3069   vat_json_print (vam->ofp, &node);
3070   vat_json_free (&node);
3071
3072   vam->retval = ntohl (mp->retval);
3073   vam->result_ready = 1;
3074 }
3075
3076 /* Format hex dump. */
3077 u8 *
3078 format_hex_bytes (u8 * s, va_list * va)
3079 {
3080   u8 *bytes = va_arg (*va, u8 *);
3081   int n_bytes = va_arg (*va, int);
3082   uword i;
3083
3084   /* Print short or long form depending on byte count. */
3085   uword short_form = n_bytes <= 32;
3086   uword indent = format_get_indent (s);
3087
3088   if (n_bytes == 0)
3089     return s;
3090
3091   for (i = 0; i < n_bytes; i++)
3092     {
3093       if (!short_form && (i % 32) == 0)
3094         s = format (s, "%08x: ", i);
3095       s = format (s, "%02x", bytes[i]);
3096       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3097         s = format (s, "\n%U", format_white_space, indent);
3098     }
3099
3100   return s;
3101 }
3102
3103 static void
3104 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3105                                             * mp)
3106 {
3107   vat_main_t *vam = &vat_main;
3108   i32 retval = ntohl (mp->retval);
3109   if (retval == 0)
3110     {
3111       fformat (vam->ofp, "classify table info :\n");
3112       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3113                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3114                ntohl (mp->miss_next_index));
3115       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3116                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3117                ntohl (mp->match_n_vectors));
3118       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3119                ntohl (mp->mask_length));
3120     }
3121   vam->retval = retval;
3122   vam->result_ready = 1;
3123 }
3124
3125 static void
3126   vl_api_classify_table_info_reply_t_handler_json
3127   (vl_api_classify_table_info_reply_t * mp)
3128 {
3129   vat_main_t *vam = &vat_main;
3130   vat_json_node_t node;
3131
3132   i32 retval = ntohl (mp->retval);
3133   if (retval == 0)
3134     {
3135       vat_json_init_object (&node);
3136
3137       vat_json_object_add_int (&node, "sessions",
3138                                ntohl (mp->active_sessions));
3139       vat_json_object_add_int (&node, "nexttbl",
3140                                ntohl (mp->next_table_index));
3141       vat_json_object_add_int (&node, "nextnode",
3142                                ntohl (mp->miss_next_index));
3143       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3144       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3145       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3146       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3147                       ntohl (mp->mask_length), 0);
3148       vat_json_object_add_string_copy (&node, "mask", s);
3149
3150       vat_json_print (vam->ofp, &node);
3151       vat_json_free (&node);
3152     }
3153   vam->retval = ntohl (mp->retval);
3154   vam->result_ready = 1;
3155 }
3156
3157 static void
3158 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3159                                            mp)
3160 {
3161   vat_main_t *vam = &vat_main;
3162
3163   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3164            ntohl (mp->hit_next_index), ntohl (mp->advance),
3165            ntohl (mp->opaque_index));
3166   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3167            ntohl (mp->match_length));
3168 }
3169
3170 static void
3171   vl_api_classify_session_details_t_handler_json
3172   (vl_api_classify_session_details_t * mp)
3173 {
3174   vat_main_t *vam = &vat_main;
3175   vat_json_node_t *node = NULL;
3176
3177   if (VAT_JSON_ARRAY != vam->json_tree.type)
3178     {
3179       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3180       vat_json_init_array (&vam->json_tree);
3181     }
3182   node = vat_json_array_add (&vam->json_tree);
3183
3184   vat_json_init_object (node);
3185   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3186   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3187   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3188   u8 *s =
3189     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3190             0);
3191   vat_json_object_add_string_copy (node, "match", s);
3192 }
3193
3194 static void vl_api_pg_create_interface_reply_t_handler
3195   (vl_api_pg_create_interface_reply_t * mp)
3196 {
3197   vat_main_t *vam = &vat_main;
3198
3199   vam->retval = ntohl (mp->retval);
3200   vam->result_ready = 1;
3201 }
3202
3203 static void vl_api_pg_create_interface_reply_t_handler_json
3204   (vl_api_pg_create_interface_reply_t * mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207   vat_json_node_t node;
3208
3209   i32 retval = ntohl (mp->retval);
3210   if (retval == 0)
3211     {
3212       vat_json_init_object (&node);
3213
3214       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3215
3216       vat_json_print (vam->ofp, &node);
3217       vat_json_free (&node);
3218     }
3219   vam->retval = ntohl (mp->retval);
3220   vam->result_ready = 1;
3221 }
3222
3223 static void vl_api_policer_classify_details_t_handler
3224   (vl_api_policer_classify_details_t * mp)
3225 {
3226   vat_main_t *vam = &vat_main;
3227
3228   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3229            ntohl (mp->table_index));
3230 }
3231
3232 static void vl_api_policer_classify_details_t_handler_json
3233   (vl_api_policer_classify_details_t * mp)
3234 {
3235   vat_main_t *vam = &vat_main;
3236   vat_json_node_t *node;
3237
3238   if (VAT_JSON_ARRAY != vam->json_tree.type)
3239     {
3240       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3241       vat_json_init_array (&vam->json_tree);
3242     }
3243   node = vat_json_array_add (&vam->json_tree);
3244
3245   vat_json_init_object (node);
3246   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3247   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3248 }
3249
3250 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3251   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3252 {
3253   vat_main_t *vam = &vat_main;
3254   i32 retval = ntohl (mp->retval);
3255   if (vam->async_mode)
3256     {
3257       vam->async_errors += (retval < 0);
3258     }
3259   else
3260     {
3261       vam->retval = retval;
3262       vam->sw_if_index = ntohl (mp->sw_if_index);
3263       vam->result_ready = 1;
3264     }
3265 }
3266
3267 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3268   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3269 {
3270   vat_main_t *vam = &vat_main;
3271   vat_json_node_t node;
3272
3273   vat_json_init_object (&node);
3274   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3275   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3276
3277   vat_json_print (vam->ofp, &node);
3278   vat_json_free (&node);
3279
3280   vam->retval = ntohl (mp->retval);
3281   vam->result_ready = 1;
3282 }
3283
3284 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3285 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3286 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3287 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3288
3289 /*
3290  * Generate boilerplate reply handlers, which
3291  * dig the return value out of the xxx_reply_t API message,
3292  * stick it into vam->retval, and set vam->result_ready
3293  *
3294  * Could also do this by pointing N message decode slots at
3295  * a single function, but that could break in subtle ways.
3296  */
3297
3298 #define foreach_standard_reply_retval_handler           \
3299 _(sw_interface_set_flags_reply)                         \
3300 _(sw_interface_add_del_address_reply)                   \
3301 _(sw_interface_set_table_reply)                         \
3302 _(sw_interface_set_vpath_reply)                         \
3303 _(sw_interface_set_l2_bridge_reply)                     \
3304 _(bridge_domain_add_del_reply)                          \
3305 _(sw_interface_set_l2_xconnect_reply)                   \
3306 _(l2fib_add_del_reply)                                  \
3307 _(ip_add_del_route_reply)                               \
3308 _(proxy_arp_add_del_reply)                              \
3309 _(proxy_arp_intfc_enable_disable_reply)                 \
3310 _(mpls_add_del_encap_reply)                             \
3311 _(mpls_add_del_decap_reply)                             \
3312 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3313 _(sw_interface_set_unnumbered_reply)                    \
3314 _(ip_neighbor_add_del_reply)                            \
3315 _(reset_vrf_reply)                                      \
3316 _(oam_add_del_reply)                                    \
3317 _(reset_fib_reply)                                      \
3318 _(dhcp_proxy_config_reply)                              \
3319 _(dhcp_proxy_config_2_reply)                            \
3320 _(dhcp_proxy_set_vss_reply)                             \
3321 _(dhcp_client_config_reply)                             \
3322 _(set_ip_flow_hash_reply)                               \
3323 _(sw_interface_ip6_enable_disable_reply)                \
3324 _(sw_interface_ip6_set_link_local_address_reply)        \
3325 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3326 _(sw_interface_ip6nd_ra_config_reply)                   \
3327 _(set_arp_neighbor_limit_reply)                         \
3328 _(l2_patch_add_del_reply)                               \
3329 _(sr_tunnel_add_del_reply)                              \
3330 _(sr_policy_add_del_reply)                              \
3331 _(sr_multicast_map_add_del_reply)                       \
3332 _(classify_add_del_session_reply)                       \
3333 _(classify_set_interface_ip_table_reply)                \
3334 _(classify_set_interface_l2_tables_reply)               \
3335 _(l2tpv3_set_tunnel_cookies_reply)                      \
3336 _(l2tpv3_interface_enable_disable_reply)                \
3337 _(l2tpv3_set_lookup_key_reply)                          \
3338 _(l2_fib_clear_table_reply)                             \
3339 _(l2_interface_efp_filter_reply)                        \
3340 _(l2_interface_vlan_tag_rewrite_reply)                  \
3341 _(modify_vhost_user_if_reply)                           \
3342 _(delete_vhost_user_if_reply)                           \
3343 _(want_ip4_arp_events_reply)                            \
3344 _(input_acl_set_interface_reply)                        \
3345 _(ipsec_spd_add_del_reply)                              \
3346 _(ipsec_interface_add_del_spd_reply)                    \
3347 _(ipsec_spd_add_del_entry_reply)                        \
3348 _(ipsec_sad_add_del_entry_reply)                        \
3349 _(ipsec_sa_set_key_reply)                               \
3350 _(ikev2_profile_add_del_reply)                          \
3351 _(ikev2_profile_set_auth_reply)                         \
3352 _(ikev2_profile_set_id_reply)                           \
3353 _(ikev2_profile_set_ts_reply)                           \
3354 _(ikev2_set_local_key_reply)                            \
3355 _(delete_loopback_reply)                                \
3356 _(bd_ip_mac_add_del_reply)                              \
3357 _(map_del_domain_reply)                                 \
3358 _(map_add_del_rule_reply)                               \
3359 _(want_interface_events_reply)                          \
3360 _(want_stats_reply)                                     \
3361 _(cop_interface_enable_disable_reply)                   \
3362 _(cop_whitelist_enable_disable_reply)                   \
3363 _(sw_interface_clear_stats_reply)                       \
3364 _(trace_profile_add_reply)                              \
3365 _(trace_profile_apply_reply)                            \
3366 _(trace_profile_del_reply)                              \
3367 _(lisp_add_del_locator_reply)                           \
3368 _(lisp_add_del_local_eid_reply)                         \
3369 _(lisp_add_del_remote_mapping_reply)                    \
3370 _(lisp_add_del_adjacency_reply)                         \
3371 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3372 _(lisp_add_del_map_resolver_reply)                      \
3373 _(lisp_gpe_enable_disable_reply)                        \
3374 _(lisp_gpe_add_del_iface_reply)                         \
3375 _(lisp_enable_disable_reply)                            \
3376 _(lisp_pitr_set_locator_set_reply)                      \
3377 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3378 _(lisp_eid_table_add_del_map_reply)                     \
3379 _(vxlan_gpe_add_del_tunnel_reply)                       \
3380 _(af_packet_delete_reply)                               \
3381 _(policer_classify_set_interface_reply)                 \
3382 _(netmap_create_reply)                                  \
3383 _(netmap_delete_reply)                                  \
3384 _(ipfix_enable_reply)                                   \
3385 _(pg_capture_reply)                                     \
3386 _(pg_enable_disable_reply)                              \
3387 _(ip_source_and_port_range_check_add_del_reply)         \
3388 _(ip_source_and_port_range_check_interface_add_del_reply)
3389
3390 #define _(n)                                    \
3391     static void vl_api_##n##_t_handler          \
3392     (vl_api_##n##_t * mp)                       \
3393     {                                           \
3394         vat_main_t * vam = &vat_main;           \
3395         i32 retval = ntohl(mp->retval);         \
3396         if (vam->async_mode) {                  \
3397             vam->async_errors += (retval < 0);  \
3398         } else {                                \
3399             vam->retval = retval;               \
3400             vam->result_ready = 1;              \
3401         }                                       \
3402     }
3403 foreach_standard_reply_retval_handler;
3404 #undef _
3405
3406 #define _(n)                                    \
3407     static void vl_api_##n##_t_handler_json     \
3408     (vl_api_##n##_t * mp)                       \
3409     {                                           \
3410         vat_main_t * vam = &vat_main;           \
3411         vat_json_node_t node;                   \
3412         vat_json_init_object(&node);            \
3413         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3414         vat_json_print(vam->ofp, &node);        \
3415         vam->retval = ntohl(mp->retval);        \
3416         vam->result_ready = 1;                  \
3417     }
3418 foreach_standard_reply_retval_handler;
3419 #undef _
3420
3421 /*
3422  * Table of message reply handlers, must include boilerplate handlers
3423  * we just generated
3424  */
3425
3426 #define foreach_vpe_api_reply_msg                                       \
3427 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3428 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3429 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3430 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3431 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3432 _(NOPRINT_CONTROL_PING_REPLY, noprint_control_ping_reply)               \
3433 _(CLI_REPLY, cli_reply)                                                 \
3434 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3435   sw_interface_add_del_address_reply)                                   \
3436 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3437 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3438 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3439   sw_interface_set_l2_xconnect_reply)                                   \
3440 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3441   sw_interface_set_l2_bridge_reply)                                     \
3442 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3443 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3444 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3445 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3446 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3447 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3448 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3449 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3450 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3451 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3452 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3453 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3454 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3455   proxy_arp_intfc_enable_disable_reply)                                 \
3456 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3457 _(MPLS_ADD_DEL_DECAP_REPLY, mpls_add_del_decap_reply)                   \
3458 _(MPLS_GRE_ADD_DEL_TUNNEL_REPLY, mpls_gre_add_del_tunnel_reply)         \
3459 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3460   mpls_ethernet_add_del_tunnel_reply)                                   \
3461 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3462   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3463 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3464   sw_interface_set_unnumbered_reply)                                    \
3465 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3466 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3467 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3468 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3469 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3470 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3471 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3472 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3473 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3474 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3475 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3476 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3477   sw_interface_ip6_enable_disable_reply)                                \
3478 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3479   sw_interface_ip6_set_link_local_address_reply)                        \
3480 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3481   sw_interface_ip6nd_ra_prefix_reply)                                   \
3482 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3483   sw_interface_ip6nd_ra_config_reply)                                   \
3484 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3485 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3486 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3487 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3488 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3489 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3490 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3491 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3492 classify_set_interface_ip_table_reply)                                  \
3493 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3494   classify_set_interface_l2_tables_reply)                               \
3495 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3496 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3497 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3498 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3499 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3500   l2tpv3_interface_enable_disable_reply)                                \
3501 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3502 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3503 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3504 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3505 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3506 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3507 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3508 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3509 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3510 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3511 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3512 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3513 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3514 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3515 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3516 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3517 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3518 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3519 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3520 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3521 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3522 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3523 _(IP_DETAILS, ip_details)                                               \
3524 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3525 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3526 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3527 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3528 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3529 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3530 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3531 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3532 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3533 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3534 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3535 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3536 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3537 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3538 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3539 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3540 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3541 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3542 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3543 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3544 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3545 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3546 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3547 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3548 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3549 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3550 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3551 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3552 _(TRACE_PROFILE_ADD_REPLY, trace_profile_add_reply)                   \
3553 _(TRACE_PROFILE_APPLY_REPLY, trace_profile_apply_reply)               \
3554 _(TRACE_PROFILE_DEL_REPLY, trace_profile_del_reply)                     \
3555 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3556 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3557 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3558 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3559 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3560 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3561 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3562 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3563 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3564 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3565 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3566 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3567 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3568 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3569 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3570 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3571 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3572 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3573 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3574 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3575 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3576   lisp_add_del_map_request_itr_rlocs_reply)                             \
3577 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3578   lisp_get_map_request_itr_rlocs_reply)                                 \
3579 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3580 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3581 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3582 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3583 _(POLICER_DETAILS, policer_details)                                     \
3584 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3585 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3586 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3587 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3588 _(MPLS_GRE_TUNNEL_DETAILS, mpls_gre_tunnel_details)                     \
3589 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3590 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3591 _(MPLS_FIB_DECAP_DETAILS, mpls_fib_decap_details)                       \
3592 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3593 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3594 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3595 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3596 _(IPFIX_ENABLE_REPLY, ipfix_enable_reply)                               \
3597 _(IPFIX_DETAILS, ipfix_details)                                         \
3598 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3599 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3600 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3601 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3602 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3603  ip_source_and_port_range_check_add_del_reply)                          \
3604 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3605  ip_source_and_port_range_check_interface_add_del_reply)                \
3606 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3607 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)
3608
3609 /* M: construct, but don't yet send a message */
3610
3611 #define M(T,t)                                  \
3612 do {                                            \
3613     vam->result_ready = 0;                      \
3614     mp = vl_msg_api_alloc(sizeof(*mp));         \
3615     memset (mp, 0, sizeof (*mp));               \
3616     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3617     mp->client_index = vam->my_client_index;    \
3618 } while(0);
3619
3620 #define M2(T,t,n)                               \
3621 do {                                            \
3622     vam->result_ready = 0;                      \
3623     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3624     memset (mp, 0, sizeof (*mp));               \
3625     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3626     mp->client_index = vam->my_client_index;    \
3627 } while(0);
3628
3629
3630 /* S: send a message */
3631 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3632
3633 /* W: wait for results, with timeout */
3634 #define W                                       \
3635 do {                                            \
3636     timeout = vat_time_now (vam) + 1.0;         \
3637                                                 \
3638     while (vat_time_now (vam) < timeout) {      \
3639         if (vam->result_ready == 1) {           \
3640             return (vam->retval);               \
3641         }                                       \
3642     }                                           \
3643     return -99;                                 \
3644 } while(0);
3645
3646 /* W2: wait for results, with timeout */
3647 #define W2(body)                                \
3648 do {                                            \
3649     timeout = vat_time_now (vam) + 1.0;         \
3650                                                 \
3651     while (vat_time_now (vam) < timeout) {      \
3652         if (vam->result_ready == 1) {           \
3653           (body);                               \
3654           return (vam->retval);                 \
3655         }                                       \
3656     }                                           \
3657     return -99;                                 \
3658 } while(0);
3659
3660 /* W_L: wait for results, with timeout */
3661 #define W_L(body)                               \
3662 do {                                            \
3663     timeout = vat_time_now (vam) + 1.0;         \
3664                                                 \
3665     while (vat_time_now (vam) < timeout) {      \
3666         if (vam->result_ready == 1) {           \
3667           (body);                               \
3668           return (vam->retval);                 \
3669         }                                       \
3670     }                                           \
3671     vam->noprint_msg = 0;     \
3672     return -99;                                 \
3673 } while(0);
3674
3675 typedef struct
3676 {
3677   u8 *name;
3678   u32 value;
3679 } name_sort_t;
3680
3681
3682 #define STR_VTR_OP_CASE(op)     \
3683     case L2_VTR_ ## op:         \
3684         return "" # op;
3685
3686 static const char *
3687 str_vtr_op (u32 vtr_op)
3688 {
3689   switch (vtr_op)
3690     {
3691       STR_VTR_OP_CASE (DISABLED);
3692       STR_VTR_OP_CASE (PUSH_1);
3693       STR_VTR_OP_CASE (PUSH_2);
3694       STR_VTR_OP_CASE (POP_1);
3695       STR_VTR_OP_CASE (POP_2);
3696       STR_VTR_OP_CASE (TRANSLATE_1_1);
3697       STR_VTR_OP_CASE (TRANSLATE_1_2);
3698       STR_VTR_OP_CASE (TRANSLATE_2_1);
3699       STR_VTR_OP_CASE (TRANSLATE_2_2);
3700     }
3701
3702   return "UNKNOWN";
3703 }
3704
3705 static int
3706 dump_sub_interface_table (vat_main_t * vam)
3707 {
3708   const sw_interface_subif_t *sub = NULL;
3709
3710   if (vam->json_output)
3711     {
3712       clib_warning
3713         ("JSON output supported only for VPE API calls and dump_stats_table");
3714       return -99;
3715     }
3716
3717   fformat (vam->ofp,
3718            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3719            "Interface", "sw_if_index",
3720            "sub id", "dot1ad", "tags", "outer id",
3721            "inner id", "exact", "default", "outer any", "inner any");
3722
3723   vec_foreach (sub, vam->sw_if_subif_table)
3724   {
3725     fformat (vam->ofp,
3726              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3727              sub->interface_name,
3728              sub->sw_if_index,
3729              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3730              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3731              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3732              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3733     if (sub->vtr_op != L2_VTR_DISABLED)
3734       {
3735         fformat (vam->ofp,
3736                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3737                  "tag1: %d tag2: %d ]\n",
3738                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3739                  sub->vtr_tag1, sub->vtr_tag2);
3740       }
3741   }
3742
3743   return 0;
3744 }
3745
3746 static int
3747 name_sort_cmp (void *a1, void *a2)
3748 {
3749   name_sort_t *n1 = a1;
3750   name_sort_t *n2 = a2;
3751
3752   return strcmp ((char *) n1->name, (char *) n2->name);
3753 }
3754
3755 static int
3756 dump_interface_table (vat_main_t * vam)
3757 {
3758   hash_pair_t *p;
3759   name_sort_t *nses = 0, *ns;
3760
3761   if (vam->json_output)
3762     {
3763       clib_warning
3764         ("JSON output supported only for VPE API calls and dump_stats_table");
3765       return -99;
3766     }
3767
3768   /* *INDENT-OFF* */
3769   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3770   ({
3771     vec_add2 (nses, ns, 1);
3772     ns->name = (u8 *)(p->key);
3773     ns->value = (u32) p->value[0];
3774   }));
3775   /* *INDENT-ON* */
3776
3777   vec_sort_with_function (nses, name_sort_cmp);
3778
3779   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3780   vec_foreach (ns, nses)
3781   {
3782     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3783   }
3784   vec_free (nses);
3785   return 0;
3786 }
3787
3788 static int
3789 dump_ip_table (vat_main_t * vam, int is_ipv6)
3790 {
3791   const ip_details_t *det = NULL;
3792   const ip_address_details_t *address = NULL;
3793   u32 i = ~0;
3794
3795   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3796
3797   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3798   {
3799     i++;
3800     if (!det->present)
3801       {
3802         continue;
3803       }
3804     fformat (vam->ofp, "%-12d\n", i);
3805     fformat (vam->ofp,
3806              "            %-30s%-13s\n", "Address", "Prefix length");
3807     if (!det->addr)
3808       {
3809         continue;
3810       }
3811     vec_foreach (address, det->addr)
3812     {
3813       fformat (vam->ofp,
3814                "            %-30U%-13d\n",
3815                is_ipv6 ? format_ip6_address : format_ip4_address,
3816                address->ip, address->prefix_length);
3817     }
3818   }
3819
3820   return 0;
3821 }
3822
3823 static int
3824 dump_ipv4_table (vat_main_t * vam)
3825 {
3826   if (vam->json_output)
3827     {
3828       clib_warning
3829         ("JSON output supported only for VPE API calls and dump_stats_table");
3830       return -99;
3831     }
3832
3833   return dump_ip_table (vam, 0);
3834 }
3835
3836 static int
3837 dump_ipv6_table (vat_main_t * vam)
3838 {
3839   if (vam->json_output)
3840     {
3841       clib_warning
3842         ("JSON output supported only for VPE API calls and dump_stats_table");
3843       return -99;
3844     }
3845
3846   return dump_ip_table (vam, 1);
3847 }
3848
3849 static char *
3850 counter_type_to_str (u8 counter_type, u8 is_combined)
3851 {
3852   if (!is_combined)
3853     {
3854       switch (counter_type)
3855         {
3856         case VNET_INTERFACE_COUNTER_DROP:
3857           return "drop";
3858         case VNET_INTERFACE_COUNTER_PUNT:
3859           return "punt";
3860         case VNET_INTERFACE_COUNTER_IP4:
3861           return "ip4";
3862         case VNET_INTERFACE_COUNTER_IP6:
3863           return "ip6";
3864         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
3865           return "rx-no-buf";
3866         case VNET_INTERFACE_COUNTER_RX_MISS:
3867           return "rx-miss";
3868         case VNET_INTERFACE_COUNTER_RX_ERROR:
3869           return "rx-error";
3870         case VNET_INTERFACE_COUNTER_TX_ERROR:
3871           return "tx-error";
3872         default:
3873           return "INVALID-COUNTER-TYPE";
3874         }
3875     }
3876   else
3877     {
3878       switch (counter_type)
3879         {
3880         case VNET_INTERFACE_COUNTER_RX:
3881           return "rx";
3882         case VNET_INTERFACE_COUNTER_TX:
3883           return "tx";
3884         default:
3885           return "INVALID-COUNTER-TYPE";
3886         }
3887     }
3888 }
3889
3890 static int
3891 dump_stats_table (vat_main_t * vam)
3892 {
3893   vat_json_node_t node;
3894   vat_json_node_t *msg_array;
3895   vat_json_node_t *msg;
3896   vat_json_node_t *counter_array;
3897   vat_json_node_t *counter;
3898   interface_counter_t c;
3899   u64 packets;
3900   ip4_fib_counter_t *c4;
3901   ip6_fib_counter_t *c6;
3902   int i, j;
3903
3904   if (!vam->json_output)
3905     {
3906       clib_warning ("dump_stats_table supported only in JSON format");
3907       return -99;
3908     }
3909
3910   vat_json_init_object (&node);
3911
3912   /* interface counters */
3913   msg_array = vat_json_object_add (&node, "interface_counters");
3914   vat_json_init_array (msg_array);
3915   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
3916     {
3917       msg = vat_json_array_add (msg_array);
3918       vat_json_init_object (msg);
3919       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3920                                        (u8 *) counter_type_to_str (i, 0));
3921       vat_json_object_add_int (msg, "is_combined", 0);
3922       counter_array = vat_json_object_add (msg, "data");
3923       vat_json_init_array (counter_array);
3924       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
3925         {
3926           packets = vam->simple_interface_counters[i][j];
3927           vat_json_array_add_uint (counter_array, packets);
3928         }
3929     }
3930   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
3931     {
3932       msg = vat_json_array_add (msg_array);
3933       vat_json_init_object (msg);
3934       vat_json_object_add_string_copy (msg, "vnet_counter_type",
3935                                        (u8 *) counter_type_to_str (i, 1));
3936       vat_json_object_add_int (msg, "is_combined", 1);
3937       counter_array = vat_json_object_add (msg, "data");
3938       vat_json_init_array (counter_array);
3939       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
3940         {
3941           c = vam->combined_interface_counters[i][j];
3942           counter = vat_json_array_add (counter_array);
3943           vat_json_init_object (counter);
3944           vat_json_object_add_uint (counter, "packets", c.packets);
3945           vat_json_object_add_uint (counter, "bytes", c.bytes);
3946         }
3947     }
3948
3949   /* ip4 fib counters */
3950   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
3951   vat_json_init_array (msg_array);
3952   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
3953     {
3954       msg = vat_json_array_add (msg_array);
3955       vat_json_init_object (msg);
3956       vat_json_object_add_uint (msg, "vrf_id",
3957                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
3958       counter_array = vat_json_object_add (msg, "c");
3959       vat_json_init_array (counter_array);
3960       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
3961         {
3962           counter = vat_json_array_add (counter_array);
3963           vat_json_init_object (counter);
3964           c4 = &vam->ip4_fib_counters[i][j];
3965           vat_json_object_add_ip4 (counter, "address", c4->address);
3966           vat_json_object_add_uint (counter, "address_length",
3967                                     c4->address_length);
3968           vat_json_object_add_uint (counter, "packets", c4->packets);
3969           vat_json_object_add_uint (counter, "bytes", c4->bytes);
3970         }
3971     }
3972
3973   /* ip6 fib counters */
3974   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
3975   vat_json_init_array (msg_array);
3976   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
3977     {
3978       msg = vat_json_array_add (msg_array);
3979       vat_json_init_object (msg);
3980       vat_json_object_add_uint (msg, "vrf_id",
3981                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
3982       counter_array = vat_json_object_add (msg, "c");
3983       vat_json_init_array (counter_array);
3984       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
3985         {
3986           counter = vat_json_array_add (counter_array);
3987           vat_json_init_object (counter);
3988           c6 = &vam->ip6_fib_counters[i][j];
3989           vat_json_object_add_ip6 (counter, "address", c6->address);
3990           vat_json_object_add_uint (counter, "address_length",
3991                                     c6->address_length);
3992           vat_json_object_add_uint (counter, "packets", c6->packets);
3993           vat_json_object_add_uint (counter, "bytes", c6->bytes);
3994         }
3995     }
3996
3997   vat_json_print (vam->ofp, &node);
3998   vat_json_free (&node);
3999
4000   return 0;
4001 }
4002
4003 int
4004 exec (vat_main_t * vam)
4005 {
4006   api_main_t *am = &api_main;
4007   vl_api_cli_request_t *mp;
4008   f64 timeout;
4009   void *oldheap;
4010   u8 *cmd = 0;
4011   unformat_input_t *i = vam->input;
4012
4013   if (vec_len (i->buffer) == 0)
4014     return -1;
4015
4016   if (vam->exec_mode == 0 && unformat (i, "mode"))
4017     {
4018       vam->exec_mode = 1;
4019       return 0;
4020     }
4021   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4022     {
4023       vam->exec_mode = 0;
4024       return 0;
4025     }
4026
4027
4028   M (CLI_REQUEST, cli_request);
4029
4030   /*
4031    * Copy cmd into shared memory.
4032    * In order for the CLI command to work, it
4033    * must be a vector ending in \n, not a C-string ending
4034    * in \n\0.
4035    */
4036   pthread_mutex_lock (&am->vlib_rp->mutex);
4037   oldheap = svm_push_data_heap (am->vlib_rp);
4038
4039   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4040   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4041
4042   svm_pop_heap (oldheap);
4043   pthread_mutex_unlock (&am->vlib_rp->mutex);
4044
4045   mp->cmd_in_shmem = (u64) cmd;
4046   S;
4047   timeout = vat_time_now (vam) + 10.0;
4048
4049   while (vat_time_now (vam) < timeout)
4050     {
4051       if (vam->result_ready == 1)
4052         {
4053           u8 *free_me;
4054           if (vam->shmem_result != NULL)
4055             fformat (vam->ofp, "%s", vam->shmem_result);
4056           pthread_mutex_lock (&am->vlib_rp->mutex);
4057           oldheap = svm_push_data_heap (am->vlib_rp);
4058
4059           free_me = (u8 *) vam->shmem_result;
4060           vec_free (free_me);
4061
4062           svm_pop_heap (oldheap);
4063           pthread_mutex_unlock (&am->vlib_rp->mutex);
4064           return 0;
4065         }
4066     }
4067   return -99;
4068 }
4069
4070 static int
4071 api_create_loopback (vat_main_t * vam)
4072 {
4073   unformat_input_t *i = vam->input;
4074   vl_api_create_loopback_t *mp;
4075   f64 timeout;
4076   u8 mac_address[6];
4077   u8 mac_set = 0;
4078
4079   memset (mac_address, 0, sizeof (mac_address));
4080
4081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4082     {
4083       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4084         mac_set = 1;
4085       else
4086         break;
4087     }
4088
4089   /* Construct the API message */
4090   M (CREATE_LOOPBACK, create_loopback);
4091   if (mac_set)
4092     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4093
4094   S;
4095   W;
4096 }
4097
4098 static int
4099 api_delete_loopback (vat_main_t * vam)
4100 {
4101   unformat_input_t *i = vam->input;
4102   vl_api_delete_loopback_t *mp;
4103   f64 timeout;
4104   u32 sw_if_index = ~0;
4105
4106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4107     {
4108       if (unformat (i, "sw_if_index %d", &sw_if_index))
4109         ;
4110       else
4111         break;
4112     }
4113
4114   if (sw_if_index == ~0)
4115     {
4116       errmsg ("missing sw_if_index\n");
4117       return -99;
4118     }
4119
4120   /* Construct the API message */
4121   M (DELETE_LOOPBACK, delete_loopback);
4122   mp->sw_if_index = ntohl (sw_if_index);
4123
4124   S;
4125   W;
4126 }
4127
4128 static int
4129 api_want_stats (vat_main_t * vam)
4130 {
4131   unformat_input_t *i = vam->input;
4132   vl_api_want_stats_t *mp;
4133   f64 timeout;
4134   int enable = -1;
4135
4136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4137     {
4138       if (unformat (i, "enable"))
4139         enable = 1;
4140       else if (unformat (i, "disable"))
4141         enable = 0;
4142       else
4143         break;
4144     }
4145
4146   if (enable == -1)
4147     {
4148       errmsg ("missing enable|disable\n");
4149       return -99;
4150     }
4151
4152   M (WANT_STATS, want_stats);
4153   mp->enable_disable = enable;
4154
4155   S;
4156   W;
4157 }
4158
4159 static int
4160 api_want_interface_events (vat_main_t * vam)
4161 {
4162   unformat_input_t *i = vam->input;
4163   vl_api_want_interface_events_t *mp;
4164   f64 timeout;
4165   int enable = -1;
4166
4167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4168     {
4169       if (unformat (i, "enable"))
4170         enable = 1;
4171       else if (unformat (i, "disable"))
4172         enable = 0;
4173       else
4174         break;
4175     }
4176
4177   if (enable == -1)
4178     {
4179       errmsg ("missing enable|disable\n");
4180       return -99;
4181     }
4182
4183   M (WANT_INTERFACE_EVENTS, want_interface_events);
4184   mp->enable_disable = enable;
4185
4186   vam->interface_event_display = enable;
4187
4188   S;
4189   W;
4190 }
4191
4192
4193 /* Note: non-static, called once to set up the initial intfc table */
4194 int
4195 api_sw_interface_dump (vat_main_t * vam)
4196 {
4197   vl_api_sw_interface_dump_t *mp;
4198   f64 timeout;
4199   hash_pair_t *p;
4200   name_sort_t *nses = 0, *ns;
4201   sw_interface_subif_t *sub = NULL;
4202
4203   /* Toss the old name table */
4204   /* *INDENT-OFF* */
4205   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4206   ({
4207     vec_add2 (nses, ns, 1);
4208     ns->name = (u8 *)(p->key);
4209     ns->value = (u32) p->value[0];
4210   }));
4211   /* *INDENT-ON* */
4212
4213   hash_free (vam->sw_if_index_by_interface_name);
4214
4215   vec_foreach (ns, nses) vec_free (ns->name);
4216
4217   vec_free (nses);
4218
4219   vec_foreach (sub, vam->sw_if_subif_table)
4220   {
4221     vec_free (sub->interface_name);
4222   }
4223   vec_free (vam->sw_if_subif_table);
4224
4225   /* recreate the interface name hash table */
4226   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4227
4228   /* Get list of ethernets */
4229   M (SW_INTERFACE_DUMP, sw_interface_dump);
4230   mp->name_filter_valid = 1;
4231   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4232   S;
4233
4234   /* and local / loopback interfaces */
4235   M (SW_INTERFACE_DUMP, sw_interface_dump);
4236   mp->name_filter_valid = 1;
4237   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4238   S;
4239
4240
4241   /* and vxlan-gpe tunnel interfaces */
4242   M (SW_INTERFACE_DUMP, sw_interface_dump);
4243   mp->name_filter_valid = 1;
4244   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4245            sizeof (mp->name_filter) - 1);
4246   S;
4247
4248   /* and vxlan tunnel interfaces */
4249   M (SW_INTERFACE_DUMP, sw_interface_dump);
4250   mp->name_filter_valid = 1;
4251   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4252   S;
4253
4254   /* and host (af_packet) interfaces */
4255   M (SW_INTERFACE_DUMP, sw_interface_dump);
4256   mp->name_filter_valid = 1;
4257   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4258   S;
4259
4260   /* and l2tpv3 tunnel interfaces */
4261   M (SW_INTERFACE_DUMP, sw_interface_dump);
4262   mp->name_filter_valid = 1;
4263   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4264            sizeof (mp->name_filter) - 1);
4265   S;
4266
4267   /* and GRE tunnel interfaces */
4268   M (SW_INTERFACE_DUMP, sw_interface_dump);
4269   mp->name_filter_valid = 1;
4270   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4271   S;
4272
4273   /* Use a control ping for synchronization */
4274   {
4275     vl_api_control_ping_t *mp;
4276     M (CONTROL_PING, control_ping);
4277     S;
4278   }
4279   W;
4280 }
4281
4282 static int
4283 api_sw_interface_set_flags (vat_main_t * vam)
4284 {
4285   unformat_input_t *i = vam->input;
4286   vl_api_sw_interface_set_flags_t *mp;
4287   f64 timeout;
4288   u32 sw_if_index;
4289   u8 sw_if_index_set = 0;
4290   u8 admin_up = 0, link_up = 0;
4291
4292   /* Parse args required to build the message */
4293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4294     {
4295       if (unformat (i, "admin-up"))
4296         admin_up = 1;
4297       else if (unformat (i, "admin-down"))
4298         admin_up = 0;
4299       else if (unformat (i, "link-up"))
4300         link_up = 1;
4301       else if (unformat (i, "link-down"))
4302         link_up = 0;
4303       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4304         sw_if_index_set = 1;
4305       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4306         sw_if_index_set = 1;
4307       else
4308         break;
4309     }
4310
4311   if (sw_if_index_set == 0)
4312     {
4313       errmsg ("missing interface name or sw_if_index\n");
4314       return -99;
4315     }
4316
4317   /* Construct the API message */
4318   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4319   mp->sw_if_index = ntohl (sw_if_index);
4320   mp->admin_up_down = admin_up;
4321   mp->link_up_down = link_up;
4322
4323   /* send it... */
4324   S;
4325
4326   /* Wait for a reply, return the good/bad news... */
4327   W;
4328 }
4329
4330 static int
4331 api_sw_interface_clear_stats (vat_main_t * vam)
4332 {
4333   unformat_input_t *i = vam->input;
4334   vl_api_sw_interface_clear_stats_t *mp;
4335   f64 timeout;
4336   u32 sw_if_index;
4337   u8 sw_if_index_set = 0;
4338
4339   /* Parse args required to build the message */
4340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4341     {
4342       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4343         sw_if_index_set = 1;
4344       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4345         sw_if_index_set = 1;
4346       else
4347         break;
4348     }
4349
4350   /* Construct the API message */
4351   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4352
4353   if (sw_if_index_set == 1)
4354     mp->sw_if_index = ntohl (sw_if_index);
4355   else
4356     mp->sw_if_index = ~0;
4357
4358   /* send it... */
4359   S;
4360
4361   /* Wait for a reply, return the good/bad news... */
4362   W;
4363 }
4364
4365 static int
4366 api_sw_interface_add_del_address (vat_main_t * vam)
4367 {
4368   unformat_input_t *i = vam->input;
4369   vl_api_sw_interface_add_del_address_t *mp;
4370   f64 timeout;
4371   u32 sw_if_index;
4372   u8 sw_if_index_set = 0;
4373   u8 is_add = 1, del_all = 0;
4374   u32 address_length = 0;
4375   u8 v4_address_set = 0;
4376   u8 v6_address_set = 0;
4377   ip4_address_t v4address;
4378   ip6_address_t v6address;
4379
4380   /* Parse args required to build the message */
4381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4382     {
4383       if (unformat (i, "del-all"))
4384         del_all = 1;
4385       else if (unformat (i, "del"))
4386         is_add = 0;
4387       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4388         sw_if_index_set = 1;
4389       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4390         sw_if_index_set = 1;
4391       else if (unformat (i, "%U/%d",
4392                          unformat_ip4_address, &v4address, &address_length))
4393         v4_address_set = 1;
4394       else if (unformat (i, "%U/%d",
4395                          unformat_ip6_address, &v6address, &address_length))
4396         v6_address_set = 1;
4397       else
4398         break;
4399     }
4400
4401   if (sw_if_index_set == 0)
4402     {
4403       errmsg ("missing interface name or sw_if_index\n");
4404       return -99;
4405     }
4406   if (v4_address_set && v6_address_set)
4407     {
4408       errmsg ("both v4 and v6 addresses set\n");
4409       return -99;
4410     }
4411   if (!v4_address_set && !v6_address_set && !del_all)
4412     {
4413       errmsg ("no addresses set\n");
4414       return -99;
4415     }
4416
4417   /* Construct the API message */
4418   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4419
4420   mp->sw_if_index = ntohl (sw_if_index);
4421   mp->is_add = is_add;
4422   mp->del_all = del_all;
4423   if (v6_address_set)
4424     {
4425       mp->is_ipv6 = 1;
4426       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4427     }
4428   else
4429     {
4430       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4431     }
4432   mp->address_length = address_length;
4433
4434   /* send it... */
4435   S;
4436
4437   /* Wait for a reply, return good/bad news  */
4438   W;
4439 }
4440
4441 static int
4442 api_sw_interface_set_table (vat_main_t * vam)
4443 {
4444   unformat_input_t *i = vam->input;
4445   vl_api_sw_interface_set_table_t *mp;
4446   f64 timeout;
4447   u32 sw_if_index, vrf_id = 0;
4448   u8 sw_if_index_set = 0;
4449   u8 is_ipv6 = 0;
4450
4451   /* Parse args required to build the message */
4452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4453     {
4454       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4455         sw_if_index_set = 1;
4456       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4457         sw_if_index_set = 1;
4458       else if (unformat (i, "vrf %d", &vrf_id))
4459         ;
4460       else if (unformat (i, "ipv6"))
4461         is_ipv6 = 1;
4462       else
4463         break;
4464     }
4465
4466   if (sw_if_index_set == 0)
4467     {
4468       errmsg ("missing interface name or sw_if_index\n");
4469       return -99;
4470     }
4471
4472   /* Construct the API message */
4473   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4474
4475   mp->sw_if_index = ntohl (sw_if_index);
4476   mp->is_ipv6 = is_ipv6;
4477   mp->vrf_id = ntohl (vrf_id);
4478
4479   /* send it... */
4480   S;
4481
4482   /* Wait for a reply... */
4483   W;
4484 }
4485
4486 static int
4487 api_sw_interface_set_vpath (vat_main_t * vam)
4488 {
4489   unformat_input_t *i = vam->input;
4490   vl_api_sw_interface_set_vpath_t *mp;
4491   f64 timeout;
4492   u32 sw_if_index = 0;
4493   u8 sw_if_index_set = 0;
4494   u8 is_enable = 0;
4495
4496   /* Parse args required to build the message */
4497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4498     {
4499       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4500         sw_if_index_set = 1;
4501       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4502         sw_if_index_set = 1;
4503       else if (unformat (i, "enable"))
4504         is_enable = 1;
4505       else if (unformat (i, "disable"))
4506         is_enable = 0;
4507       else
4508         break;
4509     }
4510
4511   if (sw_if_index_set == 0)
4512     {
4513       errmsg ("missing interface name or sw_if_index\n");
4514       return -99;
4515     }
4516
4517   /* Construct the API message */
4518   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
4519
4520   mp->sw_if_index = ntohl (sw_if_index);
4521   mp->enable = is_enable;
4522
4523   /* send it... */
4524   S;
4525
4526   /* Wait for a reply... */
4527   W;
4528 }
4529
4530 static int
4531 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4532 {
4533   unformat_input_t *i = vam->input;
4534   vl_api_sw_interface_set_l2_xconnect_t *mp;
4535   f64 timeout;
4536   u32 rx_sw_if_index;
4537   u8 rx_sw_if_index_set = 0;
4538   u32 tx_sw_if_index;
4539   u8 tx_sw_if_index_set = 0;
4540   u8 enable = 1;
4541
4542   /* Parse args required to build the message */
4543   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4544     {
4545       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4546         rx_sw_if_index_set = 1;
4547       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4548         tx_sw_if_index_set = 1;
4549       else if (unformat (i, "rx"))
4550         {
4551           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4552             {
4553               if (unformat (i, "%U", unformat_sw_if_index, vam,
4554                             &rx_sw_if_index))
4555                 rx_sw_if_index_set = 1;
4556             }
4557           else
4558             break;
4559         }
4560       else if (unformat (i, "tx"))
4561         {
4562           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4563             {
4564               if (unformat (i, "%U", unformat_sw_if_index, vam,
4565                             &tx_sw_if_index))
4566                 tx_sw_if_index_set = 1;
4567             }
4568           else
4569             break;
4570         }
4571       else if (unformat (i, "enable"))
4572         enable = 1;
4573       else if (unformat (i, "disable"))
4574         enable = 0;
4575       else
4576         break;
4577     }
4578
4579   if (rx_sw_if_index_set == 0)
4580     {
4581       errmsg ("missing rx interface name or rx_sw_if_index\n");
4582       return -99;
4583     }
4584
4585   if (enable && (tx_sw_if_index_set == 0))
4586     {
4587       errmsg ("missing tx interface name or tx_sw_if_index\n");
4588       return -99;
4589     }
4590
4591   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
4592
4593   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4594   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4595   mp->enable = enable;
4596
4597   S;
4598   W;
4599   /* NOTREACHED */
4600   return 0;
4601 }
4602
4603 static int
4604 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4605 {
4606   unformat_input_t *i = vam->input;
4607   vl_api_sw_interface_set_l2_bridge_t *mp;
4608   f64 timeout;
4609   u32 rx_sw_if_index;
4610   u8 rx_sw_if_index_set = 0;
4611   u32 bd_id;
4612   u8 bd_id_set = 0;
4613   u8 bvi = 0;
4614   u32 shg = 0;
4615   u8 enable = 1;
4616
4617   /* Parse args required to build the message */
4618   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4619     {
4620       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4621         rx_sw_if_index_set = 1;
4622       else if (unformat (i, "bd_id %d", &bd_id))
4623         bd_id_set = 1;
4624       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
4625         rx_sw_if_index_set = 1;
4626       else if (unformat (i, "shg %d", &shg))
4627         ;
4628       else if (unformat (i, "bvi"))
4629         bvi = 1;
4630       else if (unformat (i, "enable"))
4631         enable = 1;
4632       else if (unformat (i, "disable"))
4633         enable = 0;
4634       else
4635         break;
4636     }
4637
4638   if (rx_sw_if_index_set == 0)
4639     {
4640       errmsg ("missing rx interface name or sw_if_index\n");
4641       return -99;
4642     }
4643
4644   if (enable && (bd_id_set == 0))
4645     {
4646       errmsg ("missing bridge domain\n");
4647       return -99;
4648     }
4649
4650   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
4651
4652   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4653   mp->bd_id = ntohl (bd_id);
4654   mp->shg = (u8) shg;
4655   mp->bvi = bvi;
4656   mp->enable = enable;
4657
4658   S;
4659   W;
4660   /* NOTREACHED */
4661   return 0;
4662 }
4663
4664 static int
4665 api_bridge_domain_dump (vat_main_t * vam)
4666 {
4667   unformat_input_t *i = vam->input;
4668   vl_api_bridge_domain_dump_t *mp;
4669   f64 timeout;
4670   u32 bd_id = ~0;
4671
4672   /* Parse args required to build the message */
4673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4674     {
4675       if (unformat (i, "bd_id %d", &bd_id))
4676         ;
4677       else
4678         break;
4679     }
4680
4681   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
4682   mp->bd_id = ntohl (bd_id);
4683   S;
4684
4685   /* Use a control ping for synchronization */
4686   {
4687     vl_api_control_ping_t *mp;
4688     M (CONTROL_PING, control_ping);
4689     S;
4690   }
4691
4692   W;
4693   /* NOTREACHED */
4694   return 0;
4695 }
4696
4697 static int
4698 api_bridge_domain_add_del (vat_main_t * vam)
4699 {
4700   unformat_input_t *i = vam->input;
4701   vl_api_bridge_domain_add_del_t *mp;
4702   f64 timeout;
4703   u32 bd_id = ~0;
4704   u8 is_add = 1;
4705   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4706
4707   /* Parse args required to build the message */
4708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4709     {
4710       if (unformat (i, "bd_id %d", &bd_id))
4711         ;
4712       else if (unformat (i, "flood %d", &flood))
4713         ;
4714       else if (unformat (i, "uu-flood %d", &uu_flood))
4715         ;
4716       else if (unformat (i, "forward %d", &forward))
4717         ;
4718       else if (unformat (i, "learn %d", &learn))
4719         ;
4720       else if (unformat (i, "arp-term %d", &arp_term))
4721         ;
4722       else if (unformat (i, "del"))
4723         {
4724           is_add = 0;
4725           flood = uu_flood = forward = learn = 0;
4726         }
4727       else
4728         break;
4729     }
4730
4731   if (bd_id == ~0)
4732     {
4733       errmsg ("missing bridge domain\n");
4734       return -99;
4735     }
4736
4737   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
4738
4739   mp->bd_id = ntohl (bd_id);
4740   mp->flood = flood;
4741   mp->uu_flood = uu_flood;
4742   mp->forward = forward;
4743   mp->learn = learn;
4744   mp->arp_term = arp_term;
4745   mp->is_add = is_add;
4746
4747   S;
4748   W;
4749   /* NOTREACHED */
4750   return 0;
4751 }
4752
4753 static int
4754 api_l2fib_add_del (vat_main_t * vam)
4755 {
4756   unformat_input_t *i = vam->input;
4757   vl_api_l2fib_add_del_t *mp;
4758   f64 timeout;
4759   u64 mac = 0;
4760   u8 mac_set = 0;
4761   u32 bd_id;
4762   u8 bd_id_set = 0;
4763   u32 sw_if_index;
4764   u8 sw_if_index_set = 0;
4765   u8 is_add = 1;
4766   u8 static_mac = 0;
4767   u8 filter_mac = 0;
4768   u8 bvi_mac = 0;
4769   int count = 1;
4770   f64 before = 0;
4771   int j;
4772
4773   /* Parse args required to build the message */
4774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4775     {
4776       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
4777         mac_set = 1;
4778       else if (unformat (i, "bd_id %d", &bd_id))
4779         bd_id_set = 1;
4780       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4781         sw_if_index_set = 1;
4782       else if (unformat (i, "sw_if"))
4783         {
4784           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4785             {
4786               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4787                 sw_if_index_set = 1;
4788             }
4789           else
4790             break;
4791         }
4792       else if (unformat (i, "static"))
4793         static_mac = 1;
4794       else if (unformat (i, "filter"))
4795         {
4796           filter_mac = 1;
4797           static_mac = 1;
4798         }
4799       else if (unformat (i, "bvi"))
4800         {
4801           bvi_mac = 1;
4802           static_mac = 1;
4803         }
4804       else if (unformat (i, "del"))
4805         is_add = 0;
4806       else if (unformat (i, "count %d", &count))
4807         ;
4808       else
4809         break;
4810     }
4811
4812   if (mac_set == 0)
4813     {
4814       errmsg ("missing mac address\n");
4815       return -99;
4816     }
4817
4818   if (bd_id_set == 0)
4819     {
4820       errmsg ("missing bridge domain\n");
4821       return -99;
4822     }
4823
4824   if (is_add && (sw_if_index_set == 0))
4825     {
4826       errmsg ("missing interface name or sw_if_index\n");
4827       return -99;
4828     }
4829
4830   if (count > 1)
4831     {
4832       /* Turn on async mode */
4833       vam->async_mode = 1;
4834       vam->async_errors = 0;
4835       before = vat_time_now (vam);
4836     }
4837
4838   for (j = 0; j < count; j++)
4839     {
4840       M (L2FIB_ADD_DEL, l2fib_add_del);
4841
4842       mp->mac = mac;
4843       mp->bd_id = ntohl (bd_id);
4844       mp->is_add = is_add;
4845
4846       if (is_add)
4847         {
4848           mp->sw_if_index = ntohl (sw_if_index);
4849           mp->static_mac = static_mac;
4850           mp->filter_mac = filter_mac;
4851           mp->bvi_mac = bvi_mac;
4852         }
4853       increment_mac_address (&mac);
4854       /* send it... */
4855       S;
4856     }
4857
4858   if (count > 1)
4859     {
4860       vl_api_control_ping_t *mp;
4861       f64 after;
4862
4863       /* Shut off async mode */
4864       vam->async_mode = 0;
4865
4866       M (CONTROL_PING, control_ping);
4867       S;
4868
4869       timeout = vat_time_now (vam) + 1.0;
4870       while (vat_time_now (vam) < timeout)
4871         if (vam->result_ready == 1)
4872           goto out;
4873       vam->retval = -99;
4874
4875     out:
4876       if (vam->retval == -99)
4877         errmsg ("timeout\n");
4878
4879       if (vam->async_errors > 0)
4880         {
4881           errmsg ("%d asynchronous errors\n", vam->async_errors);
4882           vam->retval = -98;
4883         }
4884       vam->async_errors = 0;
4885       after = vat_time_now (vam);
4886
4887       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
4888                count, after - before, count / (after - before));
4889     }
4890   else
4891     {
4892       /* Wait for a reply... */
4893       W;
4894     }
4895   /* Return the good/bad news */
4896   return (vam->retval);
4897 }
4898
4899 static int
4900 api_l2_flags (vat_main_t * vam)
4901 {
4902   unformat_input_t *i = vam->input;
4903   vl_api_l2_flags_t *mp;
4904   f64 timeout;
4905   u32 sw_if_index;
4906   u32 feature_bitmap = 0;
4907   u8 sw_if_index_set = 0;
4908
4909   /* Parse args required to build the message */
4910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4911     {
4912       if (unformat (i, "sw_if_index %d", &sw_if_index))
4913         sw_if_index_set = 1;
4914       else if (unformat (i, "sw_if"))
4915         {
4916           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4917             {
4918               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4919                 sw_if_index_set = 1;
4920             }
4921           else
4922             break;
4923         }
4924       else if (unformat (i, "learn"))
4925         feature_bitmap |= L2INPUT_FEAT_LEARN;
4926       else if (unformat (i, "forward"))
4927         feature_bitmap |= L2INPUT_FEAT_FWD;
4928       else if (unformat (i, "flood"))
4929         feature_bitmap |= L2INPUT_FEAT_FLOOD;
4930       else if (unformat (i, "uu-flood"))
4931         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
4932       else
4933         break;
4934     }
4935
4936   if (sw_if_index_set == 0)
4937     {
4938       errmsg ("missing interface name or sw_if_index\n");
4939       return -99;
4940     }
4941
4942   M (L2_FLAGS, l2_flags);
4943
4944   mp->sw_if_index = ntohl (sw_if_index);
4945   mp->feature_bitmap = ntohl (feature_bitmap);
4946
4947   S;
4948   W;
4949   /* NOTREACHED */
4950   return 0;
4951 }
4952
4953 static int
4954 api_bridge_flags (vat_main_t * vam)
4955 {
4956   unformat_input_t *i = vam->input;
4957   vl_api_bridge_flags_t *mp;
4958   f64 timeout;
4959   u32 bd_id;
4960   u8 bd_id_set = 0;
4961   u8 is_set = 1;
4962   u32 flags = 0;
4963
4964   /* Parse args required to build the message */
4965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4966     {
4967       if (unformat (i, "bd_id %d", &bd_id))
4968         bd_id_set = 1;
4969       else if (unformat (i, "learn"))
4970         flags |= L2_LEARN;
4971       else if (unformat (i, "forward"))
4972         flags |= L2_FWD;
4973       else if (unformat (i, "flood"))
4974         flags |= L2_FLOOD;
4975       else if (unformat (i, "uu-flood"))
4976         flags |= L2_UU_FLOOD;
4977       else if (unformat (i, "arp-term"))
4978         flags |= L2_ARP_TERM;
4979       else if (unformat (i, "off"))
4980         is_set = 0;
4981       else if (unformat (i, "disable"))
4982         is_set = 0;
4983       else
4984         break;
4985     }
4986
4987   if (bd_id_set == 0)
4988     {
4989       errmsg ("missing bridge domain\n");
4990       return -99;
4991     }
4992
4993   M (BRIDGE_FLAGS, bridge_flags);
4994
4995   mp->bd_id = ntohl (bd_id);
4996   mp->feature_bitmap = ntohl (flags);
4997   mp->is_set = is_set;
4998
4999   S;
5000   W;
5001   /* NOTREACHED */
5002   return 0;
5003 }
5004
5005 static int
5006 api_bd_ip_mac_add_del (vat_main_t * vam)
5007 {
5008   unformat_input_t *i = vam->input;
5009   vl_api_bd_ip_mac_add_del_t *mp;
5010   f64 timeout;
5011   u32 bd_id;
5012   u8 is_ipv6 = 0;
5013   u8 is_add = 1;
5014   u8 bd_id_set = 0;
5015   u8 ip_set = 0;
5016   u8 mac_set = 0;
5017   ip4_address_t v4addr;
5018   ip6_address_t v6addr;
5019   u8 macaddr[6];
5020
5021
5022   /* Parse args required to build the message */
5023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5024     {
5025       if (unformat (i, "bd_id %d", &bd_id))
5026         {
5027           bd_id_set++;
5028         }
5029       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5030         {
5031           ip_set++;
5032         }
5033       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5034         {
5035           ip_set++;
5036           is_ipv6++;
5037         }
5038       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5039         {
5040           mac_set++;
5041         }
5042       else if (unformat (i, "del"))
5043         is_add = 0;
5044       else
5045         break;
5046     }
5047
5048   if (bd_id_set == 0)
5049     {
5050       errmsg ("missing bridge domain\n");
5051       return -99;
5052     }
5053   else if (ip_set == 0)
5054     {
5055       errmsg ("missing IP address\n");
5056       return -99;
5057     }
5058   else if (mac_set == 0)
5059     {
5060       errmsg ("missing MAC address\n");
5061       return -99;
5062     }
5063
5064   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5065
5066   mp->bd_id = ntohl (bd_id);
5067   mp->is_ipv6 = is_ipv6;
5068   mp->is_add = is_add;
5069   if (is_ipv6)
5070     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5071   else
5072     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5073   clib_memcpy (mp->mac_address, macaddr, 6);
5074   S;
5075   W;
5076   /* NOTREACHED */
5077   return 0;
5078 }
5079
5080 static int
5081 api_tap_connect (vat_main_t * vam)
5082 {
5083   unformat_input_t *i = vam->input;
5084   vl_api_tap_connect_t *mp;
5085   f64 timeout;
5086   u8 mac_address[6];
5087   u8 random_mac = 1;
5088   u8 name_set = 0;
5089   u8 *tap_name;
5090
5091   memset (mac_address, 0, sizeof (mac_address));
5092
5093   /* Parse args required to build the message */
5094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5095     {
5096       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5097         {
5098           random_mac = 0;
5099         }
5100       else if (unformat (i, "random-mac"))
5101         random_mac = 1;
5102       else if (unformat (i, "tapname %s", &tap_name))
5103         name_set = 1;
5104       else
5105         break;
5106     }
5107
5108   if (name_set == 0)
5109     {
5110       errmsg ("missing tap name\n");
5111       return -99;
5112     }
5113   if (vec_len (tap_name) > 63)
5114     {
5115       errmsg ("tap name too long\n");
5116     }
5117   vec_add1 (tap_name, 0);
5118
5119   /* Construct the API message */
5120   M (TAP_CONNECT, tap_connect);
5121
5122   mp->use_random_mac = random_mac;
5123   clib_memcpy (mp->mac_address, mac_address, 6);
5124   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5125   vec_free (tap_name);
5126
5127   /* send it... */
5128   S;
5129
5130   /* Wait for a reply... */
5131   W;
5132 }
5133
5134 static int
5135 api_tap_modify (vat_main_t * vam)
5136 {
5137   unformat_input_t *i = vam->input;
5138   vl_api_tap_modify_t *mp;
5139   f64 timeout;
5140   u8 mac_address[6];
5141   u8 random_mac = 1;
5142   u8 name_set = 0;
5143   u8 *tap_name;
5144   u32 sw_if_index = ~0;
5145   u8 sw_if_index_set = 0;
5146
5147   memset (mac_address, 0, sizeof (mac_address));
5148
5149   /* Parse args required to build the message */
5150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5151     {
5152       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5153         sw_if_index_set = 1;
5154       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5155         sw_if_index_set = 1;
5156       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5157         {
5158           random_mac = 0;
5159         }
5160       else if (unformat (i, "random-mac"))
5161         random_mac = 1;
5162       else if (unformat (i, "tapname %s", &tap_name))
5163         name_set = 1;
5164       else
5165         break;
5166     }
5167
5168   if (sw_if_index_set == 0)
5169     {
5170       errmsg ("missing vpp interface name");
5171       return -99;
5172     }
5173   if (name_set == 0)
5174     {
5175       errmsg ("missing tap name\n");
5176       return -99;
5177     }
5178   if (vec_len (tap_name) > 63)
5179     {
5180       errmsg ("tap name too long\n");
5181     }
5182   vec_add1 (tap_name, 0);
5183
5184   /* Construct the API message */
5185   M (TAP_MODIFY, tap_modify);
5186
5187   mp->use_random_mac = random_mac;
5188   mp->sw_if_index = ntohl (sw_if_index);
5189   clib_memcpy (mp->mac_address, mac_address, 6);
5190   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5191   vec_free (tap_name);
5192
5193   /* send it... */
5194   S;
5195
5196   /* Wait for a reply... */
5197   W;
5198 }
5199
5200 static int
5201 api_tap_delete (vat_main_t * vam)
5202 {
5203   unformat_input_t *i = vam->input;
5204   vl_api_tap_delete_t *mp;
5205   f64 timeout;
5206   u32 sw_if_index = ~0;
5207   u8 sw_if_index_set = 0;
5208
5209   /* Parse args required to build the message */
5210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5211     {
5212       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5213         sw_if_index_set = 1;
5214       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5215         sw_if_index_set = 1;
5216       else
5217         break;
5218     }
5219
5220   if (sw_if_index_set == 0)
5221     {
5222       errmsg ("missing vpp interface name");
5223       return -99;
5224     }
5225
5226   /* Construct the API message */
5227   M (TAP_DELETE, tap_delete);
5228
5229   mp->sw_if_index = ntohl (sw_if_index);
5230
5231   /* send it... */
5232   S;
5233
5234   /* Wait for a reply... */
5235   W;
5236 }
5237
5238 static int
5239 api_ip_add_del_route (vat_main_t * vam)
5240 {
5241   unformat_input_t *i = vam->input;
5242   vl_api_ip_add_del_route_t *mp;
5243   f64 timeout;
5244   u32 sw_if_index = ~0, vrf_id = 0;
5245   u8 sw_if_index_set = 0;
5246   u8 is_ipv6 = 0;
5247   u8 is_local = 0, is_drop = 0;
5248   u8 create_vrf_if_needed = 0;
5249   u8 is_add = 1;
5250   u8 next_hop_weight = 1;
5251   u8 not_last = 0;
5252   u8 is_multipath = 0;
5253   u8 address_set = 0;
5254   u8 address_length_set = 0;
5255   u32 lookup_in_vrf = 0;
5256   u32 resolve_attempts = 0;
5257   u32 dst_address_length = 0;
5258   u8 next_hop_set = 0;
5259   ip4_address_t v4_dst_address, v4_next_hop_address;
5260   ip6_address_t v6_dst_address, v6_next_hop_address;
5261   int count = 1;
5262   int j;
5263   f64 before = 0;
5264   u32 random_add_del = 0;
5265   u32 *random_vector = 0;
5266   uword *random_hash;
5267   u32 random_seed = 0xdeaddabe;
5268   u32 classify_table_index = ~0;
5269   u8 is_classify = 0;
5270
5271   /* Parse args required to build the message */
5272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5273     {
5274       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5275         sw_if_index_set = 1;
5276       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5277         sw_if_index_set = 1;
5278       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5279         {
5280           address_set = 1;
5281           is_ipv6 = 0;
5282         }
5283       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5284         {
5285           address_set = 1;
5286           is_ipv6 = 1;
5287         }
5288       else if (unformat (i, "/%d", &dst_address_length))
5289         {
5290           address_length_set = 1;
5291         }
5292
5293       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5294                                          &v4_next_hop_address))
5295         {
5296           next_hop_set = 1;
5297         }
5298       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5299                                          &v6_next_hop_address))
5300         {
5301           next_hop_set = 1;
5302         }
5303       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5304         ;
5305       else if (unformat (i, "weight %d", &next_hop_weight))
5306         ;
5307       else if (unformat (i, "drop"))
5308         {
5309           is_drop = 1;
5310         }
5311       else if (unformat (i, "local"))
5312         {
5313           is_local = 1;
5314         }
5315       else if (unformat (i, "classify %d", &classify_table_index))
5316         {
5317           is_classify = 1;
5318         }
5319       else if (unformat (i, "del"))
5320         is_add = 0;
5321       else if (unformat (i, "add"))
5322         is_add = 1;
5323       else if (unformat (i, "not-last"))
5324         not_last = 1;
5325       else if (unformat (i, "multipath"))
5326         is_multipath = 1;
5327       else if (unformat (i, "vrf %d", &vrf_id))
5328         ;
5329       else if (unformat (i, "create-vrf"))
5330         create_vrf_if_needed = 1;
5331       else if (unformat (i, "count %d", &count))
5332         ;
5333       else if (unformat (i, "lookup-in-vrf %d", &lookup_in_vrf))
5334         ;
5335       else if (unformat (i, "random"))
5336         random_add_del = 1;
5337       else if (unformat (i, "seed %d", &random_seed))
5338         ;
5339       else
5340         {
5341           clib_warning ("parse error '%U'", format_unformat_error, i);
5342           return -99;
5343         }
5344     }
5345
5346   if (resolve_attempts > 0 && sw_if_index_set == 0)
5347     {
5348       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5349       return -99;
5350     }
5351
5352   if (!next_hop_set && !is_drop && !is_local && !is_classify)
5353     {
5354       errmsg ("next hop / local / drop / classify not set\n");
5355       return -99;
5356     }
5357
5358   if (address_set == 0)
5359     {
5360       errmsg ("missing addresses\n");
5361       return -99;
5362     }
5363
5364   if (address_length_set == 0)
5365     {
5366       errmsg ("missing address length\n");
5367       return -99;
5368     }
5369
5370   /* Generate a pile of unique, random routes */
5371   if (random_add_del)
5372     {
5373       u32 this_random_address;
5374       random_hash = hash_create (count, sizeof (uword));
5375
5376       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5377       for (j = 0; j <= count; j++)
5378         {
5379           do
5380             {
5381               this_random_address = random_u32 (&random_seed);
5382               this_random_address =
5383                 clib_host_to_net_u32 (this_random_address);
5384             }
5385           while (hash_get (random_hash, this_random_address));
5386           vec_add1 (random_vector, this_random_address);
5387           hash_set (random_hash, this_random_address, 1);
5388         }
5389       hash_free (random_hash);
5390       v4_dst_address.as_u32 = random_vector[0];
5391     }
5392
5393   if (count > 1)
5394     {
5395       /* Turn on async mode */
5396       vam->async_mode = 1;
5397       vam->async_errors = 0;
5398       before = vat_time_now (vam);
5399     }
5400
5401   for (j = 0; j < count; j++)
5402     {
5403       /* Construct the API message */
5404       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5405
5406       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5407       mp->vrf_id = ntohl (vrf_id);
5408       if (resolve_attempts > 0)
5409         {
5410           mp->resolve_attempts = ntohl (resolve_attempts);
5411           mp->resolve_if_needed = 1;
5412         }
5413       mp->create_vrf_if_needed = create_vrf_if_needed;
5414
5415       mp->is_add = is_add;
5416       mp->is_drop = is_drop;
5417       mp->is_ipv6 = is_ipv6;
5418       mp->is_local = is_local;
5419       mp->is_classify = is_classify;
5420       mp->is_multipath = is_multipath;
5421       mp->not_last = not_last;
5422       mp->next_hop_weight = next_hop_weight;
5423       mp->dst_address_length = dst_address_length;
5424       mp->lookup_in_vrf = ntohl (lookup_in_vrf);
5425       mp->classify_table_index = ntohl (classify_table_index);
5426
5427       if (is_ipv6)
5428         {
5429           clib_memcpy (mp->dst_address, &v6_dst_address,
5430                        sizeof (v6_dst_address));
5431           if (next_hop_set)
5432             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5433                          sizeof (v6_next_hop_address));
5434           increment_v6_address (&v6_dst_address);
5435         }
5436       else
5437         {
5438           clib_memcpy (mp->dst_address, &v4_dst_address,
5439                        sizeof (v4_dst_address));
5440           if (next_hop_set)
5441             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5442                          sizeof (v4_next_hop_address));
5443           if (random_add_del)
5444             v4_dst_address.as_u32 = random_vector[j + 1];
5445           else
5446             increment_v4_address (&v4_dst_address);
5447         }
5448       /* send it... */
5449       S;
5450     }
5451
5452   /* When testing multiple add/del ops, use a control-ping to sync */
5453   if (count > 1)
5454     {
5455       vl_api_control_ping_t *mp;
5456       f64 after;
5457
5458       /* Shut off async mode */
5459       vam->async_mode = 0;
5460
5461       M (CONTROL_PING, control_ping);
5462       S;
5463
5464       timeout = vat_time_now (vam) + 1.0;
5465       while (vat_time_now (vam) < timeout)
5466         if (vam->result_ready == 1)
5467           goto out;
5468       vam->retval = -99;
5469
5470     out:
5471       if (vam->retval == -99)
5472         errmsg ("timeout\n");
5473
5474       if (vam->async_errors > 0)
5475         {
5476           errmsg ("%d asynchronous errors\n", vam->async_errors);
5477           vam->retval = -98;
5478         }
5479       vam->async_errors = 0;
5480       after = vat_time_now (vam);
5481
5482       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5483                count, after - before, count / (after - before));
5484     }
5485   else
5486     {
5487       /* Wait for a reply... */
5488       W;
5489     }
5490
5491   /* Return the good/bad news */
5492   return (vam->retval);
5493 }
5494
5495 static int
5496 api_proxy_arp_add_del (vat_main_t * vam)
5497 {
5498   unformat_input_t *i = vam->input;
5499   vl_api_proxy_arp_add_del_t *mp;
5500   f64 timeout;
5501   u32 vrf_id = 0;
5502   u8 is_add = 1;
5503   ip4_address_t lo, hi;
5504   u8 range_set = 0;
5505
5506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5507     {
5508       if (unformat (i, "vrf %d", &vrf_id))
5509         ;
5510       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
5511                          unformat_ip4_address, &hi))
5512         range_set = 1;
5513       else if (unformat (i, "del"))
5514         is_add = 0;
5515       else
5516         {
5517           clib_warning ("parse error '%U'", format_unformat_error, i);
5518           return -99;
5519         }
5520     }
5521
5522   if (range_set == 0)
5523     {
5524       errmsg ("address range not set\n");
5525       return -99;
5526     }
5527
5528   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
5529
5530   mp->vrf_id = ntohl (vrf_id);
5531   mp->is_add = is_add;
5532   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
5533   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
5534
5535   S;
5536   W;
5537   /* NOTREACHED */
5538   return 0;
5539 }
5540
5541 static int
5542 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
5543 {
5544   unformat_input_t *i = vam->input;
5545   vl_api_proxy_arp_intfc_enable_disable_t *mp;
5546   f64 timeout;
5547   u32 sw_if_index;
5548   u8 enable = 1;
5549   u8 sw_if_index_set = 0;
5550
5551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5552     {
5553       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5554         sw_if_index_set = 1;
5555       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5556         sw_if_index_set = 1;
5557       else if (unformat (i, "enable"))
5558         enable = 1;
5559       else if (unformat (i, "disable"))
5560         enable = 0;
5561       else
5562         {
5563           clib_warning ("parse error '%U'", format_unformat_error, i);
5564           return -99;
5565         }
5566     }
5567
5568   if (sw_if_index_set == 0)
5569     {
5570       errmsg ("missing interface name or sw_if_index\n");
5571       return -99;
5572     }
5573
5574   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
5575
5576   mp->sw_if_index = ntohl (sw_if_index);
5577   mp->enable_disable = enable;
5578
5579   S;
5580   W;
5581   /* NOTREACHED */
5582   return 0;
5583 }
5584
5585 static int
5586 api_mpls_add_del_decap (vat_main_t * vam)
5587 {
5588   unformat_input_t *i = vam->input;
5589   vl_api_mpls_add_del_decap_t *mp;
5590   f64 timeout;
5591   u32 rx_vrf_id = 0;
5592   u32 tx_vrf_id = 0;
5593   u32 label = 0;
5594   u8 is_add = 1;
5595   u8 s_bit = 1;
5596   u32 next_index = 1;
5597
5598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5599     {
5600       if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
5601         ;
5602       else if (unformat (i, "tx_vrf_id %d", &tx_vrf_id))
5603         ;
5604       else if (unformat (i, "label %d", &label))
5605         ;
5606       else if (unformat (i, "next-index %d", &next_index))
5607         ;
5608       else if (unformat (i, "del"))
5609         is_add = 0;
5610       else if (unformat (i, "s-bit-clear"))
5611         s_bit = 0;
5612       else
5613         {
5614           clib_warning ("parse error '%U'", format_unformat_error, i);
5615           return -99;
5616         }
5617     }
5618
5619   M (MPLS_ADD_DEL_DECAP, mpls_add_del_decap);
5620
5621   mp->rx_vrf_id = ntohl (rx_vrf_id);
5622   mp->tx_vrf_id = ntohl (tx_vrf_id);
5623   mp->label = ntohl (label);
5624   mp->next_index = ntohl (next_index);
5625   mp->s_bit = s_bit;
5626   mp->is_add = is_add;
5627
5628   S;
5629   W;
5630   /* NOTREACHED */
5631   return 0;
5632 }
5633
5634 static int
5635 api_mpls_add_del_encap (vat_main_t * vam)
5636 {
5637   unformat_input_t *i = vam->input;
5638   vl_api_mpls_add_del_encap_t *mp;
5639   f64 timeout;
5640   u32 vrf_id = 0;
5641   u32 *labels = 0;
5642   u32 label;
5643   ip4_address_t dst_address;
5644   u8 is_add = 1;
5645
5646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5647     {
5648       if (unformat (i, "vrf %d", &vrf_id))
5649         ;
5650       else if (unformat (i, "label %d", &label))
5651         vec_add1 (labels, ntohl (label));
5652       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5653         ;
5654       else if (unformat (i, "del"))
5655         is_add = 0;
5656       else
5657         {
5658           clib_warning ("parse error '%U'", format_unformat_error, i);
5659           return -99;
5660         }
5661     }
5662
5663   if (vec_len (labels) == 0)
5664     {
5665       errmsg ("missing encap label stack\n");
5666       return -99;
5667     }
5668
5669   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
5670       sizeof (u32) * vec_len (labels));
5671
5672   mp->vrf_id = ntohl (vrf_id);
5673   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5674   mp->is_add = is_add;
5675   mp->nlabels = vec_len (labels);
5676   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
5677
5678   vec_free (labels);
5679
5680   S;
5681   W;
5682   /* NOTREACHED */
5683   return 0;
5684 }
5685
5686 static int
5687 api_mpls_gre_add_del_tunnel (vat_main_t * vam)
5688 {
5689   unformat_input_t *i = vam->input;
5690   vl_api_mpls_gre_add_del_tunnel_t *mp;
5691   f64 timeout;
5692   u32 inner_vrf_id = 0;
5693   u32 outer_vrf_id = 0;
5694   ip4_address_t src_address;
5695   ip4_address_t dst_address;
5696   ip4_address_t intfc_address;
5697   u32 tmp;
5698   u8 intfc_address_length = 0;
5699   u8 is_add = 1;
5700   u8 l2_only = 0;
5701
5702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5703     {
5704       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5705         ;
5706       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5707         ;
5708       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
5709         ;
5710       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
5711         ;
5712       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5713                          &intfc_address, &tmp))
5714         intfc_address_length = tmp;
5715       else if (unformat (i, "l2-only"))
5716         l2_only = 1;
5717       else if (unformat (i, "del"))
5718         is_add = 0;
5719       else
5720         {
5721           clib_warning ("parse error '%U'", format_unformat_error, i);
5722           return -99;
5723         }
5724     }
5725
5726   M (MPLS_GRE_ADD_DEL_TUNNEL, mpls_gre_add_del_tunnel);
5727
5728   mp->inner_vrf_id = ntohl (inner_vrf_id);
5729   mp->outer_vrf_id = ntohl (outer_vrf_id);
5730   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
5731   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
5732   clib_memcpy (mp->intfc_address, &intfc_address, sizeof (intfc_address));
5733   mp->intfc_address_length = intfc_address_length;
5734   mp->l2_only = l2_only;
5735   mp->is_add = is_add;
5736
5737   S;
5738   W;
5739   /* NOTREACHED */
5740   return 0;
5741 }
5742
5743 static int
5744 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
5745 {
5746   unformat_input_t *i = vam->input;
5747   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
5748   f64 timeout;
5749   u32 inner_vrf_id = 0;
5750   ip4_address_t intfc_address;
5751   u8 dst_mac_address[6];
5752   int dst_set = 1;
5753   u32 tmp;
5754   u8 intfc_address_length = 0;
5755   u8 is_add = 1;
5756   u8 l2_only = 0;
5757   u32 tx_sw_if_index;
5758   int tx_sw_if_index_set = 0;
5759
5760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5761     {
5762       if (unformat (i, "vrf %d", &inner_vrf_id))
5763         ;
5764       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5765                          &intfc_address, &tmp))
5766         intfc_address_length = tmp;
5767       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
5768         tx_sw_if_index_set = 1;
5769       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5770         tx_sw_if_index_set = 1;
5771       else if (unformat (i, "dst %U", unformat_ethernet_address,
5772                          dst_mac_address))
5773         dst_set = 1;
5774       else if (unformat (i, "l2-only"))
5775         l2_only = 1;
5776       else if (unformat (i, "del"))
5777         is_add = 0;
5778       else
5779         {
5780           clib_warning ("parse error '%U'", format_unformat_error, i);
5781           return -99;
5782         }
5783     }
5784
5785   if (!dst_set)
5786     {
5787       errmsg ("dst (mac address) not set\n");
5788       return -99;
5789     }
5790   if (!tx_sw_if_index_set)
5791     {
5792       errmsg ("tx-intfc not set\n");
5793       return -99;
5794     }
5795
5796   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
5797
5798   mp->vrf_id = ntohl (inner_vrf_id);
5799   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
5800   mp->adj_address_length = intfc_address_length;
5801   clib_memcpy (mp->dst_mac_address, dst_mac_address,
5802                sizeof (dst_mac_address));
5803   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5804   mp->l2_only = l2_only;
5805   mp->is_add = is_add;
5806
5807   S;
5808   W;
5809   /* NOTREACHED */
5810   return 0;
5811 }
5812
5813 static int
5814 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
5815 {
5816   unformat_input_t *i = vam->input;
5817   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
5818   f64 timeout;
5819   u32 inner_vrf_id = 0;
5820   u32 outer_vrf_id = 0;
5821   ip4_address_t adj_address;
5822   int adj_address_set = 0;
5823   ip4_address_t next_hop_address;
5824   int next_hop_address_set = 0;
5825   u32 tmp;
5826   u8 adj_address_length = 0;
5827   u8 l2_only = 0;
5828   u8 is_add = 1;
5829   u32 resolve_attempts = 5;
5830   u8 resolve_if_needed = 1;
5831
5832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5833     {
5834       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
5835         ;
5836       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
5837         ;
5838       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
5839                          &adj_address, &tmp))
5840         {
5841           adj_address_length = tmp;
5842           adj_address_set = 1;
5843         }
5844       else if (unformat (i, "next-hop %U", unformat_ip4_address,
5845                          &next_hop_address))
5846         next_hop_address_set = 1;
5847       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5848         ;
5849       else if (unformat (i, "resolve-if-needed %d", &tmp))
5850         resolve_if_needed = tmp;
5851       else if (unformat (i, "l2-only"))
5852         l2_only = 1;
5853       else if (unformat (i, "del"))
5854         is_add = 0;
5855       else
5856         {
5857           clib_warning ("parse error '%U'", format_unformat_error, i);
5858           return -99;
5859         }
5860     }
5861
5862   if (!adj_address_set)
5863     {
5864       errmsg ("adjacency address/mask not set\n");
5865       return -99;
5866     }
5867   if (!next_hop_address_set)
5868     {
5869       errmsg ("ip4 next hop address (in outer fib) not set\n");
5870       return -99;
5871     }
5872
5873   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
5874
5875   mp->inner_vrf_id = ntohl (inner_vrf_id);
5876   mp->outer_vrf_id = ntohl (outer_vrf_id);
5877   mp->resolve_attempts = ntohl (resolve_attempts);
5878   mp->resolve_if_needed = resolve_if_needed;
5879   mp->is_add = is_add;
5880   mp->l2_only = l2_only;
5881   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
5882   mp->adj_address_length = adj_address_length;
5883   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
5884                sizeof (next_hop_address));
5885
5886   S;
5887   W;
5888   /* NOTREACHED */
5889   return 0;
5890 }
5891
5892 static int
5893 api_sw_interface_set_unnumbered (vat_main_t * vam)
5894 {
5895   unformat_input_t *i = vam->input;
5896   vl_api_sw_interface_set_unnumbered_t *mp;
5897   f64 timeout;
5898   u32 sw_if_index;
5899   u32 unnum_sw_index = ~0;
5900   u8 is_add = 1;
5901   u8 sw_if_index_set = 0;
5902
5903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5904     {
5905       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5906         sw_if_index_set = 1;
5907       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5908         sw_if_index_set = 1;
5909       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
5910         ;
5911       else if (unformat (i, "del"))
5912         is_add = 0;
5913       else
5914         {
5915           clib_warning ("parse error '%U'", format_unformat_error, i);
5916           return -99;
5917         }
5918     }
5919
5920   if (sw_if_index_set == 0)
5921     {
5922       errmsg ("missing interface name or sw_if_index\n");
5923       return -99;
5924     }
5925
5926   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
5927
5928   mp->sw_if_index = ntohl (sw_if_index);
5929   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
5930   mp->is_add = is_add;
5931
5932   S;
5933   W;
5934   /* NOTREACHED */
5935   return 0;
5936 }
5937
5938 static int
5939 api_ip_neighbor_add_del (vat_main_t * vam)
5940 {
5941   unformat_input_t *i = vam->input;
5942   vl_api_ip_neighbor_add_del_t *mp;
5943   f64 timeout;
5944   u32 sw_if_index;
5945   u8 sw_if_index_set = 0;
5946   u32 vrf_id = 0;
5947   u8 is_add = 1;
5948   u8 is_static = 0;
5949   u8 mac_address[6];
5950   u8 mac_set = 0;
5951   u8 v4_address_set = 0;
5952   u8 v6_address_set = 0;
5953   ip4_address_t v4address;
5954   ip6_address_t v6address;
5955
5956   memset (mac_address, 0, sizeof (mac_address));
5957
5958   /* Parse args required to build the message */
5959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5960     {
5961       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5962         {
5963           mac_set = 1;
5964         }
5965       else if (unformat (i, "del"))
5966         is_add = 0;
5967       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5968         sw_if_index_set = 1;
5969       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5970         sw_if_index_set = 1;
5971       else if (unformat (i, "is_static"))
5972         is_static = 1;
5973       else if (unformat (i, "vrf %d", &vrf_id))
5974         ;
5975       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
5976         v4_address_set = 1;
5977       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
5978         v6_address_set = 1;
5979       else
5980         {
5981           clib_warning ("parse error '%U'", format_unformat_error, i);
5982           return -99;
5983         }
5984     }
5985
5986   if (sw_if_index_set == 0)
5987     {
5988       errmsg ("missing interface name or sw_if_index\n");
5989       return -99;
5990     }
5991   if (v4_address_set && v6_address_set)
5992     {
5993       errmsg ("both v4 and v6 addresses set\n");
5994       return -99;
5995     }
5996   if (!v4_address_set && !v6_address_set)
5997     {
5998       errmsg ("no address set\n");
5999       return -99;
6000     }
6001
6002   /* Construct the API message */
6003   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6004
6005   mp->sw_if_index = ntohl (sw_if_index);
6006   mp->is_add = is_add;
6007   mp->vrf_id = ntohl (vrf_id);
6008   mp->is_static = is_static;
6009   if (mac_set)
6010     clib_memcpy (mp->mac_address, mac_address, 6);
6011   if (v6_address_set)
6012     {
6013       mp->is_ipv6 = 1;
6014       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6015     }
6016   else
6017     {
6018       /* mp->is_ipv6 = 0; via memset in M macro above */
6019       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6020     }
6021
6022   /* send it... */
6023   S;
6024
6025   /* Wait for a reply, return good/bad news  */
6026   W;
6027
6028   /* NOTREACHED */
6029   return 0;
6030 }
6031
6032 static int
6033 api_reset_vrf (vat_main_t * vam)
6034 {
6035   unformat_input_t *i = vam->input;
6036   vl_api_reset_vrf_t *mp;
6037   f64 timeout;
6038   u32 vrf_id = 0;
6039   u8 is_ipv6 = 0;
6040   u8 vrf_id_set = 0;
6041
6042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6043     {
6044       if (unformat (i, "vrf %d", &vrf_id))
6045         vrf_id_set = 1;
6046       else if (unformat (i, "ipv6"))
6047         is_ipv6 = 1;
6048       else
6049         {
6050           clib_warning ("parse error '%U'", format_unformat_error, i);
6051           return -99;
6052         }
6053     }
6054
6055   if (vrf_id_set == 0)
6056     {
6057       errmsg ("missing vrf id\n");
6058       return -99;
6059     }
6060
6061   M (RESET_VRF, reset_vrf);
6062
6063   mp->vrf_id = ntohl (vrf_id);
6064   mp->is_ipv6 = is_ipv6;
6065
6066   S;
6067   W;
6068   /* NOTREACHED */
6069   return 0;
6070 }
6071
6072 static int
6073 api_create_vlan_subif (vat_main_t * vam)
6074 {
6075   unformat_input_t *i = vam->input;
6076   vl_api_create_vlan_subif_t *mp;
6077   f64 timeout;
6078   u32 sw_if_index;
6079   u8 sw_if_index_set = 0;
6080   u32 vlan_id;
6081   u8 vlan_id_set = 0;
6082
6083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6084     {
6085       if (unformat (i, "sw_if_index %d", &sw_if_index))
6086         sw_if_index_set = 1;
6087       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6088         sw_if_index_set = 1;
6089       else if (unformat (i, "vlan %d", &vlan_id))
6090         vlan_id_set = 1;
6091       else
6092         {
6093           clib_warning ("parse error '%U'", format_unformat_error, i);
6094           return -99;
6095         }
6096     }
6097
6098   if (sw_if_index_set == 0)
6099     {
6100       errmsg ("missing interface name or sw_if_index\n");
6101       return -99;
6102     }
6103
6104   if (vlan_id_set == 0)
6105     {
6106       errmsg ("missing vlan_id\n");
6107       return -99;
6108     }
6109   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6110
6111   mp->sw_if_index = ntohl (sw_if_index);
6112   mp->vlan_id = ntohl (vlan_id);
6113
6114   S;
6115   W;
6116   /* NOTREACHED */
6117   return 0;
6118 }
6119
6120 #define foreach_create_subif_bit                \
6121 _(no_tags)                                      \
6122 _(one_tag)                                      \
6123 _(two_tags)                                     \
6124 _(dot1ad)                                       \
6125 _(exact_match)                                  \
6126 _(default_sub)                                  \
6127 _(outer_vlan_id_any)                            \
6128 _(inner_vlan_id_any)
6129
6130 static int
6131 api_create_subif (vat_main_t * vam)
6132 {
6133   unformat_input_t *i = vam->input;
6134   vl_api_create_subif_t *mp;
6135   f64 timeout;
6136   u32 sw_if_index;
6137   u8 sw_if_index_set = 0;
6138   u32 sub_id;
6139   u8 sub_id_set = 0;
6140   u32 no_tags = 0;
6141   u32 one_tag = 0;
6142   u32 two_tags = 0;
6143   u32 dot1ad = 0;
6144   u32 exact_match = 0;
6145   u32 default_sub = 0;
6146   u32 outer_vlan_id_any = 0;
6147   u32 inner_vlan_id_any = 0;
6148   u32 tmp;
6149   u16 outer_vlan_id = 0;
6150   u16 inner_vlan_id = 0;
6151
6152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6153     {
6154       if (unformat (i, "sw_if_index %d", &sw_if_index))
6155         sw_if_index_set = 1;
6156       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6157         sw_if_index_set = 1;
6158       else if (unformat (i, "sub_id %d", &sub_id))
6159         sub_id_set = 1;
6160       else if (unformat (i, "outer_vlan_id %d", &tmp))
6161         outer_vlan_id = tmp;
6162       else if (unformat (i, "inner_vlan_id %d", &tmp))
6163         inner_vlan_id = tmp;
6164
6165 #define _(a) else if (unformat (i, #a)) a = 1 ;
6166       foreach_create_subif_bit
6167 #undef _
6168         else
6169         {
6170           clib_warning ("parse error '%U'", format_unformat_error, i);
6171           return -99;
6172         }
6173     }
6174
6175   if (sw_if_index_set == 0)
6176     {
6177       errmsg ("missing interface name or sw_if_index\n");
6178       return -99;
6179     }
6180
6181   if (sub_id_set == 0)
6182     {
6183       errmsg ("missing sub_id\n");
6184       return -99;
6185     }
6186   M (CREATE_SUBIF, create_subif);
6187
6188   mp->sw_if_index = ntohl (sw_if_index);
6189   mp->sub_id = ntohl (sub_id);
6190
6191 #define _(a) mp->a = a;
6192   foreach_create_subif_bit;
6193 #undef _
6194
6195   mp->outer_vlan_id = ntohs (outer_vlan_id);
6196   mp->inner_vlan_id = ntohs (inner_vlan_id);
6197
6198   S;
6199   W;
6200   /* NOTREACHED */
6201   return 0;
6202 }
6203
6204 static int
6205 api_oam_add_del (vat_main_t * vam)
6206 {
6207   unformat_input_t *i = vam->input;
6208   vl_api_oam_add_del_t *mp;
6209   f64 timeout;
6210   u32 vrf_id = 0;
6211   u8 is_add = 1;
6212   ip4_address_t src, dst;
6213   u8 src_set = 0;
6214   u8 dst_set = 0;
6215
6216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6217     {
6218       if (unformat (i, "vrf %d", &vrf_id))
6219         ;
6220       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6221         src_set = 1;
6222       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6223         dst_set = 1;
6224       else if (unformat (i, "del"))
6225         is_add = 0;
6226       else
6227         {
6228           clib_warning ("parse error '%U'", format_unformat_error, i);
6229           return -99;
6230         }
6231     }
6232
6233   if (src_set == 0)
6234     {
6235       errmsg ("missing src addr\n");
6236       return -99;
6237     }
6238
6239   if (dst_set == 0)
6240     {
6241       errmsg ("missing dst addr\n");
6242       return -99;
6243     }
6244
6245   M (OAM_ADD_DEL, oam_add_del);
6246
6247   mp->vrf_id = ntohl (vrf_id);
6248   mp->is_add = is_add;
6249   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6250   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6251
6252   S;
6253   W;
6254   /* NOTREACHED */
6255   return 0;
6256 }
6257
6258 static int
6259 api_reset_fib (vat_main_t * vam)
6260 {
6261   unformat_input_t *i = vam->input;
6262   vl_api_reset_fib_t *mp;
6263   f64 timeout;
6264   u32 vrf_id = 0;
6265   u8 is_ipv6 = 0;
6266   u8 vrf_id_set = 0;
6267
6268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6269     {
6270       if (unformat (i, "vrf %d", &vrf_id))
6271         vrf_id_set = 1;
6272       else if (unformat (i, "ipv6"))
6273         is_ipv6 = 1;
6274       else
6275         {
6276           clib_warning ("parse error '%U'", format_unformat_error, i);
6277           return -99;
6278         }
6279     }
6280
6281   if (vrf_id_set == 0)
6282     {
6283       errmsg ("missing vrf id\n");
6284       return -99;
6285     }
6286
6287   M (RESET_FIB, reset_fib);
6288
6289   mp->vrf_id = ntohl (vrf_id);
6290   mp->is_ipv6 = is_ipv6;
6291
6292   S;
6293   W;
6294   /* NOTREACHED */
6295   return 0;
6296 }
6297
6298 static int
6299 api_dhcp_proxy_config (vat_main_t * vam)
6300 {
6301   unformat_input_t *i = vam->input;
6302   vl_api_dhcp_proxy_config_t *mp;
6303   f64 timeout;
6304   u32 vrf_id = 0;
6305   u8 is_add = 1;
6306   u8 insert_cid = 1;
6307   u8 v4_address_set = 0;
6308   u8 v6_address_set = 0;
6309   ip4_address_t v4address;
6310   ip6_address_t v6address;
6311   u8 v4_src_address_set = 0;
6312   u8 v6_src_address_set = 0;
6313   ip4_address_t v4srcaddress;
6314   ip6_address_t v6srcaddress;
6315
6316   /* Parse args required to build the message */
6317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6318     {
6319       if (unformat (i, "del"))
6320         is_add = 0;
6321       else if (unformat (i, "vrf %d", &vrf_id))
6322         ;
6323       else if (unformat (i, "insert-cid %d", &insert_cid))
6324         ;
6325       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6326         v4_address_set = 1;
6327       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6328         v6_address_set = 1;
6329       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6330         v4_src_address_set = 1;
6331       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6332         v6_src_address_set = 1;
6333       else
6334         break;
6335     }
6336
6337   if (v4_address_set && v6_address_set)
6338     {
6339       errmsg ("both v4 and v6 server addresses set\n");
6340       return -99;
6341     }
6342   if (!v4_address_set && !v6_address_set)
6343     {
6344       errmsg ("no server addresses set\n");
6345       return -99;
6346     }
6347
6348   if (v4_src_address_set && v6_src_address_set)
6349     {
6350       errmsg ("both v4 and v6  src addresses set\n");
6351       return -99;
6352     }
6353   if (!v4_src_address_set && !v6_src_address_set)
6354     {
6355       errmsg ("no src addresses set\n");
6356       return -99;
6357     }
6358
6359   if (!(v4_src_address_set && v4_address_set) &&
6360       !(v6_src_address_set && v6_address_set))
6361     {
6362       errmsg ("no matching server and src addresses set\n");
6363       return -99;
6364     }
6365
6366   /* Construct the API message */
6367   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
6368
6369   mp->insert_circuit_id = insert_cid;
6370   mp->is_add = is_add;
6371   mp->vrf_id = ntohl (vrf_id);
6372   if (v6_address_set)
6373     {
6374       mp->is_ipv6 = 1;
6375       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6376       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6377     }
6378   else
6379     {
6380       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6381       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6382     }
6383
6384   /* send it... */
6385   S;
6386
6387   /* Wait for a reply, return good/bad news  */
6388   W;
6389   /* NOTREACHED */
6390   return 0;
6391 }
6392
6393 static int
6394 api_dhcp_proxy_config_2 (vat_main_t * vam)
6395 {
6396   unformat_input_t *i = vam->input;
6397   vl_api_dhcp_proxy_config_2_t *mp;
6398   f64 timeout;
6399   u32 rx_vrf_id = 0;
6400   u32 server_vrf_id = 0;
6401   u8 is_add = 1;
6402   u8 insert_cid = 1;
6403   u8 v4_address_set = 0;
6404   u8 v6_address_set = 0;
6405   ip4_address_t v4address;
6406   ip6_address_t v6address;
6407   u8 v4_src_address_set = 0;
6408   u8 v6_src_address_set = 0;
6409   ip4_address_t v4srcaddress;
6410   ip6_address_t v6srcaddress;
6411
6412   /* Parse args required to build the message */
6413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6414     {
6415       if (unformat (i, "del"))
6416         is_add = 0;
6417       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
6418         ;
6419       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
6420         ;
6421       else if (unformat (i, "insert-cid %d", &insert_cid))
6422         ;
6423       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
6424         v4_address_set = 1;
6425       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
6426         v6_address_set = 1;
6427       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
6428         v4_src_address_set = 1;
6429       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
6430         v6_src_address_set = 1;
6431       else
6432         break;
6433     }
6434
6435   if (v4_address_set && v6_address_set)
6436     {
6437       errmsg ("both v4 and v6 server addresses set\n");
6438       return -99;
6439     }
6440   if (!v4_address_set && !v6_address_set)
6441     {
6442       errmsg ("no server addresses set\n");
6443       return -99;
6444     }
6445
6446   if (v4_src_address_set && v6_src_address_set)
6447     {
6448       errmsg ("both v4 and v6  src addresses set\n");
6449       return -99;
6450     }
6451   if (!v4_src_address_set && !v6_src_address_set)
6452     {
6453       errmsg ("no src addresses set\n");
6454       return -99;
6455     }
6456
6457   if (!(v4_src_address_set && v4_address_set) &&
6458       !(v6_src_address_set && v6_address_set))
6459     {
6460       errmsg ("no matching server and src addresses set\n");
6461       return -99;
6462     }
6463
6464   /* Construct the API message */
6465   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
6466
6467   mp->insert_circuit_id = insert_cid;
6468   mp->is_add = is_add;
6469   mp->rx_vrf_id = ntohl (rx_vrf_id);
6470   mp->server_vrf_id = ntohl (server_vrf_id);
6471   if (v6_address_set)
6472     {
6473       mp->is_ipv6 = 1;
6474       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
6475       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
6476     }
6477   else
6478     {
6479       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
6480       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
6481     }
6482
6483   /* send it... */
6484   S;
6485
6486   /* Wait for a reply, return good/bad news  */
6487   W;
6488   /* NOTREACHED */
6489   return 0;
6490 }
6491
6492 static int
6493 api_dhcp_proxy_set_vss (vat_main_t * vam)
6494 {
6495   unformat_input_t *i = vam->input;
6496   vl_api_dhcp_proxy_set_vss_t *mp;
6497   f64 timeout;
6498   u8 is_ipv6 = 0;
6499   u8 is_add = 1;
6500   u32 tbl_id;
6501   u8 tbl_id_set = 0;
6502   u32 oui;
6503   u8 oui_set = 0;
6504   u32 fib_id;
6505   u8 fib_id_set = 0;
6506
6507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6508     {
6509       if (unformat (i, "tbl_id %d", &tbl_id))
6510         tbl_id_set = 1;
6511       if (unformat (i, "fib_id %d", &fib_id))
6512         fib_id_set = 1;
6513       if (unformat (i, "oui %d", &oui))
6514         oui_set = 1;
6515       else if (unformat (i, "ipv6"))
6516         is_ipv6 = 1;
6517       else if (unformat (i, "del"))
6518         is_add = 0;
6519       else
6520         {
6521           clib_warning ("parse error '%U'", format_unformat_error, i);
6522           return -99;
6523         }
6524     }
6525
6526   if (tbl_id_set == 0)
6527     {
6528       errmsg ("missing tbl id\n");
6529       return -99;
6530     }
6531
6532   if (fib_id_set == 0)
6533     {
6534       errmsg ("missing fib id\n");
6535       return -99;
6536     }
6537   if (oui_set == 0)
6538     {
6539       errmsg ("missing oui\n");
6540       return -99;
6541     }
6542
6543   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
6544   mp->tbl_id = ntohl (tbl_id);
6545   mp->fib_id = ntohl (fib_id);
6546   mp->oui = ntohl (oui);
6547   mp->is_ipv6 = is_ipv6;
6548   mp->is_add = is_add;
6549
6550   S;
6551   W;
6552   /* NOTREACHED */
6553   return 0;
6554 }
6555
6556 static int
6557 api_dhcp_client_config (vat_main_t * vam)
6558 {
6559   unformat_input_t *i = vam->input;
6560   vl_api_dhcp_client_config_t *mp;
6561   f64 timeout;
6562   u32 sw_if_index;
6563   u8 sw_if_index_set = 0;
6564   u8 is_add = 1;
6565   u8 *hostname = 0;
6566   u8 disable_event = 0;
6567
6568   /* Parse args required to build the message */
6569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6570     {
6571       if (unformat (i, "del"))
6572         is_add = 0;
6573       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6574         sw_if_index_set = 1;
6575       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6576         sw_if_index_set = 1;
6577       else if (unformat (i, "hostname %s", &hostname))
6578         ;
6579       else if (unformat (i, "disable_event"))
6580         disable_event = 1;
6581       else
6582         break;
6583     }
6584
6585   if (sw_if_index_set == 0)
6586     {
6587       errmsg ("missing interface name or sw_if_index\n");
6588       return -99;
6589     }
6590
6591   if (vec_len (hostname) > 63)
6592     {
6593       errmsg ("hostname too long\n");
6594     }
6595   vec_add1 (hostname, 0);
6596
6597   /* Construct the API message */
6598   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
6599
6600   mp->sw_if_index = ntohl (sw_if_index);
6601   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
6602   vec_free (hostname);
6603   mp->is_add = is_add;
6604   mp->want_dhcp_event = disable_event ? 0 : 1;
6605   mp->pid = getpid ();
6606
6607   /* send it... */
6608   S;
6609
6610   /* Wait for a reply, return good/bad news  */
6611   W;
6612   /* NOTREACHED */
6613   return 0;
6614 }
6615
6616 static int
6617 api_set_ip_flow_hash (vat_main_t * vam)
6618 {
6619   unformat_input_t *i = vam->input;
6620   vl_api_set_ip_flow_hash_t *mp;
6621   f64 timeout;
6622   u32 vrf_id = 0;
6623   u8 is_ipv6 = 0;
6624   u8 vrf_id_set = 0;
6625   u8 src = 0;
6626   u8 dst = 0;
6627   u8 sport = 0;
6628   u8 dport = 0;
6629   u8 proto = 0;
6630   u8 reverse = 0;
6631
6632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6633     {
6634       if (unformat (i, "vrf %d", &vrf_id))
6635         vrf_id_set = 1;
6636       else if (unformat (i, "ipv6"))
6637         is_ipv6 = 1;
6638       else if (unformat (i, "src"))
6639         src = 1;
6640       else if (unformat (i, "dst"))
6641         dst = 1;
6642       else if (unformat (i, "sport"))
6643         sport = 1;
6644       else if (unformat (i, "dport"))
6645         dport = 1;
6646       else if (unformat (i, "proto"))
6647         proto = 1;
6648       else if (unformat (i, "reverse"))
6649         reverse = 1;
6650
6651       else
6652         {
6653           clib_warning ("parse error '%U'", format_unformat_error, i);
6654           return -99;
6655         }
6656     }
6657
6658   if (vrf_id_set == 0)
6659     {
6660       errmsg ("missing vrf id\n");
6661       return -99;
6662     }
6663
6664   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
6665   mp->src = src;
6666   mp->dst = dst;
6667   mp->sport = sport;
6668   mp->dport = dport;
6669   mp->proto = proto;
6670   mp->reverse = reverse;
6671   mp->vrf_id = ntohl (vrf_id);
6672   mp->is_ipv6 = is_ipv6;
6673
6674   S;
6675   W;
6676   /* NOTREACHED */
6677   return 0;
6678 }
6679
6680 static int
6681 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
6682 {
6683   unformat_input_t *i = vam->input;
6684   vl_api_sw_interface_ip6_enable_disable_t *mp;
6685   f64 timeout;
6686   u32 sw_if_index;
6687   u8 sw_if_index_set = 0;
6688   u8 enable = 0;
6689
6690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6691     {
6692       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6693         sw_if_index_set = 1;
6694       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6695         sw_if_index_set = 1;
6696       else if (unformat (i, "enable"))
6697         enable = 1;
6698       else if (unformat (i, "disable"))
6699         enable = 0;
6700       else
6701         {
6702           clib_warning ("parse error '%U'", format_unformat_error, i);
6703           return -99;
6704         }
6705     }
6706
6707   if (sw_if_index_set == 0)
6708     {
6709       errmsg ("missing interface name or sw_if_index\n");
6710       return -99;
6711     }
6712
6713   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
6714
6715   mp->sw_if_index = ntohl (sw_if_index);
6716   mp->enable = enable;
6717
6718   S;
6719   W;
6720   /* NOTREACHED */
6721   return 0;
6722 }
6723
6724 static int
6725 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
6726 {
6727   unformat_input_t *i = vam->input;
6728   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
6729   f64 timeout;
6730   u32 sw_if_index;
6731   u8 sw_if_index_set = 0;
6732   u32 address_length = 0;
6733   u8 v6_address_set = 0;
6734   ip6_address_t v6address;
6735
6736   /* Parse args required to build the message */
6737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6738     {
6739       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6740         sw_if_index_set = 1;
6741       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6742         sw_if_index_set = 1;
6743       else if (unformat (i, "%U/%d",
6744                          unformat_ip6_address, &v6address, &address_length))
6745         v6_address_set = 1;
6746       else
6747         break;
6748     }
6749
6750   if (sw_if_index_set == 0)
6751     {
6752       errmsg ("missing interface name or sw_if_index\n");
6753       return -99;
6754     }
6755   if (!v6_address_set)
6756     {
6757       errmsg ("no address set\n");
6758       return -99;
6759     }
6760
6761   /* Construct the API message */
6762   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
6763      sw_interface_ip6_set_link_local_address);
6764
6765   mp->sw_if_index = ntohl (sw_if_index);
6766   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6767   mp->address_length = address_length;
6768
6769   /* send it... */
6770   S;
6771
6772   /* Wait for a reply, return good/bad news  */
6773   W;
6774
6775   /* NOTREACHED */
6776   return 0;
6777 }
6778
6779
6780 static int
6781 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
6782 {
6783   unformat_input_t *i = vam->input;
6784   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
6785   f64 timeout;
6786   u32 sw_if_index;
6787   u8 sw_if_index_set = 0;
6788   u32 address_length = 0;
6789   u8 v6_address_set = 0;
6790   ip6_address_t v6address;
6791   u8 use_default = 0;
6792   u8 no_advertise = 0;
6793   u8 off_link = 0;
6794   u8 no_autoconfig = 0;
6795   u8 no_onlink = 0;
6796   u8 is_no = 0;
6797   u32 val_lifetime = 0;
6798   u32 pref_lifetime = 0;
6799
6800   /* Parse args required to build the message */
6801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6802     {
6803       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6804         sw_if_index_set = 1;
6805       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6806         sw_if_index_set = 1;
6807       else if (unformat (i, "%U/%d",
6808                          unformat_ip6_address, &v6address, &address_length))
6809         v6_address_set = 1;
6810       else if (unformat (i, "val_life %d", &val_lifetime))
6811         ;
6812       else if (unformat (i, "pref_life %d", &pref_lifetime))
6813         ;
6814       else if (unformat (i, "def"))
6815         use_default = 1;
6816       else if (unformat (i, "noadv"))
6817         no_advertise = 1;
6818       else if (unformat (i, "offl"))
6819         off_link = 1;
6820       else if (unformat (i, "noauto"))
6821         no_autoconfig = 1;
6822       else if (unformat (i, "nolink"))
6823         no_onlink = 1;
6824       else if (unformat (i, "isno"))
6825         is_no = 1;
6826       else
6827         {
6828           clib_warning ("parse error '%U'", format_unformat_error, i);
6829           return -99;
6830         }
6831     }
6832
6833   if (sw_if_index_set == 0)
6834     {
6835       errmsg ("missing interface name or sw_if_index\n");
6836       return -99;
6837     }
6838   if (!v6_address_set)
6839     {
6840       errmsg ("no address set\n");
6841       return -99;
6842     }
6843
6844   /* Construct the API message */
6845   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
6846
6847   mp->sw_if_index = ntohl (sw_if_index);
6848   clib_memcpy (mp->address, &v6address, sizeof (v6address));
6849   mp->address_length = address_length;
6850   mp->use_default = use_default;
6851   mp->no_advertise = no_advertise;
6852   mp->off_link = off_link;
6853   mp->no_autoconfig = no_autoconfig;
6854   mp->no_onlink = no_onlink;
6855   mp->is_no = is_no;
6856   mp->val_lifetime = ntohl (val_lifetime);
6857   mp->pref_lifetime = ntohl (pref_lifetime);
6858
6859   /* send it... */
6860   S;
6861
6862   /* Wait for a reply, return good/bad news  */
6863   W;
6864
6865   /* NOTREACHED */
6866   return 0;
6867 }
6868
6869 static int
6870 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
6871 {
6872   unformat_input_t *i = vam->input;
6873   vl_api_sw_interface_ip6nd_ra_config_t *mp;
6874   f64 timeout;
6875   u32 sw_if_index;
6876   u8 sw_if_index_set = 0;
6877   u8 suppress = 0;
6878   u8 managed = 0;
6879   u8 other = 0;
6880   u8 ll_option = 0;
6881   u8 send_unicast = 0;
6882   u8 cease = 0;
6883   u8 is_no = 0;
6884   u8 default_router = 0;
6885   u32 max_interval = 0;
6886   u32 min_interval = 0;
6887   u32 lifetime = 0;
6888   u32 initial_count = 0;
6889   u32 initial_interval = 0;
6890
6891
6892   /* Parse args required to build the message */
6893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6894     {
6895       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6896         sw_if_index_set = 1;
6897       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6898         sw_if_index_set = 1;
6899       else if (unformat (i, "maxint %d", &max_interval))
6900         ;
6901       else if (unformat (i, "minint %d", &min_interval))
6902         ;
6903       else if (unformat (i, "life %d", &lifetime))
6904         ;
6905       else if (unformat (i, "count %d", &initial_count))
6906         ;
6907       else if (unformat (i, "interval %d", &initial_interval))
6908         ;
6909       else if (unformat (i, "suppress") || unformat (i, "surpress"))
6910         suppress = 1;
6911       else if (unformat (i, "managed"))
6912         managed = 1;
6913       else if (unformat (i, "other"))
6914         other = 1;
6915       else if (unformat (i, "ll"))
6916         ll_option = 1;
6917       else if (unformat (i, "send"))
6918         send_unicast = 1;
6919       else if (unformat (i, "cease"))
6920         cease = 1;
6921       else if (unformat (i, "isno"))
6922         is_no = 1;
6923       else if (unformat (i, "def"))
6924         default_router = 1;
6925       else
6926         {
6927           clib_warning ("parse error '%U'", format_unformat_error, i);
6928           return -99;
6929         }
6930     }
6931
6932   if (sw_if_index_set == 0)
6933     {
6934       errmsg ("missing interface name or sw_if_index\n");
6935       return -99;
6936     }
6937
6938   /* Construct the API message */
6939   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
6940
6941   mp->sw_if_index = ntohl (sw_if_index);
6942   mp->max_interval = ntohl (max_interval);
6943   mp->min_interval = ntohl (min_interval);
6944   mp->lifetime = ntohl (lifetime);
6945   mp->initial_count = ntohl (initial_count);
6946   mp->initial_interval = ntohl (initial_interval);
6947   mp->suppress = suppress;
6948   mp->managed = managed;
6949   mp->other = other;
6950   mp->ll_option = ll_option;
6951   mp->send_unicast = send_unicast;
6952   mp->cease = cease;
6953   mp->is_no = is_no;
6954   mp->default_router = default_router;
6955
6956   /* send it... */
6957   S;
6958
6959   /* Wait for a reply, return good/bad news  */
6960   W;
6961
6962   /* NOTREACHED */
6963   return 0;
6964 }
6965
6966 static int
6967 api_set_arp_neighbor_limit (vat_main_t * vam)
6968 {
6969   unformat_input_t *i = vam->input;
6970   vl_api_set_arp_neighbor_limit_t *mp;
6971   f64 timeout;
6972   u32 arp_nbr_limit;
6973   u8 limit_set = 0;
6974   u8 is_ipv6 = 0;
6975
6976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6977     {
6978       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
6979         limit_set = 1;
6980       else if (unformat (i, "ipv6"))
6981         is_ipv6 = 1;
6982       else
6983         {
6984           clib_warning ("parse error '%U'", format_unformat_error, i);
6985           return -99;
6986         }
6987     }
6988
6989   if (limit_set == 0)
6990     {
6991       errmsg ("missing limit value\n");
6992       return -99;
6993     }
6994
6995   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
6996
6997   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
6998   mp->is_ipv6 = is_ipv6;
6999
7000   S;
7001   W;
7002   /* NOTREACHED */
7003   return 0;
7004 }
7005
7006 static int
7007 api_l2_patch_add_del (vat_main_t * vam)
7008 {
7009   unformat_input_t *i = vam->input;
7010   vl_api_l2_patch_add_del_t *mp;
7011   f64 timeout;
7012   u32 rx_sw_if_index;
7013   u8 rx_sw_if_index_set = 0;
7014   u32 tx_sw_if_index;
7015   u8 tx_sw_if_index_set = 0;
7016   u8 is_add = 1;
7017
7018   /* Parse args required to build the message */
7019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7020     {
7021       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7022         rx_sw_if_index_set = 1;
7023       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7024         tx_sw_if_index_set = 1;
7025       else if (unformat (i, "rx"))
7026         {
7027           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7028             {
7029               if (unformat (i, "%U", unformat_sw_if_index, vam,
7030                             &rx_sw_if_index))
7031                 rx_sw_if_index_set = 1;
7032             }
7033           else
7034             break;
7035         }
7036       else if (unformat (i, "tx"))
7037         {
7038           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7039             {
7040               if (unformat (i, "%U", unformat_sw_if_index, vam,
7041                             &tx_sw_if_index))
7042                 tx_sw_if_index_set = 1;
7043             }
7044           else
7045             break;
7046         }
7047       else if (unformat (i, "del"))
7048         is_add = 0;
7049       else
7050         break;
7051     }
7052
7053   if (rx_sw_if_index_set == 0)
7054     {
7055       errmsg ("missing rx interface name or rx_sw_if_index\n");
7056       return -99;
7057     }
7058
7059   if (tx_sw_if_index_set == 0)
7060     {
7061       errmsg ("missing tx interface name or tx_sw_if_index\n");
7062       return -99;
7063     }
7064
7065   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7066
7067   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7068   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7069   mp->is_add = is_add;
7070
7071   S;
7072   W;
7073   /* NOTREACHED */
7074   return 0;
7075 }
7076
7077 static int
7078 api_trace_profile_add (vat_main_t * vam)
7079 {
7080   unformat_input_t *input = vam->input;
7081   vl_api_trace_profile_add_t *mp;
7082   f64 timeout;
7083   u32 id = 0;
7084   u32 trace_option_elts = 0;
7085   u32 trace_type = 0, node_id = 0, app_data = 0, trace_tsp = 2;
7086   int has_pow_option = 0;
7087   int has_ppc_option = 0;
7088
7089   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7090     {
7091       if (unformat (input, "id %d trace-type 0x%x trace-elts %d "
7092                     "trace-tsp %d node-id 0x%x app-data 0x%x",
7093                     &id, &trace_type, &trace_option_elts, &trace_tsp,
7094                     &node_id, &app_data))
7095         ;
7096       else if (unformat (input, "pow"))
7097         has_pow_option = 1;
7098       else if (unformat (input, "ppc encap"))
7099         has_ppc_option = PPC_ENCAP;
7100       else if (unformat (input, "ppc decap"))
7101         has_ppc_option = PPC_DECAP;
7102       else if (unformat (input, "ppc none"))
7103         has_ppc_option = PPC_NONE;
7104       else
7105         break;
7106     }
7107   M (TRACE_PROFILE_ADD, trace_profile_add);
7108   mp->id = htons (id);
7109   mp->trace_type = trace_type;
7110   mp->trace_num_elt = trace_option_elts;
7111   mp->trace_ppc = has_ppc_option;
7112   mp->trace_app_data = htonl (app_data);
7113   mp->pow_enable = has_pow_option;
7114   mp->trace_tsp = trace_tsp;
7115   mp->node_id = htonl (node_id);
7116
7117   S;
7118   W;
7119
7120   return (0);
7121
7122 }
7123
7124 static int
7125 api_trace_profile_apply (vat_main_t * vam)
7126 {
7127   unformat_input_t *input = vam->input;
7128   vl_api_trace_profile_apply_t *mp;
7129   f64 timeout;
7130   ip6_address_t addr;
7131   u32 mask_width = ~0;
7132   int is_add = 0;
7133   int is_pop = 0;
7134   int is_none = 0;
7135   u32 vrf_id = 0;
7136   u32 id = 0;
7137
7138   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7139     {
7140       if (unformat (input, "%U/%d", unformat_ip6_address, &addr, &mask_width))
7141         ;
7142       else if (unformat (input, "id %d", &id))
7143         ;
7144       else if (unformat (input, "vrf-id %d", &vrf_id))
7145         ;
7146       else if (unformat (input, "add"))
7147         is_add = 1;
7148       else if (unformat (input, "pop"))
7149         is_pop = 1;
7150       else if (unformat (input, "none"))
7151         is_none = 1;
7152       else
7153         break;
7154     }
7155
7156   if ((is_add + is_pop + is_none) != 1)
7157     {
7158       errmsg ("One of (add, pop, none) required");
7159       return -99;
7160     }
7161   if (mask_width == ~0)
7162     {
7163       errmsg ("<address>/<mask-width> required");
7164       return -99;
7165     }
7166   M (TRACE_PROFILE_APPLY, trace_profile_apply);
7167   clib_memcpy (mp->dest_ipv6, &addr, sizeof (mp->dest_ipv6));
7168   mp->id = htons (id);
7169   mp->prefix_length = htonl (mask_width);
7170   mp->vrf_id = htonl (vrf_id);
7171   if (is_add)
7172     mp->trace_op = IOAM_HBYH_ADD;
7173   else if (is_pop)
7174     mp->trace_op = IOAM_HBYH_POP;
7175   else
7176     mp->trace_op = IOAM_HBYH_MOD;
7177
7178   if (is_none)
7179     mp->enable = 0;
7180   else
7181     mp->enable = 1;
7182
7183   S;
7184   W;
7185
7186   return 0;
7187 }
7188
7189 static int
7190 api_trace_profile_del (vat_main_t * vam)
7191 {
7192   vl_api_trace_profile_del_t *mp;
7193   f64 timeout;
7194
7195   M (TRACE_PROFILE_DEL, trace_profile_del);
7196   S;
7197   W;
7198   return 0;
7199 }
7200
7201 static int
7202 api_sr_tunnel_add_del (vat_main_t * vam)
7203 {
7204   unformat_input_t *i = vam->input;
7205   vl_api_sr_tunnel_add_del_t *mp;
7206   f64 timeout;
7207   int is_del = 0;
7208   int pl_index;
7209   ip6_address_t src_address;
7210   int src_address_set = 0;
7211   ip6_address_t dst_address;
7212   u32 dst_mask_width;
7213   int dst_address_set = 0;
7214   u16 flags = 0;
7215   u32 rx_table_id = 0;
7216   u32 tx_table_id = 0;
7217   ip6_address_t *segments = 0;
7218   ip6_address_t *this_seg;
7219   ip6_address_t *tags = 0;
7220   ip6_address_t *this_tag;
7221   ip6_address_t next_address, tag;
7222   u8 *name = 0;
7223   u8 *policy_name = 0;
7224
7225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7226     {
7227       if (unformat (i, "del"))
7228         is_del = 1;
7229       else if (unformat (i, "name %s", &name))
7230         ;
7231       else if (unformat (i, "policy %s", &policy_name))
7232         ;
7233       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7234         ;
7235       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7236         ;
7237       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7238         src_address_set = 1;
7239       else if (unformat (i, "dst %U/%d",
7240                          unformat_ip6_address, &dst_address, &dst_mask_width))
7241         dst_address_set = 1;
7242       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7243         {
7244           vec_add2 (segments, this_seg, 1);
7245           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7246                        sizeof (*this_seg));
7247         }
7248       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7249         {
7250           vec_add2 (tags, this_tag, 1);
7251           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7252         }
7253       else if (unformat (i, "clean"))
7254         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7255       else if (unformat (i, "protected"))
7256         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7257       else if (unformat (i, "InPE %d", &pl_index))
7258         {
7259           if (pl_index <= 0 || pl_index > 4)
7260             {
7261             pl_index_range_error:
7262               errmsg ("pl index %d out of range\n", pl_index);
7263               return -99;
7264             }
7265           flags |=
7266             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7267         }
7268       else if (unformat (i, "EgPE %d", &pl_index))
7269         {
7270           if (pl_index <= 0 || pl_index > 4)
7271             goto pl_index_range_error;
7272           flags |=
7273             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7274         }
7275       else if (unformat (i, "OrgSrc %d", &pl_index))
7276         {
7277           if (pl_index <= 0 || pl_index > 4)
7278             goto pl_index_range_error;
7279           flags |=
7280             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7281         }
7282       else
7283         break;
7284     }
7285
7286   if (!src_address_set)
7287     {
7288       errmsg ("src address required\n");
7289       return -99;
7290     }
7291
7292   if (!dst_address_set)
7293     {
7294       errmsg ("dst address required\n");
7295       return -99;
7296     }
7297
7298   if (!segments)
7299     {
7300       errmsg ("at least one sr segment required\n");
7301       return -99;
7302     }
7303
7304   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7305       vec_len (segments) * sizeof (ip6_address_t)
7306       + vec_len (tags) * sizeof (ip6_address_t));
7307
7308   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7309   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7310   mp->dst_mask_width = dst_mask_width;
7311   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7312   mp->n_segments = vec_len (segments);
7313   mp->n_tags = vec_len (tags);
7314   mp->is_add = is_del == 0;
7315   clib_memcpy (mp->segs_and_tags, segments,
7316                vec_len (segments) * sizeof (ip6_address_t));
7317   clib_memcpy (mp->segs_and_tags +
7318                vec_len (segments) * sizeof (ip6_address_t), tags,
7319                vec_len (tags) * sizeof (ip6_address_t));
7320
7321   mp->outer_vrf_id = ntohl (rx_table_id);
7322   mp->inner_vrf_id = ntohl (tx_table_id);
7323   memcpy (mp->name, name, vec_len (name));
7324   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7325
7326   vec_free (segments);
7327   vec_free (tags);
7328
7329   S;
7330   W;
7331   /* NOTREACHED */
7332 }
7333
7334 static int
7335 api_sr_policy_add_del (vat_main_t * vam)
7336 {
7337   unformat_input_t *input = vam->input;
7338   vl_api_sr_policy_add_del_t *mp;
7339   f64 timeout;
7340   int is_del = 0;
7341   u8 *name = 0;
7342   u8 *tunnel_name = 0;
7343   u8 **tunnel_names = 0;
7344
7345   int name_set = 0;
7346   int tunnel_set = 0;
7347   int j = 0;
7348   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7349   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7350
7351   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7352     {
7353       if (unformat (input, "del"))
7354         is_del = 1;
7355       else if (unformat (input, "name %s", &name))
7356         name_set = 1;
7357       else if (unformat (input, "tunnel %s", &tunnel_name))
7358         {
7359           if (tunnel_name)
7360             {
7361               vec_add1 (tunnel_names, tunnel_name);
7362               /* For serializer:
7363                  - length = #bytes to store in serial vector
7364                  - +1 = byte to store that length
7365                */
7366               tunnel_names_length += (vec_len (tunnel_name) + 1);
7367               tunnel_set = 1;
7368               tunnel_name = 0;
7369             }
7370         }
7371       else
7372         break;
7373     }
7374
7375   if (!name_set)
7376     {
7377       errmsg ("policy name required\n");
7378       return -99;
7379     }
7380
7381   if ((!tunnel_set) && (!is_del))
7382     {
7383       errmsg ("tunnel name required\n");
7384       return -99;
7385     }
7386
7387   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7388
7389
7390
7391   mp->is_add = !is_del;
7392
7393   memcpy (mp->name, name, vec_len (name));
7394   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7395   u8 *serial_orig = 0;
7396   vec_validate (serial_orig, tunnel_names_length);
7397   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
7398   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
7399
7400   for (j = 0; j < vec_len (tunnel_names); j++)
7401     {
7402       tun_name_len = vec_len (tunnel_names[j]);
7403       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
7404       serial_orig += 1;         // Move along one byte to store the actual tunnel name
7405       memcpy (serial_orig, tunnel_names[j], tun_name_len);
7406       serial_orig += tun_name_len;      // Advance past the copy
7407     }
7408   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
7409
7410   vec_free (tunnel_names);
7411   vec_free (tunnel_name);
7412
7413   S;
7414   W;
7415   /* NOTREACHED */
7416 }
7417
7418 static int
7419 api_sr_multicast_map_add_del (vat_main_t * vam)
7420 {
7421   unformat_input_t *input = vam->input;
7422   vl_api_sr_multicast_map_add_del_t *mp;
7423   f64 timeout;
7424   int is_del = 0;
7425   ip6_address_t multicast_address;
7426   u8 *policy_name = 0;
7427   int multicast_address_set = 0;
7428
7429   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7430     {
7431       if (unformat (input, "del"))
7432         is_del = 1;
7433       else
7434         if (unformat
7435             (input, "address %U", unformat_ip6_address, &multicast_address))
7436         multicast_address_set = 1;
7437       else if (unformat (input, "sr-policy %s", &policy_name))
7438         ;
7439       else
7440         break;
7441     }
7442
7443   if (!is_del && !policy_name)
7444     {
7445       errmsg ("sr-policy name required\n");
7446       return -99;
7447     }
7448
7449
7450   if (!multicast_address_set)
7451     {
7452       errmsg ("address required\n");
7453       return -99;
7454     }
7455
7456   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
7457
7458   mp->is_add = !is_del;
7459   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7460   clib_memcpy (mp->multicast_address, &multicast_address,
7461                sizeof (mp->multicast_address));
7462
7463
7464   vec_free (policy_name);
7465
7466   S;
7467   W;
7468   /* NOTREACHED */
7469 }
7470
7471
7472 #define foreach_ip4_proto_field                 \
7473 _(src_address)                                  \
7474 _(dst_address)                                  \
7475 _(tos)                                          \
7476 _(length)                                       \
7477 _(fragment_id)                                  \
7478 _(ttl)                                          \
7479 _(protocol)                                     \
7480 _(checksum)
7481
7482 uword
7483 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7484 {
7485   u8 **maskp = va_arg (*args, u8 **);
7486   u8 *mask = 0;
7487   u8 found_something = 0;
7488   ip4_header_t *ip;
7489
7490 #define _(a) u8 a=0;
7491   foreach_ip4_proto_field;
7492 #undef _
7493   u8 version = 0;
7494   u8 hdr_length = 0;
7495
7496
7497   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7498     {
7499       if (unformat (input, "version"))
7500         version = 1;
7501       else if (unformat (input, "hdr_length"))
7502         hdr_length = 1;
7503       else if (unformat (input, "src"))
7504         src_address = 1;
7505       else if (unformat (input, "dst"))
7506         dst_address = 1;
7507       else if (unformat (input, "proto"))
7508         protocol = 1;
7509
7510 #define _(a) else if (unformat (input, #a)) a=1;
7511       foreach_ip4_proto_field
7512 #undef _
7513         else
7514         break;
7515     }
7516
7517 #define _(a) found_something += a;
7518   foreach_ip4_proto_field;
7519 #undef _
7520
7521   if (found_something == 0)
7522     return 0;
7523
7524   vec_validate (mask, sizeof (*ip) - 1);
7525
7526   ip = (ip4_header_t *) mask;
7527
7528 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7529   foreach_ip4_proto_field;
7530 #undef _
7531
7532   ip->ip_version_and_header_length = 0;
7533
7534   if (version)
7535     ip->ip_version_and_header_length |= 0xF0;
7536
7537   if (hdr_length)
7538     ip->ip_version_and_header_length |= 0x0F;
7539
7540   *maskp = mask;
7541   return 1;
7542 }
7543
7544 #define foreach_ip6_proto_field                 \
7545 _(src_address)                                  \
7546 _(dst_address)                                  \
7547 _(payload_length)                               \
7548 _(hop_limit)                                    \
7549 _(protocol)
7550
7551 uword
7552 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7553 {
7554   u8 **maskp = va_arg (*args, u8 **);
7555   u8 *mask = 0;
7556   u8 found_something = 0;
7557   ip6_header_t *ip;
7558   u32 ip_version_traffic_class_and_flow_label;
7559
7560 #define _(a) u8 a=0;
7561   foreach_ip6_proto_field;
7562 #undef _
7563   u8 version = 0;
7564   u8 traffic_class = 0;
7565   u8 flow_label = 0;
7566
7567   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7568     {
7569       if (unformat (input, "version"))
7570         version = 1;
7571       else if (unformat (input, "traffic-class"))
7572         traffic_class = 1;
7573       else if (unformat (input, "flow-label"))
7574         flow_label = 1;
7575       else if (unformat (input, "src"))
7576         src_address = 1;
7577       else if (unformat (input, "dst"))
7578         dst_address = 1;
7579       else if (unformat (input, "proto"))
7580         protocol = 1;
7581
7582 #define _(a) else if (unformat (input, #a)) a=1;
7583       foreach_ip6_proto_field
7584 #undef _
7585         else
7586         break;
7587     }
7588
7589 #define _(a) found_something += a;
7590   foreach_ip6_proto_field;
7591 #undef _
7592
7593   if (found_something == 0)
7594     return 0;
7595
7596   vec_validate (mask, sizeof (*ip) - 1);
7597
7598   ip = (ip6_header_t *) mask;
7599
7600 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
7601   foreach_ip6_proto_field;
7602 #undef _
7603
7604   ip_version_traffic_class_and_flow_label = 0;
7605
7606   if (version)
7607     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7608
7609   if (traffic_class)
7610     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7611
7612   if (flow_label)
7613     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7614
7615   ip->ip_version_traffic_class_and_flow_label =
7616     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7617
7618   *maskp = mask;
7619   return 1;
7620 }
7621
7622 uword
7623 unformat_l3_mask (unformat_input_t * input, va_list * args)
7624 {
7625   u8 **maskp = va_arg (*args, u8 **);
7626
7627   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7628     {
7629       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7630         return 1;
7631       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7632         return 1;
7633       else
7634         break;
7635     }
7636   return 0;
7637 }
7638
7639 uword
7640 unformat_l2_mask (unformat_input_t * input, va_list * args)
7641 {
7642   u8 **maskp = va_arg (*args, u8 **);
7643   u8 *mask = 0;
7644   u8 src = 0;
7645   u8 dst = 0;
7646   u8 proto = 0;
7647   u8 tag1 = 0;
7648   u8 tag2 = 0;
7649   u8 ignore_tag1 = 0;
7650   u8 ignore_tag2 = 0;
7651   u8 cos1 = 0;
7652   u8 cos2 = 0;
7653   u8 dot1q = 0;
7654   u8 dot1ad = 0;
7655   int len = 14;
7656
7657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7658     {
7659       if (unformat (input, "src"))
7660         src = 1;
7661       else if (unformat (input, "dst"))
7662         dst = 1;
7663       else if (unformat (input, "proto"))
7664         proto = 1;
7665       else if (unformat (input, "tag1"))
7666         tag1 = 1;
7667       else if (unformat (input, "tag2"))
7668         tag2 = 1;
7669       else if (unformat (input, "ignore-tag1"))
7670         ignore_tag1 = 1;
7671       else if (unformat (input, "ignore-tag2"))
7672         ignore_tag2 = 1;
7673       else if (unformat (input, "cos1"))
7674         cos1 = 1;
7675       else if (unformat (input, "cos2"))
7676         cos2 = 1;
7677       else if (unformat (input, "dot1q"))
7678         dot1q = 1;
7679       else if (unformat (input, "dot1ad"))
7680         dot1ad = 1;
7681       else
7682         break;
7683     }
7684   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7685        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7686     return 0;
7687
7688   if (tag1 || ignore_tag1 || cos1 || dot1q)
7689     len = 18;
7690   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7691     len = 22;
7692
7693   vec_validate (mask, len - 1);
7694
7695   if (dst)
7696     memset (mask, 0xff, 6);
7697
7698   if (src)
7699     memset (mask + 6, 0xff, 6);
7700
7701   if (tag2 || dot1ad)
7702     {
7703       /* inner vlan tag */
7704       if (tag2)
7705         {
7706           mask[19] = 0xff;
7707           mask[18] = 0x0f;
7708         }
7709       if (cos2)
7710         mask[18] |= 0xe0;
7711       if (proto)
7712         mask[21] = mask[20] = 0xff;
7713       if (tag1)
7714         {
7715           mask[15] = 0xff;
7716           mask[14] = 0x0f;
7717         }
7718       if (cos1)
7719         mask[14] |= 0xe0;
7720       *maskp = mask;
7721       return 1;
7722     }
7723   if (tag1 | dot1q)
7724     {
7725       if (tag1)
7726         {
7727           mask[15] = 0xff;
7728           mask[14] = 0x0f;
7729         }
7730       if (cos1)
7731         mask[14] |= 0xe0;
7732       if (proto)
7733         mask[16] = mask[17] = 0xff;
7734
7735       *maskp = mask;
7736       return 1;
7737     }
7738   if (cos2)
7739     mask[18] |= 0xe0;
7740   if (cos1)
7741     mask[14] |= 0xe0;
7742   if (proto)
7743     mask[12] = mask[13] = 0xff;
7744
7745   *maskp = mask;
7746   return 1;
7747 }
7748
7749 uword
7750 unformat_classify_mask (unformat_input_t * input, va_list * args)
7751 {
7752   u8 **maskp = va_arg (*args, u8 **);
7753   u32 *skipp = va_arg (*args, u32 *);
7754   u32 *matchp = va_arg (*args, u32 *);
7755   u32 match;
7756   u8 *mask = 0;
7757   u8 *l2 = 0;
7758   u8 *l3 = 0;
7759   int i;
7760
7761   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7762     {
7763       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7764         ;
7765       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7766         ;
7767       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7768         ;
7769       else
7770         break;
7771     }
7772
7773   if (mask || l2 || l3)
7774     {
7775       if (l2 || l3)
7776         {
7777           /* "With a free Ethernet header in every package" */
7778           if (l2 == 0)
7779             vec_validate (l2, 13);
7780           mask = l2;
7781           if (vec_len (l3))
7782             {
7783               vec_append (mask, l3);
7784               vec_free (l3);
7785             }
7786         }
7787
7788       /* Scan forward looking for the first significant mask octet */
7789       for (i = 0; i < vec_len (mask); i++)
7790         if (mask[i])
7791           break;
7792
7793       /* compute (skip, match) params */
7794       *skipp = i / sizeof (u32x4);
7795       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7796
7797       /* Pad mask to an even multiple of the vector size */
7798       while (vec_len (mask) % sizeof (u32x4))
7799         vec_add1 (mask, 0);
7800
7801       match = vec_len (mask) / sizeof (u32x4);
7802
7803       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7804         {
7805           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7806           if (*tmp || *(tmp + 1))
7807             break;
7808           match--;
7809         }
7810       if (match == 0)
7811         clib_warning ("BUG: match 0");
7812
7813       _vec_len (mask) = match * sizeof (u32x4);
7814
7815       *matchp = match;
7816       *maskp = mask;
7817
7818       return 1;
7819     }
7820
7821   return 0;
7822 }
7823
7824 #define foreach_l2_next                         \
7825 _(drop, DROP)                                   \
7826 _(ethernet, ETHERNET_INPUT)                     \
7827 _(ip4, IP4_INPUT)                               \
7828 _(ip6, IP6_INPUT)
7829
7830 uword
7831 unformat_l2_next_index (unformat_input_t * input, va_list * args)
7832 {
7833   u32 *miss_next_indexp = va_arg (*args, u32 *);
7834   u32 next_index = 0;
7835   u32 tmp;
7836
7837 #define _(n,N) \
7838   if (unformat (input, #n)) { next_index = L2_CLASSIFY_NEXT_##N; goto out;}
7839   foreach_l2_next;
7840 #undef _
7841
7842   if (unformat (input, "%d", &tmp))
7843     {
7844       next_index = tmp;
7845       goto out;
7846     }
7847
7848   return 0;
7849
7850 out:
7851   *miss_next_indexp = next_index;
7852   return 1;
7853 }
7854
7855 #define foreach_ip_next                         \
7856 _(miss, MISS)                                   \
7857 _(drop, DROP)                                   \
7858 _(local, LOCAL)                                 \
7859 _(rewrite, REWRITE)
7860
7861 uword
7862 unformat_ip_next_index (unformat_input_t * input, va_list * args)
7863 {
7864   u32 *miss_next_indexp = va_arg (*args, u32 *);
7865   u32 next_index = 0;
7866   u32 tmp;
7867
7868 #define _(n,N) \
7869   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
7870   foreach_ip_next;
7871 #undef _
7872
7873   if (unformat (input, "%d", &tmp))
7874     {
7875       next_index = tmp;
7876       goto out;
7877     }
7878
7879   return 0;
7880
7881 out:
7882   *miss_next_indexp = next_index;
7883   return 1;
7884 }
7885
7886 #define foreach_acl_next                        \
7887 _(deny, DENY)
7888
7889 uword
7890 unformat_acl_next_index (unformat_input_t * input, va_list * args)
7891 {
7892   u32 *miss_next_indexp = va_arg (*args, u32 *);
7893   u32 next_index = 0;
7894   u32 tmp;
7895
7896 #define _(n,N) \
7897   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
7898   foreach_acl_next;
7899 #undef _
7900
7901   if (unformat (input, "permit"))
7902     {
7903       next_index = ~0;
7904       goto out;
7905     }
7906   else if (unformat (input, "%d", &tmp))
7907     {
7908       next_index = tmp;
7909       goto out;
7910     }
7911
7912   return 0;
7913
7914 out:
7915   *miss_next_indexp = next_index;
7916   return 1;
7917 }
7918
7919 uword
7920 unformat_policer_precolor (unformat_input_t * input, va_list * args)
7921 {
7922   u32 *r = va_arg (*args, u32 *);
7923
7924   if (unformat (input, "conform-color"))
7925     *r = POLICE_CONFORM;
7926   else if (unformat (input, "exceed-color"))
7927     *r = POLICE_EXCEED;
7928   else
7929     return 0;
7930
7931   return 1;
7932 }
7933
7934 static int
7935 api_classify_add_del_table (vat_main_t * vam)
7936 {
7937   unformat_input_t *i = vam->input;
7938   vl_api_classify_add_del_table_t *mp;
7939
7940   u32 nbuckets = 2;
7941   u32 skip = ~0;
7942   u32 match = ~0;
7943   int is_add = 1;
7944   u32 table_index = ~0;
7945   u32 next_table_index = ~0;
7946   u32 miss_next_index = ~0;
7947   u32 memory_size = 32 << 20;
7948   u8 *mask = 0;
7949   f64 timeout;
7950
7951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7952     {
7953       if (unformat (i, "del"))
7954         is_add = 0;
7955       else if (unformat (i, "buckets %d", &nbuckets))
7956         ;
7957       else if (unformat (i, "memory_size %d", &memory_size))
7958         ;
7959       else if (unformat (i, "skip %d", &skip))
7960         ;
7961       else if (unformat (i, "match %d", &match))
7962         ;
7963       else if (unformat (i, "table %d", &table_index))
7964         ;
7965       else if (unformat (i, "mask %U", unformat_classify_mask,
7966                          &mask, &skip, &match))
7967         ;
7968       else if (unformat (i, "next-table %d", &next_table_index))
7969         ;
7970       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
7971                          &miss_next_index))
7972         ;
7973       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
7974                          &miss_next_index))
7975         ;
7976       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
7977                          &miss_next_index))
7978         ;
7979       else
7980         break;
7981     }
7982
7983   if (is_add && mask == 0)
7984     {
7985       errmsg ("Mask required\n");
7986       return -99;
7987     }
7988
7989   if (is_add && skip == ~0)
7990     {
7991       errmsg ("skip count required\n");
7992       return -99;
7993     }
7994
7995   if (is_add && match == ~0)
7996     {
7997       errmsg ("match count required\n");
7998       return -99;
7999     }
8000
8001   if (!is_add && table_index == ~0)
8002     {
8003       errmsg ("table index required for delete\n");
8004       return -99;
8005     }
8006
8007   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8008
8009   mp->is_add = is_add;
8010   mp->table_index = ntohl (table_index);
8011   mp->nbuckets = ntohl (nbuckets);
8012   mp->memory_size = ntohl (memory_size);
8013   mp->skip_n_vectors = ntohl (skip);
8014   mp->match_n_vectors = ntohl (match);
8015   mp->next_table_index = ntohl (next_table_index);
8016   mp->miss_next_index = ntohl (miss_next_index);
8017   clib_memcpy (mp->mask, mask, vec_len (mask));
8018
8019   vec_free (mask);
8020
8021   S;
8022   W;
8023   /* NOTREACHED */
8024 }
8025
8026 uword
8027 unformat_ip4_match (unformat_input_t * input, va_list * args)
8028 {
8029   u8 **matchp = va_arg (*args, u8 **);
8030   u8 *match = 0;
8031   ip4_header_t *ip;
8032   int version = 0;
8033   u32 version_val;
8034   int hdr_length = 0;
8035   u32 hdr_length_val;
8036   int src = 0, dst = 0;
8037   ip4_address_t src_val, dst_val;
8038   int proto = 0;
8039   u32 proto_val;
8040   int tos = 0;
8041   u32 tos_val;
8042   int length = 0;
8043   u32 length_val;
8044   int fragment_id = 0;
8045   u32 fragment_id_val;
8046   int ttl = 0;
8047   int ttl_val;
8048   int checksum = 0;
8049   u32 checksum_val;
8050
8051   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8052     {
8053       if (unformat (input, "version %d", &version_val))
8054         version = 1;
8055       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8056         hdr_length = 1;
8057       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8058         src = 1;
8059       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8060         dst = 1;
8061       else if (unformat (input, "proto %d", &proto_val))
8062         proto = 1;
8063       else if (unformat (input, "tos %d", &tos_val))
8064         tos = 1;
8065       else if (unformat (input, "length %d", &length_val))
8066         length = 1;
8067       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8068         fragment_id = 1;
8069       else if (unformat (input, "ttl %d", &ttl_val))
8070         ttl = 1;
8071       else if (unformat (input, "checksum %d", &checksum_val))
8072         checksum = 1;
8073       else
8074         break;
8075     }
8076
8077   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8078       + ttl + checksum == 0)
8079     return 0;
8080
8081   /*
8082    * Aligned because we use the real comparison functions
8083    */
8084   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8085
8086   ip = (ip4_header_t *) match;
8087
8088   /* These are realistically matched in practice */
8089   if (src)
8090     ip->src_address.as_u32 = src_val.as_u32;
8091
8092   if (dst)
8093     ip->dst_address.as_u32 = dst_val.as_u32;
8094
8095   if (proto)
8096     ip->protocol = proto_val;
8097
8098
8099   /* These are not, but they're included for completeness */
8100   if (version)
8101     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8102
8103   if (hdr_length)
8104     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8105
8106   if (tos)
8107     ip->tos = tos_val;
8108
8109   if (length)
8110     ip->length = length_val;
8111
8112   if (ttl)
8113     ip->ttl = ttl_val;
8114
8115   if (checksum)
8116     ip->checksum = checksum_val;
8117
8118   *matchp = match;
8119   return 1;
8120 }
8121
8122 uword
8123 unformat_ip6_match (unformat_input_t * input, va_list * args)
8124 {
8125   u8 **matchp = va_arg (*args, u8 **);
8126   u8 *match = 0;
8127   ip6_header_t *ip;
8128   int version = 0;
8129   u32 version_val;
8130   u8 traffic_class = 0;
8131   u32 traffic_class_val = 0;
8132   u8 flow_label = 0;
8133   u8 flow_label_val;
8134   int src = 0, dst = 0;
8135   ip6_address_t src_val, dst_val;
8136   int proto = 0;
8137   u32 proto_val;
8138   int payload_length = 0;
8139   u32 payload_length_val;
8140   int hop_limit = 0;
8141   int hop_limit_val;
8142   u32 ip_version_traffic_class_and_flow_label;
8143
8144   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8145     {
8146       if (unformat (input, "version %d", &version_val))
8147         version = 1;
8148       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8149         traffic_class = 1;
8150       else if (unformat (input, "flow_label %d", &flow_label_val))
8151         flow_label = 1;
8152       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8153         src = 1;
8154       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8155         dst = 1;
8156       else if (unformat (input, "proto %d", &proto_val))
8157         proto = 1;
8158       else if (unformat (input, "payload_length %d", &payload_length_val))
8159         payload_length = 1;
8160       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8161         hop_limit = 1;
8162       else
8163         break;
8164     }
8165
8166   if (version + traffic_class + flow_label + src + dst + proto +
8167       payload_length + hop_limit == 0)
8168     return 0;
8169
8170   /*
8171    * Aligned because we use the real comparison functions
8172    */
8173   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8174
8175   ip = (ip6_header_t *) match;
8176
8177   if (src)
8178     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8179
8180   if (dst)
8181     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8182
8183   if (proto)
8184     ip->protocol = proto_val;
8185
8186   ip_version_traffic_class_and_flow_label = 0;
8187
8188   if (version)
8189     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8190
8191   if (traffic_class)
8192     ip_version_traffic_class_and_flow_label |=
8193       (traffic_class_val & 0xFF) << 20;
8194
8195   if (flow_label)
8196     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8197
8198   ip->ip_version_traffic_class_and_flow_label =
8199     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8200
8201   if (payload_length)
8202     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8203
8204   if (hop_limit)
8205     ip->hop_limit = hop_limit_val;
8206
8207   *matchp = match;
8208   return 1;
8209 }
8210
8211 uword
8212 unformat_l3_match (unformat_input_t * input, va_list * args)
8213 {
8214   u8 **matchp = va_arg (*args, u8 **);
8215
8216   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8217     {
8218       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8219         return 1;
8220       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8221         return 1;
8222       else
8223         break;
8224     }
8225   return 0;
8226 }
8227
8228 uword
8229 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8230 {
8231   u8 *tagp = va_arg (*args, u8 *);
8232   u32 tag;
8233
8234   if (unformat (input, "%d", &tag))
8235     {
8236       tagp[0] = (tag >> 8) & 0x0F;
8237       tagp[1] = tag & 0xFF;
8238       return 1;
8239     }
8240
8241   return 0;
8242 }
8243
8244 uword
8245 unformat_l2_match (unformat_input_t * input, va_list * args)
8246 {
8247   u8 **matchp = va_arg (*args, u8 **);
8248   u8 *match = 0;
8249   u8 src = 0;
8250   u8 src_val[6];
8251   u8 dst = 0;
8252   u8 dst_val[6];
8253   u8 proto = 0;
8254   u16 proto_val;
8255   u8 tag1 = 0;
8256   u8 tag1_val[2];
8257   u8 tag2 = 0;
8258   u8 tag2_val[2];
8259   int len = 14;
8260   u8 ignore_tag1 = 0;
8261   u8 ignore_tag2 = 0;
8262   u8 cos1 = 0;
8263   u8 cos2 = 0;
8264   u32 cos1_val = 0;
8265   u32 cos2_val = 0;
8266
8267   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8268     {
8269       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8270         src = 1;
8271       else
8272         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8273         dst = 1;
8274       else if (unformat (input, "proto %U",
8275                          unformat_ethernet_type_host_byte_order, &proto_val))
8276         proto = 1;
8277       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8278         tag1 = 1;
8279       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8280         tag2 = 1;
8281       else if (unformat (input, "ignore-tag1"))
8282         ignore_tag1 = 1;
8283       else if (unformat (input, "ignore-tag2"))
8284         ignore_tag2 = 1;
8285       else if (unformat (input, "cos1 %d", &cos1_val))
8286         cos1 = 1;
8287       else if (unformat (input, "cos2 %d", &cos2_val))
8288         cos2 = 1;
8289       else
8290         break;
8291     }
8292   if ((src + dst + proto + tag1 + tag2 +
8293        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8294     return 0;
8295
8296   if (tag1 || ignore_tag1 || cos1)
8297     len = 18;
8298   if (tag2 || ignore_tag2 || cos2)
8299     len = 22;
8300
8301   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8302
8303   if (dst)
8304     clib_memcpy (match, dst_val, 6);
8305
8306   if (src)
8307     clib_memcpy (match + 6, src_val, 6);
8308
8309   if (tag2)
8310     {
8311       /* inner vlan tag */
8312       match[19] = tag2_val[1];
8313       match[18] = tag2_val[0];
8314       if (cos2)
8315         match[18] |= (cos2_val & 0x7) << 5;
8316       if (proto)
8317         {
8318           match[21] = proto_val & 0xff;
8319           match[20] = proto_val >> 8;
8320         }
8321       if (tag1)
8322         {
8323           match[15] = tag1_val[1];
8324           match[14] = tag1_val[0];
8325         }
8326       if (cos1)
8327         match[14] |= (cos1_val & 0x7) << 5;
8328       *matchp = match;
8329       return 1;
8330     }
8331   if (tag1)
8332     {
8333       match[15] = tag1_val[1];
8334       match[14] = tag1_val[0];
8335       if (proto)
8336         {
8337           match[17] = proto_val & 0xff;
8338           match[16] = proto_val >> 8;
8339         }
8340       if (cos1)
8341         match[14] |= (cos1_val & 0x7) << 5;
8342
8343       *matchp = match;
8344       return 1;
8345     }
8346   if (cos2)
8347     match[18] |= (cos2_val & 0x7) << 5;
8348   if (cos1)
8349     match[14] |= (cos1_val & 0x7) << 5;
8350   if (proto)
8351     {
8352       match[13] = proto_val & 0xff;
8353       match[12] = proto_val >> 8;
8354     }
8355
8356   *matchp = match;
8357   return 1;
8358 }
8359
8360
8361 uword
8362 unformat_classify_match (unformat_input_t * input, va_list * args)
8363 {
8364   u8 **matchp = va_arg (*args, u8 **);
8365   u32 skip_n_vectors = va_arg (*args, u32);
8366   u32 match_n_vectors = va_arg (*args, u32);
8367
8368   u8 *match = 0;
8369   u8 *l2 = 0;
8370   u8 *l3 = 0;
8371
8372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8373     {
8374       if (unformat (input, "hex %U", unformat_hex_string, &match))
8375         ;
8376       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8377         ;
8378       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8379         ;
8380       else
8381         break;
8382     }
8383
8384   if (match || l2 || l3)
8385     {
8386       if (l2 || l3)
8387         {
8388           /* "Win a free Ethernet header in every packet" */
8389           if (l2 == 0)
8390             vec_validate_aligned (l2, 13, sizeof (u32x4));
8391           match = l2;
8392           if (vec_len (l3))
8393             {
8394               vec_append_aligned (match, l3, sizeof (u32x4));
8395               vec_free (l3);
8396             }
8397         }
8398
8399       /* Make sure the vector is big enough even if key is all 0's */
8400       vec_validate_aligned
8401         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8402          sizeof (u32x4));
8403
8404       /* Set size, include skipped vectors */
8405       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8406
8407       *matchp = match;
8408
8409       return 1;
8410     }
8411
8412   return 0;
8413 }
8414
8415 static int
8416 api_classify_add_del_session (vat_main_t * vam)
8417 {
8418   unformat_input_t *i = vam->input;
8419   vl_api_classify_add_del_session_t *mp;
8420   int is_add = 1;
8421   u32 table_index = ~0;
8422   u32 hit_next_index = ~0;
8423   u32 opaque_index = ~0;
8424   u8 *match = 0;
8425   i32 advance = 0;
8426   f64 timeout;
8427   u32 skip_n_vectors = 0;
8428   u32 match_n_vectors = 0;
8429
8430   /*
8431    * Warning: you have to supply skip_n and match_n
8432    * because the API client cant simply look at the classify
8433    * table object.
8434    */
8435
8436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8437     {
8438       if (unformat (i, "del"))
8439         is_add = 0;
8440       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
8441                          &hit_next_index))
8442         ;
8443       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8444                          &hit_next_index))
8445         ;
8446       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
8447                          &hit_next_index))
8448         ;
8449       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8450         ;
8451       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8452         ;
8453       else if (unformat (i, "opaque-index %d", &opaque_index))
8454         ;
8455       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8456         ;
8457       else if (unformat (i, "match_n %d", &match_n_vectors))
8458         ;
8459       else if (unformat (i, "match %U", unformat_classify_match,
8460                          &match, skip_n_vectors, match_n_vectors))
8461         ;
8462       else if (unformat (i, "advance %d", &advance))
8463         ;
8464       else if (unformat (i, "table-index %d", &table_index))
8465         ;
8466       else
8467         break;
8468     }
8469
8470   if (table_index == ~0)
8471     {
8472       errmsg ("Table index required\n");
8473       return -99;
8474     }
8475
8476   if (is_add && match == 0)
8477     {
8478       errmsg ("Match value required\n");
8479       return -99;
8480     }
8481
8482   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
8483
8484   mp->is_add = is_add;
8485   mp->table_index = ntohl (table_index);
8486   mp->hit_next_index = ntohl (hit_next_index);
8487   mp->opaque_index = ntohl (opaque_index);
8488   mp->advance = ntohl (advance);
8489   clib_memcpy (mp->match, match, vec_len (match));
8490   vec_free (match);
8491
8492   S;
8493   W;
8494   /* NOTREACHED */
8495 }
8496
8497 static int
8498 api_classify_set_interface_ip_table (vat_main_t * vam)
8499 {
8500   unformat_input_t *i = vam->input;
8501   vl_api_classify_set_interface_ip_table_t *mp;
8502   f64 timeout;
8503   u32 sw_if_index;
8504   int sw_if_index_set;
8505   u32 table_index = ~0;
8506   u8 is_ipv6 = 0;
8507
8508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8509     {
8510       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8511         sw_if_index_set = 1;
8512       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8513         sw_if_index_set = 1;
8514       else if (unformat (i, "table %d", &table_index))
8515         ;
8516       else
8517         {
8518           clib_warning ("parse error '%U'", format_unformat_error, i);
8519           return -99;
8520         }
8521     }
8522
8523   if (sw_if_index_set == 0)
8524     {
8525       errmsg ("missing interface name or sw_if_index\n");
8526       return -99;
8527     }
8528
8529
8530   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
8531
8532   mp->sw_if_index = ntohl (sw_if_index);
8533   mp->table_index = ntohl (table_index);
8534   mp->is_ipv6 = is_ipv6;
8535
8536   S;
8537   W;
8538   /* NOTREACHED */
8539   return 0;
8540 }
8541
8542 static int
8543 api_classify_set_interface_l2_tables (vat_main_t * vam)
8544 {
8545   unformat_input_t *i = vam->input;
8546   vl_api_classify_set_interface_l2_tables_t *mp;
8547   f64 timeout;
8548   u32 sw_if_index;
8549   int sw_if_index_set;
8550   u32 ip4_table_index = ~0;
8551   u32 ip6_table_index = ~0;
8552   u32 other_table_index = ~0;
8553
8554   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8555     {
8556       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8557         sw_if_index_set = 1;
8558       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8559         sw_if_index_set = 1;
8560       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8561         ;
8562       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8563         ;
8564       else if (unformat (i, "other-table %d", &other_table_index))
8565         ;
8566       else
8567         {
8568           clib_warning ("parse error '%U'", format_unformat_error, i);
8569           return -99;
8570         }
8571     }
8572
8573   if (sw_if_index_set == 0)
8574     {
8575       errmsg ("missing interface name or sw_if_index\n");
8576       return -99;
8577     }
8578
8579
8580   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
8581
8582   mp->sw_if_index = ntohl (sw_if_index);
8583   mp->ip4_table_index = ntohl (ip4_table_index);
8584   mp->ip6_table_index = ntohl (ip6_table_index);
8585   mp->other_table_index = ntohl (other_table_index);
8586
8587
8588   S;
8589   W;
8590   /* NOTREACHED */
8591   return 0;
8592 }
8593
8594 static int
8595 api_ipfix_enable (vat_main_t * vam)
8596 {
8597   unformat_input_t *i = vam->input;
8598   vl_api_ipfix_enable_t *mp;
8599   ip4_address_t collector_address;
8600   u8 collector_address_set = 0;
8601   u32 collector_port = ~0;
8602   ip4_address_t src_address;
8603   u8 src_address_set = 0;
8604   u32 vrf_id = ~0;
8605   u32 path_mtu = ~0;
8606   u32 template_interval = ~0;
8607   f64 timeout;
8608
8609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8610     {
8611       if (unformat (i, "collector_address %U", unformat_ip4_address,
8612                     &collector_address))
8613         collector_address_set = 1;
8614       else if (unformat (i, "collector_port %d", &collector_port))
8615         ;
8616       else if (unformat (i, "src_address %U", unformat_ip4_address,
8617                          &src_address))
8618         src_address_set = 1;
8619       else if (unformat (i, "vrf_id %d", &vrf_id))
8620         ;
8621       else if (unformat (i, "path_mtu %d", &path_mtu))
8622         ;
8623       else if (unformat (i, "template_interval %d", &template_interval))
8624         ;
8625       else
8626         break;
8627     }
8628
8629   if (collector_address_set == 0)
8630     {
8631       errmsg ("collector_address required\n");
8632       return -99;
8633     }
8634
8635   if (src_address_set == 0)
8636     {
8637       errmsg ("src_address required\n");
8638       return -99;
8639     }
8640
8641   M (IPFIX_ENABLE, ipfix_enable);
8642
8643   memcpy (mp->collector_address, collector_address.data,
8644           sizeof (collector_address.data));
8645   mp->collector_port = htons ((u16) collector_port);
8646   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
8647   mp->vrf_id = htonl (vrf_id);
8648   mp->path_mtu = htonl (path_mtu);
8649   mp->template_interval = htonl (template_interval);
8650
8651   S;
8652   W;
8653   /* NOTREACHED */
8654 }
8655
8656 static int
8657 api_get_node_index (vat_main_t * vam)
8658 {
8659   unformat_input_t *i = vam->input;
8660   vl_api_get_node_index_t *mp;
8661   f64 timeout;
8662   u8 *name = 0;
8663
8664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8665     {
8666       if (unformat (i, "node %s", &name))
8667         ;
8668       else
8669         break;
8670     }
8671   if (name == 0)
8672     {
8673       errmsg ("node name required\n");
8674       return -99;
8675     }
8676   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8677     {
8678       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8679       return -99;
8680     }
8681
8682   M (GET_NODE_INDEX, get_node_index);
8683   clib_memcpy (mp->node_name, name, vec_len (name));
8684   vec_free (name);
8685
8686   S;
8687   W;
8688   /* NOTREACHED */
8689   return 0;
8690 }
8691
8692 static int
8693 api_get_next_index (vat_main_t * vam)
8694 {
8695   unformat_input_t *i = vam->input;
8696   vl_api_get_next_index_t *mp;
8697   f64 timeout;
8698   u8 *node_name = 0, *next_node_name = 0;
8699
8700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8701     {
8702       if (unformat (i, "node-name %s", &node_name))
8703         ;
8704       else if (unformat (i, "next-node-name %s", &next_node_name))
8705         break;
8706     }
8707
8708   if (node_name == 0)
8709     {
8710       errmsg ("node name required\n");
8711       return -99;
8712     }
8713   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
8714     {
8715       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8716       return -99;
8717     }
8718
8719   if (next_node_name == 0)
8720     {
8721       errmsg ("next node name required\n");
8722       return -99;
8723     }
8724   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
8725     {
8726       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
8727       return -99;
8728     }
8729
8730   M (GET_NEXT_INDEX, get_next_index);
8731   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
8732   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
8733   vec_free (node_name);
8734   vec_free (next_node_name);
8735
8736   S;
8737   W;
8738   /* NOTREACHED */
8739   return 0;
8740 }
8741
8742 static int
8743 api_add_node_next (vat_main_t * vam)
8744 {
8745   unformat_input_t *i = vam->input;
8746   vl_api_add_node_next_t *mp;
8747   f64 timeout;
8748   u8 *name = 0;
8749   u8 *next = 0;
8750
8751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8752     {
8753       if (unformat (i, "node %s", &name))
8754         ;
8755       else if (unformat (i, "next %s", &next))
8756         ;
8757       else
8758         break;
8759     }
8760   if (name == 0)
8761     {
8762       errmsg ("node name required\n");
8763       return -99;
8764     }
8765   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
8766     {
8767       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
8768       return -99;
8769     }
8770   if (next == 0)
8771     {
8772       errmsg ("next node required\n");
8773       return -99;
8774     }
8775   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
8776     {
8777       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
8778       return -99;
8779     }
8780
8781   M (ADD_NODE_NEXT, add_node_next);
8782   clib_memcpy (mp->node_name, name, vec_len (name));
8783   clib_memcpy (mp->next_name, next, vec_len (next));
8784   vec_free (name);
8785   vec_free (next);
8786
8787   S;
8788   W;
8789   /* NOTREACHED */
8790   return 0;
8791 }
8792
8793 static int
8794 api_l2tpv3_create_tunnel (vat_main_t * vam)
8795 {
8796   unformat_input_t *i = vam->input;
8797   ip6_address_t client_address, our_address;
8798   int client_address_set = 0;
8799   int our_address_set = 0;
8800   u32 local_session_id = 0;
8801   u32 remote_session_id = 0;
8802   u64 local_cookie = 0;
8803   u64 remote_cookie = 0;
8804   u8 l2_sublayer_present = 0;
8805   vl_api_l2tpv3_create_tunnel_t *mp;
8806   f64 timeout;
8807
8808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8809     {
8810       if (unformat (i, "client_address %U", unformat_ip6_address,
8811                     &client_address))
8812         client_address_set = 1;
8813       else if (unformat (i, "our_address %U", unformat_ip6_address,
8814                          &our_address))
8815         our_address_set = 1;
8816       else if (unformat (i, "local_session_id %d", &local_session_id))
8817         ;
8818       else if (unformat (i, "remote_session_id %d", &remote_session_id))
8819         ;
8820       else if (unformat (i, "local_cookie %lld", &local_cookie))
8821         ;
8822       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
8823         ;
8824       else if (unformat (i, "l2-sublayer-present"))
8825         l2_sublayer_present = 1;
8826       else
8827         break;
8828     }
8829
8830   if (client_address_set == 0)
8831     {
8832       errmsg ("client_address required\n");
8833       return -99;
8834     }
8835
8836   if (our_address_set == 0)
8837     {
8838       errmsg ("our_address required\n");
8839       return -99;
8840     }
8841
8842   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
8843
8844   clib_memcpy (mp->client_address, client_address.as_u8,
8845                sizeof (mp->client_address));
8846
8847   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
8848
8849   mp->local_session_id = ntohl (local_session_id);
8850   mp->remote_session_id = ntohl (remote_session_id);
8851   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
8852   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
8853   mp->l2_sublayer_present = l2_sublayer_present;
8854   mp->is_ipv6 = 1;
8855
8856   S;
8857   W;
8858   /* NOTREACHED */
8859   return 0;
8860 }
8861
8862 static int
8863 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
8864 {
8865   unformat_input_t *i = vam->input;
8866   u32 sw_if_index;
8867   u8 sw_if_index_set = 0;
8868   u64 new_local_cookie = 0;
8869   u64 new_remote_cookie = 0;
8870   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
8871   f64 timeout;
8872
8873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8874     {
8875       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8876         sw_if_index_set = 1;
8877       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8878         sw_if_index_set = 1;
8879       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
8880         ;
8881       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
8882         ;
8883       else
8884         break;
8885     }
8886
8887   if (sw_if_index_set == 0)
8888     {
8889       errmsg ("missing interface name or sw_if_index\n");
8890       return -99;
8891     }
8892
8893   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
8894
8895   mp->sw_if_index = ntohl (sw_if_index);
8896   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
8897   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
8898
8899   S;
8900   W;
8901   /* NOTREACHED */
8902   return 0;
8903 }
8904
8905 static int
8906 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
8907 {
8908   unformat_input_t *i = vam->input;
8909   vl_api_l2tpv3_interface_enable_disable_t *mp;
8910   f64 timeout;
8911   u32 sw_if_index;
8912   u8 sw_if_index_set = 0;
8913   u8 enable_disable = 1;
8914
8915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8916     {
8917       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
8918         sw_if_index_set = 1;
8919       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8920         sw_if_index_set = 1;
8921       else if (unformat (i, "enable"))
8922         enable_disable = 1;
8923       else if (unformat (i, "disable"))
8924         enable_disable = 0;
8925       else
8926         break;
8927     }
8928
8929   if (sw_if_index_set == 0)
8930     {
8931       errmsg ("missing interface name or sw_if_index\n");
8932       return -99;
8933     }
8934
8935   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
8936
8937   mp->sw_if_index = ntohl (sw_if_index);
8938   mp->enable_disable = enable_disable;
8939
8940   S;
8941   W;
8942   /* NOTREACHED */
8943   return 0;
8944 }
8945
8946 static int
8947 api_l2tpv3_set_lookup_key (vat_main_t * vam)
8948 {
8949   unformat_input_t *i = vam->input;
8950   vl_api_l2tpv3_set_lookup_key_t *mp;
8951   f64 timeout;
8952   u8 key = ~0;
8953
8954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8955     {
8956       if (unformat (i, "lookup_v6_src"))
8957         key = L2T_LOOKUP_SRC_ADDRESS;
8958       else if (unformat (i, "lookup_v6_dst"))
8959         key = L2T_LOOKUP_DST_ADDRESS;
8960       else if (unformat (i, "lookup_session_id"))
8961         key = L2T_LOOKUP_SESSION_ID;
8962       else
8963         break;
8964     }
8965
8966   if (key == (u8) ~ 0)
8967     {
8968       errmsg ("l2tp session lookup key unset\n");
8969       return -99;
8970     }
8971
8972   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
8973
8974   mp->key = key;
8975
8976   S;
8977   W;
8978   /* NOTREACHED */
8979   return 0;
8980 }
8981
8982 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
8983   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
8984 {
8985   vat_main_t *vam = &vat_main;
8986
8987   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
8988            format_ip6_address, mp->our_address,
8989            format_ip6_address, mp->client_address,
8990            clib_net_to_host_u32 (mp->sw_if_index));
8991
8992   fformat (vam->ofp,
8993            "   local cookies %016llx %016llx remote cookie %016llx\n",
8994            clib_net_to_host_u64 (mp->local_cookie[0]),
8995            clib_net_to_host_u64 (mp->local_cookie[1]),
8996            clib_net_to_host_u64 (mp->remote_cookie));
8997
8998   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
8999            clib_net_to_host_u32 (mp->local_session_id),
9000            clib_net_to_host_u32 (mp->remote_session_id));
9001
9002   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9003            mp->l2_sublayer_present ? "preset" : "absent");
9004
9005 }
9006
9007 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9008   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9009 {
9010   vat_main_t *vam = &vat_main;
9011   vat_json_node_t *node = NULL;
9012   struct in6_addr addr;
9013
9014   if (VAT_JSON_ARRAY != vam->json_tree.type)
9015     {
9016       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9017       vat_json_init_array (&vam->json_tree);
9018     }
9019   node = vat_json_array_add (&vam->json_tree);
9020
9021   vat_json_init_object (node);
9022
9023   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9024   vat_json_object_add_ip6 (node, "our_address", addr);
9025   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9026   vat_json_object_add_ip6 (node, "client_address", addr);
9027
9028   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9029   vat_json_init_array (lc);
9030   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9031   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9032   vat_json_object_add_uint (node, "remote_cookie",
9033                             clib_net_to_host_u64 (mp->remote_cookie));
9034
9035   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9036   vat_json_object_add_uint (node, "local_session_id",
9037                             clib_net_to_host_u32 (mp->local_session_id));
9038   vat_json_object_add_uint (node, "remote_session_id",
9039                             clib_net_to_host_u32 (mp->remote_session_id));
9040   vat_json_object_add_string_copy (node, "l2_sublayer",
9041                                    mp->l2_sublayer_present ? (u8 *) "present"
9042                                    : (u8 *) "absent");
9043 }
9044
9045 static int
9046 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9047 {
9048   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9049   f64 timeout;
9050
9051   /* Get list of l2tpv3-tunnel interfaces */
9052   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9053   S;
9054
9055   /* Use a control ping for synchronization */
9056   {
9057     vl_api_control_ping_t *mp;
9058     M (CONTROL_PING, control_ping);
9059     S;
9060   }
9061   W;
9062 }
9063
9064
9065 static void vl_api_sw_interface_tap_details_t_handler
9066   (vl_api_sw_interface_tap_details_t * mp)
9067 {
9068   vat_main_t *vam = &vat_main;
9069
9070   fformat (vam->ofp, "%-16s %d\n",
9071            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9072 }
9073
9074 static void vl_api_sw_interface_tap_details_t_handler_json
9075   (vl_api_sw_interface_tap_details_t * mp)
9076 {
9077   vat_main_t *vam = &vat_main;
9078   vat_json_node_t *node = NULL;
9079
9080   if (VAT_JSON_ARRAY != vam->json_tree.type)
9081     {
9082       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9083       vat_json_init_array (&vam->json_tree);
9084     }
9085   node = vat_json_array_add (&vam->json_tree);
9086
9087   vat_json_init_object (node);
9088   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9089   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9090 }
9091
9092 static int
9093 api_sw_interface_tap_dump (vat_main_t * vam)
9094 {
9095   vl_api_sw_interface_tap_dump_t *mp;
9096   f64 timeout;
9097
9098   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
9099   /* Get list of tap interfaces */
9100   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
9101   S;
9102
9103   /* Use a control ping for synchronization */
9104   {
9105     vl_api_control_ping_t *mp;
9106     M (CONTROL_PING, control_ping);
9107     S;
9108   }
9109   W;
9110 }
9111
9112 static uword unformat_vxlan_decap_next
9113   (unformat_input_t * input, va_list * args)
9114 {
9115   u32 *result = va_arg (*args, u32 *);
9116   u32 tmp;
9117
9118   if (unformat (input, "drop"))
9119     *result = VXLAN_INPUT_NEXT_DROP;
9120   else if (unformat (input, "ip4"))
9121     *result = VXLAN_INPUT_NEXT_IP4_INPUT;
9122   else if (unformat (input, "ip6"))
9123     *result = VXLAN_INPUT_NEXT_IP6_INPUT;
9124   else if (unformat (input, "l2"))
9125     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9126   else if (unformat (input, "%d", &tmp))
9127     *result = tmp;
9128   else
9129     return 0;
9130   return 1;
9131 }
9132
9133 static int
9134 api_vxlan_add_del_tunnel (vat_main_t * vam)
9135 {
9136   unformat_input_t *line_input = vam->input;
9137   vl_api_vxlan_add_del_tunnel_t *mp;
9138   f64 timeout;
9139   ip4_address_t src4, dst4;
9140   ip6_address_t src6, dst6;
9141   u8 is_add = 1;
9142   u8 ipv4_set = 0, ipv6_set = 0;
9143   u8 src_set = 0;
9144   u8 dst_set = 0;
9145   u32 encap_vrf_id = 0;
9146   u32 decap_next_index = ~0;
9147   u32 vni = 0;
9148
9149   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9150     {
9151       if (unformat (line_input, "del"))
9152         is_add = 0;
9153       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9154         {
9155           ipv4_set = 1;
9156           src_set = 1;
9157         }
9158       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9159         {
9160           ipv4_set = 1;
9161           dst_set = 1;
9162         }
9163       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
9164         {
9165           ipv6_set = 1;
9166           src_set = 1;
9167         }
9168       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
9169         {
9170           ipv6_set = 1;
9171           dst_set = 1;
9172         }
9173       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9174         ;
9175       else if (unformat (line_input, "decap-next %U",
9176                          unformat_vxlan_decap_next, &decap_next_index))
9177         ;
9178       else if (unformat (line_input, "vni %d", &vni))
9179         ;
9180       else
9181         {
9182           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9183           return -99;
9184         }
9185     }
9186
9187   if (src_set == 0)
9188     {
9189       errmsg ("tunnel src address not specified\n");
9190       return -99;
9191     }
9192   if (dst_set == 0)
9193     {
9194       errmsg ("tunnel dst address not specified\n");
9195       return -99;
9196     }
9197
9198   if (ipv4_set && ipv6_set)
9199     {
9200       errmsg ("both IPv4 and IPv6 addresses specified");
9201       return -99;
9202     }
9203
9204   if ((vni == 0) || (vni >> 24))
9205     {
9206       errmsg ("vni not specified or out of range\n");
9207       return -99;
9208     }
9209
9210   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
9211
9212   if (ipv6_set)
9213     {
9214       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
9215       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
9216     }
9217   else
9218     {
9219       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9220       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9221     }
9222   mp->encap_vrf_id = ntohl (encap_vrf_id);
9223   mp->decap_next_index = ntohl (decap_next_index);
9224   mp->vni = ntohl (vni);
9225   mp->is_add = is_add;
9226   mp->is_ipv6 = ipv6_set;
9227
9228   S;
9229   W;
9230   /* NOTREACHED */
9231   return 0;
9232 }
9233
9234 static void vl_api_vxlan_tunnel_details_t_handler
9235   (vl_api_vxlan_tunnel_details_t * mp)
9236 {
9237   vat_main_t *vam = &vat_main;
9238
9239   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
9240            ntohl (mp->sw_if_index),
9241            format_ip46_address, &(mp->src_address[0]),
9242            IP46_TYPE_ANY,
9243            format_ip46_address, &(mp->dst_address[0]),
9244            IP46_TYPE_ANY,
9245            ntohl (mp->encap_vrf_id),
9246            ntohl (mp->decap_next_index), ntohl (mp->vni));
9247 }
9248
9249 static void vl_api_vxlan_tunnel_details_t_handler_json
9250   (vl_api_vxlan_tunnel_details_t * mp)
9251 {
9252   vat_main_t *vam = &vat_main;
9253   vat_json_node_t *node = NULL;
9254   struct in_addr ip4;
9255   struct in6_addr ip6;
9256
9257   if (VAT_JSON_ARRAY != vam->json_tree.type)
9258     {
9259       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9260       vat_json_init_array (&vam->json_tree);
9261     }
9262   node = vat_json_array_add (&vam->json_tree);
9263
9264   vat_json_init_object (node);
9265   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9266   if (mp->is_ipv6)
9267     {
9268       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
9269       vat_json_object_add_ip6 (node, "src_address", ip6);
9270       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
9271       vat_json_object_add_ip6 (node, "dst_address", ip6);
9272     }
9273   else
9274     {
9275       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
9276       vat_json_object_add_ip4 (node, "src_address", ip4);
9277       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
9278       vat_json_object_add_ip4 (node, "dst_address", ip4);
9279     }
9280   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9281   vat_json_object_add_uint (node, "decap_next_index",
9282                             ntohl (mp->decap_next_index));
9283   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9284   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
9285 }
9286
9287 static int
9288 api_vxlan_tunnel_dump (vat_main_t * vam)
9289 {
9290   unformat_input_t *i = vam->input;
9291   vl_api_vxlan_tunnel_dump_t *mp;
9292   f64 timeout;
9293   u32 sw_if_index;
9294   u8 sw_if_index_set = 0;
9295
9296   /* Parse args required to build the message */
9297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9298     {
9299       if (unformat (i, "sw_if_index %d", &sw_if_index))
9300         sw_if_index_set = 1;
9301       else
9302         break;
9303     }
9304
9305   if (sw_if_index_set == 0)
9306     {
9307       sw_if_index = ~0;
9308     }
9309
9310   if (!vam->json_output)
9311     {
9312       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
9313                "sw_if_index", "src_address", "dst_address",
9314                "encap_vrf_id", "decap_next_index", "vni");
9315     }
9316
9317   /* Get list of vxlan-tunnel interfaces */
9318   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
9319
9320   mp->sw_if_index = htonl (sw_if_index);
9321
9322   S;
9323
9324   /* Use a control ping for synchronization */
9325   {
9326     vl_api_control_ping_t *mp;
9327     M (CONTROL_PING, control_ping);
9328     S;
9329   }
9330   W;
9331 }
9332
9333 static int
9334 api_gre_add_del_tunnel (vat_main_t * vam)
9335 {
9336   unformat_input_t *line_input = vam->input;
9337   vl_api_gre_add_del_tunnel_t *mp;
9338   f64 timeout;
9339   ip4_address_t src4, dst4;
9340   u8 is_add = 1;
9341   u8 src_set = 0;
9342   u8 dst_set = 0;
9343   u32 outer_fib_id = 0;
9344
9345   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9346     {
9347       if (unformat (line_input, "del"))
9348         is_add = 0;
9349       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
9350         src_set = 1;
9351       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
9352         dst_set = 1;
9353       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
9354         ;
9355       else
9356         {
9357           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9358           return -99;
9359         }
9360     }
9361
9362   if (src_set == 0)
9363     {
9364       errmsg ("tunnel src address not specified\n");
9365       return -99;
9366     }
9367   if (dst_set == 0)
9368     {
9369       errmsg ("tunnel dst address not specified\n");
9370       return -99;
9371     }
9372
9373
9374   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
9375
9376   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
9377   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
9378   mp->outer_fib_id = ntohl (outer_fib_id);
9379   mp->is_add = is_add;
9380
9381   S;
9382   W;
9383   /* NOTREACHED */
9384   return 0;
9385 }
9386
9387 static void vl_api_gre_tunnel_details_t_handler
9388   (vl_api_gre_tunnel_details_t * mp)
9389 {
9390   vat_main_t *vam = &vat_main;
9391
9392   fformat (vam->ofp, "%11d%15U%15U%14d\n",
9393            ntohl (mp->sw_if_index),
9394            format_ip4_address, &mp->src_address,
9395            format_ip4_address, &mp->dst_address, ntohl (mp->outer_fib_id));
9396 }
9397
9398 static void vl_api_gre_tunnel_details_t_handler_json
9399   (vl_api_gre_tunnel_details_t * mp)
9400 {
9401   vat_main_t *vam = &vat_main;
9402   vat_json_node_t *node = NULL;
9403   struct in_addr ip4;
9404
9405   if (VAT_JSON_ARRAY != vam->json_tree.type)
9406     {
9407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9408       vat_json_init_array (&vam->json_tree);
9409     }
9410   node = vat_json_array_add (&vam->json_tree);
9411
9412   vat_json_init_object (node);
9413   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9414   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
9415   vat_json_object_add_ip4 (node, "src_address", ip4);
9416   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
9417   vat_json_object_add_ip4 (node, "dst_address", ip4);
9418   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
9419 }
9420
9421 static int
9422 api_gre_tunnel_dump (vat_main_t * vam)
9423 {
9424   unformat_input_t *i = vam->input;
9425   vl_api_gre_tunnel_dump_t *mp;
9426   f64 timeout;
9427   u32 sw_if_index;
9428   u8 sw_if_index_set = 0;
9429
9430   /* Parse args required to build the message */
9431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9432     {
9433       if (unformat (i, "sw_if_index %d", &sw_if_index))
9434         sw_if_index_set = 1;
9435       else
9436         break;
9437     }
9438
9439   if (sw_if_index_set == 0)
9440     {
9441       sw_if_index = ~0;
9442     }
9443
9444   if (!vam->json_output)
9445     {
9446       fformat (vam->ofp, "%11s%15s%15s%14s\n",
9447                "sw_if_index", "src_address", "dst_address", "outer_fib_id");
9448     }
9449
9450   /* Get list of gre-tunnel interfaces */
9451   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
9452
9453   mp->sw_if_index = htonl (sw_if_index);
9454
9455   S;
9456
9457   /* Use a control ping for synchronization */
9458   {
9459     vl_api_control_ping_t *mp;
9460     M (CONTROL_PING, control_ping);
9461     S;
9462   }
9463   W;
9464 }
9465
9466 static int
9467 api_l2_fib_clear_table (vat_main_t * vam)
9468 {
9469 //  unformat_input_t * i = vam->input;
9470   vl_api_l2_fib_clear_table_t *mp;
9471   f64 timeout;
9472
9473   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
9474
9475   S;
9476   W;
9477   /* NOTREACHED */
9478   return 0;
9479 }
9480
9481 static int
9482 api_l2_interface_efp_filter (vat_main_t * vam)
9483 {
9484   unformat_input_t *i = vam->input;
9485   vl_api_l2_interface_efp_filter_t *mp;
9486   f64 timeout;
9487   u32 sw_if_index;
9488   u8 enable = 1;
9489   u8 sw_if_index_set = 0;
9490
9491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9492     {
9493       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9494         sw_if_index_set = 1;
9495       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9496         sw_if_index_set = 1;
9497       else if (unformat (i, "enable"))
9498         enable = 1;
9499       else if (unformat (i, "disable"))
9500         enable = 0;
9501       else
9502         {
9503           clib_warning ("parse error '%U'", format_unformat_error, i);
9504           return -99;
9505         }
9506     }
9507
9508   if (sw_if_index_set == 0)
9509     {
9510       errmsg ("missing sw_if_index\n");
9511       return -99;
9512     }
9513
9514   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
9515
9516   mp->sw_if_index = ntohl (sw_if_index);
9517   mp->enable_disable = enable;
9518
9519   S;
9520   W;
9521   /* NOTREACHED */
9522   return 0;
9523 }
9524
9525 #define foreach_vtr_op                          \
9526 _("disable",  L2_VTR_DISABLED)                  \
9527 _("push-1",  L2_VTR_PUSH_1)                     \
9528 _("push-2",  L2_VTR_PUSH_2)                     \
9529 _("pop-1",  L2_VTR_POP_1)                       \
9530 _("pop-2",  L2_VTR_POP_2)                       \
9531 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9532 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9533 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9534 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9535
9536 static int
9537 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9538 {
9539   unformat_input_t *i = vam->input;
9540   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9541   f64 timeout;
9542   u32 sw_if_index;
9543   u8 sw_if_index_set = 0;
9544   u8 vtr_op_set = 0;
9545   u32 vtr_op = 0;
9546   u32 push_dot1q = 1;
9547   u32 tag1 = ~0;
9548   u32 tag2 = ~0;
9549
9550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9551     {
9552       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9553         sw_if_index_set = 1;
9554       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9555         sw_if_index_set = 1;
9556       else if (unformat (i, "vtr_op %d", &vtr_op))
9557         vtr_op_set = 1;
9558 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9559       foreach_vtr_op
9560 #undef _
9561         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9562         ;
9563       else if (unformat (i, "tag1 %d", &tag1))
9564         ;
9565       else if (unformat (i, "tag2 %d", &tag2))
9566         ;
9567       else
9568         {
9569           clib_warning ("parse error '%U'", format_unformat_error, i);
9570           return -99;
9571         }
9572     }
9573
9574   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9575     {
9576       errmsg ("missing vtr operation or sw_if_index\n");
9577       return -99;
9578     }
9579
9580   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
9581     mp->sw_if_index = ntohl (sw_if_index);
9582   mp->vtr_op = ntohl (vtr_op);
9583   mp->push_dot1q = ntohl (push_dot1q);
9584   mp->tag1 = ntohl (tag1);
9585   mp->tag2 = ntohl (tag2);
9586
9587   S;
9588   W;
9589   /* NOTREACHED */
9590   return 0;
9591 }
9592
9593 static int
9594 api_create_vhost_user_if (vat_main_t * vam)
9595 {
9596   unformat_input_t *i = vam->input;
9597   vl_api_create_vhost_user_if_t *mp;
9598   f64 timeout;
9599   u8 *file_name;
9600   u8 is_server = 0;
9601   u8 file_name_set = 0;
9602   u32 custom_dev_instance = ~0;
9603   u8 hwaddr[6];
9604   u8 use_custom_mac = 0;
9605
9606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9607     {
9608       if (unformat (i, "socket %s", &file_name))
9609         {
9610           file_name_set = 1;
9611         }
9612       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9613         ;
9614       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9615         use_custom_mac = 1;
9616       else if (unformat (i, "server"))
9617         is_server = 1;
9618       else
9619         break;
9620     }
9621
9622   if (file_name_set == 0)
9623     {
9624       errmsg ("missing socket file name\n");
9625       return -99;
9626     }
9627
9628   if (vec_len (file_name) > 255)
9629     {
9630       errmsg ("socket file name too long\n");
9631       return -99;
9632     }
9633   vec_add1 (file_name, 0);
9634
9635   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
9636
9637   mp->is_server = is_server;
9638   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9639   vec_free (file_name);
9640   if (custom_dev_instance != ~0)
9641     {
9642       mp->renumber = 1;
9643       mp->custom_dev_instance = ntohl (custom_dev_instance);
9644     }
9645   mp->use_custom_mac = use_custom_mac;
9646   clib_memcpy (mp->mac_address, hwaddr, 6);
9647
9648   S;
9649   W;
9650   /* NOTREACHED */
9651   return 0;
9652 }
9653
9654 static int
9655 api_modify_vhost_user_if (vat_main_t * vam)
9656 {
9657   unformat_input_t *i = vam->input;
9658   vl_api_modify_vhost_user_if_t *mp;
9659   f64 timeout;
9660   u8 *file_name;
9661   u8 is_server = 0;
9662   u8 file_name_set = 0;
9663   u32 custom_dev_instance = ~0;
9664   u8 sw_if_index_set = 0;
9665   u32 sw_if_index = (u32) ~ 0;
9666
9667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9668     {
9669       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9670         sw_if_index_set = 1;
9671       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9672         sw_if_index_set = 1;
9673       else if (unformat (i, "socket %s", &file_name))
9674         {
9675           file_name_set = 1;
9676         }
9677       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9678         ;
9679       else if (unformat (i, "server"))
9680         is_server = 1;
9681       else
9682         break;
9683     }
9684
9685   if (sw_if_index_set == 0)
9686     {
9687       errmsg ("missing sw_if_index or interface name\n");
9688       return -99;
9689     }
9690
9691   if (file_name_set == 0)
9692     {
9693       errmsg ("missing socket file name\n");
9694       return -99;
9695     }
9696
9697   if (vec_len (file_name) > 255)
9698     {
9699       errmsg ("socket file name too long\n");
9700       return -99;
9701     }
9702   vec_add1 (file_name, 0);
9703
9704   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
9705
9706   mp->sw_if_index = ntohl (sw_if_index);
9707   mp->is_server = is_server;
9708   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9709   vec_free (file_name);
9710   if (custom_dev_instance != ~0)
9711     {
9712       mp->renumber = 1;
9713       mp->custom_dev_instance = ntohl (custom_dev_instance);
9714     }
9715
9716   S;
9717   W;
9718   /* NOTREACHED */
9719   return 0;
9720 }
9721
9722 static int
9723 api_delete_vhost_user_if (vat_main_t * vam)
9724 {
9725   unformat_input_t *i = vam->input;
9726   vl_api_delete_vhost_user_if_t *mp;
9727   f64 timeout;
9728   u32 sw_if_index = ~0;
9729   u8 sw_if_index_set = 0;
9730
9731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9732     {
9733       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9734         sw_if_index_set = 1;
9735       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9736         sw_if_index_set = 1;
9737       else
9738         break;
9739     }
9740
9741   if (sw_if_index_set == 0)
9742     {
9743       errmsg ("missing sw_if_index or interface name\n");
9744       return -99;
9745     }
9746
9747
9748   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
9749
9750   mp->sw_if_index = ntohl (sw_if_index);
9751
9752   S;
9753   W;
9754   /* NOTREACHED */
9755   return 0;
9756 }
9757
9758 static void vl_api_sw_interface_vhost_user_details_t_handler
9759   (vl_api_sw_interface_vhost_user_details_t * mp)
9760 {
9761   vat_main_t *vam = &vat_main;
9762
9763   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
9764            (char *) mp->interface_name,
9765            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
9766            clib_net_to_host_u64 (mp->features), mp->is_server,
9767            ntohl (mp->num_regions), (char *) mp->sock_filename);
9768   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
9769 }
9770
9771 static void vl_api_sw_interface_vhost_user_details_t_handler_json
9772   (vl_api_sw_interface_vhost_user_details_t * mp)
9773 {
9774   vat_main_t *vam = &vat_main;
9775   vat_json_node_t *node = NULL;
9776
9777   if (VAT_JSON_ARRAY != vam->json_tree.type)
9778     {
9779       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9780       vat_json_init_array (&vam->json_tree);
9781     }
9782   node = vat_json_array_add (&vam->json_tree);
9783
9784   vat_json_init_object (node);
9785   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9786   vat_json_object_add_string_copy (node, "interface_name",
9787                                    mp->interface_name);
9788   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
9789                             ntohl (mp->virtio_net_hdr_sz));
9790   vat_json_object_add_uint (node, "features",
9791                             clib_net_to_host_u64 (mp->features));
9792   vat_json_object_add_uint (node, "is_server", mp->is_server);
9793   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
9794   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
9795   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
9796 }
9797
9798 static int
9799 api_sw_interface_vhost_user_dump (vat_main_t * vam)
9800 {
9801   vl_api_sw_interface_vhost_user_dump_t *mp;
9802   f64 timeout;
9803   fformat (vam->ofp,
9804            "Interface name           idx hdr_sz features server regions filename\n");
9805
9806   /* Get list of vhost-user interfaces */
9807   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
9808   S;
9809
9810   /* Use a control ping for synchronization */
9811   {
9812     vl_api_control_ping_t *mp;
9813     M (CONTROL_PING, control_ping);
9814     S;
9815   }
9816   W;
9817 }
9818
9819 static int
9820 api_show_version (vat_main_t * vam)
9821 {
9822   vl_api_show_version_t *mp;
9823   f64 timeout;
9824
9825   M (SHOW_VERSION, show_version);
9826
9827   S;
9828   W;
9829   /* NOTREACHED */
9830   return 0;
9831 }
9832
9833
9834 static int
9835 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
9836 {
9837   unformat_input_t *line_input = vam->input;
9838   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
9839   f64 timeout;
9840   ip4_address_t local4, remote4;
9841   ip6_address_t local6, remote6;
9842   u8 is_add = 1;
9843   u8 ipv4_set = 0, ipv6_set = 0;
9844   u8 local_set = 0;
9845   u8 remote_set = 0;
9846   u32 encap_vrf_id = 0;
9847   u32 decap_vrf_id = 0;
9848   u8 protocol = ~0;
9849   u32 vni;
9850   u8 vni_set = 0;
9851
9852   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9853     {
9854       if (unformat (line_input, "del"))
9855         is_add = 0;
9856       else if (unformat (line_input, "local %U",
9857                          unformat_ip4_address, &local4))
9858         {
9859           local_set = 1;
9860           ipv4_set = 1;
9861         }
9862       else if (unformat (line_input, "remote %U",
9863                          unformat_ip4_address, &remote4))
9864         {
9865           remote_set = 1;
9866           ipv4_set = 1;
9867         }
9868       else if (unformat (line_input, "local %U",
9869                          unformat_ip6_address, &local6))
9870         {
9871           local_set = 1;
9872           ipv6_set = 1;
9873         }
9874       else if (unformat (line_input, "remote %U",
9875                          unformat_ip6_address, &remote6))
9876         {
9877           remote_set = 1;
9878           ipv6_set = 1;
9879         }
9880       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9881         ;
9882       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
9883         ;
9884       else if (unformat (line_input, "vni %d", &vni))
9885         vni_set = 1;
9886       else if (unformat (line_input, "next-ip4"))
9887         protocol = 1;
9888       else if (unformat (line_input, "next-ip6"))
9889         protocol = 2;
9890       else if (unformat (line_input, "next-ethernet"))
9891         protocol = 3;
9892       else if (unformat (line_input, "next-nsh"))
9893         protocol = 4;
9894       else
9895         {
9896           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
9897           return -99;
9898         }
9899     }
9900
9901   if (local_set == 0)
9902     {
9903       errmsg ("tunnel local address not specified\n");
9904       return -99;
9905     }
9906   if (remote_set == 0)
9907     {
9908       errmsg ("tunnel remote address not specified\n");
9909       return -99;
9910     }
9911   if (ipv4_set && ipv6_set)
9912     {
9913       errmsg ("both IPv4 and IPv6 addresses specified");
9914       return -99;
9915     }
9916
9917   if (vni_set == 0)
9918     {
9919       errmsg ("vni not specified\n");
9920       return -99;
9921     }
9922
9923   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
9924
9925
9926   if (ipv6_set)
9927     {
9928       clib_memcpy (&mp->local, &local6, sizeof (local6));
9929       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
9930     }
9931   else
9932     {
9933       clib_memcpy (&mp->local, &local4, sizeof (local4));
9934       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
9935     }
9936
9937   mp->encap_vrf_id = ntohl (encap_vrf_id);
9938   mp->decap_vrf_id = ntohl (decap_vrf_id);
9939   mp->protocol = ntohl (protocol);
9940   mp->vni = ntohl (vni);
9941   mp->is_add = is_add;
9942   mp->is_ipv6 = ipv6_set;
9943
9944   S;
9945   W;
9946   /* NOTREACHED */
9947   return 0;
9948 }
9949
9950 static void vl_api_vxlan_gpe_tunnel_details_t_handler
9951   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9952 {
9953   vat_main_t *vam = &vat_main;
9954
9955   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
9956            ntohl (mp->sw_if_index),
9957            format_ip46_address, &(mp->local[0]),
9958            format_ip46_address, &(mp->remote[0]),
9959            ntohl (mp->vni),
9960            ntohl (mp->protocol),
9961            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
9962 }
9963
9964 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
9965   (vl_api_vxlan_gpe_tunnel_details_t * mp)
9966 {
9967   vat_main_t *vam = &vat_main;
9968   vat_json_node_t *node = NULL;
9969   struct in_addr ip4;
9970   struct in6_addr ip6;
9971
9972   if (VAT_JSON_ARRAY != vam->json_tree.type)
9973     {
9974       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9975       vat_json_init_array (&vam->json_tree);
9976     }
9977   node = vat_json_array_add (&vam->json_tree);
9978
9979   vat_json_init_object (node);
9980   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9981   if (mp->is_ipv6)
9982     {
9983       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
9984       vat_json_object_add_ip6 (node, "local", ip6);
9985       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
9986       vat_json_object_add_ip6 (node, "remote", ip6);
9987     }
9988   else
9989     {
9990       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
9991       vat_json_object_add_ip4 (node, "local", ip4);
9992       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
9993       vat_json_object_add_ip4 (node, "remote", ip4);
9994     }
9995   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9996   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
9997   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9998   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
9999   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10000 }
10001
10002 static int
10003 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10004 {
10005   unformat_input_t *i = vam->input;
10006   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10007   f64 timeout;
10008   u32 sw_if_index;
10009   u8 sw_if_index_set = 0;
10010
10011   /* Parse args required to build the message */
10012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10013     {
10014       if (unformat (i, "sw_if_index %d", &sw_if_index))
10015         sw_if_index_set = 1;
10016       else
10017         break;
10018     }
10019
10020   if (sw_if_index_set == 0)
10021     {
10022       sw_if_index = ~0;
10023     }
10024
10025   if (!vam->json_output)
10026     {
10027       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10028                "sw_if_index", "local", "remote", "vni",
10029                "protocol", "encap_vrf_id", "decap_vrf_id");
10030     }
10031
10032   /* Get list of vxlan-tunnel interfaces */
10033   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10034
10035   mp->sw_if_index = htonl (sw_if_index);
10036
10037   S;
10038
10039   /* Use a control ping for synchronization */
10040   {
10041     vl_api_control_ping_t *mp;
10042     M (CONTROL_PING, control_ping);
10043     S;
10044   }
10045   W;
10046 }
10047
10048 u8 *
10049 format_l2_fib_mac_address (u8 * s, va_list * args)
10050 {
10051   u8 *a = va_arg (*args, u8 *);
10052
10053   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
10054                  a[2], a[3], a[4], a[5], a[6], a[7]);
10055 }
10056
10057 static void vl_api_l2_fib_table_entry_t_handler
10058   (vl_api_l2_fib_table_entry_t * mp)
10059 {
10060   vat_main_t *vam = &vat_main;
10061
10062   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10063            "       %d       %d     %d\n",
10064            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
10065            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10066            mp->bvi_mac);
10067 }
10068
10069 static void vl_api_l2_fib_table_entry_t_handler_json
10070   (vl_api_l2_fib_table_entry_t * mp)
10071 {
10072   vat_main_t *vam = &vat_main;
10073   vat_json_node_t *node = NULL;
10074
10075   if (VAT_JSON_ARRAY != vam->json_tree.type)
10076     {
10077       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10078       vat_json_init_array (&vam->json_tree);
10079     }
10080   node = vat_json_array_add (&vam->json_tree);
10081
10082   vat_json_init_object (node);
10083   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10084   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
10085   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10086   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10087   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10088   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10089 }
10090
10091 static int
10092 api_l2_fib_table_dump (vat_main_t * vam)
10093 {
10094   unformat_input_t *i = vam->input;
10095   vl_api_l2_fib_table_dump_t *mp;
10096   f64 timeout;
10097   u32 bd_id;
10098   u8 bd_id_set = 0;
10099
10100   /* Parse args required to build the message */
10101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10102     {
10103       if (unformat (i, "bd_id %d", &bd_id))
10104         bd_id_set = 1;
10105       else
10106         break;
10107     }
10108
10109   if (bd_id_set == 0)
10110     {
10111       errmsg ("missing bridge domain\n");
10112       return -99;
10113     }
10114
10115   fformat (vam->ofp,
10116            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
10117
10118   /* Get list of l2 fib entries */
10119   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
10120
10121   mp->bd_id = ntohl (bd_id);
10122   S;
10123
10124   /* Use a control ping for synchronization */
10125   {
10126     vl_api_control_ping_t *mp;
10127     M (CONTROL_PING, control_ping);
10128     S;
10129   }
10130   W;
10131 }
10132
10133
10134 static int
10135 api_interface_name_renumber (vat_main_t * vam)
10136 {
10137   unformat_input_t *line_input = vam->input;
10138   vl_api_interface_name_renumber_t *mp;
10139   u32 sw_if_index = ~0;
10140   f64 timeout;
10141   u32 new_show_dev_instance = ~0;
10142
10143   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10144     {
10145       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
10146                     &sw_if_index))
10147         ;
10148       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10149         ;
10150       else if (unformat (line_input, "new_show_dev_instance %d",
10151                          &new_show_dev_instance))
10152         ;
10153       else
10154         break;
10155     }
10156
10157   if (sw_if_index == ~0)
10158     {
10159       errmsg ("missing interface name or sw_if_index\n");
10160       return -99;
10161     }
10162
10163   if (new_show_dev_instance == ~0)
10164     {
10165       errmsg ("missing new_show_dev_instance\n");
10166       return -99;
10167     }
10168
10169   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
10170
10171   mp->sw_if_index = ntohl (sw_if_index);
10172   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10173
10174   S;
10175   W;
10176 }
10177
10178 static int
10179 api_want_ip4_arp_events (vat_main_t * vam)
10180 {
10181   unformat_input_t *line_input = vam->input;
10182   vl_api_want_ip4_arp_events_t *mp;
10183   f64 timeout;
10184   ip4_address_t address;
10185   int address_set = 0;
10186   u32 enable_disable = 1;
10187
10188   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10189     {
10190       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
10191         address_set = 1;
10192       else if (unformat (line_input, "del"))
10193         enable_disable = 0;
10194       else
10195         break;
10196     }
10197
10198   if (address_set == 0)
10199     {
10200       errmsg ("missing addresses\n");
10201       return -99;
10202     }
10203
10204   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
10205   mp->enable_disable = enable_disable;
10206   mp->pid = getpid ();
10207   mp->address = address.as_u32;
10208
10209   S;
10210   W;
10211 }
10212
10213 static int
10214 api_input_acl_set_interface (vat_main_t * vam)
10215 {
10216   unformat_input_t *i = vam->input;
10217   vl_api_input_acl_set_interface_t *mp;
10218   f64 timeout;
10219   u32 sw_if_index;
10220   int sw_if_index_set;
10221   u32 ip4_table_index = ~0;
10222   u32 ip6_table_index = ~0;
10223   u32 l2_table_index = ~0;
10224   u8 is_add = 1;
10225
10226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10227     {
10228       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10229         sw_if_index_set = 1;
10230       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10231         sw_if_index_set = 1;
10232       else if (unformat (i, "del"))
10233         is_add = 0;
10234       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10235         ;
10236       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10237         ;
10238       else if (unformat (i, "l2-table %d", &l2_table_index))
10239         ;
10240       else
10241         {
10242           clib_warning ("parse error '%U'", format_unformat_error, i);
10243           return -99;
10244         }
10245     }
10246
10247   if (sw_if_index_set == 0)
10248     {
10249       errmsg ("missing interface name or sw_if_index\n");
10250       return -99;
10251     }
10252
10253   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
10254
10255   mp->sw_if_index = ntohl (sw_if_index);
10256   mp->ip4_table_index = ntohl (ip4_table_index);
10257   mp->ip6_table_index = ntohl (ip6_table_index);
10258   mp->l2_table_index = ntohl (l2_table_index);
10259   mp->is_add = is_add;
10260
10261   S;
10262   W;
10263   /* NOTREACHED */
10264   return 0;
10265 }
10266
10267 static int
10268 api_ip_address_dump (vat_main_t * vam)
10269 {
10270   unformat_input_t *i = vam->input;
10271   vl_api_ip_address_dump_t *mp;
10272   u32 sw_if_index = ~0;
10273   u8 sw_if_index_set = 0;
10274   u8 ipv4_set = 0;
10275   u8 ipv6_set = 0;
10276   f64 timeout;
10277
10278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10279     {
10280       if (unformat (i, "sw_if_index %d", &sw_if_index))
10281         sw_if_index_set = 1;
10282       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10283         sw_if_index_set = 1;
10284       else if (unformat (i, "ipv4"))
10285         ipv4_set = 1;
10286       else if (unformat (i, "ipv6"))
10287         ipv6_set = 1;
10288       else
10289         break;
10290     }
10291
10292   if (ipv4_set && ipv6_set)
10293     {
10294       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10295       return -99;
10296     }
10297
10298   if ((!ipv4_set) && (!ipv6_set))
10299     {
10300       errmsg ("no ipv4 nor ipv6 flag set\n");
10301       return -99;
10302     }
10303
10304   if (sw_if_index_set == 0)
10305     {
10306       errmsg ("missing interface name or sw_if_index\n");
10307       return -99;
10308     }
10309
10310   vam->current_sw_if_index = sw_if_index;
10311   vam->is_ipv6 = ipv6_set;
10312
10313   M (IP_ADDRESS_DUMP, ip_address_dump);
10314   mp->sw_if_index = ntohl (sw_if_index);
10315   mp->is_ipv6 = ipv6_set;
10316   S;
10317
10318   /* Use a control ping for synchronization */
10319   {
10320     vl_api_control_ping_t *mp;
10321     M (CONTROL_PING, control_ping);
10322     S;
10323   }
10324   W;
10325 }
10326
10327 static int
10328 api_ip_dump (vat_main_t * vam)
10329 {
10330   vl_api_ip_dump_t *mp;
10331   unformat_input_t *in = vam->input;
10332   int ipv4_set = 0;
10333   int ipv6_set = 0;
10334   int is_ipv6;
10335   f64 timeout;
10336   int i;
10337
10338   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10339     {
10340       if (unformat (in, "ipv4"))
10341         ipv4_set = 1;
10342       else if (unformat (in, "ipv6"))
10343         ipv6_set = 1;
10344       else
10345         break;
10346     }
10347
10348   if (ipv4_set && ipv6_set)
10349     {
10350       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
10351       return -99;
10352     }
10353
10354   if ((!ipv4_set) && (!ipv6_set))
10355     {
10356       errmsg ("no ipv4 nor ipv6 flag set\n");
10357       return -99;
10358     }
10359
10360   is_ipv6 = ipv6_set;
10361   vam->is_ipv6 = is_ipv6;
10362
10363   /* free old data */
10364   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10365     {
10366       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10367     }
10368   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10369
10370   M (IP_DUMP, ip_dump);
10371   mp->is_ipv6 = ipv6_set;
10372   S;
10373
10374   /* Use a control ping for synchronization */
10375   {
10376     vl_api_control_ping_t *mp;
10377     M (CONTROL_PING, control_ping);
10378     S;
10379   }
10380   W;
10381 }
10382
10383 static int
10384 api_ipsec_spd_add_del (vat_main_t * vam)
10385 {
10386 #if DPDK > 0
10387   unformat_input_t *i = vam->input;
10388   vl_api_ipsec_spd_add_del_t *mp;
10389   f64 timeout;
10390   u32 spd_id = ~0;
10391   u8 is_add = 1;
10392
10393   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10394     {
10395       if (unformat (i, "spd_id %d", &spd_id))
10396         ;
10397       else if (unformat (i, "del"))
10398         is_add = 0;
10399       else
10400         {
10401           clib_warning ("parse error '%U'", format_unformat_error, i);
10402           return -99;
10403         }
10404     }
10405   if (spd_id == ~0)
10406     {
10407       errmsg ("spd_id must be set\n");
10408       return -99;
10409     }
10410
10411   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
10412
10413   mp->spd_id = ntohl (spd_id);
10414   mp->is_add = is_add;
10415
10416   S;
10417   W;
10418   /* NOTREACHED */
10419   return 0;
10420 #else
10421   clib_warning ("unsupported (no dpdk)");
10422   return -99;
10423 #endif
10424 }
10425
10426 static int
10427 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10428 {
10429 #if DPDK > 0
10430   unformat_input_t *i = vam->input;
10431   vl_api_ipsec_interface_add_del_spd_t *mp;
10432   f64 timeout;
10433   u32 sw_if_index;
10434   u8 sw_if_index_set = 0;
10435   u32 spd_id = (u32) ~ 0;
10436   u8 is_add = 1;
10437
10438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10439     {
10440       if (unformat (i, "del"))
10441         is_add = 0;
10442       else if (unformat (i, "spd_id %d", &spd_id))
10443         ;
10444       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10445         sw_if_index_set = 1;
10446       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10447         sw_if_index_set = 1;
10448       else
10449         {
10450           clib_warning ("parse error '%U'", format_unformat_error, i);
10451           return -99;
10452         }
10453
10454     }
10455
10456   if (spd_id == (u32) ~ 0)
10457     {
10458       errmsg ("spd_id must be set\n");
10459       return -99;
10460     }
10461
10462   if (sw_if_index_set == 0)
10463     {
10464       errmsg ("missing interface name or sw_if_index\n");
10465       return -99;
10466     }
10467
10468   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
10469
10470   mp->spd_id = ntohl (spd_id);
10471   mp->sw_if_index = ntohl (sw_if_index);
10472   mp->is_add = is_add;
10473
10474   S;
10475   W;
10476   /* NOTREACHED */
10477   return 0;
10478 #else
10479   clib_warning ("unsupported (no dpdk)");
10480   return -99;
10481 #endif
10482 }
10483
10484 static int
10485 api_ipsec_spd_add_del_entry (vat_main_t * vam)
10486 {
10487 #if DPDK > 0
10488   unformat_input_t *i = vam->input;
10489   vl_api_ipsec_spd_add_del_entry_t *mp;
10490   f64 timeout;
10491   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
10492   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10493   i32 priority = 0;
10494   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10495   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10496   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
10497   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
10498
10499   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
10500   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
10501   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
10502   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
10503   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
10504   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
10505
10506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10507     {
10508       if (unformat (i, "del"))
10509         is_add = 0;
10510       if (unformat (i, "outbound"))
10511         is_outbound = 1;
10512       if (unformat (i, "inbound"))
10513         is_outbound = 0;
10514       else if (unformat (i, "spd_id %d", &spd_id))
10515         ;
10516       else if (unformat (i, "sa_id %d", &sa_id))
10517         ;
10518       else if (unformat (i, "priority %d", &priority))
10519         ;
10520       else if (unformat (i, "protocol %d", &protocol))
10521         ;
10522       else if (unformat (i, "lport_start %d", &lport_start))
10523         ;
10524       else if (unformat (i, "lport_stop %d", &lport_stop))
10525         ;
10526       else if (unformat (i, "rport_start %d", &rport_start))
10527         ;
10528       else if (unformat (i, "rport_stop %d", &rport_stop))
10529         ;
10530       else
10531         if (unformat
10532             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
10533         {
10534           is_ipv6 = 0;
10535           is_ip_any = 0;
10536         }
10537       else
10538         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
10539         {
10540           is_ipv6 = 0;
10541           is_ip_any = 0;
10542         }
10543       else
10544         if (unformat
10545             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
10546         {
10547           is_ipv6 = 0;
10548           is_ip_any = 0;
10549         }
10550       else
10551         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
10552         {
10553           is_ipv6 = 0;
10554           is_ip_any = 0;
10555         }
10556       else
10557         if (unformat
10558             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
10559         {
10560           is_ipv6 = 1;
10561           is_ip_any = 0;
10562         }
10563       else
10564         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
10565         {
10566           is_ipv6 = 1;
10567           is_ip_any = 0;
10568         }
10569       else
10570         if (unformat
10571             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
10572         {
10573           is_ipv6 = 1;
10574           is_ip_any = 0;
10575         }
10576       else
10577         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
10578         {
10579           is_ipv6 = 1;
10580           is_ip_any = 0;
10581         }
10582       else
10583         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10584         {
10585           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10586             {
10587               clib_warning ("unsupported action: 'resolve'");
10588               return -99;
10589             }
10590         }
10591       else
10592         {
10593           clib_warning ("parse error '%U'", format_unformat_error, i);
10594           return -99;
10595         }
10596
10597     }
10598
10599   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
10600
10601   mp->spd_id = ntohl (spd_id);
10602   mp->priority = ntohl (priority);
10603   mp->is_outbound = is_outbound;
10604
10605   mp->is_ipv6 = is_ipv6;
10606   if (is_ipv6 || is_ip_any)
10607     {
10608       clib_memcpy (mp->remote_address_start, &raddr6_start,
10609                    sizeof (ip6_address_t));
10610       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
10611                    sizeof (ip6_address_t));
10612       clib_memcpy (mp->local_address_start, &laddr6_start,
10613                    sizeof (ip6_address_t));
10614       clib_memcpy (mp->local_address_stop, &laddr6_stop,
10615                    sizeof (ip6_address_t));
10616     }
10617   else
10618     {
10619       clib_memcpy (mp->remote_address_start, &raddr4_start,
10620                    sizeof (ip4_address_t));
10621       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
10622                    sizeof (ip4_address_t));
10623       clib_memcpy (mp->local_address_start, &laddr4_start,
10624                    sizeof (ip4_address_t));
10625       clib_memcpy (mp->local_address_stop, &laddr4_stop,
10626                    sizeof (ip4_address_t));
10627     }
10628   mp->protocol = (u8) protocol;
10629   mp->local_port_start = ntohs ((u16) lport_start);
10630   mp->local_port_stop = ntohs ((u16) lport_stop);
10631   mp->remote_port_start = ntohs ((u16) rport_start);
10632   mp->remote_port_stop = ntohs ((u16) rport_stop);
10633   mp->policy = (u8) policy;
10634   mp->sa_id = ntohl (sa_id);
10635   mp->is_add = is_add;
10636   mp->is_ip_any = is_ip_any;
10637   S;
10638   W;
10639   /* NOTREACHED */
10640   return 0;
10641 #else
10642   clib_warning ("unsupported (no dpdk)");
10643   return -99;
10644 #endif
10645 }
10646
10647 static int
10648 api_ipsec_sad_add_del_entry (vat_main_t * vam)
10649 {
10650 #if DPDK > 0
10651   unformat_input_t *i = vam->input;
10652   vl_api_ipsec_sad_add_del_entry_t *mp;
10653   f64 timeout;
10654   u32 sad_id = 0, spi = 0;
10655   u8 *ck = 0, *ik = 0;
10656   u8 is_add = 1;
10657
10658   u8 protocol = IPSEC_PROTOCOL_AH;
10659   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
10660   u32 crypto_alg = 0, integ_alg = 0;
10661   ip4_address_t tun_src4;
10662   ip4_address_t tun_dst4;
10663   ip6_address_t tun_src6;
10664   ip6_address_t tun_dst6;
10665
10666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10667     {
10668       if (unformat (i, "del"))
10669         is_add = 0;
10670       else if (unformat (i, "sad_id %d", &sad_id))
10671         ;
10672       else if (unformat (i, "spi %d", &spi))
10673         ;
10674       else if (unformat (i, "esp"))
10675         protocol = IPSEC_PROTOCOL_ESP;
10676       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
10677         {
10678           is_tunnel = 1;
10679           is_tunnel_ipv6 = 0;
10680         }
10681       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
10682         {
10683           is_tunnel = 1;
10684           is_tunnel_ipv6 = 0;
10685         }
10686       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
10687         {
10688           is_tunnel = 1;
10689           is_tunnel_ipv6 = 1;
10690         }
10691       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
10692         {
10693           is_tunnel = 1;
10694           is_tunnel_ipv6 = 1;
10695         }
10696       else
10697         if (unformat
10698             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
10699         {
10700           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
10701               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
10702             {
10703               clib_warning ("unsupported crypto-alg: '%U'",
10704                             format_ipsec_crypto_alg, crypto_alg);
10705               return -99;
10706             }
10707         }
10708       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10709         ;
10710       else
10711         if (unformat
10712             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
10713         {
10714           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
10715               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
10716             {
10717               clib_warning ("unsupported integ-alg: '%U'",
10718                             format_ipsec_integ_alg, integ_alg);
10719               return -99;
10720             }
10721         }
10722       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10723         ;
10724       else
10725         {
10726           clib_warning ("parse error '%U'", format_unformat_error, i);
10727           return -99;
10728         }
10729
10730     }
10731
10732   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
10733
10734   mp->sad_id = ntohl (sad_id);
10735   mp->is_add = is_add;
10736   mp->protocol = protocol;
10737   mp->spi = ntohl (spi);
10738   mp->is_tunnel = is_tunnel;
10739   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
10740   mp->crypto_algorithm = crypto_alg;
10741   mp->integrity_algorithm = integ_alg;
10742   mp->crypto_key_length = vec_len (ck);
10743   mp->integrity_key_length = vec_len (ik);
10744
10745   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10746     mp->crypto_key_length = sizeof (mp->crypto_key);
10747
10748   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10749     mp->integrity_key_length = sizeof (mp->integrity_key);
10750
10751   if (ck)
10752     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10753   if (ik)
10754     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10755
10756   if (is_tunnel)
10757     {
10758       if (is_tunnel_ipv6)
10759         {
10760           clib_memcpy (mp->tunnel_src_address, &tun_src6,
10761                        sizeof (ip6_address_t));
10762           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
10763                        sizeof (ip6_address_t));
10764         }
10765       else
10766         {
10767           clib_memcpy (mp->tunnel_src_address, &tun_src4,
10768                        sizeof (ip4_address_t));
10769           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
10770                        sizeof (ip4_address_t));
10771         }
10772     }
10773
10774   S;
10775   W;
10776   /* NOTREACHED */
10777   return 0;
10778 #else
10779   clib_warning ("unsupported (no dpdk)");
10780   return -99;
10781 #endif
10782 }
10783
10784 static int
10785 api_ipsec_sa_set_key (vat_main_t * vam)
10786 {
10787 #if DPDK > 0
10788   unformat_input_t *i = vam->input;
10789   vl_api_ipsec_sa_set_key_t *mp;
10790   f64 timeout;
10791   u32 sa_id;
10792   u8 *ck = 0, *ik = 0;
10793
10794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10795     {
10796       if (unformat (i, "sa_id %d", &sa_id))
10797         ;
10798       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10799         ;
10800       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10801         ;
10802       else
10803         {
10804           clib_warning ("parse error '%U'", format_unformat_error, i);
10805           return -99;
10806         }
10807     }
10808
10809   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
10810
10811   mp->sa_id = ntohl (sa_id);
10812   mp->crypto_key_length = vec_len (ck);
10813   mp->integrity_key_length = vec_len (ik);
10814
10815   if (mp->crypto_key_length > sizeof (mp->crypto_key))
10816     mp->crypto_key_length = sizeof (mp->crypto_key);
10817
10818   if (mp->integrity_key_length > sizeof (mp->integrity_key))
10819     mp->integrity_key_length = sizeof (mp->integrity_key);
10820
10821   if (ck)
10822     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
10823   if (ik)
10824     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
10825
10826   S;
10827   W;
10828   /* NOTREACHED */
10829   return 0;
10830 #else
10831   clib_warning ("unsupported (no dpdk)");
10832   return -99;
10833 #endif
10834 }
10835
10836 static int
10837 api_ikev2_profile_add_del (vat_main_t * vam)
10838 {
10839 #if DPDK > 0
10840   unformat_input_t *i = vam->input;
10841   vl_api_ikev2_profile_add_del_t *mp;
10842   f64 timeout;
10843   u8 is_add = 1;
10844   u8 *name = 0;
10845
10846   const char *valid_chars = "a-zA-Z0-9_";
10847
10848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10849     {
10850       if (unformat (i, "del"))
10851         is_add = 0;
10852       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10853         vec_add1 (name, 0);
10854       else
10855         {
10856           errmsg ("parse error '%U'", format_unformat_error, i);
10857           return -99;
10858         }
10859     }
10860
10861   if (!vec_len (name))
10862     {
10863       errmsg ("profile name must be specified");
10864       return -99;
10865     }
10866
10867   if (vec_len (name) > 64)
10868     {
10869       errmsg ("profile name too long");
10870       return -99;
10871     }
10872
10873   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
10874
10875   clib_memcpy (mp->name, name, vec_len (name));
10876   mp->is_add = is_add;
10877   vec_free (name);
10878
10879   S;
10880   W;
10881   /* NOTREACHED */
10882   return 0;
10883 #else
10884   clib_warning ("unsupported (no dpdk)");
10885   return -99;
10886 #endif
10887 }
10888
10889 static int
10890 api_ikev2_profile_set_auth (vat_main_t * vam)
10891 {
10892 #if DPDK > 0
10893   unformat_input_t *i = vam->input;
10894   vl_api_ikev2_profile_set_auth_t *mp;
10895   f64 timeout;
10896   u8 *name = 0;
10897   u8 *data = 0;
10898   u32 auth_method = 0;
10899   u8 is_hex = 0;
10900
10901   const char *valid_chars = "a-zA-Z0-9_";
10902
10903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10904     {
10905       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10906         vec_add1 (name, 0);
10907       else if (unformat (i, "auth_method %U",
10908                          unformat_ikev2_auth_method, &auth_method))
10909         ;
10910       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
10911         is_hex = 1;
10912       else if (unformat (i, "auth_data %v", &data))
10913         ;
10914       else
10915         {
10916           errmsg ("parse error '%U'", format_unformat_error, i);
10917           return -99;
10918         }
10919     }
10920
10921   if (!vec_len (name))
10922     {
10923       errmsg ("profile name must be specified");
10924       return -99;
10925     }
10926
10927   if (vec_len (name) > 64)
10928     {
10929       errmsg ("profile name too long");
10930       return -99;
10931     }
10932
10933   if (!vec_len (data))
10934     {
10935       errmsg ("auth_data must be specified");
10936       return -99;
10937     }
10938
10939   if (!auth_method)
10940     {
10941       errmsg ("auth_method must be specified");
10942       return -99;
10943     }
10944
10945   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
10946
10947   mp->is_hex = is_hex;
10948   mp->auth_method = (u8) auth_method;
10949   mp->data_len = vec_len (data);
10950   clib_memcpy (mp->name, name, vec_len (name));
10951   clib_memcpy (mp->data, data, vec_len (data));
10952   vec_free (name);
10953   vec_free (data);
10954
10955   S;
10956   W;
10957   /* NOTREACHED */
10958   return 0;
10959 #else
10960   clib_warning ("unsupported (no dpdk)");
10961   return -99;
10962 #endif
10963 }
10964
10965 static int
10966 api_ikev2_profile_set_id (vat_main_t * vam)
10967 {
10968 #if DPDK > 0
10969   unformat_input_t *i = vam->input;
10970   vl_api_ikev2_profile_set_id_t *mp;
10971   f64 timeout;
10972   u8 *name = 0;
10973   u8 *data = 0;
10974   u8 is_local = 0;
10975   u32 id_type = 0;
10976   ip4_address_t ip4;
10977
10978   const char *valid_chars = "a-zA-Z0-9_";
10979
10980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10981     {
10982       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
10983         vec_add1 (name, 0);
10984       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
10985         ;
10986       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
10987         {
10988           data = vec_new (u8, 4);
10989           clib_memcpy (data, ip4.as_u8, 4);
10990         }
10991       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
10992         ;
10993       else if (unformat (i, "id_data %v", &data))
10994         ;
10995       else if (unformat (i, "local"))
10996         is_local = 1;
10997       else if (unformat (i, "remote"))
10998         is_local = 0;
10999       else
11000         {
11001           errmsg ("parse error '%U'", format_unformat_error, i);
11002           return -99;
11003         }
11004     }
11005
11006   if (!vec_len (name))
11007     {
11008       errmsg ("profile name must be specified");
11009       return -99;
11010     }
11011
11012   if (vec_len (name) > 64)
11013     {
11014       errmsg ("profile name too long");
11015       return -99;
11016     }
11017
11018   if (!vec_len (data))
11019     {
11020       errmsg ("id_data must be specified");
11021       return -99;
11022     }
11023
11024   if (!id_type)
11025     {
11026       errmsg ("id_type must be specified");
11027       return -99;
11028     }
11029
11030   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11031
11032   mp->is_local = is_local;
11033   mp->id_type = (u8) id_type;
11034   mp->data_len = vec_len (data);
11035   clib_memcpy (mp->name, name, vec_len (name));
11036   clib_memcpy (mp->data, data, vec_len (data));
11037   vec_free (name);
11038   vec_free (data);
11039
11040   S;
11041   W;
11042   /* NOTREACHED */
11043   return 0;
11044 #else
11045   clib_warning ("unsupported (no dpdk)");
11046   return -99;
11047 #endif
11048 }
11049
11050 static int
11051 api_ikev2_profile_set_ts (vat_main_t * vam)
11052 {
11053 #if DPDK > 0
11054   unformat_input_t *i = vam->input;
11055   vl_api_ikev2_profile_set_ts_t *mp;
11056   f64 timeout;
11057   u8 *name = 0;
11058   u8 is_local = 0;
11059   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
11060   ip4_address_t start_addr, end_addr;
11061
11062   const char *valid_chars = "a-zA-Z0-9_";
11063
11064   start_addr.as_u32 = 0;
11065   end_addr.as_u32 = (u32) ~ 0;
11066
11067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11068     {
11069       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11070         vec_add1 (name, 0);
11071       else if (unformat (i, "protocol %d", &proto))
11072         ;
11073       else if (unformat (i, "start_port %d", &start_port))
11074         ;
11075       else if (unformat (i, "end_port %d", &end_port))
11076         ;
11077       else
11078         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
11079         ;
11080       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
11081         ;
11082       else if (unformat (i, "local"))
11083         is_local = 1;
11084       else if (unformat (i, "remote"))
11085         is_local = 0;
11086       else
11087         {
11088           errmsg ("parse error '%U'", format_unformat_error, i);
11089           return -99;
11090         }
11091     }
11092
11093   if (!vec_len (name))
11094     {
11095       errmsg ("profile name must be specified");
11096       return -99;
11097     }
11098
11099   if (vec_len (name) > 64)
11100     {
11101       errmsg ("profile name too long");
11102       return -99;
11103     }
11104
11105   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
11106
11107   mp->is_local = is_local;
11108   mp->proto = (u8) proto;
11109   mp->start_port = (u16) start_port;
11110   mp->end_port = (u16) end_port;
11111   mp->start_addr = start_addr.as_u32;
11112   mp->end_addr = end_addr.as_u32;
11113   clib_memcpy (mp->name, name, vec_len (name));
11114   vec_free (name);
11115
11116   S;
11117   W;
11118   /* NOTREACHED */
11119   return 0;
11120 #else
11121   clib_warning ("unsupported (no dpdk)");
11122   return -99;
11123 #endif
11124 }
11125
11126 static int
11127 api_ikev2_set_local_key (vat_main_t * vam)
11128 {
11129 #if DPDK > 0
11130   unformat_input_t *i = vam->input;
11131   vl_api_ikev2_set_local_key_t *mp;
11132   f64 timeout;
11133   u8 *file = 0;
11134
11135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11136     {
11137       if (unformat (i, "file %v", &file))
11138         vec_add1 (file, 0);
11139       else
11140         {
11141           errmsg ("parse error '%U'", format_unformat_error, i);
11142           return -99;
11143         }
11144     }
11145
11146   if (!vec_len (file))
11147     {
11148       errmsg ("RSA key file must be specified");
11149       return -99;
11150     }
11151
11152   if (vec_len (file) > 256)
11153     {
11154       errmsg ("file name too long");
11155       return -99;
11156     }
11157
11158   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
11159
11160   clib_memcpy (mp->key_file, file, vec_len (file));
11161   vec_free (file);
11162
11163   S;
11164   W;
11165   /* NOTREACHED */
11166   return 0;
11167 #else
11168   clib_warning ("unsupported (no dpdk)");
11169   return -99;
11170 #endif
11171 }
11172
11173 /*
11174  * MAP
11175  */
11176 static int
11177 api_map_add_domain (vat_main_t * vam)
11178 {
11179   unformat_input_t *i = vam->input;
11180   vl_api_map_add_domain_t *mp;
11181   f64 timeout;
11182
11183   ip4_address_t ip4_prefix;
11184   ip6_address_t ip6_prefix;
11185   ip6_address_t ip6_src;
11186   u32 num_m_args = 0;
11187   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
11188     0, psid_length = 0;
11189   u8 is_translation = 0;
11190   u32 mtu = 0;
11191   u32 ip6_src_len = 128;
11192
11193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11194     {
11195       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
11196                     &ip4_prefix, &ip4_prefix_len))
11197         num_m_args++;
11198       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
11199                          &ip6_prefix, &ip6_prefix_len))
11200         num_m_args++;
11201       else
11202         if (unformat
11203             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
11204              &ip6_src_len))
11205         num_m_args++;
11206       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
11207         num_m_args++;
11208       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
11209         num_m_args++;
11210       else if (unformat (i, "psid-offset %d", &psid_offset))
11211         num_m_args++;
11212       else if (unformat (i, "psid-len %d", &psid_length))
11213         num_m_args++;
11214       else if (unformat (i, "mtu %d", &mtu))
11215         num_m_args++;
11216       else if (unformat (i, "map-t"))
11217         is_translation = 1;
11218       else
11219         {
11220           clib_warning ("parse error '%U'", format_unformat_error, i);
11221           return -99;
11222         }
11223     }
11224
11225   if (num_m_args < 3)
11226     {
11227       errmsg ("mandatory argument(s) missing\n");
11228       return -99;
11229     }
11230
11231   /* Construct the API message */
11232   M (MAP_ADD_DOMAIN, map_add_domain);
11233
11234   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
11235   mp->ip4_prefix_len = ip4_prefix_len;
11236
11237   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
11238   mp->ip6_prefix_len = ip6_prefix_len;
11239
11240   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
11241   mp->ip6_src_prefix_len = ip6_src_len;
11242
11243   mp->ea_bits_len = ea_bits_len;
11244   mp->psid_offset = psid_offset;
11245   mp->psid_length = psid_length;
11246   mp->is_translation = is_translation;
11247   mp->mtu = htons (mtu);
11248
11249   /* send it... */
11250   S;
11251
11252   /* Wait for a reply, return good/bad news  */
11253   W;
11254 }
11255
11256 static int
11257 api_map_del_domain (vat_main_t * vam)
11258 {
11259   unformat_input_t *i = vam->input;
11260   vl_api_map_del_domain_t *mp;
11261   f64 timeout;
11262
11263   u32 num_m_args = 0;
11264   u32 index;
11265
11266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11267     {
11268       if (unformat (i, "index %d", &index))
11269         num_m_args++;
11270       else
11271         {
11272           clib_warning ("parse error '%U'", format_unformat_error, i);
11273           return -99;
11274         }
11275     }
11276
11277   if (num_m_args != 1)
11278     {
11279       errmsg ("mandatory argument(s) missing\n");
11280       return -99;
11281     }
11282
11283   /* Construct the API message */
11284   M (MAP_DEL_DOMAIN, map_del_domain);
11285
11286   mp->index = ntohl (index);
11287
11288   /* send it... */
11289   S;
11290
11291   /* Wait for a reply, return good/bad news  */
11292   W;
11293 }
11294
11295 static int
11296 api_map_add_del_rule (vat_main_t * vam)
11297 {
11298   unformat_input_t *i = vam->input;
11299   vl_api_map_add_del_rule_t *mp;
11300   f64 timeout;
11301   u8 is_add = 1;
11302   ip6_address_t ip6_dst;
11303   u32 num_m_args = 0, index, psid = 0;
11304
11305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11306     {
11307       if (unformat (i, "index %d", &index))
11308         num_m_args++;
11309       else if (unformat (i, "psid %d", &psid))
11310         num_m_args++;
11311       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
11312         num_m_args++;
11313       else if (unformat (i, "del"))
11314         {
11315           is_add = 0;
11316         }
11317       else
11318         {
11319           clib_warning ("parse error '%U'", format_unformat_error, i);
11320           return -99;
11321         }
11322     }
11323
11324   /* Construct the API message */
11325   M (MAP_ADD_DEL_RULE, map_add_del_rule);
11326
11327   mp->index = ntohl (index);
11328   mp->is_add = is_add;
11329   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
11330   mp->psid = ntohs (psid);
11331
11332   /* send it... */
11333   S;
11334
11335   /* Wait for a reply, return good/bad news  */
11336   W;
11337 }
11338
11339 static int
11340 api_map_domain_dump (vat_main_t * vam)
11341 {
11342   vl_api_map_domain_dump_t *mp;
11343   f64 timeout;
11344
11345   /* Construct the API message */
11346   M (MAP_DOMAIN_DUMP, map_domain_dump);
11347
11348   /* send it... */
11349   S;
11350
11351   /* Use a control ping for synchronization */
11352   {
11353     vl_api_control_ping_t *mp;
11354     M (CONTROL_PING, control_ping);
11355     S;
11356   }
11357   W;
11358 }
11359
11360 static int
11361 api_map_rule_dump (vat_main_t * vam)
11362 {
11363   unformat_input_t *i = vam->input;
11364   vl_api_map_rule_dump_t *mp;
11365   f64 timeout;
11366   u32 domain_index = ~0;
11367
11368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11369     {
11370       if (unformat (i, "index %u", &domain_index))
11371         ;
11372       else
11373         break;
11374     }
11375
11376   if (domain_index == ~0)
11377     {
11378       clib_warning ("parse error: domain index expected");
11379       return -99;
11380     }
11381
11382   /* Construct the API message */
11383   M (MAP_RULE_DUMP, map_rule_dump);
11384
11385   mp->domain_index = htonl (domain_index);
11386
11387   /* send it... */
11388   S;
11389
11390   /* Use a control ping for synchronization */
11391   {
11392     vl_api_control_ping_t *mp;
11393     M (CONTROL_PING, control_ping);
11394     S;
11395   }
11396   W;
11397 }
11398
11399 static void vl_api_map_add_domain_reply_t_handler
11400   (vl_api_map_add_domain_reply_t * mp)
11401 {
11402   vat_main_t *vam = &vat_main;
11403   i32 retval = ntohl (mp->retval);
11404
11405   if (vam->async_mode)
11406     {
11407       vam->async_errors += (retval < 0);
11408     }
11409   else
11410     {
11411       vam->retval = retval;
11412       vam->result_ready = 1;
11413     }
11414 }
11415
11416 static void vl_api_map_add_domain_reply_t_handler_json
11417   (vl_api_map_add_domain_reply_t * mp)
11418 {
11419   vat_main_t *vam = &vat_main;
11420   vat_json_node_t node;
11421
11422   vat_json_init_object (&node);
11423   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
11424   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
11425
11426   vat_json_print (vam->ofp, &node);
11427   vat_json_free (&node);
11428
11429   vam->retval = ntohl (mp->retval);
11430   vam->result_ready = 1;
11431 }
11432
11433 static int
11434 api_get_first_msg_id (vat_main_t * vam)
11435 {
11436   vl_api_get_first_msg_id_t *mp;
11437   f64 timeout;
11438   unformat_input_t *i = vam->input;
11439   u8 *name;
11440   u8 name_set = 0;
11441
11442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11443     {
11444       if (unformat (i, "client %s", &name))
11445         name_set = 1;
11446       else
11447         break;
11448     }
11449
11450   if (name_set == 0)
11451     {
11452       errmsg ("missing client name\n");
11453       return -99;
11454     }
11455   vec_add1 (name, 0);
11456
11457   if (vec_len (name) > 63)
11458     {
11459       errmsg ("client name too long\n");
11460       return -99;
11461     }
11462
11463   M (GET_FIRST_MSG_ID, get_first_msg_id);
11464   clib_memcpy (mp->name, name, vec_len (name));
11465   S;
11466   W;
11467   /* NOTREACHED */
11468   return 0;
11469 }
11470
11471 static int
11472 api_cop_interface_enable_disable (vat_main_t * vam)
11473 {
11474   unformat_input_t *line_input = vam->input;
11475   vl_api_cop_interface_enable_disable_t *mp;
11476   f64 timeout;
11477   u32 sw_if_index = ~0;
11478   u8 enable_disable = 1;
11479
11480   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11481     {
11482       if (unformat (line_input, "disable"))
11483         enable_disable = 0;
11484       if (unformat (line_input, "enable"))
11485         enable_disable = 1;
11486       else if (unformat (line_input, "%U", unformat_sw_if_index,
11487                          vam, &sw_if_index))
11488         ;
11489       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11490         ;
11491       else
11492         break;
11493     }
11494
11495   if (sw_if_index == ~0)
11496     {
11497       errmsg ("missing interface name or sw_if_index\n");
11498       return -99;
11499     }
11500
11501   /* Construct the API message */
11502   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
11503   mp->sw_if_index = ntohl (sw_if_index);
11504   mp->enable_disable = enable_disable;
11505
11506   /* send it... */
11507   S;
11508   /* Wait for the reply */
11509   W;
11510 }
11511
11512 static int
11513 api_cop_whitelist_enable_disable (vat_main_t * vam)
11514 {
11515   unformat_input_t *line_input = vam->input;
11516   vl_api_cop_whitelist_enable_disable_t *mp;
11517   f64 timeout;
11518   u32 sw_if_index = ~0;
11519   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11520   u32 fib_id = 0;
11521
11522   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11523     {
11524       if (unformat (line_input, "ip4"))
11525         ip4 = 1;
11526       else if (unformat (line_input, "ip6"))
11527         ip6 = 1;
11528       else if (unformat (line_input, "default"))
11529         default_cop = 1;
11530       else if (unformat (line_input, "%U", unformat_sw_if_index,
11531                          vam, &sw_if_index))
11532         ;
11533       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11534         ;
11535       else if (unformat (line_input, "fib-id %d", &fib_id))
11536         ;
11537       else
11538         break;
11539     }
11540
11541   if (sw_if_index == ~0)
11542     {
11543       errmsg ("missing interface name or sw_if_index\n");
11544       return -99;
11545     }
11546
11547   /* Construct the API message */
11548   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
11549   mp->sw_if_index = ntohl (sw_if_index);
11550   mp->fib_id = ntohl (fib_id);
11551   mp->ip4 = ip4;
11552   mp->ip6 = ip6;
11553   mp->default_cop = default_cop;
11554
11555   /* send it... */
11556   S;
11557   /* Wait for the reply */
11558   W;
11559 }
11560
11561 static int
11562 api_get_node_graph (vat_main_t * vam)
11563 {
11564   vl_api_get_node_graph_t *mp;
11565   f64 timeout;
11566
11567   M (GET_NODE_GRAPH, get_node_graph);
11568
11569   /* send it... */
11570   S;
11571   /* Wait for the reply */
11572   W;
11573 }
11574
11575 /* *INDENT-OFF* */
11576 /** Used for parsing LISP eids */
11577 typedef CLIB_PACKED(struct{
11578   u8 addr[16];   /**< eid address */
11579   u32 len;       /**< prefix length if IP */
11580   u8 type;      /**< type of eid */
11581 }) lisp_eid_vat_t;
11582 /* *INDENT-ON* */
11583
11584 static uword
11585 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
11586 {
11587   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
11588
11589   memset (a, 0, sizeof (a[0]));
11590
11591   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
11592     {
11593       a->type = 0;              /* ipv4 type */
11594     }
11595   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
11596     {
11597       a->type = 1;              /* ipv6 type */
11598     }
11599   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
11600     {
11601       a->type = 2;              /* mac type */
11602     }
11603   else
11604     {
11605       return 0;
11606     }
11607
11608   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
11609     {
11610       return 0;
11611     }
11612
11613   return 1;
11614 }
11615
11616 static int
11617 lisp_eid_size_vat (u8 type)
11618 {
11619   switch (type)
11620     {
11621     case 0:
11622       return 4;
11623     case 1:
11624       return 16;
11625     case 2:
11626       return 6;
11627     }
11628   return 0;
11629 }
11630
11631 static void
11632 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
11633 {
11634   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
11635 }
11636
11637 /* *INDENT-OFF* */
11638 /** Used for transferring locators via VPP API */
11639 typedef CLIB_PACKED(struct
11640 {
11641   u32 sw_if_index; /**< locator sw_if_index */
11642   u8 priority; /**< locator priority */
11643   u8 weight;   /**< locator weight */
11644 }) ls_locator_t;
11645 /* *INDENT-ON* */
11646
11647 static int
11648 api_lisp_add_del_locator_set (vat_main_t * vam)
11649 {
11650   unformat_input_t *input = vam->input;
11651   vl_api_lisp_add_del_locator_set_t *mp;
11652   f64 timeout = ~0;
11653   u8 is_add = 1;
11654   u8 *locator_set_name = NULL;
11655   u8 locator_set_name_set = 0;
11656   ls_locator_t locator, *locators = 0;
11657   u32 sw_if_index, priority, weight;
11658
11659   /* Parse args required to build the message */
11660   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11661     {
11662       if (unformat (input, "del"))
11663         {
11664           is_add = 0;
11665         }
11666       else if (unformat (input, "locator-set %s", &locator_set_name))
11667         {
11668           locator_set_name_set = 1;
11669         }
11670       else if (unformat (input, "sw_if_index %u p %u w %u",
11671                          &sw_if_index, &priority, &weight))
11672         {
11673           locator.sw_if_index = htonl (sw_if_index);
11674           locator.priority = priority;
11675           locator.weight = weight;
11676           vec_add1 (locators, locator);
11677         }
11678       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
11679                          vam, &sw_if_index, &priority, &weight))
11680         {
11681           locator.sw_if_index = htonl (sw_if_index);
11682           locator.priority = priority;
11683           locator.weight = weight;
11684           vec_add1 (locators, locator);
11685         }
11686       else
11687         break;
11688     }
11689
11690   if (locator_set_name_set == 0)
11691     {
11692       errmsg ("missing locator-set name");
11693       vec_free (locators);
11694       return -99;
11695     }
11696
11697   if (vec_len (locator_set_name) > 64)
11698     {
11699       errmsg ("locator-set name too long\n");
11700       vec_free (locator_set_name);
11701       vec_free (locators);
11702       return -99;
11703     }
11704   vec_add1 (locator_set_name, 0);
11705
11706   /* Construct the API message */
11707   M (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set);
11708
11709   mp->is_add = is_add;
11710   clib_memcpy (mp->locator_set_name, locator_set_name,
11711                vec_len (locator_set_name));
11712   vec_free (locator_set_name);
11713
11714   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
11715   if (locators)
11716     clib_memcpy (mp->locators, locators,
11717                  (sizeof (ls_locator_t) * vec_len (locators)));
11718   vec_free (locators);
11719
11720   /* send it... */
11721   S;
11722
11723   /* Wait for a reply... */
11724   W;
11725
11726   /* NOTREACHED */
11727   return 0;
11728 }
11729
11730 static int
11731 api_lisp_add_del_locator (vat_main_t * vam)
11732 {
11733   unformat_input_t *input = vam->input;
11734   vl_api_lisp_add_del_locator_t *mp;
11735   f64 timeout = ~0;
11736   u32 tmp_if_index = ~0;
11737   u32 sw_if_index = ~0;
11738   u8 sw_if_index_set = 0;
11739   u8 sw_if_index_if_name_set = 0;
11740   u32 priority = ~0;
11741   u8 priority_set = 0;
11742   u32 weight = ~0;
11743   u8 weight_set = 0;
11744   u8 is_add = 1;
11745   u8 *locator_set_name = NULL;
11746   u8 locator_set_name_set = 0;
11747
11748   /* Parse args required to build the message */
11749   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11750     {
11751       if (unformat (input, "del"))
11752         {
11753           is_add = 0;
11754         }
11755       else if (unformat (input, "locator-set %s", &locator_set_name))
11756         {
11757           locator_set_name_set = 1;
11758         }
11759       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
11760                          &tmp_if_index))
11761         {
11762           sw_if_index_if_name_set = 1;
11763           sw_if_index = tmp_if_index;
11764         }
11765       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
11766         {
11767           sw_if_index_set = 1;
11768           sw_if_index = tmp_if_index;
11769         }
11770       else if (unformat (input, "p %d", &priority))
11771         {
11772           priority_set = 1;
11773         }
11774       else if (unformat (input, "w %d", &weight))
11775         {
11776           weight_set = 1;
11777         }
11778       else
11779         break;
11780     }
11781
11782   if (locator_set_name_set == 0)
11783     {
11784       errmsg ("missing locator-set name");
11785       return -99;
11786     }
11787
11788   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
11789     {
11790       errmsg ("missing sw_if_index");
11791       vec_free (locator_set_name);
11792       return -99;
11793     }
11794
11795   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
11796     {
11797       errmsg ("cannot use both params interface name and sw_if_index");
11798       vec_free (locator_set_name);
11799       return -99;
11800     }
11801
11802   if (priority_set == 0)
11803     {
11804       errmsg ("missing locator-set priority\n");
11805       vec_free (locator_set_name);
11806       return -99;
11807     }
11808
11809   if (weight_set == 0)
11810     {
11811       errmsg ("missing locator-set weight\n");
11812       vec_free (locator_set_name);
11813       return -99;
11814     }
11815
11816   if (vec_len (locator_set_name) > 64)
11817     {
11818       errmsg ("locator-set name too long\n");
11819       vec_free (locator_set_name);
11820       return -99;
11821     }
11822   vec_add1 (locator_set_name, 0);
11823
11824   /* Construct the API message */
11825   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
11826
11827   mp->is_add = is_add;
11828   mp->sw_if_index = ntohl (sw_if_index);
11829   mp->priority = priority;
11830   mp->weight = weight;
11831   clib_memcpy (mp->locator_set_name, locator_set_name,
11832                vec_len (locator_set_name));
11833   vec_free (locator_set_name);
11834
11835   /* send it... */
11836   S;
11837
11838   /* Wait for a reply... */
11839   W;
11840
11841   /* NOTREACHED */
11842   return 0;
11843 }
11844
11845 static int
11846 api_lisp_add_del_local_eid (vat_main_t * vam)
11847 {
11848   unformat_input_t *input = vam->input;
11849   vl_api_lisp_add_del_local_eid_t *mp;
11850   f64 timeout = ~0;
11851   u8 is_add = 1;
11852   u8 eid_set = 0;
11853   lisp_eid_vat_t _eid, *eid = &_eid;
11854   u8 *locator_set_name = 0;
11855   u8 locator_set_name_set = 0;
11856   u32 vni = 0;
11857
11858   /* Parse args required to build the message */
11859   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11860     {
11861       if (unformat (input, "del"))
11862         {
11863           is_add = 0;
11864         }
11865       else if (unformat (input, "vni %d", &vni))
11866         {
11867           ;
11868         }
11869       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
11870         {
11871           eid_set = 1;
11872         }
11873       else if (unformat (input, "locator-set %s", &locator_set_name))
11874         {
11875           locator_set_name_set = 1;
11876         }
11877       else
11878         break;
11879     }
11880
11881   if (locator_set_name_set == 0)
11882     {
11883       errmsg ("missing locator-set name\n");
11884       return -99;
11885     }
11886
11887   if (0 == eid_set)
11888     {
11889       errmsg ("EID address not set!");
11890       vec_free (locator_set_name);
11891       return -99;
11892     }
11893
11894   if (vec_len (locator_set_name) > 64)
11895     {
11896       errmsg ("locator-set name too long\n");
11897       vec_free (locator_set_name);
11898       return -99;
11899     }
11900   vec_add1 (locator_set_name, 0);
11901
11902   /* Construct the API message */
11903   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
11904
11905   mp->is_add = is_add;
11906   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
11907   mp->eid_type = eid->type;
11908   mp->prefix_len = eid->len;
11909   mp->vni = clib_host_to_net_u32 (vni);
11910   clib_memcpy (mp->locator_set_name, locator_set_name,
11911                vec_len (locator_set_name));
11912
11913   vec_free (locator_set_name);
11914
11915   /* send it... */
11916   S;
11917
11918   /* Wait for a reply... */
11919   W;
11920
11921   /* NOTREACHED */
11922   return 0;
11923 }
11924
11925 /* *INDENT-OFF* */
11926 /** Used for transferring locators via VPP API */
11927 typedef CLIB_PACKED(struct
11928 {
11929   u8 is_ip4; /**< is locator an IPv4 address? */
11930   u8 priority; /**< locator priority */
11931   u8 weight;   /**< locator weight */
11932   u8 addr[16]; /**< IPv4/IPv6 address */
11933 }) rloc_t;
11934 /* *INDENT-ON* */
11935
11936 static int
11937 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
11938 {
11939   unformat_input_t *input = vam->input;
11940   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
11941   f64 timeout = ~0;
11942   u8 is_add = 1;
11943   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
11944   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
11945   u8 rmt_eid_set = 0, lcl_eid_set = 0;
11946   u32 action = ~0, p, w;
11947   ip4_address_t rmt_rloc4, lcl_rloc4;
11948   ip6_address_t rmt_rloc6, lcl_rloc6;
11949   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
11950
11951   memset (&rloc, 0, sizeof (rloc));
11952
11953   /* Parse args required to build the message */
11954   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11955     {
11956       if (unformat (input, "del"))
11957         {
11958           is_add = 0;
11959         }
11960       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
11961         {
11962           rmt_eid_set = 1;
11963         }
11964       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
11965         {
11966           lcl_eid_set = 1;
11967         }
11968       else if (unformat (input, "p %d w %d", &p, &w))
11969         {
11970           if (!curr_rloc)
11971             {
11972               errmsg ("No RLOC configured for setting priority/weight!");
11973               return -99;
11974             }
11975           curr_rloc->priority = p;
11976           curr_rloc->weight = w;
11977         }
11978       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
11979                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
11980         {
11981           rloc.is_ip4 = 1;
11982
11983           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
11984           rloc.priority = rloc.weight = 0;
11985           vec_add1 (lcl_locs, rloc);
11986
11987           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
11988           vec_add1 (rmt_locs, rloc);
11989           /* priority and weight saved in rmt loc */
11990           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
11991         }
11992       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
11993                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
11994         {
11995           rloc.is_ip4 = 0;
11996           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
11997           rloc.priority = rloc.weight = 0;
11998           vec_add1 (lcl_locs, rloc);
11999
12000           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12001           vec_add1 (rmt_locs, rloc);
12002           /* priority and weight saved in rmt loc */
12003           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12004         }
12005       else if (unformat (input, "action %d", &action))
12006         {
12007           ;
12008         }
12009       else
12010         {
12011           clib_warning ("parse error '%U'", format_unformat_error, input);
12012           return -99;
12013         }
12014     }
12015
12016   if (!rmt_eid_set)
12017     {
12018       errmsg ("remote eid addresses not set\n");
12019       return -99;
12020     }
12021
12022   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12023     {
12024       errmsg ("eid types don't match\n");
12025       return -99;
12026     }
12027
12028   if (0 == rmt_locs && (u32) ~ 0 == action)
12029     {
12030       errmsg ("action not set for negative mapping\n");
12031       return -99;
12032     }
12033
12034   /* Construct the API message */
12035   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12036
12037   mp->is_add = is_add;
12038   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12039   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12040   mp->eid_type = rmt_eid->type;
12041   mp->rmt_len = rmt_eid->len;
12042   mp->lcl_len = lcl_eid->len;
12043   mp->action = action;
12044
12045   if (0 != rmt_locs && 0 != lcl_locs)
12046     {
12047       mp->loc_num = vec_len (rmt_locs);
12048       clib_memcpy (mp->lcl_locs, lcl_locs,
12049                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12050       clib_memcpy (mp->rmt_locs, rmt_locs,
12051                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12052     }
12053   vec_free (lcl_locs);
12054   vec_free (rmt_locs);
12055
12056   /* send it... */
12057   S;
12058
12059   /* Wait for a reply... */
12060   W;
12061
12062   /* NOTREACHED */
12063   return 0;
12064 }
12065
12066 static int
12067 api_lisp_add_del_map_resolver (vat_main_t * vam)
12068 {
12069   unformat_input_t *input = vam->input;
12070   vl_api_lisp_add_del_map_resolver_t *mp;
12071   f64 timeout = ~0;
12072   u8 is_add = 1;
12073   u8 ipv4_set = 0;
12074   u8 ipv6_set = 0;
12075   ip4_address_t ipv4;
12076   ip6_address_t ipv6;
12077
12078   /* Parse args required to build the message */
12079   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12080     {
12081       if (unformat (input, "del"))
12082         {
12083           is_add = 0;
12084         }
12085       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
12086         {
12087           ipv4_set = 1;
12088         }
12089       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
12090         {
12091           ipv6_set = 1;
12092         }
12093       else
12094         break;
12095     }
12096
12097   if (ipv4_set && ipv6_set)
12098     {
12099       errmsg ("both eid v4 and v6 addresses set\n");
12100       return -99;
12101     }
12102
12103   if (!ipv4_set && !ipv6_set)
12104     {
12105       errmsg ("eid addresses not set\n");
12106       return -99;
12107     }
12108
12109   /* Construct the API message */
12110   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
12111
12112   mp->is_add = is_add;
12113   if (ipv6_set)
12114     {
12115       mp->is_ipv6 = 1;
12116       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
12117     }
12118   else
12119     {
12120       mp->is_ipv6 = 0;
12121       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
12122     }
12123
12124   /* send it... */
12125   S;
12126
12127   /* Wait for a reply... */
12128   W;
12129
12130   /* NOTREACHED */
12131   return 0;
12132 }
12133
12134 static int
12135 api_lisp_gpe_enable_disable (vat_main_t * vam)
12136 {
12137   unformat_input_t *input = vam->input;
12138   vl_api_lisp_gpe_enable_disable_t *mp;
12139   f64 timeout = ~0;
12140   u8 is_set = 0;
12141   u8 is_en = 1;
12142
12143   /* Parse args required to build the message */
12144   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12145     {
12146       if (unformat (input, "enable"))
12147         {
12148           is_set = 1;
12149           is_en = 1;
12150         }
12151       else if (unformat (input, "disable"))
12152         {
12153           is_set = 1;
12154           is_en = 0;
12155         }
12156       else
12157         break;
12158     }
12159
12160   if (is_set == 0)
12161     {
12162       errmsg ("Value not set\n");
12163       return -99;
12164     }
12165
12166   /* Construct the API message */
12167   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
12168
12169   mp->is_en = is_en;
12170
12171   /* send it... */
12172   S;
12173
12174   /* Wait for a reply... */
12175   W;
12176
12177   /* NOTREACHED */
12178   return 0;
12179 }
12180
12181 static int
12182 api_lisp_enable_disable (vat_main_t * vam)
12183 {
12184   unformat_input_t *input = vam->input;
12185   vl_api_lisp_enable_disable_t *mp;
12186   f64 timeout = ~0;
12187   u8 is_set = 0;
12188   u8 is_en = 0;
12189
12190   /* Parse args required to build the message */
12191   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12192     {
12193       if (unformat (input, "enable"))
12194         {
12195           is_set = 1;
12196           is_en = 1;
12197         }
12198       else if (unformat (input, "disable"))
12199         {
12200           is_set = 1;
12201         }
12202       else
12203         break;
12204     }
12205
12206   if (!is_set)
12207     {
12208       errmsg ("Value not set\n");
12209       return -99;
12210     }
12211
12212   /* Construct the API message */
12213   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
12214
12215   mp->is_en = is_en;
12216
12217   /* send it... */
12218   S;
12219
12220   /* Wait for a reply... */
12221   W;
12222
12223   /* NOTREACHED */
12224   return 0;
12225 }
12226
12227 /**
12228  * Enable/disable LISP proxy ITR.
12229  *
12230  * @param vam vpp API test context
12231  * @return return code
12232  */
12233 static int
12234 api_lisp_pitr_set_locator_set (vat_main_t * vam)
12235 {
12236   f64 timeout = ~0;
12237   u8 ls_name_set = 0;
12238   unformat_input_t *input = vam->input;
12239   vl_api_lisp_pitr_set_locator_set_t *mp;
12240   u8 is_add = 1;
12241   u8 *ls_name = 0;
12242
12243   /* Parse args required to build the message */
12244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12245     {
12246       if (unformat (input, "del"))
12247         is_add = 0;
12248       else if (unformat (input, "locator-set %s", &ls_name))
12249         ls_name_set = 1;
12250       else
12251         {
12252           errmsg ("parse error '%U'", format_unformat_error, input);
12253           return -99;
12254         }
12255     }
12256
12257   if (!ls_name_set)
12258     {
12259       errmsg ("locator-set name not set!");
12260       return -99;
12261     }
12262
12263   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
12264
12265   mp->is_add = is_add;
12266   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
12267   vec_free (ls_name);
12268
12269   /* send */
12270   S;
12271
12272   /* wait for reply */
12273   W;
12274
12275   /* notreached */
12276   return 0;
12277 }
12278
12279 static int
12280 api_show_lisp_pitr (vat_main_t * vam)
12281 {
12282   vl_api_show_lisp_pitr_t *mp;
12283   f64 timeout = ~0;
12284
12285   if (!vam->json_output)
12286     {
12287       fformat (vam->ofp, "%=20s\n", "lisp status:");
12288     }
12289
12290   M (SHOW_LISP_PITR, show_lisp_pitr);
12291   /* send it... */
12292   S;
12293
12294   /* Wait for a reply... */
12295   W;
12296
12297   /* NOTREACHED */
12298   return 0;
12299 }
12300
12301 /**
12302  * Add/delete mapping between vni and vrf
12303  */
12304 static int
12305 api_lisp_eid_table_add_del_map (vat_main_t * vam)
12306 {
12307   f64 timeout = ~0;
12308   unformat_input_t *input = vam->input;
12309   vl_api_lisp_eid_table_add_del_map_t *mp;
12310   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
12311   u32 vni, vrf, bd_index;
12312
12313   /* Parse args required to build the message */
12314   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12315     {
12316       if (unformat (input, "del"))
12317         is_add = 0;
12318       else if (unformat (input, "vrf %d", &vrf))
12319         vrf_set = 1;
12320       else if (unformat (input, "bd_index %d", &bd_index))
12321         bd_index_set = 1;
12322       else if (unformat (input, "vni %d", &vni))
12323         vni_set = 1;
12324       else
12325         break;
12326     }
12327
12328   if (!vni_set || (!vrf_set && !bd_index_set))
12329     {
12330       errmsg ("missing arguments!");
12331       return -99;
12332     }
12333
12334   if (vrf_set && bd_index_set)
12335     {
12336       errmsg ("error: both vrf and bd entered!");
12337       return -99;
12338     }
12339
12340   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
12341
12342   mp->is_add = is_add;
12343   mp->vni = htonl (vni);
12344   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
12345   mp->is_l2 = bd_index_set;
12346
12347   /* send */
12348   S;
12349
12350   /* wait for reply */
12351   W;
12352
12353   /* notreached */
12354   return 0;
12355 }
12356
12357 /**
12358  * Add/del remote mapping to/from LISP control plane
12359  *
12360  * @param vam vpp API test context
12361  * @return return code
12362  */
12363 static int
12364 api_lisp_add_del_remote_mapping (vat_main_t * vam)
12365 {
12366   unformat_input_t *input = vam->input;
12367   vl_api_lisp_add_del_remote_mapping_t *mp;
12368   f64 timeout = ~0;
12369   u32 vni = 0;
12370   //TODO: seid need remove
12371   lisp_eid_vat_t _eid, *eid = &_eid;
12372   lisp_eid_vat_t _seid, *seid = &_seid;
12373   u8 is_add = 1, del_all = 0, eid_set = 0;
12374   u32 action = ~0, p, w;
12375   ip4_address_t rloc4;
12376   ip6_address_t rloc6;
12377   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
12378
12379   memset (&rloc, 0, sizeof (rloc));
12380
12381   /* Parse args required to build the message */
12382   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12383     {
12384       if (unformat (input, "del-all"))
12385         {
12386           del_all = 1;
12387         }
12388       else if (unformat (input, "del"))
12389         {
12390           is_add = 0;
12391         }
12392       else if (unformat (input, "add"))
12393         {
12394           is_add = 1;
12395         }
12396       else if (unformat (input, "deid %U", unformat_lisp_eid_vat, eid))
12397         {
12398           eid_set = 1;
12399         }
12400       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, &seid))
12401         {
12402           //TODO: Need remove, but first must be remove from CSIT test
12403         }
12404       else if (unformat (input, "vni %d", &vni))
12405         {
12406           ;
12407         }
12408       else if (unformat (input, "p %d w %d", &p, &w))
12409         {
12410           if (!curr_rloc)
12411             {
12412               errmsg ("No RLOC configured for setting priority/weight!");
12413               return -99;
12414             }
12415           curr_rloc->priority = p;
12416           curr_rloc->weight = w;
12417         }
12418       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
12419         {
12420           rloc.is_ip4 = 1;
12421           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
12422           vec_add1 (rlocs, rloc);
12423           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12424         }
12425       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
12426         {
12427           rloc.is_ip4 = 0;
12428           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
12429           vec_add1 (rlocs, rloc);
12430           curr_rloc = &rlocs[vec_len (rlocs) - 1];
12431         }
12432       else if (unformat (input, "action %d", &action))
12433         {
12434           ;
12435         }
12436       else
12437         {
12438           clib_warning ("parse error '%U'", format_unformat_error, input);
12439           return -99;
12440         }
12441     }
12442
12443   if (0 == eid_set)
12444     {
12445       errmsg ("missing params!");
12446       return -99;
12447     }
12448
12449   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
12450     {
12451       errmsg ("no action set for negative map-reply!");
12452       return -99;
12453     }
12454
12455   M (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping);
12456   mp->is_add = is_add;
12457   mp->vni = htonl (vni);
12458   mp->action = (u8) action;
12459   mp->eid_len = eid->len;
12460   mp->del_all = del_all;
12461   mp->eid_type = eid->type;
12462   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12463
12464   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
12465   clib_memcpy (mp->rlocs, rlocs, (sizeof (rloc_t) * vec_len (rlocs)));
12466   vec_free (rlocs);
12467
12468   /* send it... */
12469   S;
12470
12471   /* Wait for a reply... */
12472   W;
12473
12474   /* NOTREACHED */
12475   return 0;
12476 }
12477
12478 /**
12479  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
12480  * forwarding entries in data-plane accordingly.
12481  *
12482  * @param vam vpp API test context
12483  * @return return code
12484  */
12485 static int
12486 api_lisp_add_del_adjacency (vat_main_t * vam)
12487 {
12488   unformat_input_t *input = vam->input;
12489   vl_api_lisp_add_del_adjacency_t *mp;
12490   f64 timeout = ~0;
12491   u32 vni = 0;
12492   ip4_address_t seid4, deid4;
12493   ip6_address_t seid6, deid6;
12494   u8 deid_mac[6] = { 0 };
12495   u8 seid_mac[6] = { 0 };
12496   u8 deid_type, seid_type;
12497   u32 seid_len = 0, deid_len = 0, len;
12498   u8 is_add = 1;
12499
12500   seid_type = deid_type = (u8) ~ 0;
12501
12502   /* Parse args required to build the message */
12503   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12504     {
12505       if (unformat (input, "del"))
12506         {
12507           is_add = 0;
12508         }
12509       else if (unformat (input, "add"))
12510         {
12511           is_add = 1;
12512         }
12513       else if (unformat (input, "deid %U/%d", unformat_ip4_address,
12514                          &deid4, &len))
12515         {
12516           deid_type = 0;        /* ipv4 */
12517           deid_len = len;
12518         }
12519       else if (unformat (input, "deid %U/%d", unformat_ip6_address,
12520                          &deid6, &len))
12521         {
12522           deid_type = 1;        /* ipv6 */
12523           deid_len = len;
12524         }
12525       else if (unformat (input, "deid %U", unformat_ethernet_address,
12526                          deid_mac))
12527         {
12528           deid_type = 2;        /* mac */
12529         }
12530       else if (unformat (input, "seid %U/%d", unformat_ip4_address,
12531                          &seid4, &len))
12532         {
12533           seid_type = 0;        /* ipv4 */
12534           seid_len = len;
12535         }
12536       else if (unformat (input, "seid %U/%d", unformat_ip6_address,
12537                          &seid6, &len))
12538         {
12539           seid_type = 1;        /* ipv6 */
12540           seid_len = len;
12541         }
12542       else if (unformat (input, "seid %U", unformat_ethernet_address,
12543                          seid_mac))
12544         {
12545           seid_type = 2;        /* mac */
12546         }
12547       else if (unformat (input, "vni %d", &vni))
12548         {
12549           ;
12550         }
12551       else
12552         {
12553           errmsg ("parse error '%U'", format_unformat_error, input);
12554           return -99;
12555         }
12556     }
12557
12558   if ((u8) ~ 0 == deid_type)
12559     {
12560       errmsg ("missing params!");
12561       return -99;
12562     }
12563
12564   if (seid_type != deid_type)
12565     {
12566       errmsg ("source and destination EIDs are of different types!");
12567       return -99;
12568     }
12569
12570   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
12571   mp->is_add = is_add;
12572   mp->vni = htonl (vni);
12573   mp->seid_len = seid_len;
12574   mp->deid_len = deid_len;
12575   mp->eid_type = deid_type;
12576
12577   switch (mp->eid_type)
12578     {
12579     case 0:
12580       clib_memcpy (mp->seid, &seid4, sizeof (seid4));
12581       clib_memcpy (mp->deid, &deid4, sizeof (deid4));
12582       break;
12583     case 1:
12584       clib_memcpy (mp->seid, &seid6, sizeof (seid6));
12585       clib_memcpy (mp->deid, &deid6, sizeof (deid6));
12586       break;
12587     case 2:
12588       clib_memcpy (mp->seid, seid_mac, 6);
12589       clib_memcpy (mp->deid, deid_mac, 6);
12590       break;
12591     default:
12592       errmsg ("unknown EID type %d!", mp->eid_type);
12593       return 0;
12594     }
12595
12596   /* send it... */
12597   S;
12598
12599   /* Wait for a reply... */
12600   W;
12601
12602   /* NOTREACHED */
12603   return 0;
12604 }
12605
12606 static int
12607 api_lisp_gpe_add_del_iface (vat_main_t * vam)
12608 {
12609   unformat_input_t *input = vam->input;
12610   vl_api_lisp_gpe_add_del_iface_t *mp;
12611   f64 timeout = ~0;
12612   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
12613   u32 dp_table = 0, vni = 0;
12614
12615   /* Parse args required to build the message */
12616   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12617     {
12618       if (unformat (input, "up"))
12619         {
12620           action_set = 1;
12621           is_add = 1;
12622         }
12623       else if (unformat (input, "down"))
12624         {
12625           action_set = 1;
12626           is_add = 0;
12627         }
12628       else if (unformat (input, "table_id %d", &dp_table))
12629         {
12630           dp_table_set = 1;
12631         }
12632       else if (unformat (input, "bd_id %d", &dp_table))
12633         {
12634           dp_table_set = 1;
12635           is_l2 = 1;
12636         }
12637       else if (unformat (input, "vni %d", &vni))
12638         {
12639           vni_set = 1;
12640         }
12641       else
12642         break;
12643     }
12644
12645   if (action_set == 0)
12646     {
12647       errmsg ("Action not set\n");
12648       return -99;
12649     }
12650   if (dp_table_set == 0 || vni_set == 0)
12651     {
12652       errmsg ("vni and dp_table must be set\n");
12653       return -99;
12654     }
12655
12656   /* Construct the API message */
12657   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
12658
12659   mp->is_add = is_add;
12660   mp->dp_table = dp_table;
12661   mp->is_l2 = is_l2;
12662   mp->vni = vni;
12663
12664   /* send it... */
12665   S;
12666
12667   /* Wait for a reply... */
12668   W;
12669
12670   /* NOTREACHED */
12671   return 0;
12672 }
12673
12674 /**
12675  * Add/del map request itr rlocs from LISP control plane and updates
12676  *
12677  * @param vam vpp API test context
12678  * @return return code
12679  */
12680 static int
12681 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
12682 {
12683   unformat_input_t *input = vam->input;
12684   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
12685   f64 timeout = ~0;
12686   u8 *locator_set_name = 0;
12687   u8 locator_set_name_set = 0;
12688   u8 is_add = 1;
12689
12690   /* Parse args required to build the message */
12691   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12692     {
12693       if (unformat (input, "del"))
12694         {
12695           is_add = 0;
12696         }
12697       else if (unformat (input, "%_%v%_", &locator_set_name))
12698         {
12699           locator_set_name_set = 1;
12700         }
12701       else
12702         {
12703           clib_warning ("parse error '%U'", format_unformat_error, input);
12704           return -99;
12705         }
12706     }
12707
12708   if (is_add && !locator_set_name_set)
12709     {
12710       errmsg ("itr-rloc is not set!");
12711       return -99;
12712     }
12713
12714   if (is_add && vec_len (locator_set_name) > 64)
12715     {
12716       errmsg ("itr-rloc locator-set name too long\n");
12717       vec_free (locator_set_name);
12718       return -99;
12719     }
12720
12721   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
12722   mp->is_add = is_add;
12723   if (is_add)
12724     {
12725       clib_memcpy (mp->locator_set_name, locator_set_name,
12726                    vec_len (locator_set_name));
12727     }
12728   else
12729     {
12730       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
12731     }
12732   vec_free (locator_set_name);
12733
12734   /* send it... */
12735   S;
12736
12737   /* Wait for a reply... */
12738   W;
12739
12740   /* NOTREACHED */
12741   return 0;
12742 }
12743
12744 static int
12745 lisp_locator_dump_send_msg (vat_main_t * vam, u32 locator_set_index,
12746                             u8 filter)
12747 {
12748   vl_api_lisp_locator_dump_t *mp;
12749   f64 timeout = ~0;
12750
12751   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
12752
12753   mp->locator_set_index = htonl (locator_set_index);
12754   mp->filter = filter;
12755
12756   /* send it... */
12757   S;
12758
12759   /* Use a control ping for synchronization */
12760   {
12761     vl_api_noprint_control_ping_t *mp;
12762     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12763     S;
12764   }
12765   /* Wait for a reply... */
12766   W;
12767 }
12768
12769 static inline void
12770 clean_locator_set_message (vat_main_t * vam)
12771 {
12772   locator_set_msg_t *ls = 0;
12773
12774   vec_foreach (ls, vam->locator_set_msg)
12775   {
12776     vec_free (ls->locator_set_name);
12777   }
12778
12779   vec_free (vam->locator_set_msg);
12780 }
12781
12782 static int
12783 print_locator_in_locator_set (vat_main_t * vam, u8 filter)
12784 {
12785   locator_set_msg_t *ls;
12786   locator_msg_t *loc;
12787   u8 *tmp_str = 0;
12788   int i = 0, ret = 0;
12789
12790   vec_foreach (ls, vam->locator_set_msg)
12791   {
12792     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12793     if (ret)
12794       {
12795         vec_free (vam->locator_msg);
12796         clean_locator_set_message (vam);
12797         return ret;
12798       }
12799
12800     tmp_str = format (0, "%=20s%=16d%s", ls->locator_set_name,
12801                       ls->locator_set_index,
12802                       vec_len (vam->locator_msg) ? "" : "\n");
12803     i = 0;
12804     vec_foreach (loc, vam->locator_msg)
12805     {
12806       if (i)
12807         {
12808           tmp_str = format (tmp_str, "%=37s", " ");
12809         }
12810       if (loc->local)
12811         {
12812           tmp_str = format (tmp_str, "%=16d%=16d%=16d\n",
12813                             loc->sw_if_index, loc->priority, loc->weight);
12814         }
12815       else
12816         {
12817           tmp_str = format (tmp_str, "%=16U%=16d%=16d\n",
12818                             loc->is_ipv6 ? format_ip6_address :
12819                             format_ip4_address,
12820                             loc->ip_address, loc->priority, loc->weight);
12821         }
12822       i++;
12823     }
12824
12825     fformat (vam->ofp, "%s", tmp_str);
12826     vec_free (tmp_str);
12827     vec_free (vam->locator_msg);
12828   }
12829
12830   clean_locator_set_message (vam);
12831
12832   return ret;
12833 }
12834
12835 static int
12836 json_locator_in_locator_set (vat_main_t * vam, u8 filter)
12837 {
12838   locator_set_msg_t *ls;
12839   locator_msg_t *loc;
12840   vat_json_node_t *node = NULL;
12841   vat_json_node_t *locator_array;
12842   vat_json_node_t *locator;
12843   struct in6_addr ip6;
12844   struct in_addr ip4;
12845   int ret = 0;
12846
12847   if (!vec_len (vam->locator_set_msg))
12848     {
12849       /* just print [] */
12850       vat_json_init_array (&vam->json_tree);
12851       vat_json_print (vam->ofp, &vam->json_tree);
12852       vam->json_tree.type = VAT_JSON_NONE;
12853       return ret;
12854     }
12855
12856   if (VAT_JSON_ARRAY != vam->json_tree.type)
12857     {
12858       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12859       vat_json_init_array (&vam->json_tree);
12860     }
12861
12862   vec_foreach (ls, vam->locator_set_msg)
12863   {
12864     ret = lisp_locator_dump_send_msg (vam, ls->locator_set_index, filter);
12865     if (ret)
12866       {
12867         vec_free (ls->locator_set_name);
12868         vec_free (vam->locator_msg);
12869         vec_free (vam->locator_set_msg);
12870         vat_json_free (&vam->json_tree);
12871         vam->json_tree.type = VAT_JSON_NONE;
12872         return ret;
12873       }
12874
12875     node = vat_json_array_add (&vam->json_tree);
12876     vat_json_init_object (node);
12877
12878     vat_json_object_add_uint (node, "locator-set-index",
12879                               ls->locator_set_index);
12880     vat_json_object_add_string_copy (node, "locator-set",
12881                                      ls->locator_set_name);
12882     locator_array = vat_json_object_add_list (node, "locator");
12883     vec_foreach (loc, vam->locator_msg)
12884     {
12885       locator = vat_json_array_add (locator_array);
12886       vat_json_init_object (locator);
12887       if (loc->local)
12888         {
12889           vat_json_object_add_uint (locator, "locator-index",
12890                                     loc->sw_if_index);
12891         }
12892       else
12893         {
12894           if (loc->is_ipv6)
12895             {
12896               clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
12897               vat_json_object_add_ip6 (locator, "locator", ip6);
12898             }
12899           else
12900             {
12901               clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
12902               vat_json_object_add_ip4 (locator, "locator", ip4);
12903             }
12904         }
12905       vat_json_object_add_uint (locator, "priority", loc->priority);
12906       vat_json_object_add_uint (locator, "weight", loc->weight);
12907     }
12908
12909     vec_free (ls->locator_set_name);
12910     vec_free (vam->locator_msg);
12911   }
12912
12913   vat_json_print (vam->ofp, &vam->json_tree);
12914   vat_json_free (&vam->json_tree);
12915   vam->json_tree.type = VAT_JSON_NONE;
12916
12917   vec_free (vam->locator_set_msg);
12918
12919   return ret;
12920 }
12921
12922 static int
12923 get_locator_set_index_from_msg (vat_main_t * vam, u8 * locator_set,
12924                                 u32 * locator_set_index)
12925 {
12926   locator_set_msg_t *ls;
12927   int ret = 0;
12928
12929   *locator_set_index = ~0;
12930
12931   if (!vec_len (vam->locator_set_msg))
12932     {
12933       return ret;
12934     }
12935
12936   vec_foreach (ls, vam->locator_set_msg)
12937   {
12938     if (!strcmp ((char *) locator_set, (char *) ls->locator_set_name))
12939       {
12940         *locator_set_index = ls->locator_set_index;
12941         vec_free (vam->locator_set_msg);
12942         return ret;
12943       }
12944   }
12945
12946   vec_free (vam->locator_set_msg);
12947
12948   return ret;
12949 }
12950
12951 static int
12952 get_locator_set_index (vat_main_t * vam, u8 * locator_set,
12953                        u32 * locator_set_index)
12954 {
12955   vl_api_lisp_locator_set_dump_t *mp;
12956   f64 timeout = ~0;
12957
12958   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
12959   /* send it... */
12960   S;
12961
12962   /* Use a control ping for synchronization */
12963   {
12964     vl_api_noprint_control_ping_t *mp;
12965     M (NOPRINT_CONTROL_PING, noprint_control_ping);
12966     S;
12967   }
12968
12969   vam->noprint_msg = 1;
12970   /* Wait for a reply... */
12971   /* *INDENT-OFF* */
12972   W_L
12973   ({
12974     get_locator_set_index_from_msg (vam, locator_set, locator_set_index);
12975     vam->noprint_msg = 0;
12976   });
12977   /* *INDENT-ON* */
12978
12979   /* NOTREACHED */
12980   return 0;
12981 }
12982
12983 static inline int
12984 lisp_locator_dump (vat_main_t * vam, u32 locator_set_index, u8 * locator_set,
12985                    u8 filter)
12986 {
12987   int ret = 0;
12988
12989   ASSERT (vam);
12990
12991   if (!vam->json_output)
12992     {
12993       fformat (vam->ofp, "%=20s%=16s%=16s\n",
12994                "locator", "priority", "weight");
12995     }
12996
12997   if (locator_set)
12998     {
12999       ret = get_locator_set_index (vam, locator_set, &locator_set_index);
13000     }
13001
13002   if (!ret && ~0 == locator_set_index)
13003     {
13004       return -99;
13005     }
13006
13007   ret = lisp_locator_dump_send_msg (vam, locator_set_index, filter);
13008
13009   return ret;
13010 }
13011
13012 static int
13013 lisp_locator_set_dump (vat_main_t * vam, u8 filter)
13014 {
13015   vl_api_lisp_locator_set_dump_t *mp;
13016   f64 timeout = ~0;
13017
13018   if (!vam->json_output)
13019     {
13020       fformat (vam->ofp, "%=20s%=16s%=16s%=16s%=16s\n",
13021                "locator-set", "locator-set-index", "locator", "priority",
13022                "weight");
13023     }
13024
13025   vam->noprint_msg = 1;
13026
13027   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13028
13029   mp->filter = filter;
13030
13031   /* send it... */
13032   S;
13033
13034   /* Use a control ping for synchronization */
13035   {
13036     vl_api_noprint_control_ping_t *mp;
13037     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13038     S;
13039   }
13040
13041   /* Wait for a reply... */
13042   /* *INDENT-OFF* */
13043   W_L
13044   ({
13045     if (vam->noprint_msg)
13046       {
13047         if (!vam->json_output)
13048           {
13049             print_locator_in_locator_set(vam, filter);
13050           }
13051         else
13052           {
13053             json_locator_in_locator_set(vam, filter);
13054           }
13055       }
13056     vam->noprint_msg = 0;
13057   });
13058   /* *INDENT-ON* */
13059
13060   /* NOTREACHED */
13061   return 0;
13062 }
13063
13064 static int
13065 api_lisp_locator_set_dump (vat_main_t * vam)
13066 {
13067   unformat_input_t *input = vam->input;
13068   vam->noprint_msg = 0;
13069   u32 locator_set_index = ~0;
13070   u8 locator_set_index_set = 0;
13071   u8 *locator_set = 0;
13072   u8 locator_set_set = 0;
13073   u8 filter = 0;
13074   int ret = 0;
13075
13076   /* Parse args required to build the message */
13077   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13078     {
13079       if (unformat (input, "locator-set-index %u", &locator_set_index))
13080         {
13081           locator_set_index_set = 1;
13082         }
13083       else if (unformat (input, "locator-set %s", &locator_set))
13084         {
13085           locator_set_set = 1;
13086         }
13087       else if (unformat (input, "local"))
13088         {
13089           filter = 1;
13090         }
13091       else if (unformat (input, "remote"))
13092         {
13093           filter = 2;
13094         }
13095       else
13096         {
13097           break;
13098         }
13099     }
13100
13101   if (locator_set_index_set && locator_set_set)
13102     {
13103       errmsg ("use only input parameter!\n");
13104       return -99;
13105     }
13106
13107   if (locator_set_index_set || locator_set_set)
13108     {
13109       ret = lisp_locator_dump (vam, locator_set_index, locator_set, filter);
13110     }
13111   else
13112     {
13113       ret = lisp_locator_set_dump (vam, filter);
13114     }
13115
13116   vec_free (locator_set);
13117
13118   return ret;
13119 }
13120
13121 static int
13122 api_lisp_eid_table_map_dump (vat_main_t * vam)
13123 {
13124   u8 is_l2 = 0;
13125   u8 mode_set = 0;
13126   unformat_input_t *input = vam->input;
13127   vl_api_lisp_eid_table_map_dump_t *mp;
13128   f64 timeout = ~0;
13129
13130   /* Parse args required to build the message */
13131   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13132     {
13133       if (unformat (input, "l2"))
13134         {
13135           is_l2 = 1;
13136           mode_set = 1;
13137         }
13138       else if (unformat (input, "l3"))
13139         {
13140           is_l2 = 0;
13141           mode_set = 1;
13142         }
13143       else
13144         {
13145           errmsg ("parse error '%U'", format_unformat_error, input);
13146           return -99;
13147         }
13148     }
13149
13150   if (!mode_set)
13151     {
13152       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13153       return -99;
13154     }
13155
13156   if (!vam->json_output)
13157     {
13158       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13159     }
13160
13161   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13162   mp->is_l2 = is_l2;
13163
13164   /* send it... */
13165   S;
13166
13167   /* Use a control ping for synchronization */
13168   {
13169     vl_api_control_ping_t *mp;
13170     M (CONTROL_PING, control_ping);
13171     S;
13172   }
13173   /* Wait for a reply... */
13174   W;
13175
13176   /* NOTREACHED */
13177   return 0;
13178 }
13179
13180 static int
13181 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13182 {
13183   vl_api_lisp_eid_table_vni_dump_t *mp;
13184   f64 timeout = ~0;
13185
13186   if (!vam->json_output)
13187     {
13188       fformat (vam->ofp, "VNI\n");
13189     }
13190
13191   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13192
13193   /* send it... */
13194   S;
13195
13196   /* Use a control ping for synchronization */
13197   {
13198     vl_api_control_ping_t *mp;
13199     M (CONTROL_PING, control_ping);
13200     S;
13201   }
13202   /* Wait for a reply... */
13203   W;
13204
13205   /* NOTREACHED */
13206   return 0;
13207 }
13208
13209 static int
13210 get_locator_set (vat_main_t * vam)
13211 {
13212   vl_api_lisp_locator_set_dump_t *mp;
13213   f64 timeout = ~0;
13214
13215   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13216   /* send it... */
13217   S;
13218
13219   /* Use a control ping for synchronization */
13220   {
13221     vl_api_noprint_control_ping_t *mp;
13222     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13223     S;
13224   }
13225
13226   /* Wait for a reply... */
13227   W;
13228
13229   /* NOTREACHED */
13230   return 0;
13231 }
13232
13233 static inline u8 *
13234 format_eid_for_eid_table (vat_main_t * vam, u8 * str, eid_table_t * eid_table,
13235                           int *ret)
13236 {
13237   u8 *(*format_eid) (u8 *, va_list *) = 0;
13238
13239   ASSERT (vam != NULL);
13240   ASSERT (eid_table != NULL);
13241
13242   if (ret)
13243     {
13244       *ret = 0;
13245     }
13246
13247   switch (eid_table->eid_type)
13248     {
13249     case 0:
13250     case 1:
13251       format_eid = (eid_table->eid_type ? format_ip6_address :
13252                     format_ip4_address);
13253       str = format (0, "[%d] %U/%d", eid_table->vni,
13254                     format_eid, eid_table->eid, eid_table->eid_prefix_len);
13255       break;
13256     case 2:
13257       str = format (0, "[%d] %U", eid_table->vni,
13258                     format_ethernet_address, eid_table->eid);
13259       break;
13260     default:
13261       errmsg ("unknown EID type %d!", eid_table->eid_type);
13262       if (ret)
13263         {
13264           *ret = -99;
13265         }
13266       return 0;
13267     }
13268
13269   return str;
13270 }
13271
13272 static inline u8 *
13273 format_locator_set_for_eid_table (vat_main_t * vam, u8 * str,
13274                                   eid_table_t * eid_table)
13275 {
13276   locator_set_msg_t *ls = 0;
13277
13278   ASSERT (vam != NULL);
13279   ASSERT (eid_table != NULL);
13280
13281   if (eid_table->is_local)
13282     {
13283       vec_foreach (ls, vam->locator_set_msg)
13284       {
13285         if (ls->locator_set_index == eid_table->locator_set_index)
13286           {
13287             str = format (0, "local(%s)", ls->locator_set_name);
13288             return str;
13289           }
13290       }
13291
13292       str = format (0, "local(N/A)");
13293     }
13294   else
13295     {
13296       str = format (0, "remote");
13297     }
13298
13299   return str;
13300 }
13301
13302 static inline u8 *
13303 format_locator_for_eid_table (vat_main_t * vam, u8 * str,
13304                               eid_table_t * eid_table)
13305 {
13306   locator_msg_t *loc = 0;
13307   int first_line = 1;
13308
13309   ASSERT (vam != NULL);
13310   ASSERT (eid_table != NULL);
13311
13312   if (~0 == eid_table->locator_set_index)
13313     {
13314       return format (0, "action: %d\n", eid_table->action);
13315     }
13316
13317   vec_foreach (loc, vam->locator_msg)
13318   {
13319     if (!first_line)
13320       {
13321         if (loc->local)
13322           {
13323             str = format (str, "%-55s%-d\n", " ", loc->sw_if_index);
13324           }
13325         else
13326           {
13327             str = format (str, "%=55s%-U\n", " ",
13328                           loc->is_ipv6 ? format_ip6_address :
13329                           format_ip4_address, loc->ip_address);
13330           }
13331
13332         continue;
13333       }
13334
13335     if (loc->local)
13336       {
13337         str = format (str, "%-30d%-20u%-u\n", loc->sw_if_index,
13338                       eid_table->ttl, eid_table->authoritative);
13339       }
13340     else
13341       {
13342         str = format (str, "%-30U%-20u%-u\n",
13343                       loc->is_ipv6 ? format_ip6_address :
13344                       format_ip4_address,
13345                       loc->ip_address, eid_table->ttl,
13346                       eid_table->authoritative);
13347       }
13348     first_line = 0;
13349   }
13350
13351   return str;
13352 }
13353
13354 static int
13355 print_lisp_eid_table_dump (vat_main_t * vam)
13356 {
13357   eid_table_t *eid_table = 0;
13358   u8 *tmp_str = 0, *tmp_str2 = 0;
13359   int ret = 0;
13360
13361   ASSERT (vam != NULL);
13362
13363   ret = get_locator_set (vam);
13364   if (ret)
13365     {
13366       vec_free (vam->eid_tables);
13367       return ret;
13368     }
13369
13370   fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type", "locators",
13371            "ttl", "authoritative");
13372
13373   vec_foreach (eid_table, vam->eid_tables)
13374   {
13375     if (~0 != eid_table->locator_set_index)
13376       {
13377         ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index,
13378                                           0);
13379         if (ret)
13380           {
13381             vec_free (vam->locator_msg);
13382             clean_locator_set_message (vam);
13383             vec_free (vam->eid_tables);
13384             return ret;
13385           }
13386       }
13387
13388     tmp_str2 = format_eid_for_eid_table (vam, tmp_str2, eid_table, &ret);
13389     if (ret)
13390       {
13391         vec_free (vam->locator_msg);
13392         clean_locator_set_message (vam);
13393         vec_free (vam->eid_tables);
13394         return ret;
13395       }
13396
13397     tmp_str = format (0, "%-35s", tmp_str2);
13398     vec_free (tmp_str2);
13399
13400     tmp_str2 = format_locator_set_for_eid_table (vam, tmp_str2, eid_table);
13401     tmp_str = format (tmp_str, "%-20s", tmp_str2);
13402     vec_free (tmp_str2);
13403
13404     tmp_str2 = format_locator_for_eid_table (vam, tmp_str2, eid_table);
13405     tmp_str = format (tmp_str, "%-s", tmp_str2);
13406     vec_free (tmp_str2);
13407
13408     fformat (vam->ofp, "%s", tmp_str);
13409     vec_free (tmp_str);
13410     vec_free (vam->locator_msg);
13411   }
13412
13413   clean_locator_set_message (vam);
13414   vec_free (vam->eid_tables);
13415
13416   return ret;
13417 }
13418
13419 static inline void
13420 json_locator_set_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13421                                 eid_table_t * eid_table)
13422 {
13423   locator_set_msg_t *ls = 0;
13424   u8 *s = 0;
13425
13426   ASSERT (vam != NULL);
13427   ASSERT (node != NULL);
13428   ASSERT (eid_table != NULL);
13429
13430   if (eid_table->is_local)
13431     {
13432       vec_foreach (ls, vam->locator_set_msg)
13433       {
13434         if (ls->locator_set_index == eid_table->locator_set_index)
13435           {
13436             vat_json_object_add_string_copy (node, "locator-set",
13437                                              ls->locator_set_name);
13438             return;
13439           }
13440       }
13441
13442       s = format (0, "N/A");
13443       vec_add1 (s, 0);
13444       vat_json_object_add_string_copy (node, "locator-set", s);
13445       vec_free (s);
13446     }
13447   else
13448     {
13449       s = format (0, "remote");
13450       vec_add1 (s, 0);
13451       vat_json_object_add_string_copy (node, "locator-set", s);
13452       vec_free (s);
13453     }
13454 }
13455
13456 static inline int
13457 json_eid_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13458                         eid_table_t * eid_table)
13459 {
13460   u8 *s = 0;
13461   struct in6_addr ip6;
13462   struct in_addr ip4;
13463
13464   ASSERT (vam != NULL);
13465   ASSERT (node != NULL);
13466   ASSERT (eid_table != NULL);
13467
13468   switch (eid_table->eid_type)
13469     {
13470     case 0:
13471       clib_memcpy (&ip4, eid_table->eid, sizeof (ip4));
13472       vat_json_object_add_ip4 (node, "eid", ip4);
13473       vat_json_object_add_uint (node, "eid-prefix-len",
13474                                 eid_table->eid_prefix_len);
13475       break;
13476     case 1:
13477       clib_memcpy (&ip6, eid_table->eid, sizeof (ip6));
13478       vat_json_object_add_ip6 (node, "eid", ip6);
13479       vat_json_object_add_uint (node, "eid-prefix-len",
13480                                 eid_table->eid_prefix_len);
13481       break;
13482     case 2:
13483       s = format (0, "%U", format_ethernet_address, eid_table->eid);
13484       vec_add1 (s, 0);
13485       vat_json_object_add_string_copy (node, "eid", s);
13486       vec_free (s);
13487       break;
13488     default:
13489       errmsg ("unknown EID type %d!", eid_table->eid_type);
13490       return -99;
13491     }
13492
13493   return 0;
13494 }
13495
13496 static inline void
13497 json_locator_for_eid_table (vat_main_t * vam, vat_json_node_t * node,
13498                             eid_table_t * eid_table)
13499 {
13500   locator_msg_t *loc = 0;
13501   vat_json_node_t *locator_array = 0;
13502   vat_json_node_t *locator = 0;
13503   struct in6_addr ip6;
13504   struct in_addr ip4;
13505
13506   ASSERT (vam != NULL);
13507   ASSERT (node != NULL);
13508   ASSERT (eid_table != NULL);
13509
13510   locator_array = vat_json_object_add_list (node, "locator");
13511   vec_foreach (loc, vam->locator_msg)
13512   {
13513     locator = vat_json_array_add (locator_array);
13514     vat_json_init_object (locator);
13515     if (loc->local)
13516       {
13517         vat_json_object_add_uint (locator, "locator-index", loc->sw_if_index);
13518       }
13519     else
13520       {
13521         if (loc->is_ipv6)
13522           {
13523             clib_memcpy (&ip6, loc->ip_address, sizeof (ip6));
13524             vat_json_object_add_ip6 (locator, "locator", ip6);
13525           }
13526         else
13527           {
13528             clib_memcpy (&ip4, loc->ip_address, sizeof (ip4));
13529             vat_json_object_add_ip4 (locator, "locator", ip4);
13530           }
13531       }
13532   }
13533 }
13534
13535 static int
13536 json_lisp_eid_table_dump (vat_main_t * vam)
13537 {
13538   eid_table_t *eid_table;
13539   vat_json_node_t *node = 0;
13540   int ret = 0;
13541
13542   ASSERT (vam != NULL);
13543
13544   ret = get_locator_set (vam);
13545   if (ret)
13546     {
13547       vec_free (vam->eid_tables);
13548       return ret;
13549     }
13550
13551   if (!vec_len (vam->eid_tables))
13552     {
13553       /* just print [] */
13554       vat_json_init_array (&vam->json_tree);
13555       vat_json_print (vam->ofp, &vam->json_tree);
13556       vam->json_tree.type = VAT_JSON_NONE;
13557       return ret;
13558     }
13559
13560   if (VAT_JSON_ARRAY != vam->json_tree.type)
13561     {
13562       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13563       vat_json_init_array (&vam->json_tree);
13564     }
13565
13566   vec_foreach (eid_table, vam->eid_tables)
13567   {
13568     ret = lisp_locator_dump_send_msg (vam, eid_table->locator_set_index, 0);
13569     if (ret)
13570       {
13571         vec_free (vam->locator_msg);
13572         vec_free (vam->eid_tables);
13573         clean_locator_set_message (vam);
13574         vat_json_free (&vam->json_tree);
13575         vam->json_tree.type = VAT_JSON_NONE;
13576         return ret;
13577       }
13578
13579     node = vat_json_array_add (&vam->json_tree);
13580     vat_json_init_object (node);
13581
13582     vat_json_object_add_uint (node, "vni", eid_table->vni);
13583
13584     json_locator_set_for_eid_table (vam, node, eid_table);
13585     ret = json_eid_for_eid_table (vam, node, eid_table);
13586     if (ret)
13587       {
13588         vec_free (vam->locator_msg);
13589         vec_free (vam->eid_tables);
13590         clean_locator_set_message (vam);
13591         vat_json_free (&vam->json_tree);
13592         vam->json_tree.type = VAT_JSON_NONE;
13593         return ret;
13594       }
13595
13596     json_locator_for_eid_table (vam, node, eid_table);
13597
13598     vat_json_object_add_uint (node, "ttl", eid_table->ttl);
13599     vat_json_object_add_uint (node, "authoritative",
13600                               eid_table->authoritative);
13601
13602     vec_free (vam->locator_msg);
13603   }
13604
13605   vat_json_print (vam->ofp, &vam->json_tree);
13606   vat_json_free (&vam->json_tree);
13607   vam->json_tree.type = VAT_JSON_NONE;
13608
13609   clean_locator_set_message (vam);
13610   vec_free (vam->eid_tables);
13611
13612   return ret;
13613 }
13614
13615 static int
13616 api_lisp_eid_table_dump (vat_main_t * vam)
13617 {
13618   unformat_input_t *i = vam->input;
13619   vl_api_lisp_eid_table_dump_t *mp;
13620   f64 timeout = ~0;
13621   struct in_addr ip4;
13622   struct in6_addr ip6;
13623   u8 mac[6];
13624   u8 eid_type = ~0, eid_set = 0;
13625   u32 prefix_length = ~0, t, vni = 0;
13626   u8 filter = 0;
13627
13628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13629     {
13630       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
13631         {
13632           eid_set = 1;
13633           eid_type = 0;
13634           prefix_length = t;
13635         }
13636       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
13637         {
13638           eid_set = 1;
13639           eid_type = 1;
13640           prefix_length = t;
13641         }
13642       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
13643         {
13644           eid_set = 1;
13645           eid_type = 2;
13646         }
13647       else if (unformat (i, "vni %d", &t))
13648         {
13649           vni = t;
13650         }
13651       else if (unformat (i, "local"))
13652         {
13653           filter = 1;
13654         }
13655       else if (unformat (i, "remote"))
13656         {
13657           filter = 2;
13658         }
13659       else
13660         {
13661           errmsg ("parse error '%U'", format_unformat_error, i);
13662           return -99;
13663         }
13664     }
13665
13666   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
13667
13668   mp->filter = filter;
13669   if (eid_set)
13670     {
13671       mp->eid_set = 1;
13672       mp->vni = htonl (vni);
13673       mp->eid_type = eid_type;
13674       switch (eid_type)
13675         {
13676         case 0:
13677           mp->prefix_length = prefix_length;
13678           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
13679           break;
13680         case 1:
13681           mp->prefix_length = prefix_length;
13682           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
13683           break;
13684         case 2:
13685           clib_memcpy (mp->eid, mac, sizeof (mac));
13686           break;
13687         default:
13688           errmsg ("unknown EID type %d!", eid_type);
13689           return -99;
13690         }
13691     }
13692
13693   vam->noprint_msg = 1;
13694
13695   /* send it... */
13696   S;
13697
13698   /* Use a control ping for synchronization */
13699   {
13700     vl_api_noprint_control_ping_t *mp;
13701     M (NOPRINT_CONTROL_PING, noprint_control_ping);
13702     S;
13703   }
13704
13705   /* Wait for a reply... */
13706   /* *INDENT-OFF* */
13707   W_L
13708   ({
13709     if (vam->noprint_msg)
13710       {
13711         if (!vam->json_output)
13712           {
13713             vam->retval = print_lisp_eid_table_dump(vam);
13714           }
13715         else
13716           {
13717             vam->retval = json_lisp_eid_table_dump(vam);
13718           }
13719       }
13720     vam->noprint_msg = 0;
13721   });
13722   /* *INDENT-ON* */
13723
13724   /* NOTREACHED */
13725   return 0;
13726 }
13727
13728 static int
13729 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
13730 {
13731   vl_api_lisp_gpe_tunnel_dump_t *mp;
13732   f64 timeout = ~0;
13733
13734   if (!vam->json_output)
13735     {
13736       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
13737                "%=16s%=16s%=16s%=16s%=16s\n",
13738                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
13739                "Decap next", "Lisp version", "Flags", "Next protocol",
13740                "ver_res", "res", "iid");
13741     }
13742
13743   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
13744   /* send it... */
13745   S;
13746
13747   /* Use a control ping for synchronization */
13748   {
13749     vl_api_control_ping_t *mp;
13750     M (CONTROL_PING, control_ping);
13751     S;
13752   }
13753   /* Wait for a reply... */
13754   W;
13755
13756   /* NOTREACHED */
13757   return 0;
13758 }
13759
13760 static int
13761 api_lisp_map_resolver_dump (vat_main_t * vam)
13762 {
13763   vl_api_lisp_map_resolver_dump_t *mp;
13764   f64 timeout = ~0;
13765
13766   if (!vam->json_output)
13767     {
13768       fformat (vam->ofp, "%=20s\n", "Map resolver");
13769     }
13770
13771   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
13772   /* send it... */
13773   S;
13774
13775   /* Use a control ping for synchronization */
13776   {
13777     vl_api_control_ping_t *mp;
13778     M (CONTROL_PING, control_ping);
13779     S;
13780   }
13781   /* Wait for a reply... */
13782   W;
13783
13784   /* NOTREACHED */
13785   return 0;
13786 }
13787
13788 static int
13789 api_show_lisp_status (vat_main_t * vam)
13790 {
13791   vl_api_show_lisp_status_t *mp;
13792   f64 timeout = ~0;
13793
13794   if (!vam->json_output)
13795     {
13796       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
13797     }
13798
13799   M (SHOW_LISP_STATUS, show_lisp_status);
13800   /* send it... */
13801   S;
13802   /* Wait for a reply... */
13803   W;
13804
13805   /* NOTREACHED */
13806   return 0;
13807 }
13808
13809 static int
13810 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
13811 {
13812   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
13813   f64 timeout = ~0;
13814
13815   if (!vam->json_output)
13816     {
13817       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
13818     }
13819
13820   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
13821   /* send it... */
13822   S;
13823   /* Wait for a reply... */
13824   W;
13825
13826   /* NOTREACHED */
13827   return 0;
13828 }
13829
13830 static int
13831 api_af_packet_create (vat_main_t * vam)
13832 {
13833   unformat_input_t *i = vam->input;
13834   vl_api_af_packet_create_t *mp;
13835   f64 timeout;
13836   u8 *host_if_name = 0;
13837   u8 hw_addr[6];
13838   u8 random_hw_addr = 1;
13839
13840   memset (hw_addr, 0, sizeof (hw_addr));
13841
13842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13843     {
13844       if (unformat (i, "name %s", &host_if_name))
13845         vec_add1 (host_if_name, 0);
13846       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
13847         random_hw_addr = 0;
13848       else
13849         break;
13850     }
13851
13852   if (!vec_len (host_if_name))
13853     {
13854       errmsg ("host-interface name must be specified");
13855       return -99;
13856     }
13857
13858   if (vec_len (host_if_name) > 64)
13859     {
13860       errmsg ("host-interface name too long");
13861       return -99;
13862     }
13863
13864   M (AF_PACKET_CREATE, af_packet_create);
13865
13866   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13867   clib_memcpy (mp->hw_addr, hw_addr, 6);
13868   mp->use_random_hw_addr = random_hw_addr;
13869   vec_free (host_if_name);
13870
13871   S;
13872   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
13873   /* NOTREACHED */
13874   return 0;
13875 }
13876
13877 static int
13878 api_af_packet_delete (vat_main_t * vam)
13879 {
13880   unformat_input_t *i = vam->input;
13881   vl_api_af_packet_delete_t *mp;
13882   f64 timeout;
13883   u8 *host_if_name = 0;
13884
13885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13886     {
13887       if (unformat (i, "name %s", &host_if_name))
13888         vec_add1 (host_if_name, 0);
13889       else
13890         break;
13891     }
13892
13893   if (!vec_len (host_if_name))
13894     {
13895       errmsg ("host-interface name must be specified");
13896       return -99;
13897     }
13898
13899   if (vec_len (host_if_name) > 64)
13900     {
13901       errmsg ("host-interface name too long");
13902       return -99;
13903     }
13904
13905   M (AF_PACKET_DELETE, af_packet_delete);
13906
13907   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
13908   vec_free (host_if_name);
13909
13910   S;
13911   W;
13912   /* NOTREACHED */
13913   return 0;
13914 }
13915
13916 static int
13917 api_policer_add_del (vat_main_t * vam)
13918 {
13919   unformat_input_t *i = vam->input;
13920   vl_api_policer_add_del_t *mp;
13921   f64 timeout;
13922   u8 is_add = 1;
13923   u8 *name = 0;
13924   u32 cir = 0;
13925   u32 eir = 0;
13926   u64 cb = 0;
13927   u64 eb = 0;
13928   u8 rate_type = 0;
13929   u8 round_type = 0;
13930   u8 type = 0;
13931   u8 color_aware = 0;
13932   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
13933
13934   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
13935   conform_action.dscp = 0;
13936   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
13937   exceed_action.dscp = 0;
13938   violate_action.action_type = SSE2_QOS_ACTION_DROP;
13939   violate_action.dscp = 0;
13940
13941   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13942     {
13943       if (unformat (i, "del"))
13944         is_add = 0;
13945       else if (unformat (i, "name %s", &name))
13946         vec_add1 (name, 0);
13947       else if (unformat (i, "cir %u", &cir))
13948         ;
13949       else if (unformat (i, "eir %u", &eir))
13950         ;
13951       else if (unformat (i, "cb %u", &cb))
13952         ;
13953       else if (unformat (i, "eb %u", &eb))
13954         ;
13955       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
13956                          &rate_type))
13957         ;
13958       else if (unformat (i, "round_type %U", unformat_policer_round_type,
13959                          &round_type))
13960         ;
13961       else if (unformat (i, "type %U", unformat_policer_type, &type))
13962         ;
13963       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
13964                          &conform_action))
13965         ;
13966       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
13967                          &exceed_action))
13968         ;
13969       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
13970                          &violate_action))
13971         ;
13972       else if (unformat (i, "color-aware"))
13973         color_aware = 1;
13974       else
13975         break;
13976     }
13977
13978   if (!vec_len (name))
13979     {
13980       errmsg ("policer name must be specified");
13981       return -99;
13982     }
13983
13984   if (vec_len (name) > 64)
13985     {
13986       errmsg ("policer name too long");
13987       return -99;
13988     }
13989
13990   M (POLICER_ADD_DEL, policer_add_del);
13991
13992   clib_memcpy (mp->name, name, vec_len (name));
13993   vec_free (name);
13994   mp->is_add = is_add;
13995   mp->cir = cir;
13996   mp->eir = eir;
13997   mp->cb = cb;
13998   mp->eb = eb;
13999   mp->rate_type = rate_type;
14000   mp->round_type = round_type;
14001   mp->type = type;
14002   mp->conform_action_type = conform_action.action_type;
14003   mp->conform_dscp = conform_action.dscp;
14004   mp->exceed_action_type = exceed_action.action_type;
14005   mp->exceed_dscp = exceed_action.dscp;
14006   mp->violate_action_type = violate_action.action_type;
14007   mp->violate_dscp = violate_action.dscp;
14008   mp->color_aware = color_aware;
14009
14010   S;
14011   W;
14012   /* NOTREACHED */
14013   return 0;
14014 }
14015
14016 static int
14017 api_policer_dump (vat_main_t * vam)
14018 {
14019   unformat_input_t *i = vam->input;
14020   vl_api_policer_dump_t *mp;
14021   f64 timeout = ~0;
14022   u8 *match_name = 0;
14023   u8 match_name_valid = 0;
14024
14025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14026     {
14027       if (unformat (i, "name %s", &match_name))
14028         {
14029           vec_add1 (match_name, 0);
14030           match_name_valid = 1;
14031         }
14032       else
14033         break;
14034     }
14035
14036   M (POLICER_DUMP, policer_dump);
14037   mp->match_name_valid = match_name_valid;
14038   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14039   vec_free (match_name);
14040   /* send it... */
14041   S;
14042
14043   /* Use a control ping for synchronization */
14044   {
14045     vl_api_control_ping_t *mp;
14046     M (CONTROL_PING, control_ping);
14047     S;
14048   }
14049   /* Wait for a reply... */
14050   W;
14051
14052   /* NOTREACHED */
14053   return 0;
14054 }
14055
14056 static int
14057 api_policer_classify_set_interface (vat_main_t * vam)
14058 {
14059   unformat_input_t *i = vam->input;
14060   vl_api_policer_classify_set_interface_t *mp;
14061   f64 timeout;
14062   u32 sw_if_index;
14063   int sw_if_index_set;
14064   u32 ip4_table_index = ~0;
14065   u32 ip6_table_index = ~0;
14066   u32 l2_table_index = ~0;
14067   u8 is_add = 1;
14068
14069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14070     {
14071       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14072         sw_if_index_set = 1;
14073       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14074         sw_if_index_set = 1;
14075       else if (unformat (i, "del"))
14076         is_add = 0;
14077       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14078         ;
14079       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14080         ;
14081       else if (unformat (i, "l2-table %d", &l2_table_index))
14082         ;
14083       else
14084         {
14085           clib_warning ("parse error '%U'", format_unformat_error, i);
14086           return -99;
14087         }
14088     }
14089
14090   if (sw_if_index_set == 0)
14091     {
14092       errmsg ("missing interface name or sw_if_index\n");
14093       return -99;
14094     }
14095
14096   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14097
14098   mp->sw_if_index = ntohl (sw_if_index);
14099   mp->ip4_table_index = ntohl (ip4_table_index);
14100   mp->ip6_table_index = ntohl (ip6_table_index);
14101   mp->l2_table_index = ntohl (l2_table_index);
14102   mp->is_add = is_add;
14103
14104   S;
14105   W;
14106   /* NOTREACHED */
14107   return 0;
14108 }
14109
14110 static int
14111 api_policer_classify_dump (vat_main_t * vam)
14112 {
14113   unformat_input_t *i = vam->input;
14114   vl_api_policer_classify_dump_t *mp;
14115   f64 timeout = ~0;
14116   u8 type = POLICER_CLASSIFY_N_TABLES;
14117
14118   if (unformat (i, "type %U", unformat_classify_table_type, &type))
14119     ;
14120   else
14121     {
14122       errmsg ("classify table type must be specified\n");
14123       return -99;
14124     }
14125
14126   if (!vam->json_output)
14127     {
14128       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14129     }
14130
14131   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14132   mp->type = type;
14133   /* send it... */
14134   S;
14135
14136   /* Use a control ping for synchronization */
14137   {
14138     vl_api_control_ping_t *mp;
14139     M (CONTROL_PING, control_ping);
14140     S;
14141   }
14142   /* Wait for a reply... */
14143   W;
14144
14145   /* NOTREACHED */
14146   return 0;
14147 }
14148
14149 static int
14150 api_netmap_create (vat_main_t * vam)
14151 {
14152   unformat_input_t *i = vam->input;
14153   vl_api_netmap_create_t *mp;
14154   f64 timeout;
14155   u8 *if_name = 0;
14156   u8 hw_addr[6];
14157   u8 random_hw_addr = 1;
14158   u8 is_pipe = 0;
14159   u8 is_master = 0;
14160
14161   memset (hw_addr, 0, sizeof (hw_addr));
14162
14163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14164     {
14165       if (unformat (i, "name %s", &if_name))
14166         vec_add1 (if_name, 0);
14167       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14168         random_hw_addr = 0;
14169       else if (unformat (i, "pipe"))
14170         is_pipe = 1;
14171       else if (unformat (i, "master"))
14172         is_master = 1;
14173       else if (unformat (i, "slave"))
14174         is_master = 0;
14175       else
14176         break;
14177     }
14178
14179   if (!vec_len (if_name))
14180     {
14181       errmsg ("interface name must be specified");
14182       return -99;
14183     }
14184
14185   if (vec_len (if_name) > 64)
14186     {
14187       errmsg ("interface name too long");
14188       return -99;
14189     }
14190
14191   M (NETMAP_CREATE, netmap_create);
14192
14193   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14194   clib_memcpy (mp->hw_addr, hw_addr, 6);
14195   mp->use_random_hw_addr = random_hw_addr;
14196   mp->is_pipe = is_pipe;
14197   mp->is_master = is_master;
14198   vec_free (if_name);
14199
14200   S;
14201   W;
14202   /* NOTREACHED */
14203   return 0;
14204 }
14205
14206 static int
14207 api_netmap_delete (vat_main_t * vam)
14208 {
14209   unformat_input_t *i = vam->input;
14210   vl_api_netmap_delete_t *mp;
14211   f64 timeout;
14212   u8 *if_name = 0;
14213
14214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14215     {
14216       if (unformat (i, "name %s", &if_name))
14217         vec_add1 (if_name, 0);
14218       else
14219         break;
14220     }
14221
14222   if (!vec_len (if_name))
14223     {
14224       errmsg ("interface name must be specified");
14225       return -99;
14226     }
14227
14228   if (vec_len (if_name) > 64)
14229     {
14230       errmsg ("interface name too long");
14231       return -99;
14232     }
14233
14234   M (NETMAP_DELETE, netmap_delete);
14235
14236   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14237   vec_free (if_name);
14238
14239   S;
14240   W;
14241   /* NOTREACHED */
14242   return 0;
14243 }
14244
14245 static void vl_api_mpls_gre_tunnel_details_t_handler
14246   (vl_api_mpls_gre_tunnel_details_t * mp)
14247 {
14248   vat_main_t *vam = &vat_main;
14249   i32 i;
14250   i32 len = ntohl (mp->nlabels);
14251
14252   if (mp->l2_only == 0)
14253     {
14254       fformat (vam->ofp, "[%d]: src %U, dst %U, adj %U/%d, labels ",
14255                ntohl (mp->tunnel_index),
14256                format_ip4_address, &mp->tunnel_src,
14257                format_ip4_address, &mp->tunnel_dst,
14258                format_ip4_address, &mp->intfc_address,
14259                ntohl (mp->mask_width));
14260       for (i = 0; i < len; i++)
14261         {
14262           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14263         }
14264       fformat (vam->ofp, "\n");
14265       fformat (vam->ofp, "      inner fib index %d, outer fib index %d\n",
14266                ntohl (mp->inner_fib_index), ntohl (mp->outer_fib_index));
14267     }
14268   else
14269     {
14270       fformat (vam->ofp, "[%d]: src %U, dst %U, key %U, labels ",
14271                ntohl (mp->tunnel_index),
14272                format_ip4_address, &mp->tunnel_src,
14273                format_ip4_address, &mp->tunnel_dst,
14274                format_ip4_address, &mp->intfc_address);
14275       for (i = 0; i < len; i++)
14276         {
14277           fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14278         }
14279       fformat (vam->ofp, "\n");
14280       fformat (vam->ofp, "      l2 interface %d, outer fib index %d\n",
14281                ntohl (mp->hw_if_index), ntohl (mp->outer_fib_index));
14282     }
14283 }
14284
14285 static void vl_api_mpls_gre_tunnel_details_t_handler_json
14286   (vl_api_mpls_gre_tunnel_details_t * mp)
14287 {
14288   vat_main_t *vam = &vat_main;
14289   vat_json_node_t *node = NULL;
14290   struct in_addr ip4;
14291   i32 i;
14292   i32 len = ntohl (mp->nlabels);
14293
14294   if (VAT_JSON_ARRAY != vam->json_tree.type)
14295     {
14296       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14297       vat_json_init_array (&vam->json_tree);
14298     }
14299   node = vat_json_array_add (&vam->json_tree);
14300
14301   vat_json_init_object (node);
14302   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14303   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14304   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14305   vat_json_object_add_uint (node, "inner_fib_index",
14306                             ntohl (mp->inner_fib_index));
14307   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14308   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14309   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14310   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14311   clib_memcpy (&ip4, &(mp->tunnel_src), sizeof (ip4));
14312   vat_json_object_add_ip4 (node, "tunnel_src", ip4);
14313   clib_memcpy (&ip4, &(mp->tunnel_dst), sizeof (ip4));
14314   vat_json_object_add_ip4 (node, "tunnel_dst", ip4);
14315   vat_json_object_add_uint (node, "outer_fib_index",
14316                             ntohl (mp->outer_fib_index));
14317   vat_json_object_add_uint (node, "label_count", len);
14318   for (i = 0; i < len; i++)
14319     {
14320       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14321     }
14322 }
14323
14324 static int
14325 api_mpls_gre_tunnel_dump (vat_main_t * vam)
14326 {
14327   vl_api_mpls_gre_tunnel_dump_t *mp;
14328   f64 timeout;
14329   i32 index = -1;
14330
14331   /* Parse args required to build the message */
14332   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14333     {
14334       if (!unformat (vam->input, "tunnel_index %d", &index))
14335         {
14336           index = -1;
14337           break;
14338         }
14339     }
14340
14341   fformat (vam->ofp, "  tunnel_index %d\n", index);
14342
14343   M (MPLS_GRE_TUNNEL_DUMP, mpls_gre_tunnel_dump);
14344   mp->tunnel_index = htonl (index);
14345   S;
14346
14347   /* Use a control ping for synchronization */
14348   {
14349     vl_api_control_ping_t *mp;
14350     M (CONTROL_PING, control_ping);
14351     S;
14352   }
14353   W;
14354 }
14355
14356 static void vl_api_mpls_eth_tunnel_details_t_handler
14357   (vl_api_mpls_eth_tunnel_details_t * mp)
14358 {
14359   vat_main_t *vam = &vat_main;
14360   i32 i;
14361   i32 len = ntohl (mp->nlabels);
14362
14363   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14364            ntohl (mp->tunnel_index),
14365            format_ethernet_address, &mp->tunnel_dst_mac,
14366            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14367   for (i = 0; i < len; i++)
14368     {
14369       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14370     }
14371   fformat (vam->ofp, "\n");
14372   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14373            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14374 }
14375
14376 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14377   (vl_api_mpls_eth_tunnel_details_t * mp)
14378 {
14379   vat_main_t *vam = &vat_main;
14380   vat_json_node_t *node = NULL;
14381   struct in_addr ip4;
14382   i32 i;
14383   i32 len = ntohl (mp->nlabels);
14384
14385   if (VAT_JSON_ARRAY != vam->json_tree.type)
14386     {
14387       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14388       vat_json_init_array (&vam->json_tree);
14389     }
14390   node = vat_json_array_add (&vam->json_tree);
14391
14392   vat_json_init_object (node);
14393   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14394   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14395   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14396   vat_json_object_add_uint (node, "inner_fib_index",
14397                             ntohl (mp->inner_fib_index));
14398   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14399   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14400   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14401   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14402   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14403                                    format (0, "%U", format_ethernet_address,
14404                                            &mp->tunnel_dst_mac));
14405   vat_json_object_add_uint (node, "tx_sw_if_index",
14406                             ntohl (mp->tx_sw_if_index));
14407   vat_json_object_add_uint (node, "label_count", len);
14408   for (i = 0; i < len; i++)
14409     {
14410       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14411     }
14412 }
14413
14414 static int
14415 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14416 {
14417   vl_api_mpls_eth_tunnel_dump_t *mp;
14418   f64 timeout;
14419   i32 index = -1;
14420
14421   /* Parse args required to build the message */
14422   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14423     {
14424       if (!unformat (vam->input, "tunnel_index %d", &index))
14425         {
14426           index = -1;
14427           break;
14428         }
14429     }
14430
14431   fformat (vam->ofp, "  tunnel_index %d\n", index);
14432
14433   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14434   mp->tunnel_index = htonl (index);
14435   S;
14436
14437   /* Use a control ping for synchronization */
14438   {
14439     vl_api_control_ping_t *mp;
14440     M (CONTROL_PING, control_ping);
14441     S;
14442   }
14443   W;
14444 }
14445
14446 static void vl_api_mpls_fib_encap_details_t_handler
14447   (vl_api_mpls_fib_encap_details_t * mp)
14448 {
14449   vat_main_t *vam = &vat_main;
14450   i32 i;
14451   i32 len = ntohl (mp->nlabels);
14452
14453   fformat (vam->ofp, "table %d, dest %U, label ",
14454            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14455   for (i = 0; i < len; i++)
14456     {
14457       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14458     }
14459   fformat (vam->ofp, "\n");
14460 }
14461
14462 static void vl_api_mpls_fib_encap_details_t_handler_json
14463   (vl_api_mpls_fib_encap_details_t * mp)
14464 {
14465   vat_main_t *vam = &vat_main;
14466   vat_json_node_t *node = NULL;
14467   i32 i;
14468   i32 len = ntohl (mp->nlabels);
14469   struct in_addr ip4;
14470
14471   if (VAT_JSON_ARRAY != vam->json_tree.type)
14472     {
14473       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14474       vat_json_init_array (&vam->json_tree);
14475     }
14476   node = vat_json_array_add (&vam->json_tree);
14477
14478   vat_json_init_object (node);
14479   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14480   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14481   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14482   vat_json_object_add_ip4 (node, "dest", ip4);
14483   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14484   vat_json_object_add_uint (node, "label_count", len);
14485   for (i = 0; i < len; i++)
14486     {
14487       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14488     }
14489 }
14490
14491 static int
14492 api_mpls_fib_encap_dump (vat_main_t * vam)
14493 {
14494   vl_api_mpls_fib_encap_dump_t *mp;
14495   f64 timeout;
14496
14497   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14498   S;
14499
14500   /* Use a control ping for synchronization */
14501   {
14502     vl_api_control_ping_t *mp;
14503     M (CONTROL_PING, control_ping);
14504     S;
14505   }
14506   W;
14507 }
14508
14509 static void vl_api_mpls_fib_decap_details_t_handler
14510   (vl_api_mpls_fib_decap_details_t * mp)
14511 {
14512   vat_main_t *vam = &vat_main;
14513
14514   fformat (vam->ofp,
14515            "RX table %d, TX table/intfc %u, swif_tag '%s', label %u, s_bit %u\n",
14516            ntohl (mp->rx_table_id), ntohl (mp->tx_table_id), mp->swif_tag,
14517            ntohl (mp->label), ntohl (mp->s_bit));
14518 }
14519
14520 static void vl_api_mpls_fib_decap_details_t_handler_json
14521   (vl_api_mpls_fib_decap_details_t * mp)
14522 {
14523   vat_main_t *vam = &vat_main;
14524   vat_json_node_t *node = NULL;
14525   struct in_addr ip4;
14526
14527   if (VAT_JSON_ARRAY != vam->json_tree.type)
14528     {
14529       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14530       vat_json_init_array (&vam->json_tree);
14531     }
14532   node = vat_json_array_add (&vam->json_tree);
14533
14534   vat_json_init_object (node);
14535   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14536   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14537   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14538   vat_json_object_add_ip4 (node, "dest", ip4);
14539   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14540   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14541   vat_json_object_add_uint (node, "rx_table_id", ntohl (mp->rx_table_id));
14542   vat_json_object_add_uint (node, "tx_table_id", ntohl (mp->tx_table_id));
14543   vat_json_object_add_string_copy (node, "swif_tag", mp->swif_tag);
14544 }
14545
14546 static int
14547 api_mpls_fib_decap_dump (vat_main_t * vam)
14548 {
14549   vl_api_mpls_fib_decap_dump_t *mp;
14550   f64 timeout;
14551
14552   M (MPLS_FIB_DECAP_DUMP, mpls_fib_decap_dump);
14553   S;
14554
14555   /* Use a control ping for synchronization */
14556   {
14557     vl_api_control_ping_t *mp;
14558     M (CONTROL_PING, control_ping);
14559     S;
14560   }
14561   W;
14562 }
14563
14564 int
14565 api_classify_table_ids (vat_main_t * vam)
14566 {
14567   vl_api_classify_table_ids_t *mp;
14568   f64 timeout;
14569
14570   /* Construct the API message */
14571   M (CLASSIFY_TABLE_IDS, classify_table_ids);
14572   mp->context = 0;
14573
14574   S;
14575   W;
14576   /* NOTREACHED */
14577   return 0;
14578 }
14579
14580 int
14581 api_classify_table_by_interface (vat_main_t * vam)
14582 {
14583   unformat_input_t *input = vam->input;
14584   vl_api_classify_table_by_interface_t *mp;
14585   f64 timeout;
14586
14587   u32 sw_if_index = ~0;
14588   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14589     {
14590       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
14591         ;
14592       else if (unformat (input, "sw_if_index %d", &sw_if_index))
14593         ;
14594       else
14595         break;
14596     }
14597   if (sw_if_index == ~0)
14598     {
14599       errmsg ("missing interface name or sw_if_index\n");
14600       return -99;
14601     }
14602
14603   /* Construct the API message */
14604   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
14605   mp->context = 0;
14606   mp->sw_if_index = ntohl (sw_if_index);
14607
14608   S;
14609   W;
14610   /* NOTREACHED */
14611   return 0;
14612 }
14613
14614 int
14615 api_classify_table_info (vat_main_t * vam)
14616 {
14617   unformat_input_t *input = vam->input;
14618   vl_api_classify_table_info_t *mp;
14619   f64 timeout;
14620
14621   u32 table_id = ~0;
14622   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14623     {
14624       if (unformat (input, "table_id %d", &table_id))
14625         ;
14626       else
14627         break;
14628     }
14629   if (table_id == ~0)
14630     {
14631       errmsg ("missing table id\n");
14632       return -99;
14633     }
14634
14635   /* Construct the API message */
14636   M (CLASSIFY_TABLE_INFO, classify_table_info);
14637   mp->context = 0;
14638   mp->table_id = ntohl (table_id);
14639
14640   S;
14641   W;
14642   /* NOTREACHED */
14643   return 0;
14644 }
14645
14646 int
14647 api_classify_session_dump (vat_main_t * vam)
14648 {
14649   unformat_input_t *input = vam->input;
14650   vl_api_classify_session_dump_t *mp;
14651   f64 timeout;
14652
14653   u32 table_id = ~0;
14654   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14655     {
14656       if (unformat (input, "table_id %d", &table_id))
14657         ;
14658       else
14659         break;
14660     }
14661   if (table_id == ~0)
14662     {
14663       errmsg ("missing table id\n");
14664       return -99;
14665     }
14666
14667   /* Construct the API message */
14668   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
14669   mp->context = 0;
14670   mp->table_id = ntohl (table_id);
14671   S;
14672
14673   /* Use a control ping for synchronization */
14674   {
14675     vl_api_control_ping_t *mp;
14676     M (CONTROL_PING, control_ping);
14677     S;
14678   }
14679   W;
14680   /* NOTREACHED */
14681   return 0;
14682 }
14683
14684 static void
14685 vl_api_ipfix_details_t_handler (vl_api_ipfix_details_t * mp)
14686 {
14687   vat_main_t *vam = &vat_main;
14688
14689   fformat (vam->ofp, "collector_address %U, collector_port %d, "
14690            "src_address %U, fib_index %u, path_mtu %u, "
14691            "template_interval %u\n",
14692            format_ip4_address, mp->collector_address,
14693            ntohs (mp->collector_port),
14694            format_ip4_address, mp->src_address,
14695            ntohl (mp->fib_index),
14696            ntohl (mp->path_mtu), ntohl (mp->template_interval));
14697
14698   vam->retval = 0;
14699   vam->result_ready = 1;
14700 }
14701
14702 static void
14703 vl_api_ipfix_details_t_handler_json (vl_api_ipfix_details_t * mp)
14704 {
14705   vat_main_t *vam = &vat_main;
14706   vat_json_node_t node;
14707   struct in_addr collector_address;
14708   struct in_addr src_address;
14709
14710   vat_json_init_object (&node);
14711   clib_memcpy (&collector_address, &mp->collector_address,
14712                sizeof (collector_address));
14713   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
14714   vat_json_object_add_uint (&node, "collector_port",
14715                             ntohs (mp->collector_port));
14716   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
14717   vat_json_object_add_ip4 (&node, "src_address", src_address);
14718   vat_json_object_add_uint (&node, "fib_index", ntohl (mp->fib_index));
14719   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
14720   vat_json_object_add_uint (&node, "template_interval",
14721                             ntohl (mp->template_interval));
14722
14723   vat_json_print (vam->ofp, &node);
14724   vat_json_free (&node);
14725   vam->retval = 0;
14726   vam->result_ready = 1;
14727 }
14728
14729 int
14730 api_ipfix_dump (vat_main_t * vam)
14731 {
14732   vl_api_ipfix_dump_t *mp;
14733   f64 timeout;
14734
14735   /* Construct the API message */
14736   M (IPFIX_DUMP, ipfix_dump);
14737   mp->context = 0;
14738
14739   S;
14740   W;
14741   /* NOTREACHED */
14742   return 0;
14743 }
14744
14745 int
14746 api_pg_create_interface (vat_main_t * vam)
14747 {
14748   unformat_input_t *input = vam->input;
14749   vl_api_pg_create_interface_t *mp;
14750   f64 timeout;
14751
14752   u32 if_id = ~0;
14753   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14754     {
14755       if (unformat (input, "if_id %d", &if_id))
14756         ;
14757       else
14758         break;
14759     }
14760   if (if_id == ~0)
14761     {
14762       errmsg ("missing pg interface index\n");
14763       return -99;
14764     }
14765
14766   /* Construct the API message */
14767   M (PG_CREATE_INTERFACE, pg_create_interface);
14768   mp->context = 0;
14769   mp->interface_id = ntohl (if_id);
14770
14771   S;
14772   W;
14773   /* NOTREACHED */
14774   return 0;
14775 }
14776
14777 int
14778 api_pg_capture (vat_main_t * vam)
14779 {
14780   unformat_input_t *input = vam->input;
14781   vl_api_pg_capture_t *mp;
14782   f64 timeout;
14783
14784   u32 if_id = ~0;
14785   u8 enable = 1;
14786   u32 count = 1;
14787   u8 pcap_file_set = 0;
14788   u8 *pcap_file = 0;
14789   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14790     {
14791       if (unformat (input, "if_id %d", &if_id))
14792         ;
14793       else if (unformat (input, "pcap %s", &pcap_file))
14794         pcap_file_set = 1;
14795       else if (unformat (input, "count %d", &count))
14796         ;
14797       else if (unformat (input, "disable"))
14798         enable = 0;
14799       else
14800         break;
14801     }
14802   if (if_id == ~0)
14803     {
14804       errmsg ("missing pg interface index\n");
14805       return -99;
14806     }
14807   if (pcap_file_set > 0)
14808     {
14809       if (vec_len (pcap_file) > 255)
14810         {
14811           errmsg ("pcap file name is too long\n");
14812           return -99;
14813         }
14814     }
14815
14816   u32 name_len = vec_len (pcap_file);
14817   /* Construct the API message */
14818   M (PG_CAPTURE, pg_capture);
14819   mp->context = 0;
14820   mp->interface_id = ntohl (if_id);
14821   mp->is_enabled = enable;
14822   mp->count = ntohl (count);
14823   mp->pcap_name_length = ntohl (name_len);
14824   if (pcap_file_set != 0)
14825     {
14826       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
14827     }
14828   vec_free (pcap_file);
14829
14830   S;
14831   W;
14832   /* NOTREACHED */
14833   return 0;
14834 }
14835
14836 int
14837 api_pg_enable_disable (vat_main_t * vam)
14838 {
14839   unformat_input_t *input = vam->input;
14840   vl_api_pg_enable_disable_t *mp;
14841   f64 timeout;
14842
14843   u8 enable = 1;
14844   u8 stream_name_set = 0;
14845   u8 *stream_name = 0;
14846   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14847     {
14848       if (unformat (input, "stream %s", &stream_name))
14849         stream_name_set = 1;
14850       else if (unformat (input, "disable"))
14851         enable = 0;
14852       else
14853         break;
14854     }
14855
14856   if (stream_name_set > 0)
14857     {
14858       if (vec_len (stream_name) > 255)
14859         {
14860           errmsg ("stream name too long\n");
14861           return -99;
14862         }
14863     }
14864
14865   u32 name_len = vec_len (stream_name);
14866   /* Construct the API message */
14867   M (PG_ENABLE_DISABLE, pg_enable_disable);
14868   mp->context = 0;
14869   mp->is_enabled = enable;
14870   if (stream_name_set != 0)
14871     {
14872       mp->stream_name_length = ntohl (name_len);
14873       clib_memcpy (mp->stream_name, stream_name, name_len);
14874     }
14875   vec_free (stream_name);
14876
14877   S;
14878   W;
14879   /* NOTREACHED */
14880   return 0;
14881 }
14882
14883 int
14884 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
14885 {
14886   unformat_input_t *input = vam->input;
14887   vl_api_ip_source_and_port_range_check_add_del_t *mp;
14888   f64 timeout;
14889
14890   u16 *low_ports = 0;
14891   u16 *high_ports = 0;
14892   u16 this_low;
14893   u16 this_hi;
14894   ip4_address_t ip4_addr;
14895   ip6_address_t ip6_addr;
14896   u32 length;
14897   u32 tmp, tmp2;
14898   u8 prefix_set = 0;
14899   u32 vrf_id = ~0;
14900   u8 is_add = 1;
14901   u8 is_ipv6 = 0;
14902
14903   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14904     {
14905       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
14906         {
14907           prefix_set = 1;
14908         }
14909       else
14910         if (unformat
14911             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
14912         {
14913           prefix_set = 1;
14914           is_ipv6 = 1;
14915         }
14916       else if (unformat (input, "vrf %d", &vrf_id))
14917         ;
14918       else if (unformat (input, "del"))
14919         is_add = 0;
14920       else if (unformat (input, "port %d", &tmp))
14921         {
14922           if (tmp == 0 || tmp > 65535)
14923             {
14924               errmsg ("port %d out of range", tmp);
14925               return -99;
14926             }
14927           this_low = tmp;
14928           this_hi = this_low + 1;
14929           vec_add1 (low_ports, this_low);
14930           vec_add1 (high_ports, this_hi);
14931         }
14932       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
14933         {
14934           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
14935             {
14936               errmsg ("incorrect range parameters\n");
14937               return -99;
14938             }
14939           this_low = tmp;
14940           /* Note: in debug CLI +1 is added to high before
14941              passing to real fn that does "the work"
14942              (ip_source_and_port_range_check_add_del).
14943              This fn is a wrapper around the binary API fn a
14944              control plane will call, which expects this increment
14945              to have occurred. Hence letting the binary API control
14946              plane fn do the increment for consistency between VAT
14947              and other control planes.
14948            */
14949           this_hi = tmp2;
14950           vec_add1 (low_ports, this_low);
14951           vec_add1 (high_ports, this_hi);
14952         }
14953       else
14954         break;
14955     }
14956
14957   if (prefix_set == 0)
14958     {
14959       errmsg ("<address>/<mask> not specified\n");
14960       return -99;
14961     }
14962
14963   if (vrf_id == ~0)
14964     {
14965       errmsg ("VRF ID required, not specified\n");
14966       return -99;
14967     }
14968
14969   if (vrf_id == 0)
14970     {
14971       errmsg
14972         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
14973       return -99;
14974     }
14975
14976   if (vec_len (low_ports) == 0)
14977     {
14978       errmsg ("At least one port or port range required\n");
14979       return -99;
14980     }
14981
14982   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
14983      ip_source_and_port_range_check_add_del);
14984
14985   mp->is_add = is_add;
14986
14987   if (is_ipv6)
14988     {
14989       mp->is_ipv6 = 1;
14990       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
14991     }
14992   else
14993     {
14994       mp->is_ipv6 = 0;
14995       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
14996     }
14997
14998   mp->mask_length = length;
14999   mp->number_of_ranges = vec_len (low_ports);
15000
15001   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15002   vec_free (low_ports);
15003
15004   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15005   vec_free (high_ports);
15006
15007   mp->vrf_id = ntohl (vrf_id);
15008
15009   S;
15010   W;
15011   /* NOTREACHED */
15012   return 0;
15013 }
15014
15015 int
15016 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15017 {
15018   unformat_input_t *input = vam->input;
15019   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15020   f64 timeout;
15021   u32 sw_if_index = ~0;
15022   int vrf_set = 0;
15023   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15024   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15025   u8 is_add = 1;
15026
15027   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15028     {
15029       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15030         ;
15031       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15032         ;
15033       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15034         vrf_set = 1;
15035       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15036         vrf_set = 1;
15037       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15038         vrf_set = 1;
15039       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15040         vrf_set = 1;
15041       else if (unformat (input, "del"))
15042         is_add = 0;
15043       else
15044         break;
15045     }
15046
15047   if (sw_if_index == ~0)
15048     {
15049       errmsg ("Interface required but not specified\n");
15050       return -99;
15051     }
15052
15053   if (vrf_set == 0)
15054     {
15055       errmsg ("VRF ID required but not specified\n");
15056       return -99;
15057     }
15058
15059   if (tcp_out_vrf_id == 0
15060       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15061     {
15062       errmsg
15063         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15064       return -99;
15065     }
15066
15067   /* Construct the API message */
15068   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15069      ip_source_and_port_range_check_interface_add_del);
15070
15071   mp->sw_if_index = ntohl (sw_if_index);
15072   mp->is_add = is_add;
15073   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15074   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15075   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15076   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15077
15078   /* send it... */
15079   S;
15080
15081   /* Wait for a reply... */
15082   W;
15083 }
15084
15085 static int
15086 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15087 {
15088   unformat_input_t *i = vam->input;
15089   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15090   f64 timeout;
15091   u32 local_sa_id = 0;
15092   u32 remote_sa_id = 0;
15093   ip4_address_t src_address;
15094   ip4_address_t dst_address;
15095   u8 is_add = 1;
15096
15097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15098     {
15099       if (unformat (i, "local_sa %d", &local_sa_id))
15100         ;
15101       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15102         ;
15103       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15104         ;
15105       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15106         ;
15107       else if (unformat (i, "del"))
15108         is_add = 0;
15109       else
15110         {
15111           clib_warning ("parse error '%U'", format_unformat_error, i);
15112           return -99;
15113         }
15114     }
15115
15116   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15117
15118   mp->local_sa_id = ntohl (local_sa_id);
15119   mp->remote_sa_id = ntohl (remote_sa_id);
15120   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15121   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15122   mp->is_add = is_add;
15123
15124   S;
15125   W;
15126   /* NOTREACHED */
15127   return 0;
15128 }
15129
15130 static void vl_api_ipsec_gre_tunnel_details_t_handler
15131   (vl_api_ipsec_gre_tunnel_details_t * mp)
15132 {
15133   vat_main_t *vam = &vat_main;
15134
15135   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15136            ntohl (mp->sw_if_index),
15137            format_ip4_address, &mp->src_address,
15138            format_ip4_address, &mp->dst_address,
15139            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15140 }
15141
15142 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15143   (vl_api_ipsec_gre_tunnel_details_t * mp)
15144 {
15145   vat_main_t *vam = &vat_main;
15146   vat_json_node_t *node = NULL;
15147   struct in_addr ip4;
15148
15149   if (VAT_JSON_ARRAY != vam->json_tree.type)
15150     {
15151       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15152       vat_json_init_array (&vam->json_tree);
15153     }
15154   node = vat_json_array_add (&vam->json_tree);
15155
15156   vat_json_init_object (node);
15157   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15158   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15159   vat_json_object_add_ip4 (node, "src_address", ip4);
15160   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15161   vat_json_object_add_ip4 (node, "dst_address", ip4);
15162   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15163   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15164 }
15165
15166 static int
15167 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15168 {
15169   unformat_input_t *i = vam->input;
15170   vl_api_ipsec_gre_tunnel_dump_t *mp;
15171   f64 timeout;
15172   u32 sw_if_index;
15173   u8 sw_if_index_set = 0;
15174
15175   /* Parse args required to build the message */
15176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15177     {
15178       if (unformat (i, "sw_if_index %d", &sw_if_index))
15179         sw_if_index_set = 1;
15180       else
15181         break;
15182     }
15183
15184   if (sw_if_index_set == 0)
15185     {
15186       sw_if_index = ~0;
15187     }
15188
15189   if (!vam->json_output)
15190     {
15191       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15192                "sw_if_index", "src_address", "dst_address",
15193                "local_sa_id", "remote_sa_id");
15194     }
15195
15196   /* Get list of gre-tunnel interfaces */
15197   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15198
15199   mp->sw_if_index = htonl (sw_if_index);
15200
15201   S;
15202
15203   /* Use a control ping for synchronization */
15204   {
15205     vl_api_control_ping_t *mp;
15206     M (CONTROL_PING, control_ping);
15207     S;
15208   }
15209   W;
15210 }
15211
15212 static int
15213 q_or_quit (vat_main_t * vam)
15214 {
15215   longjmp (vam->jump_buf, 1);
15216   return 0;                     /* not so much */
15217 }
15218
15219 static int
15220 q (vat_main_t * vam)
15221 {
15222   return q_or_quit (vam);
15223 }
15224
15225 static int
15226 quit (vat_main_t * vam)
15227 {
15228   return q_or_quit (vam);
15229 }
15230
15231 static int
15232 comment (vat_main_t * vam)
15233 {
15234   return 0;
15235 }
15236
15237 static int
15238 cmd_cmp (void *a1, void *a2)
15239 {
15240   u8 **c1 = a1;
15241   u8 **c2 = a2;
15242
15243   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
15244 }
15245
15246 static int
15247 help (vat_main_t * vam)
15248 {
15249   u8 **cmds = 0;
15250   u8 *name = 0;
15251   hash_pair_t *p;
15252   unformat_input_t *i = vam->input;
15253   int j;
15254
15255   if (unformat (i, "%s", &name))
15256     {
15257       uword *hs;
15258
15259       vec_add1 (name, 0);
15260
15261       hs = hash_get_mem (vam->help_by_name, name);
15262       if (hs)
15263         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
15264       else
15265         fformat (vam->ofp, "No such msg / command '%s'\n", name);
15266       vec_free (name);
15267       return 0;
15268     }
15269
15270   fformat (vam->ofp, "Help is available for the following:\n");
15271
15272     /* *INDENT-OFF* */
15273     hash_foreach_pair (p, vam->function_by_name,
15274     ({
15275       vec_add1 (cmds, (u8 *)(p->key));
15276     }));
15277     /* *INDENT-ON* */
15278
15279   vec_sort_with_function (cmds, cmd_cmp);
15280
15281   for (j = 0; j < vec_len (cmds); j++)
15282     fformat (vam->ofp, "%s\n", cmds[j]);
15283
15284   vec_free (cmds);
15285   return 0;
15286 }
15287
15288 static int
15289 set (vat_main_t * vam)
15290 {
15291   u8 *name = 0, *value = 0;
15292   unformat_input_t *i = vam->input;
15293
15294   if (unformat (i, "%s", &name))
15295     {
15296       /* The input buffer is a vector, not a string. */
15297       value = vec_dup (i->buffer);
15298       vec_delete (value, i->index, 0);
15299       /* Almost certainly has a trailing newline */
15300       if (value[vec_len (value) - 1] == '\n')
15301         value[vec_len (value) - 1] = 0;
15302       /* Make sure it's a proper string, one way or the other */
15303       vec_add1 (value, 0);
15304       (void) clib_macro_set_value (&vam->macro_main,
15305                                    (char *) name, (char *) value);
15306     }
15307   else
15308     errmsg ("usage: set <name> <value>\n");
15309
15310   vec_free (name);
15311   vec_free (value);
15312   return 0;
15313 }
15314
15315 static int
15316 unset (vat_main_t * vam)
15317 {
15318   u8 *name = 0;
15319
15320   if (unformat (vam->input, "%s", &name))
15321     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
15322       errmsg ("unset: %s wasn't set\n", name);
15323   vec_free (name);
15324   return 0;
15325 }
15326
15327 typedef struct
15328 {
15329   u8 *name;
15330   u8 *value;
15331 } macro_sort_t;
15332
15333
15334 static int
15335 macro_sort_cmp (void *a1, void *a2)
15336 {
15337   macro_sort_t *s1 = a1;
15338   macro_sort_t *s2 = a2;
15339
15340   return strcmp ((char *) (s1->name), (char *) (s2->name));
15341 }
15342
15343 static int
15344 dump_macro_table (vat_main_t * vam)
15345 {
15346   macro_sort_t *sort_me = 0, *sm;
15347   int i;
15348   hash_pair_t *p;
15349
15350     /* *INDENT-OFF* */
15351     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
15352     ({
15353       vec_add2 (sort_me, sm, 1);
15354       sm->name = (u8 *)(p->key);
15355       sm->value = (u8 *) (p->value[0]);
15356     }));
15357     /* *INDENT-ON* */
15358
15359   vec_sort_with_function (sort_me, macro_sort_cmp);
15360
15361   if (vec_len (sort_me))
15362     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
15363   else
15364     fformat (vam->ofp, "The macro table is empty...\n");
15365
15366   for (i = 0; i < vec_len (sort_me); i++)
15367     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
15368   return 0;
15369 }
15370
15371 static int
15372 dump_node_table (vat_main_t * vam)
15373 {
15374   int i, j;
15375   vlib_node_t *node, *next_node;
15376
15377   if (vec_len (vam->graph_nodes) == 0)
15378     {
15379       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15380       return 0;
15381     }
15382
15383   for (i = 0; i < vec_len (vam->graph_nodes); i++)
15384     {
15385       node = vam->graph_nodes[i];
15386       fformat (vam->ofp, "[%d] %s\n", i, node->name);
15387       for (j = 0; j < vec_len (node->next_nodes); j++)
15388         {
15389           if (node->next_nodes[j] != ~0)
15390             {
15391               next_node = vam->graph_nodes[node->next_nodes[j]];
15392               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15393             }
15394         }
15395     }
15396   return 0;
15397 }
15398
15399 static int
15400 search_node_table (vat_main_t * vam)
15401 {
15402   unformat_input_t *line_input = vam->input;
15403   u8 *node_to_find;
15404   int j;
15405   vlib_node_t *node, *next_node;
15406   uword *p;
15407
15408   if (vam->graph_node_index_by_name == 0)
15409     {
15410       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
15411       return 0;
15412     }
15413
15414   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
15415     {
15416       if (unformat (line_input, "%s", &node_to_find))
15417         {
15418           vec_add1 (node_to_find, 0);
15419           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
15420           if (p == 0)
15421             {
15422               fformat (vam->ofp, "%s not found...\n", node_to_find);
15423               goto out;
15424             }
15425           node = vam->graph_nodes[p[0]];
15426           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
15427           for (j = 0; j < vec_len (node->next_nodes); j++)
15428             {
15429               if (node->next_nodes[j] != ~0)
15430                 {
15431                   next_node = vam->graph_nodes[node->next_nodes[j]];
15432                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
15433                 }
15434             }
15435         }
15436
15437       else
15438         {
15439           clib_warning ("parse error '%U'", format_unformat_error,
15440                         line_input);
15441           return -99;
15442         }
15443
15444     out:
15445       vec_free (node_to_find);
15446
15447     }
15448
15449   return 0;
15450 }
15451
15452
15453 static int
15454 script (vat_main_t * vam)
15455 {
15456   u8 *s = 0;
15457   char *save_current_file;
15458   unformat_input_t save_input;
15459   jmp_buf save_jump_buf;
15460   u32 save_line_number;
15461
15462   FILE *new_fp, *save_ifp;
15463
15464   if (unformat (vam->input, "%s", &s))
15465     {
15466       new_fp = fopen ((char *) s, "r");
15467       if (new_fp == 0)
15468         {
15469           errmsg ("Couldn't open script file %s\n", s);
15470           vec_free (s);
15471           return -99;
15472         }
15473     }
15474   else
15475     {
15476       errmsg ("Missing script name\n");
15477       return -99;
15478     }
15479
15480   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
15481   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
15482   save_ifp = vam->ifp;
15483   save_line_number = vam->input_line_number;
15484   save_current_file = (char *) vam->current_file;
15485
15486   vam->input_line_number = 0;
15487   vam->ifp = new_fp;
15488   vam->current_file = s;
15489   do_one_file (vam);
15490
15491   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
15492   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
15493   vam->ifp = save_ifp;
15494   vam->input_line_number = save_line_number;
15495   vam->current_file = (u8 *) save_current_file;
15496   vec_free (s);
15497
15498   return 0;
15499 }
15500
15501 static int
15502 echo (vat_main_t * vam)
15503 {
15504   fformat (vam->ofp, "%v", vam->input->buffer);
15505   return 0;
15506 }
15507
15508 /* List of API message constructors, CLI names map to api_xxx */
15509 #define foreach_vpe_api_msg                                             \
15510 _(create_loopback,"[mac <mac-addr>]")                                   \
15511 _(sw_interface_dump,"")                                                 \
15512 _(sw_interface_set_flags,                                               \
15513   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
15514 _(sw_interface_add_del_address,                                         \
15515   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
15516 _(sw_interface_set_table,                                               \
15517   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
15518 _(sw_interface_set_vpath,                                               \
15519   "<intfc> | sw_if_index <id> enable | disable")                        \
15520 _(sw_interface_set_l2_xconnect,                                         \
15521   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15522   "enable | disable")                                                   \
15523 _(sw_interface_set_l2_bridge,                                           \
15524   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
15525   "[shg <split-horizon-group>] [bvi]\n"                                 \
15526   "enable | disable")                                                   \
15527 _(bridge_domain_add_del,                                                \
15528   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
15529 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
15530 _(l2fib_add_del,                                                        \
15531   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
15532 _(l2_flags,                                                             \
15533   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
15534 _(bridge_flags,                                                         \
15535   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
15536 _(tap_connect,                                                          \
15537   "tapname <name> mac <mac-addr> | random-mac")                         \
15538 _(tap_modify,                                                           \
15539   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
15540 _(tap_delete,                                                           \
15541   "<vpp-if-name> | sw_if_index <id>")                                   \
15542 _(sw_interface_tap_dump, "")                                            \
15543 _(ip_add_del_route,                                                     \
15544   "<addr>/<mask> via <addr> [vrf <n>]\n"                                \
15545   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
15546   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
15547   "[multipath] [count <n>]")                                            \
15548 _(proxy_arp_add_del,                                                    \
15549   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
15550 _(proxy_arp_intfc_enable_disable,                                       \
15551   "<intfc> | sw_if_index <id> enable | disable")                        \
15552 _(mpls_add_del_encap,                                                   \
15553   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
15554 _(mpls_add_del_decap,                                                   \
15555   "label <n> [rx_vrf_id <n>] [tx_vrf_id] [s-bit-clear][del]")           \
15556 _(mpls_gre_add_del_tunnel,                                              \
15557   "inner_vrf_id <n> outer_vrf_id <n> src <ip4-address> dst <ip4-address>\n" \
15558   "adj <ip4-address>/<mask-width> [del]")                               \
15559 _(sw_interface_set_unnumbered,                                          \
15560   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
15561 _(ip_neighbor_add_del,                                                  \
15562   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
15563   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
15564 _(reset_vrf, "vrf <id> [ipv6]")                                         \
15565 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
15566 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
15567   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
15568   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
15569   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
15570 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
15571 _(reset_fib, "vrf <n> [ipv6]")                                          \
15572 _(dhcp_proxy_config,                                                    \
15573   "svr <v46-address> src <v46-address>\n"                               \
15574    "insert-cid <n> [del]")                                              \
15575 _(dhcp_proxy_config_2,                                                  \
15576   "svr <v46-address> src <v46-address>\n"                               \
15577    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
15578 _(dhcp_proxy_set_vss,                                                   \
15579   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
15580 _(dhcp_client_config,                                                   \
15581   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
15582 _(set_ip_flow_hash,                                                     \
15583   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
15584 _(sw_interface_ip6_enable_disable,                                      \
15585   "<intfc> | sw_if_index <id> enable | disable")                        \
15586 _(sw_interface_ip6_set_link_local_address,                              \
15587   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
15588 _(sw_interface_ip6nd_ra_prefix,                                         \
15589   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
15590   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
15591   "[nolink] [isno]")                                                    \
15592 _(sw_interface_ip6nd_ra_config,                                         \
15593   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
15594   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
15595   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
15596 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
15597 _(l2_patch_add_del,                                                     \
15598   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
15599   "enable | disable")                                                   \
15600 _(mpls_ethernet_add_del_tunnel,                                         \
15601   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
15602   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
15603 _(mpls_ethernet_add_del_tunnel_2,                                       \
15604   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
15605   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
15606 _(sr_tunnel_add_del,                                                    \
15607   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
15608   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
15609   "[policy <policy_name>]")                                             \
15610 _(sr_policy_add_del,                                                    \
15611   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
15612 _(sr_multicast_map_add_del,                                             \
15613   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
15614 _(classify_add_del_table,                                               \
15615   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15616   "[del] mask <mask-value>\n"                                           \
15617   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
15618 _(classify_add_del_session,                                             \
15619   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15620   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15621   "  [l3 [ip4|ip6]]")                                                   \
15622 _(classify_set_interface_ip_table,                                      \
15623   "<intfc> | sw_if_index <nn> table <nn>")                              \
15624 _(classify_set_interface_l2_tables,                                     \
15625   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15626   "  [other-table <nn>]")                                               \
15627 _(get_node_index, "node <node-name")                                    \
15628 _(add_node_next, "node <node-name> next <next-node-name>")              \
15629 _(l2tpv3_create_tunnel,                                                 \
15630   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
15631   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
15632   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
15633 _(l2tpv3_set_tunnel_cookies,                                            \
15634   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
15635   "[new_remote_cookie <nn>]\n")                                         \
15636 _(l2tpv3_interface_enable_disable,                                      \
15637   "<intfc> | sw_if_index <nn> enable | disable")                        \
15638 _(l2tpv3_set_lookup_key,                                                \
15639   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
15640 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
15641 _(vxlan_add_del_tunnel,                                                 \
15642   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
15643   " [decap-next l2|ip4|ip6] [del]")                                     \
15644 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15645 _(gre_add_del_tunnel,                                                   \
15646   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [del]\n")          \
15647 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
15648 _(l2_fib_clear_table, "")                                               \
15649 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15650 _(l2_interface_vlan_tag_rewrite,                                        \
15651   "<intfc> | sw_if_index <nn> \n"                                       \
15652   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15653   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15654 _(create_vhost_user_if,                                                 \
15655         "socket <filename> [server] [renumber <dev_instance>] "         \
15656         "[mac <mac_address>]")                                          \
15657 _(modify_vhost_user_if,                                                 \
15658         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15659         "[server] [renumber <dev_instance>]")                           \
15660 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15661 _(sw_interface_vhost_user_dump, "")                                     \
15662 _(show_version, "")                                                     \
15663 _(vxlan_gpe_add_del_tunnel,                                             \
15664   "local <addr> remote <addr> vni <nn>\n"                               \
15665     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
15666   "[next-ethernet] [next-nsh]\n")                                       \
15667 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15668 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15669 _(interface_name_renumber,                                              \
15670   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15671 _(input_acl_set_interface,                                              \
15672   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15673   "  [l2-table <nn>] [del]")                                            \
15674 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
15675 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15676 _(ip_dump, "ipv4 | ipv6")                                               \
15677 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15678 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15679   "  spid_id <n> ")                                                     \
15680 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15681   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15682   "  integ_alg <alg> integ_key <hex>")                                  \
15683 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
15684   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15685   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15686   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
15687 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
15688 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
15689 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
15690   "(auth_data 0x<data> | auth_data <data>)")                            \
15691 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
15692   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
15693 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
15694   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
15695   "(local|remote)")                                                     \
15696 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
15697 _(delete_loopback,"sw_if_index <nn>")                                   \
15698 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15699 _(map_add_domain,                                                       \
15700   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
15701   "ip6-src <ip6addr> "                                                  \
15702   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
15703 _(map_del_domain, "index <n>")                                          \
15704 _(map_add_del_rule,                                                     \
15705   "index <n> psid <n> dst <ip6addr> [del]")                             \
15706 _(map_domain_dump, "")                                                  \
15707 _(map_rule_dump, "index <map-domain>")                                  \
15708 _(want_interface_events,  "enable|disable")                             \
15709 _(want_stats,"enable|disable")                                          \
15710 _(get_first_msg_id, "client <name>")                                    \
15711 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15712 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15713   "fib-id <nn> [ip4][ip6][default]")                                    \
15714 _(get_node_graph, " ")                                                  \
15715 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15716 _(trace_profile_add, "id <nn> trace-type <0x1f|0x3|0x9|0x11|0x19> "     \
15717   "trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> "       \
15718   "app-data <app_data in hex> [pow] [ppc <encap|decap>]")               \
15719 _(trace_profile_apply, "id <nn> <ip6-address>/<width>"                  \
15720   " vrf_id <nn>  add | pop | none")                                     \
15721 _(trace_profile_del, "")                                                \
15722 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
15723                             " sw_if_index <sw_if_index> p <priority> "  \
15724                             "w <weight>] [del]")                        \
15725 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
15726                         "iface <intf> | sw_if_index <sw_if_index> "     \
15727                         "p <priority> w <weight> [del]")                \
15728 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
15729                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
15730                           "locator-set <locator_name> [del]")           \
15731 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
15732   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
15733 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
15734 _(lisp_gpe_enable_disable, "enable|disable")                            \
15735 _(lisp_enable_disable, "enable|disable")                                \
15736 _(lisp_gpe_add_del_iface, "up|down")                                    \
15737 _(lisp_add_del_remote_mapping, "add|del vni <vni> deid <dest-eid> "     \
15738                                "rloc <locator> p <prio> "               \
15739                                "w <weight> [rloc <loc> ... ] "          \
15740                                "action <action> [del-all]")             \
15741 _(lisp_add_del_adjacency, "add|del vni <vni> deid <dest-eid> seid "     \
15742                           "<src-eid> rloc <locator> p <prio> w <weight>"\
15743                           "[rloc <loc> ... ] action <action>")          \
15744 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
15745 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
15746 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
15747 _(lisp_locator_set_dump, "[locator-set-index <ls-index> | "             \
15748                          "locator-set <loc-set-name>] [local | remote]")\
15749 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
15750                        "[local] | [remote]")                            \
15751 _(lisp_eid_table_vni_dump, "")                                          \
15752 _(lisp_eid_table_map_dump, "l2|l3")                                     \
15753 _(lisp_gpe_tunnel_dump, "")                                             \
15754 _(lisp_map_resolver_dump, "")                                           \
15755 _(show_lisp_status, "")                                                 \
15756 _(lisp_get_map_request_itr_rlocs, "")                                   \
15757 _(show_lisp_pitr, "")                                                   \
15758 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15759 _(af_packet_delete, "name <host interface name>")                       \
15760 _(policer_add_del, "name <policer name> <params> [del]")                \
15761 _(policer_dump, "[name <policer name>]")                                \
15762 _(policer_classify_set_interface,                                       \
15763   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15764   "  [l2-table <nn>] [del]")                                            \
15765 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15766 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
15767     "[master|slave]")                                                   \
15768 _(netmap_delete, "name <interface name>")                               \
15769 _(mpls_gre_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15770 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
15771 _(mpls_fib_encap_dump, "")                                              \
15772 _(mpls_fib_decap_dump, "")                                              \
15773 _(classify_table_ids, "")                                               \
15774 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15775 _(classify_table_info, "table_id <nn>")                                 \
15776 _(classify_session_dump, "table_id <nn>")                               \
15777 _(ipfix_enable, "collector_address <ip4> [collector_port <nn>] "        \
15778                 "src_address <ip4> [fib_id <nn>] [path_mtu <nn>] "      \
15779                 "[template_interval <nn>]")                             \
15780 _(ipfix_dump, "")                                                       \
15781 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15782 _(pg_create_interface, "if_id <nn>")                                    \
15783 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15784 _(pg_enable_disable, "[stream <id>] disable")                           \
15785 _(ip_source_and_port_range_check_add_del,                               \
15786   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15787 _(ip_source_and_port_range_check_interface_add_del,                     \
15788   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15789   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15790 _(ipsec_gre_add_del_tunnel,                                             \
15791   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
15792 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")
15793
15794 /* List of command functions, CLI names map directly to functions */
15795 #define foreach_cli_function                                    \
15796 _(comment, "usage: comment <ignore-rest-of-line>")              \
15797 _(dump_interface_table, "usage: dump_interface_table")          \
15798 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15799 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15800 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15801 _(dump_stats_table, "usage: dump_stats_table")                  \
15802 _(dump_macro_table, "usage: dump_macro_table ")                 \
15803 _(dump_node_table, "usage: dump_node_table")                    \
15804 _(echo, "usage: echo <message>")                                \
15805 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15806 _(help, "usage: help")                                          \
15807 _(q, "usage: quit")                                             \
15808 _(quit, "usage: quit")                                          \
15809 _(search_node_table, "usage: search_node_table <name>...")      \
15810 _(set, "usage: set <variable-name> <value>")                    \
15811 _(script, "usage: script <file-name>")                          \
15812 _(unset, "usage: unset <variable-name>")
15813
15814 #define _(N,n)                                  \
15815     static void vl_api_##n##_t_handler_uni      \
15816     (vl_api_##n##_t * mp)                       \
15817     {                                           \
15818         vat_main_t * vam = &vat_main;           \
15819         if (vam->json_output) {                 \
15820             vl_api_##n##_t_handler_json(mp);    \
15821         } else {                                \
15822             vl_api_##n##_t_handler(mp);         \
15823         }                                       \
15824     }
15825 foreach_vpe_api_reply_msg;
15826 #undef _
15827
15828 void
15829 vat_api_hookup (vat_main_t * vam)
15830 {
15831 #define _(N,n)                                                  \
15832     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15833                            vl_api_##n##_t_handler_uni,          \
15834                            vl_noop_handler,                     \
15835                            vl_api_##n##_t_endian,               \
15836                            vl_api_##n##_t_print,                \
15837                            sizeof(vl_api_##n##_t), 1);
15838   foreach_vpe_api_reply_msg;
15839 #undef _
15840
15841   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
15842
15843   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15844
15845   vam->function_by_name = hash_create_string (0, sizeof (uword));
15846
15847   vam->help_by_name = hash_create_string (0, sizeof (uword));
15848
15849   /* API messages we can send */
15850 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15851   foreach_vpe_api_msg;
15852 #undef _
15853
15854   /* Help strings */
15855 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15856   foreach_vpe_api_msg;
15857 #undef _
15858
15859   /* CLI functions */
15860 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15861   foreach_cli_function;
15862 #undef _
15863
15864   /* Help strings */
15865 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15866   foreach_cli_function;
15867 #undef _
15868 }
15869
15870 #undef vl_api_version
15871 #define vl_api_version(n,v) static u32 vpe_api_version = v;
15872 #include <vpp-api/vpe.api.h>
15873 #undef vl_api_version
15874
15875 void
15876 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
15877 {
15878   /*
15879    * Send the main API signature in slot 0. This bit of code must
15880    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
15881    */
15882   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
15883 }
15884
15885 /*
15886  * fd.io coding-style-patch-verification: ON
15887  *
15888  * Local Variables:
15889  * eval: (c-set-style "gnu")
15890  * End:
15891  */