[re]Enable per-Adjacency/neighbour counters
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 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/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
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 #include <vlibapi/vat_helper_macros.h>
74
75 f64
76 vat_time_now (vat_main_t * vam)
77 {
78 #if VPP_API_TEST_BUILTIN
79   return vlib_time_now (vam->vlib_main);
80 #else
81   return clib_time_now (&vam->clib_time);
82 #endif
83 }
84
85 void
86 errmsg (char *fmt, ...)
87 {
88   vat_main_t *vam = &vat_main;
89   va_list va;
90   u8 *s;
91
92   va_start (va, fmt);
93   s = va_format (0, fmt, &va);
94   va_end (va);
95
96   vec_add1 (s, 0);
97
98 #if VPP_API_TEST_BUILTIN
99   vlib_cli_output (vam->vlib_main, (char *) s);
100 #else
101   {
102     if (vam->ifp != stdin)
103       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
104                vam->input_line_number);
105     fformat (vam->ofp, (char *) s);
106     fflush (vam->ofp);
107   }
108 #endif
109
110   vec_free (s);
111 }
112
113 static uword
114 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
115 {
116   vat_main_t *vam = va_arg (*args, vat_main_t *);
117   u32 *result = va_arg (*args, u32 *);
118   u8 *if_name;
119   uword *p;
120
121   if (!unformat (input, "%s", &if_name))
122     return 0;
123
124   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
125   if (p == 0)
126     return 0;
127   *result = p[0];
128   return 1;
129 }
130
131 #if VPP_API_TEST_BUILTIN == 0
132 /* Parse an IP4 address %d.%d.%d.%d. */
133 uword
134 unformat_ip4_address (unformat_input_t * input, va_list * args)
135 {
136   u8 *result = va_arg (*args, u8 *);
137   unsigned a[4];
138
139   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
140     return 0;
141
142   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
143     return 0;
144
145   result[0] = a[0];
146   result[1] = a[1];
147   result[2] = a[2];
148   result[3] = a[3];
149
150   return 1;
151 }
152
153 uword
154 unformat_ethernet_address (unformat_input_t * input, va_list * args)
155 {
156   u8 *result = va_arg (*args, u8 *);
157   u32 i, a[6];
158
159   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
160                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
161     return 0;
162
163   /* Check range. */
164   for (i = 0; i < 6; i++)
165     if (a[i] >= (1 << 8))
166       return 0;
167
168   for (i = 0; i < 6; i++)
169     result[i] = a[i];
170
171   return 1;
172 }
173
174 /* Returns ethernet type as an int in host byte order. */
175 uword
176 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
177                                         va_list * args)
178 {
179   u16 *result = va_arg (*args, u16 *);
180   int type;
181
182   /* Numeric type. */
183   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
184     {
185       if (type >= (1 << 16))
186         return 0;
187       *result = type;
188       return 1;
189     }
190   return 0;
191 }
192
193 /* Parse an IP6 address. */
194 uword
195 unformat_ip6_address (unformat_input_t * input, va_list * args)
196 {
197   ip6_address_t *result = va_arg (*args, ip6_address_t *);
198   u16 hex_quads[8];
199   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
200   uword c, n_colon, double_colon_index;
201
202   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
203   double_colon_index = ARRAY_LEN (hex_quads);
204   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
205     {
206       hex_digit = 16;
207       if (c >= '0' && c <= '9')
208         hex_digit = c - '0';
209       else if (c >= 'a' && c <= 'f')
210         hex_digit = c + 10 - 'a';
211       else if (c >= 'A' && c <= 'F')
212         hex_digit = c + 10 - 'A';
213       else if (c == ':' && n_colon < 2)
214         n_colon++;
215       else
216         {
217           unformat_put_input (input);
218           break;
219         }
220
221       /* Too many hex quads. */
222       if (n_hex_quads >= ARRAY_LEN (hex_quads))
223         return 0;
224
225       if (hex_digit < 16)
226         {
227           hex_quad = (hex_quad << 4) | hex_digit;
228
229           /* Hex quad must fit in 16 bits. */
230           if (n_hex_digits >= 4)
231             return 0;
232
233           n_colon = 0;
234           n_hex_digits++;
235         }
236
237       /* Save position of :: */
238       if (n_colon == 2)
239         {
240           /* More than one :: ? */
241           if (double_colon_index < ARRAY_LEN (hex_quads))
242             return 0;
243           double_colon_index = n_hex_quads;
244         }
245
246       if (n_colon > 0 && n_hex_digits > 0)
247         {
248           hex_quads[n_hex_quads++] = hex_quad;
249           hex_quad = 0;
250           n_hex_digits = 0;
251         }
252     }
253
254   if (n_hex_digits > 0)
255     hex_quads[n_hex_quads++] = hex_quad;
256
257   {
258     word i;
259
260     /* Expand :: to appropriate number of zero hex quads. */
261     if (double_colon_index < ARRAY_LEN (hex_quads))
262       {
263         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
264
265         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
266           hex_quads[n_zero + i] = hex_quads[i];
267
268         for (i = 0; i < n_zero; i++)
269           hex_quads[double_colon_index + i] = 0;
270
271         n_hex_quads = ARRAY_LEN (hex_quads);
272       }
273
274     /* Too few hex quads given. */
275     if (n_hex_quads < ARRAY_LEN (hex_quads))
276       return 0;
277
278     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
279       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
280
281     return 1;
282   }
283 }
284
285 uword
286 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
287 {
288   u32 *r = va_arg (*args, u32 *);
289
290   if (0);
291 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
292   foreach_ipsec_policy_action
293 #undef _
294     else
295     return 0;
296   return 1;
297 }
298
299 uword
300 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
301 {
302   u32 *r = va_arg (*args, u32 *);
303
304   if (0);
305 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
306   foreach_ipsec_crypto_alg
307 #undef _
308     else
309     return 0;
310   return 1;
311 }
312
313 u8 *
314 format_ipsec_crypto_alg (u8 * s, va_list * args)
315 {
316   u32 i = va_arg (*args, u32);
317   u8 *t = 0;
318
319   switch (i)
320     {
321 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
322       foreach_ipsec_crypto_alg
323 #undef _
324     default:
325       return format (s, "unknown");
326     }
327   return format (s, "%s", t);
328 }
329
330 uword
331 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
332 {
333   u32 *r = va_arg (*args, u32 *);
334
335   if (0);
336 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
337   foreach_ipsec_integ_alg
338 #undef _
339     else
340     return 0;
341   return 1;
342 }
343
344 u8 *
345 format_ipsec_integ_alg (u8 * s, va_list * args)
346 {
347   u32 i = va_arg (*args, u32);
348   u8 *t = 0;
349
350   switch (i)
351     {
352 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
353       foreach_ipsec_integ_alg
354 #undef _
355     default:
356       return format (s, "unknown");
357     }
358   return format (s, "%s", t);
359 }
360
361 uword
362 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
363 {
364   u32 *r = va_arg (*args, u32 *);
365
366   if (0);
367 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
368   foreach_ikev2_auth_method
369 #undef _
370     else
371     return 0;
372   return 1;
373 }
374
375 uword
376 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
377 {
378   u32 *r = va_arg (*args, u32 *);
379
380   if (0);
381 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
382   foreach_ikev2_id_type
383 #undef _
384     else
385     return 0;
386   return 1;
387 }
388 #endif /* VPP_API_TEST_BUILTIN */
389
390 static uword
391 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
392 {
393   u8 *r = va_arg (*args, u8 *);
394
395   if (unformat (input, "kbps"))
396     *r = SSE2_QOS_RATE_KBPS;
397   else if (unformat (input, "pps"))
398     *r = SSE2_QOS_RATE_PPS;
399   else
400     return 0;
401   return 1;
402 }
403
404 static uword
405 unformat_policer_round_type (unformat_input_t * input, va_list * args)
406 {
407   u8 *r = va_arg (*args, u8 *);
408
409   if (unformat (input, "closest"))
410     *r = SSE2_QOS_ROUND_TO_CLOSEST;
411   else if (unformat (input, "up"))
412     *r = SSE2_QOS_ROUND_TO_UP;
413   else if (unformat (input, "down"))
414     *r = SSE2_QOS_ROUND_TO_DOWN;
415   else
416     return 0;
417   return 1;
418 }
419
420 static uword
421 unformat_policer_type (unformat_input_t * input, va_list * args)
422 {
423   u8 *r = va_arg (*args, u8 *);
424
425   if (unformat (input, "1r2c"))
426     *r = SSE2_QOS_POLICER_TYPE_1R2C;
427   else if (unformat (input, "1r3c"))
428     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
429   else if (unformat (input, "2r3c-2698"))
430     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
431   else if (unformat (input, "2r3c-4115"))
432     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
433   else if (unformat (input, "2r3c-mef5cf1"))
434     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
435   else
436     return 0;
437   return 1;
438 }
439
440 static uword
441 unformat_dscp (unformat_input_t * input, va_list * va)
442 {
443   u8 *r = va_arg (*va, u8 *);
444
445   if (0);
446 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
447   foreach_vnet_dscp
448 #undef _
449     else
450     return 0;
451   return 1;
452 }
453
454 static uword
455 unformat_policer_action_type (unformat_input_t * input, va_list * va)
456 {
457   sse2_qos_pol_action_params_st *a
458     = va_arg (*va, sse2_qos_pol_action_params_st *);
459
460   if (unformat (input, "drop"))
461     a->action_type = SSE2_QOS_ACTION_DROP;
462   else if (unformat (input, "transmit"))
463     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
464   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
465     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
466   else
467     return 0;
468   return 1;
469 }
470
471 static uword
472 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
473 {
474   u32 *r = va_arg (*va, u32 *);
475   u32 tid;
476
477   if (unformat (input, "ip4"))
478     tid = POLICER_CLASSIFY_TABLE_IP4;
479   else if (unformat (input, "ip6"))
480     tid = POLICER_CLASSIFY_TABLE_IP6;
481   else if (unformat (input, "l2"))
482     tid = POLICER_CLASSIFY_TABLE_L2;
483   else
484     return 0;
485
486   *r = tid;
487   return 1;
488 }
489
490 static uword
491 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
492 {
493   u32 *r = va_arg (*va, u32 *);
494   u32 tid;
495
496   if (unformat (input, "ip4"))
497     tid = FLOW_CLASSIFY_TABLE_IP4;
498   else if (unformat (input, "ip6"))
499     tid = FLOW_CLASSIFY_TABLE_IP6;
500   else
501     return 0;
502
503   *r = tid;
504   return 1;
505 }
506
507 #if (VPP_API_TEST_BUILTIN==0)
508 u8 *
509 format_ip4_address (u8 * s, va_list * args)
510 {
511   u8 *a = va_arg (*args, u8 *);
512   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
513 }
514
515 u8 *
516 format_ip6_address (u8 * s, va_list * args)
517 {
518   ip6_address_t *a = va_arg (*args, ip6_address_t *);
519   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
520
521   i_max_n_zero = ARRAY_LEN (a->as_u16);
522   max_n_zeros = 0;
523   i_first_zero = i_max_n_zero;
524   n_zeros = 0;
525   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
526     {
527       u32 is_zero = a->as_u16[i] == 0;
528       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
529         {
530           i_first_zero = i;
531           n_zeros = 0;
532         }
533       n_zeros += is_zero;
534       if ((!is_zero && n_zeros > max_n_zeros)
535           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
536         {
537           i_max_n_zero = i_first_zero;
538           max_n_zeros = n_zeros;
539           i_first_zero = ARRAY_LEN (a->as_u16);
540           n_zeros = 0;
541         }
542     }
543
544   last_double_colon = 0;
545   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
546     {
547       if (i == i_max_n_zero && max_n_zeros > 1)
548         {
549           s = format (s, "::");
550           i += max_n_zeros - 1;
551           last_double_colon = 1;
552         }
553       else
554         {
555           s = format (s, "%s%x",
556                       (last_double_colon || i == 0) ? "" : ":",
557                       clib_net_to_host_u16 (a->as_u16[i]));
558           last_double_colon = 0;
559         }
560     }
561
562   return s;
563 }
564
565 /* Format an IP46 address. */
566 u8 *
567 format_ip46_address (u8 * s, va_list * args)
568 {
569   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
570   ip46_type_t type = va_arg (*args, ip46_type_t);
571   int is_ip4 = 1;
572
573   switch (type)
574     {
575     case IP46_TYPE_ANY:
576       is_ip4 = ip46_address_is_ip4 (ip46);
577       break;
578     case IP46_TYPE_IP4:
579       is_ip4 = 1;
580       break;
581     case IP46_TYPE_IP6:
582       is_ip4 = 0;
583       break;
584     }
585
586   return is_ip4 ?
587     format (s, "%U", format_ip4_address, &ip46->ip4) :
588     format (s, "%U", format_ip6_address, &ip46->ip6);
589 }
590
591 u8 *
592 format_ethernet_address (u8 * s, va_list * args)
593 {
594   u8 *a = va_arg (*args, u8 *);
595
596   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
597                  a[0], a[1], a[2], a[3], a[4], a[5]);
598 }
599 #endif
600
601 static void
602 increment_v4_address (ip4_address_t * a)
603 {
604   u32 v;
605
606   v = ntohl (a->as_u32) + 1;
607   a->as_u32 = ntohl (v);
608 }
609
610 static void
611 increment_v6_address (ip6_address_t * a)
612 {
613   u64 v0, v1;
614
615   v0 = clib_net_to_host_u64 (a->as_u64[0]);
616   v1 = clib_net_to_host_u64 (a->as_u64[1]);
617
618   v1 += 1;
619   if (v1 == 0)
620     v0 += 1;
621   a->as_u64[0] = clib_net_to_host_u64 (v0);
622   a->as_u64[1] = clib_net_to_host_u64 (v1);
623 }
624
625 static void
626 increment_mac_address (u64 * mac)
627 {
628   u64 tmp = *mac;
629
630   tmp = clib_net_to_host_u64 (tmp);
631   tmp += 1 << 16;               /* skip unused (least significant) octets */
632   tmp = clib_host_to_net_u64 (tmp);
633   *mac = tmp;
634 }
635
636 static void vl_api_create_loopback_reply_t_handler
637   (vl_api_create_loopback_reply_t * mp)
638 {
639   vat_main_t *vam = &vat_main;
640   i32 retval = ntohl (mp->retval);
641
642   vam->retval = retval;
643   vam->regenerate_interface_table = 1;
644   vam->sw_if_index = ntohl (mp->sw_if_index);
645   vam->result_ready = 1;
646 }
647
648 static void vl_api_create_loopback_reply_t_handler_json
649   (vl_api_create_loopback_reply_t * mp)
650 {
651   vat_main_t *vam = &vat_main;
652   vat_json_node_t node;
653
654   vat_json_init_object (&node);
655   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
656   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
657
658   vat_json_print (vam->ofp, &node);
659   vat_json_free (&node);
660   vam->retval = ntohl (mp->retval);
661   vam->result_ready = 1;
662 }
663
664 static void vl_api_af_packet_create_reply_t_handler
665   (vl_api_af_packet_create_reply_t * mp)
666 {
667   vat_main_t *vam = &vat_main;
668   i32 retval = ntohl (mp->retval);
669
670   vam->retval = retval;
671   vam->regenerate_interface_table = 1;
672   vam->sw_if_index = ntohl (mp->sw_if_index);
673   vam->result_ready = 1;
674 }
675
676 static void vl_api_af_packet_create_reply_t_handler_json
677   (vl_api_af_packet_create_reply_t * mp)
678 {
679   vat_main_t *vam = &vat_main;
680   vat_json_node_t node;
681
682   vat_json_init_object (&node);
683   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
684   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
685
686   vat_json_print (vam->ofp, &node);
687   vat_json_free (&node);
688
689   vam->retval = ntohl (mp->retval);
690   vam->result_ready = 1;
691 }
692
693 static void vl_api_create_vlan_subif_reply_t_handler
694   (vl_api_create_vlan_subif_reply_t * mp)
695 {
696   vat_main_t *vam = &vat_main;
697   i32 retval = ntohl (mp->retval);
698
699   vam->retval = retval;
700   vam->regenerate_interface_table = 1;
701   vam->sw_if_index = ntohl (mp->sw_if_index);
702   vam->result_ready = 1;
703 }
704
705 static void vl_api_create_vlan_subif_reply_t_handler_json
706   (vl_api_create_vlan_subif_reply_t * mp)
707 {
708   vat_main_t *vam = &vat_main;
709   vat_json_node_t node;
710
711   vat_json_init_object (&node);
712   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
713   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
714
715   vat_json_print (vam->ofp, &node);
716   vat_json_free (&node);
717
718   vam->retval = ntohl (mp->retval);
719   vam->result_ready = 1;
720 }
721
722 static void vl_api_create_subif_reply_t_handler
723   (vl_api_create_subif_reply_t * mp)
724 {
725   vat_main_t *vam = &vat_main;
726   i32 retval = ntohl (mp->retval);
727
728   vam->retval = retval;
729   vam->regenerate_interface_table = 1;
730   vam->sw_if_index = ntohl (mp->sw_if_index);
731   vam->result_ready = 1;
732 }
733
734 static void vl_api_create_subif_reply_t_handler_json
735   (vl_api_create_subif_reply_t * mp)
736 {
737   vat_main_t *vam = &vat_main;
738   vat_json_node_t node;
739
740   vat_json_init_object (&node);
741   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
742   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
743
744   vat_json_print (vam->ofp, &node);
745   vat_json_free (&node);
746
747   vam->retval = ntohl (mp->retval);
748   vam->result_ready = 1;
749 }
750
751 static void vl_api_interface_name_renumber_reply_t_handler
752   (vl_api_interface_name_renumber_reply_t * mp)
753 {
754   vat_main_t *vam = &vat_main;
755   i32 retval = ntohl (mp->retval);
756
757   vam->retval = retval;
758   vam->regenerate_interface_table = 1;
759   vam->result_ready = 1;
760 }
761
762 static void vl_api_interface_name_renumber_reply_t_handler_json
763   (vl_api_interface_name_renumber_reply_t * mp)
764 {
765   vat_main_t *vam = &vat_main;
766   vat_json_node_t node;
767
768   vat_json_init_object (&node);
769   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
770
771   vat_json_print (vam->ofp, &node);
772   vat_json_free (&node);
773
774   vam->retval = ntohl (mp->retval);
775   vam->result_ready = 1;
776 }
777
778 /*
779  * Special-case: build the interface table, maintain
780  * the next loopback sw_if_index vbl.
781  */
782 static void vl_api_sw_interface_details_t_handler
783   (vl_api_sw_interface_details_t * mp)
784 {
785   vat_main_t *vam = &vat_main;
786   u8 *s = format (0, "%s%c", mp->interface_name, 0);
787
788   hash_set_mem (vam->sw_if_index_by_interface_name, s,
789                 ntohl (mp->sw_if_index));
790
791   /* In sub interface case, fill the sub interface table entry */
792   if (mp->sw_if_index != mp->sup_sw_if_index)
793     {
794       sw_interface_subif_t *sub = NULL;
795
796       vec_add2 (vam->sw_if_subif_table, sub, 1);
797
798       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
799       strncpy ((char *) sub->interface_name, (char *) s,
800                vec_len (sub->interface_name));
801       sub->sw_if_index = ntohl (mp->sw_if_index);
802       sub->sub_id = ntohl (mp->sub_id);
803
804       sub->sub_dot1ad = mp->sub_dot1ad;
805       sub->sub_number_of_tags = mp->sub_number_of_tags;
806       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
807       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
808       sub->sub_exact_match = mp->sub_exact_match;
809       sub->sub_default = mp->sub_default;
810       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
811       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
812
813       /* vlan tag rewrite */
814       sub->vtr_op = ntohl (mp->vtr_op);
815       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
816       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
817       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
818     }
819 }
820
821 static void vl_api_sw_interface_details_t_handler_json
822   (vl_api_sw_interface_details_t * mp)
823 {
824   vat_main_t *vam = &vat_main;
825   vat_json_node_t *node = NULL;
826
827   if (VAT_JSON_ARRAY != vam->json_tree.type)
828     {
829       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
830       vat_json_init_array (&vam->json_tree);
831     }
832   node = vat_json_array_add (&vam->json_tree);
833
834   vat_json_init_object (node);
835   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
836   vat_json_object_add_uint (node, "sup_sw_if_index",
837                             ntohl (mp->sup_sw_if_index));
838   vat_json_object_add_uint (node, "l2_address_length",
839                             ntohl (mp->l2_address_length));
840   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
841                              sizeof (mp->l2_address));
842   vat_json_object_add_string_copy (node, "interface_name",
843                                    mp->interface_name);
844   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
845   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
846   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
847   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
848   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
849   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
850   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
851   vat_json_object_add_uint (node, "sub_number_of_tags",
852                             mp->sub_number_of_tags);
853   vat_json_object_add_uint (node, "sub_outer_vlan_id",
854                             ntohs (mp->sub_outer_vlan_id));
855   vat_json_object_add_uint (node, "sub_inner_vlan_id",
856                             ntohs (mp->sub_inner_vlan_id));
857   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
858   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
859   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
860                             mp->sub_outer_vlan_id_any);
861   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
862                             mp->sub_inner_vlan_id_any);
863   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
864   vat_json_object_add_uint (node, "vtr_push_dot1q",
865                             ntohl (mp->vtr_push_dot1q));
866   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
867   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
868 }
869
870 static void vl_api_sw_interface_set_flags_t_handler
871   (vl_api_sw_interface_set_flags_t * mp)
872 {
873   vat_main_t *vam = &vat_main;
874   if (vam->interface_event_display)
875     errmsg ("interface flags: sw_if_index %d %s %s",
876             ntohl (mp->sw_if_index),
877             mp->admin_up_down ? "admin-up" : "admin-down",
878             mp->link_up_down ? "link-up" : "link-down");
879 }
880
881 static void vl_api_sw_interface_set_flags_t_handler_json
882   (vl_api_sw_interface_set_flags_t * mp)
883 {
884   /* JSON output not supported */
885 }
886
887 static void
888 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
889 {
890   vat_main_t *vam = &vat_main;
891   i32 retval = ntohl (mp->retval);
892
893   vam->retval = retval;
894   vam->shmem_result = (u8 *) mp->reply_in_shmem;
895   vam->result_ready = 1;
896 }
897
898 static void
899 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
900 {
901   vat_main_t *vam = &vat_main;
902   vat_json_node_t node;
903   api_main_t *am = &api_main;
904   void *oldheap;
905   u8 *reply;
906
907   vat_json_init_object (&node);
908   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
909   vat_json_object_add_uint (&node, "reply_in_shmem",
910                             ntohl (mp->reply_in_shmem));
911   /* Toss the shared-memory original... */
912   pthread_mutex_lock (&am->vlib_rp->mutex);
913   oldheap = svm_push_data_heap (am->vlib_rp);
914
915   reply = (u8 *) (mp->reply_in_shmem);
916   vec_free (reply);
917
918   svm_pop_heap (oldheap);
919   pthread_mutex_unlock (&am->vlib_rp->mutex);
920
921   vat_json_print (vam->ofp, &node);
922   vat_json_free (&node);
923
924   vam->retval = ntohl (mp->retval);
925   vam->result_ready = 1;
926 }
927
928 static void
929 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
930 {
931   vat_main_t *vam = &vat_main;
932   i32 retval = ntohl (mp->retval);
933
934   vam->retval = retval;
935   vam->cmd_reply = mp->reply;
936   vam->result_ready = 1;
937 }
938
939 static void
940 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
941 {
942   vat_main_t *vam = &vat_main;
943   vat_json_node_t node;
944
945   vat_json_init_object (&node);
946   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
947   vat_json_object_add_string_copy (&node, "reply", mp->reply);
948
949   vat_json_print (vam->ofp, &node);
950   vat_json_free (&node);
951
952   vam->retval = ntohl (mp->retval);
953   vam->result_ready = 1;
954 }
955
956 static void vl_api_classify_add_del_table_reply_t_handler
957   (vl_api_classify_add_del_table_reply_t * mp)
958 {
959   vat_main_t *vam = &vat_main;
960   i32 retval = ntohl (mp->retval);
961   if (vam->async_mode)
962     {
963       vam->async_errors += (retval < 0);
964     }
965   else
966     {
967       vam->retval = retval;
968       if (retval == 0 &&
969           ((mp->new_table_index != 0xFFFFFFFF) ||
970            (mp->skip_n_vectors != 0xFFFFFFFF) ||
971            (mp->match_n_vectors != 0xFFFFFFFF)))
972         /*
973          * Note: this is just barely thread-safe, depends on
974          * the main thread spinning waiting for an answer...
975          */
976         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
977                 ntohl (mp->new_table_index),
978                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
979       vam->result_ready = 1;
980     }
981 }
982
983 static void vl_api_classify_add_del_table_reply_t_handler_json
984   (vl_api_classify_add_del_table_reply_t * mp)
985 {
986   vat_main_t *vam = &vat_main;
987   vat_json_node_t node;
988
989   vat_json_init_object (&node);
990   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
991   vat_json_object_add_uint (&node, "new_table_index",
992                             ntohl (mp->new_table_index));
993   vat_json_object_add_uint (&node, "skip_n_vectors",
994                             ntohl (mp->skip_n_vectors));
995   vat_json_object_add_uint (&node, "match_n_vectors",
996                             ntohl (mp->match_n_vectors));
997
998   vat_json_print (vam->ofp, &node);
999   vat_json_free (&node);
1000
1001   vam->retval = ntohl (mp->retval);
1002   vam->result_ready = 1;
1003 }
1004
1005 static void vl_api_get_node_index_reply_t_handler
1006   (vl_api_get_node_index_reply_t * mp)
1007 {
1008   vat_main_t *vam = &vat_main;
1009   i32 retval = ntohl (mp->retval);
1010   if (vam->async_mode)
1011     {
1012       vam->async_errors += (retval < 0);
1013     }
1014   else
1015     {
1016       vam->retval = retval;
1017       if (retval == 0)
1018         errmsg ("node index %d", ntohl (mp->node_index));
1019       vam->result_ready = 1;
1020     }
1021 }
1022
1023 static void vl_api_get_node_index_reply_t_handler_json
1024   (vl_api_get_node_index_reply_t * mp)
1025 {
1026   vat_main_t *vam = &vat_main;
1027   vat_json_node_t node;
1028
1029   vat_json_init_object (&node);
1030   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1031   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1032
1033   vat_json_print (vam->ofp, &node);
1034   vat_json_free (&node);
1035
1036   vam->retval = ntohl (mp->retval);
1037   vam->result_ready = 1;
1038 }
1039
1040 static void vl_api_get_next_index_reply_t_handler
1041   (vl_api_get_next_index_reply_t * mp)
1042 {
1043   vat_main_t *vam = &vat_main;
1044   i32 retval = ntohl (mp->retval);
1045   if (vam->async_mode)
1046     {
1047       vam->async_errors += (retval < 0);
1048     }
1049   else
1050     {
1051       vam->retval = retval;
1052       if (retval == 0)
1053         errmsg ("next node index %d", ntohl (mp->next_index));
1054       vam->result_ready = 1;
1055     }
1056 }
1057
1058 static void vl_api_get_next_index_reply_t_handler_json
1059   (vl_api_get_next_index_reply_t * mp)
1060 {
1061   vat_main_t *vam = &vat_main;
1062   vat_json_node_t node;
1063
1064   vat_json_init_object (&node);
1065   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1066   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1067
1068   vat_json_print (vam->ofp, &node);
1069   vat_json_free (&node);
1070
1071   vam->retval = ntohl (mp->retval);
1072   vam->result_ready = 1;
1073 }
1074
1075 static void vl_api_add_node_next_reply_t_handler
1076   (vl_api_add_node_next_reply_t * mp)
1077 {
1078   vat_main_t *vam = &vat_main;
1079   i32 retval = ntohl (mp->retval);
1080   if (vam->async_mode)
1081     {
1082       vam->async_errors += (retval < 0);
1083     }
1084   else
1085     {
1086       vam->retval = retval;
1087       if (retval == 0)
1088         errmsg ("next index %d", ntohl (mp->next_index));
1089       vam->result_ready = 1;
1090     }
1091 }
1092
1093 static void vl_api_add_node_next_reply_t_handler_json
1094   (vl_api_add_node_next_reply_t * mp)
1095 {
1096   vat_main_t *vam = &vat_main;
1097   vat_json_node_t node;
1098
1099   vat_json_init_object (&node);
1100   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1101   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1102
1103   vat_json_print (vam->ofp, &node);
1104   vat_json_free (&node);
1105
1106   vam->retval = ntohl (mp->retval);
1107   vam->result_ready = 1;
1108 }
1109
1110 static void vl_api_show_version_reply_t_handler
1111   (vl_api_show_version_reply_t * mp)
1112 {
1113   vat_main_t *vam = &vat_main;
1114   i32 retval = ntohl (mp->retval);
1115
1116   if (retval >= 0)
1117     {
1118       errmsg ("        program: %s", mp->program);
1119       errmsg ("        version: %s", mp->version);
1120       errmsg ("     build date: %s", mp->build_date);
1121       errmsg ("build directory: %s", mp->build_directory);
1122     }
1123   vam->retval = retval;
1124   vam->result_ready = 1;
1125 }
1126
1127 static void vl_api_show_version_reply_t_handler_json
1128   (vl_api_show_version_reply_t * mp)
1129 {
1130   vat_main_t *vam = &vat_main;
1131   vat_json_node_t node;
1132
1133   vat_json_init_object (&node);
1134   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1135   vat_json_object_add_string_copy (&node, "program", mp->program);
1136   vat_json_object_add_string_copy (&node, "version", mp->version);
1137   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1138   vat_json_object_add_string_copy (&node, "build_directory",
1139                                    mp->build_directory);
1140
1141   vat_json_print (vam->ofp, &node);
1142   vat_json_free (&node);
1143
1144   vam->retval = ntohl (mp->retval);
1145   vam->result_ready = 1;
1146 }
1147
1148 static void
1149 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1150 {
1151   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1152           mp->mac_ip ? "mac/ip binding" : "address resolution",
1153           format_ip4_address, &mp->address,
1154           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1155 }
1156
1157 static void
1158 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1159 {
1160   /* JSON output not supported */
1161 }
1162
1163 static void
1164 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1165 {
1166   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1167           mp->mac_ip ? "mac/ip binding" : "address resolution",
1168           format_ip6_address, mp->address,
1169           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1170 }
1171
1172 static void
1173 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1174 {
1175   /* JSON output not supported */
1176 }
1177
1178 /*
1179  * Special-case: build the bridge domain table, maintain
1180  * the next bd id vbl.
1181  */
1182 static void vl_api_bridge_domain_details_t_handler
1183   (vl_api_bridge_domain_details_t * mp)
1184 {
1185   vat_main_t *vam = &vat_main;
1186   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1187
1188   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1189          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1190
1191   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1192          ntohl (mp->bd_id), mp->learn, mp->forward,
1193          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1194
1195   if (n_sw_ifs)
1196     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1197 }
1198
1199 static void vl_api_bridge_domain_details_t_handler_json
1200   (vl_api_bridge_domain_details_t * mp)
1201 {
1202   vat_main_t *vam = &vat_main;
1203   vat_json_node_t *node, *array = NULL;
1204
1205   if (VAT_JSON_ARRAY != vam->json_tree.type)
1206     {
1207       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1208       vat_json_init_array (&vam->json_tree);
1209     }
1210   node = vat_json_array_add (&vam->json_tree);
1211
1212   vat_json_init_object (node);
1213   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1214   vat_json_object_add_uint (node, "flood", mp->flood);
1215   vat_json_object_add_uint (node, "forward", mp->forward);
1216   vat_json_object_add_uint (node, "learn", mp->learn);
1217   vat_json_object_add_uint (node, "bvi_sw_if_index",
1218                             ntohl (mp->bvi_sw_if_index));
1219   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1220   array = vat_json_object_add (node, "sw_if");
1221   vat_json_init_array (array);
1222 }
1223
1224 /*
1225  * Special-case: build the bridge domain sw if table.
1226  */
1227 static void vl_api_bridge_domain_sw_if_details_t_handler
1228   (vl_api_bridge_domain_sw_if_details_t * mp)
1229 {
1230   vat_main_t *vam = &vat_main;
1231   hash_pair_t *p;
1232   u8 *sw_if_name = 0;
1233   u32 sw_if_index;
1234
1235   sw_if_index = ntohl (mp->sw_if_index);
1236   /* *INDENT-OFF* */
1237   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1238   ({
1239     if ((u32) p->value[0] == sw_if_index)
1240       {
1241         sw_if_name = (u8 *)(p->key);
1242         break;
1243       }
1244   }));
1245   /* *INDENT-ON* */
1246
1247   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1248          mp->shg, sw_if_name ? (char *) sw_if_name :
1249          "sw_if_index not found!");
1250 }
1251
1252 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1253   (vl_api_bridge_domain_sw_if_details_t * mp)
1254 {
1255   vat_main_t *vam = &vat_main;
1256   vat_json_node_t *node = NULL;
1257   uword last_index = 0;
1258
1259   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1260   ASSERT (vec_len (vam->json_tree.array) >= 1);
1261   last_index = vec_len (vam->json_tree.array) - 1;
1262   node = &vam->json_tree.array[last_index];
1263   node = vat_json_object_get_element (node, "sw_if");
1264   ASSERT (NULL != node);
1265   node = vat_json_array_add (node);
1266
1267   vat_json_init_object (node);
1268   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1269   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1270   vat_json_object_add_uint (node, "shg", mp->shg);
1271 }
1272
1273 static void vl_api_control_ping_reply_t_handler
1274   (vl_api_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_control_ping_reply_t_handler_json
1290   (vl_api_control_ping_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   i32 retval = ntohl (mp->retval);
1294
1295   if (VAT_JSON_NONE != vam->json_tree.type)
1296     {
1297       vat_json_print (vam->ofp, &vam->json_tree);
1298       vat_json_free (&vam->json_tree);
1299       vam->json_tree.type = VAT_JSON_NONE;
1300     }
1301   else
1302     {
1303       /* just print [] */
1304       vat_json_init_array (&vam->json_tree);
1305       vat_json_print (vam->ofp, &vam->json_tree);
1306       vam->json_tree.type = VAT_JSON_NONE;
1307     }
1308
1309   vam->retval = retval;
1310   vam->result_ready = 1;
1311 }
1312
1313 static void
1314 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1315 {
1316   vat_main_t *vam = &vat_main;
1317   i32 retval = ntohl (mp->retval);
1318   if (vam->async_mode)
1319     {
1320       vam->async_errors += (retval < 0);
1321     }
1322   else
1323     {
1324       vam->retval = retval;
1325       vam->result_ready = 1;
1326     }
1327 }
1328
1329 static void vl_api_l2_flags_reply_t_handler_json
1330   (vl_api_l2_flags_reply_t * mp)
1331 {
1332   vat_main_t *vam = &vat_main;
1333   vat_json_node_t node;
1334
1335   vat_json_init_object (&node);
1336   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1337   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1338                             ntohl (mp->resulting_feature_bitmap));
1339
1340   vat_json_print (vam->ofp, &node);
1341   vat_json_free (&node);
1342
1343   vam->retval = ntohl (mp->retval);
1344   vam->result_ready = 1;
1345 }
1346
1347 static void vl_api_bridge_flags_reply_t_handler
1348   (vl_api_bridge_flags_reply_t * mp)
1349 {
1350   vat_main_t *vam = &vat_main;
1351   i32 retval = ntohl (mp->retval);
1352   if (vam->async_mode)
1353     {
1354       vam->async_errors += (retval < 0);
1355     }
1356   else
1357     {
1358       vam->retval = retval;
1359       vam->result_ready = 1;
1360     }
1361 }
1362
1363 static void vl_api_bridge_flags_reply_t_handler_json
1364   (vl_api_bridge_flags_reply_t * mp)
1365 {
1366   vat_main_t *vam = &vat_main;
1367   vat_json_node_t node;
1368
1369   vat_json_init_object (&node);
1370   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1371   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1372                             ntohl (mp->resulting_feature_bitmap));
1373
1374   vat_json_print (vam->ofp, &node);
1375   vat_json_free (&node);
1376
1377   vam->retval = ntohl (mp->retval);
1378   vam->result_ready = 1;
1379 }
1380
1381 static void vl_api_tap_connect_reply_t_handler
1382   (vl_api_tap_connect_reply_t * mp)
1383 {
1384   vat_main_t *vam = &vat_main;
1385   i32 retval = ntohl (mp->retval);
1386   if (vam->async_mode)
1387     {
1388       vam->async_errors += (retval < 0);
1389     }
1390   else
1391     {
1392       vam->retval = retval;
1393       vam->sw_if_index = ntohl (mp->sw_if_index);
1394       vam->result_ready = 1;
1395     }
1396
1397 }
1398
1399 static void vl_api_tap_connect_reply_t_handler_json
1400   (vl_api_tap_connect_reply_t * mp)
1401 {
1402   vat_main_t *vam = &vat_main;
1403   vat_json_node_t node;
1404
1405   vat_json_init_object (&node);
1406   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1407   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1408
1409   vat_json_print (vam->ofp, &node);
1410   vat_json_free (&node);
1411
1412   vam->retval = ntohl (mp->retval);
1413   vam->result_ready = 1;
1414
1415 }
1416
1417 static void
1418 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1419 {
1420   vat_main_t *vam = &vat_main;
1421   i32 retval = ntohl (mp->retval);
1422   if (vam->async_mode)
1423     {
1424       vam->async_errors += (retval < 0);
1425     }
1426   else
1427     {
1428       vam->retval = retval;
1429       vam->sw_if_index = ntohl (mp->sw_if_index);
1430       vam->result_ready = 1;
1431     }
1432 }
1433
1434 static void vl_api_tap_modify_reply_t_handler_json
1435   (vl_api_tap_modify_reply_t * mp)
1436 {
1437   vat_main_t *vam = &vat_main;
1438   vat_json_node_t node;
1439
1440   vat_json_init_object (&node);
1441   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1442   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1443
1444   vat_json_print (vam->ofp, &node);
1445   vat_json_free (&node);
1446
1447   vam->retval = ntohl (mp->retval);
1448   vam->result_ready = 1;
1449 }
1450
1451 static void
1452 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1453 {
1454   vat_main_t *vam = &vat_main;
1455   i32 retval = ntohl (mp->retval);
1456   if (vam->async_mode)
1457     {
1458       vam->async_errors += (retval < 0);
1459     }
1460   else
1461     {
1462       vam->retval = retval;
1463       vam->result_ready = 1;
1464     }
1465 }
1466
1467 static void vl_api_tap_delete_reply_t_handler_json
1468   (vl_api_tap_delete_reply_t * mp)
1469 {
1470   vat_main_t *vam = &vat_main;
1471   vat_json_node_t node;
1472
1473   vat_json_init_object (&node);
1474   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1475
1476   vat_json_print (vam->ofp, &node);
1477   vat_json_free (&node);
1478
1479   vam->retval = ntohl (mp->retval);
1480   vam->result_ready = 1;
1481 }
1482
1483 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1484   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1485 {
1486   vat_main_t *vam = &vat_main;
1487   i32 retval = ntohl (mp->retval);
1488   if (vam->async_mode)
1489     {
1490       vam->async_errors += (retval < 0);
1491     }
1492   else
1493     {
1494       vam->retval = retval;
1495       vam->result_ready = 1;
1496     }
1497 }
1498
1499 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1500   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1501 {
1502   vat_main_t *vam = &vat_main;
1503   vat_json_node_t node;
1504
1505   vat_json_init_object (&node);
1506   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1507   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1508                             ntohl (mp->sw_if_index));
1509
1510   vat_json_print (vam->ofp, &node);
1511   vat_json_free (&node);
1512
1513   vam->retval = ntohl (mp->retval);
1514   vam->result_ready = 1;
1515 }
1516
1517 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1518   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1519 {
1520   vat_main_t *vam = &vat_main;
1521   i32 retval = ntohl (mp->retval);
1522   if (vam->async_mode)
1523     {
1524       vam->async_errors += (retval < 0);
1525     }
1526   else
1527     {
1528       vam->retval = retval;
1529       vam->sw_if_index = ntohl (mp->sw_if_index);
1530       vam->result_ready = 1;
1531     }
1532 }
1533
1534 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1535   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1536 {
1537   vat_main_t *vam = &vat_main;
1538   vat_json_node_t node;
1539
1540   vat_json_init_object (&node);
1541   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1542   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1543
1544   vat_json_print (vam->ofp, &node);
1545   vat_json_free (&node);
1546
1547   vam->retval = ntohl (mp->retval);
1548   vam->result_ready = 1;
1549 }
1550
1551
1552 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1553   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1554 {
1555   vat_main_t *vam = &vat_main;
1556   i32 retval = ntohl (mp->retval);
1557   if (vam->async_mode)
1558     {
1559       vam->async_errors += (retval < 0);
1560     }
1561   else
1562     {
1563       vam->retval = retval;
1564       vam->result_ready = 1;
1565     }
1566 }
1567
1568 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1569   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1570 {
1571   vat_main_t *vam = &vat_main;
1572   vat_json_node_t node;
1573
1574   vat_json_init_object (&node);
1575   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1576   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1577
1578   vat_json_print (vam->ofp, &node);
1579   vat_json_free (&node);
1580
1581   vam->retval = ntohl (mp->retval);
1582   vam->result_ready = 1;
1583 }
1584
1585 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1586   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1587 {
1588   vat_main_t *vam = &vat_main;
1589   i32 retval = ntohl (mp->retval);
1590   if (vam->async_mode)
1591     {
1592       vam->async_errors += (retval < 0);
1593     }
1594   else
1595     {
1596       vam->retval = retval;
1597       vam->sw_if_index = ntohl (mp->sw_if_index);
1598       vam->result_ready = 1;
1599     }
1600 }
1601
1602 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1603   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1604 {
1605   vat_main_t *vam = &vat_main;
1606   vat_json_node_t node;
1607
1608   vat_json_init_object (&node);
1609   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1610   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1611
1612   vat_json_print (vam->ofp, &node);
1613   vat_json_free (&node);
1614
1615   vam->retval = ntohl (mp->retval);
1616   vam->result_ready = 1;
1617 }
1618
1619 static void vl_api_gre_add_del_tunnel_reply_t_handler
1620   (vl_api_gre_add_del_tunnel_reply_t * mp)
1621 {
1622   vat_main_t *vam = &vat_main;
1623   i32 retval = ntohl (mp->retval);
1624   if (vam->async_mode)
1625     {
1626       vam->async_errors += (retval < 0);
1627     }
1628   else
1629     {
1630       vam->retval = retval;
1631       vam->sw_if_index = ntohl (mp->sw_if_index);
1632       vam->result_ready = 1;
1633     }
1634 }
1635
1636 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1637   (vl_api_gre_add_del_tunnel_reply_t * mp)
1638 {
1639   vat_main_t *vam = &vat_main;
1640   vat_json_node_t node;
1641
1642   vat_json_init_object (&node);
1643   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1644   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1645
1646   vat_json_print (vam->ofp, &node);
1647   vat_json_free (&node);
1648
1649   vam->retval = ntohl (mp->retval);
1650   vam->result_ready = 1;
1651 }
1652
1653 static void vl_api_create_vhost_user_if_reply_t_handler
1654   (vl_api_create_vhost_user_if_reply_t * mp)
1655 {
1656   vat_main_t *vam = &vat_main;
1657   i32 retval = ntohl (mp->retval);
1658   if (vam->async_mode)
1659     {
1660       vam->async_errors += (retval < 0);
1661     }
1662   else
1663     {
1664       vam->retval = retval;
1665       vam->sw_if_index = ntohl (mp->sw_if_index);
1666       vam->result_ready = 1;
1667     }
1668 }
1669
1670 static void vl_api_create_vhost_user_if_reply_t_handler_json
1671   (vl_api_create_vhost_user_if_reply_t * mp)
1672 {
1673   vat_main_t *vam = &vat_main;
1674   vat_json_node_t node;
1675
1676   vat_json_init_object (&node);
1677   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1678   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1679
1680   vat_json_print (vam->ofp, &node);
1681   vat_json_free (&node);
1682
1683   vam->retval = ntohl (mp->retval);
1684   vam->result_ready = 1;
1685 }
1686
1687 static void vl_api_ip_address_details_t_handler
1688   (vl_api_ip_address_details_t * mp)
1689 {
1690   vat_main_t *vam = &vat_main;
1691   static ip_address_details_t empty_ip_address_details = { {0} };
1692   ip_address_details_t *address = NULL;
1693   ip_details_t *current_ip_details = NULL;
1694   ip_details_t *details = NULL;
1695
1696   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1697
1698   if (!details || vam->current_sw_if_index >= vec_len (details)
1699       || !details[vam->current_sw_if_index].present)
1700     {
1701       errmsg ("ip address details arrived but not stored");
1702       errmsg ("ip_dump should be called first");
1703       return;
1704     }
1705
1706   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1707
1708 #define addresses (current_ip_details->addr)
1709
1710   vec_validate_init_empty (addresses, vec_len (addresses),
1711                            empty_ip_address_details);
1712
1713   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1714
1715   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1716   address->prefix_length = mp->prefix_length;
1717 #undef addresses
1718 }
1719
1720 static void vl_api_ip_address_details_t_handler_json
1721   (vl_api_ip_address_details_t * mp)
1722 {
1723   vat_main_t *vam = &vat_main;
1724   vat_json_node_t *node = NULL;
1725   struct in6_addr ip6;
1726   struct in_addr ip4;
1727
1728   if (VAT_JSON_ARRAY != vam->json_tree.type)
1729     {
1730       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1731       vat_json_init_array (&vam->json_tree);
1732     }
1733   node = vat_json_array_add (&vam->json_tree);
1734
1735   vat_json_init_object (node);
1736   if (vam->is_ipv6)
1737     {
1738       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1739       vat_json_object_add_ip6 (node, "ip", ip6);
1740     }
1741   else
1742     {
1743       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1744       vat_json_object_add_ip4 (node, "ip", ip4);
1745     }
1746   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1747 }
1748
1749 static void
1750 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1751 {
1752   vat_main_t *vam = &vat_main;
1753   static ip_details_t empty_ip_details = { 0 };
1754   ip_details_t *ip = NULL;
1755   u32 sw_if_index = ~0;
1756
1757   sw_if_index = ntohl (mp->sw_if_index);
1758
1759   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1760                            sw_if_index, empty_ip_details);
1761
1762   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1763                          sw_if_index);
1764
1765   ip->present = 1;
1766 }
1767
1768 static void
1769 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1770 {
1771   vat_main_t *vam = &vat_main;
1772
1773   if (VAT_JSON_ARRAY != vam->json_tree.type)
1774     {
1775       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1776       vat_json_init_array (&vam->json_tree);
1777     }
1778   vat_json_array_add_uint (&vam->json_tree,
1779                            clib_net_to_host_u32 (mp->sw_if_index));
1780 }
1781
1782 static void vl_api_map_domain_details_t_handler_json
1783   (vl_api_map_domain_details_t * mp)
1784 {
1785   vat_json_node_t *node = NULL;
1786   vat_main_t *vam = &vat_main;
1787   struct in6_addr ip6;
1788   struct in_addr ip4;
1789
1790   if (VAT_JSON_ARRAY != vam->json_tree.type)
1791     {
1792       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1793       vat_json_init_array (&vam->json_tree);
1794     }
1795
1796   node = vat_json_array_add (&vam->json_tree);
1797   vat_json_init_object (node);
1798
1799   vat_json_object_add_uint (node, "domain_index",
1800                             clib_net_to_host_u32 (mp->domain_index));
1801   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1802   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1803   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1804   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1805   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1806   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1807   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1808   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1809   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1810   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1811   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1812   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1813   vat_json_object_add_uint (node, "flags", mp->flags);
1814   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1815   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1816 }
1817
1818 static void vl_api_map_domain_details_t_handler
1819   (vl_api_map_domain_details_t * mp)
1820 {
1821   vat_main_t *vam = &vat_main;
1822
1823   if (mp->is_translation)
1824     {
1825       print (vam->ofp,
1826              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1827              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1828              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1829              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1830              clib_net_to_host_u32 (mp->domain_index));
1831     }
1832   else
1833     {
1834       print (vam->ofp,
1835              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1836              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1837              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1838              format_ip6_address, mp->ip6_src,
1839              clib_net_to_host_u32 (mp->domain_index));
1840     }
1841   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1842          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1843          mp->is_translation ? "map-t" : "");
1844 }
1845
1846 static void vl_api_map_rule_details_t_handler_json
1847   (vl_api_map_rule_details_t * mp)
1848 {
1849   struct in6_addr ip6;
1850   vat_json_node_t *node = NULL;
1851   vat_main_t *vam = &vat_main;
1852
1853   if (VAT_JSON_ARRAY != vam->json_tree.type)
1854     {
1855       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1856       vat_json_init_array (&vam->json_tree);
1857     }
1858
1859   node = vat_json_array_add (&vam->json_tree);
1860   vat_json_init_object (node);
1861
1862   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1863   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1864   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1865 }
1866
1867 static void
1868 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1869 {
1870   vat_main_t *vam = &vat_main;
1871   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1872          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1873 }
1874
1875 static void
1876 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1877 {
1878   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1879           "router_addr %U host_mac %U",
1880           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1881           format_ip4_address, &mp->host_address,
1882           format_ip4_address, &mp->router_address,
1883           format_ethernet_address, mp->host_mac);
1884 }
1885
1886 static void vl_api_dhcp_compl_event_t_handler_json
1887   (vl_api_dhcp_compl_event_t * mp)
1888 {
1889   /* JSON output not supported */
1890 }
1891
1892 static void
1893 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1894                               u32 counter)
1895 {
1896   vat_main_t *vam = &vat_main;
1897   static u64 default_counter = 0;
1898
1899   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1900                            NULL);
1901   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1902                            sw_if_index, default_counter);
1903   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1904 }
1905
1906 static void
1907 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1908                                 interface_counter_t counter)
1909 {
1910   vat_main_t *vam = &vat_main;
1911   static interface_counter_t default_counter = { 0, };
1912
1913   vec_validate_init_empty (vam->combined_interface_counters,
1914                            vnet_counter_type, NULL);
1915   vec_validate_init_empty (vam->combined_interface_counters
1916                            [vnet_counter_type], sw_if_index, default_counter);
1917   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1918 }
1919
1920 static void vl_api_vnet_interface_counters_t_handler
1921   (vl_api_vnet_interface_counters_t * mp)
1922 {
1923   /* not supported */
1924 }
1925
1926 static void vl_api_vnet_interface_counters_t_handler_json
1927   (vl_api_vnet_interface_counters_t * mp)
1928 {
1929   interface_counter_t counter;
1930   vlib_counter_t *v;
1931   u64 *v_packets;
1932   u64 packets;
1933   u32 count;
1934   u32 first_sw_if_index;
1935   int i;
1936
1937   count = ntohl (mp->count);
1938   first_sw_if_index = ntohl (mp->first_sw_if_index);
1939
1940   if (!mp->is_combined)
1941     {
1942       v_packets = (u64 *) & mp->data;
1943       for (i = 0; i < count; i++)
1944         {
1945           packets =
1946             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1947           set_simple_interface_counter (mp->vnet_counter_type,
1948                                         first_sw_if_index + i, packets);
1949           v_packets++;
1950         }
1951     }
1952   else
1953     {
1954       v = (vlib_counter_t *) & mp->data;
1955       for (i = 0; i < count; i++)
1956         {
1957           counter.packets =
1958             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1959           counter.bytes =
1960             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1961           set_combined_interface_counter (mp->vnet_counter_type,
1962                                           first_sw_if_index + i, counter);
1963           v++;
1964         }
1965     }
1966 }
1967
1968 static u32
1969 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1970 {
1971   vat_main_t *vam = &vat_main;
1972   u32 i;
1973
1974   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1975     {
1976       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1977         {
1978           return i;
1979         }
1980     }
1981   return ~0;
1982 }
1983
1984 static u32
1985 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1986 {
1987   vat_main_t *vam = &vat_main;
1988   u32 i;
1989
1990   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1991     {
1992       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1993         {
1994           return i;
1995         }
1996     }
1997   return ~0;
1998 }
1999
2000 static void vl_api_vnet_ip4_fib_counters_t_handler
2001   (vl_api_vnet_ip4_fib_counters_t * mp)
2002 {
2003   /* not supported */
2004 }
2005
2006 static void vl_api_vnet_ip4_fib_counters_t_handler_json
2007   (vl_api_vnet_ip4_fib_counters_t * mp)
2008 {
2009   vat_main_t *vam = &vat_main;
2010   vl_api_ip4_fib_counter_t *v;
2011   ip4_fib_counter_t *counter;
2012   struct in_addr ip4;
2013   u32 vrf_id;
2014   u32 vrf_index;
2015   u32 count;
2016   int i;
2017
2018   vrf_id = ntohl (mp->vrf_id);
2019   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2020   if (~0 == vrf_index)
2021     {
2022       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2023       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2024       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2025       vec_validate (vam->ip4_fib_counters, vrf_index);
2026       vam->ip4_fib_counters[vrf_index] = NULL;
2027     }
2028
2029   vec_free (vam->ip4_fib_counters[vrf_index]);
2030   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2031   count = ntohl (mp->count);
2032   for (i = 0; i < count; i++)
2033     {
2034       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2035       counter = &vam->ip4_fib_counters[vrf_index][i];
2036       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2037       counter->address = ip4;
2038       counter->address_length = v->address_length;
2039       counter->packets = clib_net_to_host_u64 (v->packets);
2040       counter->bytes = clib_net_to_host_u64 (v->bytes);
2041       v++;
2042     }
2043 }
2044
2045 static void vl_api_vnet_ip4_nbr_counters_t_handler
2046   (vl_api_vnet_ip4_nbr_counters_t * mp)
2047 {
2048   /* not supported */
2049 }
2050
2051 static void vl_api_vnet_ip4_nbr_counters_t_handler_json
2052   (vl_api_vnet_ip4_nbr_counters_t * mp)
2053 {
2054   vat_main_t *vam = &vat_main;
2055   vl_api_ip4_nbr_counter_t *v;
2056   ip4_nbr_counter_t *counter;
2057   u32 sw_if_index;
2058   u32 count;
2059   int i;
2060
2061   sw_if_index = ntohl (mp->sw_if_index);
2062   count = ntohl (mp->count);
2063   vec_validate (vam->ip4_nbr_counters, sw_if_index);
2064
2065   if (mp->begin)
2066     vec_free (vam->ip4_nbr_counters[sw_if_index]);
2067
2068   v = (vl_api_ip4_nbr_counter_t *) & mp->c;
2069   for (i = 0; i < count; i++)
2070     {
2071       vec_validate (vam->ip4_nbr_counters[sw_if_index], i);
2072       counter = &vam->ip4_nbr_counters[sw_if_index][i];
2073       counter->address.s_addr = v->address;
2074       counter->packets = clib_net_to_host_u64 (v->packets);
2075       counter->bytes = clib_net_to_host_u64 (v->bytes);
2076       counter->linkt = v->link_type;
2077       v++;
2078     }
2079 }
2080
2081 static void vl_api_vnet_ip6_fib_counters_t_handler
2082   (vl_api_vnet_ip6_fib_counters_t * mp)
2083 {
2084   /* not supported */
2085 }
2086
2087 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2088   (vl_api_vnet_ip6_fib_counters_t * mp)
2089 {
2090   vat_main_t *vam = &vat_main;
2091   vl_api_ip6_fib_counter_t *v;
2092   ip6_fib_counter_t *counter;
2093   struct in6_addr ip6;
2094   u32 vrf_id;
2095   u32 vrf_index;
2096   u32 count;
2097   int i;
2098
2099   vrf_id = ntohl (mp->vrf_id);
2100   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2101   if (~0 == vrf_index)
2102     {
2103       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2104       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2105       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2106       vec_validate (vam->ip6_fib_counters, vrf_index);
2107       vam->ip6_fib_counters[vrf_index] = NULL;
2108     }
2109
2110   vec_free (vam->ip6_fib_counters[vrf_index]);
2111   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2112   count = ntohl (mp->count);
2113   for (i = 0; i < count; i++)
2114     {
2115       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2116       counter = &vam->ip6_fib_counters[vrf_index][i];
2117       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2118       counter->address = ip6;
2119       counter->address_length = v->address_length;
2120       counter->packets = clib_net_to_host_u64 (v->packets);
2121       counter->bytes = clib_net_to_host_u64 (v->bytes);
2122       v++;
2123     }
2124 }
2125
2126 static void vl_api_vnet_ip6_nbr_counters_t_handler
2127   (vl_api_vnet_ip6_nbr_counters_t * mp)
2128 {
2129   /* not supported */
2130 }
2131
2132 static void vl_api_vnet_ip6_nbr_counters_t_handler_json
2133   (vl_api_vnet_ip6_nbr_counters_t * mp)
2134 {
2135   vat_main_t *vam = &vat_main;
2136   vl_api_ip6_nbr_counter_t *v;
2137   ip6_nbr_counter_t *counter;
2138   struct in6_addr ip6;
2139   u32 sw_if_index;
2140   u32 count;
2141   int i;
2142
2143   sw_if_index = ntohl (mp->sw_if_index);
2144   count = ntohl (mp->count);
2145   vec_validate (vam->ip6_nbr_counters, sw_if_index);
2146
2147   if (mp->begin)
2148     vec_free (vam->ip6_nbr_counters[sw_if_index]);
2149
2150   v = (vl_api_ip6_nbr_counter_t *) & mp->c;
2151   for (i = 0; i < count; i++)
2152     {
2153       vec_validate (vam->ip6_nbr_counters[sw_if_index], i);
2154       counter = &vam->ip6_nbr_counters[sw_if_index][i];
2155       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2156       counter->address = ip6;
2157       counter->packets = clib_net_to_host_u64 (v->packets);
2158       counter->bytes = clib_net_to_host_u64 (v->bytes);
2159       v++;
2160     }
2161 }
2162
2163 static void vl_api_get_first_msg_id_reply_t_handler
2164   (vl_api_get_first_msg_id_reply_t * mp)
2165 {
2166   vat_main_t *vam = &vat_main;
2167   i32 retval = ntohl (mp->retval);
2168
2169   if (vam->async_mode)
2170     {
2171       vam->async_errors += (retval < 0);
2172     }
2173   else
2174     {
2175       vam->retval = retval;
2176       vam->result_ready = 1;
2177     }
2178   if (retval >= 0)
2179     {
2180       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2181     }
2182 }
2183
2184 static void vl_api_get_first_msg_id_reply_t_handler_json
2185   (vl_api_get_first_msg_id_reply_t * mp)
2186 {
2187   vat_main_t *vam = &vat_main;
2188   vat_json_node_t node;
2189
2190   vat_json_init_object (&node);
2191   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2192   vat_json_object_add_uint (&node, "first_msg_id",
2193                             (uint) ntohs (mp->first_msg_id));
2194
2195   vat_json_print (vam->ofp, &node);
2196   vat_json_free (&node);
2197
2198   vam->retval = ntohl (mp->retval);
2199   vam->result_ready = 1;
2200 }
2201
2202 static void vl_api_get_node_graph_reply_t_handler
2203   (vl_api_get_node_graph_reply_t * mp)
2204 {
2205   vat_main_t *vam = &vat_main;
2206   api_main_t *am = &api_main;
2207   i32 retval = ntohl (mp->retval);
2208   u8 *pvt_copy, *reply;
2209   void *oldheap;
2210   vlib_node_t *node;
2211   int i;
2212
2213   if (vam->async_mode)
2214     {
2215       vam->async_errors += (retval < 0);
2216     }
2217   else
2218     {
2219       vam->retval = retval;
2220       vam->result_ready = 1;
2221     }
2222
2223   /* "Should never happen..." */
2224   if (retval != 0)
2225     return;
2226
2227   reply = (u8 *) (mp->reply_in_shmem);
2228   pvt_copy = vec_dup (reply);
2229
2230   /* Toss the shared-memory original... */
2231   pthread_mutex_lock (&am->vlib_rp->mutex);
2232   oldheap = svm_push_data_heap (am->vlib_rp);
2233
2234   vec_free (reply);
2235
2236   svm_pop_heap (oldheap);
2237   pthread_mutex_unlock (&am->vlib_rp->mutex);
2238
2239   if (vam->graph_nodes)
2240     {
2241       hash_free (vam->graph_node_index_by_name);
2242
2243       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2244         {
2245           node = vam->graph_nodes[i];
2246           vec_free (node->name);
2247           vec_free (node->next_nodes);
2248           vec_free (node);
2249         }
2250       vec_free (vam->graph_nodes);
2251     }
2252
2253   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2254   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2255   vec_free (pvt_copy);
2256
2257   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2258     {
2259       node = vam->graph_nodes[i];
2260       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2261     }
2262 }
2263
2264 static void vl_api_get_node_graph_reply_t_handler_json
2265   (vl_api_get_node_graph_reply_t * mp)
2266 {
2267   vat_main_t *vam = &vat_main;
2268   api_main_t *am = &api_main;
2269   void *oldheap;
2270   vat_json_node_t node;
2271   u8 *reply;
2272
2273   /* $$$$ make this real? */
2274   vat_json_init_object (&node);
2275   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2276   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2277
2278   reply = (u8 *) (mp->reply_in_shmem);
2279
2280   /* Toss the shared-memory original... */
2281   pthread_mutex_lock (&am->vlib_rp->mutex);
2282   oldheap = svm_push_data_heap (am->vlib_rp);
2283
2284   vec_free (reply);
2285
2286   svm_pop_heap (oldheap);
2287   pthread_mutex_unlock (&am->vlib_rp->mutex);
2288
2289   vat_json_print (vam->ofp, &node);
2290   vat_json_free (&node);
2291
2292   vam->retval = ntohl (mp->retval);
2293   vam->result_ready = 1;
2294 }
2295
2296 static void
2297 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2298 {
2299   vat_main_t *vam = &vat_main;
2300   u8 *s = 0;
2301
2302   if (mp->local)
2303     {
2304       s = format (s, "%=16d%=16d%=16d",
2305                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2306     }
2307   else
2308     {
2309       s = format (s, "%=16U%=16d%=16d",
2310                   mp->is_ipv6 ? format_ip6_address :
2311                   format_ip4_address,
2312                   mp->ip_address, mp->priority, mp->weight);
2313     }
2314
2315   print (vam->ofp, "%v", s);
2316   vec_free (s);
2317 }
2318
2319 static void
2320 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2321                                             mp)
2322 {
2323   vat_main_t *vam = &vat_main;
2324   vat_json_node_t *node = NULL;
2325   struct in6_addr ip6;
2326   struct in_addr ip4;
2327
2328   if (VAT_JSON_ARRAY != vam->json_tree.type)
2329     {
2330       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2331       vat_json_init_array (&vam->json_tree);
2332     }
2333   node = vat_json_array_add (&vam->json_tree);
2334   vat_json_init_object (node);
2335
2336   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2337   vat_json_object_add_uint (node, "priority", mp->priority);
2338   vat_json_object_add_uint (node, "weight", mp->weight);
2339
2340   if (mp->local)
2341     vat_json_object_add_uint (node, "sw_if_index",
2342                               clib_net_to_host_u32 (mp->sw_if_index));
2343   else
2344     {
2345       if (mp->is_ipv6)
2346         {
2347           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2348           vat_json_object_add_ip6 (node, "address", ip6);
2349         }
2350       else
2351         {
2352           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2353           vat_json_object_add_ip4 (node, "address", ip4);
2354         }
2355     }
2356 }
2357
2358 static void
2359 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2360                                            mp)
2361 {
2362   vat_main_t *vam = &vat_main;
2363   u8 *ls_name = 0;
2364
2365   ls_name = format (0, "%s", mp->ls_name);
2366
2367   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2368          ls_name);
2369   vec_free (ls_name);
2370 }
2371
2372 static void
2373   vl_api_lisp_locator_set_details_t_handler_json
2374   (vl_api_lisp_locator_set_details_t * mp)
2375 {
2376   vat_main_t *vam = &vat_main;
2377   vat_json_node_t *node = 0;
2378   u8 *ls_name = 0;
2379
2380   ls_name = format (0, "%s", mp->ls_name);
2381   vec_add1 (ls_name, 0);
2382
2383   if (VAT_JSON_ARRAY != vam->json_tree.type)
2384     {
2385       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2386       vat_json_init_array (&vam->json_tree);
2387     }
2388   node = vat_json_array_add (&vam->json_tree);
2389
2390   vat_json_init_object (node);
2391   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2392   vat_json_object_add_uint (node, "ls_index",
2393                             clib_net_to_host_u32 (mp->ls_index));
2394   vec_free (ls_name);
2395 }
2396
2397 static u8 *
2398 format_lisp_flat_eid (u8 * s, va_list * args)
2399 {
2400   u32 type = va_arg (*args, u32);
2401   u8 *eid = va_arg (*args, u8 *);
2402   u32 eid_len = va_arg (*args, u32);
2403
2404   switch (type)
2405     {
2406     case 0:
2407       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2408     case 1:
2409       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2410     case 2:
2411       return format (s, "%U", format_ethernet_address, eid);
2412     }
2413   return 0;
2414 }
2415
2416 static u8 *
2417 format_lisp_eid_vat (u8 * s, va_list * args)
2418 {
2419   u32 type = va_arg (*args, u32);
2420   u8 *eid = va_arg (*args, u8 *);
2421   u32 eid_len = va_arg (*args, u32);
2422   u8 *seid = va_arg (*args, u8 *);
2423   u32 seid_len = va_arg (*args, u32);
2424   u32 is_src_dst = va_arg (*args, u32);
2425
2426   if (is_src_dst)
2427     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2428
2429   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2430
2431   return s;
2432 }
2433
2434 static void
2435 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2436 {
2437   vat_main_t *vam = &vat_main;
2438   u8 *s = 0, *eid = 0;
2439
2440   if (~0 == mp->locator_set_index)
2441     s = format (0, "action: %d", mp->action);
2442   else
2443     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2444
2445   eid = format (0, "%U", format_lisp_eid_vat,
2446                 mp->eid_type,
2447                 mp->eid,
2448                 mp->eid_prefix_len,
2449                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2450   vec_add1 (eid, 0);
2451
2452   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2453          clib_net_to_host_u32 (mp->vni),
2454          eid,
2455          mp->is_local ? "local" : "remote",
2456          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2457          clib_net_to_host_u16 (mp->key_id), mp->key);
2458
2459   vec_free (s);
2460   vec_free (eid);
2461 }
2462
2463 static void
2464 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2465                                               * mp)
2466 {
2467   vat_main_t *vam = &vat_main;
2468   vat_json_node_t *node = 0;
2469   u8 *eid = 0;
2470
2471   if (VAT_JSON_ARRAY != vam->json_tree.type)
2472     {
2473       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2474       vat_json_init_array (&vam->json_tree);
2475     }
2476   node = vat_json_array_add (&vam->json_tree);
2477
2478   vat_json_init_object (node);
2479   if (~0 == mp->locator_set_index)
2480     vat_json_object_add_uint (node, "action", mp->action);
2481   else
2482     vat_json_object_add_uint (node, "locator_set_index",
2483                               clib_net_to_host_u32 (mp->locator_set_index));
2484
2485   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2486   eid = format (0, "%U", format_lisp_eid_vat,
2487                 mp->eid_type,
2488                 mp->eid,
2489                 mp->eid_prefix_len,
2490                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2491   vec_add1 (eid, 0);
2492   vat_json_object_add_string_copy (node, "eid", eid);
2493   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2494   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2495   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2496
2497   if (mp->key_id)
2498     {
2499       vat_json_object_add_uint (node, "key_id",
2500                                 clib_net_to_host_u16 (mp->key_id));
2501       vat_json_object_add_string_copy (node, "key", mp->key);
2502     }
2503   vec_free (eid);
2504 }
2505
2506 static void
2507   vl_api_lisp_eid_table_map_details_t_handler
2508   (vl_api_lisp_eid_table_map_details_t * mp)
2509 {
2510   vat_main_t *vam = &vat_main;
2511
2512   u8 *line = format (0, "%=10d%=10d",
2513                      clib_net_to_host_u32 (mp->vni),
2514                      clib_net_to_host_u32 (mp->dp_table));
2515   print (vam->ofp, "%v", line);
2516   vec_free (line);
2517 }
2518
2519 static void
2520   vl_api_lisp_eid_table_map_details_t_handler_json
2521   (vl_api_lisp_eid_table_map_details_t * mp)
2522 {
2523   vat_main_t *vam = &vat_main;
2524   vat_json_node_t *node = NULL;
2525
2526   if (VAT_JSON_ARRAY != vam->json_tree.type)
2527     {
2528       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2529       vat_json_init_array (&vam->json_tree);
2530     }
2531   node = vat_json_array_add (&vam->json_tree);
2532   vat_json_init_object (node);
2533   vat_json_object_add_uint (node, "dp_table",
2534                             clib_net_to_host_u32 (mp->dp_table));
2535   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2536 }
2537
2538 static void
2539   vl_api_lisp_eid_table_vni_details_t_handler
2540   (vl_api_lisp_eid_table_vni_details_t * mp)
2541 {
2542   vat_main_t *vam = &vat_main;
2543
2544   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2545   print (vam->ofp, "%v", line);
2546   vec_free (line);
2547 }
2548
2549 static void
2550   vl_api_lisp_eid_table_vni_details_t_handler_json
2551   (vl_api_lisp_eid_table_vni_details_t * mp)
2552 {
2553   vat_main_t *vam = &vat_main;
2554   vat_json_node_t *node = NULL;
2555
2556   if (VAT_JSON_ARRAY != vam->json_tree.type)
2557     {
2558       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2559       vat_json_init_array (&vam->json_tree);
2560     }
2561   node = vat_json_array_add (&vam->json_tree);
2562   vat_json_init_object (node);
2563   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2564 }
2565
2566 static void
2567   vl_api_show_lisp_map_register_state_reply_t_handler
2568   (vl_api_show_lisp_map_register_state_reply_t * mp)
2569 {
2570   vat_main_t *vam = &vat_main;
2571   int retval = clib_net_to_host_u32 (mp->retval);
2572
2573   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2574
2575   vam->retval = retval;
2576   vam->result_ready = 1;
2577 }
2578
2579 static void
2580   vl_api_show_lisp_map_register_state_reply_t_handler_json
2581   (vl_api_show_lisp_map_register_state_reply_t * mp)
2582 {
2583   vat_main_t *vam = &vat_main;
2584   vat_json_node_t _node, *node = &_node;
2585   int retval = clib_net_to_host_u32 (mp->retval);
2586
2587   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2588
2589   vat_json_init_object (node);
2590   vat_json_object_add_string_copy (node, "state", s);
2591
2592   vat_json_print (vam->ofp, node);
2593   vat_json_free (node);
2594
2595   vam->retval = retval;
2596   vam->result_ready = 1;
2597   vec_free (s);
2598 }
2599
2600 static void
2601   vl_api_show_lisp_rloc_probe_state_reply_t_handler
2602   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2603 {
2604   vat_main_t *vam = &vat_main;
2605   int retval = clib_net_to_host_u32 (mp->retval);
2606
2607   if (retval)
2608     goto end;
2609
2610   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2611 end:
2612   vam->retval = retval;
2613   vam->result_ready = 1;
2614 }
2615
2616 static void
2617   vl_api_show_lisp_rloc_probe_state_reply_t_handler_json
2618   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2619 {
2620   vat_main_t *vam = &vat_main;
2621   vat_json_node_t _node, *node = &_node;
2622   int retval = clib_net_to_host_u32 (mp->retval);
2623
2624   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2625   vat_json_init_object (node);
2626   vat_json_object_add_string_copy (node, "state", s);
2627
2628   vat_json_print (vam->ofp, node);
2629   vat_json_free (node);
2630
2631   vam->retval = retval;
2632   vam->result_ready = 1;
2633   vec_free (s);
2634 }
2635
2636 static void
2637   vl_api_lisp_adjacencies_get_reply_t_handler
2638   (vl_api_lisp_adjacencies_get_reply_t * mp)
2639 {
2640   vat_main_t *vam = &vat_main;
2641   u32 i, n;
2642   int retval = clib_net_to_host_u32 (mp->retval);
2643   vl_api_lisp_adjacency_t *a;
2644
2645   if (retval)
2646     goto end;
2647
2648   n = clib_net_to_host_u32 (mp->count);
2649
2650   for (i = 0; i < n; i++)
2651     {
2652       a = &mp->adjacencies[i];
2653       print (vam->ofp, "%U %40U",
2654              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2655              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2656     }
2657
2658 end:
2659   vam->retval = retval;
2660   vam->result_ready = 1;
2661 }
2662
2663 static void
2664   vl_api_lisp_adjacencies_get_reply_t_handler_json
2665   (vl_api_lisp_adjacencies_get_reply_t * mp)
2666 {
2667   u8 *s = 0;
2668   vat_main_t *vam = &vat_main;
2669   vat_json_node_t *e = 0, root;
2670   u32 i, n;
2671   int retval = clib_net_to_host_u32 (mp->retval);
2672   vl_api_lisp_adjacency_t *a;
2673
2674   if (retval)
2675     goto end;
2676
2677   n = clib_net_to_host_u32 (mp->count);
2678   vat_json_init_array (&root);
2679
2680   for (i = 0; i < n; i++)
2681     {
2682       e = vat_json_array_add (&root);
2683       a = &mp->adjacencies[i];
2684
2685       vat_json_init_object (e);
2686       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2687                   a->leid_prefix_len);
2688       vec_add1 (s, 0);
2689       vat_json_object_add_string_copy (e, "leid", s);
2690       vec_free (s);
2691
2692       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2693                   a->reid_prefix_len);
2694       vec_add1 (s, 0);
2695       vat_json_object_add_string_copy (e, "reid", s);
2696       vec_free (s);
2697     }
2698
2699   vat_json_print (vam->ofp, &root);
2700   vat_json_free (&root);
2701
2702 end:
2703   vam->retval = retval;
2704   vam->result_ready = 1;
2705 }
2706
2707 static void
2708 vl_api_lisp_map_server_details_t_handler (vl_api_lisp_map_server_details_t
2709                                           * mp)
2710 {
2711   vat_main_t *vam = &vat_main;
2712
2713   print (vam->ofp, "%=20U",
2714          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2715          mp->ip_address);
2716 }
2717
2718 static void
2719   vl_api_lisp_map_server_details_t_handler_json
2720   (vl_api_lisp_map_server_details_t * mp)
2721 {
2722   vat_main_t *vam = &vat_main;
2723   vat_json_node_t *node = NULL;
2724   struct in6_addr ip6;
2725   struct in_addr ip4;
2726
2727   if (VAT_JSON_ARRAY != vam->json_tree.type)
2728     {
2729       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2730       vat_json_init_array (&vam->json_tree);
2731     }
2732   node = vat_json_array_add (&vam->json_tree);
2733
2734   vat_json_init_object (node);
2735   if (mp->is_ipv6)
2736     {
2737       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2738       vat_json_object_add_ip6 (node, "map-server", ip6);
2739     }
2740   else
2741     {
2742       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2743       vat_json_object_add_ip4 (node, "map-server", ip4);
2744     }
2745 }
2746
2747 static void
2748 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2749                                             * mp)
2750 {
2751   vat_main_t *vam = &vat_main;
2752
2753   print (vam->ofp, "%=20U",
2754          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2755          mp->ip_address);
2756 }
2757
2758 static void
2759   vl_api_lisp_map_resolver_details_t_handler_json
2760   (vl_api_lisp_map_resolver_details_t * mp)
2761 {
2762   vat_main_t *vam = &vat_main;
2763   vat_json_node_t *node = NULL;
2764   struct in6_addr ip6;
2765   struct in_addr ip4;
2766
2767   if (VAT_JSON_ARRAY != vam->json_tree.type)
2768     {
2769       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2770       vat_json_init_array (&vam->json_tree);
2771     }
2772   node = vat_json_array_add (&vam->json_tree);
2773
2774   vat_json_init_object (node);
2775   if (mp->is_ipv6)
2776     {
2777       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2778       vat_json_object_add_ip6 (node, "map resolver", ip6);
2779     }
2780   else
2781     {
2782       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2783       vat_json_object_add_ip4 (node, "map resolver", ip4);
2784     }
2785 }
2786
2787 static void
2788   vl_api_show_lisp_status_reply_t_handler
2789   (vl_api_show_lisp_status_reply_t * mp)
2790 {
2791   vat_main_t *vam = &vat_main;
2792   i32 retval = ntohl (mp->retval);
2793
2794   if (0 <= retval)
2795     {
2796       print (vam->ofp, "feature: %s\ngpe: %s",
2797              mp->feature_status ? "enabled" : "disabled",
2798              mp->gpe_status ? "enabled" : "disabled");
2799     }
2800
2801   vam->retval = retval;
2802   vam->result_ready = 1;
2803 }
2804
2805 static void
2806   vl_api_show_lisp_status_reply_t_handler_json
2807   (vl_api_show_lisp_status_reply_t * mp)
2808 {
2809   vat_main_t *vam = &vat_main;
2810   vat_json_node_t node;
2811   u8 *gpe_status = NULL;
2812   u8 *feature_status = NULL;
2813
2814   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2815   feature_status = format (0, "%s",
2816                            mp->feature_status ? "enabled" : "disabled");
2817   vec_add1 (gpe_status, 0);
2818   vec_add1 (feature_status, 0);
2819
2820   vat_json_init_object (&node);
2821   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2822   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2823
2824   vec_free (gpe_status);
2825   vec_free (feature_status);
2826
2827   vat_json_print (vam->ofp, &node);
2828   vat_json_free (&node);
2829
2830   vam->retval = ntohl (mp->retval);
2831   vam->result_ready = 1;
2832 }
2833
2834 static void
2835   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2836   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2837 {
2838   vat_main_t *vam = &vat_main;
2839   i32 retval = ntohl (mp->retval);
2840
2841   if (retval >= 0)
2842     {
2843       print (vam->ofp, "%=20s", mp->locator_set_name);
2844     }
2845
2846   vam->retval = retval;
2847   vam->result_ready = 1;
2848 }
2849
2850 static void
2851   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2852   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2853 {
2854   vat_main_t *vam = &vat_main;
2855   vat_json_node_t *node = NULL;
2856
2857   if (VAT_JSON_ARRAY != vam->json_tree.type)
2858     {
2859       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2860       vat_json_init_array (&vam->json_tree);
2861     }
2862   node = vat_json_array_add (&vam->json_tree);
2863
2864   vat_json_init_object (node);
2865   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2866
2867   vat_json_print (vam->ofp, node);
2868   vat_json_free (node);
2869
2870   vam->retval = ntohl (mp->retval);
2871   vam->result_ready = 1;
2872 }
2873
2874 static u8 *
2875 format_lisp_map_request_mode (u8 * s, va_list * args)
2876 {
2877   u32 mode = va_arg (*args, u32);
2878
2879   switch (mode)
2880     {
2881     case 0:
2882       return format (0, "dst-only");
2883     case 1:
2884       return format (0, "src-dst");
2885     }
2886   return 0;
2887 }
2888
2889 static void
2890   vl_api_show_lisp_map_request_mode_reply_t_handler
2891   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2892 {
2893   vat_main_t *vam = &vat_main;
2894   i32 retval = ntohl (mp->retval);
2895
2896   if (0 <= retval)
2897     {
2898       u32 mode = mp->mode;
2899       print (vam->ofp, "map_request_mode: %U",
2900              format_lisp_map_request_mode, mode);
2901     }
2902
2903   vam->retval = retval;
2904   vam->result_ready = 1;
2905 }
2906
2907 static void
2908   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2909   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2910 {
2911   vat_main_t *vam = &vat_main;
2912   vat_json_node_t node;
2913   u8 *s = 0;
2914   u32 mode;
2915
2916   mode = mp->mode;
2917   s = format (0, "%U", format_lisp_map_request_mode, mode);
2918   vec_add1 (s, 0);
2919
2920   vat_json_init_object (&node);
2921   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2922   vat_json_print (vam->ofp, &node);
2923   vat_json_free (&node);
2924
2925   vec_free (s);
2926   vam->retval = ntohl (mp->retval);
2927   vam->result_ready = 1;
2928 }
2929
2930 static void
2931 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2932 {
2933   vat_main_t *vam = &vat_main;
2934   i32 retval = ntohl (mp->retval);
2935
2936   if (0 <= retval)
2937     {
2938       print (vam->ofp, "%-20s%-16s",
2939              mp->status ? "enabled" : "disabled",
2940              mp->status ? (char *) mp->locator_set_name : "");
2941     }
2942
2943   vam->retval = retval;
2944   vam->result_ready = 1;
2945 }
2946
2947 static void
2948 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2949                                             mp)
2950 {
2951   vat_main_t *vam = &vat_main;
2952   vat_json_node_t node;
2953   u8 *status = 0;
2954
2955   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2956   vec_add1 (status, 0);
2957
2958   vat_json_init_object (&node);
2959   vat_json_object_add_string_copy (&node, "status", status);
2960   if (mp->status)
2961     {
2962       vat_json_object_add_string_copy (&node, "locator_set",
2963                                        mp->locator_set_name);
2964     }
2965
2966   vec_free (status);
2967
2968   vat_json_print (vam->ofp, &node);
2969   vat_json_free (&node);
2970
2971   vam->retval = ntohl (mp->retval);
2972   vam->result_ready = 1;
2973 }
2974
2975 static u8 *
2976 format_policer_type (u8 * s, va_list * va)
2977 {
2978   u32 i = va_arg (*va, u32);
2979
2980   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2981     s = format (s, "1r2c");
2982   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2983     s = format (s, "1r3c");
2984   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2985     s = format (s, "2r3c-2698");
2986   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2987     s = format (s, "2r3c-4115");
2988   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2989     s = format (s, "2r3c-mef5cf1");
2990   else
2991     s = format (s, "ILLEGAL");
2992   return s;
2993 }
2994
2995 static u8 *
2996 format_policer_rate_type (u8 * s, va_list * va)
2997 {
2998   u32 i = va_arg (*va, u32);
2999
3000   if (i == SSE2_QOS_RATE_KBPS)
3001     s = format (s, "kbps");
3002   else if (i == SSE2_QOS_RATE_PPS)
3003     s = format (s, "pps");
3004   else
3005     s = format (s, "ILLEGAL");
3006   return s;
3007 }
3008
3009 static u8 *
3010 format_policer_round_type (u8 * s, va_list * va)
3011 {
3012   u32 i = va_arg (*va, u32);
3013
3014   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3015     s = format (s, "closest");
3016   else if (i == SSE2_QOS_ROUND_TO_UP)
3017     s = format (s, "up");
3018   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3019     s = format (s, "down");
3020   else
3021     s = format (s, "ILLEGAL");
3022   return s;
3023 }
3024
3025 static u8 *
3026 format_policer_action_type (u8 * s, va_list * va)
3027 {
3028   u32 i = va_arg (*va, u32);
3029
3030   if (i == SSE2_QOS_ACTION_DROP)
3031     s = format (s, "drop");
3032   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3033     s = format (s, "transmit");
3034   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3035     s = format (s, "mark-and-transmit");
3036   else
3037     s = format (s, "ILLEGAL");
3038   return s;
3039 }
3040
3041 static u8 *
3042 format_dscp (u8 * s, va_list * va)
3043 {
3044   u32 i = va_arg (*va, u32);
3045   char *t = 0;
3046
3047   switch (i)
3048     {
3049 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3050       foreach_vnet_dscp
3051 #undef _
3052     default:
3053       return format (s, "ILLEGAL");
3054     }
3055   s = format (s, "%s", t);
3056   return s;
3057 }
3058
3059 static void
3060 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3061 {
3062   vat_main_t *vam = &vat_main;
3063   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3064
3065   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3066     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3067   else
3068     conform_dscp_str = format (0, "");
3069
3070   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3071     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3072   else
3073     exceed_dscp_str = format (0, "");
3074
3075   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3076     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3077   else
3078     violate_dscp_str = format (0, "");
3079
3080   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3081          "rate type %U, round type %U, %s rate, %s color-aware, "
3082          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3083          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3084          "conform action %U%s, exceed action %U%s, violate action %U%s",
3085          mp->name,
3086          format_policer_type, mp->type,
3087          ntohl (mp->cir),
3088          ntohl (mp->eir),
3089          clib_net_to_host_u64 (mp->cb),
3090          clib_net_to_host_u64 (mp->eb),
3091          format_policer_rate_type, mp->rate_type,
3092          format_policer_round_type, mp->round_type,
3093          mp->single_rate ? "single" : "dual",
3094          mp->color_aware ? "is" : "not",
3095          ntohl (mp->cir_tokens_per_period),
3096          ntohl (mp->pir_tokens_per_period),
3097          ntohl (mp->scale),
3098          ntohl (mp->current_limit),
3099          ntohl (mp->current_bucket),
3100          ntohl (mp->extended_limit),
3101          ntohl (mp->extended_bucket),
3102          clib_net_to_host_u64 (mp->last_update_time),
3103          format_policer_action_type, mp->conform_action_type,
3104          conform_dscp_str,
3105          format_policer_action_type, mp->exceed_action_type,
3106          exceed_dscp_str,
3107          format_policer_action_type, mp->violate_action_type,
3108          violate_dscp_str);
3109
3110   vec_free (conform_dscp_str);
3111   vec_free (exceed_dscp_str);
3112   vec_free (violate_dscp_str);
3113 }
3114
3115 static void vl_api_policer_details_t_handler_json
3116   (vl_api_policer_details_t * mp)
3117 {
3118   vat_main_t *vam = &vat_main;
3119   vat_json_node_t *node;
3120   u8 *rate_type_str, *round_type_str, *type_str;
3121   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3122
3123   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3124   round_type_str =
3125     format (0, "%U", format_policer_round_type, mp->round_type);
3126   type_str = format (0, "%U", format_policer_type, mp->type);
3127   conform_action_str = format (0, "%U", format_policer_action_type,
3128                                mp->conform_action_type);
3129   exceed_action_str = format (0, "%U", format_policer_action_type,
3130                               mp->exceed_action_type);
3131   violate_action_str = format (0, "%U", format_policer_action_type,
3132                                mp->violate_action_type);
3133
3134   if (VAT_JSON_ARRAY != vam->json_tree.type)
3135     {
3136       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3137       vat_json_init_array (&vam->json_tree);
3138     }
3139   node = vat_json_array_add (&vam->json_tree);
3140
3141   vat_json_init_object (node);
3142   vat_json_object_add_string_copy (node, "name", mp->name);
3143   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3144   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3145   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3146   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3147   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3148   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3149   vat_json_object_add_string_copy (node, "type", type_str);
3150   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3151   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3152   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3153   vat_json_object_add_uint (node, "cir_tokens_per_period",
3154                             ntohl (mp->cir_tokens_per_period));
3155   vat_json_object_add_uint (node, "eir_tokens_per_period",
3156                             ntohl (mp->pir_tokens_per_period));
3157   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3158   vat_json_object_add_uint (node, "current_bucket",
3159                             ntohl (mp->current_bucket));
3160   vat_json_object_add_uint (node, "extended_limit",
3161                             ntohl (mp->extended_limit));
3162   vat_json_object_add_uint (node, "extended_bucket",
3163                             ntohl (mp->extended_bucket));
3164   vat_json_object_add_uint (node, "last_update_time",
3165                             ntohl (mp->last_update_time));
3166   vat_json_object_add_string_copy (node, "conform_action",
3167                                    conform_action_str);
3168   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3169     {
3170       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3171       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3172       vec_free (dscp_str);
3173     }
3174   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3175   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3176     {
3177       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3178       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3179       vec_free (dscp_str);
3180     }
3181   vat_json_object_add_string_copy (node, "violate_action",
3182                                    violate_action_str);
3183   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3184     {
3185       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3186       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3187       vec_free (dscp_str);
3188     }
3189
3190   vec_free (rate_type_str);
3191   vec_free (round_type_str);
3192   vec_free (type_str);
3193   vec_free (conform_action_str);
3194   vec_free (exceed_action_str);
3195   vec_free (violate_action_str);
3196 }
3197
3198 static void
3199 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3200                                            mp)
3201 {
3202   vat_main_t *vam = &vat_main;
3203   int i, count = ntohl (mp->count);
3204
3205   if (count > 0)
3206     print (vam->ofp, "classify table ids (%d) : ", count);
3207   for (i = 0; i < count; i++)
3208     {
3209       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3210       print (vam->ofp, (i < count - 1) ? "," : "");
3211     }
3212   vam->retval = ntohl (mp->retval);
3213   vam->result_ready = 1;
3214 }
3215
3216 static void
3217   vl_api_classify_table_ids_reply_t_handler_json
3218   (vl_api_classify_table_ids_reply_t * mp)
3219 {
3220   vat_main_t *vam = &vat_main;
3221   int i, count = ntohl (mp->count);
3222
3223   if (count > 0)
3224     {
3225       vat_json_node_t node;
3226
3227       vat_json_init_object (&node);
3228       for (i = 0; i < count; i++)
3229         {
3230           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3231         }
3232       vat_json_print (vam->ofp, &node);
3233       vat_json_free (&node);
3234     }
3235   vam->retval = ntohl (mp->retval);
3236   vam->result_ready = 1;
3237 }
3238
3239 static void
3240   vl_api_classify_table_by_interface_reply_t_handler
3241   (vl_api_classify_table_by_interface_reply_t * mp)
3242 {
3243   vat_main_t *vam = &vat_main;
3244   u32 table_id;
3245
3246   table_id = ntohl (mp->l2_table_id);
3247   if (table_id != ~0)
3248     print (vam->ofp, "l2 table id : %d", table_id);
3249   else
3250     print (vam->ofp, "l2 table id : No input ACL tables configured");
3251   table_id = ntohl (mp->ip4_table_id);
3252   if (table_id != ~0)
3253     print (vam->ofp, "ip4 table id : %d", table_id);
3254   else
3255     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3256   table_id = ntohl (mp->ip6_table_id);
3257   if (table_id != ~0)
3258     print (vam->ofp, "ip6 table id : %d", table_id);
3259   else
3260     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3261   vam->retval = ntohl (mp->retval);
3262   vam->result_ready = 1;
3263 }
3264
3265 static void
3266   vl_api_classify_table_by_interface_reply_t_handler_json
3267   (vl_api_classify_table_by_interface_reply_t * mp)
3268 {
3269   vat_main_t *vam = &vat_main;
3270   vat_json_node_t node;
3271
3272   vat_json_init_object (&node);
3273
3274   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3275   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3276   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3277
3278   vat_json_print (vam->ofp, &node);
3279   vat_json_free (&node);
3280
3281   vam->retval = ntohl (mp->retval);
3282   vam->result_ready = 1;
3283 }
3284
3285 static void vl_api_policer_add_del_reply_t_handler
3286   (vl_api_policer_add_del_reply_t * mp)
3287 {
3288   vat_main_t *vam = &vat_main;
3289   i32 retval = ntohl (mp->retval);
3290   if (vam->async_mode)
3291     {
3292       vam->async_errors += (retval < 0);
3293     }
3294   else
3295     {
3296       vam->retval = retval;
3297       vam->result_ready = 1;
3298       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3299         /*
3300          * Note: this is just barely thread-safe, depends on
3301          * the main thread spinning waiting for an answer...
3302          */
3303         errmsg ("policer index %d", ntohl (mp->policer_index));
3304     }
3305 }
3306
3307 static void vl_api_policer_add_del_reply_t_handler_json
3308   (vl_api_policer_add_del_reply_t * mp)
3309 {
3310   vat_main_t *vam = &vat_main;
3311   vat_json_node_t node;
3312
3313   vat_json_init_object (&node);
3314   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3315   vat_json_object_add_uint (&node, "policer_index",
3316                             ntohl (mp->policer_index));
3317
3318   vat_json_print (vam->ofp, &node);
3319   vat_json_free (&node);
3320
3321   vam->retval = ntohl (mp->retval);
3322   vam->result_ready = 1;
3323 }
3324
3325 /* Format hex dump. */
3326 u8 *
3327 format_hex_bytes (u8 * s, va_list * va)
3328 {
3329   u8 *bytes = va_arg (*va, u8 *);
3330   int n_bytes = va_arg (*va, int);
3331   uword i;
3332
3333   /* Print short or long form depending on byte count. */
3334   uword short_form = n_bytes <= 32;
3335   uword indent = format_get_indent (s);
3336
3337   if (n_bytes == 0)
3338     return s;
3339
3340   for (i = 0; i < n_bytes; i++)
3341     {
3342       if (!short_form && (i % 32) == 0)
3343         s = format (s, "%08x: ", i);
3344       s = format (s, "%02x", bytes[i]);
3345       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3346         s = format (s, "\n%U", format_white_space, indent);
3347     }
3348
3349   return s;
3350 }
3351
3352 static void
3353 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3354                                             * mp)
3355 {
3356   vat_main_t *vam = &vat_main;
3357   i32 retval = ntohl (mp->retval);
3358   if (retval == 0)
3359     {
3360       print (vam->ofp, "classify table info :");
3361       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3362              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3363              ntohl (mp->miss_next_index));
3364       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3365              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3366              ntohl (mp->match_n_vectors));
3367       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3368              ntohl (mp->mask_length));
3369     }
3370   vam->retval = retval;
3371   vam->result_ready = 1;
3372 }
3373
3374 static void
3375   vl_api_classify_table_info_reply_t_handler_json
3376   (vl_api_classify_table_info_reply_t * mp)
3377 {
3378   vat_main_t *vam = &vat_main;
3379   vat_json_node_t node;
3380
3381   i32 retval = ntohl (mp->retval);
3382   if (retval == 0)
3383     {
3384       vat_json_init_object (&node);
3385
3386       vat_json_object_add_int (&node, "sessions",
3387                                ntohl (mp->active_sessions));
3388       vat_json_object_add_int (&node, "nexttbl",
3389                                ntohl (mp->next_table_index));
3390       vat_json_object_add_int (&node, "nextnode",
3391                                ntohl (mp->miss_next_index));
3392       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3393       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3394       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3395       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3396                       ntohl (mp->mask_length), 0);
3397       vat_json_object_add_string_copy (&node, "mask", s);
3398
3399       vat_json_print (vam->ofp, &node);
3400       vat_json_free (&node);
3401     }
3402   vam->retval = ntohl (mp->retval);
3403   vam->result_ready = 1;
3404 }
3405
3406 static void
3407 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3408                                            mp)
3409 {
3410   vat_main_t *vam = &vat_main;
3411
3412   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3413          ntohl (mp->hit_next_index), ntohl (mp->advance),
3414          ntohl (mp->opaque_index));
3415   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3416          ntohl (mp->match_length));
3417 }
3418
3419 static void
3420   vl_api_classify_session_details_t_handler_json
3421   (vl_api_classify_session_details_t * mp)
3422 {
3423   vat_main_t *vam = &vat_main;
3424   vat_json_node_t *node = NULL;
3425
3426   if (VAT_JSON_ARRAY != vam->json_tree.type)
3427     {
3428       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3429       vat_json_init_array (&vam->json_tree);
3430     }
3431   node = vat_json_array_add (&vam->json_tree);
3432
3433   vat_json_init_object (node);
3434   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3435   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3436   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3437   u8 *s =
3438     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3439             0);
3440   vat_json_object_add_string_copy (node, "match", s);
3441 }
3442
3443 static void vl_api_pg_create_interface_reply_t_handler
3444   (vl_api_pg_create_interface_reply_t * mp)
3445 {
3446   vat_main_t *vam = &vat_main;
3447
3448   vam->retval = ntohl (mp->retval);
3449   vam->result_ready = 1;
3450 }
3451
3452 static void vl_api_pg_create_interface_reply_t_handler_json
3453   (vl_api_pg_create_interface_reply_t * mp)
3454 {
3455   vat_main_t *vam = &vat_main;
3456   vat_json_node_t node;
3457
3458   i32 retval = ntohl (mp->retval);
3459   if (retval == 0)
3460     {
3461       vat_json_init_object (&node);
3462
3463       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3464
3465       vat_json_print (vam->ofp, &node);
3466       vat_json_free (&node);
3467     }
3468   vam->retval = ntohl (mp->retval);
3469   vam->result_ready = 1;
3470 }
3471
3472 static void vl_api_policer_classify_details_t_handler
3473   (vl_api_policer_classify_details_t * mp)
3474 {
3475   vat_main_t *vam = &vat_main;
3476
3477   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3478          ntohl (mp->table_index));
3479 }
3480
3481 static void vl_api_policer_classify_details_t_handler_json
3482   (vl_api_policer_classify_details_t * mp)
3483 {
3484   vat_main_t *vam = &vat_main;
3485   vat_json_node_t *node;
3486
3487   if (VAT_JSON_ARRAY != vam->json_tree.type)
3488     {
3489       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3490       vat_json_init_array (&vam->json_tree);
3491     }
3492   node = vat_json_array_add (&vam->json_tree);
3493
3494   vat_json_init_object (node);
3495   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3496   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3497 }
3498
3499 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3500   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3501 {
3502   vat_main_t *vam = &vat_main;
3503   i32 retval = ntohl (mp->retval);
3504   if (vam->async_mode)
3505     {
3506       vam->async_errors += (retval < 0);
3507     }
3508   else
3509     {
3510       vam->retval = retval;
3511       vam->sw_if_index = ntohl (mp->sw_if_index);
3512       vam->result_ready = 1;
3513     }
3514 }
3515
3516 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3517   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3518 {
3519   vat_main_t *vam = &vat_main;
3520   vat_json_node_t node;
3521
3522   vat_json_init_object (&node);
3523   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3524   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3525
3526   vat_json_print (vam->ofp, &node);
3527   vat_json_free (&node);
3528
3529   vam->retval = ntohl (mp->retval);
3530   vam->result_ready = 1;
3531 }
3532
3533 static void vl_api_flow_classify_details_t_handler
3534   (vl_api_flow_classify_details_t * mp)
3535 {
3536   vat_main_t *vam = &vat_main;
3537
3538   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3539          ntohl (mp->table_index));
3540 }
3541
3542 static void vl_api_flow_classify_details_t_handler_json
3543   (vl_api_flow_classify_details_t * mp)
3544 {
3545   vat_main_t *vam = &vat_main;
3546   vat_json_node_t *node;
3547
3548   if (VAT_JSON_ARRAY != vam->json_tree.type)
3549     {
3550       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3551       vat_json_init_array (&vam->json_tree);
3552     }
3553   node = vat_json_array_add (&vam->json_tree);
3554
3555   vat_json_init_object (node);
3556   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3557   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3558 }
3559
3560
3561
3562 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3563 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3564 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3565 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3566 #define vl_api_vnet_ip4_nbr_counters_t_endian vl_noop_handler
3567 #define vl_api_vnet_ip4_nbr_counters_t_print vl_noop_handler
3568 #define vl_api_vnet_ip6_nbr_counters_t_endian vl_noop_handler
3569 #define vl_api_vnet_ip6_nbr_counters_t_print vl_noop_handler
3570 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3571 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3572
3573 /*
3574  * Generate boilerplate reply handlers, which
3575  * dig the return value out of the xxx_reply_t API message,
3576  * stick it into vam->retval, and set vam->result_ready
3577  *
3578  * Could also do this by pointing N message decode slots at
3579  * a single function, but that could break in subtle ways.
3580  */
3581
3582 #define foreach_standard_reply_retval_handler           \
3583 _(sw_interface_set_flags_reply)                         \
3584 _(sw_interface_add_del_address_reply)                   \
3585 _(sw_interface_set_table_reply)                         \
3586 _(sw_interface_set_mpls_enable_reply)                   \
3587 _(sw_interface_set_vpath_reply)                         \
3588 _(sw_interface_set_vxlan_bypass_reply)                  \
3589 _(sw_interface_set_l2_bridge_reply)                     \
3590 _(bridge_domain_add_del_reply)                          \
3591 _(sw_interface_set_l2_xconnect_reply)                   \
3592 _(l2fib_add_del_reply)                                  \
3593 _(ip_add_del_route_reply)                               \
3594 _(mpls_route_add_del_reply)                             \
3595 _(mpls_ip_bind_unbind_reply)                            \
3596 _(proxy_arp_add_del_reply)                              \
3597 _(proxy_arp_intfc_enable_disable_reply)                 \
3598 _(sw_interface_set_unnumbered_reply)                    \
3599 _(ip_neighbor_add_del_reply)                            \
3600 _(reset_vrf_reply)                                      \
3601 _(oam_add_del_reply)                                    \
3602 _(reset_fib_reply)                                      \
3603 _(dhcp_proxy_config_reply)                              \
3604 _(dhcp_proxy_config_2_reply)                            \
3605 _(dhcp_proxy_set_vss_reply)                             \
3606 _(dhcp_client_config_reply)                             \
3607 _(set_ip_flow_hash_reply)                               \
3608 _(sw_interface_ip6_enable_disable_reply)                \
3609 _(sw_interface_ip6_set_link_local_address_reply)        \
3610 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3611 _(sw_interface_ip6nd_ra_config_reply)                   \
3612 _(set_arp_neighbor_limit_reply)                         \
3613 _(l2_patch_add_del_reply)                               \
3614 _(sr_tunnel_add_del_reply)                              \
3615 _(sr_policy_add_del_reply)                              \
3616 _(sr_multicast_map_add_del_reply)                       \
3617 _(classify_add_del_session_reply)                       \
3618 _(classify_set_interface_ip_table_reply)                \
3619 _(classify_set_interface_l2_tables_reply)               \
3620 _(l2tpv3_set_tunnel_cookies_reply)                      \
3621 _(l2tpv3_interface_enable_disable_reply)                \
3622 _(l2tpv3_set_lookup_key_reply)                          \
3623 _(l2_fib_clear_table_reply)                             \
3624 _(l2_interface_efp_filter_reply)                        \
3625 _(l2_interface_vlan_tag_rewrite_reply)                  \
3626 _(modify_vhost_user_if_reply)                           \
3627 _(delete_vhost_user_if_reply)                           \
3628 _(want_ip4_arp_events_reply)                            \
3629 _(want_ip6_nd_events_reply)                             \
3630 _(input_acl_set_interface_reply)                        \
3631 _(ipsec_spd_add_del_reply)                              \
3632 _(ipsec_interface_add_del_spd_reply)                    \
3633 _(ipsec_spd_add_del_entry_reply)                        \
3634 _(ipsec_sad_add_del_entry_reply)                        \
3635 _(ipsec_sa_set_key_reply)                               \
3636 _(ikev2_profile_add_del_reply)                          \
3637 _(ikev2_profile_set_auth_reply)                         \
3638 _(ikev2_profile_set_id_reply)                           \
3639 _(ikev2_profile_set_ts_reply)                           \
3640 _(ikev2_set_local_key_reply)                            \
3641 _(delete_loopback_reply)                                \
3642 _(bd_ip_mac_add_del_reply)                              \
3643 _(map_del_domain_reply)                                 \
3644 _(map_add_del_rule_reply)                               \
3645 _(want_interface_events_reply)                          \
3646 _(want_stats_reply)                                     \
3647 _(cop_interface_enable_disable_reply)                   \
3648 _(cop_whitelist_enable_disable_reply)                   \
3649 _(sw_interface_clear_stats_reply)                       \
3650 _(ioam_enable_reply)                              \
3651 _(ioam_disable_reply)                              \
3652 _(lisp_add_del_locator_reply)                           \
3653 _(lisp_add_del_local_eid_reply)                         \
3654 _(lisp_add_del_remote_mapping_reply)                    \
3655 _(lisp_add_del_adjacency_reply)                         \
3656 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3657 _(lisp_add_del_map_resolver_reply)                      \
3658 _(lisp_add_del_map_server_reply)                        \
3659 _(lisp_gpe_enable_disable_reply)                        \
3660 _(lisp_gpe_add_del_iface_reply)                         \
3661 _(lisp_enable_disable_reply)                            \
3662 _(lisp_rloc_probe_enable_disable_reply)                 \
3663 _(lisp_map_register_enable_disable_reply)               \
3664 _(lisp_pitr_set_locator_set_reply)                      \
3665 _(lisp_map_request_mode_reply)                          \
3666 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3667 _(lisp_eid_table_add_del_map_reply)                     \
3668 _(vxlan_gpe_add_del_tunnel_reply)                       \
3669 _(af_packet_delete_reply)                               \
3670 _(policer_classify_set_interface_reply)                 \
3671 _(netmap_create_reply)                                  \
3672 _(netmap_delete_reply)                                  \
3673 _(set_ipfix_exporter_reply)                             \
3674 _(set_ipfix_classify_stream_reply)                      \
3675 _(ipfix_classify_table_add_del_reply)                   \
3676 _(flow_classify_set_interface_reply)                    \
3677 _(sw_interface_span_enable_disable_reply)               \
3678 _(pg_capture_reply)                                     \
3679 _(pg_enable_disable_reply)                              \
3680 _(ip_source_and_port_range_check_add_del_reply)         \
3681 _(ip_source_and_port_range_check_interface_add_del_reply)\
3682 _(delete_subif_reply)                                   \
3683 _(l2_interface_pbb_tag_rewrite_reply)                   \
3684 _(punt_reply)                                           \
3685 _(feature_enable_disable_reply)                         \
3686 _(sw_interface_tag_add_del_reply)                       \
3687 _(sw_interface_set_mtu_reply)
3688
3689 #if DPDK > 0
3690 #define foreach_standard_dpdk_reply_retval_handler      \
3691 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3692 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3693 _(sw_interface_set_dpdk_hqos_tctbl_reply)
3694 #endif
3695
3696 #define _(n)                                    \
3697     static void vl_api_##n##_t_handler          \
3698     (vl_api_##n##_t * mp)                       \
3699     {                                           \
3700         vat_main_t * vam = &vat_main;           \
3701         i32 retval = ntohl(mp->retval);         \
3702         if (vam->async_mode) {                  \
3703             vam->async_errors += (retval < 0);  \
3704         } else {                                \
3705             vam->retval = retval;               \
3706             vam->result_ready = 1;              \
3707         }                                       \
3708     }
3709 foreach_standard_reply_retval_handler;
3710 #undef _
3711
3712 #define _(n)                                    \
3713     static void vl_api_##n##_t_handler_json     \
3714     (vl_api_##n##_t * mp)                       \
3715     {                                           \
3716         vat_main_t * vam = &vat_main;           \
3717         vat_json_node_t node;                   \
3718         vat_json_init_object(&node);            \
3719         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3720         vat_json_print(vam->ofp, &node);        \
3721         vam->retval = ntohl(mp->retval);        \
3722         vam->result_ready = 1;                  \
3723     }
3724 foreach_standard_reply_retval_handler;
3725 #undef _
3726
3727 #if DPDK > 0
3728 #define _(n)                                    \
3729     static void vl_api_##n##_t_handler          \
3730     (vl_api_##n##_t * mp)                       \
3731     {                                           \
3732         vat_main_t * vam = &vat_main;           \
3733         i32 retval = ntohl(mp->retval);         \
3734         if (vam->async_mode) {                  \
3735             vam->async_errors += (retval < 0);  \
3736         } else {                                \
3737             vam->retval = retval;               \
3738             vam->result_ready = 1;              \
3739         }                                       \
3740     }
3741 foreach_standard_dpdk_reply_retval_handler;
3742 #undef _
3743
3744 #define _(n)                                    \
3745     static void vl_api_##n##_t_handler_json     \
3746     (vl_api_##n##_t * mp)                       \
3747     {                                           \
3748         vat_main_t * vam = &vat_main;           \
3749         vat_json_node_t node;                   \
3750         vat_json_init_object(&node);            \
3751         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3752         vat_json_print(vam->ofp, &node);        \
3753         vam->retval = ntohl(mp->retval);        \
3754         vam->result_ready = 1;                  \
3755     }
3756 foreach_standard_dpdk_reply_retval_handler;
3757 #undef _
3758 #endif
3759
3760 /*
3761  * Table of message reply handlers, must include boilerplate handlers
3762  * we just generated
3763  */
3764
3765 #define foreach_vpe_api_reply_msg                                       \
3766 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3767 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3768 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3769 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3770 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3771 _(CLI_REPLY, cli_reply)                                                 \
3772 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3773 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3774   sw_interface_add_del_address_reply)                                   \
3775 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3776 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3777 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3778 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3779 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3780   sw_interface_set_l2_xconnect_reply)                                   \
3781 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3782   sw_interface_set_l2_bridge_reply)                                     \
3783 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3784 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3785 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3786 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3787 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3788 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3789 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3790 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3791 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3792 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3793 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3794 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3795 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3796 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3797 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3798   proxy_arp_intfc_enable_disable_reply)                                 \
3799 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
3800 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3801   sw_interface_set_unnumbered_reply)                                    \
3802 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3803 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3804 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3805 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3806 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3807 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3808 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3809 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3810 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3811 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3812 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3813 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3814   sw_interface_ip6_enable_disable_reply)                                \
3815 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3816   sw_interface_ip6_set_link_local_address_reply)                        \
3817 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3818   sw_interface_ip6nd_ra_prefix_reply)                                   \
3819 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3820   sw_interface_ip6nd_ra_config_reply)                                   \
3821 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3822 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3823 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3824 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3825 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3826 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3827 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3828 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3829 classify_set_interface_ip_table_reply)                                  \
3830 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3831   classify_set_interface_l2_tables_reply)                               \
3832 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3833 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3834 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3835 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3836 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3837   l2tpv3_interface_enable_disable_reply)                                \
3838 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3839 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3840 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3841 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3842 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3843 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3844 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3845 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3846 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3847 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3848 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3849 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3850 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3851 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3852 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3853 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3854 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3855 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3856 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3857 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3858 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3859 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3860 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3861 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3862 _(IP_DETAILS, ip_details)                                               \
3863 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3864 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3865 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3866 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3867 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3868 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3869 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3870 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3871 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3872 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3873 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3874 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3875 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3876 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3877 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3878 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3879 _(VNET_IP4_NBR_COUNTERS, vnet_ip4_nbr_counters)                         \
3880 _(VNET_IP6_NBR_COUNTERS, vnet_ip6_nbr_counters)                         \
3881 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3882 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3883 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3884 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3885 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3886 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3887 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3888 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3889 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3890 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3891 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3892 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3893 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3894 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3895 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3896 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3897 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3898 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3899 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3900 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3901 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3902 _(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply)         \
3903 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3904 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3905 _(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY,                               \
3906   lisp_map_register_enable_disable_reply)                               \
3907 _(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                 \
3908   lisp_rloc_probe_enable_disable_reply)                                 \
3909 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3910 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3911 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3912 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3913 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3914 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3915 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3916 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3917 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3918 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3919 _(LISP_MAP_SERVER_DETAILS, lisp_map_server_details)                     \
3920 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3921 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3922 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3923   lisp_add_del_map_request_itr_rlocs_reply)                             \
3924 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3925   lisp_get_map_request_itr_rlocs_reply)                                 \
3926 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3927 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3928 _(SHOW_LISP_RLOC_PROBE_STATE_REPLY, show_lisp_rloc_probe_state_reply)   \
3929 _(SHOW_LISP_MAP_REGISTER_STATE_REPLY,                                   \
3930   show_lisp_map_register_state_reply)                                   \
3931 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3932 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3933 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3934 _(POLICER_DETAILS, policer_details)                                     \
3935 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3936 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3937 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3938 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3939 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
3940 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3941 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3942 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3943 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3944 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3945 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3946 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3947 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3948 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3949 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3950 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3951 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3952 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3953 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3954 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3955 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3956 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3957 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3958 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3959 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3960  ip_source_and_port_range_check_add_del_reply)                          \
3961 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3962  ip_source_and_port_range_check_interface_add_del_reply)                \
3963 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3964 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3965 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3966 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3967 _(PUNT_REPLY, punt_reply)                                               \
3968 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3969 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3970 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
3971 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
3972 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
3973 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
3974 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
3975 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
3976
3977 #if DPDK > 0
3978 #define foreach_vpe_dpdk_api_reply_msg                                  \
3979 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3980   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3981 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3982   sw_interface_set_dpdk_hqos_subport_reply)                             \
3983 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3984   sw_interface_set_dpdk_hqos_tctbl_reply)
3985 #endif
3986
3987 typedef struct
3988 {
3989   u8 *name;
3990   u32 value;
3991 } name_sort_t;
3992
3993
3994 #define STR_VTR_OP_CASE(op)     \
3995     case L2_VTR_ ## op:         \
3996         return "" # op;
3997
3998 static const char *
3999 str_vtr_op (u32 vtr_op)
4000 {
4001   switch (vtr_op)
4002     {
4003       STR_VTR_OP_CASE (DISABLED);
4004       STR_VTR_OP_CASE (PUSH_1);
4005       STR_VTR_OP_CASE (PUSH_2);
4006       STR_VTR_OP_CASE (POP_1);
4007       STR_VTR_OP_CASE (POP_2);
4008       STR_VTR_OP_CASE (TRANSLATE_1_1);
4009       STR_VTR_OP_CASE (TRANSLATE_1_2);
4010       STR_VTR_OP_CASE (TRANSLATE_2_1);
4011       STR_VTR_OP_CASE (TRANSLATE_2_2);
4012     }
4013
4014   return "UNKNOWN";
4015 }
4016
4017 static int
4018 dump_sub_interface_table (vat_main_t * vam)
4019 {
4020   const sw_interface_subif_t *sub = NULL;
4021
4022   if (vam->json_output)
4023     {
4024       clib_warning
4025         ("JSON output supported only for VPE API calls and dump_stats_table");
4026       return -99;
4027     }
4028
4029   print (vam->ofp,
4030          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4031          "Interface", "sw_if_index",
4032          "sub id", "dot1ad", "tags", "outer id",
4033          "inner id", "exact", "default", "outer any", "inner any");
4034
4035   vec_foreach (sub, vam->sw_if_subif_table)
4036   {
4037     print (vam->ofp,
4038            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4039            sub->interface_name,
4040            sub->sw_if_index,
4041            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4042            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4043            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4044            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4045     if (sub->vtr_op != L2_VTR_DISABLED)
4046       {
4047         print (vam->ofp,
4048                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4049                "tag1: %d tag2: %d ]",
4050                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4051                sub->vtr_tag1, sub->vtr_tag2);
4052       }
4053   }
4054
4055   return 0;
4056 }
4057
4058 static int
4059 name_sort_cmp (void *a1, void *a2)
4060 {
4061   name_sort_t *n1 = a1;
4062   name_sort_t *n2 = a2;
4063
4064   return strcmp ((char *) n1->name, (char *) n2->name);
4065 }
4066
4067 static int
4068 dump_interface_table (vat_main_t * vam)
4069 {
4070   hash_pair_t *p;
4071   name_sort_t *nses = 0, *ns;
4072
4073   if (vam->json_output)
4074     {
4075       clib_warning
4076         ("JSON output supported only for VPE API calls and dump_stats_table");
4077       return -99;
4078     }
4079
4080   /* *INDENT-OFF* */
4081   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4082   ({
4083     vec_add2 (nses, ns, 1);
4084     ns->name = (u8 *)(p->key);
4085     ns->value = (u32) p->value[0];
4086   }));
4087   /* *INDENT-ON* */
4088
4089   vec_sort_with_function (nses, name_sort_cmp);
4090
4091   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4092   vec_foreach (ns, nses)
4093   {
4094     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4095   }
4096   vec_free (nses);
4097   return 0;
4098 }
4099
4100 static int
4101 dump_ip_table (vat_main_t * vam, int is_ipv6)
4102 {
4103   const ip_details_t *det = NULL;
4104   const ip_address_details_t *address = NULL;
4105   u32 i = ~0;
4106
4107   print (vam->ofp, "%-12s", "sw_if_index");
4108
4109   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4110   {
4111     i++;
4112     if (!det->present)
4113       {
4114         continue;
4115       }
4116     print (vam->ofp, "%-12d", i);
4117     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4118     if (!det->addr)
4119       {
4120         continue;
4121       }
4122     vec_foreach (address, det->addr)
4123     {
4124       print (vam->ofp,
4125              "            %-30U%-13d",
4126              is_ipv6 ? format_ip6_address : format_ip4_address,
4127              address->ip, address->prefix_length);
4128     }
4129   }
4130
4131   return 0;
4132 }
4133
4134 static int
4135 dump_ipv4_table (vat_main_t * vam)
4136 {
4137   if (vam->json_output)
4138     {
4139       clib_warning
4140         ("JSON output supported only for VPE API calls and dump_stats_table");
4141       return -99;
4142     }
4143
4144   return dump_ip_table (vam, 0);
4145 }
4146
4147 static int
4148 dump_ipv6_table (vat_main_t * vam)
4149 {
4150   if (vam->json_output)
4151     {
4152       clib_warning
4153         ("JSON output supported only for VPE API calls and dump_stats_table");
4154       return -99;
4155     }
4156
4157   return dump_ip_table (vam, 1);
4158 }
4159
4160 static char *
4161 counter_type_to_str (u8 counter_type, u8 is_combined)
4162 {
4163   if (!is_combined)
4164     {
4165       switch (counter_type)
4166         {
4167         case VNET_INTERFACE_COUNTER_DROP:
4168           return "drop";
4169         case VNET_INTERFACE_COUNTER_PUNT:
4170           return "punt";
4171         case VNET_INTERFACE_COUNTER_IP4:
4172           return "ip4";
4173         case VNET_INTERFACE_COUNTER_IP6:
4174           return "ip6";
4175         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4176           return "rx-no-buf";
4177         case VNET_INTERFACE_COUNTER_RX_MISS:
4178           return "rx-miss";
4179         case VNET_INTERFACE_COUNTER_RX_ERROR:
4180           return "rx-error";
4181         case VNET_INTERFACE_COUNTER_TX_ERROR:
4182           return "tx-error";
4183         default:
4184           return "INVALID-COUNTER-TYPE";
4185         }
4186     }
4187   else
4188     {
4189       switch (counter_type)
4190         {
4191         case VNET_INTERFACE_COUNTER_RX:
4192           return "rx";
4193         case VNET_INTERFACE_COUNTER_TX:
4194           return "tx";
4195         default:
4196           return "INVALID-COUNTER-TYPE";
4197         }
4198     }
4199 }
4200
4201 static int
4202 dump_stats_table (vat_main_t * vam)
4203 {
4204   vat_json_node_t node;
4205   vat_json_node_t *msg_array;
4206   vat_json_node_t *msg;
4207   vat_json_node_t *counter_array;
4208   vat_json_node_t *counter;
4209   interface_counter_t c;
4210   u64 packets;
4211   ip4_fib_counter_t *c4;
4212   ip6_fib_counter_t *c6;
4213   ip4_nbr_counter_t *n4;
4214   ip6_nbr_counter_t *n6;
4215   int i, j;
4216
4217   if (!vam->json_output)
4218     {
4219       clib_warning ("dump_stats_table supported only in JSON format");
4220       return -99;
4221     }
4222
4223   vat_json_init_object (&node);
4224
4225   /* interface counters */
4226   msg_array = vat_json_object_add (&node, "interface_counters");
4227   vat_json_init_array (msg_array);
4228   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4229     {
4230       msg = vat_json_array_add (msg_array);
4231       vat_json_init_object (msg);
4232       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4233                                        (u8 *) counter_type_to_str (i, 0));
4234       vat_json_object_add_int (msg, "is_combined", 0);
4235       counter_array = vat_json_object_add (msg, "data");
4236       vat_json_init_array (counter_array);
4237       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4238         {
4239           packets = vam->simple_interface_counters[i][j];
4240           vat_json_array_add_uint (counter_array, packets);
4241         }
4242     }
4243   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4244     {
4245       msg = vat_json_array_add (msg_array);
4246       vat_json_init_object (msg);
4247       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4248                                        (u8 *) counter_type_to_str (i, 1));
4249       vat_json_object_add_int (msg, "is_combined", 1);
4250       counter_array = vat_json_object_add (msg, "data");
4251       vat_json_init_array (counter_array);
4252       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4253         {
4254           c = vam->combined_interface_counters[i][j];
4255           counter = vat_json_array_add (counter_array);
4256           vat_json_init_object (counter);
4257           vat_json_object_add_uint (counter, "packets", c.packets);
4258           vat_json_object_add_uint (counter, "bytes", c.bytes);
4259         }
4260     }
4261
4262   /* ip4 fib counters */
4263   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4264   vat_json_init_array (msg_array);
4265   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4266     {
4267       msg = vat_json_array_add (msg_array);
4268       vat_json_init_object (msg);
4269       vat_json_object_add_uint (msg, "vrf_id",
4270                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4271       counter_array = vat_json_object_add (msg, "c");
4272       vat_json_init_array (counter_array);
4273       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4274         {
4275           counter = vat_json_array_add (counter_array);
4276           vat_json_init_object (counter);
4277           c4 = &vam->ip4_fib_counters[i][j];
4278           vat_json_object_add_ip4 (counter, "address", c4->address);
4279           vat_json_object_add_uint (counter, "address_length",
4280                                     c4->address_length);
4281           vat_json_object_add_uint (counter, "packets", c4->packets);
4282           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4283         }
4284     }
4285
4286   /* ip6 fib counters */
4287   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4288   vat_json_init_array (msg_array);
4289   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4290     {
4291       msg = vat_json_array_add (msg_array);
4292       vat_json_init_object (msg);
4293       vat_json_object_add_uint (msg, "vrf_id",
4294                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4295       counter_array = vat_json_object_add (msg, "c");
4296       vat_json_init_array (counter_array);
4297       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4298         {
4299           counter = vat_json_array_add (counter_array);
4300           vat_json_init_object (counter);
4301           c6 = &vam->ip6_fib_counters[i][j];
4302           vat_json_object_add_ip6 (counter, "address", c6->address);
4303           vat_json_object_add_uint (counter, "address_length",
4304                                     c6->address_length);
4305           vat_json_object_add_uint (counter, "packets", c6->packets);
4306           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4307         }
4308     }
4309
4310   /* ip4 nbr counters */
4311   msg_array = vat_json_object_add (&node, "ip4_nbr_counters");
4312   vat_json_init_array (msg_array);
4313   for (i = 0; i < vec_len (vam->ip4_nbr_counters); i++)
4314     {
4315       msg = vat_json_array_add (msg_array);
4316       vat_json_init_object (msg);
4317       vat_json_object_add_uint (msg, "sw_if_index", i);
4318       counter_array = vat_json_object_add (msg, "c");
4319       vat_json_init_array (counter_array);
4320       for (j = 0; j < vec_len (vam->ip4_nbr_counters[i]); j++)
4321         {
4322           counter = vat_json_array_add (counter_array);
4323           vat_json_init_object (counter);
4324           n4 = &vam->ip4_nbr_counters[i][j];
4325           vat_json_object_add_ip4 (counter, "address", n4->address);
4326           vat_json_object_add_uint (counter, "link-type", n4->linkt);
4327           vat_json_object_add_uint (counter, "packets", n4->packets);
4328           vat_json_object_add_uint (counter, "bytes", n4->bytes);
4329         }
4330     }
4331
4332   /* ip6 nbr counters */
4333   msg_array = vat_json_object_add (&node, "ip6_nbr_counters");
4334   vat_json_init_array (msg_array);
4335   for (i = 0; i < vec_len (vam->ip6_nbr_counters); i++)
4336     {
4337       msg = vat_json_array_add (msg_array);
4338       vat_json_init_object (msg);
4339       vat_json_object_add_uint (msg, "sw_if_index", i);
4340       counter_array = vat_json_object_add (msg, "c");
4341       vat_json_init_array (counter_array);
4342       for (j = 0; j < vec_len (vam->ip6_nbr_counters[i]); j++)
4343         {
4344           counter = vat_json_array_add (counter_array);
4345           vat_json_init_object (counter);
4346           n6 = &vam->ip6_nbr_counters[i][j];
4347           vat_json_object_add_ip6 (counter, "address", n6->address);
4348           vat_json_object_add_uint (counter, "packets", n6->packets);
4349           vat_json_object_add_uint (counter, "bytes", n6->bytes);
4350         }
4351     }
4352
4353   vat_json_print (vam->ofp, &node);
4354   vat_json_free (&node);
4355
4356   return 0;
4357 }
4358
4359 int
4360 exec (vat_main_t * vam)
4361 {
4362   api_main_t *am = &api_main;
4363   vl_api_cli_request_t *mp;
4364   f64 timeout;
4365   void *oldheap;
4366   u8 *cmd = 0;
4367   unformat_input_t *i = vam->input;
4368
4369   if (vec_len (i->buffer) == 0)
4370     return -1;
4371
4372   if (vam->exec_mode == 0 && unformat (i, "mode"))
4373     {
4374       vam->exec_mode = 1;
4375       return 0;
4376     }
4377   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4378     {
4379       vam->exec_mode = 0;
4380       return 0;
4381     }
4382
4383
4384   M (CLI_REQUEST, cli_request);
4385
4386   /*
4387    * Copy cmd into shared memory.
4388    * In order for the CLI command to work, it
4389    * must be a vector ending in \n, not a C-string ending
4390    * in \n\0.
4391    */
4392   pthread_mutex_lock (&am->vlib_rp->mutex);
4393   oldheap = svm_push_data_heap (am->vlib_rp);
4394
4395   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4396   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4397
4398   svm_pop_heap (oldheap);
4399   pthread_mutex_unlock (&am->vlib_rp->mutex);
4400
4401   mp->cmd_in_shmem = (u64) cmd;
4402   S;
4403   timeout = vat_time_now (vam) + 10.0;
4404
4405   while (vat_time_now (vam) < timeout)
4406     {
4407       if (vam->result_ready == 1)
4408         {
4409           u8 *free_me;
4410           if (vam->shmem_result != NULL)
4411             print (vam->ofp, "%s", vam->shmem_result);
4412           pthread_mutex_lock (&am->vlib_rp->mutex);
4413           oldheap = svm_push_data_heap (am->vlib_rp);
4414
4415           free_me = (u8 *) vam->shmem_result;
4416           vec_free (free_me);
4417
4418           svm_pop_heap (oldheap);
4419           pthread_mutex_unlock (&am->vlib_rp->mutex);
4420           return 0;
4421         }
4422     }
4423   return -99;
4424 }
4425
4426 /*
4427  * Future replacement of exec() that passes CLI buffers directly in
4428  * the API messages instead of an additional shared memory area.
4429  */
4430 static int
4431 exec_inband (vat_main_t * vam)
4432 {
4433   vl_api_cli_inband_t *mp;
4434   f64 timeout;
4435   unformat_input_t *i = vam->input;
4436
4437   if (vec_len (i->buffer) == 0)
4438     return -1;
4439
4440   if (vam->exec_mode == 0 && unformat (i, "mode"))
4441     {
4442       vam->exec_mode = 1;
4443       return 0;
4444     }
4445   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4446     {
4447       vam->exec_mode = 0;
4448       return 0;
4449     }
4450
4451   /*
4452    * In order for the CLI command to work, it
4453    * must be a vector ending in \n, not a C-string ending
4454    * in \n\0.
4455    */
4456   u32 len = vec_len (vam->input->buffer);
4457   M2 (CLI_INBAND, cli_inband, len);
4458   clib_memcpy (mp->cmd, vam->input->buffer, len);
4459   mp->length = htonl (len);
4460
4461   S;
4462   W2 (print (vam->ofp, "%s", vam->cmd_reply));
4463 }
4464
4465 static int
4466 api_create_loopback (vat_main_t * vam)
4467 {
4468   unformat_input_t *i = vam->input;
4469   vl_api_create_loopback_t *mp;
4470   f64 timeout;
4471   u8 mac_address[6];
4472   u8 mac_set = 0;
4473
4474   memset (mac_address, 0, sizeof (mac_address));
4475
4476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4477     {
4478       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4479         mac_set = 1;
4480       else
4481         break;
4482     }
4483
4484   /* Construct the API message */
4485   M (CREATE_LOOPBACK, create_loopback);
4486   if (mac_set)
4487     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4488
4489   S;
4490   W;
4491 }
4492
4493 static int
4494 api_delete_loopback (vat_main_t * vam)
4495 {
4496   unformat_input_t *i = vam->input;
4497   vl_api_delete_loopback_t *mp;
4498   f64 timeout;
4499   u32 sw_if_index = ~0;
4500
4501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4502     {
4503       if (unformat (i, "sw_if_index %d", &sw_if_index))
4504         ;
4505       else
4506         break;
4507     }
4508
4509   if (sw_if_index == ~0)
4510     {
4511       errmsg ("missing sw_if_index");
4512       return -99;
4513     }
4514
4515   /* Construct the API message */
4516   M (DELETE_LOOPBACK, delete_loopback);
4517   mp->sw_if_index = ntohl (sw_if_index);
4518
4519   S;
4520   W;
4521 }
4522
4523 static int
4524 api_want_stats (vat_main_t * vam)
4525 {
4526   unformat_input_t *i = vam->input;
4527   vl_api_want_stats_t *mp;
4528   f64 timeout;
4529   int enable = -1;
4530
4531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4532     {
4533       if (unformat (i, "enable"))
4534         enable = 1;
4535       else if (unformat (i, "disable"))
4536         enable = 0;
4537       else
4538         break;
4539     }
4540
4541   if (enable == -1)
4542     {
4543       errmsg ("missing enable|disable");
4544       return -99;
4545     }
4546
4547   M (WANT_STATS, want_stats);
4548   mp->enable_disable = enable;
4549
4550   S;
4551   W;
4552 }
4553
4554 static int
4555 api_want_interface_events (vat_main_t * vam)
4556 {
4557   unformat_input_t *i = vam->input;
4558   vl_api_want_interface_events_t *mp;
4559   f64 timeout;
4560   int enable = -1;
4561
4562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4563     {
4564       if (unformat (i, "enable"))
4565         enable = 1;
4566       else if (unformat (i, "disable"))
4567         enable = 0;
4568       else
4569         break;
4570     }
4571
4572   if (enable == -1)
4573     {
4574       errmsg ("missing enable|disable");
4575       return -99;
4576     }
4577
4578   M (WANT_INTERFACE_EVENTS, want_interface_events);
4579   mp->enable_disable = enable;
4580
4581   vam->interface_event_display = enable;
4582
4583   S;
4584   W;
4585 }
4586
4587
4588 /* Note: non-static, called once to set up the initial intfc table */
4589 int
4590 api_sw_interface_dump (vat_main_t * vam)
4591 {
4592   vl_api_sw_interface_dump_t *mp;
4593   f64 timeout;
4594   hash_pair_t *p;
4595   name_sort_t *nses = 0, *ns;
4596   sw_interface_subif_t *sub = NULL;
4597
4598   /* Toss the old name table */
4599   /* *INDENT-OFF* */
4600   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4601   ({
4602     vec_add2 (nses, ns, 1);
4603     ns->name = (u8 *)(p->key);
4604     ns->value = (u32) p->value[0];
4605   }));
4606   /* *INDENT-ON* */
4607
4608   hash_free (vam->sw_if_index_by_interface_name);
4609
4610   vec_foreach (ns, nses) vec_free (ns->name);
4611
4612   vec_free (nses);
4613
4614   vec_foreach (sub, vam->sw_if_subif_table)
4615   {
4616     vec_free (sub->interface_name);
4617   }
4618   vec_free (vam->sw_if_subif_table);
4619
4620   /* recreate the interface name hash table */
4621   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4622
4623   /* Get list of ethernets */
4624   M (SW_INTERFACE_DUMP, sw_interface_dump);
4625   mp->name_filter_valid = 1;
4626   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4627   S;
4628
4629   /* and local / loopback interfaces */
4630   M (SW_INTERFACE_DUMP, sw_interface_dump);
4631   mp->name_filter_valid = 1;
4632   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4633   S;
4634
4635   /* and packet-generator interfaces */
4636   M (SW_INTERFACE_DUMP, sw_interface_dump);
4637   mp->name_filter_valid = 1;
4638   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4639   S;
4640
4641   /* and vxlan-gpe tunnel interfaces */
4642   M (SW_INTERFACE_DUMP, sw_interface_dump);
4643   mp->name_filter_valid = 1;
4644   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4645            sizeof (mp->name_filter) - 1);
4646   S;
4647
4648   /* and vxlan tunnel interfaces */
4649   M (SW_INTERFACE_DUMP, sw_interface_dump);
4650   mp->name_filter_valid = 1;
4651   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4652   S;
4653
4654   /* and host (af_packet) interfaces */
4655   M (SW_INTERFACE_DUMP, sw_interface_dump);
4656   mp->name_filter_valid = 1;
4657   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4658   S;
4659
4660   /* and l2tpv3 tunnel interfaces */
4661   M (SW_INTERFACE_DUMP, sw_interface_dump);
4662   mp->name_filter_valid = 1;
4663   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4664            sizeof (mp->name_filter) - 1);
4665   S;
4666
4667   /* and GRE tunnel interfaces */
4668   M (SW_INTERFACE_DUMP, sw_interface_dump);
4669   mp->name_filter_valid = 1;
4670   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4671   S;
4672
4673   /* and LISP-GPE interfaces */
4674   M (SW_INTERFACE_DUMP, sw_interface_dump);
4675   mp->name_filter_valid = 1;
4676   strncpy ((char *) mp->name_filter, "lisp_gpe",
4677            sizeof (mp->name_filter) - 1);
4678   S;
4679
4680   /* and IPSEC tunnel interfaces */
4681   M (SW_INTERFACE_DUMP, sw_interface_dump);
4682   mp->name_filter_valid = 1;
4683   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4684   S;
4685
4686   /* Use a control ping for synchronization */
4687   {
4688     vl_api_control_ping_t *mp;
4689     M (CONTROL_PING, control_ping);
4690     S;
4691   }
4692   W;
4693 }
4694
4695 static int
4696 api_sw_interface_set_flags (vat_main_t * vam)
4697 {
4698   unformat_input_t *i = vam->input;
4699   vl_api_sw_interface_set_flags_t *mp;
4700   f64 timeout;
4701   u32 sw_if_index;
4702   u8 sw_if_index_set = 0;
4703   u8 admin_up = 0, link_up = 0;
4704
4705   /* Parse args required to build the message */
4706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4707     {
4708       if (unformat (i, "admin-up"))
4709         admin_up = 1;
4710       else if (unformat (i, "admin-down"))
4711         admin_up = 0;
4712       else if (unformat (i, "link-up"))
4713         link_up = 1;
4714       else if (unformat (i, "link-down"))
4715         link_up = 0;
4716       else
4717         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4718         sw_if_index_set = 1;
4719       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4720         sw_if_index_set = 1;
4721       else
4722         break;
4723     }
4724
4725   if (sw_if_index_set == 0)
4726     {
4727       errmsg ("missing interface name or sw_if_index");
4728       return -99;
4729     }
4730
4731   /* Construct the API message */
4732   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4733   mp->sw_if_index = ntohl (sw_if_index);
4734   mp->admin_up_down = admin_up;
4735   mp->link_up_down = link_up;
4736
4737   /* send it... */
4738   S;
4739
4740   /* Wait for a reply, return the good/bad news... */
4741   W;
4742 }
4743
4744 static int
4745 api_sw_interface_clear_stats (vat_main_t * vam)
4746 {
4747   unformat_input_t *i = vam->input;
4748   vl_api_sw_interface_clear_stats_t *mp;
4749   f64 timeout;
4750   u32 sw_if_index;
4751   u8 sw_if_index_set = 0;
4752
4753   /* Parse args required to build the message */
4754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4755     {
4756       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4757         sw_if_index_set = 1;
4758       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4759         sw_if_index_set = 1;
4760       else
4761         break;
4762     }
4763
4764   /* Construct the API message */
4765   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4766
4767   if (sw_if_index_set == 1)
4768     mp->sw_if_index = ntohl (sw_if_index);
4769   else
4770     mp->sw_if_index = ~0;
4771
4772   /* send it... */
4773   S;
4774
4775   /* Wait for a reply, return the good/bad news... */
4776   W;
4777 }
4778
4779 #if DPDK >0
4780 static int
4781 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4782 {
4783   unformat_input_t *i = vam->input;
4784   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4785   f64 timeout;
4786   u32 sw_if_index;
4787   u8 sw_if_index_set = 0;
4788   u32 subport;
4789   u8 subport_set = 0;
4790   u32 pipe;
4791   u8 pipe_set = 0;
4792   u32 profile;
4793   u8 profile_set = 0;
4794
4795   /* Parse args required to build the message */
4796   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4797     {
4798       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4799         sw_if_index_set = 1;
4800       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4801         sw_if_index_set = 1;
4802       else if (unformat (i, "subport %u", &subport))
4803         subport_set = 1;
4804       else
4805         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4806         sw_if_index_set = 1;
4807       else if (unformat (i, "pipe %u", &pipe))
4808         pipe_set = 1;
4809       else if (unformat (i, "profile %u", &profile))
4810         profile_set = 1;
4811       else
4812         break;
4813     }
4814
4815   if (sw_if_index_set == 0)
4816     {
4817       errmsg ("missing interface name or sw_if_index");
4818       return -99;
4819     }
4820
4821   if (subport_set == 0)
4822     {
4823       errmsg ("missing subport ");
4824       return -99;
4825     }
4826
4827   if (pipe_set == 0)
4828     {
4829       errmsg ("missing pipe");
4830       return -99;
4831     }
4832
4833   if (profile_set == 0)
4834     {
4835       errmsg ("missing profile");
4836       return -99;
4837     }
4838
4839   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4840
4841   mp->sw_if_index = ntohl (sw_if_index);
4842   mp->subport = ntohl (subport);
4843   mp->pipe = ntohl (pipe);
4844   mp->profile = ntohl (profile);
4845
4846
4847   S;
4848   W;
4849   /* NOTREACHED */
4850   return 0;
4851 }
4852
4853 static int
4854 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4855 {
4856   unformat_input_t *i = vam->input;
4857   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4858   f64 timeout;
4859   u32 sw_if_index;
4860   u8 sw_if_index_set = 0;
4861   u32 subport;
4862   u8 subport_set = 0;
4863   u32 tb_rate = 1250000000;     /* 10GbE */
4864   u32 tb_size = 1000000;
4865   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4866   u32 tc_period = 10;
4867
4868   /* Parse args required to build the message */
4869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4870     {
4871       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4872         sw_if_index_set = 1;
4873       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4874         sw_if_index_set = 1;
4875       else if (unformat (i, "subport %u", &subport))
4876         subport_set = 1;
4877       else
4878         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4879         sw_if_index_set = 1;
4880       else if (unformat (i, "rate %u", &tb_rate))
4881         {
4882           u32 tc_id;
4883
4884           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4885                tc_id++)
4886             tc_rate[tc_id] = tb_rate;
4887         }
4888       else if (unformat (i, "bktsize %u", &tb_size))
4889         ;
4890       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4891         ;
4892       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4893         ;
4894       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4895         ;
4896       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4897         ;
4898       else if (unformat (i, "period %u", &tc_period))
4899         ;
4900       else
4901         break;
4902     }
4903
4904   if (sw_if_index_set == 0)
4905     {
4906       errmsg ("missing interface name or sw_if_index");
4907       return -99;
4908     }
4909
4910   if (subport_set == 0)
4911     {
4912       errmsg ("missing subport ");
4913       return -99;
4914     }
4915
4916   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4917
4918   mp->sw_if_index = ntohl (sw_if_index);
4919   mp->subport = ntohl (subport);
4920   mp->tb_rate = ntohl (tb_rate);
4921   mp->tb_size = ntohl (tb_size);
4922   mp->tc_rate[0] = ntohl (tc_rate[0]);
4923   mp->tc_rate[1] = ntohl (tc_rate[1]);
4924   mp->tc_rate[2] = ntohl (tc_rate[2]);
4925   mp->tc_rate[3] = ntohl (tc_rate[3]);
4926   mp->tc_period = ntohl (tc_period);
4927
4928   S;
4929   W;
4930   /* NOTREACHED */
4931   return 0;
4932 }
4933
4934 static int
4935 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4936 {
4937   unformat_input_t *i = vam->input;
4938   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4939   f64 timeout;
4940   u32 sw_if_index;
4941   u8 sw_if_index_set = 0;
4942   u8 entry_set = 0;
4943   u8 tc_set = 0;
4944   u8 queue_set = 0;
4945   u32 entry, tc, queue;
4946
4947   /* Parse args required to build the message */
4948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4949     {
4950       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4951         sw_if_index_set = 1;
4952       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4953         sw_if_index_set = 1;
4954       else if (unformat (i, "entry %d", &entry))
4955         entry_set = 1;
4956       else if (unformat (i, "tc %d", &tc))
4957         tc_set = 1;
4958       else if (unformat (i, "queue %d", &queue))
4959         queue_set = 1;
4960       else
4961         break;
4962     }
4963
4964   if (sw_if_index_set == 0)
4965     {
4966       errmsg ("missing interface name or sw_if_index");
4967       return -99;
4968     }
4969
4970   if (entry_set == 0)
4971     {
4972       errmsg ("missing entry ");
4973       return -99;
4974     }
4975
4976   if (tc_set == 0)
4977     {
4978       errmsg ("missing traffic class ");
4979       return -99;
4980     }
4981
4982   if (queue_set == 0)
4983     {
4984       errmsg ("missing queue ");
4985       return -99;
4986     }
4987
4988   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4989
4990   mp->sw_if_index = ntohl (sw_if_index);
4991   mp->entry = ntohl (entry);
4992   mp->tc = ntohl (tc);
4993   mp->queue = ntohl (queue);
4994
4995   S;
4996   W;
4997   /* NOTREACHED */
4998   return 0;
4999 }
5000 #endif
5001
5002 static int
5003 api_sw_interface_add_del_address (vat_main_t * vam)
5004 {
5005   unformat_input_t *i = vam->input;
5006   vl_api_sw_interface_add_del_address_t *mp;
5007   f64 timeout;
5008   u32 sw_if_index;
5009   u8 sw_if_index_set = 0;
5010   u8 is_add = 1, del_all = 0;
5011   u32 address_length = 0;
5012   u8 v4_address_set = 0;
5013   u8 v6_address_set = 0;
5014   ip4_address_t v4address;
5015   ip6_address_t v6address;
5016
5017   /* Parse args required to build the message */
5018   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5019     {
5020       if (unformat (i, "del-all"))
5021         del_all = 1;
5022       else if (unformat (i, "del"))
5023         is_add = 0;
5024       else
5025         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5026         sw_if_index_set = 1;
5027       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5028         sw_if_index_set = 1;
5029       else if (unformat (i, "%U/%d",
5030                          unformat_ip4_address, &v4address, &address_length))
5031         v4_address_set = 1;
5032       else if (unformat (i, "%U/%d",
5033                          unformat_ip6_address, &v6address, &address_length))
5034         v6_address_set = 1;
5035       else
5036         break;
5037     }
5038
5039   if (sw_if_index_set == 0)
5040     {
5041       errmsg ("missing interface name or sw_if_index");
5042       return -99;
5043     }
5044   if (v4_address_set && v6_address_set)
5045     {
5046       errmsg ("both v4 and v6 addresses set");
5047       return -99;
5048     }
5049   if (!v4_address_set && !v6_address_set && !del_all)
5050     {
5051       errmsg ("no addresses set");
5052       return -99;
5053     }
5054
5055   /* Construct the API message */
5056   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
5057
5058   mp->sw_if_index = ntohl (sw_if_index);
5059   mp->is_add = is_add;
5060   mp->del_all = del_all;
5061   if (v6_address_set)
5062     {
5063       mp->is_ipv6 = 1;
5064       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5065     }
5066   else
5067     {
5068       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5069     }
5070   mp->address_length = address_length;
5071
5072   /* send it... */
5073   S;
5074
5075   /* Wait for a reply, return good/bad news  */
5076   W;
5077 }
5078
5079 static int
5080 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5081 {
5082   unformat_input_t *i = vam->input;
5083   vl_api_sw_interface_set_mpls_enable_t *mp;
5084   f64 timeout;
5085   u32 sw_if_index;
5086   u8 sw_if_index_set = 0;
5087   u8 enable = 1;
5088
5089   /* Parse args required to build the message */
5090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5091     {
5092       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5093         sw_if_index_set = 1;
5094       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5095         sw_if_index_set = 1;
5096       else if (unformat (i, "disable"))
5097         enable = 0;
5098       else if (unformat (i, "dis"))
5099         enable = 0;
5100       else
5101         break;
5102     }
5103
5104   if (sw_if_index_set == 0)
5105     {
5106       errmsg ("missing interface name or sw_if_index");
5107       return -99;
5108     }
5109
5110   /* Construct the API message */
5111   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
5112
5113   mp->sw_if_index = ntohl (sw_if_index);
5114   mp->enable = enable;
5115
5116   /* send it... */
5117   S;
5118
5119   /* Wait for a reply... */
5120   W;
5121 }
5122
5123 static int
5124 api_sw_interface_set_table (vat_main_t * vam)
5125 {
5126   unformat_input_t *i = vam->input;
5127   vl_api_sw_interface_set_table_t *mp;
5128   f64 timeout;
5129   u32 sw_if_index, vrf_id = 0;
5130   u8 sw_if_index_set = 0;
5131   u8 is_ipv6 = 0;
5132
5133   /* Parse args required to build the message */
5134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5135     {
5136       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5137         sw_if_index_set = 1;
5138       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5139         sw_if_index_set = 1;
5140       else if (unformat (i, "vrf %d", &vrf_id))
5141         ;
5142       else if (unformat (i, "ipv6"))
5143         is_ipv6 = 1;
5144       else
5145         break;
5146     }
5147
5148   if (sw_if_index_set == 0)
5149     {
5150       errmsg ("missing interface name or sw_if_index");
5151       return -99;
5152     }
5153
5154   /* Construct the API message */
5155   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
5156
5157   mp->sw_if_index = ntohl (sw_if_index);
5158   mp->is_ipv6 = is_ipv6;
5159   mp->vrf_id = ntohl (vrf_id);
5160
5161   /* send it... */
5162   S;
5163
5164   /* Wait for a reply... */
5165   W;
5166 }
5167
5168 static void vl_api_sw_interface_get_table_reply_t_handler
5169   (vl_api_sw_interface_get_table_reply_t * mp)
5170 {
5171   vat_main_t *vam = &vat_main;
5172
5173   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5174
5175   vam->retval = ntohl (mp->retval);
5176   vam->result_ready = 1;
5177
5178 }
5179
5180 static void vl_api_sw_interface_get_table_reply_t_handler_json
5181   (vl_api_sw_interface_get_table_reply_t * mp)
5182 {
5183   vat_main_t *vam = &vat_main;
5184   vat_json_node_t node;
5185
5186   vat_json_init_object (&node);
5187   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5188   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5189
5190   vat_json_print (vam->ofp, &node);
5191   vat_json_free (&node);
5192
5193   vam->retval = ntohl (mp->retval);
5194   vam->result_ready = 1;
5195 }
5196
5197 static int
5198 api_sw_interface_get_table (vat_main_t * vam)
5199 {
5200   unformat_input_t *i = vam->input;
5201   vl_api_sw_interface_get_table_t *mp;
5202   u32 sw_if_index;
5203   u8 sw_if_index_set = 0;
5204   u8 is_ipv6 = 0;
5205   f64 timeout;
5206
5207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5208     {
5209       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5210         sw_if_index_set = 1;
5211       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5212         sw_if_index_set = 1;
5213       else if (unformat (i, "ipv6"))
5214         is_ipv6 = 1;
5215       else
5216         break;
5217     }
5218
5219   if (sw_if_index_set == 0)
5220     {
5221       errmsg ("missing interface name or sw_if_index");
5222       return -99;
5223     }
5224
5225   M (SW_INTERFACE_GET_TABLE, sw_interface_get_table);
5226   mp->sw_if_index = htonl (sw_if_index);
5227   mp->is_ipv6 = is_ipv6;
5228
5229   S;
5230   W;
5231 }
5232
5233 static int
5234 api_sw_interface_set_vpath (vat_main_t * vam)
5235 {
5236   unformat_input_t *i = vam->input;
5237   vl_api_sw_interface_set_vpath_t *mp;
5238   f64 timeout;
5239   u32 sw_if_index = 0;
5240   u8 sw_if_index_set = 0;
5241   u8 is_enable = 0;
5242
5243   /* Parse args required to build the message */
5244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5245     {
5246       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5247         sw_if_index_set = 1;
5248       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5249         sw_if_index_set = 1;
5250       else if (unformat (i, "enable"))
5251         is_enable = 1;
5252       else if (unformat (i, "disable"))
5253         is_enable = 0;
5254       else
5255         break;
5256     }
5257
5258   if (sw_if_index_set == 0)
5259     {
5260       errmsg ("missing interface name or sw_if_index");
5261       return -99;
5262     }
5263
5264   /* Construct the API message */
5265   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5266
5267   mp->sw_if_index = ntohl (sw_if_index);
5268   mp->enable = is_enable;
5269
5270   /* send it... */
5271   S;
5272
5273   /* Wait for a reply... */
5274   W;
5275 }
5276
5277 static int
5278 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5279 {
5280   unformat_input_t *i = vam->input;
5281   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5282   f64 timeout;
5283   u32 sw_if_index = 0;
5284   u8 sw_if_index_set = 0;
5285   u8 is_enable = 0;
5286   u8 is_ipv6 = 0;
5287
5288   /* Parse args required to build the message */
5289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5290     {
5291       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5292         sw_if_index_set = 1;
5293       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5294         sw_if_index_set = 1;
5295       else if (unformat (i, "enable"))
5296         is_enable = 1;
5297       else if (unformat (i, "disable"))
5298         is_enable = 0;
5299       else if (unformat (i, "ip4"))
5300         is_ipv6 = 0;
5301       else if (unformat (i, "ip6"))
5302         is_ipv6 = 1;
5303       else
5304         break;
5305     }
5306
5307   if (sw_if_index_set == 0)
5308     {
5309       errmsg ("missing interface name or sw_if_index");
5310       return -99;
5311     }
5312
5313   /* Construct the API message */
5314   M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5315
5316   mp->sw_if_index = ntohl (sw_if_index);
5317   mp->enable = is_enable;
5318   mp->is_ipv6 = is_ipv6;
5319
5320   /* send it... */
5321   S;
5322
5323   /* Wait for a reply... */
5324   W;
5325 }
5326
5327 static int
5328 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5329 {
5330   unformat_input_t *i = vam->input;
5331   vl_api_sw_interface_set_l2_xconnect_t *mp;
5332   f64 timeout;
5333   u32 rx_sw_if_index;
5334   u8 rx_sw_if_index_set = 0;
5335   u32 tx_sw_if_index;
5336   u8 tx_sw_if_index_set = 0;
5337   u8 enable = 1;
5338
5339   /* Parse args required to build the message */
5340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5341     {
5342       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5343         rx_sw_if_index_set = 1;
5344       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5345         tx_sw_if_index_set = 1;
5346       else if (unformat (i, "rx"))
5347         {
5348           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5349             {
5350               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5351                             &rx_sw_if_index))
5352                 rx_sw_if_index_set = 1;
5353             }
5354           else
5355             break;
5356         }
5357       else if (unformat (i, "tx"))
5358         {
5359           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5360             {
5361               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5362                             &tx_sw_if_index))
5363                 tx_sw_if_index_set = 1;
5364             }
5365           else
5366             break;
5367         }
5368       else if (unformat (i, "enable"))
5369         enable = 1;
5370       else if (unformat (i, "disable"))
5371         enable = 0;
5372       else
5373         break;
5374     }
5375
5376   if (rx_sw_if_index_set == 0)
5377     {
5378       errmsg ("missing rx interface name or rx_sw_if_index");
5379       return -99;
5380     }
5381
5382   if (enable && (tx_sw_if_index_set == 0))
5383     {
5384       errmsg ("missing tx interface name or tx_sw_if_index");
5385       return -99;
5386     }
5387
5388   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5389
5390   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5391   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5392   mp->enable = enable;
5393
5394   S;
5395   W;
5396   /* NOTREACHED */
5397   return 0;
5398 }
5399
5400 static int
5401 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5402 {
5403   unformat_input_t *i = vam->input;
5404   vl_api_sw_interface_set_l2_bridge_t *mp;
5405   f64 timeout;
5406   u32 rx_sw_if_index;
5407   u8 rx_sw_if_index_set = 0;
5408   u32 bd_id;
5409   u8 bd_id_set = 0;
5410   u8 bvi = 0;
5411   u32 shg = 0;
5412   u8 enable = 1;
5413
5414   /* Parse args required to build the message */
5415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5416     {
5417       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5418         rx_sw_if_index_set = 1;
5419       else if (unformat (i, "bd_id %d", &bd_id))
5420         bd_id_set = 1;
5421       else
5422         if (unformat
5423             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5424         rx_sw_if_index_set = 1;
5425       else if (unformat (i, "shg %d", &shg))
5426         ;
5427       else if (unformat (i, "bvi"))
5428         bvi = 1;
5429       else if (unformat (i, "enable"))
5430         enable = 1;
5431       else if (unformat (i, "disable"))
5432         enable = 0;
5433       else
5434         break;
5435     }
5436
5437   if (rx_sw_if_index_set == 0)
5438     {
5439       errmsg ("missing rx interface name or sw_if_index");
5440       return -99;
5441     }
5442
5443   if (enable && (bd_id_set == 0))
5444     {
5445       errmsg ("missing bridge domain");
5446       return -99;
5447     }
5448
5449   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5450
5451   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5452   mp->bd_id = ntohl (bd_id);
5453   mp->shg = (u8) shg;
5454   mp->bvi = bvi;
5455   mp->enable = enable;
5456
5457   S;
5458   W;
5459   /* NOTREACHED */
5460   return 0;
5461 }
5462
5463 static int
5464 api_bridge_domain_dump (vat_main_t * vam)
5465 {
5466   unformat_input_t *i = vam->input;
5467   vl_api_bridge_domain_dump_t *mp;
5468   f64 timeout;
5469   u32 bd_id = ~0;
5470
5471   /* Parse args required to build the message */
5472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5473     {
5474       if (unformat (i, "bd_id %d", &bd_id))
5475         ;
5476       else
5477         break;
5478     }
5479
5480   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5481   mp->bd_id = ntohl (bd_id);
5482   S;
5483
5484   /* Use a control ping for synchronization */
5485   {
5486     vl_api_control_ping_t *mp;
5487     M (CONTROL_PING, control_ping);
5488     S;
5489   }
5490
5491   W;
5492   /* NOTREACHED */
5493   return 0;
5494 }
5495
5496 static int
5497 api_bridge_domain_add_del (vat_main_t * vam)
5498 {
5499   unformat_input_t *i = vam->input;
5500   vl_api_bridge_domain_add_del_t *mp;
5501   f64 timeout;
5502   u32 bd_id = ~0;
5503   u8 is_add = 1;
5504   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5505   u32 mac_age = 0;
5506
5507   /* Parse args required to build the message */
5508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5509     {
5510       if (unformat (i, "bd_id %d", &bd_id))
5511         ;
5512       else if (unformat (i, "flood %d", &flood))
5513         ;
5514       else if (unformat (i, "uu-flood %d", &uu_flood))
5515         ;
5516       else if (unformat (i, "forward %d", &forward))
5517         ;
5518       else if (unformat (i, "learn %d", &learn))
5519         ;
5520       else if (unformat (i, "arp-term %d", &arp_term))
5521         ;
5522       else if (unformat (i, "mac-age %d", &mac_age))
5523         ;
5524       else if (unformat (i, "del"))
5525         {
5526           is_add = 0;
5527           flood = uu_flood = forward = learn = 0;
5528         }
5529       else
5530         break;
5531     }
5532
5533   if (bd_id == ~0)
5534     {
5535       errmsg ("missing bridge domain");
5536       return -99;
5537     }
5538
5539   if (mac_age > 255)
5540     {
5541       errmsg ("mac age must be less than 256 ");
5542       return -99;
5543     }
5544
5545   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5546
5547   mp->bd_id = ntohl (bd_id);
5548   mp->flood = flood;
5549   mp->uu_flood = uu_flood;
5550   mp->forward = forward;
5551   mp->learn = learn;
5552   mp->arp_term = arp_term;
5553   mp->is_add = is_add;
5554   mp->mac_age = (u8) mac_age;
5555
5556   S;
5557   W;
5558   /* NOTREACHED */
5559   return 0;
5560 }
5561
5562 static int
5563 api_l2fib_add_del (vat_main_t * vam)
5564 {
5565   unformat_input_t *i = vam->input;
5566   vl_api_l2fib_add_del_t *mp;
5567   f64 timeout;
5568   u64 mac = 0;
5569   u8 mac_set = 0;
5570   u32 bd_id;
5571   u8 bd_id_set = 0;
5572   u32 sw_if_index = ~0;
5573   u8 sw_if_index_set = 0;
5574   u8 is_add = 1;
5575   u8 static_mac = 0;
5576   u8 filter_mac = 0;
5577   u8 bvi_mac = 0;
5578   int count = 1;
5579   f64 before = 0;
5580   int j;
5581
5582   /* Parse args required to build the message */
5583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5584     {
5585       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5586         mac_set = 1;
5587       else if (unformat (i, "bd_id %d", &bd_id))
5588         bd_id_set = 1;
5589       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5590         sw_if_index_set = 1;
5591       else if (unformat (i, "sw_if"))
5592         {
5593           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5594             {
5595               if (unformat
5596                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5597                 sw_if_index_set = 1;
5598             }
5599           else
5600             break;
5601         }
5602       else if (unformat (i, "static"))
5603         static_mac = 1;
5604       else if (unformat (i, "filter"))
5605         {
5606           filter_mac = 1;
5607           static_mac = 1;
5608         }
5609       else if (unformat (i, "bvi"))
5610         {
5611           bvi_mac = 1;
5612           static_mac = 1;
5613         }
5614       else if (unformat (i, "del"))
5615         is_add = 0;
5616       else if (unformat (i, "count %d", &count))
5617         ;
5618       else
5619         break;
5620     }
5621
5622   if (mac_set == 0)
5623     {
5624       errmsg ("missing mac address");
5625       return -99;
5626     }
5627
5628   if (bd_id_set == 0)
5629     {
5630       errmsg ("missing bridge domain");
5631       return -99;
5632     }
5633
5634   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5635     {
5636       errmsg ("missing interface name or sw_if_index");
5637       return -99;
5638     }
5639
5640   if (count > 1)
5641     {
5642       /* Turn on async mode */
5643       vam->async_mode = 1;
5644       vam->async_errors = 0;
5645       before = vat_time_now (vam);
5646     }
5647
5648   for (j = 0; j < count; j++)
5649     {
5650       M (L2FIB_ADD_DEL, l2fib_add_del);
5651
5652       mp->mac = mac;
5653       mp->bd_id = ntohl (bd_id);
5654       mp->is_add = is_add;
5655
5656       if (is_add)
5657         {
5658           mp->sw_if_index = ntohl (sw_if_index);
5659           mp->static_mac = static_mac;
5660           mp->filter_mac = filter_mac;
5661           mp->bvi_mac = bvi_mac;
5662         }
5663       increment_mac_address (&mac);
5664       /* send it... */
5665       S;
5666     }
5667
5668   if (count > 1)
5669     {
5670       vl_api_control_ping_t *mp;
5671       f64 after;
5672
5673       /* Shut off async mode */
5674       vam->async_mode = 0;
5675
5676       M (CONTROL_PING, control_ping);
5677       S;
5678
5679       timeout = vat_time_now (vam) + 1.0;
5680       while (vat_time_now (vam) < timeout)
5681         if (vam->result_ready == 1)
5682           goto out;
5683       vam->retval = -99;
5684
5685     out:
5686       if (vam->retval == -99)
5687         errmsg ("timeout");
5688
5689       if (vam->async_errors > 0)
5690         {
5691           errmsg ("%d asynchronous errors", vam->async_errors);
5692           vam->retval = -98;
5693         }
5694       vam->async_errors = 0;
5695       after = vat_time_now (vam);
5696
5697       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5698              count, after - before, count / (after - before));
5699     }
5700   else
5701     {
5702       /* Wait for a reply... */
5703       W;
5704     }
5705   /* Return the good/bad news */
5706   return (vam->retval);
5707 }
5708
5709 static int
5710 api_l2_flags (vat_main_t * vam)
5711 {
5712   unformat_input_t *i = vam->input;
5713   vl_api_l2_flags_t *mp;
5714   f64 timeout;
5715   u32 sw_if_index;
5716   u32 feature_bitmap = 0;
5717   u8 sw_if_index_set = 0;
5718
5719   /* Parse args required to build the message */
5720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5721     {
5722       if (unformat (i, "sw_if_index %d", &sw_if_index))
5723         sw_if_index_set = 1;
5724       else if (unformat (i, "sw_if"))
5725         {
5726           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5727             {
5728               if (unformat
5729                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5730                 sw_if_index_set = 1;
5731             }
5732           else
5733             break;
5734         }
5735       else if (unformat (i, "learn"))
5736         feature_bitmap |= L2INPUT_FEAT_LEARN;
5737       else if (unformat (i, "forward"))
5738         feature_bitmap |= L2INPUT_FEAT_FWD;
5739       else if (unformat (i, "flood"))
5740         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5741       else if (unformat (i, "uu-flood"))
5742         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5743       else
5744         break;
5745     }
5746
5747   if (sw_if_index_set == 0)
5748     {
5749       errmsg ("missing interface name or sw_if_index");
5750       return -99;
5751     }
5752
5753   M (L2_FLAGS, l2_flags);
5754
5755   mp->sw_if_index = ntohl (sw_if_index);
5756   mp->feature_bitmap = ntohl (feature_bitmap);
5757
5758   S;
5759   W;
5760   /* NOTREACHED */
5761   return 0;
5762 }
5763
5764 static int
5765 api_bridge_flags (vat_main_t * vam)
5766 {
5767   unformat_input_t *i = vam->input;
5768   vl_api_bridge_flags_t *mp;
5769   f64 timeout;
5770   u32 bd_id;
5771   u8 bd_id_set = 0;
5772   u8 is_set = 1;
5773   u32 flags = 0;
5774
5775   /* Parse args required to build the message */
5776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5777     {
5778       if (unformat (i, "bd_id %d", &bd_id))
5779         bd_id_set = 1;
5780       else if (unformat (i, "learn"))
5781         flags |= L2_LEARN;
5782       else if (unformat (i, "forward"))
5783         flags |= L2_FWD;
5784       else if (unformat (i, "flood"))
5785         flags |= L2_FLOOD;
5786       else if (unformat (i, "uu-flood"))
5787         flags |= L2_UU_FLOOD;
5788       else if (unformat (i, "arp-term"))
5789         flags |= L2_ARP_TERM;
5790       else if (unformat (i, "off"))
5791         is_set = 0;
5792       else if (unformat (i, "disable"))
5793         is_set = 0;
5794       else
5795         break;
5796     }
5797
5798   if (bd_id_set == 0)
5799     {
5800       errmsg ("missing bridge domain");
5801       return -99;
5802     }
5803
5804   M (BRIDGE_FLAGS, bridge_flags);
5805
5806   mp->bd_id = ntohl (bd_id);
5807   mp->feature_bitmap = ntohl (flags);
5808   mp->is_set = is_set;
5809
5810   S;
5811   W;
5812   /* NOTREACHED */
5813   return 0;
5814 }
5815
5816 static int
5817 api_bd_ip_mac_add_del (vat_main_t * vam)
5818 {
5819   unformat_input_t *i = vam->input;
5820   vl_api_bd_ip_mac_add_del_t *mp;
5821   f64 timeout;
5822   u32 bd_id;
5823   u8 is_ipv6 = 0;
5824   u8 is_add = 1;
5825   u8 bd_id_set = 0;
5826   u8 ip_set = 0;
5827   u8 mac_set = 0;
5828   ip4_address_t v4addr;
5829   ip6_address_t v6addr;
5830   u8 macaddr[6];
5831
5832
5833   /* Parse args required to build the message */
5834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5835     {
5836       if (unformat (i, "bd_id %d", &bd_id))
5837         {
5838           bd_id_set++;
5839         }
5840       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5841         {
5842           ip_set++;
5843         }
5844       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5845         {
5846           ip_set++;
5847           is_ipv6++;
5848         }
5849       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5850         {
5851           mac_set++;
5852         }
5853       else if (unformat (i, "del"))
5854         is_add = 0;
5855       else
5856         break;
5857     }
5858
5859   if (bd_id_set == 0)
5860     {
5861       errmsg ("missing bridge domain");
5862       return -99;
5863     }
5864   else if (ip_set == 0)
5865     {
5866       errmsg ("missing IP address");
5867       return -99;
5868     }
5869   else if (mac_set == 0)
5870     {
5871       errmsg ("missing MAC address");
5872       return -99;
5873     }
5874
5875   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5876
5877   mp->bd_id = ntohl (bd_id);
5878   mp->is_ipv6 = is_ipv6;
5879   mp->is_add = is_add;
5880   if (is_ipv6)
5881     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5882   else
5883     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5884   clib_memcpy (mp->mac_address, macaddr, 6);
5885   S;
5886   W;
5887   /* NOTREACHED */
5888   return 0;
5889 }
5890
5891 static int
5892 api_tap_connect (vat_main_t * vam)
5893 {
5894   unformat_input_t *i = vam->input;
5895   vl_api_tap_connect_t *mp;
5896   f64 timeout;
5897   u8 mac_address[6];
5898   u8 random_mac = 1;
5899   u8 name_set = 0;
5900   u8 *tap_name;
5901   u8 *tag = 0;
5902   ip4_address_t ip4_address;
5903   u32 ip4_mask_width;
5904   int ip4_address_set = 0;
5905   ip6_address_t ip6_address;
5906   u32 ip6_mask_width;
5907   int ip6_address_set = 0;
5908
5909   memset (mac_address, 0, sizeof (mac_address));
5910
5911   /* Parse args required to build the message */
5912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5913     {
5914       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5915         {
5916           random_mac = 0;
5917         }
5918       else if (unformat (i, "random-mac"))
5919         random_mac = 1;
5920       else if (unformat (i, "tapname %s", &tap_name))
5921         name_set = 1;
5922       else if (unformat (i, "tag %s", &tag))
5923         ;
5924       else if (unformat (i, "address %U/%d",
5925                          unformat_ip4_address, &ip4_address, &ip4_mask_width))
5926         ip4_address_set = 1;
5927       else if (unformat (i, "address %U/%d",
5928                          unformat_ip6_address, &ip6_address, &ip6_mask_width))
5929         ip6_address_set = 1;
5930       else
5931         break;
5932     }
5933
5934   if (name_set == 0)
5935     {
5936       errmsg ("missing tap name");
5937       return -99;
5938     }
5939   if (vec_len (tap_name) > 63)
5940     {
5941       errmsg ("tap name too long");
5942       return -99;
5943     }
5944   vec_add1 (tap_name, 0);
5945
5946   if (vec_len (tag) > 63)
5947     {
5948       errmsg ("tag too long");
5949       return -99;
5950     }
5951
5952   /* Construct the API message */
5953   M (TAP_CONNECT, tap_connect);
5954
5955   mp->use_random_mac = random_mac;
5956   clib_memcpy (mp->mac_address, mac_address, 6);
5957   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5958   if (tag)
5959     clib_memcpy (mp->tag, tag, vec_len (tag));
5960
5961   if (ip4_address_set)
5962     {
5963       mp->ip4_address_set = 1;
5964       clib_memcpy (mp->ip4_address, &ip4_address, sizeof (mp->ip4_address));
5965       mp->ip4_mask_width = ip4_mask_width;
5966     }
5967   if (ip6_address_set)
5968     {
5969       mp->ip6_address_set = 1;
5970       clib_memcpy (mp->ip6_address, &ip6_address, sizeof (mp->ip6_address));
5971       mp->ip6_mask_width = ip6_mask_width;
5972     }
5973
5974   vec_free (tap_name);
5975   vec_free (tag);
5976
5977   /* send it... */
5978   S;
5979
5980   /* Wait for a reply... */
5981   W;
5982 }
5983
5984 static int
5985 api_tap_modify (vat_main_t * vam)
5986 {
5987   unformat_input_t *i = vam->input;
5988   vl_api_tap_modify_t *mp;
5989   f64 timeout;
5990   u8 mac_address[6];
5991   u8 random_mac = 1;
5992   u8 name_set = 0;
5993   u8 *tap_name;
5994   u32 sw_if_index = ~0;
5995   u8 sw_if_index_set = 0;
5996
5997   memset (mac_address, 0, sizeof (mac_address));
5998
5999   /* Parse args required to build the message */
6000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6001     {
6002       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6003         sw_if_index_set = 1;
6004       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6005         sw_if_index_set = 1;
6006       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6007         {
6008           random_mac = 0;
6009         }
6010       else if (unformat (i, "random-mac"))
6011         random_mac = 1;
6012       else if (unformat (i, "tapname %s", &tap_name))
6013         name_set = 1;
6014       else
6015         break;
6016     }
6017
6018   if (sw_if_index_set == 0)
6019     {
6020       errmsg ("missing vpp interface name");
6021       return -99;
6022     }
6023   if (name_set == 0)
6024     {
6025       errmsg ("missing tap name");
6026       return -99;
6027     }
6028   if (vec_len (tap_name) > 63)
6029     {
6030       errmsg ("tap name too long");
6031     }
6032   vec_add1 (tap_name, 0);
6033
6034   /* Construct the API message */
6035   M (TAP_MODIFY, tap_modify);
6036
6037   mp->use_random_mac = random_mac;
6038   mp->sw_if_index = ntohl (sw_if_index);
6039   clib_memcpy (mp->mac_address, mac_address, 6);
6040   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6041   vec_free (tap_name);
6042
6043   /* send it... */
6044   S;
6045
6046   /* Wait for a reply... */
6047   W;
6048 }
6049
6050 static int
6051 api_tap_delete (vat_main_t * vam)
6052 {
6053   unformat_input_t *i = vam->input;
6054   vl_api_tap_delete_t *mp;
6055   f64 timeout;
6056   u32 sw_if_index = ~0;
6057   u8 sw_if_index_set = 0;
6058
6059   /* Parse args required to build the message */
6060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6061     {
6062       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6063         sw_if_index_set = 1;
6064       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6065         sw_if_index_set = 1;
6066       else
6067         break;
6068     }
6069
6070   if (sw_if_index_set == 0)
6071     {
6072       errmsg ("missing vpp interface name");
6073       return -99;
6074     }
6075
6076   /* Construct the API message */
6077   M (TAP_DELETE, tap_delete);
6078
6079   mp->sw_if_index = ntohl (sw_if_index);
6080
6081   /* send it... */
6082   S;
6083
6084   /* Wait for a reply... */
6085   W;
6086 }
6087
6088 static int
6089 api_ip_add_del_route (vat_main_t * vam)
6090 {
6091   unformat_input_t *i = vam->input;
6092   vl_api_ip_add_del_route_t *mp;
6093   f64 timeout;
6094   u32 sw_if_index = ~0, vrf_id = 0;
6095   u8 is_ipv6 = 0;
6096   u8 is_local = 0, is_drop = 0;
6097   u8 is_unreach = 0, is_prohibit = 0;
6098   u8 create_vrf_if_needed = 0;
6099   u8 is_add = 1;
6100   u32 next_hop_weight = 1;
6101   u8 not_last = 0;
6102   u8 is_multipath = 0;
6103   u8 address_set = 0;
6104   u8 address_length_set = 0;
6105   u32 next_hop_table_id = 0;
6106   u32 resolve_attempts = 0;
6107   u32 dst_address_length = 0;
6108   u8 next_hop_set = 0;
6109   ip4_address_t v4_dst_address, v4_next_hop_address;
6110   ip6_address_t v6_dst_address, v6_next_hop_address;
6111   int count = 1;
6112   int j;
6113   f64 before = 0;
6114   u32 random_add_del = 0;
6115   u32 *random_vector = 0;
6116   uword *random_hash;
6117   u32 random_seed = 0xdeaddabe;
6118   u32 classify_table_index = ~0;
6119   u8 is_classify = 0;
6120   u8 resolve_host = 0, resolve_attached = 0;
6121   mpls_label_t *next_hop_out_label_stack = NULL;
6122   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6123   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6124
6125   /* Parse args required to build the message */
6126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6127     {
6128       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6129         ;
6130       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6131         ;
6132       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6133         {
6134           address_set = 1;
6135           is_ipv6 = 0;
6136         }
6137       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6138         {
6139           address_set = 1;
6140           is_ipv6 = 1;
6141         }
6142       else if (unformat (i, "/%d", &dst_address_length))
6143         {
6144           address_length_set = 1;
6145         }
6146
6147       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6148                                          &v4_next_hop_address))
6149         {
6150           next_hop_set = 1;
6151         }
6152       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6153                                          &v6_next_hop_address))
6154         {
6155           next_hop_set = 1;
6156         }
6157       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6158         ;
6159       else if (unformat (i, "weight %d", &next_hop_weight))
6160         ;
6161       else if (unformat (i, "drop"))
6162         {
6163           is_drop = 1;
6164         }
6165       else if (unformat (i, "null-send-unreach"))
6166         {
6167           is_unreach = 1;
6168         }
6169       else if (unformat (i, "null-send-prohibit"))
6170         {
6171           is_prohibit = 1;
6172         }
6173       else if (unformat (i, "local"))
6174         {
6175           is_local = 1;
6176         }
6177       else if (unformat (i, "classify %d", &classify_table_index))
6178         {
6179           is_classify = 1;
6180         }
6181       else if (unformat (i, "del"))
6182         is_add = 0;
6183       else if (unformat (i, "add"))
6184         is_add = 1;
6185       else if (unformat (i, "not-last"))
6186         not_last = 1;
6187       else if (unformat (i, "resolve-via-host"))
6188         resolve_host = 1;
6189       else if (unformat (i, "resolve-via-attached"))
6190         resolve_attached = 1;
6191       else if (unformat (i, "multipath"))
6192         is_multipath = 1;
6193       else if (unformat (i, "vrf %d", &vrf_id))
6194         ;
6195       else if (unformat (i, "create-vrf"))
6196         create_vrf_if_needed = 1;
6197       else if (unformat (i, "count %d", &count))
6198         ;
6199       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6200         ;
6201       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6202         ;
6203       else if (unformat (i, "out-label %d", &next_hop_out_label))
6204         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6205       else if (unformat (i, "via-label %d", &next_hop_via_label))
6206         ;
6207       else if (unformat (i, "random"))
6208         random_add_del = 1;
6209       else if (unformat (i, "seed %d", &random_seed))
6210         ;
6211       else
6212         {
6213           clib_warning ("parse error '%U'", format_unformat_error, i);
6214           return -99;
6215         }
6216     }
6217
6218   if (!next_hop_set && !is_drop && !is_local &&
6219       !is_classify && !is_unreach && !is_prohibit &&
6220       MPLS_LABEL_INVALID == next_hop_via_label)
6221     {
6222       errmsg
6223         ("next hop / local / drop / unreach / prohibit / classify not set");
6224       return -99;
6225     }
6226
6227   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6228     {
6229       errmsg ("next hop and next-hop via label set");
6230       return -99;
6231     }
6232   if (address_set == 0)
6233     {
6234       errmsg ("missing addresses");
6235       return -99;
6236     }
6237
6238   if (address_length_set == 0)
6239     {
6240       errmsg ("missing address length");
6241       return -99;
6242     }
6243
6244   /* Generate a pile of unique, random routes */
6245   if (random_add_del)
6246     {
6247       u32 this_random_address;
6248       random_hash = hash_create (count, sizeof (uword));
6249
6250       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6251       for (j = 0; j <= count; j++)
6252         {
6253           do
6254             {
6255               this_random_address = random_u32 (&random_seed);
6256               this_random_address =
6257                 clib_host_to_net_u32 (this_random_address);
6258             }
6259           while (hash_get (random_hash, this_random_address));
6260           vec_add1 (random_vector, this_random_address);
6261           hash_set (random_hash, this_random_address, 1);
6262         }
6263       hash_free (random_hash);
6264       v4_dst_address.as_u32 = random_vector[0];
6265     }
6266
6267   if (count > 1)
6268     {
6269       /* Turn on async mode */
6270       vam->async_mode = 1;
6271       vam->async_errors = 0;
6272       before = vat_time_now (vam);
6273     }
6274
6275   for (j = 0; j < count; j++)
6276     {
6277       /* Construct the API message */
6278       M2 (IP_ADD_DEL_ROUTE, ip_add_del_route,
6279           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6280
6281       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6282       mp->table_id = ntohl (vrf_id);
6283       mp->create_vrf_if_needed = create_vrf_if_needed;
6284
6285       mp->is_add = is_add;
6286       mp->is_drop = is_drop;
6287       mp->is_unreach = is_unreach;
6288       mp->is_prohibit = is_prohibit;
6289       mp->is_ipv6 = is_ipv6;
6290       mp->is_local = is_local;
6291       mp->is_classify = is_classify;
6292       mp->is_multipath = is_multipath;
6293       mp->is_resolve_host = resolve_host;
6294       mp->is_resolve_attached = resolve_attached;
6295       mp->not_last = not_last;
6296       mp->next_hop_weight = next_hop_weight;
6297       mp->dst_address_length = dst_address_length;
6298       mp->next_hop_table_id = ntohl (next_hop_table_id);
6299       mp->classify_table_index = ntohl (classify_table_index);
6300       mp->next_hop_via_label = ntohl (next_hop_via_label);
6301       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6302       if (0 != mp->next_hop_n_out_labels)
6303         {
6304           memcpy (mp->next_hop_out_label_stack,
6305                   next_hop_out_label_stack,
6306                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6307           vec_free (next_hop_out_label_stack);
6308         }
6309
6310       if (is_ipv6)
6311         {
6312           clib_memcpy (mp->dst_address, &v6_dst_address,
6313                        sizeof (v6_dst_address));
6314           if (next_hop_set)
6315             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6316                          sizeof (v6_next_hop_address));
6317           increment_v6_address (&v6_dst_address);
6318         }
6319       else
6320         {
6321           clib_memcpy (mp->dst_address, &v4_dst_address,
6322                        sizeof (v4_dst_address));
6323           if (next_hop_set)
6324             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6325                          sizeof (v4_next_hop_address));
6326           if (random_add_del)
6327             v4_dst_address.as_u32 = random_vector[j + 1];
6328           else
6329             increment_v4_address (&v4_dst_address);
6330         }
6331       /* send it... */
6332       S;
6333       /* If we receive SIGTERM, stop now... */
6334       if (vam->do_exit)
6335         break;
6336     }
6337
6338   /* When testing multiple add/del ops, use a control-ping to sync */
6339   if (count > 1)
6340     {
6341       vl_api_control_ping_t *mp;
6342       f64 after;
6343
6344       /* Shut off async mode */
6345       vam->async_mode = 0;
6346
6347       M (CONTROL_PING, control_ping);
6348       S;
6349
6350       timeout = vat_time_now (vam) + 1.0;
6351       while (vat_time_now (vam) < timeout)
6352         if (vam->result_ready == 1)
6353           goto out;
6354       vam->retval = -99;
6355
6356     out:
6357       if (vam->retval == -99)
6358         errmsg ("timeout");
6359
6360       if (vam->async_errors > 0)
6361         {
6362           errmsg ("%d asynchronous errors", vam->async_errors);
6363           vam->retval = -98;
6364         }
6365       vam->async_errors = 0;
6366       after = vat_time_now (vam);
6367
6368       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6369       if (j > 0)
6370         count = j;
6371
6372       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6373              count, after - before, count / (after - before));
6374     }
6375   else
6376     {
6377       /* Wait for a reply... */
6378       W;
6379     }
6380
6381   /* Return the good/bad news */
6382   return (vam->retval);
6383 }
6384
6385 static int
6386 api_mpls_route_add_del (vat_main_t * vam)
6387 {
6388   unformat_input_t *i = vam->input;
6389   vl_api_mpls_route_add_del_t *mp;
6390   f64 timeout;
6391   u32 sw_if_index = ~0, table_id = 0;
6392   u8 create_table_if_needed = 0;
6393   u8 is_add = 1;
6394   u32 next_hop_weight = 1;
6395   u8 is_multipath = 0;
6396   u32 next_hop_table_id = 0;
6397   u8 next_hop_set = 0;
6398   ip4_address_t v4_next_hop_address = {
6399     .as_u32 = 0,
6400   };
6401   ip6_address_t v6_next_hop_address = { {0} };
6402   int count = 1;
6403   int j;
6404   f64 before = 0;
6405   u32 classify_table_index = ~0;
6406   u8 is_classify = 0;
6407   u8 resolve_host = 0, resolve_attached = 0;
6408   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6409   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6410   mpls_label_t *next_hop_out_label_stack = NULL;
6411   mpls_label_t local_label = MPLS_LABEL_INVALID;
6412   u8 is_eos = 0;
6413   u8 next_hop_proto_is_ip4 = 1;
6414
6415   /* Parse args required to build the message */
6416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6417     {
6418       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6419         ;
6420       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6421         ;
6422       else if (unformat (i, "%d", &local_label))
6423         ;
6424       else if (unformat (i, "eos"))
6425         is_eos = 1;
6426       else if (unformat (i, "non-eos"))
6427         is_eos = 0;
6428       else if (unformat (i, "via %U", unformat_ip4_address,
6429                          &v4_next_hop_address))
6430         {
6431           next_hop_set = 1;
6432           next_hop_proto_is_ip4 = 1;
6433         }
6434       else if (unformat (i, "via %U", unformat_ip6_address,
6435                          &v6_next_hop_address))
6436         {
6437           next_hop_set = 1;
6438           next_hop_proto_is_ip4 = 0;
6439         }
6440       else if (unformat (i, "weight %d", &next_hop_weight))
6441         ;
6442       else if (unformat (i, "create-table"))
6443         create_table_if_needed = 1;
6444       else if (unformat (i, "classify %d", &classify_table_index))
6445         {
6446           is_classify = 1;
6447         }
6448       else if (unformat (i, "del"))
6449         is_add = 0;
6450       else if (unformat (i, "add"))
6451         is_add = 1;
6452       else if (unformat (i, "resolve-via-host"))
6453         resolve_host = 1;
6454       else if (unformat (i, "resolve-via-attached"))
6455         resolve_attached = 1;
6456       else if (unformat (i, "multipath"))
6457         is_multipath = 1;
6458       else if (unformat (i, "count %d", &count))
6459         ;
6460       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6461         {
6462           next_hop_set = 1;
6463           next_hop_proto_is_ip4 = 1;
6464         }
6465       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6466         {
6467           next_hop_set = 1;
6468           next_hop_proto_is_ip4 = 0;
6469         }
6470       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6471         ;
6472       else if (unformat (i, "via-label %d", &next_hop_via_label))
6473         ;
6474       else if (unformat (i, "out-label %d", &next_hop_out_label))
6475         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6476       else
6477         {
6478           clib_warning ("parse error '%U'", format_unformat_error, i);
6479           return -99;
6480         }
6481     }
6482
6483   if (!next_hop_set && !is_classify)
6484     {
6485       errmsg ("next hop / classify not set");
6486       return -99;
6487     }
6488
6489   if (MPLS_LABEL_INVALID == local_label)
6490     {
6491       errmsg ("missing label");
6492       return -99;
6493     }
6494
6495   if (count > 1)
6496     {
6497       /* Turn on async mode */
6498       vam->async_mode = 1;
6499       vam->async_errors = 0;
6500       before = vat_time_now (vam);
6501     }
6502
6503   for (j = 0; j < count; j++)
6504     {
6505       /* Construct the API message */
6506       M2 (MPLS_ROUTE_ADD_DEL, mpls_route_add_del,
6507           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6508
6509       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6510       mp->mr_table_id = ntohl (table_id);
6511       mp->mr_create_table_if_needed = create_table_if_needed;
6512
6513       mp->mr_is_add = is_add;
6514       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6515       mp->mr_is_classify = is_classify;
6516       mp->mr_is_multipath = is_multipath;
6517       mp->mr_is_resolve_host = resolve_host;
6518       mp->mr_is_resolve_attached = resolve_attached;
6519       mp->mr_next_hop_weight = next_hop_weight;
6520       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6521       mp->mr_classify_table_index = ntohl (classify_table_index);
6522       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6523       mp->mr_label = ntohl (local_label);
6524       mp->mr_eos = is_eos;
6525
6526       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6527       if (0 != mp->mr_next_hop_n_out_labels)
6528         {
6529           memcpy (mp->mr_next_hop_out_label_stack,
6530                   next_hop_out_label_stack,
6531                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6532           vec_free (next_hop_out_label_stack);
6533         }
6534
6535       if (next_hop_set)
6536         {
6537           if (next_hop_proto_is_ip4)
6538             {
6539               clib_memcpy (mp->mr_next_hop,
6540                            &v4_next_hop_address,
6541                            sizeof (v4_next_hop_address));
6542             }
6543           else
6544             {
6545               clib_memcpy (mp->mr_next_hop,
6546                            &v6_next_hop_address,
6547                            sizeof (v6_next_hop_address));
6548             }
6549         }
6550       local_label++;
6551
6552       /* send it... */
6553       S;
6554       /* If we receive SIGTERM, stop now... */
6555       if (vam->do_exit)
6556         break;
6557     }
6558
6559   /* When testing multiple add/del ops, use a control-ping to sync */
6560   if (count > 1)
6561     {
6562       vl_api_control_ping_t *mp;
6563       f64 after;
6564
6565       /* Shut off async mode */
6566       vam->async_mode = 0;
6567
6568       M (CONTROL_PING, control_ping);
6569       S;
6570
6571       timeout = vat_time_now (vam) + 1.0;
6572       while (vat_time_now (vam) < timeout)
6573         if (vam->result_ready == 1)
6574           goto out;
6575       vam->retval = -99;
6576
6577     out:
6578       if (vam->retval == -99)
6579         errmsg ("timeout");
6580
6581       if (vam->async_errors > 0)
6582         {
6583           errmsg ("%d asynchronous errors", vam->async_errors);
6584           vam->retval = -98;
6585         }
6586       vam->async_errors = 0;
6587       after = vat_time_now (vam);
6588
6589       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6590       if (j > 0)
6591         count = j;
6592
6593       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6594              count, after - before, count / (after - before));
6595     }
6596   else
6597     {
6598       /* Wait for a reply... */
6599       W;
6600     }
6601
6602   /* Return the good/bad news */
6603   return (vam->retval);
6604 }
6605
6606 static int
6607 api_mpls_ip_bind_unbind (vat_main_t * vam)
6608 {
6609   unformat_input_t *i = vam->input;
6610   vl_api_mpls_ip_bind_unbind_t *mp;
6611   f64 timeout;
6612   u32 ip_table_id = 0;
6613   u8 create_table_if_needed = 0;
6614   u8 is_bind = 1;
6615   u8 is_ip4 = 1;
6616   ip4_address_t v4_address;
6617   ip6_address_t v6_address;
6618   u32 address_length;
6619   u8 address_set = 0;
6620   mpls_label_t local_label = MPLS_LABEL_INVALID;
6621
6622   /* Parse args required to build the message */
6623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6624     {
6625       if (unformat (i, "%U/%d", unformat_ip4_address,
6626                     &v4_address, &address_length))
6627         {
6628           is_ip4 = 1;
6629           address_set = 1;
6630         }
6631       else if (unformat (i, "%U/%d", unformat_ip6_address,
6632                          &v6_address, &address_length))
6633         {
6634           is_ip4 = 0;
6635           address_set = 1;
6636         }
6637       else if (unformat (i, "%d", &local_label))
6638         ;
6639       else if (unformat (i, "create-table"))
6640         create_table_if_needed = 1;
6641       else if (unformat (i, "table-id %d", &ip_table_id))
6642         ;
6643       else if (unformat (i, "unbind"))
6644         is_bind = 0;
6645       else if (unformat (i, "bind"))
6646         is_bind = 1;
6647       else
6648         {
6649           clib_warning ("parse error '%U'", format_unformat_error, i);
6650           return -99;
6651         }
6652     }
6653
6654   if (!address_set)
6655     {
6656       errmsg ("IP addres not set");
6657       return -99;
6658     }
6659
6660   if (MPLS_LABEL_INVALID == local_label)
6661     {
6662       errmsg ("missing label");
6663       return -99;
6664     }
6665
6666   /* Construct the API message */
6667   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6668
6669   mp->mb_create_table_if_needed = create_table_if_needed;
6670   mp->mb_is_bind = is_bind;
6671   mp->mb_is_ip4 = is_ip4;
6672   mp->mb_ip_table_id = ntohl (ip_table_id);
6673   mp->mb_mpls_table_id = 0;
6674   mp->mb_label = ntohl (local_label);
6675   mp->mb_address_length = address_length;
6676
6677   if (is_ip4)
6678     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6679   else
6680     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6681
6682   /* send it... */
6683   S;
6684
6685   /* Wait for a reply... */
6686   W;
6687 }
6688
6689 static int
6690 api_proxy_arp_add_del (vat_main_t * vam)
6691 {
6692   unformat_input_t *i = vam->input;
6693   vl_api_proxy_arp_add_del_t *mp;
6694   f64 timeout;
6695   u32 vrf_id = 0;
6696   u8 is_add = 1;
6697   ip4_address_t lo, hi;
6698   u8 range_set = 0;
6699
6700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6701     {
6702       if (unformat (i, "vrf %d", &vrf_id))
6703         ;
6704       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6705                          unformat_ip4_address, &hi))
6706         range_set = 1;
6707       else if (unformat (i, "del"))
6708         is_add = 0;
6709       else
6710         {
6711           clib_warning ("parse error '%U'", format_unformat_error, i);
6712           return -99;
6713         }
6714     }
6715
6716   if (range_set == 0)
6717     {
6718       errmsg ("address range not set");
6719       return -99;
6720     }
6721
6722   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6723
6724   mp->vrf_id = ntohl (vrf_id);
6725   mp->is_add = is_add;
6726   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6727   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6728
6729   S;
6730   W;
6731   /* NOTREACHED */
6732   return 0;
6733 }
6734
6735 static int
6736 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6737 {
6738   unformat_input_t *i = vam->input;
6739   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6740   f64 timeout;
6741   u32 sw_if_index;
6742   u8 enable = 1;
6743   u8 sw_if_index_set = 0;
6744
6745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6746     {
6747       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6748         sw_if_index_set = 1;
6749       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6750         sw_if_index_set = 1;
6751       else if (unformat (i, "enable"))
6752         enable = 1;
6753       else if (unformat (i, "disable"))
6754         enable = 0;
6755       else
6756         {
6757           clib_warning ("parse error '%U'", format_unformat_error, i);
6758           return -99;
6759         }
6760     }
6761
6762   if (sw_if_index_set == 0)
6763     {
6764       errmsg ("missing interface name or sw_if_index");
6765       return -99;
6766     }
6767
6768   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6769
6770   mp->sw_if_index = ntohl (sw_if_index);
6771   mp->enable_disable = enable;
6772
6773   S;
6774   W;
6775   /* NOTREACHED */
6776   return 0;
6777 }
6778
6779 static int
6780 api_mpls_tunnel_add_del (vat_main_t * vam)
6781 {
6782   unformat_input_t *i = vam->input;
6783   vl_api_mpls_tunnel_add_del_t *mp;
6784   f64 timeout;
6785
6786   u8 is_add = 1;
6787   u8 l2_only = 0;
6788   u32 sw_if_index = ~0;
6789   u32 next_hop_sw_if_index = ~0;
6790   u32 next_hop_proto_is_ip4 = 1;
6791
6792   u32 next_hop_table_id = 0;
6793   ip4_address_t v4_next_hop_address = {
6794     .as_u32 = 0,
6795   };
6796   ip6_address_t v6_next_hop_address = { {0} };
6797   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6798
6799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6800     {
6801       if (unformat (i, "add"))
6802         is_add = 1;
6803       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6804         is_add = 0;
6805       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6806         ;
6807       else if (unformat (i, "via %U",
6808                          unformat_ip4_address, &v4_next_hop_address))
6809         {
6810           next_hop_proto_is_ip4 = 1;
6811         }
6812       else if (unformat (i, "via %U",
6813                          unformat_ip6_address, &v6_next_hop_address))
6814         {
6815           next_hop_proto_is_ip4 = 0;
6816         }
6817       else if (unformat (i, "l2-only"))
6818         l2_only = 1;
6819       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6820         ;
6821       else if (unformat (i, "out-label %d", &next_hop_out_label))
6822         vec_add1 (labels, ntohl (next_hop_out_label));
6823       else
6824         {
6825           clib_warning ("parse error '%U'", format_unformat_error, i);
6826           return -99;
6827         }
6828     }
6829
6830   M2 (MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del,
6831       sizeof (mpls_label_t) * vec_len (labels));
6832
6833   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
6834   mp->mt_sw_if_index = ntohl (sw_if_index);
6835   mp->mt_is_add = is_add;
6836   mp->mt_l2_only = l2_only;
6837   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
6838   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6839
6840   mp->mt_next_hop_n_out_labels = vec_len (labels);
6841
6842   if (0 != mp->mt_next_hop_n_out_labels)
6843     {
6844       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
6845                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
6846       vec_free (labels);
6847     }
6848
6849   if (next_hop_proto_is_ip4)
6850     {
6851       clib_memcpy (mp->mt_next_hop,
6852                    &v4_next_hop_address, sizeof (v4_next_hop_address));
6853     }
6854   else
6855     {
6856       clib_memcpy (mp->mt_next_hop,
6857                    &v6_next_hop_address, sizeof (v6_next_hop_address));
6858     }
6859
6860   S;
6861   W;
6862   /* NOTREACHED */
6863   return 0;
6864 }
6865
6866 static int
6867 api_sw_interface_set_unnumbered (vat_main_t * vam)
6868 {
6869   unformat_input_t *i = vam->input;
6870   vl_api_sw_interface_set_unnumbered_t *mp;
6871   f64 timeout;
6872   u32 sw_if_index;
6873   u32 unnum_sw_index = ~0;
6874   u8 is_add = 1;
6875   u8 sw_if_index_set = 0;
6876
6877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6878     {
6879       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6880         sw_if_index_set = 1;
6881       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6882         sw_if_index_set = 1;
6883       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6884         ;
6885       else if (unformat (i, "del"))
6886         is_add = 0;
6887       else
6888         {
6889           clib_warning ("parse error '%U'", format_unformat_error, i);
6890           return -99;
6891         }
6892     }
6893
6894   if (sw_if_index_set == 0)
6895     {
6896       errmsg ("missing interface name or sw_if_index");
6897       return -99;
6898     }
6899
6900   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6901
6902   mp->sw_if_index = ntohl (sw_if_index);
6903   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6904   mp->is_add = is_add;
6905
6906   S;
6907   W;
6908   /* NOTREACHED */
6909   return 0;
6910 }
6911
6912 static int
6913 api_ip_neighbor_add_del (vat_main_t * vam)
6914 {
6915   unformat_input_t *i = vam->input;
6916   vl_api_ip_neighbor_add_del_t *mp;
6917   f64 timeout;
6918   u32 sw_if_index;
6919   u8 sw_if_index_set = 0;
6920   u32 vrf_id = 0;
6921   u8 is_add = 1;
6922   u8 is_static = 0;
6923   u8 mac_address[6];
6924   u8 mac_set = 0;
6925   u8 v4_address_set = 0;
6926   u8 v6_address_set = 0;
6927   ip4_address_t v4address;
6928   ip6_address_t v6address;
6929
6930   memset (mac_address, 0, sizeof (mac_address));
6931
6932   /* Parse args required to build the message */
6933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6934     {
6935       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6936         {
6937           mac_set = 1;
6938         }
6939       else if (unformat (i, "del"))
6940         is_add = 0;
6941       else
6942         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6943         sw_if_index_set = 1;
6944       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6945         sw_if_index_set = 1;
6946       else if (unformat (i, "is_static"))
6947         is_static = 1;
6948       else if (unformat (i, "vrf %d", &vrf_id))
6949         ;
6950       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6951         v4_address_set = 1;
6952       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6953         v6_address_set = 1;
6954       else
6955         {
6956           clib_warning ("parse error '%U'", format_unformat_error, i);
6957           return -99;
6958         }
6959     }
6960
6961   if (sw_if_index_set == 0)
6962     {
6963       errmsg ("missing interface name or sw_if_index");
6964       return -99;
6965     }
6966   if (v4_address_set && v6_address_set)
6967     {
6968       errmsg ("both v4 and v6 addresses set");
6969       return -99;
6970     }
6971   if (!v4_address_set && !v6_address_set)
6972     {
6973       errmsg ("no address set");
6974       return -99;
6975     }
6976
6977   /* Construct the API message */
6978   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6979
6980   mp->sw_if_index = ntohl (sw_if_index);
6981   mp->is_add = is_add;
6982   mp->vrf_id = ntohl (vrf_id);
6983   mp->is_static = is_static;
6984   if (mac_set)
6985     clib_memcpy (mp->mac_address, mac_address, 6);
6986   if (v6_address_set)
6987     {
6988       mp->is_ipv6 = 1;
6989       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6990     }
6991   else
6992     {
6993       /* mp->is_ipv6 = 0; via memset in M macro above */
6994       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6995     }
6996
6997   /* send it... */
6998   S;
6999
7000   /* Wait for a reply, return good/bad news  */
7001   W;
7002
7003   /* NOTREACHED */
7004   return 0;
7005 }
7006
7007 static int
7008 api_reset_vrf (vat_main_t * vam)
7009 {
7010   unformat_input_t *i = vam->input;
7011   vl_api_reset_vrf_t *mp;
7012   f64 timeout;
7013   u32 vrf_id = 0;
7014   u8 is_ipv6 = 0;
7015   u8 vrf_id_set = 0;
7016
7017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7018     {
7019       if (unformat (i, "vrf %d", &vrf_id))
7020         vrf_id_set = 1;
7021       else if (unformat (i, "ipv6"))
7022         is_ipv6 = 1;
7023       else
7024         {
7025           clib_warning ("parse error '%U'", format_unformat_error, i);
7026           return -99;
7027         }
7028     }
7029
7030   if (vrf_id_set == 0)
7031     {
7032       errmsg ("missing vrf id");
7033       return -99;
7034     }
7035
7036   M (RESET_VRF, reset_vrf);
7037
7038   mp->vrf_id = ntohl (vrf_id);
7039   mp->is_ipv6 = is_ipv6;
7040
7041   S;
7042   W;
7043   /* NOTREACHED */
7044   return 0;
7045 }
7046
7047 static int
7048 api_create_vlan_subif (vat_main_t * vam)
7049 {
7050   unformat_input_t *i = vam->input;
7051   vl_api_create_vlan_subif_t *mp;
7052   f64 timeout;
7053   u32 sw_if_index;
7054   u8 sw_if_index_set = 0;
7055   u32 vlan_id;
7056   u8 vlan_id_set = 0;
7057
7058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7059     {
7060       if (unformat (i, "sw_if_index %d", &sw_if_index))
7061         sw_if_index_set = 1;
7062       else
7063         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7064         sw_if_index_set = 1;
7065       else if (unformat (i, "vlan %d", &vlan_id))
7066         vlan_id_set = 1;
7067       else
7068         {
7069           clib_warning ("parse error '%U'", format_unformat_error, i);
7070           return -99;
7071         }
7072     }
7073
7074   if (sw_if_index_set == 0)
7075     {
7076       errmsg ("missing interface name or sw_if_index");
7077       return -99;
7078     }
7079
7080   if (vlan_id_set == 0)
7081     {
7082       errmsg ("missing vlan_id");
7083       return -99;
7084     }
7085   M (CREATE_VLAN_SUBIF, create_vlan_subif);
7086
7087   mp->sw_if_index = ntohl (sw_if_index);
7088   mp->vlan_id = ntohl (vlan_id);
7089
7090   S;
7091   W;
7092   /* NOTREACHED */
7093   return 0;
7094 }
7095
7096 #define foreach_create_subif_bit                \
7097 _(no_tags)                                      \
7098 _(one_tag)                                      \
7099 _(two_tags)                                     \
7100 _(dot1ad)                                       \
7101 _(exact_match)                                  \
7102 _(default_sub)                                  \
7103 _(outer_vlan_id_any)                            \
7104 _(inner_vlan_id_any)
7105
7106 static int
7107 api_create_subif (vat_main_t * vam)
7108 {
7109   unformat_input_t *i = vam->input;
7110   vl_api_create_subif_t *mp;
7111   f64 timeout;
7112   u32 sw_if_index;
7113   u8 sw_if_index_set = 0;
7114   u32 sub_id;
7115   u8 sub_id_set = 0;
7116   u32 no_tags = 0;
7117   u32 one_tag = 0;
7118   u32 two_tags = 0;
7119   u32 dot1ad = 0;
7120   u32 exact_match = 0;
7121   u32 default_sub = 0;
7122   u32 outer_vlan_id_any = 0;
7123   u32 inner_vlan_id_any = 0;
7124   u32 tmp;
7125   u16 outer_vlan_id = 0;
7126   u16 inner_vlan_id = 0;
7127
7128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7129     {
7130       if (unformat (i, "sw_if_index %d", &sw_if_index))
7131         sw_if_index_set = 1;
7132       else
7133         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7134         sw_if_index_set = 1;
7135       else if (unformat (i, "sub_id %d", &sub_id))
7136         sub_id_set = 1;
7137       else if (unformat (i, "outer_vlan_id %d", &tmp))
7138         outer_vlan_id = tmp;
7139       else if (unformat (i, "inner_vlan_id %d", &tmp))
7140         inner_vlan_id = tmp;
7141
7142 #define _(a) else if (unformat (i, #a)) a = 1 ;
7143       foreach_create_subif_bit
7144 #undef _
7145         else
7146         {
7147           clib_warning ("parse error '%U'", format_unformat_error, i);
7148           return -99;
7149         }
7150     }
7151
7152   if (sw_if_index_set == 0)
7153     {
7154       errmsg ("missing interface name or sw_if_index");
7155       return -99;
7156     }
7157
7158   if (sub_id_set == 0)
7159     {
7160       errmsg ("missing sub_id");
7161       return -99;
7162     }
7163   M (CREATE_SUBIF, create_subif);
7164
7165   mp->sw_if_index = ntohl (sw_if_index);
7166   mp->sub_id = ntohl (sub_id);
7167
7168 #define _(a) mp->a = a;
7169   foreach_create_subif_bit;
7170 #undef _
7171
7172   mp->outer_vlan_id = ntohs (outer_vlan_id);
7173   mp->inner_vlan_id = ntohs (inner_vlan_id);
7174
7175   S;
7176   W;
7177   /* NOTREACHED */
7178   return 0;
7179 }
7180
7181 static int
7182 api_oam_add_del (vat_main_t * vam)
7183 {
7184   unformat_input_t *i = vam->input;
7185   vl_api_oam_add_del_t *mp;
7186   f64 timeout;
7187   u32 vrf_id = 0;
7188   u8 is_add = 1;
7189   ip4_address_t src, dst;
7190   u8 src_set = 0;
7191   u8 dst_set = 0;
7192
7193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7194     {
7195       if (unformat (i, "vrf %d", &vrf_id))
7196         ;
7197       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7198         src_set = 1;
7199       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7200         dst_set = 1;
7201       else if (unformat (i, "del"))
7202         is_add = 0;
7203       else
7204         {
7205           clib_warning ("parse error '%U'", format_unformat_error, i);
7206           return -99;
7207         }
7208     }
7209
7210   if (src_set == 0)
7211     {
7212       errmsg ("missing src addr");
7213       return -99;
7214     }
7215
7216   if (dst_set == 0)
7217     {
7218       errmsg ("missing dst addr");
7219       return -99;
7220     }
7221
7222   M (OAM_ADD_DEL, oam_add_del);
7223
7224   mp->vrf_id = ntohl (vrf_id);
7225   mp->is_add = is_add;
7226   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7227   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7228
7229   S;
7230   W;
7231   /* NOTREACHED */
7232   return 0;
7233 }
7234
7235 static int
7236 api_reset_fib (vat_main_t * vam)
7237 {
7238   unformat_input_t *i = vam->input;
7239   vl_api_reset_fib_t *mp;
7240   f64 timeout;
7241   u32 vrf_id = 0;
7242   u8 is_ipv6 = 0;
7243   u8 vrf_id_set = 0;
7244
7245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7246     {
7247       if (unformat (i, "vrf %d", &vrf_id))
7248         vrf_id_set = 1;
7249       else if (unformat (i, "ipv6"))
7250         is_ipv6 = 1;
7251       else
7252         {
7253           clib_warning ("parse error '%U'", format_unformat_error, i);
7254           return -99;
7255         }
7256     }
7257
7258   if (vrf_id_set == 0)
7259     {
7260       errmsg ("missing vrf id");
7261       return -99;
7262     }
7263
7264   M (RESET_FIB, reset_fib);
7265
7266   mp->vrf_id = ntohl (vrf_id);
7267   mp->is_ipv6 = is_ipv6;
7268
7269   S;
7270   W;
7271   /* NOTREACHED */
7272   return 0;
7273 }
7274
7275 static int
7276 api_dhcp_proxy_config (vat_main_t * vam)
7277 {
7278   unformat_input_t *i = vam->input;
7279   vl_api_dhcp_proxy_config_t *mp;
7280   f64 timeout;
7281   u32 vrf_id = 0;
7282   u8 is_add = 1;
7283   u8 insert_cid = 1;
7284   u8 v4_address_set = 0;
7285   u8 v6_address_set = 0;
7286   ip4_address_t v4address;
7287   ip6_address_t v6address;
7288   u8 v4_src_address_set = 0;
7289   u8 v6_src_address_set = 0;
7290   ip4_address_t v4srcaddress;
7291   ip6_address_t v6srcaddress;
7292
7293   /* Parse args required to build the message */
7294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7295     {
7296       if (unformat (i, "del"))
7297         is_add = 0;
7298       else if (unformat (i, "vrf %d", &vrf_id))
7299         ;
7300       else if (unformat (i, "insert-cid %d", &insert_cid))
7301         ;
7302       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7303         v4_address_set = 1;
7304       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7305         v6_address_set = 1;
7306       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7307         v4_src_address_set = 1;
7308       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7309         v6_src_address_set = 1;
7310       else
7311         break;
7312     }
7313
7314   if (v4_address_set && v6_address_set)
7315     {
7316       errmsg ("both v4 and v6 server addresses set");
7317       return -99;
7318     }
7319   if (!v4_address_set && !v6_address_set)
7320     {
7321       errmsg ("no server addresses set");
7322       return -99;
7323     }
7324
7325   if (v4_src_address_set && v6_src_address_set)
7326     {
7327       errmsg ("both v4 and v6  src addresses set");
7328       return -99;
7329     }
7330   if (!v4_src_address_set && !v6_src_address_set)
7331     {
7332       errmsg ("no src addresses set");
7333       return -99;
7334     }
7335
7336   if (!(v4_src_address_set && v4_address_set) &&
7337       !(v6_src_address_set && v6_address_set))
7338     {
7339       errmsg ("no matching server and src addresses set");
7340       return -99;
7341     }
7342
7343   /* Construct the API message */
7344   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7345
7346   mp->insert_circuit_id = insert_cid;
7347   mp->is_add = is_add;
7348   mp->vrf_id = ntohl (vrf_id);
7349   if (v6_address_set)
7350     {
7351       mp->is_ipv6 = 1;
7352       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7353       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7354     }
7355   else
7356     {
7357       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7358       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7359     }
7360
7361   /* send it... */
7362   S;
7363
7364   /* Wait for a reply, return good/bad news  */
7365   W;
7366   /* NOTREACHED */
7367   return 0;
7368 }
7369
7370 static int
7371 api_dhcp_proxy_config_2 (vat_main_t * vam)
7372 {
7373   unformat_input_t *i = vam->input;
7374   vl_api_dhcp_proxy_config_2_t *mp;
7375   f64 timeout;
7376   u32 rx_vrf_id = 0;
7377   u32 server_vrf_id = 0;
7378   u8 is_add = 1;
7379   u8 insert_cid = 1;
7380   u8 v4_address_set = 0;
7381   u8 v6_address_set = 0;
7382   ip4_address_t v4address;
7383   ip6_address_t v6address;
7384   u8 v4_src_address_set = 0;
7385   u8 v6_src_address_set = 0;
7386   ip4_address_t v4srcaddress;
7387   ip6_address_t v6srcaddress;
7388
7389   /* Parse args required to build the message */
7390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7391     {
7392       if (unformat (i, "del"))
7393         is_add = 0;
7394       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7395         ;
7396       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7397         ;
7398       else if (unformat (i, "insert-cid %d", &insert_cid))
7399         ;
7400       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7401         v4_address_set = 1;
7402       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7403         v6_address_set = 1;
7404       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7405         v4_src_address_set = 1;
7406       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7407         v6_src_address_set = 1;
7408       else
7409         break;
7410     }
7411
7412   if (v4_address_set && v6_address_set)
7413     {
7414       errmsg ("both v4 and v6 server addresses set");
7415       return -99;
7416     }
7417   if (!v4_address_set && !v6_address_set)
7418     {
7419       errmsg ("no server addresses set");
7420       return -99;
7421     }
7422
7423   if (v4_src_address_set && v6_src_address_set)
7424     {
7425       errmsg ("both v4 and v6  src addresses set");
7426       return -99;
7427     }
7428   if (!v4_src_address_set && !v6_src_address_set)
7429     {
7430       errmsg ("no src addresses set");
7431       return -99;
7432     }
7433
7434   if (!(v4_src_address_set && v4_address_set) &&
7435       !(v6_src_address_set && v6_address_set))
7436     {
7437       errmsg ("no matching server and src addresses set");
7438       return -99;
7439     }
7440
7441   /* Construct the API message */
7442   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7443
7444   mp->insert_circuit_id = insert_cid;
7445   mp->is_add = is_add;
7446   mp->rx_vrf_id = ntohl (rx_vrf_id);
7447   mp->server_vrf_id = ntohl (server_vrf_id);
7448   if (v6_address_set)
7449     {
7450       mp->is_ipv6 = 1;
7451       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7452       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7453     }
7454   else
7455     {
7456       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7457       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7458     }
7459
7460   /* send it... */
7461   S;
7462
7463   /* Wait for a reply, return good/bad news  */
7464   W;
7465   /* NOTREACHED */
7466   return 0;
7467 }
7468
7469 static int
7470 api_dhcp_proxy_set_vss (vat_main_t * vam)
7471 {
7472   unformat_input_t *i = vam->input;
7473   vl_api_dhcp_proxy_set_vss_t *mp;
7474   f64 timeout;
7475   u8 is_ipv6 = 0;
7476   u8 is_add = 1;
7477   u32 tbl_id;
7478   u8 tbl_id_set = 0;
7479   u32 oui;
7480   u8 oui_set = 0;
7481   u32 fib_id;
7482   u8 fib_id_set = 0;
7483
7484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7485     {
7486       if (unformat (i, "tbl_id %d", &tbl_id))
7487         tbl_id_set = 1;
7488       if (unformat (i, "fib_id %d", &fib_id))
7489         fib_id_set = 1;
7490       if (unformat (i, "oui %d", &oui))
7491         oui_set = 1;
7492       else if (unformat (i, "ipv6"))
7493         is_ipv6 = 1;
7494       else if (unformat (i, "del"))
7495         is_add = 0;
7496       else
7497         {
7498           clib_warning ("parse error '%U'", format_unformat_error, i);
7499           return -99;
7500         }
7501     }
7502
7503   if (tbl_id_set == 0)
7504     {
7505       errmsg ("missing tbl id");
7506       return -99;
7507     }
7508
7509   if (fib_id_set == 0)
7510     {
7511       errmsg ("missing fib id");
7512       return -99;
7513     }
7514   if (oui_set == 0)
7515     {
7516       errmsg ("missing oui");
7517       return -99;
7518     }
7519
7520   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7521   mp->tbl_id = ntohl (tbl_id);
7522   mp->fib_id = ntohl (fib_id);
7523   mp->oui = ntohl (oui);
7524   mp->is_ipv6 = is_ipv6;
7525   mp->is_add = is_add;
7526
7527   S;
7528   W;
7529   /* NOTREACHED */
7530   return 0;
7531 }
7532
7533 static int
7534 api_dhcp_client_config (vat_main_t * vam)
7535 {
7536   unformat_input_t *i = vam->input;
7537   vl_api_dhcp_client_config_t *mp;
7538   f64 timeout;
7539   u32 sw_if_index;
7540   u8 sw_if_index_set = 0;
7541   u8 is_add = 1;
7542   u8 *hostname = 0;
7543   u8 disable_event = 0;
7544
7545   /* Parse args required to build the message */
7546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7547     {
7548       if (unformat (i, "del"))
7549         is_add = 0;
7550       else
7551         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7552         sw_if_index_set = 1;
7553       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7554         sw_if_index_set = 1;
7555       else if (unformat (i, "hostname %s", &hostname))
7556         ;
7557       else if (unformat (i, "disable_event"))
7558         disable_event = 1;
7559       else
7560         break;
7561     }
7562
7563   if (sw_if_index_set == 0)
7564     {
7565       errmsg ("missing interface name or sw_if_index");
7566       return -99;
7567     }
7568
7569   if (vec_len (hostname) > 63)
7570     {
7571       errmsg ("hostname too long");
7572     }
7573   vec_add1 (hostname, 0);
7574
7575   /* Construct the API message */
7576   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7577
7578   mp->sw_if_index = ntohl (sw_if_index);
7579   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7580   vec_free (hostname);
7581   mp->is_add = is_add;
7582   mp->want_dhcp_event = disable_event ? 0 : 1;
7583   mp->pid = getpid ();
7584
7585   /* send it... */
7586   S;
7587
7588   /* Wait for a reply, return good/bad news  */
7589   W;
7590   /* NOTREACHED */
7591   return 0;
7592 }
7593
7594 static int
7595 api_set_ip_flow_hash (vat_main_t * vam)
7596 {
7597   unformat_input_t *i = vam->input;
7598   vl_api_set_ip_flow_hash_t *mp;
7599   f64 timeout;
7600   u32 vrf_id = 0;
7601   u8 is_ipv6 = 0;
7602   u8 vrf_id_set = 0;
7603   u8 src = 0;
7604   u8 dst = 0;
7605   u8 sport = 0;
7606   u8 dport = 0;
7607   u8 proto = 0;
7608   u8 reverse = 0;
7609
7610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7611     {
7612       if (unformat (i, "vrf %d", &vrf_id))
7613         vrf_id_set = 1;
7614       else if (unformat (i, "ipv6"))
7615         is_ipv6 = 1;
7616       else if (unformat (i, "src"))
7617         src = 1;
7618       else if (unformat (i, "dst"))
7619         dst = 1;
7620       else if (unformat (i, "sport"))
7621         sport = 1;
7622       else if (unformat (i, "dport"))
7623         dport = 1;
7624       else if (unformat (i, "proto"))
7625         proto = 1;
7626       else if (unformat (i, "reverse"))
7627         reverse = 1;
7628
7629       else
7630         {
7631           clib_warning ("parse error '%U'", format_unformat_error, i);
7632           return -99;
7633         }
7634     }
7635
7636   if (vrf_id_set == 0)
7637     {
7638       errmsg ("missing vrf id");
7639       return -99;
7640     }
7641
7642   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7643   mp->src = src;
7644   mp->dst = dst;
7645   mp->sport = sport;
7646   mp->dport = dport;
7647   mp->proto = proto;
7648   mp->reverse = reverse;
7649   mp->vrf_id = ntohl (vrf_id);
7650   mp->is_ipv6 = is_ipv6;
7651
7652   S;
7653   W;
7654   /* NOTREACHED */
7655   return 0;
7656 }
7657
7658 static int
7659 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7660 {
7661   unformat_input_t *i = vam->input;
7662   vl_api_sw_interface_ip6_enable_disable_t *mp;
7663   f64 timeout;
7664   u32 sw_if_index;
7665   u8 sw_if_index_set = 0;
7666   u8 enable = 0;
7667
7668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7669     {
7670       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7671         sw_if_index_set = 1;
7672       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7673         sw_if_index_set = 1;
7674       else if (unformat (i, "enable"))
7675         enable = 1;
7676       else if (unformat (i, "disable"))
7677         enable = 0;
7678       else
7679         {
7680           clib_warning ("parse error '%U'", format_unformat_error, i);
7681           return -99;
7682         }
7683     }
7684
7685   if (sw_if_index_set == 0)
7686     {
7687       errmsg ("missing interface name or sw_if_index");
7688       return -99;
7689     }
7690
7691   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7692
7693   mp->sw_if_index = ntohl (sw_if_index);
7694   mp->enable = enable;
7695
7696   S;
7697   W;
7698   /* NOTREACHED */
7699   return 0;
7700 }
7701
7702 static int
7703 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7704 {
7705   unformat_input_t *i = vam->input;
7706   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7707   f64 timeout;
7708   u32 sw_if_index;
7709   u8 sw_if_index_set = 0;
7710   u8 v6_address_set = 0;
7711   ip6_address_t v6address;
7712
7713   /* Parse args required to build the message */
7714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7715     {
7716       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7717         sw_if_index_set = 1;
7718       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7719         sw_if_index_set = 1;
7720       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
7721         v6_address_set = 1;
7722       else
7723         break;
7724     }
7725
7726   if (sw_if_index_set == 0)
7727     {
7728       errmsg ("missing interface name or sw_if_index");
7729       return -99;
7730     }
7731   if (!v6_address_set)
7732     {
7733       errmsg ("no address set");
7734       return -99;
7735     }
7736
7737   /* Construct the API message */
7738   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7739      sw_interface_ip6_set_link_local_address);
7740
7741   mp->sw_if_index = ntohl (sw_if_index);
7742   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7743
7744   /* send it... */
7745   S;
7746
7747   /* Wait for a reply, return good/bad news  */
7748   W;
7749
7750   /* NOTREACHED */
7751   return 0;
7752 }
7753
7754
7755 static int
7756 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7757 {
7758   unformat_input_t *i = vam->input;
7759   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7760   f64 timeout;
7761   u32 sw_if_index;
7762   u8 sw_if_index_set = 0;
7763   u32 address_length = 0;
7764   u8 v6_address_set = 0;
7765   ip6_address_t v6address;
7766   u8 use_default = 0;
7767   u8 no_advertise = 0;
7768   u8 off_link = 0;
7769   u8 no_autoconfig = 0;
7770   u8 no_onlink = 0;
7771   u8 is_no = 0;
7772   u32 val_lifetime = 0;
7773   u32 pref_lifetime = 0;
7774
7775   /* Parse args required to build the message */
7776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7777     {
7778       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7779         sw_if_index_set = 1;
7780       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7781         sw_if_index_set = 1;
7782       else if (unformat (i, "%U/%d",
7783                          unformat_ip6_address, &v6address, &address_length))
7784         v6_address_set = 1;
7785       else if (unformat (i, "val_life %d", &val_lifetime))
7786         ;
7787       else if (unformat (i, "pref_life %d", &pref_lifetime))
7788         ;
7789       else if (unformat (i, "def"))
7790         use_default = 1;
7791       else if (unformat (i, "noadv"))
7792         no_advertise = 1;
7793       else if (unformat (i, "offl"))
7794         off_link = 1;
7795       else if (unformat (i, "noauto"))
7796         no_autoconfig = 1;
7797       else if (unformat (i, "nolink"))
7798         no_onlink = 1;
7799       else if (unformat (i, "isno"))
7800         is_no = 1;
7801       else
7802         {
7803           clib_warning ("parse error '%U'", format_unformat_error, i);
7804           return -99;
7805         }
7806     }
7807
7808   if (sw_if_index_set == 0)
7809     {
7810       errmsg ("missing interface name or sw_if_index");
7811       return -99;
7812     }
7813   if (!v6_address_set)
7814     {
7815       errmsg ("no address set");
7816       return -99;
7817     }
7818
7819   /* Construct the API message */
7820   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7821
7822   mp->sw_if_index = ntohl (sw_if_index);
7823   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7824   mp->address_length = address_length;
7825   mp->use_default = use_default;
7826   mp->no_advertise = no_advertise;
7827   mp->off_link = off_link;
7828   mp->no_autoconfig = no_autoconfig;
7829   mp->no_onlink = no_onlink;
7830   mp->is_no = is_no;
7831   mp->val_lifetime = ntohl (val_lifetime);
7832   mp->pref_lifetime = ntohl (pref_lifetime);
7833
7834   /* send it... */
7835   S;
7836
7837   /* Wait for a reply, return good/bad news  */
7838   W;
7839
7840   /* NOTREACHED */
7841   return 0;
7842 }
7843
7844 static int
7845 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7846 {
7847   unformat_input_t *i = vam->input;
7848   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7849   f64 timeout;
7850   u32 sw_if_index;
7851   u8 sw_if_index_set = 0;
7852   u8 suppress = 0;
7853   u8 managed = 0;
7854   u8 other = 0;
7855   u8 ll_option = 0;
7856   u8 send_unicast = 0;
7857   u8 cease = 0;
7858   u8 is_no = 0;
7859   u8 default_router = 0;
7860   u32 max_interval = 0;
7861   u32 min_interval = 0;
7862   u32 lifetime = 0;
7863   u32 initial_count = 0;
7864   u32 initial_interval = 0;
7865
7866
7867   /* Parse args required to build the message */
7868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7869     {
7870       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7871         sw_if_index_set = 1;
7872       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7873         sw_if_index_set = 1;
7874       else if (unformat (i, "maxint %d", &max_interval))
7875         ;
7876       else if (unformat (i, "minint %d", &min_interval))
7877         ;
7878       else if (unformat (i, "life %d", &lifetime))
7879         ;
7880       else if (unformat (i, "count %d", &initial_count))
7881         ;
7882       else if (unformat (i, "interval %d", &initial_interval))
7883         ;
7884       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7885         suppress = 1;
7886       else if (unformat (i, "managed"))
7887         managed = 1;
7888       else if (unformat (i, "other"))
7889         other = 1;
7890       else if (unformat (i, "ll"))
7891         ll_option = 1;
7892       else if (unformat (i, "send"))
7893         send_unicast = 1;
7894       else if (unformat (i, "cease"))
7895         cease = 1;
7896       else if (unformat (i, "isno"))
7897         is_no = 1;
7898       else if (unformat (i, "def"))
7899         default_router = 1;
7900       else
7901         {
7902           clib_warning ("parse error '%U'", format_unformat_error, i);
7903           return -99;
7904         }
7905     }
7906
7907   if (sw_if_index_set == 0)
7908     {
7909       errmsg ("missing interface name or sw_if_index");
7910       return -99;
7911     }
7912
7913   /* Construct the API message */
7914   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7915
7916   mp->sw_if_index = ntohl (sw_if_index);
7917   mp->max_interval = ntohl (max_interval);
7918   mp->min_interval = ntohl (min_interval);
7919   mp->lifetime = ntohl (lifetime);
7920   mp->initial_count = ntohl (initial_count);
7921   mp->initial_interval = ntohl (initial_interval);
7922   mp->suppress = suppress;
7923   mp->managed = managed;
7924   mp->other = other;
7925   mp->ll_option = ll_option;
7926   mp->send_unicast = send_unicast;
7927   mp->cease = cease;
7928   mp->is_no = is_no;
7929   mp->default_router = default_router;
7930
7931   /* send it... */
7932   S;
7933
7934   /* Wait for a reply, return good/bad news  */
7935   W;
7936
7937   /* NOTREACHED */
7938   return 0;
7939 }
7940
7941 static int
7942 api_set_arp_neighbor_limit (vat_main_t * vam)
7943 {
7944   unformat_input_t *i = vam->input;
7945   vl_api_set_arp_neighbor_limit_t *mp;
7946   f64 timeout;
7947   u32 arp_nbr_limit;
7948   u8 limit_set = 0;
7949   u8 is_ipv6 = 0;
7950
7951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7952     {
7953       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7954         limit_set = 1;
7955       else if (unformat (i, "ipv6"))
7956         is_ipv6 = 1;
7957       else
7958         {
7959           clib_warning ("parse error '%U'", format_unformat_error, i);
7960           return -99;
7961         }
7962     }
7963
7964   if (limit_set == 0)
7965     {
7966       errmsg ("missing limit value");
7967       return -99;
7968     }
7969
7970   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7971
7972   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7973   mp->is_ipv6 = is_ipv6;
7974
7975   S;
7976   W;
7977   /* NOTREACHED */
7978   return 0;
7979 }
7980
7981 static int
7982 api_l2_patch_add_del (vat_main_t * vam)
7983 {
7984   unformat_input_t *i = vam->input;
7985   vl_api_l2_patch_add_del_t *mp;
7986   f64 timeout;
7987   u32 rx_sw_if_index;
7988   u8 rx_sw_if_index_set = 0;
7989   u32 tx_sw_if_index;
7990   u8 tx_sw_if_index_set = 0;
7991   u8 is_add = 1;
7992
7993   /* Parse args required to build the message */
7994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7995     {
7996       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7997         rx_sw_if_index_set = 1;
7998       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7999         tx_sw_if_index_set = 1;
8000       else if (unformat (i, "rx"))
8001         {
8002           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8003             {
8004               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8005                             &rx_sw_if_index))
8006                 rx_sw_if_index_set = 1;
8007             }
8008           else
8009             break;
8010         }
8011       else if (unformat (i, "tx"))
8012         {
8013           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8014             {
8015               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
8016                             &tx_sw_if_index))
8017                 tx_sw_if_index_set = 1;
8018             }
8019           else
8020             break;
8021         }
8022       else if (unformat (i, "del"))
8023         is_add = 0;
8024       else
8025         break;
8026     }
8027
8028   if (rx_sw_if_index_set == 0)
8029     {
8030       errmsg ("missing rx interface name or rx_sw_if_index");
8031       return -99;
8032     }
8033
8034   if (tx_sw_if_index_set == 0)
8035     {
8036       errmsg ("missing tx interface name or tx_sw_if_index");
8037       return -99;
8038     }
8039
8040   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
8041
8042   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8043   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8044   mp->is_add = is_add;
8045
8046   S;
8047   W;
8048   /* NOTREACHED */
8049   return 0;
8050 }
8051
8052 static int
8053 api_ioam_enable (vat_main_t * vam)
8054 {
8055   unformat_input_t *input = vam->input;
8056   vl_api_ioam_enable_t *mp;
8057   f64 timeout;
8058   u32 id = 0;
8059   int has_trace_option = 0;
8060   int has_pot_option = 0;
8061   int has_seqno_option = 0;
8062   int has_analyse_option = 0;
8063
8064   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8065     {
8066       if (unformat (input, "trace"))
8067         has_trace_option = 1;
8068       else if (unformat (input, "pot"))
8069         has_pot_option = 1;
8070       else if (unformat (input, "seqno"))
8071         has_seqno_option = 1;
8072       else if (unformat (input, "analyse"))
8073         has_analyse_option = 1;
8074       else
8075         break;
8076     }
8077   M (IOAM_ENABLE, ioam_enable);
8078   mp->id = htons (id);
8079   mp->seqno = has_seqno_option;
8080   mp->analyse = has_analyse_option;
8081   mp->pot_enable = has_pot_option;
8082   mp->trace_enable = has_trace_option;
8083
8084   S;
8085   W;
8086
8087   return (0);
8088
8089 }
8090
8091
8092 static int
8093 api_ioam_disable (vat_main_t * vam)
8094 {
8095   vl_api_ioam_disable_t *mp;
8096   f64 timeout;
8097
8098   M (IOAM_DISABLE, ioam_disable);
8099   S;
8100   W;
8101   return 0;
8102 }
8103
8104 static int
8105 api_sr_tunnel_add_del (vat_main_t * vam)
8106 {
8107   unformat_input_t *i = vam->input;
8108   vl_api_sr_tunnel_add_del_t *mp;
8109   f64 timeout;
8110   int is_del = 0;
8111   int pl_index;
8112   ip6_address_t src_address;
8113   int src_address_set = 0;
8114   ip6_address_t dst_address;
8115   u32 dst_mask_width;
8116   int dst_address_set = 0;
8117   u16 flags = 0;
8118   u32 rx_table_id = 0;
8119   u32 tx_table_id = 0;
8120   ip6_address_t *segments = 0;
8121   ip6_address_t *this_seg;
8122   ip6_address_t *tags = 0;
8123   ip6_address_t *this_tag;
8124   ip6_address_t next_address, tag;
8125   u8 *name = 0;
8126   u8 *policy_name = 0;
8127
8128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8129     {
8130       if (unformat (i, "del"))
8131         is_del = 1;
8132       else if (unformat (i, "name %s", &name))
8133         ;
8134       else if (unformat (i, "policy %s", &policy_name))
8135         ;
8136       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8137         ;
8138       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8139         ;
8140       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8141         src_address_set = 1;
8142       else if (unformat (i, "dst %U/%d",
8143                          unformat_ip6_address, &dst_address, &dst_mask_width))
8144         dst_address_set = 1;
8145       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8146         {
8147           vec_add2 (segments, this_seg, 1);
8148           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8149                        sizeof (*this_seg));
8150         }
8151       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8152         {
8153           vec_add2 (tags, this_tag, 1);
8154           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8155         }
8156       else if (unformat (i, "clean"))
8157         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8158       else if (unformat (i, "protected"))
8159         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8160       else if (unformat (i, "InPE %d", &pl_index))
8161         {
8162           if (pl_index <= 0 || pl_index > 4)
8163             {
8164             pl_index_range_error:
8165               errmsg ("pl index %d out of range", pl_index);
8166               return -99;
8167             }
8168           flags |=
8169             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8170         }
8171       else if (unformat (i, "EgPE %d", &pl_index))
8172         {
8173           if (pl_index <= 0 || pl_index > 4)
8174             goto pl_index_range_error;
8175           flags |=
8176             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8177         }
8178       else if (unformat (i, "OrgSrc %d", &pl_index))
8179         {
8180           if (pl_index <= 0 || pl_index > 4)
8181             goto pl_index_range_error;
8182           flags |=
8183             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8184         }
8185       else
8186         break;
8187     }
8188
8189   if (!src_address_set)
8190     {
8191       errmsg ("src address required");
8192       return -99;
8193     }
8194
8195   if (!dst_address_set)
8196     {
8197       errmsg ("dst address required");
8198       return -99;
8199     }
8200
8201   if (!segments)
8202     {
8203       errmsg ("at least one sr segment required");
8204       return -99;
8205     }
8206
8207   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
8208       vec_len (segments) * sizeof (ip6_address_t)
8209       + vec_len (tags) * sizeof (ip6_address_t));
8210
8211   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8212   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8213   mp->dst_mask_width = dst_mask_width;
8214   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8215   mp->n_segments = vec_len (segments);
8216   mp->n_tags = vec_len (tags);
8217   mp->is_add = is_del == 0;
8218   clib_memcpy (mp->segs_and_tags, segments,
8219                vec_len (segments) * sizeof (ip6_address_t));
8220   clib_memcpy (mp->segs_and_tags +
8221                vec_len (segments) * sizeof (ip6_address_t), tags,
8222                vec_len (tags) * sizeof (ip6_address_t));
8223
8224   mp->outer_vrf_id = ntohl (rx_table_id);
8225   mp->inner_vrf_id = ntohl (tx_table_id);
8226   memcpy (mp->name, name, vec_len (name));
8227   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8228
8229   vec_free (segments);
8230   vec_free (tags);
8231
8232   S;
8233   W;
8234   /* NOTREACHED */
8235 }
8236
8237 static int
8238 api_sr_policy_add_del (vat_main_t * vam)
8239 {
8240   unformat_input_t *input = vam->input;
8241   vl_api_sr_policy_add_del_t *mp;
8242   f64 timeout;
8243   int is_del = 0;
8244   u8 *name = 0;
8245   u8 *tunnel_name = 0;
8246   u8 **tunnel_names = 0;
8247
8248   int name_set = 0;
8249   int tunnel_set = 0;
8250   int j = 0;
8251   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8252   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8253
8254   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8255     {
8256       if (unformat (input, "del"))
8257         is_del = 1;
8258       else if (unformat (input, "name %s", &name))
8259         name_set = 1;
8260       else if (unformat (input, "tunnel %s", &tunnel_name))
8261         {
8262           if (tunnel_name)
8263             {
8264               vec_add1 (tunnel_names, tunnel_name);
8265               /* For serializer:
8266                  - length = #bytes to store in serial vector
8267                  - +1 = byte to store that length
8268                */
8269               tunnel_names_length += (vec_len (tunnel_name) + 1);
8270               tunnel_set = 1;
8271               tunnel_name = 0;
8272             }
8273         }
8274       else
8275         break;
8276     }
8277
8278   if (!name_set)
8279     {
8280       errmsg ("policy name required");
8281       return -99;
8282     }
8283
8284   if ((!tunnel_set) && (!is_del))
8285     {
8286       errmsg ("tunnel name required");
8287       return -99;
8288     }
8289
8290   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8291
8292
8293
8294   mp->is_add = !is_del;
8295
8296   memcpy (mp->name, name, vec_len (name));
8297   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8298   u8 *serial_orig = 0;
8299   vec_validate (serial_orig, tunnel_names_length);
8300   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8301   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8302
8303   for (j = 0; j < vec_len (tunnel_names); j++)
8304     {
8305       tun_name_len = vec_len (tunnel_names[j]);
8306       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8307       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8308       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8309       serial_orig += tun_name_len;      // Advance past the copy
8310     }
8311   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8312
8313   vec_free (tunnel_names);
8314   vec_free (tunnel_name);
8315
8316   S;
8317   W;
8318   /* NOTREACHED */
8319 }
8320
8321 static int
8322 api_sr_multicast_map_add_del (vat_main_t * vam)
8323 {
8324   unformat_input_t *input = vam->input;
8325   vl_api_sr_multicast_map_add_del_t *mp;
8326   f64 timeout;
8327   int is_del = 0;
8328   ip6_address_t multicast_address;
8329   u8 *policy_name = 0;
8330   int multicast_address_set = 0;
8331
8332   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8333     {
8334       if (unformat (input, "del"))
8335         is_del = 1;
8336       else
8337         if (unformat
8338             (input, "address %U", unformat_ip6_address, &multicast_address))
8339         multicast_address_set = 1;
8340       else if (unformat (input, "sr-policy %s", &policy_name))
8341         ;
8342       else
8343         break;
8344     }
8345
8346   if (!is_del && !policy_name)
8347     {
8348       errmsg ("sr-policy name required");
8349       return -99;
8350     }
8351
8352
8353   if (!multicast_address_set)
8354     {
8355       errmsg ("address required");
8356       return -99;
8357     }
8358
8359   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8360
8361   mp->is_add = !is_del;
8362   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8363   clib_memcpy (mp->multicast_address, &multicast_address,
8364                sizeof (mp->multicast_address));
8365
8366
8367   vec_free (policy_name);
8368
8369   S;
8370   W;
8371   /* NOTREACHED */
8372 }
8373
8374
8375 #define foreach_tcp_proto_field                 \
8376 _(src_port)                                     \
8377 _(dst_port)
8378
8379 #define foreach_udp_proto_field                 \
8380 _(src_port)                                     \
8381 _(dst_port)
8382
8383 #define foreach_ip4_proto_field                 \
8384 _(src_address)                                  \
8385 _(dst_address)                                  \
8386 _(tos)                                          \
8387 _(length)                                       \
8388 _(fragment_id)                                  \
8389 _(ttl)                                          \
8390 _(protocol)                                     \
8391 _(checksum)
8392
8393 uword
8394 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8395 {
8396   u8 **maskp = va_arg (*args, u8 **);
8397   u8 *mask = 0;
8398   u8 found_something = 0;
8399   tcp_header_t *tcp;
8400
8401 #define _(a) u8 a=0;
8402   foreach_tcp_proto_field;
8403 #undef _
8404
8405   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8406     {
8407       if (0);
8408 #define _(a) else if (unformat (input, #a)) a=1;
8409       foreach_tcp_proto_field
8410 #undef _
8411         else
8412         break;
8413     }
8414
8415 #define _(a) found_something += a;
8416   foreach_tcp_proto_field;
8417 #undef _
8418
8419   if (found_something == 0)
8420     return 0;
8421
8422   vec_validate (mask, sizeof (*tcp) - 1);
8423
8424   tcp = (tcp_header_t *) mask;
8425
8426 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8427   foreach_tcp_proto_field;
8428 #undef _
8429
8430   *maskp = mask;
8431   return 1;
8432 }
8433
8434 uword
8435 unformat_udp_mask (unformat_input_t * input, va_list * args)
8436 {
8437   u8 **maskp = va_arg (*args, u8 **);
8438   u8 *mask = 0;
8439   u8 found_something = 0;
8440   udp_header_t *udp;
8441
8442 #define _(a) u8 a=0;
8443   foreach_udp_proto_field;
8444 #undef _
8445
8446   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8447     {
8448       if (0);
8449 #define _(a) else if (unformat (input, #a)) a=1;
8450       foreach_udp_proto_field
8451 #undef _
8452         else
8453         break;
8454     }
8455
8456 #define _(a) found_something += a;
8457   foreach_udp_proto_field;
8458 #undef _
8459
8460   if (found_something == 0)
8461     return 0;
8462
8463   vec_validate (mask, sizeof (*udp) - 1);
8464
8465   udp = (udp_header_t *) mask;
8466
8467 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8468   foreach_udp_proto_field;
8469 #undef _
8470
8471   *maskp = mask;
8472   return 1;
8473 }
8474
8475 typedef struct
8476 {
8477   u16 src_port, dst_port;
8478 } tcpudp_header_t;
8479
8480 uword
8481 unformat_l4_mask (unformat_input_t * input, va_list * args)
8482 {
8483   u8 **maskp = va_arg (*args, u8 **);
8484   u16 src_port = 0, dst_port = 0;
8485   tcpudp_header_t *tcpudp;
8486
8487   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8488     {
8489       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8490         return 1;
8491       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8492         return 1;
8493       else if (unformat (input, "src_port"))
8494         src_port = 0xFFFF;
8495       else if (unformat (input, "dst_port"))
8496         dst_port = 0xFFFF;
8497       else
8498         return 0;
8499     }
8500
8501   if (!src_port && !dst_port)
8502     return 0;
8503
8504   u8 *mask = 0;
8505   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8506
8507   tcpudp = (tcpudp_header_t *) mask;
8508   tcpudp->src_port = src_port;
8509   tcpudp->dst_port = dst_port;
8510
8511   *maskp = mask;
8512
8513   return 1;
8514 }
8515
8516 uword
8517 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8518 {
8519   u8 **maskp = va_arg (*args, u8 **);
8520   u8 *mask = 0;
8521   u8 found_something = 0;
8522   ip4_header_t *ip;
8523
8524 #define _(a) u8 a=0;
8525   foreach_ip4_proto_field;
8526 #undef _
8527   u8 version = 0;
8528   u8 hdr_length = 0;
8529
8530
8531   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8532     {
8533       if (unformat (input, "version"))
8534         version = 1;
8535       else if (unformat (input, "hdr_length"))
8536         hdr_length = 1;
8537       else if (unformat (input, "src"))
8538         src_address = 1;
8539       else if (unformat (input, "dst"))
8540         dst_address = 1;
8541       else if (unformat (input, "proto"))
8542         protocol = 1;
8543
8544 #define _(a) else if (unformat (input, #a)) a=1;
8545       foreach_ip4_proto_field
8546 #undef _
8547         else
8548         break;
8549     }
8550
8551 #define _(a) found_something += a;
8552   foreach_ip4_proto_field;
8553 #undef _
8554
8555   if (found_something == 0)
8556     return 0;
8557
8558   vec_validate (mask, sizeof (*ip) - 1);
8559
8560   ip = (ip4_header_t *) mask;
8561
8562 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8563   foreach_ip4_proto_field;
8564 #undef _
8565
8566   ip->ip_version_and_header_length = 0;
8567
8568   if (version)
8569     ip->ip_version_and_header_length |= 0xF0;
8570
8571   if (hdr_length)
8572     ip->ip_version_and_header_length |= 0x0F;
8573
8574   *maskp = mask;
8575   return 1;
8576 }
8577
8578 #define foreach_ip6_proto_field                 \
8579 _(src_address)                                  \
8580 _(dst_address)                                  \
8581 _(payload_length)                               \
8582 _(hop_limit)                                    \
8583 _(protocol)
8584
8585 uword
8586 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8587 {
8588   u8 **maskp = va_arg (*args, u8 **);
8589   u8 *mask = 0;
8590   u8 found_something = 0;
8591   ip6_header_t *ip;
8592   u32 ip_version_traffic_class_and_flow_label;
8593
8594 #define _(a) u8 a=0;
8595   foreach_ip6_proto_field;
8596 #undef _
8597   u8 version = 0;
8598   u8 traffic_class = 0;
8599   u8 flow_label = 0;
8600
8601   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8602     {
8603       if (unformat (input, "version"))
8604         version = 1;
8605       else if (unformat (input, "traffic-class"))
8606         traffic_class = 1;
8607       else if (unformat (input, "flow-label"))
8608         flow_label = 1;
8609       else if (unformat (input, "src"))
8610         src_address = 1;
8611       else if (unformat (input, "dst"))
8612         dst_address = 1;
8613       else if (unformat (input, "proto"))
8614         protocol = 1;
8615
8616 #define _(a) else if (unformat (input, #a)) a=1;
8617       foreach_ip6_proto_field
8618 #undef _
8619         else
8620         break;
8621     }
8622
8623 #define _(a) found_something += a;
8624   foreach_ip6_proto_field;
8625 #undef _
8626
8627   if (found_something == 0)
8628     return 0;
8629
8630   vec_validate (mask, sizeof (*ip) - 1);
8631
8632   ip = (ip6_header_t *) mask;
8633
8634 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8635   foreach_ip6_proto_field;
8636 #undef _
8637
8638   ip_version_traffic_class_and_flow_label = 0;
8639
8640   if (version)
8641     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8642
8643   if (traffic_class)
8644     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8645
8646   if (flow_label)
8647     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8648
8649   ip->ip_version_traffic_class_and_flow_label =
8650     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8651
8652   *maskp = mask;
8653   return 1;
8654 }
8655
8656 uword
8657 unformat_l3_mask (unformat_input_t * input, va_list * args)
8658 {
8659   u8 **maskp = va_arg (*args, u8 **);
8660
8661   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8662     {
8663       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8664         return 1;
8665       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8666         return 1;
8667       else
8668         break;
8669     }
8670   return 0;
8671 }
8672
8673 uword
8674 unformat_l2_mask (unformat_input_t * input, va_list * args)
8675 {
8676   u8 **maskp = va_arg (*args, u8 **);
8677   u8 *mask = 0;
8678   u8 src = 0;
8679   u8 dst = 0;
8680   u8 proto = 0;
8681   u8 tag1 = 0;
8682   u8 tag2 = 0;
8683   u8 ignore_tag1 = 0;
8684   u8 ignore_tag2 = 0;
8685   u8 cos1 = 0;
8686   u8 cos2 = 0;
8687   u8 dot1q = 0;
8688   u8 dot1ad = 0;
8689   int len = 14;
8690
8691   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8692     {
8693       if (unformat (input, "src"))
8694         src = 1;
8695       else if (unformat (input, "dst"))
8696         dst = 1;
8697       else if (unformat (input, "proto"))
8698         proto = 1;
8699       else if (unformat (input, "tag1"))
8700         tag1 = 1;
8701       else if (unformat (input, "tag2"))
8702         tag2 = 1;
8703       else if (unformat (input, "ignore-tag1"))
8704         ignore_tag1 = 1;
8705       else if (unformat (input, "ignore-tag2"))
8706         ignore_tag2 = 1;
8707       else if (unformat (input, "cos1"))
8708         cos1 = 1;
8709       else if (unformat (input, "cos2"))
8710         cos2 = 1;
8711       else if (unformat (input, "dot1q"))
8712         dot1q = 1;
8713       else if (unformat (input, "dot1ad"))
8714         dot1ad = 1;
8715       else
8716         break;
8717     }
8718   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8719        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8720     return 0;
8721
8722   if (tag1 || ignore_tag1 || cos1 || dot1q)
8723     len = 18;
8724   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8725     len = 22;
8726
8727   vec_validate (mask, len - 1);
8728
8729   if (dst)
8730     memset (mask, 0xff, 6);
8731
8732   if (src)
8733     memset (mask + 6, 0xff, 6);
8734
8735   if (tag2 || dot1ad)
8736     {
8737       /* inner vlan tag */
8738       if (tag2)
8739         {
8740           mask[19] = 0xff;
8741           mask[18] = 0x0f;
8742         }
8743       if (cos2)
8744         mask[18] |= 0xe0;
8745       if (proto)
8746         mask[21] = mask[20] = 0xff;
8747       if (tag1)
8748         {
8749           mask[15] = 0xff;
8750           mask[14] = 0x0f;
8751         }
8752       if (cos1)
8753         mask[14] |= 0xe0;
8754       *maskp = mask;
8755       return 1;
8756     }
8757   if (tag1 | dot1q)
8758     {
8759       if (tag1)
8760         {
8761           mask[15] = 0xff;
8762           mask[14] = 0x0f;
8763         }
8764       if (cos1)
8765         mask[14] |= 0xe0;
8766       if (proto)
8767         mask[16] = mask[17] = 0xff;
8768
8769       *maskp = mask;
8770       return 1;
8771     }
8772   if (cos2)
8773     mask[18] |= 0xe0;
8774   if (cos1)
8775     mask[14] |= 0xe0;
8776   if (proto)
8777     mask[12] = mask[13] = 0xff;
8778
8779   *maskp = mask;
8780   return 1;
8781 }
8782
8783 uword
8784 unformat_classify_mask (unformat_input_t * input, va_list * args)
8785 {
8786   u8 **maskp = va_arg (*args, u8 **);
8787   u32 *skipp = va_arg (*args, u32 *);
8788   u32 *matchp = va_arg (*args, u32 *);
8789   u32 match;
8790   u8 *mask = 0;
8791   u8 *l2 = 0;
8792   u8 *l3 = 0;
8793   u8 *l4 = 0;
8794   int i;
8795
8796   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8797     {
8798       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8799         ;
8800       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8801         ;
8802       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8803         ;
8804       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8805         ;
8806       else
8807         break;
8808     }
8809
8810   if (l4 && !l3)
8811     {
8812       vec_free (mask);
8813       vec_free (l2);
8814       vec_free (l4);
8815       return 0;
8816     }
8817
8818   if (mask || l2 || l3 || l4)
8819     {
8820       if (l2 || l3 || l4)
8821         {
8822           /* "With a free Ethernet header in every package" */
8823           if (l2 == 0)
8824             vec_validate (l2, 13);
8825           mask = l2;
8826           if (vec_len (l3))
8827             {
8828               vec_append (mask, l3);
8829               vec_free (l3);
8830             }
8831           if (vec_len (l4))
8832             {
8833               vec_append (mask, l4);
8834               vec_free (l4);
8835             }
8836         }
8837
8838       /* Scan forward looking for the first significant mask octet */
8839       for (i = 0; i < vec_len (mask); i++)
8840         if (mask[i])
8841           break;
8842
8843       /* compute (skip, match) params */
8844       *skipp = i / sizeof (u32x4);
8845       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8846
8847       /* Pad mask to an even multiple of the vector size */
8848       while (vec_len (mask) % sizeof (u32x4))
8849         vec_add1 (mask, 0);
8850
8851       match = vec_len (mask) / sizeof (u32x4);
8852
8853       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8854         {
8855           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8856           if (*tmp || *(tmp + 1))
8857             break;
8858           match--;
8859         }
8860       if (match == 0)
8861         clib_warning ("BUG: match 0");
8862
8863       _vec_len (mask) = match * sizeof (u32x4);
8864
8865       *matchp = match;
8866       *maskp = mask;
8867
8868       return 1;
8869     }
8870
8871   return 0;
8872 }
8873
8874 #define foreach_l2_next                         \
8875 _(drop, DROP)                                   \
8876 _(ethernet, ETHERNET_INPUT)                     \
8877 _(ip4, IP4_INPUT)                               \
8878 _(ip6, IP6_INPUT)
8879
8880 uword
8881 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8882 {
8883   u32 *miss_next_indexp = va_arg (*args, u32 *);
8884   u32 next_index = 0;
8885   u32 tmp;
8886
8887 #define _(n,N) \
8888   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8889   foreach_l2_next;
8890 #undef _
8891
8892   if (unformat (input, "%d", &tmp))
8893     {
8894       next_index = tmp;
8895       goto out;
8896     }
8897
8898   return 0;
8899
8900 out:
8901   *miss_next_indexp = next_index;
8902   return 1;
8903 }
8904
8905 #define foreach_ip_next                         \
8906 _(drop, DROP)                                   \
8907 _(local, LOCAL)                                 \
8908 _(rewrite, REWRITE)
8909
8910 uword
8911 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8912 {
8913   u32 *miss_next_indexp = va_arg (*args, u32 *);
8914   u32 next_index = 0;
8915   u32 tmp;
8916
8917 #define _(n,N) \
8918   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8919   foreach_ip_next;
8920 #undef _
8921
8922   if (unformat (input, "%d", &tmp))
8923     {
8924       next_index = tmp;
8925       goto out;
8926     }
8927
8928   return 0;
8929
8930 out:
8931   *miss_next_indexp = next_index;
8932   return 1;
8933 }
8934
8935 #define foreach_acl_next                        \
8936 _(deny, DENY)
8937
8938 uword
8939 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8940 {
8941   u32 *miss_next_indexp = va_arg (*args, u32 *);
8942   u32 next_index = 0;
8943   u32 tmp;
8944
8945 #define _(n,N) \
8946   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8947   foreach_acl_next;
8948 #undef _
8949
8950   if (unformat (input, "permit"))
8951     {
8952       next_index = ~0;
8953       goto out;
8954     }
8955   else if (unformat (input, "%d", &tmp))
8956     {
8957       next_index = tmp;
8958       goto out;
8959     }
8960
8961   return 0;
8962
8963 out:
8964   *miss_next_indexp = next_index;
8965   return 1;
8966 }
8967
8968 uword
8969 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8970 {
8971   u32 *r = va_arg (*args, u32 *);
8972
8973   if (unformat (input, "conform-color"))
8974     *r = POLICE_CONFORM;
8975   else if (unformat (input, "exceed-color"))
8976     *r = POLICE_EXCEED;
8977   else
8978     return 0;
8979
8980   return 1;
8981 }
8982
8983 static int
8984 api_classify_add_del_table (vat_main_t * vam)
8985 {
8986   unformat_input_t *i = vam->input;
8987   vl_api_classify_add_del_table_t *mp;
8988
8989   u32 nbuckets = 2;
8990   u32 skip = ~0;
8991   u32 match = ~0;
8992   int is_add = 1;
8993   int del_chain = 0;
8994   u32 table_index = ~0;
8995   u32 next_table_index = ~0;
8996   u32 miss_next_index = ~0;
8997   u32 memory_size = 32 << 20;
8998   u8 *mask = 0;
8999   f64 timeout;
9000   u32 current_data_flag = 0;
9001   int current_data_offset = 0;
9002
9003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9004     {
9005       if (unformat (i, "del"))
9006         is_add = 0;
9007       else if (unformat (i, "del-chain"))
9008         {
9009           is_add = 0;
9010           del_chain = 1;
9011         }
9012       else if (unformat (i, "buckets %d", &nbuckets))
9013         ;
9014       else if (unformat (i, "memory_size %d", &memory_size))
9015         ;
9016       else if (unformat (i, "skip %d", &skip))
9017         ;
9018       else if (unformat (i, "match %d", &match))
9019         ;
9020       else if (unformat (i, "table %d", &table_index))
9021         ;
9022       else if (unformat (i, "mask %U", unformat_classify_mask,
9023                          &mask, &skip, &match))
9024         ;
9025       else if (unformat (i, "next-table %d", &next_table_index))
9026         ;
9027       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
9028                          &miss_next_index))
9029         ;
9030       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
9031                          &miss_next_index))
9032         ;
9033       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
9034                          &miss_next_index))
9035         ;
9036       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9037         ;
9038       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9039         ;
9040       else
9041         break;
9042     }
9043
9044   if (is_add && mask == 0)
9045     {
9046       errmsg ("Mask required");
9047       return -99;
9048     }
9049
9050   if (is_add && skip == ~0)
9051     {
9052       errmsg ("skip count required");
9053       return -99;
9054     }
9055
9056   if (is_add && match == ~0)
9057     {
9058       errmsg ("match count required");
9059       return -99;
9060     }
9061
9062   if (!is_add && table_index == ~0)
9063     {
9064       errmsg ("table index required for delete");
9065       return -99;
9066     }
9067
9068   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
9069
9070   mp->is_add = is_add;
9071   mp->del_chain = del_chain;
9072   mp->table_index = ntohl (table_index);
9073   mp->nbuckets = ntohl (nbuckets);
9074   mp->memory_size = ntohl (memory_size);
9075   mp->skip_n_vectors = ntohl (skip);
9076   mp->match_n_vectors = ntohl (match);
9077   mp->next_table_index = ntohl (next_table_index);
9078   mp->miss_next_index = ntohl (miss_next_index);
9079   mp->current_data_flag = ntohl (current_data_flag);
9080   mp->current_data_offset = ntohl (current_data_offset);
9081   clib_memcpy (mp->mask, mask, vec_len (mask));
9082
9083   vec_free (mask);
9084
9085   S;
9086   W;
9087   /* NOTREACHED */
9088 }
9089
9090 uword
9091 unformat_l4_match (unformat_input_t * input, va_list * args)
9092 {
9093   u8 **matchp = va_arg (*args, u8 **);
9094
9095   u8 *proto_header = 0;
9096   int src_port = 0;
9097   int dst_port = 0;
9098
9099   tcpudp_header_t h;
9100
9101   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9102     {
9103       if (unformat (input, "src_port %d", &src_port))
9104         ;
9105       else if (unformat (input, "dst_port %d", &dst_port))
9106         ;
9107       else
9108         return 0;
9109     }
9110
9111   h.src_port = clib_host_to_net_u16 (src_port);
9112   h.dst_port = clib_host_to_net_u16 (dst_port);
9113   vec_validate (proto_header, sizeof (h) - 1);
9114   memcpy (proto_header, &h, sizeof (h));
9115
9116   *matchp = proto_header;
9117
9118   return 1;
9119 }
9120
9121 uword
9122 unformat_ip4_match (unformat_input_t * input, va_list * args)
9123 {
9124   u8 **matchp = va_arg (*args, u8 **);
9125   u8 *match = 0;
9126   ip4_header_t *ip;
9127   int version = 0;
9128   u32 version_val;
9129   int hdr_length = 0;
9130   u32 hdr_length_val;
9131   int src = 0, dst = 0;
9132   ip4_address_t src_val, dst_val;
9133   int proto = 0;
9134   u32 proto_val;
9135   int tos = 0;
9136   u32 tos_val;
9137   int length = 0;
9138   u32 length_val;
9139   int fragment_id = 0;
9140   u32 fragment_id_val;
9141   int ttl = 0;
9142   int ttl_val;
9143   int checksum = 0;
9144   u32 checksum_val;
9145
9146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9147     {
9148       if (unformat (input, "version %d", &version_val))
9149         version = 1;
9150       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9151         hdr_length = 1;
9152       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9153         src = 1;
9154       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9155         dst = 1;
9156       else if (unformat (input, "proto %d", &proto_val))
9157         proto = 1;
9158       else if (unformat (input, "tos %d", &tos_val))
9159         tos = 1;
9160       else if (unformat (input, "length %d", &length_val))
9161         length = 1;
9162       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9163         fragment_id = 1;
9164       else if (unformat (input, "ttl %d", &ttl_val))
9165         ttl = 1;
9166       else if (unformat (input, "checksum %d", &checksum_val))
9167         checksum = 1;
9168       else
9169         break;
9170     }
9171
9172   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9173       + ttl + checksum == 0)
9174     return 0;
9175
9176   /*
9177    * Aligned because we use the real comparison functions
9178    */
9179   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9180
9181   ip = (ip4_header_t *) match;
9182
9183   /* These are realistically matched in practice */
9184   if (src)
9185     ip->src_address.as_u32 = src_val.as_u32;
9186
9187   if (dst)
9188     ip->dst_address.as_u32 = dst_val.as_u32;
9189
9190   if (proto)
9191     ip->protocol = proto_val;
9192
9193
9194   /* These are not, but they're included for completeness */
9195   if (version)
9196     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9197
9198   if (hdr_length)
9199     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9200
9201   if (tos)
9202     ip->tos = tos_val;
9203
9204   if (length)
9205     ip->length = clib_host_to_net_u16 (length_val);
9206
9207   if (ttl)
9208     ip->ttl = ttl_val;
9209
9210   if (checksum)
9211     ip->checksum = clib_host_to_net_u16 (checksum_val);
9212
9213   *matchp = match;
9214   return 1;
9215 }
9216
9217 uword
9218 unformat_ip6_match (unformat_input_t * input, va_list * args)
9219 {
9220   u8 **matchp = va_arg (*args, u8 **);
9221   u8 *match = 0;
9222   ip6_header_t *ip;
9223   int version = 0;
9224   u32 version_val;
9225   u8 traffic_class = 0;
9226   u32 traffic_class_val = 0;
9227   u8 flow_label = 0;
9228   u8 flow_label_val;
9229   int src = 0, dst = 0;
9230   ip6_address_t src_val, dst_val;
9231   int proto = 0;
9232   u32 proto_val;
9233   int payload_length = 0;
9234   u32 payload_length_val;
9235   int hop_limit = 0;
9236   int hop_limit_val;
9237   u32 ip_version_traffic_class_and_flow_label;
9238
9239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9240     {
9241       if (unformat (input, "version %d", &version_val))
9242         version = 1;
9243       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9244         traffic_class = 1;
9245       else if (unformat (input, "flow_label %d", &flow_label_val))
9246         flow_label = 1;
9247       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9248         src = 1;
9249       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9250         dst = 1;
9251       else if (unformat (input, "proto %d", &proto_val))
9252         proto = 1;
9253       else if (unformat (input, "payload_length %d", &payload_length_val))
9254         payload_length = 1;
9255       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9256         hop_limit = 1;
9257       else
9258         break;
9259     }
9260
9261   if (version + traffic_class + flow_label + src + dst + proto +
9262       payload_length + hop_limit == 0)
9263     return 0;
9264
9265   /*
9266    * Aligned because we use the real comparison functions
9267    */
9268   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9269
9270   ip = (ip6_header_t *) match;
9271
9272   if (src)
9273     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9274
9275   if (dst)
9276     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9277
9278   if (proto)
9279     ip->protocol = proto_val;
9280
9281   ip_version_traffic_class_and_flow_label = 0;
9282
9283   if (version)
9284     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9285
9286   if (traffic_class)
9287     ip_version_traffic_class_and_flow_label |=
9288       (traffic_class_val & 0xFF) << 20;
9289
9290   if (flow_label)
9291     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9292
9293   ip->ip_version_traffic_class_and_flow_label =
9294     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9295
9296   if (payload_length)
9297     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9298
9299   if (hop_limit)
9300     ip->hop_limit = hop_limit_val;
9301
9302   *matchp = match;
9303   return 1;
9304 }
9305
9306 uword
9307 unformat_l3_match (unformat_input_t * input, va_list * args)
9308 {
9309   u8 **matchp = va_arg (*args, u8 **);
9310
9311   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9312     {
9313       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9314         return 1;
9315       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9316         return 1;
9317       else
9318         break;
9319     }
9320   return 0;
9321 }
9322
9323 uword
9324 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9325 {
9326   u8 *tagp = va_arg (*args, u8 *);
9327   u32 tag;
9328
9329   if (unformat (input, "%d", &tag))
9330     {
9331       tagp[0] = (tag >> 8) & 0x0F;
9332       tagp[1] = tag & 0xFF;
9333       return 1;
9334     }
9335
9336   return 0;
9337 }
9338
9339 uword
9340 unformat_l2_match (unformat_input_t * input, va_list * args)
9341 {
9342   u8 **matchp = va_arg (*args, u8 **);
9343   u8 *match = 0;
9344   u8 src = 0;
9345   u8 src_val[6];
9346   u8 dst = 0;
9347   u8 dst_val[6];
9348   u8 proto = 0;
9349   u16 proto_val;
9350   u8 tag1 = 0;
9351   u8 tag1_val[2];
9352   u8 tag2 = 0;
9353   u8 tag2_val[2];
9354   int len = 14;
9355   u8 ignore_tag1 = 0;
9356   u8 ignore_tag2 = 0;
9357   u8 cos1 = 0;
9358   u8 cos2 = 0;
9359   u32 cos1_val = 0;
9360   u32 cos2_val = 0;
9361
9362   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9363     {
9364       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9365         src = 1;
9366       else
9367         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9368         dst = 1;
9369       else if (unformat (input, "proto %U",
9370                          unformat_ethernet_type_host_byte_order, &proto_val))
9371         proto = 1;
9372       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9373         tag1 = 1;
9374       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9375         tag2 = 1;
9376       else if (unformat (input, "ignore-tag1"))
9377         ignore_tag1 = 1;
9378       else if (unformat (input, "ignore-tag2"))
9379         ignore_tag2 = 1;
9380       else if (unformat (input, "cos1 %d", &cos1_val))
9381         cos1 = 1;
9382       else if (unformat (input, "cos2 %d", &cos2_val))
9383         cos2 = 1;
9384       else
9385         break;
9386     }
9387   if ((src + dst + proto + tag1 + tag2 +
9388        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9389     return 0;
9390
9391   if (tag1 || ignore_tag1 || cos1)
9392     len = 18;
9393   if (tag2 || ignore_tag2 || cos2)
9394     len = 22;
9395
9396   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9397
9398   if (dst)
9399     clib_memcpy (match, dst_val, 6);
9400
9401   if (src)
9402     clib_memcpy (match + 6, src_val, 6);
9403
9404   if (tag2)
9405     {
9406       /* inner vlan tag */
9407       match[19] = tag2_val[1];
9408       match[18] = tag2_val[0];
9409       if (cos2)
9410         match[18] |= (cos2_val & 0x7) << 5;
9411       if (proto)
9412         {
9413           match[21] = proto_val & 0xff;
9414           match[20] = proto_val >> 8;
9415         }
9416       if (tag1)
9417         {
9418           match[15] = tag1_val[1];
9419           match[14] = tag1_val[0];
9420         }
9421       if (cos1)
9422         match[14] |= (cos1_val & 0x7) << 5;
9423       *matchp = match;
9424       return 1;
9425     }
9426   if (tag1)
9427     {
9428       match[15] = tag1_val[1];
9429       match[14] = tag1_val[0];
9430       if (proto)
9431         {
9432           match[17] = proto_val & 0xff;
9433           match[16] = proto_val >> 8;
9434         }
9435       if (cos1)
9436         match[14] |= (cos1_val & 0x7) << 5;
9437
9438       *matchp = match;
9439       return 1;
9440     }
9441   if (cos2)
9442     match[18] |= (cos2_val & 0x7) << 5;
9443   if (cos1)
9444     match[14] |= (cos1_val & 0x7) << 5;
9445   if (proto)
9446     {
9447       match[13] = proto_val & 0xff;
9448       match[12] = proto_val >> 8;
9449     }
9450
9451   *matchp = match;
9452   return 1;
9453 }
9454
9455
9456 uword
9457 unformat_classify_match (unformat_input_t * input, va_list * args)
9458 {
9459   u8 **matchp = va_arg (*args, u8 **);
9460   u32 skip_n_vectors = va_arg (*args, u32);
9461   u32 match_n_vectors = va_arg (*args, u32);
9462
9463   u8 *match = 0;
9464   u8 *l2 = 0;
9465   u8 *l3 = 0;
9466   u8 *l4 = 0;
9467
9468   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9469     {
9470       if (unformat (input, "hex %U", unformat_hex_string, &match))
9471         ;
9472       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9473         ;
9474       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9475         ;
9476       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9477         ;
9478       else
9479         break;
9480     }
9481
9482   if (l4 && !l3)
9483     {
9484       vec_free (match);
9485       vec_free (l2);
9486       vec_free (l4);
9487       return 0;
9488     }
9489
9490   if (match || l2 || l3 || l4)
9491     {
9492       if (l2 || l3 || l4)
9493         {
9494           /* "Win a free Ethernet header in every packet" */
9495           if (l2 == 0)
9496             vec_validate_aligned (l2, 13, sizeof (u32x4));
9497           match = l2;
9498           if (vec_len (l3))
9499             {
9500               vec_append_aligned (match, l3, sizeof (u32x4));
9501               vec_free (l3);
9502             }
9503           if (vec_len (l4))
9504             {
9505               vec_append_aligned (match, l4, sizeof (u32x4));
9506               vec_free (l4);
9507             }
9508         }
9509
9510       /* Make sure the vector is big enough even if key is all 0's */
9511       vec_validate_aligned
9512         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9513          sizeof (u32x4));
9514
9515       /* Set size, include skipped vectors */
9516       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9517
9518       *matchp = match;
9519
9520       return 1;
9521     }
9522
9523   return 0;
9524 }
9525
9526 static int
9527 api_classify_add_del_session (vat_main_t * vam)
9528 {
9529   unformat_input_t *i = vam->input;
9530   vl_api_classify_add_del_session_t *mp;
9531   int is_add = 1;
9532   u32 table_index = ~0;
9533   u32 hit_next_index = ~0;
9534   u32 opaque_index = ~0;
9535   u8 *match = 0;
9536   i32 advance = 0;
9537   f64 timeout;
9538   u32 skip_n_vectors = 0;
9539   u32 match_n_vectors = 0;
9540   u32 action = 0;
9541   u32 metadata = 0;
9542
9543   /*
9544    * Warning: you have to supply skip_n and match_n
9545    * because the API client cant simply look at the classify
9546    * table object.
9547    */
9548
9549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9550     {
9551       if (unformat (i, "del"))
9552         is_add = 0;
9553       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9554                          &hit_next_index))
9555         ;
9556       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9557                          &hit_next_index))
9558         ;
9559       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9560                          &hit_next_index))
9561         ;
9562       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9563         ;
9564       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9565         ;
9566       else if (unformat (i, "opaque-index %d", &opaque_index))
9567         ;
9568       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9569         ;
9570       else if (unformat (i, "match_n %d", &match_n_vectors))
9571         ;
9572       else if (unformat (i, "match %U", unformat_classify_match,
9573                          &match, skip_n_vectors, match_n_vectors))
9574         ;
9575       else if (unformat (i, "advance %d", &advance))
9576         ;
9577       else if (unformat (i, "table-index %d", &table_index))
9578         ;
9579       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9580         action = 1;
9581       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9582         action = 2;
9583       else if (unformat (i, "action %d", &action))
9584         ;
9585       else if (unformat (i, "metadata %d", &metadata))
9586         ;
9587       else
9588         break;
9589     }
9590
9591   if (table_index == ~0)
9592     {
9593       errmsg ("Table index required");
9594       return -99;
9595     }
9596
9597   if (is_add && match == 0)
9598     {
9599       errmsg ("Match value required");
9600       return -99;
9601     }
9602
9603   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9604
9605   mp->is_add = is_add;
9606   mp->table_index = ntohl (table_index);
9607   mp->hit_next_index = ntohl (hit_next_index);
9608   mp->opaque_index = ntohl (opaque_index);
9609   mp->advance = ntohl (advance);
9610   mp->action = action;
9611   mp->metadata = ntohl (metadata);
9612   clib_memcpy (mp->match, match, vec_len (match));
9613   vec_free (match);
9614
9615   S;
9616   W;
9617   /* NOTREACHED */
9618 }
9619
9620 static int
9621 api_classify_set_interface_ip_table (vat_main_t * vam)
9622 {
9623   unformat_input_t *i = vam->input;
9624   vl_api_classify_set_interface_ip_table_t *mp;
9625   f64 timeout;
9626   u32 sw_if_index;
9627   int sw_if_index_set;
9628   u32 table_index = ~0;
9629   u8 is_ipv6 = 0;
9630
9631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9632     {
9633       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9634         sw_if_index_set = 1;
9635       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9636         sw_if_index_set = 1;
9637       else if (unformat (i, "table %d", &table_index))
9638         ;
9639       else
9640         {
9641           clib_warning ("parse error '%U'", format_unformat_error, i);
9642           return -99;
9643         }
9644     }
9645
9646   if (sw_if_index_set == 0)
9647     {
9648       errmsg ("missing interface name or sw_if_index");
9649       return -99;
9650     }
9651
9652
9653   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9654
9655   mp->sw_if_index = ntohl (sw_if_index);
9656   mp->table_index = ntohl (table_index);
9657   mp->is_ipv6 = is_ipv6;
9658
9659   S;
9660   W;
9661   /* NOTREACHED */
9662   return 0;
9663 }
9664
9665 static int
9666 api_classify_set_interface_l2_tables (vat_main_t * vam)
9667 {
9668   unformat_input_t *i = vam->input;
9669   vl_api_classify_set_interface_l2_tables_t *mp;
9670   f64 timeout;
9671   u32 sw_if_index;
9672   int sw_if_index_set;
9673   u32 ip4_table_index = ~0;
9674   u32 ip6_table_index = ~0;
9675   u32 other_table_index = ~0;
9676   u32 is_input = 1;
9677
9678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9679     {
9680       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9681         sw_if_index_set = 1;
9682       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9683         sw_if_index_set = 1;
9684       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9685         ;
9686       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9687         ;
9688       else if (unformat (i, "other-table %d", &other_table_index))
9689         ;
9690       else if (unformat (i, "is-input %d", &is_input))
9691         ;
9692       else
9693         {
9694           clib_warning ("parse error '%U'", format_unformat_error, i);
9695           return -99;
9696         }
9697     }
9698
9699   if (sw_if_index_set == 0)
9700     {
9701       errmsg ("missing interface name or sw_if_index");
9702       return -99;
9703     }
9704
9705
9706   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9707
9708   mp->sw_if_index = ntohl (sw_if_index);
9709   mp->ip4_table_index = ntohl (ip4_table_index);
9710   mp->ip6_table_index = ntohl (ip6_table_index);
9711   mp->other_table_index = ntohl (other_table_index);
9712   mp->is_input = (u8) is_input;
9713
9714   S;
9715   W;
9716   /* NOTREACHED */
9717   return 0;
9718 }
9719
9720 static int
9721 api_set_ipfix_exporter (vat_main_t * vam)
9722 {
9723   unformat_input_t *i = vam->input;
9724   vl_api_set_ipfix_exporter_t *mp;
9725   ip4_address_t collector_address;
9726   u8 collector_address_set = 0;
9727   u32 collector_port = ~0;
9728   ip4_address_t src_address;
9729   u8 src_address_set = 0;
9730   u32 vrf_id = ~0;
9731   u32 path_mtu = ~0;
9732   u32 template_interval = ~0;
9733   u8 udp_checksum = 0;
9734   f64 timeout;
9735
9736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9737     {
9738       if (unformat (i, "collector_address %U", unformat_ip4_address,
9739                     &collector_address))
9740         collector_address_set = 1;
9741       else if (unformat (i, "collector_port %d", &collector_port))
9742         ;
9743       else if (unformat (i, "src_address %U", unformat_ip4_address,
9744                          &src_address))
9745         src_address_set = 1;
9746       else if (unformat (i, "vrf_id %d", &vrf_id))
9747         ;
9748       else if (unformat (i, "path_mtu %d", &path_mtu))
9749         ;
9750       else if (unformat (i, "template_interval %d", &template_interval))
9751         ;
9752       else if (unformat (i, "udp_checksum"))
9753         udp_checksum = 1;
9754       else
9755         break;
9756     }
9757
9758   if (collector_address_set == 0)
9759     {
9760       errmsg ("collector_address required");
9761       return -99;
9762     }
9763
9764   if (src_address_set == 0)
9765     {
9766       errmsg ("src_address required");
9767       return -99;
9768     }
9769
9770   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9771
9772   memcpy (mp->collector_address, collector_address.data,
9773           sizeof (collector_address.data));
9774   mp->collector_port = htons ((u16) collector_port);
9775   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9776   mp->vrf_id = htonl (vrf_id);
9777   mp->path_mtu = htonl (path_mtu);
9778   mp->template_interval = htonl (template_interval);
9779   mp->udp_checksum = udp_checksum;
9780
9781   S;
9782   W;
9783   /* NOTREACHED */
9784 }
9785
9786 static int
9787 api_set_ipfix_classify_stream (vat_main_t * vam)
9788 {
9789   unformat_input_t *i = vam->input;
9790   vl_api_set_ipfix_classify_stream_t *mp;
9791   u32 domain_id = 0;
9792   u32 src_port = UDP_DST_PORT_ipfix;
9793   f64 timeout;
9794
9795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9796     {
9797       if (unformat (i, "domain %d", &domain_id))
9798         ;
9799       else if (unformat (i, "src_port %d", &src_port))
9800         ;
9801       else
9802         {
9803           errmsg ("unknown input `%U'", format_unformat_error, i);
9804           return -99;
9805         }
9806     }
9807
9808   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9809
9810   mp->domain_id = htonl (domain_id);
9811   mp->src_port = htons ((u16) src_port);
9812
9813   S;
9814   W;
9815   /* NOTREACHED */
9816 }
9817
9818 static int
9819 api_ipfix_classify_table_add_del (vat_main_t * vam)
9820 {
9821   unformat_input_t *i = vam->input;
9822   vl_api_ipfix_classify_table_add_del_t *mp;
9823   int is_add = -1;
9824   u32 classify_table_index = ~0;
9825   u8 ip_version = 0;
9826   u8 transport_protocol = 255;
9827   f64 timeout;
9828
9829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9830     {
9831       if (unformat (i, "add"))
9832         is_add = 1;
9833       else if (unformat (i, "del"))
9834         is_add = 0;
9835       else if (unformat (i, "table %d", &classify_table_index))
9836         ;
9837       else if (unformat (i, "ip4"))
9838         ip_version = 4;
9839       else if (unformat (i, "ip6"))
9840         ip_version = 6;
9841       else if (unformat (i, "tcp"))
9842         transport_protocol = 6;
9843       else if (unformat (i, "udp"))
9844         transport_protocol = 17;
9845       else
9846         {
9847           errmsg ("unknown input `%U'", format_unformat_error, i);
9848           return -99;
9849         }
9850     }
9851
9852   if (is_add == -1)
9853     {
9854       errmsg ("expecting: add|del");
9855       return -99;
9856     }
9857   if (classify_table_index == ~0)
9858     {
9859       errmsg ("classifier table not specified");
9860       return -99;
9861     }
9862   if (ip_version == 0)
9863     {
9864       errmsg ("IP version not specified");
9865       return -99;
9866     }
9867
9868   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9869
9870   mp->is_add = is_add;
9871   mp->table_id = htonl (classify_table_index);
9872   mp->ip_version = ip_version;
9873   mp->transport_protocol = transport_protocol;
9874
9875   S;
9876   W;
9877   /* NOTREACHED */
9878 }
9879
9880 static int
9881 api_get_node_index (vat_main_t * vam)
9882 {
9883   unformat_input_t *i = vam->input;
9884   vl_api_get_node_index_t *mp;
9885   f64 timeout;
9886   u8 *name = 0;
9887
9888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9889     {
9890       if (unformat (i, "node %s", &name))
9891         ;
9892       else
9893         break;
9894     }
9895   if (name == 0)
9896     {
9897       errmsg ("node name required");
9898       return -99;
9899     }
9900   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9901     {
9902       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9903       return -99;
9904     }
9905
9906   M (GET_NODE_INDEX, get_node_index);
9907   clib_memcpy (mp->node_name, name, vec_len (name));
9908   vec_free (name);
9909
9910   S;
9911   W;
9912   /* NOTREACHED */
9913   return 0;
9914 }
9915
9916 static int
9917 api_get_next_index (vat_main_t * vam)
9918 {
9919   unformat_input_t *i = vam->input;
9920   vl_api_get_next_index_t *mp;
9921   f64 timeout;
9922   u8 *node_name = 0, *next_node_name = 0;
9923
9924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9925     {
9926       if (unformat (i, "node-name %s", &node_name))
9927         ;
9928       else if (unformat (i, "next-node-name %s", &next_node_name))
9929         break;
9930     }
9931
9932   if (node_name == 0)
9933     {
9934       errmsg ("node name required");
9935       return -99;
9936     }
9937   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9938     {
9939       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9940       return -99;
9941     }
9942
9943   if (next_node_name == 0)
9944     {
9945       errmsg ("next node name required");
9946       return -99;
9947     }
9948   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9949     {
9950       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9951       return -99;
9952     }
9953
9954   M (GET_NEXT_INDEX, get_next_index);
9955   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9956   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9957   vec_free (node_name);
9958   vec_free (next_node_name);
9959
9960   S;
9961   W;
9962   /* NOTREACHED */
9963   return 0;
9964 }
9965
9966 static int
9967 api_add_node_next (vat_main_t * vam)
9968 {
9969   unformat_input_t *i = vam->input;
9970   vl_api_add_node_next_t *mp;
9971   f64 timeout;
9972   u8 *name = 0;
9973   u8 *next = 0;
9974
9975   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9976     {
9977       if (unformat (i, "node %s", &name))
9978         ;
9979       else if (unformat (i, "next %s", &next))
9980         ;
9981       else
9982         break;
9983     }
9984   if (name == 0)
9985     {
9986       errmsg ("node name required");
9987       return -99;
9988     }
9989   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9990     {
9991       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9992       return -99;
9993     }
9994   if (next == 0)
9995     {
9996       errmsg ("next node required");
9997       return -99;
9998     }
9999   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
10000     {
10001       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
10002       return -99;
10003     }
10004
10005   M (ADD_NODE_NEXT, add_node_next);
10006   clib_memcpy (mp->node_name, name, vec_len (name));
10007   clib_memcpy (mp->next_name, next, vec_len (next));
10008   vec_free (name);
10009   vec_free (next);
10010
10011   S;
10012   W;
10013   /* NOTREACHED */
10014   return 0;
10015 }
10016
10017 static int
10018 api_l2tpv3_create_tunnel (vat_main_t * vam)
10019 {
10020   unformat_input_t *i = vam->input;
10021   ip6_address_t client_address, our_address;
10022   int client_address_set = 0;
10023   int our_address_set = 0;
10024   u32 local_session_id = 0;
10025   u32 remote_session_id = 0;
10026   u64 local_cookie = 0;
10027   u64 remote_cookie = 0;
10028   u8 l2_sublayer_present = 0;
10029   vl_api_l2tpv3_create_tunnel_t *mp;
10030   f64 timeout;
10031
10032   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10033     {
10034       if (unformat (i, "client_address %U", unformat_ip6_address,
10035                     &client_address))
10036         client_address_set = 1;
10037       else if (unformat (i, "our_address %U", unformat_ip6_address,
10038                          &our_address))
10039         our_address_set = 1;
10040       else if (unformat (i, "local_session_id %d", &local_session_id))
10041         ;
10042       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10043         ;
10044       else if (unformat (i, "local_cookie %lld", &local_cookie))
10045         ;
10046       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10047         ;
10048       else if (unformat (i, "l2-sublayer-present"))
10049         l2_sublayer_present = 1;
10050       else
10051         break;
10052     }
10053
10054   if (client_address_set == 0)
10055     {
10056       errmsg ("client_address required");
10057       return -99;
10058     }
10059
10060   if (our_address_set == 0)
10061     {
10062       errmsg ("our_address required");
10063       return -99;
10064     }
10065
10066   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
10067
10068   clib_memcpy (mp->client_address, client_address.as_u8,
10069                sizeof (mp->client_address));
10070
10071   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10072
10073   mp->local_session_id = ntohl (local_session_id);
10074   mp->remote_session_id = ntohl (remote_session_id);
10075   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10076   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10077   mp->l2_sublayer_present = l2_sublayer_present;
10078   mp->is_ipv6 = 1;
10079
10080   S;
10081   W;
10082   /* NOTREACHED */
10083   return 0;
10084 }
10085
10086 static int
10087 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10088 {
10089   unformat_input_t *i = vam->input;
10090   u32 sw_if_index;
10091   u8 sw_if_index_set = 0;
10092   u64 new_local_cookie = 0;
10093   u64 new_remote_cookie = 0;
10094   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10095   f64 timeout;
10096
10097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10098     {
10099       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10100         sw_if_index_set = 1;
10101       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10102         sw_if_index_set = 1;
10103       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10104         ;
10105       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10106         ;
10107       else
10108         break;
10109     }
10110
10111   if (sw_if_index_set == 0)
10112     {
10113       errmsg ("missing interface name or sw_if_index");
10114       return -99;
10115     }
10116
10117   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
10118
10119   mp->sw_if_index = ntohl (sw_if_index);
10120   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10121   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10122
10123   S;
10124   W;
10125   /* NOTREACHED */
10126   return 0;
10127 }
10128
10129 static int
10130 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10131 {
10132   unformat_input_t *i = vam->input;
10133   vl_api_l2tpv3_interface_enable_disable_t *mp;
10134   f64 timeout;
10135   u32 sw_if_index;
10136   u8 sw_if_index_set = 0;
10137   u8 enable_disable = 1;
10138
10139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10140     {
10141       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10142         sw_if_index_set = 1;
10143       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10144         sw_if_index_set = 1;
10145       else if (unformat (i, "enable"))
10146         enable_disable = 1;
10147       else if (unformat (i, "disable"))
10148         enable_disable = 0;
10149       else
10150         break;
10151     }
10152
10153   if (sw_if_index_set == 0)
10154     {
10155       errmsg ("missing interface name or sw_if_index");
10156       return -99;
10157     }
10158
10159   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
10160
10161   mp->sw_if_index = ntohl (sw_if_index);
10162   mp->enable_disable = enable_disable;
10163
10164   S;
10165   W;
10166   /* NOTREACHED */
10167   return 0;
10168 }
10169
10170 static int
10171 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10172 {
10173   unformat_input_t *i = vam->input;
10174   vl_api_l2tpv3_set_lookup_key_t *mp;
10175   f64 timeout;
10176   u8 key = ~0;
10177
10178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10179     {
10180       if (unformat (i, "lookup_v6_src"))
10181         key = L2T_LOOKUP_SRC_ADDRESS;
10182       else if (unformat (i, "lookup_v6_dst"))
10183         key = L2T_LOOKUP_DST_ADDRESS;
10184       else if (unformat (i, "lookup_session_id"))
10185         key = L2T_LOOKUP_SESSION_ID;
10186       else
10187         break;
10188     }
10189
10190   if (key == (u8) ~ 0)
10191     {
10192       errmsg ("l2tp session lookup key unset");
10193       return -99;
10194     }
10195
10196   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
10197
10198   mp->key = key;
10199
10200   S;
10201   W;
10202   /* NOTREACHED */
10203   return 0;
10204 }
10205
10206 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10207   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10208 {
10209   vat_main_t *vam = &vat_main;
10210
10211   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10212          format_ip6_address, mp->our_address,
10213          format_ip6_address, mp->client_address,
10214          clib_net_to_host_u32 (mp->sw_if_index));
10215
10216   print (vam->ofp,
10217          "   local cookies %016llx %016llx remote cookie %016llx",
10218          clib_net_to_host_u64 (mp->local_cookie[0]),
10219          clib_net_to_host_u64 (mp->local_cookie[1]),
10220          clib_net_to_host_u64 (mp->remote_cookie));
10221
10222   print (vam->ofp, "   local session-id %d remote session-id %d",
10223          clib_net_to_host_u32 (mp->local_session_id),
10224          clib_net_to_host_u32 (mp->remote_session_id));
10225
10226   print (vam->ofp, "   l2 specific sublayer %s\n",
10227          mp->l2_sublayer_present ? "preset" : "absent");
10228
10229 }
10230
10231 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10232   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10233 {
10234   vat_main_t *vam = &vat_main;
10235   vat_json_node_t *node = NULL;
10236   struct in6_addr addr;
10237
10238   if (VAT_JSON_ARRAY != vam->json_tree.type)
10239     {
10240       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10241       vat_json_init_array (&vam->json_tree);
10242     }
10243   node = vat_json_array_add (&vam->json_tree);
10244
10245   vat_json_init_object (node);
10246
10247   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10248   vat_json_object_add_ip6 (node, "our_address", addr);
10249   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10250   vat_json_object_add_ip6 (node, "client_address", addr);
10251
10252   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10253   vat_json_init_array (lc);
10254   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10255   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10256   vat_json_object_add_uint (node, "remote_cookie",
10257                             clib_net_to_host_u64 (mp->remote_cookie));
10258
10259   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10260   vat_json_object_add_uint (node, "local_session_id",
10261                             clib_net_to_host_u32 (mp->local_session_id));
10262   vat_json_object_add_uint (node, "remote_session_id",
10263                             clib_net_to_host_u32 (mp->remote_session_id));
10264   vat_json_object_add_string_copy (node, "l2_sublayer",
10265                                    mp->l2_sublayer_present ? (u8 *) "present"
10266                                    : (u8 *) "absent");
10267 }
10268
10269 static int
10270 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10271 {
10272   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10273   f64 timeout;
10274
10275   /* Get list of l2tpv3-tunnel interfaces */
10276   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10277   S;
10278
10279   /* Use a control ping for synchronization */
10280   {
10281     vl_api_control_ping_t *mp;
10282     M (CONTROL_PING, control_ping);
10283     S;
10284   }
10285   W;
10286 }
10287
10288
10289 static void vl_api_sw_interface_tap_details_t_handler
10290   (vl_api_sw_interface_tap_details_t * mp)
10291 {
10292   vat_main_t *vam = &vat_main;
10293
10294   print (vam->ofp, "%-16s %d",
10295          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10296 }
10297
10298 static void vl_api_sw_interface_tap_details_t_handler_json
10299   (vl_api_sw_interface_tap_details_t * mp)
10300 {
10301   vat_main_t *vam = &vat_main;
10302   vat_json_node_t *node = NULL;
10303
10304   if (VAT_JSON_ARRAY != vam->json_tree.type)
10305     {
10306       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10307       vat_json_init_array (&vam->json_tree);
10308     }
10309   node = vat_json_array_add (&vam->json_tree);
10310
10311   vat_json_init_object (node);
10312   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10313   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10314 }
10315
10316 static int
10317 api_sw_interface_tap_dump (vat_main_t * vam)
10318 {
10319   vl_api_sw_interface_tap_dump_t *mp;
10320   f64 timeout;
10321
10322   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10323   /* Get list of tap interfaces */
10324   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10325   S;
10326
10327   /* Use a control ping for synchronization */
10328   {
10329     vl_api_control_ping_t *mp;
10330     M (CONTROL_PING, control_ping);
10331     S;
10332   }
10333   W;
10334 }
10335
10336 static uword unformat_vxlan_decap_next
10337   (unformat_input_t * input, va_list * args)
10338 {
10339   u32 *result = va_arg (*args, u32 *);
10340   u32 tmp;
10341
10342   if (unformat (input, "l2"))
10343     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10344   else if (unformat (input, "%d", &tmp))
10345     *result = tmp;
10346   else
10347     return 0;
10348   return 1;
10349 }
10350
10351 static int
10352 api_vxlan_add_del_tunnel (vat_main_t * vam)
10353 {
10354   unformat_input_t *line_input = vam->input;
10355   vl_api_vxlan_add_del_tunnel_t *mp;
10356   f64 timeout;
10357   ip46_address_t src, dst;
10358   u8 is_add = 1;
10359   u8 ipv4_set = 0, ipv6_set = 0;
10360   u8 src_set = 0;
10361   u8 dst_set = 0;
10362   u8 grp_set = 0;
10363   u32 mcast_sw_if_index = ~0;
10364   u32 encap_vrf_id = 0;
10365   u32 decap_next_index = ~0;
10366   u32 vni = 0;
10367
10368   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10369   memset (&src, 0, sizeof src);
10370   memset (&dst, 0, sizeof dst);
10371
10372   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10373     {
10374       if (unformat (line_input, "del"))
10375         is_add = 0;
10376       else
10377         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10378         {
10379           ipv4_set = 1;
10380           src_set = 1;
10381         }
10382       else
10383         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10384         {
10385           ipv4_set = 1;
10386           dst_set = 1;
10387         }
10388       else
10389         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10390         {
10391           ipv6_set = 1;
10392           src_set = 1;
10393         }
10394       else
10395         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10396         {
10397           ipv6_set = 1;
10398           dst_set = 1;
10399         }
10400       else if (unformat (line_input, "group %U %U",
10401                          unformat_ip4_address, &dst.ip4,
10402                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10403         {
10404           grp_set = dst_set = 1;
10405           ipv4_set = 1;
10406         }
10407       else if (unformat (line_input, "group %U",
10408                          unformat_ip4_address, &dst.ip4))
10409         {
10410           grp_set = dst_set = 1;
10411           ipv4_set = 1;
10412         }
10413       else if (unformat (line_input, "group %U %U",
10414                          unformat_ip6_address, &dst.ip6,
10415                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10416         {
10417           grp_set = dst_set = 1;
10418           ipv6_set = 1;
10419         }
10420       else if (unformat (line_input, "group %U",
10421                          unformat_ip6_address, &dst.ip6))
10422         {
10423           grp_set = dst_set = 1;
10424           ipv6_set = 1;
10425         }
10426       else
10427         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10428         ;
10429       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10430         ;
10431       else if (unformat (line_input, "decap-next %U",
10432                          unformat_vxlan_decap_next, &decap_next_index))
10433         ;
10434       else if (unformat (line_input, "vni %d", &vni))
10435         ;
10436       else
10437         {
10438           errmsg ("parse error '%U'", format_unformat_error, line_input);
10439           return -99;
10440         }
10441     }
10442
10443   if (src_set == 0)
10444     {
10445       errmsg ("tunnel src address not specified");
10446       return -99;
10447     }
10448   if (dst_set == 0)
10449     {
10450       errmsg ("tunnel dst address not specified");
10451       return -99;
10452     }
10453
10454   if (grp_set && !ip46_address_is_multicast (&dst))
10455     {
10456       errmsg ("tunnel group address not multicast");
10457       return -99;
10458     }
10459   if (grp_set && mcast_sw_if_index == ~0)
10460     {
10461       errmsg ("tunnel nonexistent multicast device");
10462       return -99;
10463     }
10464   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10465     {
10466       errmsg ("tunnel dst address must be unicast");
10467       return -99;
10468     }
10469
10470
10471   if (ipv4_set && ipv6_set)
10472     {
10473       errmsg ("both IPv4 and IPv6 addresses specified");
10474       return -99;
10475     }
10476
10477   if ((vni == 0) || (vni >> 24))
10478     {
10479       errmsg ("vni not specified or out of range");
10480       return -99;
10481     }
10482
10483   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10484
10485   if (ipv6_set)
10486     {
10487       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10488       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10489     }
10490   else
10491     {
10492       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10493       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10494     }
10495   mp->encap_vrf_id = ntohl (encap_vrf_id);
10496   mp->decap_next_index = ntohl (decap_next_index);
10497   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10498   mp->vni = ntohl (vni);
10499   mp->is_add = is_add;
10500   mp->is_ipv6 = ipv6_set;
10501
10502   S;
10503   W;
10504   /* NOTREACHED */
10505   return 0;
10506 }
10507
10508 static void vl_api_vxlan_tunnel_details_t_handler
10509   (vl_api_vxlan_tunnel_details_t * mp)
10510 {
10511   vat_main_t *vam = &vat_main;
10512   ip46_address_t src, dst;
10513
10514   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10515   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10516
10517   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10518          ntohl (mp->sw_if_index),
10519          format_ip46_address, &src, IP46_TYPE_ANY,
10520          format_ip46_address, &dst, IP46_TYPE_ANY,
10521          ntohl (mp->encap_vrf_id),
10522          ntohl (mp->decap_next_index), ntohl (mp->vni),
10523          ntohl (mp->mcast_sw_if_index));
10524 }
10525
10526 static void vl_api_vxlan_tunnel_details_t_handler_json
10527   (vl_api_vxlan_tunnel_details_t * mp)
10528 {
10529   vat_main_t *vam = &vat_main;
10530   vat_json_node_t *node = NULL;
10531
10532   if (VAT_JSON_ARRAY != vam->json_tree.type)
10533     {
10534       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10535       vat_json_init_array (&vam->json_tree);
10536     }
10537   node = vat_json_array_add (&vam->json_tree);
10538
10539   vat_json_init_object (node);
10540   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10541   if (mp->is_ipv6)
10542     {
10543       struct in6_addr ip6;
10544
10545       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10546       vat_json_object_add_ip6 (node, "src_address", ip6);
10547       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10548       vat_json_object_add_ip6 (node, "dst_address", ip6);
10549     }
10550   else
10551     {
10552       struct in_addr ip4;
10553
10554       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10555       vat_json_object_add_ip4 (node, "src_address", ip4);
10556       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10557       vat_json_object_add_ip4 (node, "dst_address", ip4);
10558     }
10559   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10560   vat_json_object_add_uint (node, "decap_next_index",
10561                             ntohl (mp->decap_next_index));
10562   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10563   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10564   vat_json_object_add_uint (node, "mcast_sw_if_index",
10565                             ntohl (mp->mcast_sw_if_index));
10566 }
10567
10568 static int
10569 api_vxlan_tunnel_dump (vat_main_t * vam)
10570 {
10571   unformat_input_t *i = vam->input;
10572   vl_api_vxlan_tunnel_dump_t *mp;
10573   f64 timeout;
10574   u32 sw_if_index;
10575   u8 sw_if_index_set = 0;
10576
10577   /* Parse args required to build the message */
10578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10579     {
10580       if (unformat (i, "sw_if_index %d", &sw_if_index))
10581         sw_if_index_set = 1;
10582       else
10583         break;
10584     }
10585
10586   if (sw_if_index_set == 0)
10587     {
10588       sw_if_index = ~0;
10589     }
10590
10591   if (!vam->json_output)
10592     {
10593       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10594              "sw_if_index", "src_address", "dst_address",
10595              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10596     }
10597
10598   /* Get list of vxlan-tunnel interfaces */
10599   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10600
10601   mp->sw_if_index = htonl (sw_if_index);
10602
10603   S;
10604
10605   /* Use a control ping for synchronization */
10606   {
10607     vl_api_control_ping_t *mp;
10608     M (CONTROL_PING, control_ping);
10609     S;
10610   }
10611   W;
10612 }
10613
10614 static int
10615 api_gre_add_del_tunnel (vat_main_t * vam)
10616 {
10617   unformat_input_t *line_input = vam->input;
10618   vl_api_gre_add_del_tunnel_t *mp;
10619   f64 timeout;
10620   ip4_address_t src4, dst4;
10621   u8 is_add = 1;
10622   u8 teb = 0;
10623   u8 src_set = 0;
10624   u8 dst_set = 0;
10625   u32 outer_fib_id = 0;
10626
10627   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10628     {
10629       if (unformat (line_input, "del"))
10630         is_add = 0;
10631       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10632         src_set = 1;
10633       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10634         dst_set = 1;
10635       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10636         ;
10637       else if (unformat (line_input, "teb"))
10638         teb = 1;
10639       else
10640         {
10641           errmsg ("parse error '%U'", format_unformat_error, line_input);
10642           return -99;
10643         }
10644     }
10645
10646   if (src_set == 0)
10647     {
10648       errmsg ("tunnel src address not specified");
10649       return -99;
10650     }
10651   if (dst_set == 0)
10652     {
10653       errmsg ("tunnel dst address not specified");
10654       return -99;
10655     }
10656
10657
10658   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10659
10660   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10661   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10662   mp->outer_fib_id = ntohl (outer_fib_id);
10663   mp->is_add = is_add;
10664   mp->teb = teb;
10665
10666   S;
10667   W;
10668   /* NOTREACHED */
10669   return 0;
10670 }
10671
10672 static void vl_api_gre_tunnel_details_t_handler
10673   (vl_api_gre_tunnel_details_t * mp)
10674 {
10675   vat_main_t *vam = &vat_main;
10676
10677   print (vam->ofp, "%11d%15U%15U%6d%14d",
10678          ntohl (mp->sw_if_index),
10679          format_ip4_address, &mp->src_address,
10680          format_ip4_address, &mp->dst_address,
10681          mp->teb, ntohl (mp->outer_fib_id));
10682 }
10683
10684 static void vl_api_gre_tunnel_details_t_handler_json
10685   (vl_api_gre_tunnel_details_t * mp)
10686 {
10687   vat_main_t *vam = &vat_main;
10688   vat_json_node_t *node = NULL;
10689   struct in_addr ip4;
10690
10691   if (VAT_JSON_ARRAY != vam->json_tree.type)
10692     {
10693       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10694       vat_json_init_array (&vam->json_tree);
10695     }
10696   node = vat_json_array_add (&vam->json_tree);
10697
10698   vat_json_init_object (node);
10699   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10700   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10701   vat_json_object_add_ip4 (node, "src_address", ip4);
10702   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10703   vat_json_object_add_ip4 (node, "dst_address", ip4);
10704   vat_json_object_add_uint (node, "teb", mp->teb);
10705   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10706 }
10707
10708 static int
10709 api_gre_tunnel_dump (vat_main_t * vam)
10710 {
10711   unformat_input_t *i = vam->input;
10712   vl_api_gre_tunnel_dump_t *mp;
10713   f64 timeout;
10714   u32 sw_if_index;
10715   u8 sw_if_index_set = 0;
10716
10717   /* Parse args required to build the message */
10718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10719     {
10720       if (unformat (i, "sw_if_index %d", &sw_if_index))
10721         sw_if_index_set = 1;
10722       else
10723         break;
10724     }
10725
10726   if (sw_if_index_set == 0)
10727     {
10728       sw_if_index = ~0;
10729     }
10730
10731   if (!vam->json_output)
10732     {
10733       print (vam->ofp, "%11s%15s%15s%6s%14s",
10734              "sw_if_index", "src_address", "dst_address", "teb",
10735              "outer_fib_id");
10736     }
10737
10738   /* Get list of gre-tunnel interfaces */
10739   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10740
10741   mp->sw_if_index = htonl (sw_if_index);
10742
10743   S;
10744
10745   /* Use a control ping for synchronization */
10746   {
10747     vl_api_control_ping_t *mp;
10748     M (CONTROL_PING, control_ping);
10749     S;
10750   }
10751   W;
10752 }
10753
10754 static int
10755 api_l2_fib_clear_table (vat_main_t * vam)
10756 {
10757 //  unformat_input_t * i = vam->input;
10758   vl_api_l2_fib_clear_table_t *mp;
10759   f64 timeout;
10760
10761   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10762
10763   S;
10764   W;
10765   /* NOTREACHED */
10766   return 0;
10767 }
10768
10769 static int
10770 api_l2_interface_efp_filter (vat_main_t * vam)
10771 {
10772   unformat_input_t *i = vam->input;
10773   vl_api_l2_interface_efp_filter_t *mp;
10774   f64 timeout;
10775   u32 sw_if_index;
10776   u8 enable = 1;
10777   u8 sw_if_index_set = 0;
10778
10779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10780     {
10781       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10782         sw_if_index_set = 1;
10783       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10784         sw_if_index_set = 1;
10785       else if (unformat (i, "enable"))
10786         enable = 1;
10787       else if (unformat (i, "disable"))
10788         enable = 0;
10789       else
10790         {
10791           clib_warning ("parse error '%U'", format_unformat_error, i);
10792           return -99;
10793         }
10794     }
10795
10796   if (sw_if_index_set == 0)
10797     {
10798       errmsg ("missing sw_if_index");
10799       return -99;
10800     }
10801
10802   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10803
10804   mp->sw_if_index = ntohl (sw_if_index);
10805   mp->enable_disable = enable;
10806
10807   S;
10808   W;
10809   /* NOTREACHED */
10810   return 0;
10811 }
10812
10813 #define foreach_vtr_op                          \
10814 _("disable",  L2_VTR_DISABLED)                  \
10815 _("push-1",  L2_VTR_PUSH_1)                     \
10816 _("push-2",  L2_VTR_PUSH_2)                     \
10817 _("pop-1",  L2_VTR_POP_1)                       \
10818 _("pop-2",  L2_VTR_POP_2)                       \
10819 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10820 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10821 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10822 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10823
10824 static int
10825 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10826 {
10827   unformat_input_t *i = vam->input;
10828   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10829   f64 timeout;
10830   u32 sw_if_index;
10831   u8 sw_if_index_set = 0;
10832   u8 vtr_op_set = 0;
10833   u32 vtr_op = 0;
10834   u32 push_dot1q = 1;
10835   u32 tag1 = ~0;
10836   u32 tag2 = ~0;
10837
10838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10839     {
10840       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10841         sw_if_index_set = 1;
10842       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10843         sw_if_index_set = 1;
10844       else if (unformat (i, "vtr_op %d", &vtr_op))
10845         vtr_op_set = 1;
10846 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10847       foreach_vtr_op
10848 #undef _
10849         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10850         ;
10851       else if (unformat (i, "tag1 %d", &tag1))
10852         ;
10853       else if (unformat (i, "tag2 %d", &tag2))
10854         ;
10855       else
10856         {
10857           clib_warning ("parse error '%U'", format_unformat_error, i);
10858           return -99;
10859         }
10860     }
10861
10862   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10863     {
10864       errmsg ("missing vtr operation or sw_if_index");
10865       return -99;
10866     }
10867
10868   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10869     mp->sw_if_index = ntohl (sw_if_index);
10870   mp->vtr_op = ntohl (vtr_op);
10871   mp->push_dot1q = ntohl (push_dot1q);
10872   mp->tag1 = ntohl (tag1);
10873   mp->tag2 = ntohl (tag2);
10874
10875   S;
10876   W;
10877   /* NOTREACHED */
10878   return 0;
10879 }
10880
10881 static int
10882 api_create_vhost_user_if (vat_main_t * vam)
10883 {
10884   unformat_input_t *i = vam->input;
10885   vl_api_create_vhost_user_if_t *mp;
10886   f64 timeout;
10887   u8 *file_name;
10888   u8 is_server = 0;
10889   u8 file_name_set = 0;
10890   u32 custom_dev_instance = ~0;
10891   u8 hwaddr[6];
10892   u8 use_custom_mac = 0;
10893   u8 *tag = 0;
10894
10895   /* Shut up coverity */
10896   memset (hwaddr, 0, sizeof (hwaddr));
10897
10898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10899     {
10900       if (unformat (i, "socket %s", &file_name))
10901         {
10902           file_name_set = 1;
10903         }
10904       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10905         ;
10906       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10907         use_custom_mac = 1;
10908       else if (unformat (i, "server"))
10909         is_server = 1;
10910       else if (unformat (i, "tag %s", &tag))
10911         ;
10912       else
10913         break;
10914     }
10915
10916   if (file_name_set == 0)
10917     {
10918       errmsg ("missing socket file name");
10919       return -99;
10920     }
10921
10922   if (vec_len (file_name) > 255)
10923     {
10924       errmsg ("socket file name too long");
10925       return -99;
10926     }
10927   vec_add1 (file_name, 0);
10928
10929   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10930
10931   mp->is_server = is_server;
10932   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10933   vec_free (file_name);
10934   if (custom_dev_instance != ~0)
10935     {
10936       mp->renumber = 1;
10937       mp->custom_dev_instance = ntohl (custom_dev_instance);
10938     }
10939   mp->use_custom_mac = use_custom_mac;
10940   clib_memcpy (mp->mac_address, hwaddr, 6);
10941   if (tag)
10942     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10943   vec_free (tag);
10944
10945   S;
10946   W;
10947   /* NOTREACHED */
10948   return 0;
10949 }
10950
10951 static int
10952 api_modify_vhost_user_if (vat_main_t * vam)
10953 {
10954   unformat_input_t *i = vam->input;
10955   vl_api_modify_vhost_user_if_t *mp;
10956   f64 timeout;
10957   u8 *file_name;
10958   u8 is_server = 0;
10959   u8 file_name_set = 0;
10960   u32 custom_dev_instance = ~0;
10961   u8 sw_if_index_set = 0;
10962   u32 sw_if_index = (u32) ~ 0;
10963
10964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10965     {
10966       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10967         sw_if_index_set = 1;
10968       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10969         sw_if_index_set = 1;
10970       else if (unformat (i, "socket %s", &file_name))
10971         {
10972           file_name_set = 1;
10973         }
10974       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10975         ;
10976       else if (unformat (i, "server"))
10977         is_server = 1;
10978       else
10979         break;
10980     }
10981
10982   if (sw_if_index_set == 0)
10983     {
10984       errmsg ("missing sw_if_index or interface name");
10985       return -99;
10986     }
10987
10988   if (file_name_set == 0)
10989     {
10990       errmsg ("missing socket file name");
10991       return -99;
10992     }
10993
10994   if (vec_len (file_name) > 255)
10995     {
10996       errmsg ("socket file name too long");
10997       return -99;
10998     }
10999   vec_add1 (file_name, 0);
11000
11001   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
11002
11003   mp->sw_if_index = ntohl (sw_if_index);
11004   mp->is_server = is_server;
11005   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
11006   vec_free (file_name);
11007   if (custom_dev_instance != ~0)
11008     {
11009       mp->renumber = 1;
11010       mp->custom_dev_instance = ntohl (custom_dev_instance);
11011     }
11012
11013   S;
11014   W;
11015   /* NOTREACHED */
11016   return 0;
11017 }
11018
11019 static int
11020 api_delete_vhost_user_if (vat_main_t * vam)
11021 {
11022   unformat_input_t *i = vam->input;
11023   vl_api_delete_vhost_user_if_t *mp;
11024   f64 timeout;
11025   u32 sw_if_index = ~0;
11026   u8 sw_if_index_set = 0;
11027
11028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11029     {
11030       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11031         sw_if_index_set = 1;
11032       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11033         sw_if_index_set = 1;
11034       else
11035         break;
11036     }
11037
11038   if (sw_if_index_set == 0)
11039     {
11040       errmsg ("missing sw_if_index or interface name");
11041       return -99;
11042     }
11043
11044
11045   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
11046
11047   mp->sw_if_index = ntohl (sw_if_index);
11048
11049   S;
11050   W;
11051   /* NOTREACHED */
11052   return 0;
11053 }
11054
11055 static void vl_api_sw_interface_vhost_user_details_t_handler
11056   (vl_api_sw_interface_vhost_user_details_t * mp)
11057 {
11058   vat_main_t *vam = &vat_main;
11059
11060   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11061          (char *) mp->interface_name,
11062          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11063          clib_net_to_host_u64 (mp->features), mp->is_server,
11064          ntohl (mp->num_regions), (char *) mp->sock_filename);
11065   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11066 }
11067
11068 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11069   (vl_api_sw_interface_vhost_user_details_t * mp)
11070 {
11071   vat_main_t *vam = &vat_main;
11072   vat_json_node_t *node = NULL;
11073
11074   if (VAT_JSON_ARRAY != vam->json_tree.type)
11075     {
11076       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11077       vat_json_init_array (&vam->json_tree);
11078     }
11079   node = vat_json_array_add (&vam->json_tree);
11080
11081   vat_json_init_object (node);
11082   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11083   vat_json_object_add_string_copy (node, "interface_name",
11084                                    mp->interface_name);
11085   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11086                             ntohl (mp->virtio_net_hdr_sz));
11087   vat_json_object_add_uint (node, "features",
11088                             clib_net_to_host_u64 (mp->features));
11089   vat_json_object_add_uint (node, "is_server", mp->is_server);
11090   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11091   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11092   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11093 }
11094
11095 static int
11096 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11097 {
11098   vl_api_sw_interface_vhost_user_dump_t *mp;
11099   f64 timeout;
11100   print (vam->ofp,
11101          "Interface name           idx hdr_sz features server regions filename");
11102
11103   /* Get list of vhost-user interfaces */
11104   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
11105   S;
11106
11107   /* Use a control ping for synchronization */
11108   {
11109     vl_api_control_ping_t *mp;
11110     M (CONTROL_PING, control_ping);
11111     S;
11112   }
11113   W;
11114 }
11115
11116 static int
11117 api_show_version (vat_main_t * vam)
11118 {
11119   vl_api_show_version_t *mp;
11120   f64 timeout;
11121
11122   M (SHOW_VERSION, show_version);
11123
11124   S;
11125   W;
11126   /* NOTREACHED */
11127   return 0;
11128 }
11129
11130
11131 static int
11132 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11133 {
11134   unformat_input_t *line_input = vam->input;
11135   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11136   f64 timeout;
11137   ip4_address_t local4, remote4;
11138   ip6_address_t local6, remote6;
11139   u8 is_add = 1;
11140   u8 ipv4_set = 0, ipv6_set = 0;
11141   u8 local_set = 0;
11142   u8 remote_set = 0;
11143   u32 encap_vrf_id = 0;
11144   u32 decap_vrf_id = 0;
11145   u8 protocol = ~0;
11146   u32 vni;
11147   u8 vni_set = 0;
11148
11149   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11150     {
11151       if (unformat (line_input, "del"))
11152         is_add = 0;
11153       else if (unformat (line_input, "local %U",
11154                          unformat_ip4_address, &local4))
11155         {
11156           local_set = 1;
11157           ipv4_set = 1;
11158         }
11159       else if (unformat (line_input, "remote %U",
11160                          unformat_ip4_address, &remote4))
11161         {
11162           remote_set = 1;
11163           ipv4_set = 1;
11164         }
11165       else if (unformat (line_input, "local %U",
11166                          unformat_ip6_address, &local6))
11167         {
11168           local_set = 1;
11169           ipv6_set = 1;
11170         }
11171       else if (unformat (line_input, "remote %U",
11172                          unformat_ip6_address, &remote6))
11173         {
11174           remote_set = 1;
11175           ipv6_set = 1;
11176         }
11177       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11178         ;
11179       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11180         ;
11181       else if (unformat (line_input, "vni %d", &vni))
11182         vni_set = 1;
11183       else if (unformat (line_input, "next-ip4"))
11184         protocol = 1;
11185       else if (unformat (line_input, "next-ip6"))
11186         protocol = 2;
11187       else if (unformat (line_input, "next-ethernet"))
11188         protocol = 3;
11189       else if (unformat (line_input, "next-nsh"))
11190         protocol = 4;
11191       else
11192         {
11193           errmsg ("parse error '%U'", format_unformat_error, line_input);
11194           return -99;
11195         }
11196     }
11197
11198   if (local_set == 0)
11199     {
11200       errmsg ("tunnel local address not specified");
11201       return -99;
11202     }
11203   if (remote_set == 0)
11204     {
11205       errmsg ("tunnel remote address not specified");
11206       return -99;
11207     }
11208   if (ipv4_set && ipv6_set)
11209     {
11210       errmsg ("both IPv4 and IPv6 addresses specified");
11211       return -99;
11212     }
11213
11214   if (vni_set == 0)
11215     {
11216       errmsg ("vni not specified");
11217       return -99;
11218     }
11219
11220   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
11221
11222
11223   if (ipv6_set)
11224     {
11225       clib_memcpy (&mp->local, &local6, sizeof (local6));
11226       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11227     }
11228   else
11229     {
11230       clib_memcpy (&mp->local, &local4, sizeof (local4));
11231       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11232     }
11233
11234   mp->encap_vrf_id = ntohl (encap_vrf_id);
11235   mp->decap_vrf_id = ntohl (decap_vrf_id);
11236   mp->protocol = protocol;
11237   mp->vni = ntohl (vni);
11238   mp->is_add = is_add;
11239   mp->is_ipv6 = ipv6_set;
11240
11241   S;
11242   W;
11243   /* NOTREACHED */
11244   return 0;
11245 }
11246
11247 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11248   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11249 {
11250   vat_main_t *vam = &vat_main;
11251
11252   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11253          ntohl (mp->sw_if_index),
11254          format_ip46_address, &(mp->local[0]),
11255          format_ip46_address, &(mp->remote[0]),
11256          ntohl (mp->vni),
11257          ntohl (mp->protocol),
11258          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11259 }
11260
11261 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11262   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11263 {
11264   vat_main_t *vam = &vat_main;
11265   vat_json_node_t *node = NULL;
11266   struct in_addr ip4;
11267   struct in6_addr ip6;
11268
11269   if (VAT_JSON_ARRAY != vam->json_tree.type)
11270     {
11271       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11272       vat_json_init_array (&vam->json_tree);
11273     }
11274   node = vat_json_array_add (&vam->json_tree);
11275
11276   vat_json_init_object (node);
11277   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11278   if (mp->is_ipv6)
11279     {
11280       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11281       vat_json_object_add_ip6 (node, "local", ip6);
11282       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11283       vat_json_object_add_ip6 (node, "remote", ip6);
11284     }
11285   else
11286     {
11287       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11288       vat_json_object_add_ip4 (node, "local", ip4);
11289       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11290       vat_json_object_add_ip4 (node, "remote", ip4);
11291     }
11292   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11293   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11294   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11295   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11296   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11297 }
11298
11299 static int
11300 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11301 {
11302   unformat_input_t *i = vam->input;
11303   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11304   f64 timeout;
11305   u32 sw_if_index;
11306   u8 sw_if_index_set = 0;
11307
11308   /* Parse args required to build the message */
11309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11310     {
11311       if (unformat (i, "sw_if_index %d", &sw_if_index))
11312         sw_if_index_set = 1;
11313       else
11314         break;
11315     }
11316
11317   if (sw_if_index_set == 0)
11318     {
11319       sw_if_index = ~0;
11320     }
11321
11322   if (!vam->json_output)
11323     {
11324       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11325              "sw_if_index", "local", "remote", "vni",
11326              "protocol", "encap_vrf_id", "decap_vrf_id");
11327     }
11328
11329   /* Get list of vxlan-tunnel interfaces */
11330   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11331
11332   mp->sw_if_index = htonl (sw_if_index);
11333
11334   S;
11335
11336   /* Use a control ping for synchronization */
11337   {
11338     vl_api_control_ping_t *mp;
11339     M (CONTROL_PING, control_ping);
11340     S;
11341   }
11342   W;
11343 }
11344
11345 u8 *
11346 format_l2_fib_mac_address (u8 * s, va_list * args)
11347 {
11348   u8 *a = va_arg (*args, u8 *);
11349
11350   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11351                  a[2], a[3], a[4], a[5], a[6], a[7]);
11352 }
11353
11354 static void vl_api_l2_fib_table_entry_t_handler
11355   (vl_api_l2_fib_table_entry_t * mp)
11356 {
11357   vat_main_t *vam = &vat_main;
11358
11359   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11360          "       %d       %d     %d",
11361          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11362          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11363          mp->bvi_mac);
11364 }
11365
11366 static void vl_api_l2_fib_table_entry_t_handler_json
11367   (vl_api_l2_fib_table_entry_t * mp)
11368 {
11369   vat_main_t *vam = &vat_main;
11370   vat_json_node_t *node = NULL;
11371
11372   if (VAT_JSON_ARRAY != vam->json_tree.type)
11373     {
11374       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11375       vat_json_init_array (&vam->json_tree);
11376     }
11377   node = vat_json_array_add (&vam->json_tree);
11378
11379   vat_json_init_object (node);
11380   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11381   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11382   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11383   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11384   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11385   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11386 }
11387
11388 static int
11389 api_l2_fib_table_dump (vat_main_t * vam)
11390 {
11391   unformat_input_t *i = vam->input;
11392   vl_api_l2_fib_table_dump_t *mp;
11393   f64 timeout;
11394   u32 bd_id;
11395   u8 bd_id_set = 0;
11396
11397   /* Parse args required to build the message */
11398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11399     {
11400       if (unformat (i, "bd_id %d", &bd_id))
11401         bd_id_set = 1;
11402       else
11403         break;
11404     }
11405
11406   if (bd_id_set == 0)
11407     {
11408       errmsg ("missing bridge domain");
11409       return -99;
11410     }
11411
11412   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11413
11414   /* Get list of l2 fib entries */
11415   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11416
11417   mp->bd_id = ntohl (bd_id);
11418   S;
11419
11420   /* Use a control ping for synchronization */
11421   {
11422     vl_api_control_ping_t *mp;
11423     M (CONTROL_PING, control_ping);
11424     S;
11425   }
11426   W;
11427 }
11428
11429
11430 static int
11431 api_interface_name_renumber (vat_main_t * vam)
11432 {
11433   unformat_input_t *line_input = vam->input;
11434   vl_api_interface_name_renumber_t *mp;
11435   u32 sw_if_index = ~0;
11436   f64 timeout;
11437   u32 new_show_dev_instance = ~0;
11438
11439   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11440     {
11441       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11442                     &sw_if_index))
11443         ;
11444       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11445         ;
11446       else if (unformat (line_input, "new_show_dev_instance %d",
11447                          &new_show_dev_instance))
11448         ;
11449       else
11450         break;
11451     }
11452
11453   if (sw_if_index == ~0)
11454     {
11455       errmsg ("missing interface name or sw_if_index");
11456       return -99;
11457     }
11458
11459   if (new_show_dev_instance == ~0)
11460     {
11461       errmsg ("missing new_show_dev_instance");
11462       return -99;
11463     }
11464
11465   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11466
11467   mp->sw_if_index = ntohl (sw_if_index);
11468   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11469
11470   S;
11471   W;
11472 }
11473
11474 static int
11475 api_want_ip4_arp_events (vat_main_t * vam)
11476 {
11477   unformat_input_t *line_input = vam->input;
11478   vl_api_want_ip4_arp_events_t *mp;
11479   f64 timeout;
11480   ip4_address_t address;
11481   int address_set = 0;
11482   u32 enable_disable = 1;
11483
11484   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11485     {
11486       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11487         address_set = 1;
11488       else if (unformat (line_input, "del"))
11489         enable_disable = 0;
11490       else
11491         break;
11492     }
11493
11494   if (address_set == 0)
11495     {
11496       errmsg ("missing addresses");
11497       return -99;
11498     }
11499
11500   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11501   mp->enable_disable = enable_disable;
11502   mp->pid = getpid ();
11503   mp->address = address.as_u32;
11504
11505   S;
11506   W;
11507 }
11508
11509 static int
11510 api_want_ip6_nd_events (vat_main_t * vam)
11511 {
11512   unformat_input_t *line_input = vam->input;
11513   vl_api_want_ip6_nd_events_t *mp;
11514   f64 timeout;
11515   ip6_address_t address;
11516   int address_set = 0;
11517   u32 enable_disable = 1;
11518
11519   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11520     {
11521       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11522         address_set = 1;
11523       else if (unformat (line_input, "del"))
11524         enable_disable = 0;
11525       else
11526         break;
11527     }
11528
11529   if (address_set == 0)
11530     {
11531       errmsg ("missing addresses");
11532       return -99;
11533     }
11534
11535   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11536   mp->enable_disable = enable_disable;
11537   mp->pid = getpid ();
11538   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11539
11540   S;
11541   W;
11542 }
11543
11544 static int
11545 api_input_acl_set_interface (vat_main_t * vam)
11546 {
11547   unformat_input_t *i = vam->input;
11548   vl_api_input_acl_set_interface_t *mp;
11549   f64 timeout;
11550   u32 sw_if_index;
11551   int sw_if_index_set;
11552   u32 ip4_table_index = ~0;
11553   u32 ip6_table_index = ~0;
11554   u32 l2_table_index = ~0;
11555   u8 is_add = 1;
11556
11557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11558     {
11559       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11560         sw_if_index_set = 1;
11561       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11562         sw_if_index_set = 1;
11563       else if (unformat (i, "del"))
11564         is_add = 0;
11565       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11566         ;
11567       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11568         ;
11569       else if (unformat (i, "l2-table %d", &l2_table_index))
11570         ;
11571       else
11572         {
11573           clib_warning ("parse error '%U'", format_unformat_error, i);
11574           return -99;
11575         }
11576     }
11577
11578   if (sw_if_index_set == 0)
11579     {
11580       errmsg ("missing interface name or sw_if_index");
11581       return -99;
11582     }
11583
11584   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11585
11586   mp->sw_if_index = ntohl (sw_if_index);
11587   mp->ip4_table_index = ntohl (ip4_table_index);
11588   mp->ip6_table_index = ntohl (ip6_table_index);
11589   mp->l2_table_index = ntohl (l2_table_index);
11590   mp->is_add = is_add;
11591
11592   S;
11593   W;
11594   /* NOTREACHED */
11595   return 0;
11596 }
11597
11598 static int
11599 api_ip_address_dump (vat_main_t * vam)
11600 {
11601   unformat_input_t *i = vam->input;
11602   vl_api_ip_address_dump_t *mp;
11603   u32 sw_if_index = ~0;
11604   u8 sw_if_index_set = 0;
11605   u8 ipv4_set = 0;
11606   u8 ipv6_set = 0;
11607   f64 timeout;
11608
11609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11610     {
11611       if (unformat (i, "sw_if_index %d", &sw_if_index))
11612         sw_if_index_set = 1;
11613       else
11614         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11615         sw_if_index_set = 1;
11616       else if (unformat (i, "ipv4"))
11617         ipv4_set = 1;
11618       else if (unformat (i, "ipv6"))
11619         ipv6_set = 1;
11620       else
11621         break;
11622     }
11623
11624   if (ipv4_set && ipv6_set)
11625     {
11626       errmsg ("ipv4 and ipv6 flags cannot be both set");
11627       return -99;
11628     }
11629
11630   if ((!ipv4_set) && (!ipv6_set))
11631     {
11632       errmsg ("no ipv4 nor ipv6 flag set");
11633       return -99;
11634     }
11635
11636   if (sw_if_index_set == 0)
11637     {
11638       errmsg ("missing interface name or sw_if_index");
11639       return -99;
11640     }
11641
11642   vam->current_sw_if_index = sw_if_index;
11643   vam->is_ipv6 = ipv6_set;
11644
11645   M (IP_ADDRESS_DUMP, ip_address_dump);
11646   mp->sw_if_index = ntohl (sw_if_index);
11647   mp->is_ipv6 = ipv6_set;
11648   S;
11649
11650   /* Use a control ping for synchronization */
11651   {
11652     vl_api_control_ping_t *mp;
11653     M (CONTROL_PING, control_ping);
11654     S;
11655   }
11656   W;
11657 }
11658
11659 static int
11660 api_ip_dump (vat_main_t * vam)
11661 {
11662   vl_api_ip_dump_t *mp;
11663   unformat_input_t *in = vam->input;
11664   int ipv4_set = 0;
11665   int ipv6_set = 0;
11666   int is_ipv6;
11667   f64 timeout;
11668   int i;
11669
11670   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11671     {
11672       if (unformat (in, "ipv4"))
11673         ipv4_set = 1;
11674       else if (unformat (in, "ipv6"))
11675         ipv6_set = 1;
11676       else
11677         break;
11678     }
11679
11680   if (ipv4_set && ipv6_set)
11681     {
11682       errmsg ("ipv4 and ipv6 flags cannot be both set");
11683       return -99;
11684     }
11685
11686   if ((!ipv4_set) && (!ipv6_set))
11687     {
11688       errmsg ("no ipv4 nor ipv6 flag set");
11689       return -99;
11690     }
11691
11692   is_ipv6 = ipv6_set;
11693   vam->is_ipv6 = is_ipv6;
11694
11695   /* free old data */
11696   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11697     {
11698       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11699     }
11700   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11701
11702   M (IP_DUMP, ip_dump);
11703   mp->is_ipv6 = ipv6_set;
11704   S;
11705
11706   /* Use a control ping for synchronization */
11707   {
11708     vl_api_control_ping_t *mp;
11709     M (CONTROL_PING, control_ping);
11710     S;
11711   }
11712   W;
11713 }
11714
11715 static int
11716 api_ipsec_spd_add_del (vat_main_t * vam)
11717 {
11718   unformat_input_t *i = vam->input;
11719   vl_api_ipsec_spd_add_del_t *mp;
11720   f64 timeout;
11721   u32 spd_id = ~0;
11722   u8 is_add = 1;
11723
11724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11725     {
11726       if (unformat (i, "spd_id %d", &spd_id))
11727         ;
11728       else if (unformat (i, "del"))
11729         is_add = 0;
11730       else
11731         {
11732           clib_warning ("parse error '%U'", format_unformat_error, i);
11733           return -99;
11734         }
11735     }
11736   if (spd_id == ~0)
11737     {
11738       errmsg ("spd_id must be set");
11739       return -99;
11740     }
11741
11742   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11743
11744   mp->spd_id = ntohl (spd_id);
11745   mp->is_add = is_add;
11746
11747   S;
11748   W;
11749   /* NOTREACHED */
11750   return 0;
11751 }
11752
11753 static int
11754 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11755 {
11756   unformat_input_t *i = vam->input;
11757   vl_api_ipsec_interface_add_del_spd_t *mp;
11758   f64 timeout;
11759   u32 sw_if_index;
11760   u8 sw_if_index_set = 0;
11761   u32 spd_id = (u32) ~ 0;
11762   u8 is_add = 1;
11763
11764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11765     {
11766       if (unformat (i, "del"))
11767         is_add = 0;
11768       else if (unformat (i, "spd_id %d", &spd_id))
11769         ;
11770       else
11771         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11772         sw_if_index_set = 1;
11773       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11774         sw_if_index_set = 1;
11775       else
11776         {
11777           clib_warning ("parse error '%U'", format_unformat_error, i);
11778           return -99;
11779         }
11780
11781     }
11782
11783   if (spd_id == (u32) ~ 0)
11784     {
11785       errmsg ("spd_id must be set");
11786       return -99;
11787     }
11788
11789   if (sw_if_index_set == 0)
11790     {
11791       errmsg ("missing interface name or sw_if_index");
11792       return -99;
11793     }
11794
11795   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11796
11797   mp->spd_id = ntohl (spd_id);
11798   mp->sw_if_index = ntohl (sw_if_index);
11799   mp->is_add = is_add;
11800
11801   S;
11802   W;
11803   /* NOTREACHED */
11804   return 0;
11805 }
11806
11807 static int
11808 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11809 {
11810   unformat_input_t *i = vam->input;
11811   vl_api_ipsec_spd_add_del_entry_t *mp;
11812   f64 timeout;
11813   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11814   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11815   i32 priority = 0;
11816   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11817   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11818   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11819   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11820
11821   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11822   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11823   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11824   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11825   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11826   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11827
11828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11829     {
11830       if (unformat (i, "del"))
11831         is_add = 0;
11832       if (unformat (i, "outbound"))
11833         is_outbound = 1;
11834       if (unformat (i, "inbound"))
11835         is_outbound = 0;
11836       else if (unformat (i, "spd_id %d", &spd_id))
11837         ;
11838       else if (unformat (i, "sa_id %d", &sa_id))
11839         ;
11840       else if (unformat (i, "priority %d", &priority))
11841         ;
11842       else if (unformat (i, "protocol %d", &protocol))
11843         ;
11844       else if (unformat (i, "lport_start %d", &lport_start))
11845         ;
11846       else if (unformat (i, "lport_stop %d", &lport_stop))
11847         ;
11848       else if (unformat (i, "rport_start %d", &rport_start))
11849         ;
11850       else if (unformat (i, "rport_stop %d", &rport_stop))
11851         ;
11852       else
11853         if (unformat
11854             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11855         {
11856           is_ipv6 = 0;
11857           is_ip_any = 0;
11858         }
11859       else
11860         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11861         {
11862           is_ipv6 = 0;
11863           is_ip_any = 0;
11864         }
11865       else
11866         if (unformat
11867             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11868         {
11869           is_ipv6 = 0;
11870           is_ip_any = 0;
11871         }
11872       else
11873         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11874         {
11875           is_ipv6 = 0;
11876           is_ip_any = 0;
11877         }
11878       else
11879         if (unformat
11880             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11881         {
11882           is_ipv6 = 1;
11883           is_ip_any = 0;
11884         }
11885       else
11886         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11887         {
11888           is_ipv6 = 1;
11889           is_ip_any = 0;
11890         }
11891       else
11892         if (unformat
11893             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11894         {
11895           is_ipv6 = 1;
11896           is_ip_any = 0;
11897         }
11898       else
11899         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11900         {
11901           is_ipv6 = 1;
11902           is_ip_any = 0;
11903         }
11904       else
11905         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11906         {
11907           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11908             {
11909               clib_warning ("unsupported action: 'resolve'");
11910               return -99;
11911             }
11912         }
11913       else
11914         {
11915           clib_warning ("parse error '%U'", format_unformat_error, i);
11916           return -99;
11917         }
11918
11919     }
11920
11921   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11922
11923   mp->spd_id = ntohl (spd_id);
11924   mp->priority = ntohl (priority);
11925   mp->is_outbound = is_outbound;
11926
11927   mp->is_ipv6 = is_ipv6;
11928   if (is_ipv6 || is_ip_any)
11929     {
11930       clib_memcpy (mp->remote_address_start, &raddr6_start,
11931                    sizeof (ip6_address_t));
11932       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11933                    sizeof (ip6_address_t));
11934       clib_memcpy (mp->local_address_start, &laddr6_start,
11935                    sizeof (ip6_address_t));
11936       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11937                    sizeof (ip6_address_t));
11938     }
11939   else
11940     {
11941       clib_memcpy (mp->remote_address_start, &raddr4_start,
11942                    sizeof (ip4_address_t));
11943       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11944                    sizeof (ip4_address_t));
11945       clib_memcpy (mp->local_address_start, &laddr4_start,
11946                    sizeof (ip4_address_t));
11947       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11948                    sizeof (ip4_address_t));
11949     }
11950   mp->protocol = (u8) protocol;
11951   mp->local_port_start = ntohs ((u16) lport_start);
11952   mp->local_port_stop = ntohs ((u16) lport_stop);
11953   mp->remote_port_start = ntohs ((u16) rport_start);
11954   mp->remote_port_stop = ntohs ((u16) rport_stop);
11955   mp->policy = (u8) policy;
11956   mp->sa_id = ntohl (sa_id);
11957   mp->is_add = is_add;
11958   mp->is_ip_any = is_ip_any;
11959   S;
11960   W;
11961   /* NOTREACHED */
11962   return 0;
11963 }
11964
11965 static int
11966 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11967 {
11968   unformat_input_t *i = vam->input;
11969   vl_api_ipsec_sad_add_del_entry_t *mp;
11970   f64 timeout;
11971   u32 sad_id = 0, spi = 0;
11972   u8 *ck = 0, *ik = 0;
11973   u8 is_add = 1;
11974
11975   u8 protocol = IPSEC_PROTOCOL_AH;
11976   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11977   u32 crypto_alg = 0, integ_alg = 0;
11978   ip4_address_t tun_src4;
11979   ip4_address_t tun_dst4;
11980   ip6_address_t tun_src6;
11981   ip6_address_t tun_dst6;
11982
11983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11984     {
11985       if (unformat (i, "del"))
11986         is_add = 0;
11987       else if (unformat (i, "sad_id %d", &sad_id))
11988         ;
11989       else if (unformat (i, "spi %d", &spi))
11990         ;
11991       else if (unformat (i, "esp"))
11992         protocol = IPSEC_PROTOCOL_ESP;
11993       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11994         {
11995           is_tunnel = 1;
11996           is_tunnel_ipv6 = 0;
11997         }
11998       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11999         {
12000           is_tunnel = 1;
12001           is_tunnel_ipv6 = 0;
12002         }
12003       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
12004         {
12005           is_tunnel = 1;
12006           is_tunnel_ipv6 = 1;
12007         }
12008       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
12009         {
12010           is_tunnel = 1;
12011           is_tunnel_ipv6 = 1;
12012         }
12013       else
12014         if (unformat
12015             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
12016         {
12017           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
12018               crypto_alg >= IPSEC_CRYPTO_N_ALG)
12019             {
12020               clib_warning ("unsupported crypto-alg: '%U'",
12021                             format_ipsec_crypto_alg, crypto_alg);
12022               return -99;
12023             }
12024         }
12025       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12026         ;
12027       else
12028         if (unformat
12029             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
12030         {
12031 #if DPDK_CRYPTO==1
12032           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
12033 #else
12034           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
12035 #endif
12036               integ_alg >= IPSEC_INTEG_N_ALG)
12037             {
12038               clib_warning ("unsupported integ-alg: '%U'",
12039                             format_ipsec_integ_alg, integ_alg);
12040               return -99;
12041             }
12042         }
12043       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12044         ;
12045       else
12046         {
12047           clib_warning ("parse error '%U'", format_unformat_error, i);
12048           return -99;
12049         }
12050
12051     }
12052
12053 #if DPDK_CRYPTO==1
12054   /*Special cases, aes-gcm-128 encryption */
12055   if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
12056     {
12057       if (integ_alg != IPSEC_INTEG_ALG_NONE
12058           && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
12059         {
12060           clib_warning
12061             ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
12062           return -99;
12063         }
12064       else                      /*set integ-alg internally to aes-gcm-128 */
12065         integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
12066     }
12067   else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
12068     {
12069       clib_warning ("unsupported integ-alg: aes-gcm-128");
12070       return -99;
12071     }
12072   else if (integ_alg == IPSEC_INTEG_ALG_NONE)
12073     {
12074       clib_warning ("unsupported integ-alg: none");
12075       return -99;
12076     }
12077 #endif
12078
12079
12080   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
12081
12082   mp->sad_id = ntohl (sad_id);
12083   mp->is_add = is_add;
12084   mp->protocol = protocol;
12085   mp->spi = ntohl (spi);
12086   mp->is_tunnel = is_tunnel;
12087   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12088   mp->crypto_algorithm = crypto_alg;
12089   mp->integrity_algorithm = integ_alg;
12090   mp->crypto_key_length = vec_len (ck);
12091   mp->integrity_key_length = vec_len (ik);
12092
12093   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12094     mp->crypto_key_length = sizeof (mp->crypto_key);
12095
12096   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12097     mp->integrity_key_length = sizeof (mp->integrity_key);
12098
12099   if (ck)
12100     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12101   if (ik)
12102     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12103
12104   if (is_tunnel)
12105     {
12106       if (is_tunnel_ipv6)
12107         {
12108           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12109                        sizeof (ip6_address_t));
12110           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12111                        sizeof (ip6_address_t));
12112         }
12113       else
12114         {
12115           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12116                        sizeof (ip4_address_t));
12117           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12118                        sizeof (ip4_address_t));
12119         }
12120     }
12121
12122   S;
12123   W;
12124   /* NOTREACHED */
12125   return 0;
12126 }
12127
12128 static int
12129 api_ipsec_sa_set_key (vat_main_t * vam)
12130 {
12131   unformat_input_t *i = vam->input;
12132   vl_api_ipsec_sa_set_key_t *mp;
12133   f64 timeout;
12134   u32 sa_id;
12135   u8 *ck = 0, *ik = 0;
12136
12137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12138     {
12139       if (unformat (i, "sa_id %d", &sa_id))
12140         ;
12141       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12142         ;
12143       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12144         ;
12145       else
12146         {
12147           clib_warning ("parse error '%U'", format_unformat_error, i);
12148           return -99;
12149         }
12150     }
12151
12152   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
12153
12154   mp->sa_id = ntohl (sa_id);
12155   mp->crypto_key_length = vec_len (ck);
12156   mp->integrity_key_length = vec_len (ik);
12157
12158   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12159     mp->crypto_key_length = sizeof (mp->crypto_key);
12160
12161   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12162     mp->integrity_key_length = sizeof (mp->integrity_key);
12163
12164   if (ck)
12165     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12166   if (ik)
12167     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12168
12169   S;
12170   W;
12171   /* NOTREACHED */
12172   return 0;
12173 }
12174
12175 static int
12176 api_ikev2_profile_add_del (vat_main_t * vam)
12177 {
12178   unformat_input_t *i = vam->input;
12179   vl_api_ikev2_profile_add_del_t *mp;
12180   f64 timeout;
12181   u8 is_add = 1;
12182   u8 *name = 0;
12183
12184   const char *valid_chars = "a-zA-Z0-9_";
12185
12186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12187     {
12188       if (unformat (i, "del"))
12189         is_add = 0;
12190       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12191         vec_add1 (name, 0);
12192       else
12193         {
12194           errmsg ("parse error '%U'", format_unformat_error, i);
12195           return -99;
12196         }
12197     }
12198
12199   if (!vec_len (name))
12200     {
12201       errmsg ("profile name must be specified");
12202       return -99;
12203     }
12204
12205   if (vec_len (name) > 64)
12206     {
12207       errmsg ("profile name too long");
12208       return -99;
12209     }
12210
12211   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12212
12213   clib_memcpy (mp->name, name, vec_len (name));
12214   mp->is_add = is_add;
12215   vec_free (name);
12216
12217   S;
12218   W;
12219   /* NOTREACHED */
12220   return 0;
12221 }
12222
12223 static int
12224 api_ikev2_profile_set_auth (vat_main_t * vam)
12225 {
12226   unformat_input_t *i = vam->input;
12227   vl_api_ikev2_profile_set_auth_t *mp;
12228   f64 timeout;
12229   u8 *name = 0;
12230   u8 *data = 0;
12231   u32 auth_method = 0;
12232   u8 is_hex = 0;
12233
12234   const char *valid_chars = "a-zA-Z0-9_";
12235
12236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12237     {
12238       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12239         vec_add1 (name, 0);
12240       else if (unformat (i, "auth_method %U",
12241                          unformat_ikev2_auth_method, &auth_method))
12242         ;
12243       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12244         is_hex = 1;
12245       else if (unformat (i, "auth_data %v", &data))
12246         ;
12247       else
12248         {
12249           errmsg ("parse error '%U'", format_unformat_error, i);
12250           return -99;
12251         }
12252     }
12253
12254   if (!vec_len (name))
12255     {
12256       errmsg ("profile name must be specified");
12257       return -99;
12258     }
12259
12260   if (vec_len (name) > 64)
12261     {
12262       errmsg ("profile name too long");
12263       return -99;
12264     }
12265
12266   if (!vec_len (data))
12267     {
12268       errmsg ("auth_data must be specified");
12269       return -99;
12270     }
12271
12272   if (!auth_method)
12273     {
12274       errmsg ("auth_method must be specified");
12275       return -99;
12276     }
12277
12278   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12279
12280   mp->is_hex = is_hex;
12281   mp->auth_method = (u8) auth_method;
12282   mp->data_len = vec_len (data);
12283   clib_memcpy (mp->name, name, vec_len (name));
12284   clib_memcpy (mp->data, data, vec_len (data));
12285   vec_free (name);
12286   vec_free (data);
12287
12288   S;
12289   W;
12290   /* NOTREACHED */
12291   return 0;
12292 }
12293
12294 static int
12295 api_ikev2_profile_set_id (vat_main_t * vam)
12296 {
12297   unformat_input_t *i = vam->input;
12298   vl_api_ikev2_profile_set_id_t *mp;
12299   f64 timeout;
12300   u8 *name = 0;
12301   u8 *data = 0;
12302   u8 is_local = 0;
12303   u32 id_type = 0;
12304   ip4_address_t ip4;
12305
12306   const char *valid_chars = "a-zA-Z0-9_";
12307
12308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12309     {
12310       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12311         vec_add1 (name, 0);
12312       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12313         ;
12314       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12315         {
12316           data = vec_new (u8, 4);
12317           clib_memcpy (data, ip4.as_u8, 4);
12318         }
12319       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12320         ;
12321       else if (unformat (i, "id_data %v", &data))
12322         ;
12323       else if (unformat (i, "local"))
12324         is_local = 1;
12325       else if (unformat (i, "remote"))
12326         is_local = 0;
12327       else
12328         {
12329           errmsg ("parse error '%U'", format_unformat_error, i);
12330           return -99;
12331         }
12332     }
12333
12334   if (!vec_len (name))
12335     {
12336       errmsg ("profile name must be specified");
12337       return -99;
12338     }
12339
12340   if (vec_len (name) > 64)
12341     {
12342       errmsg ("profile name too long");
12343       return -99;
12344     }
12345
12346   if (!vec_len (data))
12347     {
12348       errmsg ("id_data must be specified");
12349       return -99;
12350     }
12351
12352   if (!id_type)
12353     {
12354       errmsg ("id_type must be specified");
12355       return -99;
12356     }
12357
12358   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12359
12360   mp->is_local = is_local;
12361   mp->id_type = (u8) id_type;
12362   mp->data_len = vec_len (data);
12363   clib_memcpy (mp->name, name, vec_len (name));
12364   clib_memcpy (mp->data, data, vec_len (data));
12365   vec_free (name);
12366   vec_free (data);
12367
12368   S;
12369   W;
12370   /* NOTREACHED */
12371   return 0;
12372 }
12373
12374 static int
12375 api_ikev2_profile_set_ts (vat_main_t * vam)
12376 {
12377   unformat_input_t *i = vam->input;
12378   vl_api_ikev2_profile_set_ts_t *mp;
12379   f64 timeout;
12380   u8 *name = 0;
12381   u8 is_local = 0;
12382   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12383   ip4_address_t start_addr, end_addr;
12384
12385   const char *valid_chars = "a-zA-Z0-9_";
12386
12387   start_addr.as_u32 = 0;
12388   end_addr.as_u32 = (u32) ~ 0;
12389
12390   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12391     {
12392       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12393         vec_add1 (name, 0);
12394       else if (unformat (i, "protocol %d", &proto))
12395         ;
12396       else if (unformat (i, "start_port %d", &start_port))
12397         ;
12398       else if (unformat (i, "end_port %d", &end_port))
12399         ;
12400       else
12401         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12402         ;
12403       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12404         ;
12405       else if (unformat (i, "local"))
12406         is_local = 1;
12407       else if (unformat (i, "remote"))
12408         is_local = 0;
12409       else
12410         {
12411           errmsg ("parse error '%U'", format_unformat_error, i);
12412           return -99;
12413         }
12414     }
12415
12416   if (!vec_len (name))
12417     {
12418       errmsg ("profile name must be specified");
12419       return -99;
12420     }
12421
12422   if (vec_len (name) > 64)
12423     {
12424       errmsg ("profile name too long");
12425       return -99;
12426     }
12427
12428   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12429
12430   mp->is_local = is_local;
12431   mp->proto = (u8) proto;
12432   mp->start_port = (u16) start_port;
12433   mp->end_port = (u16) end_port;
12434   mp->start_addr = start_addr.as_u32;
12435   mp->end_addr = end_addr.as_u32;
12436   clib_memcpy (mp->name, name, vec_len (name));
12437   vec_free (name);
12438
12439   S;
12440   W;
12441   /* NOTREACHED */
12442   return 0;
12443 }
12444
12445 static int
12446 api_ikev2_set_local_key (vat_main_t * vam)
12447 {
12448   unformat_input_t *i = vam->input;
12449   vl_api_ikev2_set_local_key_t *mp;
12450   f64 timeout;
12451   u8 *file = 0;
12452
12453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12454     {
12455       if (unformat (i, "file %v", &file))
12456         vec_add1 (file, 0);
12457       else
12458         {
12459           errmsg ("parse error '%U'", format_unformat_error, i);
12460           return -99;
12461         }
12462     }
12463
12464   if (!vec_len (file))
12465     {
12466       errmsg ("RSA key file must be specified");
12467       return -99;
12468     }
12469
12470   if (vec_len (file) > 256)
12471     {
12472       errmsg ("file name too long");
12473       return -99;
12474     }
12475
12476   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12477
12478   clib_memcpy (mp->key_file, file, vec_len (file));
12479   vec_free (file);
12480
12481   S;
12482   W;
12483   /* NOTREACHED */
12484   return 0;
12485 }
12486
12487 /*
12488  * MAP
12489  */
12490 static int
12491 api_map_add_domain (vat_main_t * vam)
12492 {
12493   unformat_input_t *i = vam->input;
12494   vl_api_map_add_domain_t *mp;
12495   f64 timeout;
12496
12497   ip4_address_t ip4_prefix;
12498   ip6_address_t ip6_prefix;
12499   ip6_address_t ip6_src;
12500   u32 num_m_args = 0;
12501   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12502     0, psid_length = 0;
12503   u8 is_translation = 0;
12504   u32 mtu = 0;
12505   u32 ip6_src_len = 128;
12506
12507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12508     {
12509       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12510                     &ip4_prefix, &ip4_prefix_len))
12511         num_m_args++;
12512       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12513                          &ip6_prefix, &ip6_prefix_len))
12514         num_m_args++;
12515       else
12516         if (unformat
12517             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12518              &ip6_src_len))
12519         num_m_args++;
12520       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12521         num_m_args++;
12522       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12523         num_m_args++;
12524       else if (unformat (i, "psid-offset %d", &psid_offset))
12525         num_m_args++;
12526       else if (unformat (i, "psid-len %d", &psid_length))
12527         num_m_args++;
12528       else if (unformat (i, "mtu %d", &mtu))
12529         num_m_args++;
12530       else if (unformat (i, "map-t"))
12531         is_translation = 1;
12532       else
12533         {
12534           clib_warning ("parse error '%U'", format_unformat_error, i);
12535           return -99;
12536         }
12537     }
12538
12539   if (num_m_args < 3)
12540     {
12541       errmsg ("mandatory argument(s) missing");
12542       return -99;
12543     }
12544
12545   /* Construct the API message */
12546   M (MAP_ADD_DOMAIN, map_add_domain);
12547
12548   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12549   mp->ip4_prefix_len = ip4_prefix_len;
12550
12551   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12552   mp->ip6_prefix_len = ip6_prefix_len;
12553
12554   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12555   mp->ip6_src_prefix_len = ip6_src_len;
12556
12557   mp->ea_bits_len = ea_bits_len;
12558   mp->psid_offset = psid_offset;
12559   mp->psid_length = psid_length;
12560   mp->is_translation = is_translation;
12561   mp->mtu = htons (mtu);
12562
12563   /* send it... */
12564   S;
12565
12566   /* Wait for a reply, return good/bad news  */
12567   W;
12568 }
12569
12570 static int
12571 api_map_del_domain (vat_main_t * vam)
12572 {
12573   unformat_input_t *i = vam->input;
12574   vl_api_map_del_domain_t *mp;
12575   f64 timeout;
12576
12577   u32 num_m_args = 0;
12578   u32 index;
12579
12580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12581     {
12582       if (unformat (i, "index %d", &index))
12583         num_m_args++;
12584       else
12585         {
12586           clib_warning ("parse error '%U'", format_unformat_error, i);
12587           return -99;
12588         }
12589     }
12590
12591   if (num_m_args != 1)
12592     {
12593       errmsg ("mandatory argument(s) missing");
12594       return -99;
12595     }
12596
12597   /* Construct the API message */
12598   M (MAP_DEL_DOMAIN, map_del_domain);
12599
12600   mp->index = ntohl (index);
12601
12602   /* send it... */
12603   S;
12604
12605   /* Wait for a reply, return good/bad news  */
12606   W;
12607 }
12608
12609 static int
12610 api_map_add_del_rule (vat_main_t * vam)
12611 {
12612   unformat_input_t *i = vam->input;
12613   vl_api_map_add_del_rule_t *mp;
12614   f64 timeout;
12615   u8 is_add = 1;
12616   ip6_address_t ip6_dst;
12617   u32 num_m_args = 0, index, psid = 0;
12618
12619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12620     {
12621       if (unformat (i, "index %d", &index))
12622         num_m_args++;
12623       else if (unformat (i, "psid %d", &psid))
12624         num_m_args++;
12625       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12626         num_m_args++;
12627       else if (unformat (i, "del"))
12628         {
12629           is_add = 0;
12630         }
12631       else
12632         {
12633           clib_warning ("parse error '%U'", format_unformat_error, i);
12634           return -99;
12635         }
12636     }
12637
12638   /* Construct the API message */
12639   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12640
12641   mp->index = ntohl (index);
12642   mp->is_add = is_add;
12643   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12644   mp->psid = ntohs (psid);
12645
12646   /* send it... */
12647   S;
12648
12649   /* Wait for a reply, return good/bad news  */
12650   W;
12651 }
12652
12653 static int
12654 api_map_domain_dump (vat_main_t * vam)
12655 {
12656   vl_api_map_domain_dump_t *mp;
12657   f64 timeout;
12658
12659   /* Construct the API message */
12660   M (MAP_DOMAIN_DUMP, map_domain_dump);
12661
12662   /* send it... */
12663   S;
12664
12665   /* Use a control ping for synchronization */
12666   {
12667     vl_api_control_ping_t *mp;
12668     M (CONTROL_PING, control_ping);
12669     S;
12670   }
12671   W;
12672 }
12673
12674 static int
12675 api_map_rule_dump (vat_main_t * vam)
12676 {
12677   unformat_input_t *i = vam->input;
12678   vl_api_map_rule_dump_t *mp;
12679   f64 timeout;
12680   u32 domain_index = ~0;
12681
12682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12683     {
12684       if (unformat (i, "index %u", &domain_index))
12685         ;
12686       else
12687         break;
12688     }
12689
12690   if (domain_index == ~0)
12691     {
12692       clib_warning ("parse error: domain index expected");
12693       return -99;
12694     }
12695
12696   /* Construct the API message */
12697   M (MAP_RULE_DUMP, map_rule_dump);
12698
12699   mp->domain_index = htonl (domain_index);
12700
12701   /* send it... */
12702   S;
12703
12704   /* Use a control ping for synchronization */
12705   {
12706     vl_api_control_ping_t *mp;
12707     M (CONTROL_PING, control_ping);
12708     S;
12709   }
12710   W;
12711 }
12712
12713 static void vl_api_map_add_domain_reply_t_handler
12714   (vl_api_map_add_domain_reply_t * mp)
12715 {
12716   vat_main_t *vam = &vat_main;
12717   i32 retval = ntohl (mp->retval);
12718
12719   if (vam->async_mode)
12720     {
12721       vam->async_errors += (retval < 0);
12722     }
12723   else
12724     {
12725       vam->retval = retval;
12726       vam->result_ready = 1;
12727     }
12728 }
12729
12730 static void vl_api_map_add_domain_reply_t_handler_json
12731   (vl_api_map_add_domain_reply_t * mp)
12732 {
12733   vat_main_t *vam = &vat_main;
12734   vat_json_node_t node;
12735
12736   vat_json_init_object (&node);
12737   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12738   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12739
12740   vat_json_print (vam->ofp, &node);
12741   vat_json_free (&node);
12742
12743   vam->retval = ntohl (mp->retval);
12744   vam->result_ready = 1;
12745 }
12746
12747 static int
12748 api_get_first_msg_id (vat_main_t * vam)
12749 {
12750   vl_api_get_first_msg_id_t *mp;
12751   f64 timeout;
12752   unformat_input_t *i = vam->input;
12753   u8 *name;
12754   u8 name_set = 0;
12755
12756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12757     {
12758       if (unformat (i, "client %s", &name))
12759         name_set = 1;
12760       else
12761         break;
12762     }
12763
12764   if (name_set == 0)
12765     {
12766       errmsg ("missing client name");
12767       return -99;
12768     }
12769   vec_add1 (name, 0);
12770
12771   if (vec_len (name) > 63)
12772     {
12773       errmsg ("client name too long");
12774       return -99;
12775     }
12776
12777   M (GET_FIRST_MSG_ID, get_first_msg_id);
12778   clib_memcpy (mp->name, name, vec_len (name));
12779   S;
12780   W;
12781   /* NOTREACHED */
12782   return 0;
12783 }
12784
12785 static int
12786 api_cop_interface_enable_disable (vat_main_t * vam)
12787 {
12788   unformat_input_t *line_input = vam->input;
12789   vl_api_cop_interface_enable_disable_t *mp;
12790   f64 timeout;
12791   u32 sw_if_index = ~0;
12792   u8 enable_disable = 1;
12793
12794   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12795     {
12796       if (unformat (line_input, "disable"))
12797         enable_disable = 0;
12798       if (unformat (line_input, "enable"))
12799         enable_disable = 1;
12800       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12801                          vam, &sw_if_index))
12802         ;
12803       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12804         ;
12805       else
12806         break;
12807     }
12808
12809   if (sw_if_index == ~0)
12810     {
12811       errmsg ("missing interface name or sw_if_index");
12812       return -99;
12813     }
12814
12815   /* Construct the API message */
12816   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12817   mp->sw_if_index = ntohl (sw_if_index);
12818   mp->enable_disable = enable_disable;
12819
12820   /* send it... */
12821   S;
12822   /* Wait for the reply */
12823   W;
12824 }
12825
12826 static int
12827 api_cop_whitelist_enable_disable (vat_main_t * vam)
12828 {
12829   unformat_input_t *line_input = vam->input;
12830   vl_api_cop_whitelist_enable_disable_t *mp;
12831   f64 timeout;
12832   u32 sw_if_index = ~0;
12833   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12834   u32 fib_id = 0;
12835
12836   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12837     {
12838       if (unformat (line_input, "ip4"))
12839         ip4 = 1;
12840       else if (unformat (line_input, "ip6"))
12841         ip6 = 1;
12842       else if (unformat (line_input, "default"))
12843         default_cop = 1;
12844       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12845                          vam, &sw_if_index))
12846         ;
12847       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12848         ;
12849       else if (unformat (line_input, "fib-id %d", &fib_id))
12850         ;
12851       else
12852         break;
12853     }
12854
12855   if (sw_if_index == ~0)
12856     {
12857       errmsg ("missing interface name or sw_if_index");
12858       return -99;
12859     }
12860
12861   /* Construct the API message */
12862   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12863   mp->sw_if_index = ntohl (sw_if_index);
12864   mp->fib_id = ntohl (fib_id);
12865   mp->ip4 = ip4;
12866   mp->ip6 = ip6;
12867   mp->default_cop = default_cop;
12868
12869   /* send it... */
12870   S;
12871   /* Wait for the reply */
12872   W;
12873 }
12874
12875 static int
12876 api_get_node_graph (vat_main_t * vam)
12877 {
12878   vl_api_get_node_graph_t *mp;
12879   f64 timeout;
12880
12881   M (GET_NODE_GRAPH, get_node_graph);
12882
12883   /* send it... */
12884   S;
12885   /* Wait for the reply */
12886   W;
12887 }
12888
12889 /* *INDENT-OFF* */
12890 /** Used for parsing LISP eids */
12891 typedef CLIB_PACKED(struct{
12892   u8 addr[16];   /**< eid address */
12893   u32 len;       /**< prefix length if IP */
12894   u8 type;      /**< type of eid */
12895 }) lisp_eid_vat_t;
12896 /* *INDENT-ON* */
12897
12898 static uword
12899 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12900 {
12901   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12902
12903   memset (a, 0, sizeof (a[0]));
12904
12905   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12906     {
12907       a->type = 0;              /* ipv4 type */
12908     }
12909   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12910     {
12911       a->type = 1;              /* ipv6 type */
12912     }
12913   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12914     {
12915       a->type = 2;              /* mac type */
12916     }
12917   else
12918     {
12919       return 0;
12920     }
12921
12922   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12923     {
12924       return 0;
12925     }
12926
12927   return 1;
12928 }
12929
12930 static int
12931 lisp_eid_size_vat (u8 type)
12932 {
12933   switch (type)
12934     {
12935     case 0:
12936       return 4;
12937     case 1:
12938       return 16;
12939     case 2:
12940       return 6;
12941     }
12942   return 0;
12943 }
12944
12945 static void
12946 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12947 {
12948   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12949 }
12950
12951 /* *INDENT-OFF* */
12952 /** Used for transferring locators via VPP API */
12953 typedef CLIB_PACKED(struct
12954 {
12955   u32 sw_if_index; /**< locator sw_if_index */
12956   u8 priority; /**< locator priority */
12957   u8 weight;   /**< locator weight */
12958 }) ls_locator_t;
12959 /* *INDENT-ON* */
12960
12961 static int
12962 api_lisp_add_del_locator_set (vat_main_t * vam)
12963 {
12964   unformat_input_t *input = vam->input;
12965   vl_api_lisp_add_del_locator_set_t *mp;
12966   f64 timeout = ~0;
12967   u8 is_add = 1;
12968   u8 *locator_set_name = NULL;
12969   u8 locator_set_name_set = 0;
12970   ls_locator_t locator, *locators = 0;
12971   u32 sw_if_index, priority, weight;
12972   u32 data_len = 0;
12973
12974   /* Parse args required to build the message */
12975   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12976     {
12977       if (unformat (input, "del"))
12978         {
12979           is_add = 0;
12980         }
12981       else if (unformat (input, "locator-set %s", &locator_set_name))
12982         {
12983           locator_set_name_set = 1;
12984         }
12985       else if (unformat (input, "sw_if_index %u p %u w %u",
12986                          &sw_if_index, &priority, &weight))
12987         {
12988           locator.sw_if_index = htonl (sw_if_index);
12989           locator.priority = priority;
12990           locator.weight = weight;
12991           vec_add1 (locators, locator);
12992         }
12993       else
12994         if (unformat
12995             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
12996              &sw_if_index, &priority, &weight))
12997         {
12998           locator.sw_if_index = htonl (sw_if_index);
12999           locator.priority = priority;
13000           locator.weight = weight;
13001           vec_add1 (locators, locator);
13002         }
13003       else
13004         break;
13005     }
13006
13007   if (locator_set_name_set == 0)
13008     {
13009       errmsg ("missing locator-set name");
13010       vec_free (locators);
13011       return -99;
13012     }
13013
13014   if (vec_len (locator_set_name) > 64)
13015     {
13016       errmsg ("locator-set name too long");
13017       vec_free (locator_set_name);
13018       vec_free (locators);
13019       return -99;
13020     }
13021   vec_add1 (locator_set_name, 0);
13022
13023   data_len = sizeof (ls_locator_t) * vec_len (locators);
13024
13025   /* Construct the API message */
13026   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
13027
13028   mp->is_add = is_add;
13029   clib_memcpy (mp->locator_set_name, locator_set_name,
13030                vec_len (locator_set_name));
13031   vec_free (locator_set_name);
13032
13033   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
13034   if (locators)
13035     clib_memcpy (mp->locators, locators, data_len);
13036   vec_free (locators);
13037
13038   /* send it... */
13039   S;
13040
13041   /* Wait for a reply... */
13042   W;
13043
13044   /* NOTREACHED */
13045   return 0;
13046 }
13047
13048 static int
13049 api_lisp_add_del_locator (vat_main_t * vam)
13050 {
13051   unformat_input_t *input = vam->input;
13052   vl_api_lisp_add_del_locator_t *mp;
13053   f64 timeout = ~0;
13054   u32 tmp_if_index = ~0;
13055   u32 sw_if_index = ~0;
13056   u8 sw_if_index_set = 0;
13057   u8 sw_if_index_if_name_set = 0;
13058   u32 priority = ~0;
13059   u8 priority_set = 0;
13060   u32 weight = ~0;
13061   u8 weight_set = 0;
13062   u8 is_add = 1;
13063   u8 *locator_set_name = NULL;
13064   u8 locator_set_name_set = 0;
13065
13066   /* Parse args required to build the message */
13067   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13068     {
13069       if (unformat (input, "del"))
13070         {
13071           is_add = 0;
13072         }
13073       else if (unformat (input, "locator-set %s", &locator_set_name))
13074         {
13075           locator_set_name_set = 1;
13076         }
13077       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13078                          &tmp_if_index))
13079         {
13080           sw_if_index_if_name_set = 1;
13081           sw_if_index = tmp_if_index;
13082         }
13083       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13084         {
13085           sw_if_index_set = 1;
13086           sw_if_index = tmp_if_index;
13087         }
13088       else if (unformat (input, "p %d", &priority))
13089         {
13090           priority_set = 1;
13091         }
13092       else if (unformat (input, "w %d", &weight))
13093         {
13094           weight_set = 1;
13095         }
13096       else
13097         break;
13098     }
13099
13100   if (locator_set_name_set == 0)
13101     {
13102       errmsg ("missing locator-set name");
13103       return -99;
13104     }
13105
13106   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13107     {
13108       errmsg ("missing sw_if_index");
13109       vec_free (locator_set_name);
13110       return -99;
13111     }
13112
13113   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13114     {
13115       errmsg ("cannot use both params interface name and sw_if_index");
13116       vec_free (locator_set_name);
13117       return -99;
13118     }
13119
13120   if (priority_set == 0)
13121     {
13122       errmsg ("missing locator-set priority");
13123       vec_free (locator_set_name);
13124       return -99;
13125     }
13126
13127   if (weight_set == 0)
13128     {
13129       errmsg ("missing locator-set weight");
13130       vec_free (locator_set_name);
13131       return -99;
13132     }
13133
13134   if (vec_len (locator_set_name) > 64)
13135     {
13136       errmsg ("locator-set name too long");
13137       vec_free (locator_set_name);
13138       return -99;
13139     }
13140   vec_add1 (locator_set_name, 0);
13141
13142   /* Construct the API message */
13143   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
13144
13145   mp->is_add = is_add;
13146   mp->sw_if_index = ntohl (sw_if_index);
13147   mp->priority = priority;
13148   mp->weight = weight;
13149   clib_memcpy (mp->locator_set_name, locator_set_name,
13150                vec_len (locator_set_name));
13151   vec_free (locator_set_name);
13152
13153   /* send it... */
13154   S;
13155
13156   /* Wait for a reply... */
13157   W;
13158
13159   /* NOTREACHED */
13160   return 0;
13161 }
13162
13163 uword
13164 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13165 {
13166   u32 *key_id = va_arg (*args, u32 *);
13167   u8 *s = 0;
13168
13169   if (unformat (input, "%s", &s))
13170     {
13171       if (!strcmp ((char *) s, "sha1"))
13172         key_id[0] = HMAC_SHA_1_96;
13173       else if (!strcmp ((char *) s, "sha256"))
13174         key_id[0] = HMAC_SHA_256_128;
13175       else
13176         {
13177           clib_warning ("invalid key_id: '%s'", s);
13178           key_id[0] = HMAC_NO_KEY;
13179         }
13180     }
13181   else
13182     return 0;
13183
13184   vec_free (s);
13185   return 1;
13186 }
13187
13188 static int
13189 api_lisp_add_del_local_eid (vat_main_t * vam)
13190 {
13191   unformat_input_t *input = vam->input;
13192   vl_api_lisp_add_del_local_eid_t *mp;
13193   f64 timeout = ~0;
13194   u8 is_add = 1;
13195   u8 eid_set = 0;
13196   lisp_eid_vat_t _eid, *eid = &_eid;
13197   u8 *locator_set_name = 0;
13198   u8 locator_set_name_set = 0;
13199   u32 vni = 0;
13200   u16 key_id = 0;
13201   u8 *key = 0;
13202
13203   /* Parse args required to build the message */
13204   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13205     {
13206       if (unformat (input, "del"))
13207         {
13208           is_add = 0;
13209         }
13210       else if (unformat (input, "vni %d", &vni))
13211         {
13212           ;
13213         }
13214       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13215         {
13216           eid_set = 1;
13217         }
13218       else if (unformat (input, "locator-set %s", &locator_set_name))
13219         {
13220           locator_set_name_set = 1;
13221         }
13222       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13223         ;
13224       else if (unformat (input, "secret-key %_%v%_", &key))
13225         ;
13226       else
13227         break;
13228     }
13229
13230   if (locator_set_name_set == 0)
13231     {
13232       errmsg ("missing locator-set name");
13233       return -99;
13234     }
13235
13236   if (0 == eid_set)
13237     {
13238       errmsg ("EID address not set!");
13239       vec_free (locator_set_name);
13240       return -99;
13241     }
13242
13243   if (key && (0 == key_id))
13244     {
13245       errmsg ("invalid key_id!");
13246       return -99;
13247     }
13248
13249   if (vec_len (key) > 64)
13250     {
13251       errmsg ("key too long");
13252       vec_free (key);
13253       return -99;
13254     }
13255
13256   if (vec_len (locator_set_name) > 64)
13257     {
13258       errmsg ("locator-set name too long");
13259       vec_free (locator_set_name);
13260       return -99;
13261     }
13262   vec_add1 (locator_set_name, 0);
13263
13264   /* Construct the API message */
13265   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13266
13267   mp->is_add = is_add;
13268   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13269   mp->eid_type = eid->type;
13270   mp->prefix_len = eid->len;
13271   mp->vni = clib_host_to_net_u32 (vni);
13272   mp->key_id = clib_host_to_net_u16 (key_id);
13273   clib_memcpy (mp->locator_set_name, locator_set_name,
13274                vec_len (locator_set_name));
13275   clib_memcpy (mp->key, key, vec_len (key));
13276
13277   vec_free (locator_set_name);
13278   vec_free (key);
13279
13280   /* send it... */
13281   S;
13282
13283   /* Wait for a reply... */
13284   W;
13285
13286   /* NOTREACHED */
13287   return 0;
13288 }
13289
13290 /* *INDENT-OFF* */
13291 /** Used for transferring locators via VPP API */
13292 typedef CLIB_PACKED(struct
13293 {
13294   u8 is_ip4; /**< is locator an IPv4 address? */
13295   u8 priority; /**< locator priority */
13296   u8 weight;   /**< locator weight */
13297   u8 addr[16]; /**< IPv4/IPv6 address */
13298 }) rloc_t;
13299 /* *INDENT-ON* */
13300
13301 static int
13302 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13303 {
13304   u32 dp_table = 0, vni = 0;;
13305   unformat_input_t *input = vam->input;
13306   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13307   f64 timeout = ~0;
13308   u8 is_add = 1;
13309   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13310   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13311   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13312   u32 action = ~0, w;
13313   ip4_address_t rmt_rloc4, lcl_rloc4;
13314   ip6_address_t rmt_rloc6, lcl_rloc6;
13315   vl_api_lisp_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc =
13316     0;
13317
13318   memset (&rloc, 0, sizeof (rloc));
13319
13320   /* Parse args required to build the message */
13321   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13322     {
13323       if (unformat (input, "del"))
13324         is_add = 0;
13325       else if (unformat (input, "add"))
13326         is_add = 1;
13327       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13328         {
13329           rmt_eid_set = 1;
13330         }
13331       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13332         {
13333           lcl_eid_set = 1;
13334         }
13335       else if (unformat (input, "vrf %d", &dp_table))
13336         ;
13337       else if (unformat (input, "bd %d", &dp_table))
13338         ;
13339       else if (unformat (input, "vni %d", &vni))
13340         ;
13341       else if (unformat (input, "w %d", &w))
13342         {
13343           if (!curr_rloc)
13344             {
13345               errmsg ("No RLOC configured for setting priority/weight!");
13346               return -99;
13347             }
13348           curr_rloc->weight = w;
13349         }
13350       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13351                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13352         {
13353           rloc.is_ip4 = 1;
13354
13355           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13356           rloc.weight = 0;
13357           vec_add1 (lcl_locs, rloc);
13358
13359           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13360           vec_add1 (rmt_locs, rloc);
13361           /* weight saved in rmt loc */
13362           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13363         }
13364       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13365                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13366         {
13367           rloc.is_ip4 = 0;
13368           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13369           rloc.weight = 0;
13370           vec_add1 (lcl_locs, rloc);
13371
13372           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13373           vec_add1 (rmt_locs, rloc);
13374           /* weight saved in rmt loc */
13375           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13376         }
13377       else if (unformat (input, "action %d", &action))
13378         {
13379           ;
13380         }
13381       else
13382         {
13383           clib_warning ("parse error '%U'", format_unformat_error, input);
13384           return -99;
13385         }
13386     }
13387
13388   if (!rmt_eid_set)
13389     {
13390       errmsg ("remote eid addresses not set");
13391       return -99;
13392     }
13393
13394   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13395     {
13396       errmsg ("eid types don't match");
13397       return -99;
13398     }
13399
13400   if (0 == rmt_locs && (u32) ~ 0 == action)
13401     {
13402       errmsg ("action not set for negative mapping");
13403       return -99;
13404     }
13405
13406   /* Construct the API message */
13407   M2 (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry,
13408       sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs) * 2);
13409
13410   mp->is_add = is_add;
13411   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13412   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13413   mp->eid_type = rmt_eid->type;
13414   mp->dp_table = clib_host_to_net_u32 (dp_table);
13415   mp->vni = clib_host_to_net_u32 (vni);
13416   mp->rmt_len = rmt_eid->len;
13417   mp->lcl_len = lcl_eid->len;
13418   mp->action = action;
13419
13420   if (0 != rmt_locs && 0 != lcl_locs)
13421     {
13422       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13423       clib_memcpy (mp->locs, lcl_locs,
13424                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs)));
13425
13426       u32 offset = sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs);
13427       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13428                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs)));
13429     }
13430   vec_free (lcl_locs);
13431   vec_free (rmt_locs);
13432
13433   /* send it... */
13434   S;
13435
13436   /* Wait for a reply... */
13437   W;
13438
13439   /* NOTREACHED */
13440   return 0;
13441 }
13442
13443 static int
13444 api_lisp_add_del_map_server (vat_main_t * vam)
13445 {
13446   unformat_input_t *input = vam->input;
13447   vl_api_lisp_add_del_map_server_t *mp;
13448   f64 timeout = ~0;
13449   u8 is_add = 1;
13450   u8 ipv4_set = 0;
13451   u8 ipv6_set = 0;
13452   ip4_address_t ipv4;
13453   ip6_address_t ipv6;
13454
13455   /* Parse args required to build the message */
13456   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13457     {
13458       if (unformat (input, "del"))
13459         {
13460           is_add = 0;
13461         }
13462       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13463         {
13464           ipv4_set = 1;
13465         }
13466       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13467         {
13468           ipv6_set = 1;
13469         }
13470       else
13471         break;
13472     }
13473
13474   if (ipv4_set && ipv6_set)
13475     {
13476       errmsg ("both eid v4 and v6 addresses set");
13477       return -99;
13478     }
13479
13480   if (!ipv4_set && !ipv6_set)
13481     {
13482       errmsg ("eid addresses not set");
13483       return -99;
13484     }
13485
13486   /* Construct the API message */
13487   M (LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server);
13488
13489   mp->is_add = is_add;
13490   if (ipv6_set)
13491     {
13492       mp->is_ipv6 = 1;
13493       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13494     }
13495   else
13496     {
13497       mp->is_ipv6 = 0;
13498       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13499     }
13500
13501   /* send it... */
13502   S;
13503
13504   /* Wait for a reply... */
13505   W;
13506
13507   /* NOTREACHED */
13508   return 0;
13509 }
13510
13511 static int
13512 api_lisp_add_del_map_resolver (vat_main_t * vam)
13513 {
13514   unformat_input_t *input = vam->input;
13515   vl_api_lisp_add_del_map_resolver_t *mp;
13516   f64 timeout = ~0;
13517   u8 is_add = 1;
13518   u8 ipv4_set = 0;
13519   u8 ipv6_set = 0;
13520   ip4_address_t ipv4;
13521   ip6_address_t ipv6;
13522
13523   /* Parse args required to build the message */
13524   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13525     {
13526       if (unformat (input, "del"))
13527         {
13528           is_add = 0;
13529         }
13530       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13531         {
13532           ipv4_set = 1;
13533         }
13534       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13535         {
13536           ipv6_set = 1;
13537         }
13538       else
13539         break;
13540     }
13541
13542   if (ipv4_set && ipv6_set)
13543     {
13544       errmsg ("both eid v4 and v6 addresses set");
13545       return -99;
13546     }
13547
13548   if (!ipv4_set && !ipv6_set)
13549     {
13550       errmsg ("eid addresses not set");
13551       return -99;
13552     }
13553
13554   /* Construct the API message */
13555   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13556
13557   mp->is_add = is_add;
13558   if (ipv6_set)
13559     {
13560       mp->is_ipv6 = 1;
13561       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13562     }
13563   else
13564     {
13565       mp->is_ipv6 = 0;
13566       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13567     }
13568
13569   /* send it... */
13570   S;
13571
13572   /* Wait for a reply... */
13573   W;
13574
13575   /* NOTREACHED */
13576   return 0;
13577 }
13578
13579 static int
13580 api_lisp_gpe_enable_disable (vat_main_t * vam)
13581 {
13582   unformat_input_t *input = vam->input;
13583   vl_api_lisp_gpe_enable_disable_t *mp;
13584   f64 timeout = ~0;
13585   u8 is_set = 0;
13586   u8 is_en = 1;
13587
13588   /* Parse args required to build the message */
13589   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13590     {
13591       if (unformat (input, "enable"))
13592         {
13593           is_set = 1;
13594           is_en = 1;
13595         }
13596       else if (unformat (input, "disable"))
13597         {
13598           is_set = 1;
13599           is_en = 0;
13600         }
13601       else
13602         break;
13603     }
13604
13605   if (is_set == 0)
13606     {
13607       errmsg ("Value not set");
13608       return -99;
13609     }
13610
13611   /* Construct the API message */
13612   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13613
13614   mp->is_en = is_en;
13615
13616   /* send it... */
13617   S;
13618
13619   /* Wait for a reply... */
13620   W;
13621
13622   /* NOTREACHED */
13623   return 0;
13624 }
13625
13626 static int
13627 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13628 {
13629   unformat_input_t *input = vam->input;
13630   vl_api_lisp_rloc_probe_enable_disable_t *mp;
13631   f64 timeout = ~0;
13632   u8 is_set = 0;
13633   u8 is_en = 0;
13634
13635   /* Parse args required to build the message */
13636   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13637     {
13638       if (unformat (input, "enable"))
13639         {
13640           is_set = 1;
13641           is_en = 1;
13642         }
13643       else if (unformat (input, "disable"))
13644         is_set = 1;
13645       else
13646         break;
13647     }
13648
13649   if (!is_set)
13650     {
13651       errmsg ("Value not set");
13652       return -99;
13653     }
13654
13655   /* Construct the API message */
13656   M (LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable);
13657
13658   mp->is_enabled = is_en;
13659
13660   /* send it... */
13661   S;
13662
13663   /* Wait for a reply... */
13664   W;
13665
13666   /* NOTREACHED */
13667   return 0;
13668 }
13669
13670 static int
13671 api_lisp_map_register_enable_disable (vat_main_t * vam)
13672 {
13673   unformat_input_t *input = vam->input;
13674   vl_api_lisp_map_register_enable_disable_t *mp;
13675   f64 timeout = ~0;
13676   u8 is_set = 0;
13677   u8 is_en = 0;
13678
13679   /* Parse args required to build the message */
13680   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13681     {
13682       if (unformat (input, "enable"))
13683         {
13684           is_set = 1;
13685           is_en = 1;
13686         }
13687       else if (unformat (input, "disable"))
13688         is_set = 1;
13689       else
13690         break;
13691     }
13692
13693   if (!is_set)
13694     {
13695       errmsg ("Value not set");
13696       return -99;
13697     }
13698
13699   /* Construct the API message */
13700   M (LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable);
13701
13702   mp->is_enabled = is_en;
13703
13704   /* send it... */
13705   S;
13706
13707   /* Wait for a reply... */
13708   W;
13709
13710   /* NOTREACHED */
13711   return 0;
13712 }
13713
13714 static int
13715 api_lisp_enable_disable (vat_main_t * vam)
13716 {
13717   unformat_input_t *input = vam->input;
13718   vl_api_lisp_enable_disable_t *mp;
13719   f64 timeout = ~0;
13720   u8 is_set = 0;
13721   u8 is_en = 0;
13722
13723   /* Parse args required to build the message */
13724   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13725     {
13726       if (unformat (input, "enable"))
13727         {
13728           is_set = 1;
13729           is_en = 1;
13730         }
13731       else if (unformat (input, "disable"))
13732         {
13733           is_set = 1;
13734         }
13735       else
13736         break;
13737     }
13738
13739   if (!is_set)
13740     {
13741       errmsg ("Value not set");
13742       return -99;
13743     }
13744
13745   /* Construct the API message */
13746   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13747
13748   mp->is_en = is_en;
13749
13750   /* send it... */
13751   S;
13752
13753   /* Wait for a reply... */
13754   W;
13755
13756   /* NOTREACHED */
13757   return 0;
13758 }
13759
13760 static int
13761 api_show_lisp_map_register_state (vat_main_t * vam)
13762 {
13763   f64 timeout = ~0;
13764   vl_api_show_lisp_map_register_state_t *mp;
13765
13766   M (SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state);
13767
13768   /* send */
13769   S;
13770
13771   /* wait for reply */
13772   W;
13773
13774   return 0;
13775 }
13776
13777 static int
13778 api_show_lisp_rloc_probe_state (vat_main_t * vam)
13779 {
13780   f64 timeout = ~0;
13781   vl_api_show_lisp_rloc_probe_state_t *mp;
13782
13783   M (SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state);
13784
13785   /* send */
13786   S;
13787
13788   /* wait for reply */
13789   W;
13790
13791   return 0;
13792 }
13793
13794 static int
13795 api_show_lisp_map_request_mode (vat_main_t * vam)
13796 {
13797   f64 timeout = ~0;
13798   vl_api_show_lisp_map_request_mode_t *mp;
13799
13800   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13801
13802   /* send */
13803   S;
13804
13805   /* wait for reply */
13806   W;
13807
13808   return 0;
13809 }
13810
13811 static int
13812 api_lisp_map_request_mode (vat_main_t * vam)
13813 {
13814   f64 timeout = ~0;
13815   unformat_input_t *input = vam->input;
13816   vl_api_lisp_map_request_mode_t *mp;
13817   u8 mode = 0;
13818
13819   /* Parse args required to build the message */
13820   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13821     {
13822       if (unformat (input, "dst-only"))
13823         mode = 0;
13824       else if (unformat (input, "src-dst"))
13825         mode = 1;
13826       else
13827         {
13828           errmsg ("parse error '%U'", format_unformat_error, input);
13829           return -99;
13830         }
13831     }
13832
13833   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13834
13835   mp->mode = mode;
13836
13837   /* send */
13838   S;
13839
13840   /* wait for reply */
13841   W;
13842
13843   /* notreached */
13844   return 0;
13845 }
13846
13847 /**
13848  * Enable/disable LISP proxy ITR.
13849  *
13850  * @param vam vpp API test context
13851  * @return return code
13852  */
13853 static int
13854 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13855 {
13856   f64 timeout = ~0;
13857   u8 ls_name_set = 0;
13858   unformat_input_t *input = vam->input;
13859   vl_api_lisp_pitr_set_locator_set_t *mp;
13860   u8 is_add = 1;
13861   u8 *ls_name = 0;
13862
13863   /* Parse args required to build the message */
13864   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13865     {
13866       if (unformat (input, "del"))
13867         is_add = 0;
13868       else if (unformat (input, "locator-set %s", &ls_name))
13869         ls_name_set = 1;
13870       else
13871         {
13872           errmsg ("parse error '%U'", format_unformat_error, input);
13873           return -99;
13874         }
13875     }
13876
13877   if (!ls_name_set)
13878     {
13879       errmsg ("locator-set name not set!");
13880       return -99;
13881     }
13882
13883   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13884
13885   mp->is_add = is_add;
13886   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13887   vec_free (ls_name);
13888
13889   /* send */
13890   S;
13891
13892   /* wait for reply */
13893   W;
13894
13895   /* notreached */
13896   return 0;
13897 }
13898
13899 static int
13900 api_show_lisp_pitr (vat_main_t * vam)
13901 {
13902   vl_api_show_lisp_pitr_t *mp;
13903   f64 timeout = ~0;
13904
13905   if (!vam->json_output)
13906     {
13907       print (vam->ofp, "%=20s", "lisp status:");
13908     }
13909
13910   M (SHOW_LISP_PITR, show_lisp_pitr);
13911   /* send it... */
13912   S;
13913
13914   /* Wait for a reply... */
13915   W;
13916
13917   /* NOTREACHED */
13918   return 0;
13919 }
13920
13921 /**
13922  * Add/delete mapping between vni and vrf
13923  */
13924 static int
13925 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13926 {
13927   f64 timeout = ~0;
13928   unformat_input_t *input = vam->input;
13929   vl_api_lisp_eid_table_add_del_map_t *mp;
13930   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13931   u32 vni, vrf, bd_index;
13932
13933   /* Parse args required to build the message */
13934   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13935     {
13936       if (unformat (input, "del"))
13937         is_add = 0;
13938       else if (unformat (input, "vrf %d", &vrf))
13939         vrf_set = 1;
13940       else if (unformat (input, "bd_index %d", &bd_index))
13941         bd_index_set = 1;
13942       else if (unformat (input, "vni %d", &vni))
13943         vni_set = 1;
13944       else
13945         break;
13946     }
13947
13948   if (!vni_set || (!vrf_set && !bd_index_set))
13949     {
13950       errmsg ("missing arguments!");
13951       return -99;
13952     }
13953
13954   if (vrf_set && bd_index_set)
13955     {
13956       errmsg ("error: both vrf and bd entered!");
13957       return -99;
13958     }
13959
13960   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13961
13962   mp->is_add = is_add;
13963   mp->vni = htonl (vni);
13964   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13965   mp->is_l2 = bd_index_set;
13966
13967   /* send */
13968   S;
13969
13970   /* wait for reply */
13971   W;
13972
13973   /* notreached */
13974   return 0;
13975 }
13976
13977 uword
13978 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13979 {
13980   u32 *action = va_arg (*args, u32 *);
13981   u8 *s = 0;
13982
13983   if (unformat (input, "%s", &s))
13984     {
13985       if (!strcmp ((char *) s, "no-action"))
13986         action[0] = 0;
13987       else if (!strcmp ((char *) s, "natively-forward"))
13988         action[0] = 1;
13989       else if (!strcmp ((char *) s, "send-map-request"))
13990         action[0] = 2;
13991       else if (!strcmp ((char *) s, "drop"))
13992         action[0] = 3;
13993       else
13994         {
13995           clib_warning ("invalid action: '%s'", s);
13996           action[0] = 3;
13997         }
13998     }
13999   else
14000     return 0;
14001
14002   vec_free (s);
14003   return 1;
14004 }
14005
14006 /**
14007  * Add/del remote mapping to/from LISP control plane
14008  *
14009  * @param vam vpp API test context
14010  * @return return code
14011  */
14012 static int
14013 api_lisp_add_del_remote_mapping (vat_main_t * vam)
14014 {
14015   unformat_input_t *input = vam->input;
14016   vl_api_lisp_add_del_remote_mapping_t *mp;
14017   f64 timeout = ~0;
14018   u32 vni = 0;
14019   lisp_eid_vat_t _eid, *eid = &_eid;
14020   lisp_eid_vat_t _seid, *seid = &_seid;
14021   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
14022   u32 action = ~0, p, w, data_len;
14023   ip4_address_t rloc4;
14024   ip6_address_t rloc6;
14025   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
14026
14027   memset (&rloc, 0, sizeof (rloc));
14028
14029   /* Parse args required to build the message */
14030   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14031     {
14032       if (unformat (input, "del-all"))
14033         {
14034           del_all = 1;
14035         }
14036       else if (unformat (input, "del"))
14037         {
14038           is_add = 0;
14039         }
14040       else if (unformat (input, "add"))
14041         {
14042           is_add = 1;
14043         }
14044       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14045         {
14046           eid_set = 1;
14047         }
14048       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14049         {
14050           seid_set = 1;
14051         }
14052       else if (unformat (input, "vni %d", &vni))
14053         {
14054           ;
14055         }
14056       else if (unformat (input, "p %d w %d", &p, &w))
14057         {
14058           if (!curr_rloc)
14059             {
14060               errmsg ("No RLOC configured for setting priority/weight!");
14061               return -99;
14062             }
14063           curr_rloc->priority = p;
14064           curr_rloc->weight = w;
14065         }
14066       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14067         {
14068           rloc.is_ip4 = 1;
14069           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14070           vec_add1 (rlocs, rloc);
14071           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14072         }
14073       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14074         {
14075           rloc.is_ip4 = 0;
14076           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14077           vec_add1 (rlocs, rloc);
14078           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14079         }
14080       else if (unformat (input, "action %U",
14081                          unformat_negative_mapping_action, &action))
14082         {
14083           ;
14084         }
14085       else
14086         {
14087           clib_warning ("parse error '%U'", format_unformat_error, input);
14088           return -99;
14089         }
14090     }
14091
14092   if (0 == eid_set)
14093     {
14094       errmsg ("missing params!");
14095       return -99;
14096     }
14097
14098   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14099     {
14100       errmsg ("no action set for negative map-reply!");
14101       return -99;
14102     }
14103
14104   data_len = vec_len (rlocs) * sizeof (rloc_t);
14105
14106   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
14107   mp->is_add = is_add;
14108   mp->vni = htonl (vni);
14109   mp->action = (u8) action;
14110   mp->is_src_dst = seid_set;
14111   mp->eid_len = eid->len;
14112   mp->seid_len = seid->len;
14113   mp->del_all = del_all;
14114   mp->eid_type = eid->type;
14115   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14116   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14117
14118   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14119   clib_memcpy (mp->rlocs, rlocs, data_len);
14120   vec_free (rlocs);
14121
14122   /* send it... */
14123   S;
14124
14125   /* Wait for a reply... */
14126   W;
14127
14128   /* NOTREACHED */
14129   return 0;
14130 }
14131
14132 /**
14133  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14134  * forwarding entries in data-plane accordingly.
14135  *
14136  * @param vam vpp API test context
14137  * @return return code
14138  */
14139 static int
14140 api_lisp_add_del_adjacency (vat_main_t * vam)
14141 {
14142   unformat_input_t *input = vam->input;
14143   vl_api_lisp_add_del_adjacency_t *mp;
14144   f64 timeout = ~0;
14145   u32 vni = 0;
14146   ip4_address_t leid4, reid4;
14147   ip6_address_t leid6, reid6;
14148   u8 reid_mac[6] = { 0 };
14149   u8 leid_mac[6] = { 0 };
14150   u8 reid_type, leid_type;
14151   u32 leid_len = 0, reid_len = 0, len;
14152   u8 is_add = 1;
14153
14154   leid_type = reid_type = (u8) ~ 0;
14155
14156   /* Parse args required to build the message */
14157   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14158     {
14159       if (unformat (input, "del"))
14160         {
14161           is_add = 0;
14162         }
14163       else if (unformat (input, "add"))
14164         {
14165           is_add = 1;
14166         }
14167       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14168                          &reid4, &len))
14169         {
14170           reid_type = 0;        /* ipv4 */
14171           reid_len = len;
14172         }
14173       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14174                          &reid6, &len))
14175         {
14176           reid_type = 1;        /* ipv6 */
14177           reid_len = len;
14178         }
14179       else if (unformat (input, "reid %U", unformat_ethernet_address,
14180                          reid_mac))
14181         {
14182           reid_type = 2;        /* mac */
14183         }
14184       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14185                          &leid4, &len))
14186         {
14187           leid_type = 0;        /* ipv4 */
14188           leid_len = len;
14189         }
14190       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14191                          &leid6, &len))
14192         {
14193           leid_type = 1;        /* ipv6 */
14194           leid_len = len;
14195         }
14196       else if (unformat (input, "leid %U", unformat_ethernet_address,
14197                          leid_mac))
14198         {
14199           leid_type = 2;        /* mac */
14200         }
14201       else if (unformat (input, "vni %d", &vni))
14202         {
14203           ;
14204         }
14205       else
14206         {
14207           errmsg ("parse error '%U'", format_unformat_error, input);
14208           return -99;
14209         }
14210     }
14211
14212   if ((u8) ~ 0 == reid_type)
14213     {
14214       errmsg ("missing params!");
14215       return -99;
14216     }
14217
14218   if (leid_type != reid_type)
14219     {
14220       errmsg ("remote and local EIDs are of different types!");
14221       return -99;
14222     }
14223
14224   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
14225   mp->is_add = is_add;
14226   mp->vni = htonl (vni);
14227   mp->leid_len = leid_len;
14228   mp->reid_len = reid_len;
14229   mp->eid_type = reid_type;
14230
14231   switch (mp->eid_type)
14232     {
14233     case 0:
14234       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14235       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14236       break;
14237     case 1:
14238       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14239       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14240       break;
14241     case 2:
14242       clib_memcpy (mp->leid, leid_mac, 6);
14243       clib_memcpy (mp->reid, reid_mac, 6);
14244       break;
14245     default:
14246       errmsg ("unknown EID type %d!", mp->eid_type);
14247       return 0;
14248     }
14249
14250   /* send it... */
14251   S;
14252
14253   /* Wait for a reply... */
14254   W;
14255
14256   /* NOTREACHED */
14257   return 0;
14258 }
14259
14260 static int
14261 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14262 {
14263   unformat_input_t *input = vam->input;
14264   vl_api_lisp_gpe_add_del_iface_t *mp;
14265   f64 timeout = ~0;
14266   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14267   u32 dp_table = 0, vni = 0;
14268
14269   /* Parse args required to build the message */
14270   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14271     {
14272       if (unformat (input, "up"))
14273         {
14274           action_set = 1;
14275           is_add = 1;
14276         }
14277       else if (unformat (input, "down"))
14278         {
14279           action_set = 1;
14280           is_add = 0;
14281         }
14282       else if (unformat (input, "table_id %d", &dp_table))
14283         {
14284           dp_table_set = 1;
14285         }
14286       else if (unformat (input, "bd_id %d", &dp_table))
14287         {
14288           dp_table_set = 1;
14289           is_l2 = 1;
14290         }
14291       else if (unformat (input, "vni %d", &vni))
14292         {
14293           vni_set = 1;
14294         }
14295       else
14296         break;
14297     }
14298
14299   if (action_set == 0)
14300     {
14301       errmsg ("Action not set");
14302       return -99;
14303     }
14304   if (dp_table_set == 0 || vni_set == 0)
14305     {
14306       errmsg ("vni and dp_table must be set");
14307       return -99;
14308     }
14309
14310   /* Construct the API message */
14311   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
14312
14313   mp->is_add = is_add;
14314   mp->dp_table = dp_table;
14315   mp->is_l2 = is_l2;
14316   mp->vni = vni;
14317
14318   /* send it... */
14319   S;
14320
14321   /* Wait for a reply... */
14322   W;
14323
14324   /* NOTREACHED */
14325   return 0;
14326 }
14327
14328 /**
14329  * Add/del map request itr rlocs from LISP control plane and updates
14330  *
14331  * @param vam vpp API test context
14332  * @return return code
14333  */
14334 static int
14335 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14336 {
14337   unformat_input_t *input = vam->input;
14338   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14339   f64 timeout = ~0;
14340   u8 *locator_set_name = 0;
14341   u8 locator_set_name_set = 0;
14342   u8 is_add = 1;
14343
14344   /* Parse args required to build the message */
14345   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14346     {
14347       if (unformat (input, "del"))
14348         {
14349           is_add = 0;
14350         }
14351       else if (unformat (input, "%_%v%_", &locator_set_name))
14352         {
14353           locator_set_name_set = 1;
14354         }
14355       else
14356         {
14357           clib_warning ("parse error '%U'", format_unformat_error, input);
14358           return -99;
14359         }
14360     }
14361
14362   if (is_add && !locator_set_name_set)
14363     {
14364       errmsg ("itr-rloc is not set!");
14365       return -99;
14366     }
14367
14368   if (is_add && vec_len (locator_set_name) > 64)
14369     {
14370       errmsg ("itr-rloc locator-set name too long");
14371       vec_free (locator_set_name);
14372       return -99;
14373     }
14374
14375   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
14376   mp->is_add = is_add;
14377   if (is_add)
14378     {
14379       clib_memcpy (mp->locator_set_name, locator_set_name,
14380                    vec_len (locator_set_name));
14381     }
14382   else
14383     {
14384       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14385     }
14386   vec_free (locator_set_name);
14387
14388   /* send it... */
14389   S;
14390
14391   /* Wait for a reply... */
14392   W;
14393
14394   /* NOTREACHED */
14395   return 0;
14396 }
14397
14398 static int
14399 api_lisp_locator_dump (vat_main_t * vam)
14400 {
14401   unformat_input_t *input = vam->input;
14402   vl_api_lisp_locator_dump_t *mp;
14403   f64 timeout = ~0;
14404   u8 is_index_set = 0, is_name_set = 0;
14405   u8 *ls_name = 0;
14406   u32 ls_index = ~0;
14407
14408   /* Parse args required to build the message */
14409   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14410     {
14411       if (unformat (input, "ls_name %_%v%_", &ls_name))
14412         {
14413           is_name_set = 1;
14414         }
14415       else if (unformat (input, "ls_index %d", &ls_index))
14416         {
14417           is_index_set = 1;
14418         }
14419       else
14420         {
14421           errmsg ("parse error '%U'", format_unformat_error, input);
14422           return -99;
14423         }
14424     }
14425
14426   if (!is_index_set && !is_name_set)
14427     {
14428       errmsg ("error: expected one of index or name!");
14429       return -99;
14430     }
14431
14432   if (is_index_set && is_name_set)
14433     {
14434       errmsg ("error: only one param expected!");
14435       return -99;
14436     }
14437
14438   if (vec_len (ls_name) > 62)
14439     {
14440       errmsg ("error: locator set name too long!");
14441       return -99;
14442     }
14443
14444   if (!vam->json_output)
14445     {
14446       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14447     }
14448
14449   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
14450   mp->is_index_set = is_index_set;
14451
14452   if (is_index_set)
14453     mp->ls_index = clib_host_to_net_u32 (ls_index);
14454   else
14455     {
14456       vec_add1 (ls_name, 0);
14457       strncpy ((char *) mp->ls_name, (char *) ls_name,
14458                sizeof (mp->ls_name) - 1);
14459     }
14460
14461   /* send it... */
14462   S;
14463
14464   /* Use a control ping for synchronization */
14465   {
14466     vl_api_control_ping_t *mp;
14467     M (CONTROL_PING, control_ping);
14468     S;
14469   }
14470   /* Wait for a reply... */
14471   W;
14472
14473   /* NOTREACHED */
14474   return 0;
14475 }
14476
14477 static int
14478 api_lisp_locator_set_dump (vat_main_t * vam)
14479 {
14480   vl_api_lisp_locator_set_dump_t *mp;
14481   unformat_input_t *input = vam->input;
14482   f64 timeout = ~0;
14483   u8 filter = 0;
14484
14485   /* Parse args required to build the message */
14486   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14487     {
14488       if (unformat (input, "local"))
14489         {
14490           filter = 1;
14491         }
14492       else if (unformat (input, "remote"))
14493         {
14494           filter = 2;
14495         }
14496       else
14497         {
14498           errmsg ("parse error '%U'", format_unformat_error, input);
14499           return -99;
14500         }
14501     }
14502
14503   if (!vam->json_output)
14504     {
14505       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14506     }
14507
14508   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14509
14510   mp->filter = filter;
14511
14512   /* send it... */
14513   S;
14514
14515   /* Use a control ping for synchronization */
14516   {
14517     vl_api_control_ping_t *mp;
14518     M (CONTROL_PING, control_ping);
14519     S;
14520   }
14521   /* Wait for a reply... */
14522   W;
14523
14524   /* NOTREACHED */
14525   return 0;
14526 }
14527
14528 static int
14529 api_lisp_eid_table_map_dump (vat_main_t * vam)
14530 {
14531   u8 is_l2 = 0;
14532   u8 mode_set = 0;
14533   unformat_input_t *input = vam->input;
14534   vl_api_lisp_eid_table_map_dump_t *mp;
14535   f64 timeout = ~0;
14536
14537   /* Parse args required to build the message */
14538   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14539     {
14540       if (unformat (input, "l2"))
14541         {
14542           is_l2 = 1;
14543           mode_set = 1;
14544         }
14545       else if (unformat (input, "l3"))
14546         {
14547           is_l2 = 0;
14548           mode_set = 1;
14549         }
14550       else
14551         {
14552           errmsg ("parse error '%U'", format_unformat_error, input);
14553           return -99;
14554         }
14555     }
14556
14557   if (!mode_set)
14558     {
14559       errmsg ("expected one of 'l2' or 'l3' parameter!");
14560       return -99;
14561     }
14562
14563   if (!vam->json_output)
14564     {
14565       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14566     }
14567
14568   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14569   mp->is_l2 = is_l2;
14570
14571   /* send it... */
14572   S;
14573
14574   /* Use a control ping for synchronization */
14575   {
14576     vl_api_control_ping_t *mp;
14577     M (CONTROL_PING, control_ping);
14578     S;
14579   }
14580   /* Wait for a reply... */
14581   W;
14582
14583   /* NOTREACHED */
14584   return 0;
14585 }
14586
14587 static int
14588 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14589 {
14590   vl_api_lisp_eid_table_vni_dump_t *mp;
14591   f64 timeout = ~0;
14592
14593   if (!vam->json_output)
14594     {
14595       print (vam->ofp, "VNI");
14596     }
14597
14598   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14599
14600   /* send it... */
14601   S;
14602
14603   /* Use a control ping for synchronization */
14604   {
14605     vl_api_control_ping_t *mp;
14606     M (CONTROL_PING, control_ping);
14607     S;
14608   }
14609   /* Wait for a reply... */
14610   W;
14611
14612   /* NOTREACHED */
14613   return 0;
14614 }
14615
14616 static int
14617 api_lisp_eid_table_dump (vat_main_t * vam)
14618 {
14619   unformat_input_t *i = vam->input;
14620   vl_api_lisp_eid_table_dump_t *mp;
14621   f64 timeout = ~0;
14622   struct in_addr ip4;
14623   struct in6_addr ip6;
14624   u8 mac[6];
14625   u8 eid_type = ~0, eid_set = 0;
14626   u32 prefix_length = ~0, t, vni = 0;
14627   u8 filter = 0;
14628
14629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14630     {
14631       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14632         {
14633           eid_set = 1;
14634           eid_type = 0;
14635           prefix_length = t;
14636         }
14637       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14638         {
14639           eid_set = 1;
14640           eid_type = 1;
14641           prefix_length = t;
14642         }
14643       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14644         {
14645           eid_set = 1;
14646           eid_type = 2;
14647         }
14648       else if (unformat (i, "vni %d", &t))
14649         {
14650           vni = t;
14651         }
14652       else if (unformat (i, "local"))
14653         {
14654           filter = 1;
14655         }
14656       else if (unformat (i, "remote"))
14657         {
14658           filter = 2;
14659         }
14660       else
14661         {
14662           errmsg ("parse error '%U'", format_unformat_error, i);
14663           return -99;
14664         }
14665     }
14666
14667   if (!vam->json_output)
14668     {
14669       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
14670              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14671     }
14672
14673   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14674
14675   mp->filter = filter;
14676   if (eid_set)
14677     {
14678       mp->eid_set = 1;
14679       mp->vni = htonl (vni);
14680       mp->eid_type = eid_type;
14681       switch (eid_type)
14682         {
14683         case 0:
14684           mp->prefix_length = prefix_length;
14685           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14686           break;
14687         case 1:
14688           mp->prefix_length = prefix_length;
14689           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14690           break;
14691         case 2:
14692           clib_memcpy (mp->eid, mac, sizeof (mac));
14693           break;
14694         default:
14695           errmsg ("unknown EID type %d!", eid_type);
14696           return -99;
14697         }
14698     }
14699
14700   /* send it... */
14701   S;
14702
14703   /* Use a control ping for synchronization */
14704   {
14705     vl_api_control_ping_t *mp;
14706     M (CONTROL_PING, control_ping);
14707     S;
14708   }
14709
14710   /* Wait for a reply... */
14711   W;
14712
14713   /* NOTREACHED */
14714   return 0;
14715 }
14716
14717 static int
14718 api_lisp_adjacencies_get (vat_main_t * vam)
14719 {
14720   unformat_input_t *i = vam->input;
14721   vl_api_lisp_adjacencies_get_t *mp;
14722   f64 timeout = ~0;
14723   u8 vni_set = 0;
14724   u32 vni = ~0;
14725
14726   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14727     {
14728       if (unformat (i, "vni %d", &vni))
14729         {
14730           vni_set = 1;
14731         }
14732       else
14733         {
14734           errmsg ("parse error '%U'", format_unformat_error, i);
14735           return -99;
14736         }
14737     }
14738
14739   if (!vni_set)
14740     {
14741       errmsg ("vni not set!");
14742       return -99;
14743     }
14744
14745   if (!vam->json_output)
14746     {
14747       print (vam->ofp, "%s %40s", "leid", "reid");
14748     }
14749
14750   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14751   mp->vni = clib_host_to_net_u32 (vni);
14752
14753   /* send it... */
14754   S;
14755
14756   /* Wait for a reply... */
14757   W;
14758
14759   /* NOTREACHED */
14760   return 0;
14761 }
14762
14763 static int
14764 api_lisp_map_server_dump (vat_main_t * vam)
14765 {
14766   vl_api_lisp_map_server_dump_t *mp;
14767   f64 timeout = ~0;
14768
14769   if (!vam->json_output)
14770     {
14771       print (vam->ofp, "%=20s", "Map server");
14772     }
14773
14774   M (LISP_MAP_SERVER_DUMP, lisp_map_server_dump);
14775   /* send it... */
14776   S;
14777
14778   /* Use a control ping for synchronization */
14779   {
14780     vl_api_control_ping_t *mp;
14781     M (CONTROL_PING, control_ping);
14782     S;
14783   }
14784   /* Wait for a reply... */
14785   W;
14786
14787   /* NOTREACHED */
14788   return 0;
14789 }
14790
14791 static int
14792 api_lisp_map_resolver_dump (vat_main_t * vam)
14793 {
14794   vl_api_lisp_map_resolver_dump_t *mp;
14795   f64 timeout = ~0;
14796
14797   if (!vam->json_output)
14798     {
14799       print (vam->ofp, "%=20s", "Map resolver");
14800     }
14801
14802   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14803   /* send it... */
14804   S;
14805
14806   /* Use a control ping for synchronization */
14807   {
14808     vl_api_control_ping_t *mp;
14809     M (CONTROL_PING, control_ping);
14810     S;
14811   }
14812   /* Wait for a reply... */
14813   W;
14814
14815   /* NOTREACHED */
14816   return 0;
14817 }
14818
14819 static int
14820 api_show_lisp_status (vat_main_t * vam)
14821 {
14822   vl_api_show_lisp_status_t *mp;
14823   f64 timeout = ~0;
14824
14825   if (!vam->json_output)
14826     {
14827       print (vam->ofp, "%-20s%-16s", "lisp status", "locator-set");
14828     }
14829
14830   M (SHOW_LISP_STATUS, show_lisp_status);
14831   /* send it... */
14832   S;
14833   /* Wait for a reply... */
14834   W;
14835
14836   /* NOTREACHED */
14837   return 0;
14838 }
14839
14840 static int
14841 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14842 {
14843   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14844   f64 timeout = ~0;
14845
14846   if (!vam->json_output)
14847     {
14848       print (vam->ofp, "%=20s", "itr-rlocs:");
14849     }
14850
14851   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14852   /* send it... */
14853   S;
14854   /* Wait for a reply... */
14855   W;
14856
14857   /* NOTREACHED */
14858   return 0;
14859 }
14860
14861 static int
14862 api_af_packet_create (vat_main_t * vam)
14863 {
14864   unformat_input_t *i = vam->input;
14865   vl_api_af_packet_create_t *mp;
14866   f64 timeout;
14867   u8 *host_if_name = 0;
14868   u8 hw_addr[6];
14869   u8 random_hw_addr = 1;
14870
14871   memset (hw_addr, 0, sizeof (hw_addr));
14872
14873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14874     {
14875       if (unformat (i, "name %s", &host_if_name))
14876         vec_add1 (host_if_name, 0);
14877       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14878         random_hw_addr = 0;
14879       else
14880         break;
14881     }
14882
14883   if (!vec_len (host_if_name))
14884     {
14885       errmsg ("host-interface name must be specified");
14886       return -99;
14887     }
14888
14889   if (vec_len (host_if_name) > 64)
14890     {
14891       errmsg ("host-interface name too long");
14892       return -99;
14893     }
14894
14895   M (AF_PACKET_CREATE, af_packet_create);
14896
14897   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14898   clib_memcpy (mp->hw_addr, hw_addr, 6);
14899   mp->use_random_hw_addr = random_hw_addr;
14900   vec_free (host_if_name);
14901
14902   S;
14903   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14904   /* NOTREACHED */
14905   return 0;
14906 }
14907
14908 static int
14909 api_af_packet_delete (vat_main_t * vam)
14910 {
14911   unformat_input_t *i = vam->input;
14912   vl_api_af_packet_delete_t *mp;
14913   f64 timeout;
14914   u8 *host_if_name = 0;
14915
14916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14917     {
14918       if (unformat (i, "name %s", &host_if_name))
14919         vec_add1 (host_if_name, 0);
14920       else
14921         break;
14922     }
14923
14924   if (!vec_len (host_if_name))
14925     {
14926       errmsg ("host-interface name must be specified");
14927       return -99;
14928     }
14929
14930   if (vec_len (host_if_name) > 64)
14931     {
14932       errmsg ("host-interface name too long");
14933       return -99;
14934     }
14935
14936   M (AF_PACKET_DELETE, af_packet_delete);
14937
14938   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14939   vec_free (host_if_name);
14940
14941   S;
14942   W;
14943   /* NOTREACHED */
14944   return 0;
14945 }
14946
14947 static int
14948 api_policer_add_del (vat_main_t * vam)
14949 {
14950   unformat_input_t *i = vam->input;
14951   vl_api_policer_add_del_t *mp;
14952   f64 timeout;
14953   u8 is_add = 1;
14954   u8 *name = 0;
14955   u32 cir = 0;
14956   u32 eir = 0;
14957   u64 cb = 0;
14958   u64 eb = 0;
14959   u8 rate_type = 0;
14960   u8 round_type = 0;
14961   u8 type = 0;
14962   u8 color_aware = 0;
14963   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14964
14965   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14966   conform_action.dscp = 0;
14967   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14968   exceed_action.dscp = 0;
14969   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14970   violate_action.dscp = 0;
14971
14972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14973     {
14974       if (unformat (i, "del"))
14975         is_add = 0;
14976       else if (unformat (i, "name %s", &name))
14977         vec_add1 (name, 0);
14978       else if (unformat (i, "cir %u", &cir))
14979         ;
14980       else if (unformat (i, "eir %u", &eir))
14981         ;
14982       else if (unformat (i, "cb %u", &cb))
14983         ;
14984       else if (unformat (i, "eb %u", &eb))
14985         ;
14986       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14987                          &rate_type))
14988         ;
14989       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14990                          &round_type))
14991         ;
14992       else if (unformat (i, "type %U", unformat_policer_type, &type))
14993         ;
14994       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14995                          &conform_action))
14996         ;
14997       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14998                          &exceed_action))
14999         ;
15000       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
15001                          &violate_action))
15002         ;
15003       else if (unformat (i, "color-aware"))
15004         color_aware = 1;
15005       else
15006         break;
15007     }
15008
15009   if (!vec_len (name))
15010     {
15011       errmsg ("policer name must be specified");
15012       return -99;
15013     }
15014
15015   if (vec_len (name) > 64)
15016     {
15017       errmsg ("policer name too long");
15018       return -99;
15019     }
15020
15021   M (POLICER_ADD_DEL, policer_add_del);
15022
15023   clib_memcpy (mp->name, name, vec_len (name));
15024   vec_free (name);
15025   mp->is_add = is_add;
15026   mp->cir = cir;
15027   mp->eir = eir;
15028   mp->cb = cb;
15029   mp->eb = eb;
15030   mp->rate_type = rate_type;
15031   mp->round_type = round_type;
15032   mp->type = type;
15033   mp->conform_action_type = conform_action.action_type;
15034   mp->conform_dscp = conform_action.dscp;
15035   mp->exceed_action_type = exceed_action.action_type;
15036   mp->exceed_dscp = exceed_action.dscp;
15037   mp->violate_action_type = violate_action.action_type;
15038   mp->violate_dscp = violate_action.dscp;
15039   mp->color_aware = color_aware;
15040
15041   S;
15042   W;
15043   /* NOTREACHED */
15044   return 0;
15045 }
15046
15047 static int
15048 api_policer_dump (vat_main_t * vam)
15049 {
15050   unformat_input_t *i = vam->input;
15051   vl_api_policer_dump_t *mp;
15052   f64 timeout = ~0;
15053   u8 *match_name = 0;
15054   u8 match_name_valid = 0;
15055
15056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15057     {
15058       if (unformat (i, "name %s", &match_name))
15059         {
15060           vec_add1 (match_name, 0);
15061           match_name_valid = 1;
15062         }
15063       else
15064         break;
15065     }
15066
15067   M (POLICER_DUMP, policer_dump);
15068   mp->match_name_valid = match_name_valid;
15069   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15070   vec_free (match_name);
15071   /* send it... */
15072   S;
15073
15074   /* Use a control ping for synchronization */
15075   {
15076     vl_api_control_ping_t *mp;
15077     M (CONTROL_PING, control_ping);
15078     S;
15079   }
15080   /* Wait for a reply... */
15081   W;
15082
15083   /* NOTREACHED */
15084   return 0;
15085 }
15086
15087 static int
15088 api_policer_classify_set_interface (vat_main_t * vam)
15089 {
15090   unformat_input_t *i = vam->input;
15091   vl_api_policer_classify_set_interface_t *mp;
15092   f64 timeout;
15093   u32 sw_if_index;
15094   int sw_if_index_set;
15095   u32 ip4_table_index = ~0;
15096   u32 ip6_table_index = ~0;
15097   u32 l2_table_index = ~0;
15098   u8 is_add = 1;
15099
15100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15101     {
15102       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15103         sw_if_index_set = 1;
15104       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15105         sw_if_index_set = 1;
15106       else if (unformat (i, "del"))
15107         is_add = 0;
15108       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15109         ;
15110       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15111         ;
15112       else if (unformat (i, "l2-table %d", &l2_table_index))
15113         ;
15114       else
15115         {
15116           clib_warning ("parse error '%U'", format_unformat_error, i);
15117           return -99;
15118         }
15119     }
15120
15121   if (sw_if_index_set == 0)
15122     {
15123       errmsg ("missing interface name or sw_if_index");
15124       return -99;
15125     }
15126
15127   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
15128
15129   mp->sw_if_index = ntohl (sw_if_index);
15130   mp->ip4_table_index = ntohl (ip4_table_index);
15131   mp->ip6_table_index = ntohl (ip6_table_index);
15132   mp->l2_table_index = ntohl (l2_table_index);
15133   mp->is_add = is_add;
15134
15135   S;
15136   W;
15137   /* NOTREACHED */
15138   return 0;
15139 }
15140
15141 static int
15142 api_policer_classify_dump (vat_main_t * vam)
15143 {
15144   unformat_input_t *i = vam->input;
15145   vl_api_policer_classify_dump_t *mp;
15146   f64 timeout = ~0;
15147   u8 type = POLICER_CLASSIFY_N_TABLES;
15148
15149   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15150     ;
15151   else
15152     {
15153       errmsg ("classify table type must be specified");
15154       return -99;
15155     }
15156
15157   if (!vam->json_output)
15158     {
15159       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15160     }
15161
15162   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
15163   mp->type = type;
15164   /* send it... */
15165   S;
15166
15167   /* Use a control ping for synchronization */
15168   {
15169     vl_api_control_ping_t *mp;
15170     M (CONTROL_PING, control_ping);
15171     S;
15172   }
15173   /* Wait for a reply... */
15174   W;
15175
15176   /* NOTREACHED */
15177   return 0;
15178 }
15179
15180 static int
15181 api_netmap_create (vat_main_t * vam)
15182 {
15183   unformat_input_t *i = vam->input;
15184   vl_api_netmap_create_t *mp;
15185   f64 timeout;
15186   u8 *if_name = 0;
15187   u8 hw_addr[6];
15188   u8 random_hw_addr = 1;
15189   u8 is_pipe = 0;
15190   u8 is_master = 0;
15191
15192   memset (hw_addr, 0, sizeof (hw_addr));
15193
15194   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15195     {
15196       if (unformat (i, "name %s", &if_name))
15197         vec_add1 (if_name, 0);
15198       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15199         random_hw_addr = 0;
15200       else if (unformat (i, "pipe"))
15201         is_pipe = 1;
15202       else if (unformat (i, "master"))
15203         is_master = 1;
15204       else if (unformat (i, "slave"))
15205         is_master = 0;
15206       else
15207         break;
15208     }
15209
15210   if (!vec_len (if_name))
15211     {
15212       errmsg ("interface name must be specified");
15213       return -99;
15214     }
15215
15216   if (vec_len (if_name) > 64)
15217     {
15218       errmsg ("interface name too long");
15219       return -99;
15220     }
15221
15222   M (NETMAP_CREATE, netmap_create);
15223
15224   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15225   clib_memcpy (mp->hw_addr, hw_addr, 6);
15226   mp->use_random_hw_addr = random_hw_addr;
15227   mp->is_pipe = is_pipe;
15228   mp->is_master = is_master;
15229   vec_free (if_name);
15230
15231   S;
15232   W;
15233   /* NOTREACHED */
15234   return 0;
15235 }
15236
15237 static int
15238 api_netmap_delete (vat_main_t * vam)
15239 {
15240   unformat_input_t *i = vam->input;
15241   vl_api_netmap_delete_t *mp;
15242   f64 timeout;
15243   u8 *if_name = 0;
15244
15245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15246     {
15247       if (unformat (i, "name %s", &if_name))
15248         vec_add1 (if_name, 0);
15249       else
15250         break;
15251     }
15252
15253   if (!vec_len (if_name))
15254     {
15255       errmsg ("interface name must be specified");
15256       return -99;
15257     }
15258
15259   if (vec_len (if_name) > 64)
15260     {
15261       errmsg ("interface name too long");
15262       return -99;
15263     }
15264
15265   M (NETMAP_DELETE, netmap_delete);
15266
15267   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15268   vec_free (if_name);
15269
15270   S;
15271   W;
15272   /* NOTREACHED */
15273   return 0;
15274 }
15275
15276 static void vl_api_mpls_tunnel_details_t_handler
15277   (vl_api_mpls_tunnel_details_t * mp)
15278 {
15279   vat_main_t *vam = &vat_main;
15280   i32 len = mp->mt_next_hop_n_labels;
15281   i32 i;
15282
15283   print (vam->ofp, "[%d]: via %U %d labels ",
15284          mp->tunnel_index,
15285          format_ip4_address, mp->mt_next_hop,
15286          ntohl (mp->mt_next_hop_sw_if_index));
15287   for (i = 0; i < len; i++)
15288     {
15289       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15290     }
15291   print (vam->ofp, "");
15292 }
15293
15294 static void vl_api_mpls_tunnel_details_t_handler_json
15295   (vl_api_mpls_tunnel_details_t * mp)
15296 {
15297   vat_main_t *vam = &vat_main;
15298   vat_json_node_t *node = NULL;
15299   struct in_addr ip4;
15300   i32 i;
15301   i32 len = mp->mt_next_hop_n_labels;
15302
15303   if (VAT_JSON_ARRAY != vam->json_tree.type)
15304     {
15305       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15306       vat_json_init_array (&vam->json_tree);
15307     }
15308   node = vat_json_array_add (&vam->json_tree);
15309
15310   vat_json_init_object (node);
15311   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15312   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15313   vat_json_object_add_ip4 (node, "next_hop", ip4);
15314   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15315                             ntohl (mp->mt_next_hop_sw_if_index));
15316   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15317   vat_json_object_add_uint (node, "label_count", len);
15318   for (i = 0; i < len; i++)
15319     {
15320       vat_json_object_add_uint (node, "label",
15321                                 ntohl (mp->mt_next_hop_out_labels[i]));
15322     }
15323 }
15324
15325 static int
15326 api_mpls_tunnel_dump (vat_main_t * vam)
15327 {
15328   vl_api_mpls_tunnel_dump_t *mp;
15329   f64 timeout;
15330   i32 index = -1;
15331
15332   /* Parse args required to build the message */
15333   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15334     {
15335       if (!unformat (vam->input, "tunnel_index %d", &index))
15336         {
15337           index = -1;
15338           break;
15339         }
15340     }
15341
15342   print (vam->ofp, "  tunnel_index %d", index);
15343
15344   M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
15345   mp->tunnel_index = htonl (index);
15346   S;
15347
15348   /* Use a control ping for synchronization */
15349   {
15350     vl_api_control_ping_t *mp;
15351     M (CONTROL_PING, control_ping);
15352     S;
15353   }
15354   W;
15355 }
15356
15357 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15358 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15359
15360 static void
15361 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15362 {
15363   vat_main_t *vam = &vat_main;
15364   int count = ntohl (mp->count);
15365   vl_api_fib_path2_t *fp;
15366   int i;
15367
15368   print (vam->ofp,
15369          "table-id %d, label %u, ess_bit %u",
15370          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15371   fp = mp->path;
15372   for (i = 0; i < count; i++)
15373     {
15374       if (fp->afi == IP46_TYPE_IP6)
15375         print (vam->ofp,
15376                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15377                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15378                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15379                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15380                format_ip6_address, fp->next_hop);
15381       else if (fp->afi == IP46_TYPE_IP4)
15382         print (vam->ofp,
15383                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15384                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15385                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15386                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15387                format_ip4_address, fp->next_hop);
15388       fp++;
15389     }
15390 }
15391
15392 static void vl_api_mpls_fib_details_t_handler_json
15393   (vl_api_mpls_fib_details_t * mp)
15394 {
15395   vat_main_t *vam = &vat_main;
15396   int count = ntohl (mp->count);
15397   vat_json_node_t *node = NULL;
15398   struct in_addr ip4;
15399   struct in6_addr ip6;
15400   vl_api_fib_path2_t *fp;
15401   int i;
15402
15403   if (VAT_JSON_ARRAY != vam->json_tree.type)
15404     {
15405       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15406       vat_json_init_array (&vam->json_tree);
15407     }
15408   node = vat_json_array_add (&vam->json_tree);
15409
15410   vat_json_init_object (node);
15411   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15412   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15413   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15414   vat_json_object_add_uint (node, "path_count", count);
15415   fp = mp->path;
15416   for (i = 0; i < count; i++)
15417     {
15418       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15419       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15420       vat_json_object_add_uint (node, "is_local", fp->is_local);
15421       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15422       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15423       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15424       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15425       if (fp->afi == IP46_TYPE_IP4)
15426         {
15427           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15428           vat_json_object_add_ip4 (node, "next_hop", ip4);
15429         }
15430       else if (fp->afi == IP46_TYPE_IP6)
15431         {
15432           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15433           vat_json_object_add_ip6 (node, "next_hop", ip6);
15434         }
15435     }
15436 }
15437
15438 static int
15439 api_mpls_fib_dump (vat_main_t * vam)
15440 {
15441   vl_api_mpls_fib_dump_t *mp;
15442   f64 timeout;
15443
15444   M (MPLS_FIB_DUMP, mpls_fib_dump);
15445   S;
15446
15447   /* Use a control ping for synchronization */
15448   {
15449     vl_api_control_ping_t *mp;
15450     M (CONTROL_PING, control_ping);
15451     S;
15452   }
15453   W;
15454 }
15455
15456 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15457 #define vl_api_ip_fib_details_t_print vl_noop_handler
15458
15459 static void
15460 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15461 {
15462   vat_main_t *vam = &vat_main;
15463   int count = ntohl (mp->count);
15464   vl_api_fib_path_t *fp;
15465   int i;
15466
15467   print (vam->ofp,
15468          "table-id %d, prefix %U/%d",
15469          ntohl (mp->table_id), format_ip4_address, mp->address,
15470          mp->address_length);
15471   fp = mp->path;
15472   for (i = 0; i < count; i++)
15473     {
15474       if (fp->afi == IP46_TYPE_IP6)
15475         print (vam->ofp,
15476                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15477                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15478                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15479                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15480                format_ip6_address, fp->next_hop);
15481       else if (fp->afi == IP46_TYPE_IP4)
15482         print (vam->ofp,
15483                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15484                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15485                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15486                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15487                format_ip4_address, fp->next_hop);
15488       fp++;
15489     }
15490 }
15491
15492 static void vl_api_ip_fib_details_t_handler_json
15493   (vl_api_ip_fib_details_t * mp)
15494 {
15495   vat_main_t *vam = &vat_main;
15496   int count = ntohl (mp->count);
15497   vat_json_node_t *node = NULL;
15498   struct in_addr ip4;
15499   struct in6_addr ip6;
15500   vl_api_fib_path_t *fp;
15501   int i;
15502
15503   if (VAT_JSON_ARRAY != vam->json_tree.type)
15504     {
15505       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15506       vat_json_init_array (&vam->json_tree);
15507     }
15508   node = vat_json_array_add (&vam->json_tree);
15509
15510   vat_json_init_object (node);
15511   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15512   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15513   vat_json_object_add_ip4 (node, "prefix", ip4);
15514   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15515   vat_json_object_add_uint (node, "path_count", count);
15516   fp = mp->path;
15517   for (i = 0; i < count; i++)
15518     {
15519       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15520       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15521       vat_json_object_add_uint (node, "is_local", fp->is_local);
15522       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15523       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15524       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15525       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15526       if (fp->afi == IP46_TYPE_IP4)
15527         {
15528           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15529           vat_json_object_add_ip4 (node, "next_hop", ip4);
15530         }
15531       else if (fp->afi == IP46_TYPE_IP6)
15532         {
15533           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15534           vat_json_object_add_ip6 (node, "next_hop", ip6);
15535         }
15536     }
15537 }
15538
15539 static int
15540 api_ip_fib_dump (vat_main_t * vam)
15541 {
15542   vl_api_ip_fib_dump_t *mp;
15543   f64 timeout;
15544
15545   M (IP_FIB_DUMP, ip_fib_dump);
15546   S;
15547
15548   /* Use a control ping for synchronization */
15549   {
15550     vl_api_control_ping_t *mp;
15551     M (CONTROL_PING, control_ping);
15552     S;
15553   }
15554   W;
15555 }
15556
15557 static void vl_api_ip_neighbor_details_t_handler
15558   (vl_api_ip_neighbor_details_t * mp)
15559 {
15560   vat_main_t *vam = &vat_main;
15561
15562   print (vam->ofp, "%c %U %U",
15563          (mp->is_static) ? 'S' : 'D',
15564          format_ethernet_address, &mp->mac_address,
15565          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15566          &mp->ip_address);
15567 }
15568
15569 static void vl_api_ip_neighbor_details_t_handler_json
15570   (vl_api_ip_neighbor_details_t * mp)
15571 {
15572
15573   vat_main_t *vam = &vat_main;
15574   vat_json_node_t *node;
15575   struct in_addr ip4;
15576   struct in6_addr ip6;
15577
15578   if (VAT_JSON_ARRAY != vam->json_tree.type)
15579     {
15580       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15581       vat_json_init_array (&vam->json_tree);
15582     }
15583   node = vat_json_array_add (&vam->json_tree);
15584
15585   vat_json_init_object (node);
15586   vat_json_object_add_string_copy (node, "flag",
15587                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15588                                    "dynamic");
15589
15590   vat_json_object_add_string_copy (node, "link_layer",
15591                                    format (0, "%U", format_ethernet_address,
15592                                            &mp->mac_address));
15593
15594   if (mp->is_ipv6)
15595     {
15596       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15597       vat_json_object_add_ip6 (node, "ip_address", ip6);
15598     }
15599   else
15600     {
15601       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15602       vat_json_object_add_ip4 (node, "ip_address", ip4);
15603     }
15604 }
15605
15606 static int
15607 api_ip_neighbor_dump (vat_main_t * vam)
15608 {
15609   unformat_input_t *i = vam->input;
15610   vl_api_ip_neighbor_dump_t *mp;
15611   f64 timeout;
15612   u8 is_ipv6 = 0;
15613   u32 sw_if_index = ~0;
15614
15615   /* Parse args required to build the message */
15616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15617     {
15618       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15619         ;
15620       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15621         ;
15622       else if (unformat (i, "ip6"))
15623         is_ipv6 = 1;
15624       else
15625         break;
15626     }
15627
15628   if (sw_if_index == ~0)
15629     {
15630       errmsg ("missing interface name or sw_if_index");
15631       return -99;
15632     }
15633
15634   M (IP_NEIGHBOR_DUMP, ip_neighbor_dump);
15635   mp->is_ipv6 = (u8) is_ipv6;
15636   mp->sw_if_index = ntohl (sw_if_index);
15637   S;
15638
15639   /* Use a control ping for synchronization */
15640   {
15641     vl_api_control_ping_t *mp;
15642     M (CONTROL_PING, control_ping);
15643     S;
15644   }
15645   W;
15646 }
15647
15648 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15649 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15650
15651 static void
15652 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15653 {
15654   vat_main_t *vam = &vat_main;
15655   int count = ntohl (mp->count);
15656   vl_api_fib_path_t *fp;
15657   int i;
15658
15659   print (vam->ofp,
15660          "table-id %d, prefix %U/%d",
15661          ntohl (mp->table_id), format_ip6_address, mp->address,
15662          mp->address_length);
15663   fp = mp->path;
15664   for (i = 0; i < count; i++)
15665     {
15666       if (fp->afi == IP46_TYPE_IP6)
15667         print (vam->ofp,
15668                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15669                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15670                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15671                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15672                format_ip6_address, fp->next_hop);
15673       else if (fp->afi == IP46_TYPE_IP4)
15674         print (vam->ofp,
15675                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15676                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15677                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15678                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15679                format_ip4_address, fp->next_hop);
15680       fp++;
15681     }
15682 }
15683
15684 static void vl_api_ip6_fib_details_t_handler_json
15685   (vl_api_ip6_fib_details_t * mp)
15686 {
15687   vat_main_t *vam = &vat_main;
15688   int count = ntohl (mp->count);
15689   vat_json_node_t *node = NULL;
15690   struct in_addr ip4;
15691   struct in6_addr ip6;
15692   vl_api_fib_path_t *fp;
15693   int i;
15694
15695   if (VAT_JSON_ARRAY != vam->json_tree.type)
15696     {
15697       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15698       vat_json_init_array (&vam->json_tree);
15699     }
15700   node = vat_json_array_add (&vam->json_tree);
15701
15702   vat_json_init_object (node);
15703   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15704   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15705   vat_json_object_add_ip6 (node, "prefix", ip6);
15706   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15707   vat_json_object_add_uint (node, "path_count", count);
15708   fp = mp->path;
15709   for (i = 0; i < count; i++)
15710     {
15711       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15712       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15713       vat_json_object_add_uint (node, "is_local", fp->is_local);
15714       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15715       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15716       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15717       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15718       if (fp->afi == IP46_TYPE_IP4)
15719         {
15720           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15721           vat_json_object_add_ip4 (node, "next_hop", ip4);
15722         }
15723       else if (fp->afi == IP46_TYPE_IP6)
15724         {
15725           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15726           vat_json_object_add_ip6 (node, "next_hop", ip6);
15727         }
15728     }
15729 }
15730
15731 static int
15732 api_ip6_fib_dump (vat_main_t * vam)
15733 {
15734   vl_api_ip6_fib_dump_t *mp;
15735   f64 timeout;
15736
15737   M (IP6_FIB_DUMP, ip6_fib_dump);
15738   S;
15739
15740   /* Use a control ping for synchronization */
15741   {
15742     vl_api_control_ping_t *mp;
15743     M (CONTROL_PING, control_ping);
15744     S;
15745   }
15746   W;
15747 }
15748
15749 int
15750 api_classify_table_ids (vat_main_t * vam)
15751 {
15752   vl_api_classify_table_ids_t *mp;
15753   f64 timeout;
15754
15755   /* Construct the API message */
15756   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15757   mp->context = 0;
15758
15759   S;
15760   W;
15761   /* NOTREACHED */
15762   return 0;
15763 }
15764
15765 int
15766 api_classify_table_by_interface (vat_main_t * vam)
15767 {
15768   unformat_input_t *input = vam->input;
15769   vl_api_classify_table_by_interface_t *mp;
15770   f64 timeout;
15771
15772   u32 sw_if_index = ~0;
15773   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15774     {
15775       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15776         ;
15777       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15778         ;
15779       else
15780         break;
15781     }
15782   if (sw_if_index == ~0)
15783     {
15784       errmsg ("missing interface name or sw_if_index");
15785       return -99;
15786     }
15787
15788   /* Construct the API message */
15789   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15790   mp->context = 0;
15791   mp->sw_if_index = ntohl (sw_if_index);
15792
15793   S;
15794   W;
15795   /* NOTREACHED */
15796   return 0;
15797 }
15798
15799 int
15800 api_classify_table_info (vat_main_t * vam)
15801 {
15802   unformat_input_t *input = vam->input;
15803   vl_api_classify_table_info_t *mp;
15804   f64 timeout;
15805
15806   u32 table_id = ~0;
15807   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15808     {
15809       if (unformat (input, "table_id %d", &table_id))
15810         ;
15811       else
15812         break;
15813     }
15814   if (table_id == ~0)
15815     {
15816       errmsg ("missing table id");
15817       return -99;
15818     }
15819
15820   /* Construct the API message */
15821   M (CLASSIFY_TABLE_INFO, classify_table_info);
15822   mp->context = 0;
15823   mp->table_id = ntohl (table_id);
15824
15825   S;
15826   W;
15827   /* NOTREACHED */
15828   return 0;
15829 }
15830
15831 int
15832 api_classify_session_dump (vat_main_t * vam)
15833 {
15834   unformat_input_t *input = vam->input;
15835   vl_api_classify_session_dump_t *mp;
15836   f64 timeout;
15837
15838   u32 table_id = ~0;
15839   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15840     {
15841       if (unformat (input, "table_id %d", &table_id))
15842         ;
15843       else
15844         break;
15845     }
15846   if (table_id == ~0)
15847     {
15848       errmsg ("missing table id");
15849       return -99;
15850     }
15851
15852   /* Construct the API message */
15853   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15854   mp->context = 0;
15855   mp->table_id = ntohl (table_id);
15856   S;
15857
15858   /* Use a control ping for synchronization */
15859   {
15860     vl_api_control_ping_t *mp;
15861     M (CONTROL_PING, control_ping);
15862     S;
15863   }
15864   W;
15865   /* NOTREACHED */
15866   return 0;
15867 }
15868
15869 static void
15870 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15871 {
15872   vat_main_t *vam = &vat_main;
15873
15874   print (vam->ofp, "collector_address %U, collector_port %d, "
15875          "src_address %U, vrf_id %d, path_mtu %u, "
15876          "template_interval %u, udp_checksum %d",
15877          format_ip4_address, mp->collector_address,
15878          ntohs (mp->collector_port),
15879          format_ip4_address, mp->src_address,
15880          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15881          ntohl (mp->template_interval), mp->udp_checksum);
15882
15883   vam->retval = 0;
15884   vam->result_ready = 1;
15885 }
15886
15887 static void
15888   vl_api_ipfix_exporter_details_t_handler_json
15889   (vl_api_ipfix_exporter_details_t * mp)
15890 {
15891   vat_main_t *vam = &vat_main;
15892   vat_json_node_t node;
15893   struct in_addr collector_address;
15894   struct in_addr src_address;
15895
15896   vat_json_init_object (&node);
15897   clib_memcpy (&collector_address, &mp->collector_address,
15898                sizeof (collector_address));
15899   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15900   vat_json_object_add_uint (&node, "collector_port",
15901                             ntohs (mp->collector_port));
15902   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15903   vat_json_object_add_ip4 (&node, "src_address", src_address);
15904   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15905   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15906   vat_json_object_add_uint (&node, "template_interval",
15907                             ntohl (mp->template_interval));
15908   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15909
15910   vat_json_print (vam->ofp, &node);
15911   vat_json_free (&node);
15912   vam->retval = 0;
15913   vam->result_ready = 1;
15914 }
15915
15916 int
15917 api_ipfix_exporter_dump (vat_main_t * vam)
15918 {
15919   vl_api_ipfix_exporter_dump_t *mp;
15920   f64 timeout;
15921
15922   /* Construct the API message */
15923   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15924   mp->context = 0;
15925
15926   S;
15927   W;
15928   /* NOTREACHED */
15929   return 0;
15930 }
15931
15932 static int
15933 api_ipfix_classify_stream_dump (vat_main_t * vam)
15934 {
15935   vl_api_ipfix_classify_stream_dump_t *mp;
15936   f64 timeout;
15937
15938   /* Construct the API message */
15939   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15940   mp->context = 0;
15941
15942   S;
15943   W;
15944   /* NOTREACHED */
15945   return 0;
15946 }
15947
15948 static void
15949   vl_api_ipfix_classify_stream_details_t_handler
15950   (vl_api_ipfix_classify_stream_details_t * mp)
15951 {
15952   vat_main_t *vam = &vat_main;
15953   print (vam->ofp, "domain_id %d, src_port %d",
15954          ntohl (mp->domain_id), ntohs (mp->src_port));
15955   vam->retval = 0;
15956   vam->result_ready = 1;
15957 }
15958
15959 static void
15960   vl_api_ipfix_classify_stream_details_t_handler_json
15961   (vl_api_ipfix_classify_stream_details_t * mp)
15962 {
15963   vat_main_t *vam = &vat_main;
15964   vat_json_node_t node;
15965
15966   vat_json_init_object (&node);
15967   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15968   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15969
15970   vat_json_print (vam->ofp, &node);
15971   vat_json_free (&node);
15972   vam->retval = 0;
15973   vam->result_ready = 1;
15974 }
15975
15976 static int
15977 api_ipfix_classify_table_dump (vat_main_t * vam)
15978 {
15979   vl_api_ipfix_classify_table_dump_t *mp;
15980   f64 timeout;
15981
15982   if (!vam->json_output)
15983     {
15984       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
15985              "transport_protocol");
15986     }
15987
15988   /* Construct the API message */
15989   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15990
15991   /* send it... */
15992   S;
15993
15994   /* Use a control ping for synchronization */
15995   {
15996     vl_api_control_ping_t *mp;
15997     M (CONTROL_PING, control_ping);
15998     S;
15999   }
16000   W;
16001 }
16002
16003 static void
16004   vl_api_ipfix_classify_table_details_t_handler
16005   (vl_api_ipfix_classify_table_details_t * mp)
16006 {
16007   vat_main_t *vam = &vat_main;
16008   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
16009          mp->transport_protocol);
16010 }
16011
16012 static void
16013   vl_api_ipfix_classify_table_details_t_handler_json
16014   (vl_api_ipfix_classify_table_details_t * mp)
16015 {
16016   vat_json_node_t *node = NULL;
16017   vat_main_t *vam = &vat_main;
16018
16019   if (VAT_JSON_ARRAY != vam->json_tree.type)
16020     {
16021       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16022       vat_json_init_array (&vam->json_tree);
16023     }
16024
16025   node = vat_json_array_add (&vam->json_tree);
16026   vat_json_init_object (node);
16027
16028   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16029   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16030   vat_json_object_add_uint (node, "transport_protocol",
16031                             mp->transport_protocol);
16032 }
16033
16034 static int
16035 api_sw_interface_span_enable_disable (vat_main_t * vam)
16036 {
16037   unformat_input_t *i = vam->input;
16038   vl_api_sw_interface_span_enable_disable_t *mp;
16039   f64 timeout;
16040   u32 src_sw_if_index = ~0;
16041   u32 dst_sw_if_index = ~0;
16042   u8 state = 3;
16043
16044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16045     {
16046       if (unformat
16047           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16048         ;
16049       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16050         ;
16051       else
16052         if (unformat
16053             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16054         ;
16055       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16056         ;
16057       else if (unformat (i, "disable"))
16058         state = 0;
16059       else if (unformat (i, "rx"))
16060         state = 1;
16061       else if (unformat (i, "tx"))
16062         state = 2;
16063       else if (unformat (i, "both"))
16064         state = 3;
16065       else
16066         break;
16067     }
16068
16069   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
16070
16071   mp->sw_if_index_from = htonl (src_sw_if_index);
16072   mp->sw_if_index_to = htonl (dst_sw_if_index);
16073   mp->state = state;
16074
16075   S;
16076   W;
16077   /* NOTREACHED */
16078   return 0;
16079 }
16080
16081 static void
16082 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16083                                             * mp)
16084 {
16085   vat_main_t *vam = &vat_main;
16086   u8 *sw_if_from_name = 0;
16087   u8 *sw_if_to_name = 0;
16088   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16089   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16090   char *states[] = { "none", "rx", "tx", "both" };
16091   hash_pair_t *p;
16092
16093   /* *INDENT-OFF* */
16094   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16095   ({
16096     if ((u32) p->value[0] == sw_if_index_from)
16097       {
16098         sw_if_from_name = (u8 *)(p->key);
16099         if (sw_if_to_name)
16100           break;
16101       }
16102     if ((u32) p->value[0] == sw_if_index_to)
16103       {
16104         sw_if_to_name = (u8 *)(p->key);
16105         if (sw_if_from_name)
16106           break;
16107       }
16108   }));
16109   /* *INDENT-ON* */
16110   print (vam->ofp, "%20s => %20s (%s)",
16111          sw_if_from_name, sw_if_to_name, states[mp->state]);
16112 }
16113
16114 static void
16115   vl_api_sw_interface_span_details_t_handler_json
16116   (vl_api_sw_interface_span_details_t * mp)
16117 {
16118   vat_main_t *vam = &vat_main;
16119   vat_json_node_t *node = NULL;
16120   u8 *sw_if_from_name = 0;
16121   u8 *sw_if_to_name = 0;
16122   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16123   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16124   hash_pair_t *p;
16125
16126   /* *INDENT-OFF* */
16127   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16128   ({
16129     if ((u32) p->value[0] == sw_if_index_from)
16130       {
16131         sw_if_from_name = (u8 *)(p->key);
16132         if (sw_if_to_name)
16133           break;
16134       }
16135     if ((u32) p->value[0] == sw_if_index_to)
16136       {
16137         sw_if_to_name = (u8 *)(p->key);
16138         if (sw_if_from_name)
16139           break;
16140       }
16141   }));
16142   /* *INDENT-ON* */
16143
16144   if (VAT_JSON_ARRAY != vam->json_tree.type)
16145     {
16146       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16147       vat_json_init_array (&vam->json_tree);
16148     }
16149   node = vat_json_array_add (&vam->json_tree);
16150
16151   vat_json_init_object (node);
16152   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16153   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16154   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16155   vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16156   vat_json_object_add_uint (node, "state", mp->state);
16157 }
16158
16159 static int
16160 api_sw_interface_span_dump (vat_main_t * vam)
16161 {
16162   vl_api_sw_interface_span_dump_t *mp;
16163   f64 timeout;
16164
16165   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
16166   S;
16167
16168   /* Use a control ping for synchronization */
16169   {
16170     vl_api_control_ping_t *mp;
16171     M (CONTROL_PING, control_ping);
16172     S;
16173   }
16174   W;
16175 }
16176
16177 int
16178 api_pg_create_interface (vat_main_t * vam)
16179 {
16180   unformat_input_t *input = vam->input;
16181   vl_api_pg_create_interface_t *mp;
16182   f64 timeout;
16183
16184   u32 if_id = ~0;
16185   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16186     {
16187       if (unformat (input, "if_id %d", &if_id))
16188         ;
16189       else
16190         break;
16191     }
16192   if (if_id == ~0)
16193     {
16194       errmsg ("missing pg interface index");
16195       return -99;
16196     }
16197
16198   /* Construct the API message */
16199   M (PG_CREATE_INTERFACE, pg_create_interface);
16200   mp->context = 0;
16201   mp->interface_id = ntohl (if_id);
16202
16203   S;
16204   W;
16205   /* NOTREACHED */
16206   return 0;
16207 }
16208
16209 int
16210 api_pg_capture (vat_main_t * vam)
16211 {
16212   unformat_input_t *input = vam->input;
16213   vl_api_pg_capture_t *mp;
16214   f64 timeout;
16215
16216   u32 if_id = ~0;
16217   u8 enable = 1;
16218   u32 count = 1;
16219   u8 pcap_file_set = 0;
16220   u8 *pcap_file = 0;
16221   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16222     {
16223       if (unformat (input, "if_id %d", &if_id))
16224         ;
16225       else if (unformat (input, "pcap %s", &pcap_file))
16226         pcap_file_set = 1;
16227       else if (unformat (input, "count %d", &count))
16228         ;
16229       else if (unformat (input, "disable"))
16230         enable = 0;
16231       else
16232         break;
16233     }
16234   if (if_id == ~0)
16235     {
16236       errmsg ("missing pg interface index");
16237       return -99;
16238     }
16239   if (pcap_file_set > 0)
16240     {
16241       if (vec_len (pcap_file) > 255)
16242         {
16243           errmsg ("pcap file name is too long");
16244           return -99;
16245         }
16246     }
16247
16248   u32 name_len = vec_len (pcap_file);
16249   /* Construct the API message */
16250   M (PG_CAPTURE, pg_capture);
16251   mp->context = 0;
16252   mp->interface_id = ntohl (if_id);
16253   mp->is_enabled = enable;
16254   mp->count = ntohl (count);
16255   mp->pcap_name_length = ntohl (name_len);
16256   if (pcap_file_set != 0)
16257     {
16258       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16259     }
16260   vec_free (pcap_file);
16261
16262   S;
16263   W;
16264   /* NOTREACHED */
16265   return 0;
16266 }
16267
16268 int
16269 api_pg_enable_disable (vat_main_t * vam)
16270 {
16271   unformat_input_t *input = vam->input;
16272   vl_api_pg_enable_disable_t *mp;
16273   f64 timeout;
16274
16275   u8 enable = 1;
16276   u8 stream_name_set = 0;
16277   u8 *stream_name = 0;
16278   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16279     {
16280       if (unformat (input, "stream %s", &stream_name))
16281         stream_name_set = 1;
16282       else if (unformat (input, "disable"))
16283         enable = 0;
16284       else
16285         break;
16286     }
16287
16288   if (stream_name_set > 0)
16289     {
16290       if (vec_len (stream_name) > 255)
16291         {
16292           errmsg ("stream name too long");
16293           return -99;
16294         }
16295     }
16296
16297   u32 name_len = vec_len (stream_name);
16298   /* Construct the API message */
16299   M (PG_ENABLE_DISABLE, pg_enable_disable);
16300   mp->context = 0;
16301   mp->is_enabled = enable;
16302   if (stream_name_set != 0)
16303     {
16304       mp->stream_name_length = ntohl (name_len);
16305       clib_memcpy (mp->stream_name, stream_name, name_len);
16306     }
16307   vec_free (stream_name);
16308
16309   S;
16310   W;
16311   /* NOTREACHED */
16312   return 0;
16313 }
16314
16315 int
16316 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16317 {
16318   unformat_input_t *input = vam->input;
16319   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16320   f64 timeout;
16321
16322   u16 *low_ports = 0;
16323   u16 *high_ports = 0;
16324   u16 this_low;
16325   u16 this_hi;
16326   ip4_address_t ip4_addr;
16327   ip6_address_t ip6_addr;
16328   u32 length;
16329   u32 tmp, tmp2;
16330   u8 prefix_set = 0;
16331   u32 vrf_id = ~0;
16332   u8 is_add = 1;
16333   u8 is_ipv6 = 0;
16334
16335   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16336     {
16337       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16338         {
16339           prefix_set = 1;
16340         }
16341       else
16342         if (unformat
16343             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16344         {
16345           prefix_set = 1;
16346           is_ipv6 = 1;
16347         }
16348       else if (unformat (input, "vrf %d", &vrf_id))
16349         ;
16350       else if (unformat (input, "del"))
16351         is_add = 0;
16352       else if (unformat (input, "port %d", &tmp))
16353         {
16354           if (tmp == 0 || tmp > 65535)
16355             {
16356               errmsg ("port %d out of range", tmp);
16357               return -99;
16358             }
16359           this_low = tmp;
16360           this_hi = this_low + 1;
16361           vec_add1 (low_ports, this_low);
16362           vec_add1 (high_ports, this_hi);
16363         }
16364       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16365         {
16366           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16367             {
16368               errmsg ("incorrect range parameters");
16369               return -99;
16370             }
16371           this_low = tmp;
16372           /* Note: in debug CLI +1 is added to high before
16373              passing to real fn that does "the work"
16374              (ip_source_and_port_range_check_add_del).
16375              This fn is a wrapper around the binary API fn a
16376              control plane will call, which expects this increment
16377              to have occurred. Hence letting the binary API control
16378              plane fn do the increment for consistency between VAT
16379              and other control planes.
16380            */
16381           this_hi = tmp2;
16382           vec_add1 (low_ports, this_low);
16383           vec_add1 (high_ports, this_hi);
16384         }
16385       else
16386         break;
16387     }
16388
16389   if (prefix_set == 0)
16390     {
16391       errmsg ("<address>/<mask> not specified");
16392       return -99;
16393     }
16394
16395   if (vrf_id == ~0)
16396     {
16397       errmsg ("VRF ID required, not specified");
16398       return -99;
16399     }
16400
16401   if (vrf_id == 0)
16402     {
16403       errmsg
16404         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16405       return -99;
16406     }
16407
16408   if (vec_len (low_ports) == 0)
16409     {
16410       errmsg ("At least one port or port range required");
16411       return -99;
16412     }
16413
16414   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
16415      ip_source_and_port_range_check_add_del);
16416
16417   mp->is_add = is_add;
16418
16419   if (is_ipv6)
16420     {
16421       mp->is_ipv6 = 1;
16422       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16423     }
16424   else
16425     {
16426       mp->is_ipv6 = 0;
16427       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16428     }
16429
16430   mp->mask_length = length;
16431   mp->number_of_ranges = vec_len (low_ports);
16432
16433   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16434   vec_free (low_ports);
16435
16436   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16437   vec_free (high_ports);
16438
16439   mp->vrf_id = ntohl (vrf_id);
16440
16441   S;
16442   W;
16443   /* NOTREACHED */
16444   return 0;
16445 }
16446
16447 int
16448 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16449 {
16450   unformat_input_t *input = vam->input;
16451   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16452   f64 timeout;
16453   u32 sw_if_index = ~0;
16454   int vrf_set = 0;
16455   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16456   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16457   u8 is_add = 1;
16458
16459   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16460     {
16461       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16462         ;
16463       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16464         ;
16465       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16466         vrf_set = 1;
16467       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16468         vrf_set = 1;
16469       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16470         vrf_set = 1;
16471       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16472         vrf_set = 1;
16473       else if (unformat (input, "del"))
16474         is_add = 0;
16475       else
16476         break;
16477     }
16478
16479   if (sw_if_index == ~0)
16480     {
16481       errmsg ("Interface required but not specified");
16482       return -99;
16483     }
16484
16485   if (vrf_set == 0)
16486     {
16487       errmsg ("VRF ID required but not specified");
16488       return -99;
16489     }
16490
16491   if (tcp_out_vrf_id == 0
16492       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16493     {
16494       errmsg
16495         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16496       return -99;
16497     }
16498
16499   /* Construct the API message */
16500   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
16501      ip_source_and_port_range_check_interface_add_del);
16502
16503   mp->sw_if_index = ntohl (sw_if_index);
16504   mp->is_add = is_add;
16505   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16506   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16507   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16508   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16509
16510   /* send it... */
16511   S;
16512
16513   /* Wait for a reply... */
16514   W;
16515 }
16516
16517 static int
16518 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16519 {
16520   unformat_input_t *i = vam->input;
16521   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16522   f64 timeout;
16523   u32 local_sa_id = 0;
16524   u32 remote_sa_id = 0;
16525   ip4_address_t src_address;
16526   ip4_address_t dst_address;
16527   u8 is_add = 1;
16528
16529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16530     {
16531       if (unformat (i, "local_sa %d", &local_sa_id))
16532         ;
16533       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16534         ;
16535       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16536         ;
16537       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16538         ;
16539       else if (unformat (i, "del"))
16540         is_add = 0;
16541       else
16542         {
16543           clib_warning ("parse error '%U'", format_unformat_error, i);
16544           return -99;
16545         }
16546     }
16547
16548   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16549
16550   mp->local_sa_id = ntohl (local_sa_id);
16551   mp->remote_sa_id = ntohl (remote_sa_id);
16552   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16553   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16554   mp->is_add = is_add;
16555
16556   S;
16557   W;
16558   /* NOTREACHED */
16559   return 0;
16560 }
16561
16562 static int
16563 api_punt (vat_main_t * vam)
16564 {
16565   unformat_input_t *i = vam->input;
16566   vl_api_punt_t *mp;
16567   f64 timeout;
16568   u32 ipv = ~0;
16569   u32 protocol = ~0;
16570   u32 port = ~0;
16571   int is_add = 1;
16572
16573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16574     {
16575       if (unformat (i, "ip %d", &ipv))
16576         ;
16577       else if (unformat (i, "protocol %d", &protocol))
16578         ;
16579       else if (unformat (i, "port %d", &port))
16580         ;
16581       else if (unformat (i, "del"))
16582         is_add = 0;
16583       else
16584         {
16585           clib_warning ("parse error '%U'", format_unformat_error, i);
16586           return -99;
16587         }
16588     }
16589
16590   M (PUNT, punt);
16591
16592   mp->is_add = (u8) is_add;
16593   mp->ipv = (u8) ipv;
16594   mp->l4_protocol = (u8) protocol;
16595   mp->l4_port = htons ((u16) port);
16596
16597   S;
16598   W;
16599   /* NOTREACHED */
16600   return 0;
16601 }
16602
16603 static void vl_api_ipsec_gre_tunnel_details_t_handler
16604   (vl_api_ipsec_gre_tunnel_details_t * mp)
16605 {
16606   vat_main_t *vam = &vat_main;
16607
16608   print (vam->ofp, "%11d%15U%15U%14d%14d",
16609          ntohl (mp->sw_if_index),
16610          format_ip4_address, &mp->src_address,
16611          format_ip4_address, &mp->dst_address,
16612          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16613 }
16614
16615 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16616   (vl_api_ipsec_gre_tunnel_details_t * mp)
16617 {
16618   vat_main_t *vam = &vat_main;
16619   vat_json_node_t *node = NULL;
16620   struct in_addr ip4;
16621
16622   if (VAT_JSON_ARRAY != vam->json_tree.type)
16623     {
16624       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16625       vat_json_init_array (&vam->json_tree);
16626     }
16627   node = vat_json_array_add (&vam->json_tree);
16628
16629   vat_json_init_object (node);
16630   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16631   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16632   vat_json_object_add_ip4 (node, "src_address", ip4);
16633   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16634   vat_json_object_add_ip4 (node, "dst_address", ip4);
16635   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16636   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16637 }
16638
16639 static int
16640 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16641 {
16642   unformat_input_t *i = vam->input;
16643   vl_api_ipsec_gre_tunnel_dump_t *mp;
16644   f64 timeout;
16645   u32 sw_if_index;
16646   u8 sw_if_index_set = 0;
16647
16648   /* Parse args required to build the message */
16649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16650     {
16651       if (unformat (i, "sw_if_index %d", &sw_if_index))
16652         sw_if_index_set = 1;
16653       else
16654         break;
16655     }
16656
16657   if (sw_if_index_set == 0)
16658     {
16659       sw_if_index = ~0;
16660     }
16661
16662   if (!vam->json_output)
16663     {
16664       print (vam->ofp, "%11s%15s%15s%14s%14s",
16665              "sw_if_index", "src_address", "dst_address",
16666              "local_sa_id", "remote_sa_id");
16667     }
16668
16669   /* Get list of gre-tunnel interfaces */
16670   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16671
16672   mp->sw_if_index = htonl (sw_if_index);
16673
16674   S;
16675
16676   /* Use a control ping for synchronization */
16677   {
16678     vl_api_control_ping_t *mp;
16679     M (CONTROL_PING, control_ping);
16680     S;
16681   }
16682   W;
16683 }
16684
16685 static int
16686 api_delete_subif (vat_main_t * vam)
16687 {
16688   unformat_input_t *i = vam->input;
16689   vl_api_delete_subif_t *mp;
16690   f64 timeout;
16691   u32 sw_if_index = ~0;
16692
16693   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16694     {
16695       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16696         ;
16697       if (unformat (i, "sw_if_index %d", &sw_if_index))
16698         ;
16699       else
16700         break;
16701     }
16702
16703   if (sw_if_index == ~0)
16704     {
16705       errmsg ("missing sw_if_index");
16706       return -99;
16707     }
16708
16709   /* Construct the API message */
16710   M (DELETE_SUBIF, delete_subif);
16711   mp->sw_if_index = ntohl (sw_if_index);
16712
16713   S;
16714   W;
16715 }
16716
16717 #define foreach_pbb_vtr_op      \
16718 _("disable",  L2_VTR_DISABLED)  \
16719 _("pop",  L2_VTR_POP_2)         \
16720 _("push",  L2_VTR_PUSH_2)
16721
16722 static int
16723 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16724 {
16725   unformat_input_t *i = vam->input;
16726   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16727   f64 timeout;
16728   u32 sw_if_index = ~0, vtr_op = ~0;
16729   u16 outer_tag = ~0;
16730   u8 dmac[6], smac[6];
16731   u8 dmac_set = 0, smac_set = 0;
16732   u16 vlanid = 0;
16733   u32 sid = ~0;
16734   u32 tmp;
16735
16736   /* Shut up coverity */
16737   memset (dmac, 0, sizeof (dmac));
16738   memset (smac, 0, sizeof (smac));
16739
16740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16741     {
16742       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16743         ;
16744       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16745         ;
16746       else if (unformat (i, "vtr_op %d", &vtr_op))
16747         ;
16748 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16749       foreach_pbb_vtr_op
16750 #undef _
16751         else if (unformat (i, "translate_pbb_stag"))
16752         {
16753           if (unformat (i, "%d", &tmp))
16754             {
16755               vtr_op = L2_VTR_TRANSLATE_2_1;
16756               outer_tag = tmp;
16757             }
16758           else
16759             {
16760               errmsg
16761                 ("translate_pbb_stag operation requires outer tag definition");
16762               return -99;
16763             }
16764         }
16765       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16766         dmac_set++;
16767       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16768         smac_set++;
16769       else if (unformat (i, "sid %d", &sid))
16770         ;
16771       else if (unformat (i, "vlanid %d", &tmp))
16772         vlanid = tmp;
16773       else
16774         {
16775           clib_warning ("parse error '%U'", format_unformat_error, i);
16776           return -99;
16777         }
16778     }
16779
16780   if ((sw_if_index == ~0) || (vtr_op == ~0))
16781     {
16782       errmsg ("missing sw_if_index or vtr operation");
16783       return -99;
16784     }
16785   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16786       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16787     {
16788       errmsg
16789         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
16790       return -99;
16791     }
16792
16793   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16794   mp->sw_if_index = ntohl (sw_if_index);
16795   mp->vtr_op = ntohl (vtr_op);
16796   mp->outer_tag = ntohs (outer_tag);
16797   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16798   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16799   mp->b_vlanid = ntohs (vlanid);
16800   mp->i_sid = ntohl (sid);
16801
16802   S;
16803   W;
16804   /* NOTREACHED */
16805   return 0;
16806 }
16807
16808 static int
16809 api_flow_classify_set_interface (vat_main_t * vam)
16810 {
16811   unformat_input_t *i = vam->input;
16812   vl_api_flow_classify_set_interface_t *mp;
16813   f64 timeout;
16814   u32 sw_if_index;
16815   int sw_if_index_set;
16816   u32 ip4_table_index = ~0;
16817   u32 ip6_table_index = ~0;
16818   u8 is_add = 1;
16819
16820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16821     {
16822       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16823         sw_if_index_set = 1;
16824       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16825         sw_if_index_set = 1;
16826       else if (unformat (i, "del"))
16827         is_add = 0;
16828       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16829         ;
16830       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16831         ;
16832       else
16833         {
16834           clib_warning ("parse error '%U'", format_unformat_error, i);
16835           return -99;
16836         }
16837     }
16838
16839   if (sw_if_index_set == 0)
16840     {
16841       errmsg ("missing interface name or sw_if_index");
16842       return -99;
16843     }
16844
16845   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16846
16847   mp->sw_if_index = ntohl (sw_if_index);
16848   mp->ip4_table_index = ntohl (ip4_table_index);
16849   mp->ip6_table_index = ntohl (ip6_table_index);
16850   mp->is_add = is_add;
16851
16852   S;
16853   W;
16854   /* NOTREACHED */
16855   return 0;
16856 }
16857
16858 static int
16859 api_flow_classify_dump (vat_main_t * vam)
16860 {
16861   unformat_input_t *i = vam->input;
16862   vl_api_flow_classify_dump_t *mp;
16863   f64 timeout = ~0;
16864   u8 type = FLOW_CLASSIFY_N_TABLES;
16865
16866   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16867     ;
16868   else
16869     {
16870       errmsg ("classify table type must be specified");
16871       return -99;
16872     }
16873
16874   if (!vam->json_output)
16875     {
16876       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16877     }
16878
16879   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16880   mp->type = type;
16881   /* send it... */
16882   S;
16883
16884   /* Use a control ping for synchronization */
16885   {
16886     vl_api_control_ping_t *mp;
16887     M (CONTROL_PING, control_ping);
16888     S;
16889   }
16890   /* Wait for a reply... */
16891   W;
16892
16893   /* NOTREACHED */
16894   return 0;
16895 }
16896
16897 static int
16898 api_feature_enable_disable (vat_main_t * vam)
16899 {
16900   unformat_input_t *i = vam->input;
16901   vl_api_feature_enable_disable_t *mp;
16902   f64 timeout;
16903   u8 *arc_name = 0;
16904   u8 *feature_name = 0;
16905   u32 sw_if_index = ~0;
16906   u8 enable = 1;
16907
16908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16909     {
16910       if (unformat (i, "arc_name %s", &arc_name))
16911         ;
16912       else if (unformat (i, "feature_name %s", &feature_name))
16913         ;
16914       else
16915         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16916         ;
16917       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16918         ;
16919       else if (unformat (i, "disable"))
16920         enable = 0;
16921       else
16922         break;
16923     }
16924
16925   if (arc_name == 0)
16926     {
16927       errmsg ("missing arc name");
16928       return -99;
16929     }
16930   if (vec_len (arc_name) > 63)
16931     {
16932       errmsg ("arc name too long");
16933     }
16934
16935   if (feature_name == 0)
16936     {
16937       errmsg ("missing feature name");
16938       return -99;
16939     }
16940   if (vec_len (feature_name) > 63)
16941     {
16942       errmsg ("feature name too long");
16943     }
16944
16945   if (sw_if_index == ~0)
16946     {
16947       errmsg ("missing interface name or sw_if_index");
16948       return -99;
16949     }
16950
16951   /* Construct the API message */
16952   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16953   mp->sw_if_index = ntohl (sw_if_index);
16954   mp->enable = enable;
16955   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16956   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16957   vec_free (arc_name);
16958   vec_free (feature_name);
16959
16960   S;
16961   W;
16962 }
16963
16964 static int
16965 api_sw_interface_tag_add_del (vat_main_t * vam)
16966 {
16967   unformat_input_t *i = vam->input;
16968   vl_api_sw_interface_tag_add_del_t *mp;
16969   f64 timeout;
16970   u32 sw_if_index = ~0;
16971   u8 *tag = 0;
16972   u8 enable = 1;
16973
16974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16975     {
16976       if (unformat (i, "tag %s", &tag))
16977         ;
16978       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16979         ;
16980       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16981         ;
16982       else if (unformat (i, "del"))
16983         enable = 0;
16984       else
16985         break;
16986     }
16987
16988   if (sw_if_index == ~0)
16989     {
16990       errmsg ("missing interface name or sw_if_index");
16991       return -99;
16992     }
16993
16994   if (enable && (tag == 0))
16995     {
16996       errmsg ("no tag specified");
16997       return -99;
16998     }
16999
17000   /* Construct the API message */
17001   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
17002   mp->sw_if_index = ntohl (sw_if_index);
17003   mp->is_add = enable;
17004   if (enable)
17005     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
17006   vec_free (tag);
17007
17008   S;
17009   W;
17010 }
17011
17012 static void vl_api_l2_xconnect_details_t_handler
17013   (vl_api_l2_xconnect_details_t * mp)
17014 {
17015   vat_main_t *vam = &vat_main;
17016
17017   print (vam->ofp, "%15d%15d",
17018          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17019 }
17020
17021 static void vl_api_l2_xconnect_details_t_handler_json
17022   (vl_api_l2_xconnect_details_t * mp)
17023 {
17024   vat_main_t *vam = &vat_main;
17025   vat_json_node_t *node = NULL;
17026
17027   if (VAT_JSON_ARRAY != vam->json_tree.type)
17028     {
17029       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17030       vat_json_init_array (&vam->json_tree);
17031     }
17032   node = vat_json_array_add (&vam->json_tree);
17033
17034   vat_json_init_object (node);
17035   vat_json_object_add_uint (node, "rx_sw_if_index",
17036                             ntohl (mp->rx_sw_if_index));
17037   vat_json_object_add_uint (node, "tx_sw_if_index",
17038                             ntohl (mp->tx_sw_if_index));
17039 }
17040
17041 static int
17042 api_l2_xconnect_dump (vat_main_t * vam)
17043 {
17044   vl_api_l2_xconnect_dump_t *mp;
17045   f64 timeout;
17046
17047   if (!vam->json_output)
17048     {
17049       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17050     }
17051
17052   M (L2_XCONNECT_DUMP, l2_xconnect_dump);
17053
17054   S;
17055
17056   /* Use a control ping for synchronization */
17057   {
17058     vl_api_control_ping_t *mp;
17059     M (CONTROL_PING, control_ping);
17060     S;
17061   }
17062   W;
17063 }
17064
17065 static int
17066 api_sw_interface_set_mtu (vat_main_t * vam)
17067 {
17068   unformat_input_t *i = vam->input;
17069   vl_api_sw_interface_set_mtu_t *mp;
17070   f64 timeout;
17071   u32 sw_if_index = ~0;
17072   u32 mtu = 0;
17073
17074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17075     {
17076       if (unformat (i, "mtu %d", &mtu))
17077         ;
17078       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17079         ;
17080       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17081         ;
17082       else
17083         break;
17084     }
17085
17086   if (sw_if_index == ~0)
17087     {
17088       errmsg ("missing interface name or sw_if_index");
17089       return -99;
17090     }
17091
17092   if (mtu == 0)
17093     {
17094       errmsg ("no mtu specified");
17095       return -99;
17096     }
17097
17098   /* Construct the API message */
17099   M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
17100   mp->sw_if_index = ntohl (sw_if_index);
17101   mp->mtu = ntohs ((u16) mtu);
17102
17103   S;
17104   W;
17105 }
17106
17107
17108 static int
17109 q_or_quit (vat_main_t * vam)
17110 {
17111   longjmp (vam->jump_buf, 1);
17112   return 0;                     /* not so much */
17113 }
17114
17115 static int
17116 q (vat_main_t * vam)
17117 {
17118   return q_or_quit (vam);
17119 }
17120
17121 static int
17122 quit (vat_main_t * vam)
17123 {
17124   return q_or_quit (vam);
17125 }
17126
17127 static int
17128 comment (vat_main_t * vam)
17129 {
17130   return 0;
17131 }
17132
17133 static int
17134 cmd_cmp (void *a1, void *a2)
17135 {
17136   u8 **c1 = a1;
17137   u8 **c2 = a2;
17138
17139   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17140 }
17141
17142 static int
17143 help (vat_main_t * vam)
17144 {
17145   u8 **cmds = 0;
17146   u8 *name = 0;
17147   hash_pair_t *p;
17148   unformat_input_t *i = vam->input;
17149   int j;
17150
17151   if (unformat (i, "%s", &name))
17152     {
17153       uword *hs;
17154
17155       vec_add1 (name, 0);
17156
17157       hs = hash_get_mem (vam->help_by_name, name);
17158       if (hs)
17159         print (vam->ofp, "usage: %s %s", name, hs[0]);
17160       else
17161         print (vam->ofp, "No such msg / command '%s'", name);
17162       vec_free (name);
17163       return 0;
17164     }
17165
17166   print (vam->ofp, "Help is available for the following:");
17167
17168     /* *INDENT-OFF* */
17169     hash_foreach_pair (p, vam->function_by_name,
17170     ({
17171       vec_add1 (cmds, (u8 *)(p->key));
17172     }));
17173     /* *INDENT-ON* */
17174
17175   vec_sort_with_function (cmds, cmd_cmp);
17176
17177   for (j = 0; j < vec_len (cmds); j++)
17178     print (vam->ofp, "%s", cmds[j]);
17179
17180   vec_free (cmds);
17181   return 0;
17182 }
17183
17184 static int
17185 set (vat_main_t * vam)
17186 {
17187   u8 *name = 0, *value = 0;
17188   unformat_input_t *i = vam->input;
17189
17190   if (unformat (i, "%s", &name))
17191     {
17192       /* The input buffer is a vector, not a string. */
17193       value = vec_dup (i->buffer);
17194       vec_delete (value, i->index, 0);
17195       /* Almost certainly has a trailing newline */
17196       if (value[vec_len (value) - 1] == '\n')
17197         value[vec_len (value) - 1] = 0;
17198       /* Make sure it's a proper string, one way or the other */
17199       vec_add1 (value, 0);
17200       (void) clib_macro_set_value (&vam->macro_main,
17201                                    (char *) name, (char *) value);
17202     }
17203   else
17204     errmsg ("usage: set <name> <value>");
17205
17206   vec_free (name);
17207   vec_free (value);
17208   return 0;
17209 }
17210
17211 static int
17212 unset (vat_main_t * vam)
17213 {
17214   u8 *name = 0;
17215
17216   if (unformat (vam->input, "%s", &name))
17217     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17218       errmsg ("unset: %s wasn't set", name);
17219   vec_free (name);
17220   return 0;
17221 }
17222
17223 typedef struct
17224 {
17225   u8 *name;
17226   u8 *value;
17227 } macro_sort_t;
17228
17229
17230 static int
17231 macro_sort_cmp (void *a1, void *a2)
17232 {
17233   macro_sort_t *s1 = a1;
17234   macro_sort_t *s2 = a2;
17235
17236   return strcmp ((char *) (s1->name), (char *) (s2->name));
17237 }
17238
17239 static int
17240 dump_macro_table (vat_main_t * vam)
17241 {
17242   macro_sort_t *sort_me = 0, *sm;
17243   int i;
17244   hash_pair_t *p;
17245
17246     /* *INDENT-OFF* */
17247     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17248     ({
17249       vec_add2 (sort_me, sm, 1);
17250       sm->name = (u8 *)(p->key);
17251       sm->value = (u8 *) (p->value[0]);
17252     }));
17253     /* *INDENT-ON* */
17254
17255   vec_sort_with_function (sort_me, macro_sort_cmp);
17256
17257   if (vec_len (sort_me))
17258     print (vam->ofp, "%-15s%s", "Name", "Value");
17259   else
17260     print (vam->ofp, "The macro table is empty...");
17261
17262   for (i = 0; i < vec_len (sort_me); i++)
17263     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17264   return 0;
17265 }
17266
17267 static int
17268 dump_node_table (vat_main_t * vam)
17269 {
17270   int i, j;
17271   vlib_node_t *node, *next_node;
17272
17273   if (vec_len (vam->graph_nodes) == 0)
17274     {
17275       print (vam->ofp, "Node table empty, issue get_node_graph...");
17276       return 0;
17277     }
17278
17279   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17280     {
17281       node = vam->graph_nodes[i];
17282       print (vam->ofp, "[%d] %s", i, node->name);
17283       for (j = 0; j < vec_len (node->next_nodes); j++)
17284         {
17285           if (node->next_nodes[j] != ~0)
17286             {
17287               next_node = vam->graph_nodes[node->next_nodes[j]];
17288               print (vam->ofp, "  [%d] %s", j, next_node->name);
17289             }
17290         }
17291     }
17292   return 0;
17293 }
17294
17295 static int
17296 value_sort_cmp (void *a1, void *a2)
17297 {
17298   name_sort_t *n1 = a1;
17299   name_sort_t *n2 = a2;
17300
17301   if (n1->value < n2->value)
17302     return -1;
17303   if (n1->value > n2->value)
17304     return 1;
17305   return 0;
17306 }
17307
17308
17309 static int
17310 dump_msg_api_table (vat_main_t * vam)
17311 {
17312   api_main_t *am = &api_main;
17313   name_sort_t *nses = 0, *ns;
17314   hash_pair_t *hp;
17315   int i;
17316
17317   /* *INDENT-OFF* */
17318   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17319   ({
17320     vec_add2 (nses, ns, 1);
17321     ns->name = (u8 *)(hp->key);
17322     ns->value = (u32) hp->value[0];
17323   }));
17324   /* *INDENT-ON* */
17325
17326   vec_sort_with_function (nses, value_sort_cmp);
17327
17328   for (i = 0; i < vec_len (nses); i++)
17329     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17330   vec_free (nses);
17331   return 0;
17332 }
17333
17334 static int
17335 get_msg_id (vat_main_t * vam)
17336 {
17337   u8 *name_and_crc;
17338   u32 message_index;
17339
17340   if (unformat (vam->input, "%s", &name_and_crc))
17341     {
17342       message_index = vl_api_get_msg_index (name_and_crc);
17343       if (message_index == ~0)
17344         {
17345           print (vam->ofp, " '%s' not found", name_and_crc);
17346           return 0;
17347         }
17348       print (vam->ofp, " '%s' has message index %d",
17349              name_and_crc, message_index);
17350       return 0;
17351     }
17352   errmsg ("name_and_crc required...");
17353   return 0;
17354 }
17355
17356 static int
17357 search_node_table (vat_main_t * vam)
17358 {
17359   unformat_input_t *line_input = vam->input;
17360   u8 *node_to_find;
17361   int j;
17362   vlib_node_t *node, *next_node;
17363   uword *p;
17364
17365   if (vam->graph_node_index_by_name == 0)
17366     {
17367       print (vam->ofp, "Node table empty, issue get_node_graph...");
17368       return 0;
17369     }
17370
17371   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17372     {
17373       if (unformat (line_input, "%s", &node_to_find))
17374         {
17375           vec_add1 (node_to_find, 0);
17376           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17377           if (p == 0)
17378             {
17379               print (vam->ofp, "%s not found...", node_to_find);
17380               goto out;
17381             }
17382           node = vam->graph_nodes[p[0]];
17383           print (vam->ofp, "[%d] %s", p[0], node->name);
17384           for (j = 0; j < vec_len (node->next_nodes); j++)
17385             {
17386               if (node->next_nodes[j] != ~0)
17387                 {
17388                   next_node = vam->graph_nodes[node->next_nodes[j]];
17389                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17390                 }
17391             }
17392         }
17393
17394       else
17395         {
17396           clib_warning ("parse error '%U'", format_unformat_error,
17397                         line_input);
17398           return -99;
17399         }
17400
17401     out:
17402       vec_free (node_to_find);
17403
17404     }
17405
17406   return 0;
17407 }
17408
17409
17410 static int
17411 script (vat_main_t * vam)
17412 {
17413 #if (VPP_API_TEST_BUILTIN==0)
17414   u8 *s = 0;
17415   char *save_current_file;
17416   unformat_input_t save_input;
17417   jmp_buf save_jump_buf;
17418   u32 save_line_number;
17419
17420   FILE *new_fp, *save_ifp;
17421
17422   if (unformat (vam->input, "%s", &s))
17423     {
17424       new_fp = fopen ((char *) s, "r");
17425       if (new_fp == 0)
17426         {
17427           errmsg ("Couldn't open script file %s", s);
17428           vec_free (s);
17429           return -99;
17430         }
17431     }
17432   else
17433     {
17434       errmsg ("Missing script name");
17435       return -99;
17436     }
17437
17438   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17439   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17440   save_ifp = vam->ifp;
17441   save_line_number = vam->input_line_number;
17442   save_current_file = (char *) vam->current_file;
17443
17444   vam->input_line_number = 0;
17445   vam->ifp = new_fp;
17446   vam->current_file = s;
17447   do_one_file (vam);
17448
17449   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17450   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17451   vam->ifp = save_ifp;
17452   vam->input_line_number = save_line_number;
17453   vam->current_file = (u8 *) save_current_file;
17454   vec_free (s);
17455
17456   return 0;
17457 #else
17458   clib_warning ("use the exec command...");
17459   return -99;
17460 #endif
17461 }
17462
17463 static int
17464 echo (vat_main_t * vam)
17465 {
17466   print (vam->ofp, "%v", vam->input->buffer);
17467   return 0;
17468 }
17469
17470 /* List of API message constructors, CLI names map to api_xxx */
17471 #define foreach_vpe_api_msg                                             \
17472 _(create_loopback,"[mac <mac-addr>]")                                   \
17473 _(sw_interface_dump,"")                                                 \
17474 _(sw_interface_set_flags,                                               \
17475   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17476 _(sw_interface_add_del_address,                                         \
17477   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17478 _(sw_interface_set_table,                                               \
17479   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17480 _(sw_interface_set_mpls_enable,                                         \
17481   "<intfc> | sw_if_index [disable | dis]")                              \
17482 _(sw_interface_set_vpath,                                               \
17483   "<intfc> | sw_if_index <id> enable | disable")                        \
17484 _(sw_interface_set_vxlan_bypass,                                        \
17485   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")            \
17486 _(sw_interface_set_l2_xconnect,                                         \
17487   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17488   "enable | disable")                                                   \
17489 _(sw_interface_set_l2_bridge,                                           \
17490   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
17491   "[shg <split-horizon-group>] [bvi]\n"                                 \
17492   "enable | disable")                                                   \
17493 _(bridge_domain_add_del,                                                \
17494   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
17495 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
17496 _(l2fib_add_del,                                                        \
17497   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17498 _(l2_flags,                                                             \
17499   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
17500 _(bridge_flags,                                                         \
17501   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17502 _(tap_connect,                                                          \
17503   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17504 _(tap_modify,                                                           \
17505   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17506 _(tap_delete,                                                           \
17507   "<vpp-if-name> | sw_if_index <id>")                                   \
17508 _(sw_interface_tap_dump, "")                                            \
17509 _(ip_add_del_route,                                                     \
17510   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17511   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17512   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17513   "[multipath] [count <n>]")                                            \
17514 _(mpls_route_add_del,                                                   \
17515   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17516   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17517   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17518   "[multipath] [count <n>]")                                            \
17519 _(mpls_ip_bind_unbind,                                                  \
17520   "<label> <addr/len>")                                                 \
17521 _(mpls_tunnel_add_del,                                                  \
17522   " via <addr> [table-id <n>]\n"                                        \
17523   "sw_if_index <id>] [l2]  [del]")                                      \
17524 _(proxy_arp_add_del,                                                    \
17525   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17526 _(proxy_arp_intfc_enable_disable,                                       \
17527   "<intfc> | sw_if_index <id> enable | disable")                        \
17528 _(sw_interface_set_unnumbered,                                          \
17529   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17530 _(ip_neighbor_add_del,                                                  \
17531   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17532   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17533 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17534 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17535 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17536   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17537   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17538   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17539 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17540 _(reset_fib, "vrf <n> [ipv6]")                                          \
17541 _(dhcp_proxy_config,                                                    \
17542   "svr <v46-address> src <v46-address>\n"                               \
17543    "insert-cid <n> [del]")                                              \
17544 _(dhcp_proxy_config_2,                                                  \
17545   "svr <v46-address> src <v46-address>\n"                               \
17546    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
17547 _(dhcp_proxy_set_vss,                                                   \
17548   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17549 _(dhcp_client_config,                                                   \
17550   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17551 _(set_ip_flow_hash,                                                     \
17552   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17553 _(sw_interface_ip6_enable_disable,                                      \
17554   "<intfc> | sw_if_index <id> enable | disable")                        \
17555 _(sw_interface_ip6_set_link_local_address,                              \
17556   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17557 _(sw_interface_ip6nd_ra_prefix,                                         \
17558   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17559   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17560   "[nolink] [isno]")                                                    \
17561 _(sw_interface_ip6nd_ra_config,                                         \
17562   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17563   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17564   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17565 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17566 _(l2_patch_add_del,                                                     \
17567   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17568   "enable | disable")                                                   \
17569 _(sr_tunnel_add_del,                                                    \
17570   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
17571   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
17572   "[policy <policy_name>]")                                             \
17573 _(sr_policy_add_del,                                                    \
17574   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
17575 _(sr_multicast_map_add_del,                                             \
17576   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
17577 _(classify_add_del_table,                                               \
17578   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17579   " [del] [del-chain] mask <mask-value>\n"                              \
17580   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17581   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17582 _(classify_add_del_session,                                             \
17583   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17584   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17585   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17586   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17587 _(classify_set_interface_ip_table,                                      \
17588   "<intfc> | sw_if_index <nn> table <nn>")                              \
17589 _(classify_set_interface_l2_tables,                                     \
17590   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17591   "  [other-table <nn>]")                                               \
17592 _(get_node_index, "node <node-name")                                    \
17593 _(add_node_next, "node <node-name> next <next-node-name>")              \
17594 _(l2tpv3_create_tunnel,                                                 \
17595   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17596   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
17597   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17598 _(l2tpv3_set_tunnel_cookies,                                            \
17599   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17600   "[new_remote_cookie <nn>]\n")                                         \
17601 _(l2tpv3_interface_enable_disable,                                      \
17602   "<intfc> | sw_if_index <nn> enable | disable")                        \
17603 _(l2tpv3_set_lookup_key,                                                \
17604   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17605 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17606 _(vxlan_add_del_tunnel,                                                 \
17607   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17608   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17609   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17610 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17611 _(gre_add_del_tunnel,                                                   \
17612   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
17613 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
17614 _(l2_fib_clear_table, "")                                               \
17615 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
17616 _(l2_interface_vlan_tag_rewrite,                                        \
17617   "<intfc> | sw_if_index <nn> \n"                                       \
17618   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
17619   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
17620 _(create_vhost_user_if,                                                 \
17621         "socket <filename> [server] [renumber <dev_instance>] "         \
17622         "[mac <mac_address>]")                                          \
17623 _(modify_vhost_user_if,                                                 \
17624         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
17625         "[server] [renumber <dev_instance>]")                           \
17626 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
17627 _(sw_interface_vhost_user_dump, "")                                     \
17628 _(show_version, "")                                                     \
17629 _(vxlan_gpe_add_del_tunnel,                                             \
17630   "local <addr> remote <addr> vni <nn>\n"                               \
17631     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
17632   "[next-ethernet] [next-nsh]\n")                                       \
17633 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
17634 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
17635 _(interface_name_renumber,                                              \
17636   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
17637 _(input_acl_set_interface,                                              \
17638   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17639   "  [l2-table <nn>] [del]")                                            \
17640 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
17641 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
17642 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
17643 _(ip_dump, "ipv4 | ipv6")                                               \
17644 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
17645 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
17646   "  spid_id <n> ")                                                     \
17647 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
17648   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
17649   "  integ_alg <alg> integ_key <hex>")                                  \
17650 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
17651   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
17652   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17653   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
17654 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
17655 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
17656 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
17657   "(auth_data 0x<data> | auth_data <data>)")                            \
17658 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
17659   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
17660 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
17661   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17662   "(local|remote)")                                                     \
17663 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
17664 _(delete_loopback,"sw_if_index <nn>")                                   \
17665 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17666 _(map_add_domain,                                                       \
17667   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
17668   "ip6-src <ip6addr> "                                                  \
17669   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
17670 _(map_del_domain, "index <n>")                                          \
17671 _(map_add_del_rule,                                                     \
17672   "index <n> psid <n> dst <ip6addr> [del]")                             \
17673 _(map_domain_dump, "")                                                  \
17674 _(map_rule_dump, "index <map-domain>")                                  \
17675 _(want_interface_events,  "enable|disable")                             \
17676 _(want_stats,"enable|disable")                                          \
17677 _(get_first_msg_id, "client <name>")                                    \
17678 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17679 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
17680   "fib-id <nn> [ip4][ip6][default]")                                    \
17681 _(get_node_graph, " ")                                                  \
17682 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
17683 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
17684 _(ioam_disable, "")                                                     \
17685 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
17686                             " sw_if_index <sw_if_index> p <priority> "  \
17687                             "w <weight>] [del]")                        \
17688 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
17689                         "iface <intf> | sw_if_index <sw_if_index> "     \
17690                         "p <priority> w <weight> [del]")                \
17691 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
17692                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
17693                          "locator-set <locator_name> [del]"             \
17694                          "[key-id sha1|sha256 secret-key <secret-key>]") \
17695 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
17696   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
17697 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
17698 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
17699 _(lisp_gpe_enable_disable, "enable|disable")                            \
17700 _(lisp_enable_disable, "enable|disable")                                \
17701 _(lisp_map_register_enable_disable, "enable|disable")                   \
17702 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
17703 _(lisp_gpe_add_del_iface, "up|down")                                    \
17704 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17705                                "[seid <seid>] "                         \
17706                                "rloc <locator> p <prio> "               \
17707                                "w <weight> [rloc <loc> ... ] "          \
17708                                "action <action> [del-all]")             \
17709 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17710                           "<local-eid>")                                \
17711 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
17712 _(lisp_map_request_mode, "src-dst|dst-only")                            \
17713 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
17714 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
17715 _(lisp_locator_set_dump, "[local | remote]")                            \
17716 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
17717 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
17718                        "[local] | [remote]")                            \
17719 _(lisp_eid_table_vni_dump, "")                                          \
17720 _(lisp_eid_table_map_dump, "l2|l3")                                     \
17721 _(lisp_map_resolver_dump, "")                                           \
17722 _(lisp_map_server_dump, "")                                             \
17723 _(lisp_adjacencies_get, "vni <vni>")                                    \
17724 _(show_lisp_rloc_probe_state, "")                                       \
17725 _(show_lisp_map_register_state, "")                                     \
17726 _(show_lisp_status, "")                                                 \
17727 _(lisp_get_map_request_itr_rlocs, "")                                   \
17728 _(show_lisp_pitr, "")                                                   \
17729 _(show_lisp_map_request_mode, "")                                       \
17730 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
17731 _(af_packet_delete, "name <host interface name>")                       \
17732 _(policer_add_del, "name <policer name> <params> [del]")                \
17733 _(policer_dump, "[name <policer name>]")                                \
17734 _(policer_classify_set_interface,                                       \
17735   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17736   "  [l2-table <nn>] [del]")                                            \
17737 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
17738 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
17739     "[master|slave]")                                                   \
17740 _(netmap_delete, "name <interface name>")                               \
17741 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
17742 _(mpls_fib_dump, "")                                                    \
17743 _(classify_table_ids, "")                                               \
17744 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
17745 _(classify_table_info, "table_id <nn>")                                 \
17746 _(classify_session_dump, "table_id <nn>")                               \
17747 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
17748     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
17749     "[template_interval <nn>] [udp_checksum]")                          \
17750 _(ipfix_exporter_dump, "")                                              \
17751 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17752 _(ipfix_classify_stream_dump, "")                                       \
17753 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
17754 _(ipfix_classify_table_dump, "")                                        \
17755 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
17756 _(sw_interface_span_dump, "")                                           \
17757 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17758 _(pg_create_interface, "if_id <nn>")                                    \
17759 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17760 _(pg_enable_disable, "[stream <id>] disable")                           \
17761 _(ip_source_and_port_range_check_add_del,                               \
17762   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17763 _(ip_source_and_port_range_check_interface_add_del,                     \
17764   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17765   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17766 _(ipsec_gre_add_del_tunnel,                                             \
17767   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17768 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17769 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17770 _(l2_interface_pbb_tag_rewrite,                                         \
17771   "<intfc> | sw_if_index <nn> \n"                                       \
17772   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17773   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17774 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17775 _(flow_classify_set_interface,                                          \
17776   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17777 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17778 _(ip_fib_dump, "")                                                      \
17779 _(ip6_fib_dump, "")                                                     \
17780 _(feature_enable_disable, "arc_name <arc_name> "                        \
17781   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
17782 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
17783 "[disable]")                                                            \
17784 _(l2_xconnect_dump, "")                                                 \
17785 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
17786 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
17787 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
17788
17789 #if DPDK > 0
17790 #define foreach_vpe_dpdk_api_msg                                        \
17791 _(sw_interface_set_dpdk_hqos_pipe,                                      \
17792   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
17793   "profile <profile-id>\n")                                             \
17794 _(sw_interface_set_dpdk_hqos_subport,                                   \
17795   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
17796   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
17797 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
17798   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
17799 #endif
17800
17801 /* List of command functions, CLI names map directly to functions */
17802 #define foreach_cli_function                                    \
17803 _(comment, "usage: comment <ignore-rest-of-line>")              \
17804 _(dump_interface_table, "usage: dump_interface_table")          \
17805 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17806 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17807 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17808 _(dump_stats_table, "usage: dump_stats_table")                  \
17809 _(dump_macro_table, "usage: dump_macro_table ")                 \
17810 _(dump_node_table, "usage: dump_node_table")                    \
17811 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17812 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17813 _(echo, "usage: echo <message>")                                \
17814 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17815 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17816 _(help, "usage: help")                                          \
17817 _(q, "usage: quit")                                             \
17818 _(quit, "usage: quit")                                          \
17819 _(search_node_table, "usage: search_node_table <name>...")      \
17820 _(set, "usage: set <variable-name> <value>")                    \
17821 _(script, "usage: script <file-name>")                          \
17822 _(unset, "usage: unset <variable-name>")
17823
17824 #define _(N,n)                                  \
17825     static void vl_api_##n##_t_handler_uni      \
17826     (vl_api_##n##_t * mp)                       \
17827     {                                           \
17828         vat_main_t * vam = &vat_main;           \
17829         if (vam->json_output) {                 \
17830             vl_api_##n##_t_handler_json(mp);    \
17831         } else {                                \
17832             vl_api_##n##_t_handler(mp);         \
17833         }                                       \
17834     }
17835 foreach_vpe_api_reply_msg;
17836 #undef _
17837
17838 #if DPDK > 0
17839 #define _(N,n)                                  \
17840     static void vl_api_##n##_t_handler_uni      \
17841     (vl_api_##n##_t * mp)                       \
17842     {                                           \
17843         vat_main_t * vam = &vat_main;           \
17844         if (vam->json_output) {                 \
17845             vl_api_##n##_t_handler_json(mp);    \
17846         } else {                                \
17847             vl_api_##n##_t_handler(mp);         \
17848         }                                       \
17849     }
17850 foreach_vpe_dpdk_api_reply_msg;
17851 #undef _
17852 #endif
17853
17854 void
17855 vat_api_hookup (vat_main_t * vam)
17856 {
17857 #define _(N,n)                                                  \
17858     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17859                            vl_api_##n##_t_handler_uni,          \
17860                            vl_noop_handler,                     \
17861                            vl_api_##n##_t_endian,               \
17862                            vl_api_##n##_t_print,                \
17863                            sizeof(vl_api_##n##_t), 1);
17864   foreach_vpe_api_reply_msg;
17865 #undef _
17866
17867 #if DPDK > 0
17868 #define _(N,n)                                                  \
17869     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17870                            vl_api_##n##_t_handler_uni,          \
17871                            vl_noop_handler,                     \
17872                            vl_api_##n##_t_endian,               \
17873                            vl_api_##n##_t_print,                \
17874                            sizeof(vl_api_##n##_t), 1);
17875   foreach_vpe_dpdk_api_reply_msg;
17876 #undef _
17877 #endif
17878
17879 #if (VPP_API_TEST_BUILTIN==0)
17880   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17881 #endif
17882
17883   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17884
17885   vam->function_by_name = hash_create_string (0, sizeof (uword));
17886
17887   vam->help_by_name = hash_create_string (0, sizeof (uword));
17888
17889   /* API messages we can send */
17890 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17891   foreach_vpe_api_msg;
17892 #undef _
17893 #if DPDK >0
17894 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17895   foreach_vpe_dpdk_api_msg;
17896 #undef _
17897 #endif
17898
17899   /* Help strings */
17900 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17901   foreach_vpe_api_msg;
17902 #undef _
17903 #if DPDK >0
17904 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17905   foreach_vpe_dpdk_api_msg;
17906 #undef _
17907 #endif
17908
17909   /* CLI functions */
17910 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17911   foreach_cli_function;
17912 #undef _
17913
17914   /* Help strings */
17915 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17916   foreach_cli_function;
17917 #undef _
17918 }
17919
17920 /*
17921  * fd.io coding-style-patch-verification: ON
17922  *
17923  * Local Variables:
17924  * eval: (c-set-style "gnu")
17925  * End:
17926  */