IPv6 NS RS tests and fixes
[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 static uword
74 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 void vat_suspend (vlib_main_t * vm, f64 interval);
92
93 #if VPP_API_TEST_BUILTIN == 0
94 /* Parse an IP4 address %d.%d.%d.%d. */
95 uword
96 unformat_ip4_address (unformat_input_t * input, va_list * args)
97 {
98   u8 *result = va_arg (*args, u8 *);
99   unsigned a[4];
100
101   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
102     return 0;
103
104   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
105     return 0;
106
107   result[0] = a[0];
108   result[1] = a[1];
109   result[2] = a[2];
110   result[3] = a[3];
111
112   return 1;
113 }
114
115 uword
116 unformat_ethernet_address (unformat_input_t * input, va_list * args)
117 {
118   u8 *result = va_arg (*args, u8 *);
119   u32 i, a[6];
120
121   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
122                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
123     return 0;
124
125   /* Check range. */
126   for (i = 0; i < 6; i++)
127     if (a[i] >= (1 << 8))
128       return 0;
129
130   for (i = 0; i < 6; i++)
131     result[i] = a[i];
132
133   return 1;
134 }
135
136 /* Returns ethernet type as an int in host byte order. */
137 uword
138 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
139                                         va_list * args)
140 {
141   u16 *result = va_arg (*args, u16 *);
142   int type;
143
144   /* Numeric type. */
145   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
146     {
147       if (type >= (1 << 16))
148         return 0;
149       *result = type;
150       return 1;
151     }
152   return 0;
153 }
154
155 /* Parse an IP6 address. */
156 uword
157 unformat_ip6_address (unformat_input_t * input, va_list * args)
158 {
159   ip6_address_t *result = va_arg (*args, ip6_address_t *);
160   u16 hex_quads[8];
161   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
162   uword c, n_colon, double_colon_index;
163
164   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
165   double_colon_index = ARRAY_LEN (hex_quads);
166   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
167     {
168       hex_digit = 16;
169       if (c >= '0' && c <= '9')
170         hex_digit = c - '0';
171       else if (c >= 'a' && c <= 'f')
172         hex_digit = c + 10 - 'a';
173       else if (c >= 'A' && c <= 'F')
174         hex_digit = c + 10 - 'A';
175       else if (c == ':' && n_colon < 2)
176         n_colon++;
177       else
178         {
179           unformat_put_input (input);
180           break;
181         }
182
183       /* Too many hex quads. */
184       if (n_hex_quads >= ARRAY_LEN (hex_quads))
185         return 0;
186
187       if (hex_digit < 16)
188         {
189           hex_quad = (hex_quad << 4) | hex_digit;
190
191           /* Hex quad must fit in 16 bits. */
192           if (n_hex_digits >= 4)
193             return 0;
194
195           n_colon = 0;
196           n_hex_digits++;
197         }
198
199       /* Save position of :: */
200       if (n_colon == 2)
201         {
202           /* More than one :: ? */
203           if (double_colon_index < ARRAY_LEN (hex_quads))
204             return 0;
205           double_colon_index = n_hex_quads;
206         }
207
208       if (n_colon > 0 && n_hex_digits > 0)
209         {
210           hex_quads[n_hex_quads++] = hex_quad;
211           hex_quad = 0;
212           n_hex_digits = 0;
213         }
214     }
215
216   if (n_hex_digits > 0)
217     hex_quads[n_hex_quads++] = hex_quad;
218
219   {
220     word i;
221
222     /* Expand :: to appropriate number of zero hex quads. */
223     if (double_colon_index < ARRAY_LEN (hex_quads))
224       {
225         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
226
227         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
228           hex_quads[n_zero + i] = hex_quads[i];
229
230         for (i = 0; i < n_zero; i++)
231           hex_quads[double_colon_index + i] = 0;
232
233         n_hex_quads = ARRAY_LEN (hex_quads);
234       }
235
236     /* Too few hex quads given. */
237     if (n_hex_quads < ARRAY_LEN (hex_quads))
238       return 0;
239
240     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
241       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
242
243     return 1;
244   }
245 }
246
247 uword
248 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
249 {
250   u32 *r = va_arg (*args, u32 *);
251
252   if (0);
253 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
254   foreach_ipsec_policy_action
255 #undef _
256     else
257     return 0;
258   return 1;
259 }
260
261 uword
262 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
263 {
264   u32 *r = va_arg (*args, u32 *);
265
266   if (0);
267 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
268   foreach_ipsec_crypto_alg
269 #undef _
270     else
271     return 0;
272   return 1;
273 }
274
275 u8 *
276 format_ipsec_crypto_alg (u8 * s, va_list * args)
277 {
278   u32 i = va_arg (*args, u32);
279   u8 *t = 0;
280
281   switch (i)
282     {
283 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
284       foreach_ipsec_crypto_alg
285 #undef _
286     default:
287       return format (s, "unknown");
288     }
289   return format (s, "%s", t);
290 }
291
292 uword
293 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
294 {
295   u32 *r = va_arg (*args, u32 *);
296
297   if (0);
298 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
299   foreach_ipsec_integ_alg
300 #undef _
301     else
302     return 0;
303   return 1;
304 }
305
306 u8 *
307 format_ipsec_integ_alg (u8 * s, va_list * args)
308 {
309   u32 i = va_arg (*args, u32);
310   u8 *t = 0;
311
312   switch (i)
313     {
314 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
315       foreach_ipsec_integ_alg
316 #undef _
317     default:
318       return format (s, "unknown");
319     }
320   return format (s, "%s", t);
321 }
322
323 uword
324 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
325 {
326   u32 *r = va_arg (*args, u32 *);
327
328   if (0);
329 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
330   foreach_ikev2_auth_method
331 #undef _
332     else
333     return 0;
334   return 1;
335 }
336
337 uword
338 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
339 {
340   u32 *r = va_arg (*args, u32 *);
341
342   if (0);
343 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
344   foreach_ikev2_id_type
345 #undef _
346     else
347     return 0;
348   return 1;
349 }
350 #endif /* VPP_API_TEST_BUILTIN */
351
352 static uword
353 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
354 {
355   u8 *r = va_arg (*args, u8 *);
356
357   if (unformat (input, "kbps"))
358     *r = SSE2_QOS_RATE_KBPS;
359   else if (unformat (input, "pps"))
360     *r = SSE2_QOS_RATE_PPS;
361   else
362     return 0;
363   return 1;
364 }
365
366 static uword
367 unformat_policer_round_type (unformat_input_t * input, va_list * args)
368 {
369   u8 *r = va_arg (*args, u8 *);
370
371   if (unformat (input, "closest"))
372     *r = SSE2_QOS_ROUND_TO_CLOSEST;
373   else if (unformat (input, "up"))
374     *r = SSE2_QOS_ROUND_TO_UP;
375   else if (unformat (input, "down"))
376     *r = SSE2_QOS_ROUND_TO_DOWN;
377   else
378     return 0;
379   return 1;
380 }
381
382 static uword
383 unformat_policer_type (unformat_input_t * input, va_list * args)
384 {
385   u8 *r = va_arg (*args, u8 *);
386
387   if (unformat (input, "1r2c"))
388     *r = SSE2_QOS_POLICER_TYPE_1R2C;
389   else if (unformat (input, "1r3c"))
390     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
391   else if (unformat (input, "2r3c-2698"))
392     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
393   else if (unformat (input, "2r3c-4115"))
394     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
395   else if (unformat (input, "2r3c-mef5cf1"))
396     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
397   else
398     return 0;
399   return 1;
400 }
401
402 static uword
403 unformat_dscp (unformat_input_t * input, va_list * va)
404 {
405   u8 *r = va_arg (*va, u8 *);
406
407   if (0);
408 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
409   foreach_vnet_dscp
410 #undef _
411     else
412     return 0;
413   return 1;
414 }
415
416 static uword
417 unformat_policer_action_type (unformat_input_t * input, va_list * va)
418 {
419   sse2_qos_pol_action_params_st *a
420     = va_arg (*va, sse2_qos_pol_action_params_st *);
421
422   if (unformat (input, "drop"))
423     a->action_type = SSE2_QOS_ACTION_DROP;
424   else if (unformat (input, "transmit"))
425     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
426   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
427     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
428   else
429     return 0;
430   return 1;
431 }
432
433 static uword
434 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
435 {
436   u32 *r = va_arg (*va, u32 *);
437   u32 tid;
438
439   if (unformat (input, "ip4"))
440     tid = POLICER_CLASSIFY_TABLE_IP4;
441   else if (unformat (input, "ip6"))
442     tid = POLICER_CLASSIFY_TABLE_IP6;
443   else if (unformat (input, "l2"))
444     tid = POLICER_CLASSIFY_TABLE_L2;
445   else
446     return 0;
447
448   *r = tid;
449   return 1;
450 }
451
452 static uword
453 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
454 {
455   u32 *r = va_arg (*va, u32 *);
456   u32 tid;
457
458   if (unformat (input, "ip4"))
459     tid = FLOW_CLASSIFY_TABLE_IP4;
460   else if (unformat (input, "ip6"))
461     tid = FLOW_CLASSIFY_TABLE_IP6;
462   else
463     return 0;
464
465   *r = tid;
466   return 1;
467 }
468
469 #if (VPP_API_TEST_BUILTIN==0)
470 u8 *
471 format_ip4_address (u8 * s, va_list * args)
472 {
473   u8 *a = va_arg (*args, u8 *);
474   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
475 }
476
477 u8 *
478 format_ip6_address (u8 * s, va_list * args)
479 {
480   ip6_address_t *a = va_arg (*args, ip6_address_t *);
481   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
482
483   i_max_n_zero = ARRAY_LEN (a->as_u16);
484   max_n_zeros = 0;
485   i_first_zero = i_max_n_zero;
486   n_zeros = 0;
487   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
488     {
489       u32 is_zero = a->as_u16[i] == 0;
490       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
491         {
492           i_first_zero = i;
493           n_zeros = 0;
494         }
495       n_zeros += is_zero;
496       if ((!is_zero && n_zeros > max_n_zeros)
497           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
498         {
499           i_max_n_zero = i_first_zero;
500           max_n_zeros = n_zeros;
501           i_first_zero = ARRAY_LEN (a->as_u16);
502           n_zeros = 0;
503         }
504     }
505
506   last_double_colon = 0;
507   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
508     {
509       if (i == i_max_n_zero && max_n_zeros > 1)
510         {
511           s = format (s, "::");
512           i += max_n_zeros - 1;
513           last_double_colon = 1;
514         }
515       else
516         {
517           s = format (s, "%s%x",
518                       (last_double_colon || i == 0) ? "" : ":",
519                       clib_net_to_host_u16 (a->as_u16[i]));
520           last_double_colon = 0;
521         }
522     }
523
524   return s;
525 }
526
527 /* Format an IP46 address. */
528 u8 *
529 format_ip46_address (u8 * s, va_list * args)
530 {
531   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
532   ip46_type_t type = va_arg (*args, ip46_type_t);
533   int is_ip4 = 1;
534
535   switch (type)
536     {
537     case IP46_TYPE_ANY:
538       is_ip4 = ip46_address_is_ip4 (ip46);
539       break;
540     case IP46_TYPE_IP4:
541       is_ip4 = 1;
542       break;
543     case IP46_TYPE_IP6:
544       is_ip4 = 0;
545       break;
546     }
547
548   return is_ip4 ?
549     format (s, "%U", format_ip4_address, &ip46->ip4) :
550     format (s, "%U", format_ip6_address, &ip46->ip6);
551 }
552
553 u8 *
554 format_ethernet_address (u8 * s, va_list * args)
555 {
556   u8 *a = va_arg (*args, u8 *);
557
558   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
559                  a[0], a[1], a[2], a[3], a[4], a[5]);
560 }
561 #endif
562
563 static void
564 increment_v4_address (ip4_address_t * a)
565 {
566   u32 v;
567
568   v = ntohl (a->as_u32) + 1;
569   a->as_u32 = ntohl (v);
570 }
571
572 static void
573 increment_v6_address (ip6_address_t * a)
574 {
575   u64 v0, v1;
576
577   v0 = clib_net_to_host_u64 (a->as_u64[0]);
578   v1 = clib_net_to_host_u64 (a->as_u64[1]);
579
580   v1 += 1;
581   if (v1 == 0)
582     v0 += 1;
583   a->as_u64[0] = clib_net_to_host_u64 (v0);
584   a->as_u64[1] = clib_net_to_host_u64 (v1);
585 }
586
587 static void
588 increment_mac_address (u64 * mac)
589 {
590   u64 tmp = *mac;
591
592   tmp = clib_net_to_host_u64 (tmp);
593   tmp += 1 << 16;               /* skip unused (least significant) octets */
594   tmp = clib_host_to_net_u64 (tmp);
595   *mac = tmp;
596 }
597
598 static void vl_api_create_loopback_reply_t_handler
599   (vl_api_create_loopback_reply_t * mp)
600 {
601   vat_main_t *vam = &vat_main;
602   i32 retval = ntohl (mp->retval);
603
604   vam->retval = retval;
605   vam->regenerate_interface_table = 1;
606   vam->sw_if_index = ntohl (mp->sw_if_index);
607   vam->result_ready = 1;
608 }
609
610 static void vl_api_create_loopback_reply_t_handler_json
611   (vl_api_create_loopback_reply_t * mp)
612 {
613   vat_main_t *vam = &vat_main;
614   vat_json_node_t node;
615
616   vat_json_init_object (&node);
617   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
618   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
619
620   vat_json_print (vam->ofp, &node);
621   vat_json_free (&node);
622   vam->retval = ntohl (mp->retval);
623   vam->result_ready = 1;
624 }
625
626 static void vl_api_af_packet_create_reply_t_handler
627   (vl_api_af_packet_create_reply_t * mp)
628 {
629   vat_main_t *vam = &vat_main;
630   i32 retval = ntohl (mp->retval);
631
632   vam->retval = retval;
633   vam->regenerate_interface_table = 1;
634   vam->sw_if_index = ntohl (mp->sw_if_index);
635   vam->result_ready = 1;
636 }
637
638 static void vl_api_af_packet_create_reply_t_handler_json
639   (vl_api_af_packet_create_reply_t * mp)
640 {
641   vat_main_t *vam = &vat_main;
642   vat_json_node_t node;
643
644   vat_json_init_object (&node);
645   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
646   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
647
648   vat_json_print (vam->ofp, &node);
649   vat_json_free (&node);
650
651   vam->retval = ntohl (mp->retval);
652   vam->result_ready = 1;
653 }
654
655 static void vl_api_create_vlan_subif_reply_t_handler
656   (vl_api_create_vlan_subif_reply_t * mp)
657 {
658   vat_main_t *vam = &vat_main;
659   i32 retval = ntohl (mp->retval);
660
661   vam->retval = retval;
662   vam->regenerate_interface_table = 1;
663   vam->sw_if_index = ntohl (mp->sw_if_index);
664   vam->result_ready = 1;
665 }
666
667 static void vl_api_create_vlan_subif_reply_t_handler_json
668   (vl_api_create_vlan_subif_reply_t * mp)
669 {
670   vat_main_t *vam = &vat_main;
671   vat_json_node_t node;
672
673   vat_json_init_object (&node);
674   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
675   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
676
677   vat_json_print (vam->ofp, &node);
678   vat_json_free (&node);
679
680   vam->retval = ntohl (mp->retval);
681   vam->result_ready = 1;
682 }
683
684 static void vl_api_create_subif_reply_t_handler
685   (vl_api_create_subif_reply_t * mp)
686 {
687   vat_main_t *vam = &vat_main;
688   i32 retval = ntohl (mp->retval);
689
690   vam->retval = retval;
691   vam->regenerate_interface_table = 1;
692   vam->sw_if_index = ntohl (mp->sw_if_index);
693   vam->result_ready = 1;
694 }
695
696 static void vl_api_create_subif_reply_t_handler_json
697   (vl_api_create_subif_reply_t * mp)
698 {
699   vat_main_t *vam = &vat_main;
700   vat_json_node_t node;
701
702   vat_json_init_object (&node);
703   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
704   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
705
706   vat_json_print (vam->ofp, &node);
707   vat_json_free (&node);
708
709   vam->retval = ntohl (mp->retval);
710   vam->result_ready = 1;
711 }
712
713 static void vl_api_interface_name_renumber_reply_t_handler
714   (vl_api_interface_name_renumber_reply_t * mp)
715 {
716   vat_main_t *vam = &vat_main;
717   i32 retval = ntohl (mp->retval);
718
719   vam->retval = retval;
720   vam->regenerate_interface_table = 1;
721   vam->result_ready = 1;
722 }
723
724 static void vl_api_interface_name_renumber_reply_t_handler_json
725   (vl_api_interface_name_renumber_reply_t * mp)
726 {
727   vat_main_t *vam = &vat_main;
728   vat_json_node_t node;
729
730   vat_json_init_object (&node);
731   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
732
733   vat_json_print (vam->ofp, &node);
734   vat_json_free (&node);
735
736   vam->retval = ntohl (mp->retval);
737   vam->result_ready = 1;
738 }
739
740 /*
741  * Special-case: build the interface table, maintain
742  * the next loopback sw_if_index vbl.
743  */
744 static void vl_api_sw_interface_details_t_handler
745   (vl_api_sw_interface_details_t * mp)
746 {
747   vat_main_t *vam = &vat_main;
748   u8 *s = format (0, "%s%c", mp->interface_name, 0);
749
750   hash_set_mem (vam->sw_if_index_by_interface_name, s,
751                 ntohl (mp->sw_if_index));
752
753   /* In sub interface case, fill the sub interface table entry */
754   if (mp->sw_if_index != mp->sup_sw_if_index)
755     {
756       sw_interface_subif_t *sub = NULL;
757
758       vec_add2 (vam->sw_if_subif_table, sub, 1);
759
760       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
761       strncpy ((char *) sub->interface_name, (char *) s,
762                vec_len (sub->interface_name));
763       sub->sw_if_index = ntohl (mp->sw_if_index);
764       sub->sub_id = ntohl (mp->sub_id);
765
766       sub->sub_dot1ad = mp->sub_dot1ad;
767       sub->sub_number_of_tags = mp->sub_number_of_tags;
768       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
769       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
770       sub->sub_exact_match = mp->sub_exact_match;
771       sub->sub_default = mp->sub_default;
772       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
773       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
774
775       /* vlan tag rewrite */
776       sub->vtr_op = ntohl (mp->vtr_op);
777       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
778       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
779       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
780     }
781 }
782
783 static void vl_api_sw_interface_details_t_handler_json
784   (vl_api_sw_interface_details_t * mp)
785 {
786   vat_main_t *vam = &vat_main;
787   vat_json_node_t *node = NULL;
788
789   if (VAT_JSON_ARRAY != vam->json_tree.type)
790     {
791       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
792       vat_json_init_array (&vam->json_tree);
793     }
794   node = vat_json_array_add (&vam->json_tree);
795
796   vat_json_init_object (node);
797   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
798   vat_json_object_add_uint (node, "sup_sw_if_index",
799                             ntohl (mp->sup_sw_if_index));
800   vat_json_object_add_uint (node, "l2_address_length",
801                             ntohl (mp->l2_address_length));
802   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
803                              sizeof (mp->l2_address));
804   vat_json_object_add_string_copy (node, "interface_name",
805                                    mp->interface_name);
806   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
807   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
808   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
809   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
810   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
811   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
812   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
813   vat_json_object_add_uint (node, "sub_number_of_tags",
814                             mp->sub_number_of_tags);
815   vat_json_object_add_uint (node, "sub_outer_vlan_id",
816                             ntohs (mp->sub_outer_vlan_id));
817   vat_json_object_add_uint (node, "sub_inner_vlan_id",
818                             ntohs (mp->sub_inner_vlan_id));
819   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
820   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
821   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
822                             mp->sub_outer_vlan_id_any);
823   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
824                             mp->sub_inner_vlan_id_any);
825   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
826   vat_json_object_add_uint (node, "vtr_push_dot1q",
827                             ntohl (mp->vtr_push_dot1q));
828   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
829   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
830 }
831
832 static void vl_api_sw_interface_set_flags_t_handler
833   (vl_api_sw_interface_set_flags_t * mp)
834 {
835   vat_main_t *vam = &vat_main;
836   if (vam->interface_event_display)
837     errmsg ("interface flags: sw_if_index %d %s %s",
838             ntohl (mp->sw_if_index),
839             mp->admin_up_down ? "admin-up" : "admin-down",
840             mp->link_up_down ? "link-up" : "link-down");
841 }
842
843 static void vl_api_sw_interface_set_flags_t_handler_json
844   (vl_api_sw_interface_set_flags_t * mp)
845 {
846   /* JSON output not supported */
847 }
848
849 static void
850 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
851 {
852   vat_main_t *vam = &vat_main;
853   i32 retval = ntohl (mp->retval);
854
855   vam->retval = retval;
856   vam->shmem_result = (u8 *) mp->reply_in_shmem;
857   vam->result_ready = 1;
858 }
859
860 static void
861 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
862 {
863   vat_main_t *vam = &vat_main;
864   vat_json_node_t node;
865   api_main_t *am = &api_main;
866   void *oldheap;
867   u8 *reply;
868
869   vat_json_init_object (&node);
870   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
871   vat_json_object_add_uint (&node, "reply_in_shmem",
872                             ntohl (mp->reply_in_shmem));
873   /* Toss the shared-memory original... */
874   pthread_mutex_lock (&am->vlib_rp->mutex);
875   oldheap = svm_push_data_heap (am->vlib_rp);
876
877   reply = (u8 *) (mp->reply_in_shmem);
878   vec_free (reply);
879
880   svm_pop_heap (oldheap);
881   pthread_mutex_unlock (&am->vlib_rp->mutex);
882
883   vat_json_print (vam->ofp, &node);
884   vat_json_free (&node);
885
886   vam->retval = ntohl (mp->retval);
887   vam->result_ready = 1;
888 }
889
890 static void
891 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
892 {
893   vat_main_t *vam = &vat_main;
894   i32 retval = ntohl (mp->retval);
895
896   vam->retval = retval;
897   vam->cmd_reply = mp->reply;
898   vam->result_ready = 1;
899 }
900
901 static void
902 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
903 {
904   vat_main_t *vam = &vat_main;
905   vat_json_node_t node;
906
907   vat_json_init_object (&node);
908   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
909   vat_json_object_add_string_copy (&node, "reply", mp->reply);
910
911   vat_json_print (vam->ofp, &node);
912   vat_json_free (&node);
913
914   vam->retval = ntohl (mp->retval);
915   vam->result_ready = 1;
916 }
917
918 static void vl_api_classify_add_del_table_reply_t_handler
919   (vl_api_classify_add_del_table_reply_t * mp)
920 {
921   vat_main_t *vam = &vat_main;
922   i32 retval = ntohl (mp->retval);
923   if (vam->async_mode)
924     {
925       vam->async_errors += (retval < 0);
926     }
927   else
928     {
929       vam->retval = retval;
930       if (retval == 0 &&
931           ((mp->new_table_index != 0xFFFFFFFF) ||
932            (mp->skip_n_vectors != 0xFFFFFFFF) ||
933            (mp->match_n_vectors != 0xFFFFFFFF)))
934         /*
935          * Note: this is just barely thread-safe, depends on
936          * the main thread spinning waiting for an answer...
937          */
938         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
939                 ntohl (mp->new_table_index),
940                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
941       vam->result_ready = 1;
942     }
943 }
944
945 static void vl_api_classify_add_del_table_reply_t_handler_json
946   (vl_api_classify_add_del_table_reply_t * mp)
947 {
948   vat_main_t *vam = &vat_main;
949   vat_json_node_t node;
950
951   vat_json_init_object (&node);
952   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
953   vat_json_object_add_uint (&node, "new_table_index",
954                             ntohl (mp->new_table_index));
955   vat_json_object_add_uint (&node, "skip_n_vectors",
956                             ntohl (mp->skip_n_vectors));
957   vat_json_object_add_uint (&node, "match_n_vectors",
958                             ntohl (mp->match_n_vectors));
959
960   vat_json_print (vam->ofp, &node);
961   vat_json_free (&node);
962
963   vam->retval = ntohl (mp->retval);
964   vam->result_ready = 1;
965 }
966
967 static void vl_api_get_node_index_reply_t_handler
968   (vl_api_get_node_index_reply_t * mp)
969 {
970   vat_main_t *vam = &vat_main;
971   i32 retval = ntohl (mp->retval);
972   if (vam->async_mode)
973     {
974       vam->async_errors += (retval < 0);
975     }
976   else
977     {
978       vam->retval = retval;
979       if (retval == 0)
980         errmsg ("node index %d", ntohl (mp->node_index));
981       vam->result_ready = 1;
982     }
983 }
984
985 static void vl_api_get_node_index_reply_t_handler_json
986   (vl_api_get_node_index_reply_t * mp)
987 {
988   vat_main_t *vam = &vat_main;
989   vat_json_node_t node;
990
991   vat_json_init_object (&node);
992   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
993   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
994
995   vat_json_print (vam->ofp, &node);
996   vat_json_free (&node);
997
998   vam->retval = ntohl (mp->retval);
999   vam->result_ready = 1;
1000 }
1001
1002 static void vl_api_get_next_index_reply_t_handler
1003   (vl_api_get_next_index_reply_t * mp)
1004 {
1005   vat_main_t *vam = &vat_main;
1006   i32 retval = ntohl (mp->retval);
1007   if (vam->async_mode)
1008     {
1009       vam->async_errors += (retval < 0);
1010     }
1011   else
1012     {
1013       vam->retval = retval;
1014       if (retval == 0)
1015         errmsg ("next node index %d", ntohl (mp->next_index));
1016       vam->result_ready = 1;
1017     }
1018 }
1019
1020 static void vl_api_get_next_index_reply_t_handler_json
1021   (vl_api_get_next_index_reply_t * mp)
1022 {
1023   vat_main_t *vam = &vat_main;
1024   vat_json_node_t node;
1025
1026   vat_json_init_object (&node);
1027   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1028   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1029
1030   vat_json_print (vam->ofp, &node);
1031   vat_json_free (&node);
1032
1033   vam->retval = ntohl (mp->retval);
1034   vam->result_ready = 1;
1035 }
1036
1037 static void vl_api_add_node_next_reply_t_handler
1038   (vl_api_add_node_next_reply_t * mp)
1039 {
1040   vat_main_t *vam = &vat_main;
1041   i32 retval = ntohl (mp->retval);
1042   if (vam->async_mode)
1043     {
1044       vam->async_errors += (retval < 0);
1045     }
1046   else
1047     {
1048       vam->retval = retval;
1049       if (retval == 0)
1050         errmsg ("next index %d", ntohl (mp->next_index));
1051       vam->result_ready = 1;
1052     }
1053 }
1054
1055 static void vl_api_add_node_next_reply_t_handler_json
1056   (vl_api_add_node_next_reply_t * mp)
1057 {
1058   vat_main_t *vam = &vat_main;
1059   vat_json_node_t node;
1060
1061   vat_json_init_object (&node);
1062   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1063   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1064
1065   vat_json_print (vam->ofp, &node);
1066   vat_json_free (&node);
1067
1068   vam->retval = ntohl (mp->retval);
1069   vam->result_ready = 1;
1070 }
1071
1072 static void vl_api_show_version_reply_t_handler
1073   (vl_api_show_version_reply_t * mp)
1074 {
1075   vat_main_t *vam = &vat_main;
1076   i32 retval = ntohl (mp->retval);
1077
1078   if (retval >= 0)
1079     {
1080       errmsg ("        program: %s", mp->program);
1081       errmsg ("        version: %s", mp->version);
1082       errmsg ("     build date: %s", mp->build_date);
1083       errmsg ("build directory: %s", mp->build_directory);
1084     }
1085   vam->retval = retval;
1086   vam->result_ready = 1;
1087 }
1088
1089 static void vl_api_show_version_reply_t_handler_json
1090   (vl_api_show_version_reply_t * mp)
1091 {
1092   vat_main_t *vam = &vat_main;
1093   vat_json_node_t node;
1094
1095   vat_json_init_object (&node);
1096   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1097   vat_json_object_add_string_copy (&node, "program", mp->program);
1098   vat_json_object_add_string_copy (&node, "version", mp->version);
1099   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1100   vat_json_object_add_string_copy (&node, "build_directory",
1101                                    mp->build_directory);
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
1111 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1112 {
1113   errmsg ("arp %s event: address %U new mac %U sw_if_index %d",
1114           mp->mac_ip ? "mac/ip binding" : "address resolution",
1115           format_ip4_address, &mp->address,
1116           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1117 }
1118
1119 static void
1120 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1121 {
1122   /* JSON output not supported */
1123 }
1124
1125 static void
1126 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1127 {
1128   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d",
1129           mp->mac_ip ? "mac/ip binding" : "address resolution",
1130           format_ip6_address, mp->address,
1131           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1132 }
1133
1134 static void
1135 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1136 {
1137   /* JSON output not supported */
1138 }
1139
1140 /*
1141  * Special-case: build the bridge domain table, maintain
1142  * the next bd id vbl.
1143  */
1144 static void vl_api_bridge_domain_details_t_handler
1145   (vl_api_bridge_domain_details_t * mp)
1146 {
1147   vat_main_t *vam = &vat_main;
1148   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1149
1150   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s",
1151          " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1152
1153   print (vam->ofp, "%3d %3d %3d %3d %3d %3d",
1154          ntohl (mp->bd_id), mp->learn, mp->forward,
1155          mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1156
1157   if (n_sw_ifs)
1158     print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG", "Interface Name");
1159 }
1160
1161 static void vl_api_bridge_domain_details_t_handler_json
1162   (vl_api_bridge_domain_details_t * mp)
1163 {
1164   vat_main_t *vam = &vat_main;
1165   vat_json_node_t *node, *array = NULL;
1166
1167   if (VAT_JSON_ARRAY != vam->json_tree.type)
1168     {
1169       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1170       vat_json_init_array (&vam->json_tree);
1171     }
1172   node = vat_json_array_add (&vam->json_tree);
1173
1174   vat_json_init_object (node);
1175   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1176   vat_json_object_add_uint (node, "flood", mp->flood);
1177   vat_json_object_add_uint (node, "forward", mp->forward);
1178   vat_json_object_add_uint (node, "learn", mp->learn);
1179   vat_json_object_add_uint (node, "bvi_sw_if_index",
1180                             ntohl (mp->bvi_sw_if_index));
1181   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1182   array = vat_json_object_add (node, "sw_if");
1183   vat_json_init_array (array);
1184 }
1185
1186 /*
1187  * Special-case: build the bridge domain sw if table.
1188  */
1189 static void vl_api_bridge_domain_sw_if_details_t_handler
1190   (vl_api_bridge_domain_sw_if_details_t * mp)
1191 {
1192   vat_main_t *vam = &vat_main;
1193   hash_pair_t *p;
1194   u8 *sw_if_name = 0;
1195   u32 sw_if_index;
1196
1197   sw_if_index = ntohl (mp->sw_if_index);
1198   /* *INDENT-OFF* */
1199   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1200   ({
1201     if ((u32) p->value[0] == sw_if_index)
1202       {
1203         sw_if_name = (u8 *)(p->key);
1204         break;
1205       }
1206   }));
1207   /* *INDENT-ON* */
1208
1209   print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1210          mp->shg, sw_if_name ? (char *) sw_if_name :
1211          "sw_if_index not found!");
1212 }
1213
1214 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1215   (vl_api_bridge_domain_sw_if_details_t * mp)
1216 {
1217   vat_main_t *vam = &vat_main;
1218   vat_json_node_t *node = NULL;
1219   uword last_index = 0;
1220
1221   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1222   ASSERT (vec_len (vam->json_tree.array) >= 1);
1223   last_index = vec_len (vam->json_tree.array) - 1;
1224   node = &vam->json_tree.array[last_index];
1225   node = vat_json_object_get_element (node, "sw_if");
1226   ASSERT (NULL != node);
1227   node = vat_json_array_add (node);
1228
1229   vat_json_init_object (node);
1230   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1231   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1232   vat_json_object_add_uint (node, "shg", mp->shg);
1233 }
1234
1235 static void vl_api_control_ping_reply_t_handler
1236   (vl_api_control_ping_reply_t * mp)
1237 {
1238   vat_main_t *vam = &vat_main;
1239   i32 retval = ntohl (mp->retval);
1240   if (vam->async_mode)
1241     {
1242       vam->async_errors += (retval < 0);
1243     }
1244   else
1245     {
1246       vam->retval = retval;
1247       vam->result_ready = 1;
1248     }
1249 }
1250
1251 static void vl_api_control_ping_reply_t_handler_json
1252   (vl_api_control_ping_reply_t * mp)
1253 {
1254   vat_main_t *vam = &vat_main;
1255   i32 retval = ntohl (mp->retval);
1256
1257   if (VAT_JSON_NONE != vam->json_tree.type)
1258     {
1259       vat_json_print (vam->ofp, &vam->json_tree);
1260       vat_json_free (&vam->json_tree);
1261       vam->json_tree.type = VAT_JSON_NONE;
1262     }
1263   else
1264     {
1265       /* just print [] */
1266       vat_json_init_array (&vam->json_tree);
1267       vat_json_print (vam->ofp, &vam->json_tree);
1268       vam->json_tree.type = VAT_JSON_NONE;
1269     }
1270
1271   vam->retval = retval;
1272   vam->result_ready = 1;
1273 }
1274
1275 static void
1276 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1277 {
1278   vat_main_t *vam = &vat_main;
1279   i32 retval = ntohl (mp->retval);
1280   if (vam->async_mode)
1281     {
1282       vam->async_errors += (retval < 0);
1283     }
1284   else
1285     {
1286       vam->retval = retval;
1287       vam->result_ready = 1;
1288     }
1289 }
1290
1291 static void vl_api_l2_flags_reply_t_handler_json
1292   (vl_api_l2_flags_reply_t * mp)
1293 {
1294   vat_main_t *vam = &vat_main;
1295   vat_json_node_t node;
1296
1297   vat_json_init_object (&node);
1298   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1299   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1300                             ntohl (mp->resulting_feature_bitmap));
1301
1302   vat_json_print (vam->ofp, &node);
1303   vat_json_free (&node);
1304
1305   vam->retval = ntohl (mp->retval);
1306   vam->result_ready = 1;
1307 }
1308
1309 static void vl_api_bridge_flags_reply_t_handler
1310   (vl_api_bridge_flags_reply_t * mp)
1311 {
1312   vat_main_t *vam = &vat_main;
1313   i32 retval = ntohl (mp->retval);
1314   if (vam->async_mode)
1315     {
1316       vam->async_errors += (retval < 0);
1317     }
1318   else
1319     {
1320       vam->retval = retval;
1321       vam->result_ready = 1;
1322     }
1323 }
1324
1325 static void vl_api_bridge_flags_reply_t_handler_json
1326   (vl_api_bridge_flags_reply_t * mp)
1327 {
1328   vat_main_t *vam = &vat_main;
1329   vat_json_node_t node;
1330
1331   vat_json_init_object (&node);
1332   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1333   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1334                             ntohl (mp->resulting_feature_bitmap));
1335
1336   vat_json_print (vam->ofp, &node);
1337   vat_json_free (&node);
1338
1339   vam->retval = ntohl (mp->retval);
1340   vam->result_ready = 1;
1341 }
1342
1343 static void vl_api_tap_connect_reply_t_handler
1344   (vl_api_tap_connect_reply_t * mp)
1345 {
1346   vat_main_t *vam = &vat_main;
1347   i32 retval = ntohl (mp->retval);
1348   if (vam->async_mode)
1349     {
1350       vam->async_errors += (retval < 0);
1351     }
1352   else
1353     {
1354       vam->retval = retval;
1355       vam->sw_if_index = ntohl (mp->sw_if_index);
1356       vam->result_ready = 1;
1357     }
1358
1359 }
1360
1361 static void vl_api_tap_connect_reply_t_handler_json
1362   (vl_api_tap_connect_reply_t * mp)
1363 {
1364   vat_main_t *vam = &vat_main;
1365   vat_json_node_t node;
1366
1367   vat_json_init_object (&node);
1368   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1369   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1370
1371   vat_json_print (vam->ofp, &node);
1372   vat_json_free (&node);
1373
1374   vam->retval = ntohl (mp->retval);
1375   vam->result_ready = 1;
1376
1377 }
1378
1379 static void
1380 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1381 {
1382   vat_main_t *vam = &vat_main;
1383   i32 retval = ntohl (mp->retval);
1384   if (vam->async_mode)
1385     {
1386       vam->async_errors += (retval < 0);
1387     }
1388   else
1389     {
1390       vam->retval = retval;
1391       vam->sw_if_index = ntohl (mp->sw_if_index);
1392       vam->result_ready = 1;
1393     }
1394 }
1395
1396 static void vl_api_tap_modify_reply_t_handler_json
1397   (vl_api_tap_modify_reply_t * mp)
1398 {
1399   vat_main_t *vam = &vat_main;
1400   vat_json_node_t node;
1401
1402   vat_json_init_object (&node);
1403   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1404   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1405
1406   vat_json_print (vam->ofp, &node);
1407   vat_json_free (&node);
1408
1409   vam->retval = ntohl (mp->retval);
1410   vam->result_ready = 1;
1411 }
1412
1413 static void
1414 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1415 {
1416   vat_main_t *vam = &vat_main;
1417   i32 retval = ntohl (mp->retval);
1418   if (vam->async_mode)
1419     {
1420       vam->async_errors += (retval < 0);
1421     }
1422   else
1423     {
1424       vam->retval = retval;
1425       vam->result_ready = 1;
1426     }
1427 }
1428
1429 static void vl_api_tap_delete_reply_t_handler_json
1430   (vl_api_tap_delete_reply_t * mp)
1431 {
1432   vat_main_t *vam = &vat_main;
1433   vat_json_node_t node;
1434
1435   vat_json_init_object (&node);
1436   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1437
1438   vat_json_print (vam->ofp, &node);
1439   vat_json_free (&node);
1440
1441   vam->retval = ntohl (mp->retval);
1442   vam->result_ready = 1;
1443 }
1444
1445 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1446   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1447 {
1448   vat_main_t *vam = &vat_main;
1449   i32 retval = ntohl (mp->retval);
1450   if (vam->async_mode)
1451     {
1452       vam->async_errors += (retval < 0);
1453     }
1454   else
1455     {
1456       vam->retval = retval;
1457       vam->result_ready = 1;
1458     }
1459 }
1460
1461 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1462   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1463 {
1464   vat_main_t *vam = &vat_main;
1465   vat_json_node_t node;
1466
1467   vat_json_init_object (&node);
1468   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1469   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1470                             ntohl (mp->sw_if_index));
1471
1472   vat_json_print (vam->ofp, &node);
1473   vat_json_free (&node);
1474
1475   vam->retval = ntohl (mp->retval);
1476   vam->result_ready = 1;
1477 }
1478
1479 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1480   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1481 {
1482   vat_main_t *vam = &vat_main;
1483   i32 retval = ntohl (mp->retval);
1484   if (vam->async_mode)
1485     {
1486       vam->async_errors += (retval < 0);
1487     }
1488   else
1489     {
1490       vam->retval = retval;
1491       vam->sw_if_index = ntohl (mp->sw_if_index);
1492       vam->result_ready = 1;
1493     }
1494 }
1495
1496 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1497   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1498 {
1499   vat_main_t *vam = &vat_main;
1500   vat_json_node_t node;
1501
1502   vat_json_init_object (&node);
1503   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1504   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1505
1506   vat_json_print (vam->ofp, &node);
1507   vat_json_free (&node);
1508
1509   vam->retval = ntohl (mp->retval);
1510   vam->result_ready = 1;
1511 }
1512
1513
1514 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1515   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1516 {
1517   vat_main_t *vam = &vat_main;
1518   i32 retval = ntohl (mp->retval);
1519   if (vam->async_mode)
1520     {
1521       vam->async_errors += (retval < 0);
1522     }
1523   else
1524     {
1525       vam->retval = retval;
1526       vam->result_ready = 1;
1527     }
1528 }
1529
1530 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1531   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1532 {
1533   vat_main_t *vam = &vat_main;
1534   vat_json_node_t node;
1535
1536   vat_json_init_object (&node);
1537   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1538   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1539
1540   vat_json_print (vam->ofp, &node);
1541   vat_json_free (&node);
1542
1543   vam->retval = ntohl (mp->retval);
1544   vam->result_ready = 1;
1545 }
1546
1547 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1548   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1549 {
1550   vat_main_t *vam = &vat_main;
1551   i32 retval = ntohl (mp->retval);
1552   if (vam->async_mode)
1553     {
1554       vam->async_errors += (retval < 0);
1555     }
1556   else
1557     {
1558       vam->retval = retval;
1559       vam->sw_if_index = ntohl (mp->sw_if_index);
1560       vam->result_ready = 1;
1561     }
1562 }
1563
1564 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1565   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1566 {
1567   vat_main_t *vam = &vat_main;
1568   vat_json_node_t node;
1569
1570   vat_json_init_object (&node);
1571   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1572   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1573
1574   vat_json_print (vam->ofp, &node);
1575   vat_json_free (&node);
1576
1577   vam->retval = ntohl (mp->retval);
1578   vam->result_ready = 1;
1579 }
1580
1581 static void vl_api_gre_add_del_tunnel_reply_t_handler
1582   (vl_api_gre_add_del_tunnel_reply_t * mp)
1583 {
1584   vat_main_t *vam = &vat_main;
1585   i32 retval = ntohl (mp->retval);
1586   if (vam->async_mode)
1587     {
1588       vam->async_errors += (retval < 0);
1589     }
1590   else
1591     {
1592       vam->retval = retval;
1593       vam->sw_if_index = ntohl (mp->sw_if_index);
1594       vam->result_ready = 1;
1595     }
1596 }
1597
1598 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1599   (vl_api_gre_add_del_tunnel_reply_t * mp)
1600 {
1601   vat_main_t *vam = &vat_main;
1602   vat_json_node_t node;
1603
1604   vat_json_init_object (&node);
1605   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1606   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1607
1608   vat_json_print (vam->ofp, &node);
1609   vat_json_free (&node);
1610
1611   vam->retval = ntohl (mp->retval);
1612   vam->result_ready = 1;
1613 }
1614
1615 static void vl_api_create_vhost_user_if_reply_t_handler
1616   (vl_api_create_vhost_user_if_reply_t * mp)
1617 {
1618   vat_main_t *vam = &vat_main;
1619   i32 retval = ntohl (mp->retval);
1620   if (vam->async_mode)
1621     {
1622       vam->async_errors += (retval < 0);
1623     }
1624   else
1625     {
1626       vam->retval = retval;
1627       vam->sw_if_index = ntohl (mp->sw_if_index);
1628       vam->result_ready = 1;
1629     }
1630 }
1631
1632 static void vl_api_create_vhost_user_if_reply_t_handler_json
1633   (vl_api_create_vhost_user_if_reply_t * mp)
1634 {
1635   vat_main_t *vam = &vat_main;
1636   vat_json_node_t node;
1637
1638   vat_json_init_object (&node);
1639   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1640   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1641
1642   vat_json_print (vam->ofp, &node);
1643   vat_json_free (&node);
1644
1645   vam->retval = ntohl (mp->retval);
1646   vam->result_ready = 1;
1647 }
1648
1649 static void vl_api_ip_address_details_t_handler
1650   (vl_api_ip_address_details_t * mp)
1651 {
1652   vat_main_t *vam = &vat_main;
1653   static ip_address_details_t empty_ip_address_details = { {0} };
1654   ip_address_details_t *address = NULL;
1655   ip_details_t *current_ip_details = NULL;
1656   ip_details_t *details = NULL;
1657
1658   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1659
1660   if (!details || vam->current_sw_if_index >= vec_len (details)
1661       || !details[vam->current_sw_if_index].present)
1662     {
1663       errmsg ("ip address details arrived but not stored");
1664       errmsg ("ip_dump should be called first");
1665       return;
1666     }
1667
1668   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1669
1670 #define addresses (current_ip_details->addr)
1671
1672   vec_validate_init_empty (addresses, vec_len (addresses),
1673                            empty_ip_address_details);
1674
1675   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1676
1677   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1678   address->prefix_length = mp->prefix_length;
1679 #undef addresses
1680 }
1681
1682 static void vl_api_ip_address_details_t_handler_json
1683   (vl_api_ip_address_details_t * mp)
1684 {
1685   vat_main_t *vam = &vat_main;
1686   vat_json_node_t *node = NULL;
1687   struct in6_addr ip6;
1688   struct in_addr ip4;
1689
1690   if (VAT_JSON_ARRAY != vam->json_tree.type)
1691     {
1692       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1693       vat_json_init_array (&vam->json_tree);
1694     }
1695   node = vat_json_array_add (&vam->json_tree);
1696
1697   vat_json_init_object (node);
1698   if (vam->is_ipv6)
1699     {
1700       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1701       vat_json_object_add_ip6 (node, "ip", ip6);
1702     }
1703   else
1704     {
1705       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1706       vat_json_object_add_ip4 (node, "ip", ip4);
1707     }
1708   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1709 }
1710
1711 static void
1712 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1713 {
1714   vat_main_t *vam = &vat_main;
1715   static ip_details_t empty_ip_details = { 0 };
1716   ip_details_t *ip = NULL;
1717   u32 sw_if_index = ~0;
1718
1719   sw_if_index = ntohl (mp->sw_if_index);
1720
1721   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1722                            sw_if_index, empty_ip_details);
1723
1724   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1725                          sw_if_index);
1726
1727   ip->present = 1;
1728 }
1729
1730 static void
1731 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1732 {
1733   vat_main_t *vam = &vat_main;
1734
1735   if (VAT_JSON_ARRAY != vam->json_tree.type)
1736     {
1737       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1738       vat_json_init_array (&vam->json_tree);
1739     }
1740   vat_json_array_add_uint (&vam->json_tree,
1741                            clib_net_to_host_u32 (mp->sw_if_index));
1742 }
1743
1744 static void vl_api_map_domain_details_t_handler_json
1745   (vl_api_map_domain_details_t * mp)
1746 {
1747   vat_json_node_t *node = NULL;
1748   vat_main_t *vam = &vat_main;
1749   struct in6_addr ip6;
1750   struct in_addr ip4;
1751
1752   if (VAT_JSON_ARRAY != vam->json_tree.type)
1753     {
1754       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1755       vat_json_init_array (&vam->json_tree);
1756     }
1757
1758   node = vat_json_array_add (&vam->json_tree);
1759   vat_json_init_object (node);
1760
1761   vat_json_object_add_uint (node, "domain_index",
1762                             clib_net_to_host_u32 (mp->domain_index));
1763   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1764   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1765   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1766   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1767   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1768   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1769   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1770   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1771   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1772   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1773   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1774   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1775   vat_json_object_add_uint (node, "flags", mp->flags);
1776   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1777   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1778 }
1779
1780 static void vl_api_map_domain_details_t_handler
1781   (vl_api_map_domain_details_t * mp)
1782 {
1783   vat_main_t *vam = &vat_main;
1784
1785   if (mp->is_translation)
1786     {
1787       print (vam->ofp,
1788              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u",
1789              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1790              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1791              format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1792              clib_net_to_host_u32 (mp->domain_index));
1793     }
1794   else
1795     {
1796       print (vam->ofp,
1797              "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u",
1798              format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1799              format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1800              format_ip6_address, mp->ip6_src,
1801              clib_net_to_host_u32 (mp->domain_index));
1802     }
1803   print (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s",
1804          mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1805          mp->is_translation ? "map-t" : "");
1806 }
1807
1808 static void vl_api_map_rule_details_t_handler_json
1809   (vl_api_map_rule_details_t * mp)
1810 {
1811   struct in6_addr ip6;
1812   vat_json_node_t *node = NULL;
1813   vat_main_t *vam = &vat_main;
1814
1815   if (VAT_JSON_ARRAY != vam->json_tree.type)
1816     {
1817       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1818       vat_json_init_array (&vam->json_tree);
1819     }
1820
1821   node = vat_json_array_add (&vam->json_tree);
1822   vat_json_init_object (node);
1823
1824   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1825   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1826   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1827 }
1828
1829 static void
1830 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1831 {
1832   vat_main_t *vam = &vat_main;
1833   print (vam->ofp, " %d (psid) %U (ip6-dst)",
1834          clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1835 }
1836
1837 static void
1838 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1839 {
1840   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1841           "router_addr %U host_mac %U",
1842           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1843           format_ip4_address, &mp->host_address,
1844           format_ip4_address, &mp->router_address,
1845           format_ethernet_address, mp->host_mac);
1846 }
1847
1848 static void vl_api_dhcp_compl_event_t_handler_json
1849   (vl_api_dhcp_compl_event_t * mp)
1850 {
1851   /* JSON output not supported */
1852 }
1853
1854 static void
1855 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1856                               u32 counter)
1857 {
1858   vat_main_t *vam = &vat_main;
1859   static u64 default_counter = 0;
1860
1861   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1862                            NULL);
1863   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1864                            sw_if_index, default_counter);
1865   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1866 }
1867
1868 static void
1869 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1870                                 interface_counter_t counter)
1871 {
1872   vat_main_t *vam = &vat_main;
1873   static interface_counter_t default_counter = { 0, };
1874
1875   vec_validate_init_empty (vam->combined_interface_counters,
1876                            vnet_counter_type, NULL);
1877   vec_validate_init_empty (vam->combined_interface_counters
1878                            [vnet_counter_type], sw_if_index, default_counter);
1879   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1880 }
1881
1882 static void vl_api_vnet_interface_counters_t_handler
1883   (vl_api_vnet_interface_counters_t * mp)
1884 {
1885   /* not supported */
1886 }
1887
1888 static void vl_api_vnet_interface_counters_t_handler_json
1889   (vl_api_vnet_interface_counters_t * mp)
1890 {
1891   interface_counter_t counter;
1892   vlib_counter_t *v;
1893   u64 *v_packets;
1894   u64 packets;
1895   u32 count;
1896   u32 first_sw_if_index;
1897   int i;
1898
1899   count = ntohl (mp->count);
1900   first_sw_if_index = ntohl (mp->first_sw_if_index);
1901
1902   if (!mp->is_combined)
1903     {
1904       v_packets = (u64 *) & mp->data;
1905       for (i = 0; i < count; i++)
1906         {
1907           packets =
1908             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1909           set_simple_interface_counter (mp->vnet_counter_type,
1910                                         first_sw_if_index + i, packets);
1911           v_packets++;
1912         }
1913     }
1914   else
1915     {
1916       v = (vlib_counter_t *) & mp->data;
1917       for (i = 0; i < count; i++)
1918         {
1919           counter.packets =
1920             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1921           counter.bytes =
1922             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1923           set_combined_interface_counter (mp->vnet_counter_type,
1924                                           first_sw_if_index + i, counter);
1925           v++;
1926         }
1927     }
1928 }
1929
1930 static u32
1931 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1932 {
1933   vat_main_t *vam = &vat_main;
1934   u32 i;
1935
1936   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1937     {
1938       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1939         {
1940           return i;
1941         }
1942     }
1943   return ~0;
1944 }
1945
1946 static u32
1947 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1948 {
1949   vat_main_t *vam = &vat_main;
1950   u32 i;
1951
1952   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1953     {
1954       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1955         {
1956           return i;
1957         }
1958     }
1959   return ~0;
1960 }
1961
1962 static void vl_api_vnet_ip4_fib_counters_t_handler
1963   (vl_api_vnet_ip4_fib_counters_t * mp)
1964 {
1965   /* not supported */
1966 }
1967
1968 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1969   (vl_api_vnet_ip4_fib_counters_t * mp)
1970 {
1971   vat_main_t *vam = &vat_main;
1972   vl_api_ip4_fib_counter_t *v;
1973   ip4_fib_counter_t *counter;
1974   struct in_addr ip4;
1975   u32 vrf_id;
1976   u32 vrf_index;
1977   u32 count;
1978   int i;
1979
1980   vrf_id = ntohl (mp->vrf_id);
1981   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
1982   if (~0 == vrf_index)
1983     {
1984       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
1985       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1986       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1987       vec_validate (vam->ip4_fib_counters, vrf_index);
1988       vam->ip4_fib_counters[vrf_index] = NULL;
1989     }
1990
1991   vec_free (vam->ip4_fib_counters[vrf_index]);
1992   v = (vl_api_ip4_fib_counter_t *) & mp->c;
1993   count = ntohl (mp->count);
1994   for (i = 0; i < count; i++)
1995     {
1996       vec_validate (vam->ip4_fib_counters[vrf_index], i);
1997       counter = &vam->ip4_fib_counters[vrf_index][i];
1998       clib_memcpy (&ip4, &v->address, sizeof (ip4));
1999       counter->address = ip4;
2000       counter->address_length = v->address_length;
2001       counter->packets = clib_net_to_host_u64 (v->packets);
2002       counter->bytes = clib_net_to_host_u64 (v->bytes);
2003       v++;
2004     }
2005 }
2006
2007 static void vl_api_vnet_ip6_fib_counters_t_handler
2008   (vl_api_vnet_ip6_fib_counters_t * mp)
2009 {
2010   /* not supported */
2011 }
2012
2013 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2014   (vl_api_vnet_ip6_fib_counters_t * mp)
2015 {
2016   vat_main_t *vam = &vat_main;
2017   vl_api_ip6_fib_counter_t *v;
2018   ip6_fib_counter_t *counter;
2019   struct in6_addr ip6;
2020   u32 vrf_id;
2021   u32 vrf_index;
2022   u32 count;
2023   int i;
2024
2025   vrf_id = ntohl (mp->vrf_id);
2026   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2027   if (~0 == vrf_index)
2028     {
2029       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2030       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2031       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2032       vec_validate (vam->ip6_fib_counters, vrf_index);
2033       vam->ip6_fib_counters[vrf_index] = NULL;
2034     }
2035
2036   vec_free (vam->ip6_fib_counters[vrf_index]);
2037   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2038   count = ntohl (mp->count);
2039   for (i = 0; i < count; i++)
2040     {
2041       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2042       counter = &vam->ip6_fib_counters[vrf_index][i];
2043       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2044       counter->address = ip6;
2045       counter->address_length = v->address_length;
2046       counter->packets = clib_net_to_host_u64 (v->packets);
2047       counter->bytes = clib_net_to_host_u64 (v->bytes);
2048       v++;
2049     }
2050 }
2051
2052 static void vl_api_get_first_msg_id_reply_t_handler
2053   (vl_api_get_first_msg_id_reply_t * mp)
2054 {
2055   vat_main_t *vam = &vat_main;
2056   i32 retval = ntohl (mp->retval);
2057
2058   if (vam->async_mode)
2059     {
2060       vam->async_errors += (retval < 0);
2061     }
2062   else
2063     {
2064       vam->retval = retval;
2065       vam->result_ready = 1;
2066     }
2067   if (retval >= 0)
2068     {
2069       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2070     }
2071 }
2072
2073 static void vl_api_get_first_msg_id_reply_t_handler_json
2074   (vl_api_get_first_msg_id_reply_t * mp)
2075 {
2076   vat_main_t *vam = &vat_main;
2077   vat_json_node_t node;
2078
2079   vat_json_init_object (&node);
2080   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2081   vat_json_object_add_uint (&node, "first_msg_id",
2082                             (uint) ntohs (mp->first_msg_id));
2083
2084   vat_json_print (vam->ofp, &node);
2085   vat_json_free (&node);
2086
2087   vam->retval = ntohl (mp->retval);
2088   vam->result_ready = 1;
2089 }
2090
2091 static void vl_api_get_node_graph_reply_t_handler
2092   (vl_api_get_node_graph_reply_t * mp)
2093 {
2094   vat_main_t *vam = &vat_main;
2095   api_main_t *am = &api_main;
2096   i32 retval = ntohl (mp->retval);
2097   u8 *pvt_copy, *reply;
2098   void *oldheap;
2099   vlib_node_t *node;
2100   int i;
2101
2102   if (vam->async_mode)
2103     {
2104       vam->async_errors += (retval < 0);
2105     }
2106   else
2107     {
2108       vam->retval = retval;
2109       vam->result_ready = 1;
2110     }
2111
2112   /* "Should never happen..." */
2113   if (retval != 0)
2114     return;
2115
2116   reply = (u8 *) (mp->reply_in_shmem);
2117   pvt_copy = vec_dup (reply);
2118
2119   /* Toss the shared-memory original... */
2120   pthread_mutex_lock (&am->vlib_rp->mutex);
2121   oldheap = svm_push_data_heap (am->vlib_rp);
2122
2123   vec_free (reply);
2124
2125   svm_pop_heap (oldheap);
2126   pthread_mutex_unlock (&am->vlib_rp->mutex);
2127
2128   if (vam->graph_nodes)
2129     {
2130       hash_free (vam->graph_node_index_by_name);
2131
2132       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2133         {
2134           node = vam->graph_nodes[i];
2135           vec_free (node->name);
2136           vec_free (node->next_nodes);
2137           vec_free (node);
2138         }
2139       vec_free (vam->graph_nodes);
2140     }
2141
2142   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2143   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2144   vec_free (pvt_copy);
2145
2146   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2147     {
2148       node = vam->graph_nodes[i];
2149       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2150     }
2151 }
2152
2153 static void vl_api_get_node_graph_reply_t_handler_json
2154   (vl_api_get_node_graph_reply_t * mp)
2155 {
2156   vat_main_t *vam = &vat_main;
2157   api_main_t *am = &api_main;
2158   void *oldheap;
2159   vat_json_node_t node;
2160   u8 *reply;
2161
2162   /* $$$$ make this real? */
2163   vat_json_init_object (&node);
2164   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2165   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2166
2167   reply = (u8 *) (mp->reply_in_shmem);
2168
2169   /* Toss the shared-memory original... */
2170   pthread_mutex_lock (&am->vlib_rp->mutex);
2171   oldheap = svm_push_data_heap (am->vlib_rp);
2172
2173   vec_free (reply);
2174
2175   svm_pop_heap (oldheap);
2176   pthread_mutex_unlock (&am->vlib_rp->mutex);
2177
2178   vat_json_print (vam->ofp, &node);
2179   vat_json_free (&node);
2180
2181   vam->retval = ntohl (mp->retval);
2182   vam->result_ready = 1;
2183 }
2184
2185 static void
2186 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2187 {
2188   vat_main_t *vam = &vat_main;
2189   u8 *s = 0;
2190
2191   if (mp->local)
2192     {
2193       s = format (s, "%=16d%=16d%=16d",
2194                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2195     }
2196   else
2197     {
2198       s = format (s, "%=16U%=16d%=16d",
2199                   mp->is_ipv6 ? format_ip6_address :
2200                   format_ip4_address,
2201                   mp->ip_address, mp->priority, mp->weight);
2202     }
2203
2204   print (vam->ofp, "%v", s);
2205   vec_free (s);
2206 }
2207
2208 static void
2209 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2210                                             mp)
2211 {
2212   vat_main_t *vam = &vat_main;
2213   vat_json_node_t *node = NULL;
2214   struct in6_addr ip6;
2215   struct in_addr ip4;
2216
2217   if (VAT_JSON_ARRAY != vam->json_tree.type)
2218     {
2219       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2220       vat_json_init_array (&vam->json_tree);
2221     }
2222   node = vat_json_array_add (&vam->json_tree);
2223   vat_json_init_object (node);
2224
2225   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2226   vat_json_object_add_uint (node, "priority", mp->priority);
2227   vat_json_object_add_uint (node, "weight", mp->weight);
2228
2229   if (mp->local)
2230     vat_json_object_add_uint (node, "sw_if_index",
2231                               clib_net_to_host_u32 (mp->sw_if_index));
2232   else
2233     {
2234       if (mp->is_ipv6)
2235         {
2236           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2237           vat_json_object_add_ip6 (node, "address", ip6);
2238         }
2239       else
2240         {
2241           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2242           vat_json_object_add_ip4 (node, "address", ip4);
2243         }
2244     }
2245 }
2246
2247 static void
2248 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2249                                            mp)
2250 {
2251   vat_main_t *vam = &vat_main;
2252   u8 *ls_name = 0;
2253
2254   ls_name = format (0, "%s", mp->ls_name);
2255
2256   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2257          ls_name);
2258   vec_free (ls_name);
2259 }
2260
2261 static void
2262   vl_api_lisp_locator_set_details_t_handler_json
2263   (vl_api_lisp_locator_set_details_t * mp)
2264 {
2265   vat_main_t *vam = &vat_main;
2266   vat_json_node_t *node = 0;
2267   u8 *ls_name = 0;
2268
2269   ls_name = format (0, "%s", mp->ls_name);
2270   vec_add1 (ls_name, 0);
2271
2272   if (VAT_JSON_ARRAY != vam->json_tree.type)
2273     {
2274       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2275       vat_json_init_array (&vam->json_tree);
2276     }
2277   node = vat_json_array_add (&vam->json_tree);
2278
2279   vat_json_init_object (node);
2280   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2281   vat_json_object_add_uint (node, "ls_index",
2282                             clib_net_to_host_u32 (mp->ls_index));
2283   vec_free (ls_name);
2284 }
2285
2286 static u8 *
2287 format_lisp_flat_eid (u8 * s, va_list * args)
2288 {
2289   u32 type = va_arg (*args, u32);
2290   u8 *eid = va_arg (*args, u8 *);
2291   u32 eid_len = va_arg (*args, u32);
2292
2293   switch (type)
2294     {
2295     case 0:
2296       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2297     case 1:
2298       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2299     case 2:
2300       return format (s, "%U", format_ethernet_address, eid);
2301     }
2302   return 0;
2303 }
2304
2305 static u8 *
2306 format_lisp_eid_vat (u8 * s, va_list * args)
2307 {
2308   u32 type = va_arg (*args, u32);
2309   u8 *eid = va_arg (*args, u8 *);
2310   u32 eid_len = va_arg (*args, u32);
2311   u8 *seid = va_arg (*args, u8 *);
2312   u32 seid_len = va_arg (*args, u32);
2313   u32 is_src_dst = va_arg (*args, u32);
2314
2315   if (is_src_dst)
2316     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2317
2318   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2319
2320   return s;
2321 }
2322
2323 static void
2324 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2325 {
2326   vat_main_t *vam = &vat_main;
2327   u8 *s = 0, *eid = 0;
2328
2329   if (~0 == mp->locator_set_index)
2330     s = format (0, "action: %d", mp->action);
2331   else
2332     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2333
2334   eid = format (0, "%U", format_lisp_eid_vat,
2335                 mp->eid_type,
2336                 mp->eid,
2337                 mp->eid_prefix_len,
2338                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2339   vec_add1 (eid, 0);
2340
2341   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2342          clib_net_to_host_u32 (mp->vni),
2343          eid,
2344          mp->is_local ? "local" : "remote",
2345          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2346          clib_net_to_host_u16 (mp->key_id), mp->key);
2347
2348   vec_free (s);
2349   vec_free (eid);
2350 }
2351
2352 static void
2353 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2354                                               * mp)
2355 {
2356   vat_main_t *vam = &vat_main;
2357   vat_json_node_t *node = 0;
2358   u8 *eid = 0;
2359
2360   if (VAT_JSON_ARRAY != vam->json_tree.type)
2361     {
2362       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2363       vat_json_init_array (&vam->json_tree);
2364     }
2365   node = vat_json_array_add (&vam->json_tree);
2366
2367   vat_json_init_object (node);
2368   if (~0 == mp->locator_set_index)
2369     vat_json_object_add_uint (node, "action", mp->action);
2370   else
2371     vat_json_object_add_uint (node, "locator_set_index",
2372                               clib_net_to_host_u32 (mp->locator_set_index));
2373
2374   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2375   eid = format (0, "%U", format_lisp_eid_vat,
2376                 mp->eid_type,
2377                 mp->eid,
2378                 mp->eid_prefix_len,
2379                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2380   vec_add1 (eid, 0);
2381   vat_json_object_add_string_copy (node, "eid", eid);
2382   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2383   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2384   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2385
2386   if (mp->key_id)
2387     {
2388       vat_json_object_add_uint (node, "key_id",
2389                                 clib_net_to_host_u16 (mp->key_id));
2390       vat_json_object_add_string_copy (node, "key", mp->key);
2391     }
2392   vec_free (eid);
2393 }
2394
2395 static void
2396   vl_api_lisp_eid_table_map_details_t_handler
2397   (vl_api_lisp_eid_table_map_details_t * mp)
2398 {
2399   vat_main_t *vam = &vat_main;
2400
2401   u8 *line = format (0, "%=10d%=10d",
2402                      clib_net_to_host_u32 (mp->vni),
2403                      clib_net_to_host_u32 (mp->dp_table));
2404   print (vam->ofp, "%v", line);
2405   vec_free (line);
2406 }
2407
2408 static void
2409   vl_api_lisp_eid_table_map_details_t_handler_json
2410   (vl_api_lisp_eid_table_map_details_t * mp)
2411 {
2412   vat_main_t *vam = &vat_main;
2413   vat_json_node_t *node = NULL;
2414
2415   if (VAT_JSON_ARRAY != vam->json_tree.type)
2416     {
2417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2418       vat_json_init_array (&vam->json_tree);
2419     }
2420   node = vat_json_array_add (&vam->json_tree);
2421   vat_json_init_object (node);
2422   vat_json_object_add_uint (node, "dp_table",
2423                             clib_net_to_host_u32 (mp->dp_table));
2424   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2425 }
2426
2427 static void
2428   vl_api_lisp_eid_table_vni_details_t_handler
2429   (vl_api_lisp_eid_table_vni_details_t * mp)
2430 {
2431   vat_main_t *vam = &vat_main;
2432
2433   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2434   print (vam->ofp, "%v", line);
2435   vec_free (line);
2436 }
2437
2438 static void
2439   vl_api_lisp_eid_table_vni_details_t_handler_json
2440   (vl_api_lisp_eid_table_vni_details_t * mp)
2441 {
2442   vat_main_t *vam = &vat_main;
2443   vat_json_node_t *node = NULL;
2444
2445   if (VAT_JSON_ARRAY != vam->json_tree.type)
2446     {
2447       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2448       vat_json_init_array (&vam->json_tree);
2449     }
2450   node = vat_json_array_add (&vam->json_tree);
2451   vat_json_init_object (node);
2452   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2453 }
2454
2455 static u8 *
2456 format_decap_next (u8 * s, va_list * args)
2457 {
2458   u32 next_index = va_arg (*args, u32);
2459
2460   switch (next_index)
2461     {
2462     case LISP_GPE_INPUT_NEXT_DROP:
2463       return format (s, "drop");
2464     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2465       return format (s, "ip4");
2466     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2467       return format (s, "ip6");
2468     default:
2469       return format (s, "unknown %d", next_index);
2470     }
2471   return s;
2472 }
2473
2474 static void
2475 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2476                                           mp)
2477 {
2478   vat_main_t *vam = &vat_main;
2479   u8 *iid_str;
2480   u8 *flag_str = NULL;
2481
2482   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2483
2484 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2485   foreach_lisp_gpe_flag_bit;
2486 #undef _
2487
2488   print (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2489          "%=16d%=16d%=16sd=16d%=16s%=16s",
2490          mp->tunnels,
2491          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2492          mp->source_ip,
2493          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2494          mp->destination_ip,
2495          ntohl (mp->encap_fib_id),
2496          ntohl (mp->decap_fib_id),
2497          format_decap_next, ntohl (mp->dcap_next),
2498          mp->ver_res >> 6,
2499          flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2500
2501   vec_free (iid_str);
2502 }
2503
2504 static void
2505   vl_api_lisp_gpe_tunnel_details_t_handler_json
2506   (vl_api_lisp_gpe_tunnel_details_t * mp)
2507 {
2508   vat_main_t *vam = &vat_main;
2509   vat_json_node_t *node = NULL;
2510   struct in6_addr ip6;
2511   struct in_addr ip4;
2512   u8 *next_decap_str;
2513
2514   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2515
2516   if (VAT_JSON_ARRAY != vam->json_tree.type)
2517     {
2518       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2519       vat_json_init_array (&vam->json_tree);
2520     }
2521   node = vat_json_array_add (&vam->json_tree);
2522
2523   vat_json_init_object (node);
2524   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2525   if (mp->is_ipv6)
2526     {
2527       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2528       vat_json_object_add_ip6 (node, "source address", ip6);
2529       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2530       vat_json_object_add_ip6 (node, "destination address", ip6);
2531     }
2532   else
2533     {
2534       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2535       vat_json_object_add_ip4 (node, "source address", ip4);
2536       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2537       vat_json_object_add_ip4 (node, "destination address", ip4);
2538     }
2539   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2540   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2541   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2542   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2543   vat_json_object_add_uint (node, "flags", mp->flags);
2544   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2545   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2546   vat_json_object_add_uint (node, "res", mp->res);
2547   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2548
2549   vec_free (next_decap_str);
2550 }
2551
2552 static void
2553   vl_api_show_lisp_map_register_state_reply_t_handler
2554   (vl_api_show_lisp_map_register_state_reply_t * mp)
2555 {
2556   vat_main_t *vam = &vat_main;
2557   int retval = clib_net_to_host_u32 (mp->retval);
2558
2559   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2560
2561   vam->retval = retval;
2562   vam->result_ready = 1;
2563 }
2564
2565 static void
2566   vl_api_show_lisp_map_register_state_reply_t_handler_json
2567   (vl_api_show_lisp_map_register_state_reply_t * mp)
2568 {
2569   vat_main_t *vam = &vat_main;
2570   vat_json_node_t _node, *node = &_node;
2571   int retval = clib_net_to_host_u32 (mp->retval);
2572
2573   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2574
2575   vat_json_init_object (node);
2576   vat_json_object_add_string_copy (node, "state", s);
2577
2578   vat_json_print (vam->ofp, node);
2579   vat_json_free (node);
2580
2581   vam->retval = retval;
2582   vam->result_ready = 1;
2583   vec_free (s);
2584 }
2585
2586 static void
2587   vl_api_show_lisp_rloc_probe_state_reply_t_handler
2588   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2589 {
2590   vat_main_t *vam = &vat_main;
2591   int retval = clib_net_to_host_u32 (mp->retval);
2592
2593   if (retval)
2594     goto end;
2595
2596   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2597 end:
2598   vam->retval = retval;
2599   vam->result_ready = 1;
2600 }
2601
2602 static void
2603   vl_api_show_lisp_rloc_probe_state_reply_t_handler_json
2604   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2605 {
2606   vat_main_t *vam = &vat_main;
2607   vat_json_node_t _node, *node = &_node;
2608   int retval = clib_net_to_host_u32 (mp->retval);
2609
2610   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2611   vat_json_init_object (node);
2612   vat_json_object_add_string_copy (node, "state", s);
2613
2614   vat_json_print (vam->ofp, node);
2615   vat_json_free (node);
2616
2617   vam->retval = retval;
2618   vam->result_ready = 1;
2619   vec_free (s);
2620 }
2621
2622 static void
2623   vl_api_lisp_adjacencies_get_reply_t_handler
2624   (vl_api_lisp_adjacencies_get_reply_t * mp)
2625 {
2626   vat_main_t *vam = &vat_main;
2627   u32 i, n;
2628   int retval = clib_net_to_host_u32 (mp->retval);
2629   vl_api_lisp_adjacency_t *a;
2630
2631   if (retval)
2632     goto end;
2633
2634   n = clib_net_to_host_u32 (mp->count);
2635
2636   for (i = 0; i < n; i++)
2637     {
2638       a = &mp->adjacencies[i];
2639       print (vam->ofp, "%U %40U",
2640              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2641              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2642     }
2643
2644 end:
2645   vam->retval = retval;
2646   vam->result_ready = 1;
2647 }
2648
2649 static void
2650   vl_api_lisp_adjacencies_get_reply_t_handler_json
2651   (vl_api_lisp_adjacencies_get_reply_t * mp)
2652 {
2653   u8 *s = 0;
2654   vat_main_t *vam = &vat_main;
2655   vat_json_node_t *e = 0, root;
2656   u32 i, n;
2657   int retval = clib_net_to_host_u32 (mp->retval);
2658   vl_api_lisp_adjacency_t *a;
2659
2660   if (retval)
2661     goto end;
2662
2663   n = clib_net_to_host_u32 (mp->count);
2664   vat_json_init_array (&root);
2665
2666   for (i = 0; i < n; i++)
2667     {
2668       e = vat_json_array_add (&root);
2669       a = &mp->adjacencies[i];
2670
2671       vat_json_init_object (e);
2672       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2673                   a->leid_prefix_len);
2674       vec_add1 (s, 0);
2675       vat_json_object_add_string_copy (e, "leid", s);
2676       vec_free (s);
2677
2678       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2679                   a->reid_prefix_len);
2680       vec_add1 (s, 0);
2681       vat_json_object_add_string_copy (e, "reid", s);
2682       vec_free (s);
2683     }
2684
2685   vat_json_print (vam->ofp, &root);
2686   vat_json_free (&root);
2687
2688 end:
2689   vam->retval = retval;
2690   vam->result_ready = 1;
2691 }
2692
2693 static void
2694 vl_api_lisp_map_server_details_t_handler (vl_api_lisp_map_server_details_t
2695                                           * mp)
2696 {
2697   vat_main_t *vam = &vat_main;
2698
2699   print (vam->ofp, "%=20U",
2700          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2701          mp->ip_address);
2702 }
2703
2704 static void
2705   vl_api_lisp_map_server_details_t_handler_json
2706   (vl_api_lisp_map_server_details_t * mp)
2707 {
2708   vat_main_t *vam = &vat_main;
2709   vat_json_node_t *node = NULL;
2710   struct in6_addr ip6;
2711   struct in_addr ip4;
2712
2713   if (VAT_JSON_ARRAY != vam->json_tree.type)
2714     {
2715       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2716       vat_json_init_array (&vam->json_tree);
2717     }
2718   node = vat_json_array_add (&vam->json_tree);
2719
2720   vat_json_init_object (node);
2721   if (mp->is_ipv6)
2722     {
2723       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2724       vat_json_object_add_ip6 (node, "map-server", ip6);
2725     }
2726   else
2727     {
2728       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2729       vat_json_object_add_ip4 (node, "map-server", ip4);
2730     }
2731 }
2732
2733 static void
2734 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2735                                             * mp)
2736 {
2737   vat_main_t *vam = &vat_main;
2738
2739   print (vam->ofp, "%=20U",
2740          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2741          mp->ip_address);
2742 }
2743
2744 static void
2745   vl_api_lisp_map_resolver_details_t_handler_json
2746   (vl_api_lisp_map_resolver_details_t * mp)
2747 {
2748   vat_main_t *vam = &vat_main;
2749   vat_json_node_t *node = NULL;
2750   struct in6_addr ip6;
2751   struct in_addr ip4;
2752
2753   if (VAT_JSON_ARRAY != vam->json_tree.type)
2754     {
2755       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2756       vat_json_init_array (&vam->json_tree);
2757     }
2758   node = vat_json_array_add (&vam->json_tree);
2759
2760   vat_json_init_object (node);
2761   if (mp->is_ipv6)
2762     {
2763       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2764       vat_json_object_add_ip6 (node, "map resolver", ip6);
2765     }
2766   else
2767     {
2768       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2769       vat_json_object_add_ip4 (node, "map resolver", ip4);
2770     }
2771 }
2772
2773 static void
2774   vl_api_show_lisp_status_reply_t_handler
2775   (vl_api_show_lisp_status_reply_t * mp)
2776 {
2777   vat_main_t *vam = &vat_main;
2778   i32 retval = ntohl (mp->retval);
2779
2780   if (0 <= retval)
2781     {
2782       print (vam->ofp, "feature: %s\ngpe: %s",
2783              mp->feature_status ? "enabled" : "disabled",
2784              mp->gpe_status ? "enabled" : "disabled");
2785     }
2786
2787   vam->retval = retval;
2788   vam->result_ready = 1;
2789 }
2790
2791 static void
2792   vl_api_show_lisp_status_reply_t_handler_json
2793   (vl_api_show_lisp_status_reply_t * mp)
2794 {
2795   vat_main_t *vam = &vat_main;
2796   vat_json_node_t node;
2797   u8 *gpe_status = NULL;
2798   u8 *feature_status = NULL;
2799
2800   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2801   feature_status = format (0, "%s",
2802                            mp->feature_status ? "enabled" : "disabled");
2803   vec_add1 (gpe_status, 0);
2804   vec_add1 (feature_status, 0);
2805
2806   vat_json_init_object (&node);
2807   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2808   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2809
2810   vec_free (gpe_status);
2811   vec_free (feature_status);
2812
2813   vat_json_print (vam->ofp, &node);
2814   vat_json_free (&node);
2815
2816   vam->retval = ntohl (mp->retval);
2817   vam->result_ready = 1;
2818 }
2819
2820 static void
2821   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2822   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2823 {
2824   vat_main_t *vam = &vat_main;
2825   i32 retval = ntohl (mp->retval);
2826
2827   if (retval >= 0)
2828     {
2829       print (vam->ofp, "%=20s", mp->locator_set_name);
2830     }
2831
2832   vam->retval = retval;
2833   vam->result_ready = 1;
2834 }
2835
2836 static void
2837   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2838   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2839 {
2840   vat_main_t *vam = &vat_main;
2841   vat_json_node_t *node = NULL;
2842
2843   if (VAT_JSON_ARRAY != vam->json_tree.type)
2844     {
2845       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2846       vat_json_init_array (&vam->json_tree);
2847     }
2848   node = vat_json_array_add (&vam->json_tree);
2849
2850   vat_json_init_object (node);
2851   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2852
2853   vat_json_print (vam->ofp, node);
2854   vat_json_free (node);
2855
2856   vam->retval = ntohl (mp->retval);
2857   vam->result_ready = 1;
2858 }
2859
2860 static u8 *
2861 format_lisp_map_request_mode (u8 * s, va_list * args)
2862 {
2863   u32 mode = va_arg (*args, u32);
2864
2865   switch (mode)
2866     {
2867     case 0:
2868       return format (0, "dst-only");
2869     case 1:
2870       return format (0, "src-dst");
2871     }
2872   return 0;
2873 }
2874
2875 static void
2876   vl_api_show_lisp_map_request_mode_reply_t_handler
2877   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2878 {
2879   vat_main_t *vam = &vat_main;
2880   i32 retval = ntohl (mp->retval);
2881
2882   if (0 <= retval)
2883     {
2884       u32 mode = mp->mode;
2885       print (vam->ofp, "map_request_mode: %U",
2886              format_lisp_map_request_mode, mode);
2887     }
2888
2889   vam->retval = retval;
2890   vam->result_ready = 1;
2891 }
2892
2893 static void
2894   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2895   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2896 {
2897   vat_main_t *vam = &vat_main;
2898   vat_json_node_t node;
2899   u8 *s = 0;
2900   u32 mode;
2901
2902   mode = mp->mode;
2903   s = format (0, "%U", format_lisp_map_request_mode, mode);
2904   vec_add1 (s, 0);
2905
2906   vat_json_init_object (&node);
2907   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2908   vat_json_print (vam->ofp, &node);
2909   vat_json_free (&node);
2910
2911   vec_free (s);
2912   vam->retval = ntohl (mp->retval);
2913   vam->result_ready = 1;
2914 }
2915
2916 static void
2917 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2918 {
2919   vat_main_t *vam = &vat_main;
2920   i32 retval = ntohl (mp->retval);
2921
2922   if (0 <= retval)
2923     {
2924       print (vam->ofp, "%-20s%-16s",
2925              mp->status ? "enabled" : "disabled",
2926              mp->status ? (char *) mp->locator_set_name : "");
2927     }
2928
2929   vam->retval = retval;
2930   vam->result_ready = 1;
2931 }
2932
2933 static void
2934 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2935                                             mp)
2936 {
2937   vat_main_t *vam = &vat_main;
2938   vat_json_node_t node;
2939   u8 *status = 0;
2940
2941   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2942   vec_add1 (status, 0);
2943
2944   vat_json_init_object (&node);
2945   vat_json_object_add_string_copy (&node, "status", status);
2946   if (mp->status)
2947     {
2948       vat_json_object_add_string_copy (&node, "locator_set",
2949                                        mp->locator_set_name);
2950     }
2951
2952   vec_free (status);
2953
2954   vat_json_print (vam->ofp, &node);
2955   vat_json_free (&node);
2956
2957   vam->retval = ntohl (mp->retval);
2958   vam->result_ready = 1;
2959 }
2960
2961 static u8 *
2962 format_policer_type (u8 * s, va_list * va)
2963 {
2964   u32 i = va_arg (*va, u32);
2965
2966   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2967     s = format (s, "1r2c");
2968   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2969     s = format (s, "1r3c");
2970   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2971     s = format (s, "2r3c-2698");
2972   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2973     s = format (s, "2r3c-4115");
2974   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2975     s = format (s, "2r3c-mef5cf1");
2976   else
2977     s = format (s, "ILLEGAL");
2978   return s;
2979 }
2980
2981 static u8 *
2982 format_policer_rate_type (u8 * s, va_list * va)
2983 {
2984   u32 i = va_arg (*va, u32);
2985
2986   if (i == SSE2_QOS_RATE_KBPS)
2987     s = format (s, "kbps");
2988   else if (i == SSE2_QOS_RATE_PPS)
2989     s = format (s, "pps");
2990   else
2991     s = format (s, "ILLEGAL");
2992   return s;
2993 }
2994
2995 static u8 *
2996 format_policer_round_type (u8 * s, va_list * va)
2997 {
2998   u32 i = va_arg (*va, u32);
2999
3000   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3001     s = format (s, "closest");
3002   else if (i == SSE2_QOS_ROUND_TO_UP)
3003     s = format (s, "up");
3004   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3005     s = format (s, "down");
3006   else
3007     s = format (s, "ILLEGAL");
3008   return s;
3009 }
3010
3011 static u8 *
3012 format_policer_action_type (u8 * s, va_list * va)
3013 {
3014   u32 i = va_arg (*va, u32);
3015
3016   if (i == SSE2_QOS_ACTION_DROP)
3017     s = format (s, "drop");
3018   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3019     s = format (s, "transmit");
3020   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3021     s = format (s, "mark-and-transmit");
3022   else
3023     s = format (s, "ILLEGAL");
3024   return s;
3025 }
3026
3027 static u8 *
3028 format_dscp (u8 * s, va_list * va)
3029 {
3030   u32 i = va_arg (*va, u32);
3031   char *t = 0;
3032
3033   switch (i)
3034     {
3035 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3036       foreach_vnet_dscp
3037 #undef _
3038     default:
3039       return format (s, "ILLEGAL");
3040     }
3041   s = format (s, "%s", t);
3042   return s;
3043 }
3044
3045 static void
3046 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3047 {
3048   vat_main_t *vam = &vat_main;
3049   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3050
3051   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3052     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3053   else
3054     conform_dscp_str = format (0, "");
3055
3056   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3057     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3058   else
3059     exceed_dscp_str = format (0, "");
3060
3061   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3062     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3063   else
3064     violate_dscp_str = format (0, "");
3065
3066   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3067          "rate type %U, round type %U, %s rate, %s color-aware, "
3068          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3069          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3070          "conform action %U%s, exceed action %U%s, violate action %U%s",
3071          mp->name,
3072          format_policer_type, mp->type,
3073          ntohl (mp->cir),
3074          ntohl (mp->eir),
3075          clib_net_to_host_u64 (mp->cb),
3076          clib_net_to_host_u64 (mp->eb),
3077          format_policer_rate_type, mp->rate_type,
3078          format_policer_round_type, mp->round_type,
3079          mp->single_rate ? "single" : "dual",
3080          mp->color_aware ? "is" : "not",
3081          ntohl (mp->cir_tokens_per_period),
3082          ntohl (mp->pir_tokens_per_period),
3083          ntohl (mp->scale),
3084          ntohl (mp->current_limit),
3085          ntohl (mp->current_bucket),
3086          ntohl (mp->extended_limit),
3087          ntohl (mp->extended_bucket),
3088          clib_net_to_host_u64 (mp->last_update_time),
3089          format_policer_action_type, mp->conform_action_type,
3090          conform_dscp_str,
3091          format_policer_action_type, mp->exceed_action_type,
3092          exceed_dscp_str,
3093          format_policer_action_type, mp->violate_action_type,
3094          violate_dscp_str);
3095
3096   vec_free (conform_dscp_str);
3097   vec_free (exceed_dscp_str);
3098   vec_free (violate_dscp_str);
3099 }
3100
3101 static void vl_api_policer_details_t_handler_json
3102   (vl_api_policer_details_t * mp)
3103 {
3104   vat_main_t *vam = &vat_main;
3105   vat_json_node_t *node;
3106   u8 *rate_type_str, *round_type_str, *type_str;
3107   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3108
3109   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3110   round_type_str =
3111     format (0, "%U", format_policer_round_type, mp->round_type);
3112   type_str = format (0, "%U", format_policer_type, mp->type);
3113   conform_action_str = format (0, "%U", format_policer_action_type,
3114                                mp->conform_action_type);
3115   exceed_action_str = format (0, "%U", format_policer_action_type,
3116                               mp->exceed_action_type);
3117   violate_action_str = format (0, "%U", format_policer_action_type,
3118                                mp->violate_action_type);
3119
3120   if (VAT_JSON_ARRAY != vam->json_tree.type)
3121     {
3122       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3123       vat_json_init_array (&vam->json_tree);
3124     }
3125   node = vat_json_array_add (&vam->json_tree);
3126
3127   vat_json_init_object (node);
3128   vat_json_object_add_string_copy (node, "name", mp->name);
3129   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3130   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3131   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3132   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3133   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3134   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3135   vat_json_object_add_string_copy (node, "type", type_str);
3136   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3137   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3138   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3139   vat_json_object_add_uint (node, "cir_tokens_per_period",
3140                             ntohl (mp->cir_tokens_per_period));
3141   vat_json_object_add_uint (node, "eir_tokens_per_period",
3142                             ntohl (mp->pir_tokens_per_period));
3143   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3144   vat_json_object_add_uint (node, "current_bucket",
3145                             ntohl (mp->current_bucket));
3146   vat_json_object_add_uint (node, "extended_limit",
3147                             ntohl (mp->extended_limit));
3148   vat_json_object_add_uint (node, "extended_bucket",
3149                             ntohl (mp->extended_bucket));
3150   vat_json_object_add_uint (node, "last_update_time",
3151                             ntohl (mp->last_update_time));
3152   vat_json_object_add_string_copy (node, "conform_action",
3153                                    conform_action_str);
3154   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3155     {
3156       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3157       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3158       vec_free (dscp_str);
3159     }
3160   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3161   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3162     {
3163       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3164       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3165       vec_free (dscp_str);
3166     }
3167   vat_json_object_add_string_copy (node, "violate_action",
3168                                    violate_action_str);
3169   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3170     {
3171       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3172       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3173       vec_free (dscp_str);
3174     }
3175
3176   vec_free (rate_type_str);
3177   vec_free (round_type_str);
3178   vec_free (type_str);
3179   vec_free (conform_action_str);
3180   vec_free (exceed_action_str);
3181   vec_free (violate_action_str);
3182 }
3183
3184 static void
3185 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3186                                            mp)
3187 {
3188   vat_main_t *vam = &vat_main;
3189   int i, count = ntohl (mp->count);
3190
3191   if (count > 0)
3192     print (vam->ofp, "classify table ids (%d) : ", count);
3193   for (i = 0; i < count; i++)
3194     {
3195       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3196       print (vam->ofp, (i < count - 1) ? "," : "");
3197     }
3198   vam->retval = ntohl (mp->retval);
3199   vam->result_ready = 1;
3200 }
3201
3202 static void
3203   vl_api_classify_table_ids_reply_t_handler_json
3204   (vl_api_classify_table_ids_reply_t * mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207   int i, count = ntohl (mp->count);
3208
3209   if (count > 0)
3210     {
3211       vat_json_node_t node;
3212
3213       vat_json_init_object (&node);
3214       for (i = 0; i < count; i++)
3215         {
3216           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3217         }
3218       vat_json_print (vam->ofp, &node);
3219       vat_json_free (&node);
3220     }
3221   vam->retval = ntohl (mp->retval);
3222   vam->result_ready = 1;
3223 }
3224
3225 static void
3226   vl_api_classify_table_by_interface_reply_t_handler
3227   (vl_api_classify_table_by_interface_reply_t * mp)
3228 {
3229   vat_main_t *vam = &vat_main;
3230   u32 table_id;
3231
3232   table_id = ntohl (mp->l2_table_id);
3233   if (table_id != ~0)
3234     print (vam->ofp, "l2 table id : %d", table_id);
3235   else
3236     print (vam->ofp, "l2 table id : No input ACL tables configured");
3237   table_id = ntohl (mp->ip4_table_id);
3238   if (table_id != ~0)
3239     print (vam->ofp, "ip4 table id : %d", table_id);
3240   else
3241     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3242   table_id = ntohl (mp->ip6_table_id);
3243   if (table_id != ~0)
3244     print (vam->ofp, "ip6 table id : %d", table_id);
3245   else
3246     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3247   vam->retval = ntohl (mp->retval);
3248   vam->result_ready = 1;
3249 }
3250
3251 static void
3252   vl_api_classify_table_by_interface_reply_t_handler_json
3253   (vl_api_classify_table_by_interface_reply_t * mp)
3254 {
3255   vat_main_t *vam = &vat_main;
3256   vat_json_node_t node;
3257
3258   vat_json_init_object (&node);
3259
3260   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3261   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3262   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3263
3264   vat_json_print (vam->ofp, &node);
3265   vat_json_free (&node);
3266
3267   vam->retval = ntohl (mp->retval);
3268   vam->result_ready = 1;
3269 }
3270
3271 static void vl_api_policer_add_del_reply_t_handler
3272   (vl_api_policer_add_del_reply_t * mp)
3273 {
3274   vat_main_t *vam = &vat_main;
3275   i32 retval = ntohl (mp->retval);
3276   if (vam->async_mode)
3277     {
3278       vam->async_errors += (retval < 0);
3279     }
3280   else
3281     {
3282       vam->retval = retval;
3283       vam->result_ready = 1;
3284       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3285         /*
3286          * Note: this is just barely thread-safe, depends on
3287          * the main thread spinning waiting for an answer...
3288          */
3289         errmsg ("policer index %d", ntohl (mp->policer_index));
3290     }
3291 }
3292
3293 static void vl_api_policer_add_del_reply_t_handler_json
3294   (vl_api_policer_add_del_reply_t * mp)
3295 {
3296   vat_main_t *vam = &vat_main;
3297   vat_json_node_t node;
3298
3299   vat_json_init_object (&node);
3300   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3301   vat_json_object_add_uint (&node, "policer_index",
3302                             ntohl (mp->policer_index));
3303
3304   vat_json_print (vam->ofp, &node);
3305   vat_json_free (&node);
3306
3307   vam->retval = ntohl (mp->retval);
3308   vam->result_ready = 1;
3309 }
3310
3311 /* Format hex dump. */
3312 u8 *
3313 format_hex_bytes (u8 * s, va_list * va)
3314 {
3315   u8 *bytes = va_arg (*va, u8 *);
3316   int n_bytes = va_arg (*va, int);
3317   uword i;
3318
3319   /* Print short or long form depending on byte count. */
3320   uword short_form = n_bytes <= 32;
3321   uword indent = format_get_indent (s);
3322
3323   if (n_bytes == 0)
3324     return s;
3325
3326   for (i = 0; i < n_bytes; i++)
3327     {
3328       if (!short_form && (i % 32) == 0)
3329         s = format (s, "%08x: ", i);
3330       s = format (s, "%02x", bytes[i]);
3331       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3332         s = format (s, "\n%U", format_white_space, indent);
3333     }
3334
3335   return s;
3336 }
3337
3338 static void
3339 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3340                                             * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   i32 retval = ntohl (mp->retval);
3344   if (retval == 0)
3345     {
3346       print (vam->ofp, "classify table info :");
3347       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3348              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3349              ntohl (mp->miss_next_index));
3350       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3351              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3352              ntohl (mp->match_n_vectors));
3353       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3354              ntohl (mp->mask_length));
3355     }
3356   vam->retval = retval;
3357   vam->result_ready = 1;
3358 }
3359
3360 static void
3361   vl_api_classify_table_info_reply_t_handler_json
3362   (vl_api_classify_table_info_reply_t * mp)
3363 {
3364   vat_main_t *vam = &vat_main;
3365   vat_json_node_t node;
3366
3367   i32 retval = ntohl (mp->retval);
3368   if (retval == 0)
3369     {
3370       vat_json_init_object (&node);
3371
3372       vat_json_object_add_int (&node, "sessions",
3373                                ntohl (mp->active_sessions));
3374       vat_json_object_add_int (&node, "nexttbl",
3375                                ntohl (mp->next_table_index));
3376       vat_json_object_add_int (&node, "nextnode",
3377                                ntohl (mp->miss_next_index));
3378       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3379       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3380       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3381       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3382                       ntohl (mp->mask_length), 0);
3383       vat_json_object_add_string_copy (&node, "mask", s);
3384
3385       vat_json_print (vam->ofp, &node);
3386       vat_json_free (&node);
3387     }
3388   vam->retval = ntohl (mp->retval);
3389   vam->result_ready = 1;
3390 }
3391
3392 static void
3393 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3394                                            mp)
3395 {
3396   vat_main_t *vam = &vat_main;
3397
3398   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3399          ntohl (mp->hit_next_index), ntohl (mp->advance),
3400          ntohl (mp->opaque_index));
3401   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3402          ntohl (mp->match_length));
3403 }
3404
3405 static void
3406   vl_api_classify_session_details_t_handler_json
3407   (vl_api_classify_session_details_t * mp)
3408 {
3409   vat_main_t *vam = &vat_main;
3410   vat_json_node_t *node = NULL;
3411
3412   if (VAT_JSON_ARRAY != vam->json_tree.type)
3413     {
3414       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3415       vat_json_init_array (&vam->json_tree);
3416     }
3417   node = vat_json_array_add (&vam->json_tree);
3418
3419   vat_json_init_object (node);
3420   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3421   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3422   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3423   u8 *s =
3424     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3425             0);
3426   vat_json_object_add_string_copy (node, "match", s);
3427 }
3428
3429 static void vl_api_pg_create_interface_reply_t_handler
3430   (vl_api_pg_create_interface_reply_t * mp)
3431 {
3432   vat_main_t *vam = &vat_main;
3433
3434   vam->retval = ntohl (mp->retval);
3435   vam->result_ready = 1;
3436 }
3437
3438 static void vl_api_pg_create_interface_reply_t_handler_json
3439   (vl_api_pg_create_interface_reply_t * mp)
3440 {
3441   vat_main_t *vam = &vat_main;
3442   vat_json_node_t node;
3443
3444   i32 retval = ntohl (mp->retval);
3445   if (retval == 0)
3446     {
3447       vat_json_init_object (&node);
3448
3449       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3450
3451       vat_json_print (vam->ofp, &node);
3452       vat_json_free (&node);
3453     }
3454   vam->retval = ntohl (mp->retval);
3455   vam->result_ready = 1;
3456 }
3457
3458 static void vl_api_policer_classify_details_t_handler
3459   (vl_api_policer_classify_details_t * mp)
3460 {
3461   vat_main_t *vam = &vat_main;
3462
3463   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3464          ntohl (mp->table_index));
3465 }
3466
3467 static void vl_api_policer_classify_details_t_handler_json
3468   (vl_api_policer_classify_details_t * mp)
3469 {
3470   vat_main_t *vam = &vat_main;
3471   vat_json_node_t *node;
3472
3473   if (VAT_JSON_ARRAY != vam->json_tree.type)
3474     {
3475       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3476       vat_json_init_array (&vam->json_tree);
3477     }
3478   node = vat_json_array_add (&vam->json_tree);
3479
3480   vat_json_init_object (node);
3481   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3482   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3483 }
3484
3485 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3486   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3487 {
3488   vat_main_t *vam = &vat_main;
3489   i32 retval = ntohl (mp->retval);
3490   if (vam->async_mode)
3491     {
3492       vam->async_errors += (retval < 0);
3493     }
3494   else
3495     {
3496       vam->retval = retval;
3497       vam->sw_if_index = ntohl (mp->sw_if_index);
3498       vam->result_ready = 1;
3499     }
3500 }
3501
3502 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3503   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3504 {
3505   vat_main_t *vam = &vat_main;
3506   vat_json_node_t node;
3507
3508   vat_json_init_object (&node);
3509   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3510   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3511
3512   vat_json_print (vam->ofp, &node);
3513   vat_json_free (&node);
3514
3515   vam->retval = ntohl (mp->retval);
3516   vam->result_ready = 1;
3517 }
3518
3519 static void vl_api_flow_classify_details_t_handler
3520   (vl_api_flow_classify_details_t * mp)
3521 {
3522   vat_main_t *vam = &vat_main;
3523
3524   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3525          ntohl (mp->table_index));
3526 }
3527
3528 static void vl_api_flow_classify_details_t_handler_json
3529   (vl_api_flow_classify_details_t * mp)
3530 {
3531   vat_main_t *vam = &vat_main;
3532   vat_json_node_t *node;
3533
3534   if (VAT_JSON_ARRAY != vam->json_tree.type)
3535     {
3536       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3537       vat_json_init_array (&vam->json_tree);
3538     }
3539   node = vat_json_array_add (&vam->json_tree);
3540
3541   vat_json_init_object (node);
3542   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3543   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3544 }
3545
3546
3547
3548 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3549 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3550 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3551 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3552 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3553 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3554
3555 /*
3556  * Generate boilerplate reply handlers, which
3557  * dig the return value out of the xxx_reply_t API message,
3558  * stick it into vam->retval, and set vam->result_ready
3559  *
3560  * Could also do this by pointing N message decode slots at
3561  * a single function, but that could break in subtle ways.
3562  */
3563
3564 #define foreach_standard_reply_retval_handler           \
3565 _(sw_interface_set_flags_reply)                         \
3566 _(sw_interface_add_del_address_reply)                   \
3567 _(sw_interface_set_table_reply)                         \
3568 _(sw_interface_set_mpls_enable_reply)                   \
3569 _(sw_interface_set_vpath_reply)                         \
3570 _(sw_interface_set_vxlan_bypass_reply)                  \
3571 _(sw_interface_set_l2_bridge_reply)                     \
3572 _(bridge_domain_add_del_reply)                          \
3573 _(sw_interface_set_l2_xconnect_reply)                   \
3574 _(l2fib_add_del_reply)                                  \
3575 _(ip_add_del_route_reply)                               \
3576 _(mpls_route_add_del_reply)                             \
3577 _(mpls_ip_bind_unbind_reply)                            \
3578 _(proxy_arp_add_del_reply)                              \
3579 _(proxy_arp_intfc_enable_disable_reply)                 \
3580 _(sw_interface_set_unnumbered_reply)                    \
3581 _(ip_neighbor_add_del_reply)                            \
3582 _(reset_vrf_reply)                                      \
3583 _(oam_add_del_reply)                                    \
3584 _(reset_fib_reply)                                      \
3585 _(dhcp_proxy_config_reply)                              \
3586 _(dhcp_proxy_config_2_reply)                            \
3587 _(dhcp_proxy_set_vss_reply)                             \
3588 _(dhcp_client_config_reply)                             \
3589 _(set_ip_flow_hash_reply)                               \
3590 _(sw_interface_ip6_enable_disable_reply)                \
3591 _(sw_interface_ip6_set_link_local_address_reply)        \
3592 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3593 _(sw_interface_ip6nd_ra_config_reply)                   \
3594 _(set_arp_neighbor_limit_reply)                         \
3595 _(l2_patch_add_del_reply)                               \
3596 _(sr_tunnel_add_del_reply)                              \
3597 _(sr_policy_add_del_reply)                              \
3598 _(sr_multicast_map_add_del_reply)                       \
3599 _(classify_add_del_session_reply)                       \
3600 _(classify_set_interface_ip_table_reply)                \
3601 _(classify_set_interface_l2_tables_reply)               \
3602 _(l2tpv3_set_tunnel_cookies_reply)                      \
3603 _(l2tpv3_interface_enable_disable_reply)                \
3604 _(l2tpv3_set_lookup_key_reply)                          \
3605 _(l2_fib_clear_table_reply)                             \
3606 _(l2_interface_efp_filter_reply)                        \
3607 _(l2_interface_vlan_tag_rewrite_reply)                  \
3608 _(modify_vhost_user_if_reply)                           \
3609 _(delete_vhost_user_if_reply)                           \
3610 _(want_ip4_arp_events_reply)                            \
3611 _(want_ip6_nd_events_reply)                             \
3612 _(input_acl_set_interface_reply)                        \
3613 _(ipsec_spd_add_del_reply)                              \
3614 _(ipsec_interface_add_del_spd_reply)                    \
3615 _(ipsec_spd_add_del_entry_reply)                        \
3616 _(ipsec_sad_add_del_entry_reply)                        \
3617 _(ipsec_sa_set_key_reply)                               \
3618 _(ikev2_profile_add_del_reply)                          \
3619 _(ikev2_profile_set_auth_reply)                         \
3620 _(ikev2_profile_set_id_reply)                           \
3621 _(ikev2_profile_set_ts_reply)                           \
3622 _(ikev2_set_local_key_reply)                            \
3623 _(delete_loopback_reply)                                \
3624 _(bd_ip_mac_add_del_reply)                              \
3625 _(map_del_domain_reply)                                 \
3626 _(map_add_del_rule_reply)                               \
3627 _(want_interface_events_reply)                          \
3628 _(want_stats_reply)                                     \
3629 _(cop_interface_enable_disable_reply)                   \
3630 _(cop_whitelist_enable_disable_reply)                   \
3631 _(sw_interface_clear_stats_reply)                       \
3632 _(ioam_enable_reply)                              \
3633 _(ioam_disable_reply)                              \
3634 _(lisp_add_del_locator_reply)                           \
3635 _(lisp_add_del_local_eid_reply)                         \
3636 _(lisp_add_del_remote_mapping_reply)                    \
3637 _(lisp_add_del_adjacency_reply)                         \
3638 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3639 _(lisp_add_del_map_resolver_reply)                      \
3640 _(lisp_add_del_map_server_reply)                        \
3641 _(lisp_gpe_enable_disable_reply)                        \
3642 _(lisp_gpe_add_del_iface_reply)                         \
3643 _(lisp_enable_disable_reply)                            \
3644 _(lisp_rloc_probe_enable_disable_reply)                 \
3645 _(lisp_map_register_enable_disable_reply)               \
3646 _(lisp_pitr_set_locator_set_reply)                      \
3647 _(lisp_map_request_mode_reply)                          \
3648 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3649 _(lisp_eid_table_add_del_map_reply)                     \
3650 _(vxlan_gpe_add_del_tunnel_reply)                       \
3651 _(af_packet_delete_reply)                               \
3652 _(policer_classify_set_interface_reply)                 \
3653 _(netmap_create_reply)                                  \
3654 _(netmap_delete_reply)                                  \
3655 _(set_ipfix_exporter_reply)                             \
3656 _(set_ipfix_classify_stream_reply)                      \
3657 _(ipfix_classify_table_add_del_reply)                   \
3658 _(flow_classify_set_interface_reply)                    \
3659 _(sw_interface_span_enable_disable_reply)               \
3660 _(pg_capture_reply)                                     \
3661 _(pg_enable_disable_reply)                              \
3662 _(ip_source_and_port_range_check_add_del_reply)         \
3663 _(ip_source_and_port_range_check_interface_add_del_reply)\
3664 _(delete_subif_reply)                                   \
3665 _(l2_interface_pbb_tag_rewrite_reply)                   \
3666 _(punt_reply)                                           \
3667 _(feature_enable_disable_reply)                         \
3668 _(sw_interface_tag_add_del_reply)                       \
3669 _(sw_interface_set_mtu_reply)
3670
3671 #if DPDK > 0
3672 #define foreach_standard_dpdk_reply_retval_handler      \
3673 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3674 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3675 _(sw_interface_set_dpdk_hqos_tctbl_reply)
3676 #endif
3677
3678 #define _(n)                                    \
3679     static void vl_api_##n##_t_handler          \
3680     (vl_api_##n##_t * mp)                       \
3681     {                                           \
3682         vat_main_t * vam = &vat_main;           \
3683         i32 retval = ntohl(mp->retval);         \
3684         if (vam->async_mode) {                  \
3685             vam->async_errors += (retval < 0);  \
3686         } else {                                \
3687             vam->retval = retval;               \
3688             vam->result_ready = 1;              \
3689         }                                       \
3690     }
3691 foreach_standard_reply_retval_handler;
3692 #undef _
3693
3694 #define _(n)                                    \
3695     static void vl_api_##n##_t_handler_json     \
3696     (vl_api_##n##_t * mp)                       \
3697     {                                           \
3698         vat_main_t * vam = &vat_main;           \
3699         vat_json_node_t node;                   \
3700         vat_json_init_object(&node);            \
3701         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3702         vat_json_print(vam->ofp, &node);        \
3703         vam->retval = ntohl(mp->retval);        \
3704         vam->result_ready = 1;                  \
3705     }
3706 foreach_standard_reply_retval_handler;
3707 #undef _
3708
3709 #if DPDK > 0
3710 #define _(n)                                    \
3711     static void vl_api_##n##_t_handler          \
3712     (vl_api_##n##_t * mp)                       \
3713     {                                           \
3714         vat_main_t * vam = &vat_main;           \
3715         i32 retval = ntohl(mp->retval);         \
3716         if (vam->async_mode) {                  \
3717             vam->async_errors += (retval < 0);  \
3718         } else {                                \
3719             vam->retval = retval;               \
3720             vam->result_ready = 1;              \
3721         }                                       \
3722     }
3723 foreach_standard_dpdk_reply_retval_handler;
3724 #undef _
3725
3726 #define _(n)                                    \
3727     static void vl_api_##n##_t_handler_json     \
3728     (vl_api_##n##_t * mp)                       \
3729     {                                           \
3730         vat_main_t * vam = &vat_main;           \
3731         vat_json_node_t node;                   \
3732         vat_json_init_object(&node);            \
3733         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3734         vat_json_print(vam->ofp, &node);        \
3735         vam->retval = ntohl(mp->retval);        \
3736         vam->result_ready = 1;                  \
3737     }
3738 foreach_standard_dpdk_reply_retval_handler;
3739 #undef _
3740 #endif
3741
3742 /*
3743  * Table of message reply handlers, must include boilerplate handlers
3744  * we just generated
3745  */
3746
3747 #define foreach_vpe_api_reply_msg                                       \
3748 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3749 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3750 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3751 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3752 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3753 _(CLI_REPLY, cli_reply)                                                 \
3754 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3755 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3756   sw_interface_add_del_address_reply)                                   \
3757 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3758 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3759 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3760 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3761 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3762   sw_interface_set_l2_xconnect_reply)                                   \
3763 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3764   sw_interface_set_l2_bridge_reply)                                     \
3765 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3766 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3767 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3768 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3769 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3770 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3771 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3772 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3773 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3774 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3775 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3776 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3777 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3778 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3779 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3780   proxy_arp_intfc_enable_disable_reply)                                 \
3781 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
3782 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3783   sw_interface_set_unnumbered_reply)                                    \
3784 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3785 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3786 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3787 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3788 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3789 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3790 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3791 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3792 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3793 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3794 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3795 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3796   sw_interface_ip6_enable_disable_reply)                                \
3797 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3798   sw_interface_ip6_set_link_local_address_reply)                        \
3799 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3800   sw_interface_ip6nd_ra_prefix_reply)                                   \
3801 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3802   sw_interface_ip6nd_ra_config_reply)                                   \
3803 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3804 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3805 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3806 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3807 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3808 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3809 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3810 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3811 classify_set_interface_ip_table_reply)                                  \
3812 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3813   classify_set_interface_l2_tables_reply)                               \
3814 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3815 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3816 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3817 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3818 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3819   l2tpv3_interface_enable_disable_reply)                                \
3820 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3821 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3822 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3823 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3824 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3825 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3826 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3827 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3828 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3829 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3830 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3831 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3832 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3833 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3834 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3835 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3836 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3837 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3838 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3839 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3840 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3841 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3842 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3843 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3844 _(IP_DETAILS, ip_details)                                               \
3845 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3846 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3847 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3848 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3849 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3850 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3851 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3852 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3853 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3854 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3855 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3856 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3857 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3858 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3859 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3860 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3861 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3862 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3863 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3864 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3865 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3866 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3867 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3868 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3869 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3870 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3871 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3872 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3873 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3874 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3875 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3876 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3877 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3878 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3879 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3880 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3881 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3882 _(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply)         \
3883 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3884 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3885 _(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY,                               \
3886   lisp_map_register_enable_disable_reply)                               \
3887 _(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                 \
3888   lisp_rloc_probe_enable_disable_reply)                                 \
3889 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3890 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3891 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3892 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3893 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3894 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3895 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3896 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3897 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3898 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3899 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3900 _(LISP_MAP_SERVER_DETAILS, lisp_map_server_details)                     \
3901 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3902 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3903 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3904   lisp_add_del_map_request_itr_rlocs_reply)                             \
3905 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3906   lisp_get_map_request_itr_rlocs_reply)                                 \
3907 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3908 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3909 _(SHOW_LISP_RLOC_PROBE_STATE_REPLY, show_lisp_rloc_probe_state_reply)   \
3910 _(SHOW_LISP_MAP_REGISTER_STATE_REPLY,                                   \
3911   show_lisp_map_register_state_reply)                                   \
3912 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3913 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3914 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3915 _(POLICER_DETAILS, policer_details)                                     \
3916 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3917 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3918 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3919 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3920 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
3921 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3922 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3923 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3924 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3925 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3926 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3927 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3928 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3929 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3930 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3931 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3932 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3933 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3934 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3935 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3936 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3937 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3938 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3939 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3940 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3941  ip_source_and_port_range_check_add_del_reply)                          \
3942 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3943  ip_source_and_port_range_check_interface_add_del_reply)                \
3944 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3945 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3946 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3947 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3948 _(PUNT_REPLY, punt_reply)                                               \
3949 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3950 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3951 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
3952 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
3953 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
3954 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
3955 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
3956 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
3957
3958 #if DPDK > 0
3959 #define foreach_vpe_dpdk_api_reply_msg                                  \
3960 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3961   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3962 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3963   sw_interface_set_dpdk_hqos_subport_reply)                             \
3964 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3965   sw_interface_set_dpdk_hqos_tctbl_reply)
3966 #endif
3967
3968 /* M: construct, but don't yet send a message */
3969
3970 #define M(T,t)                                          \
3971 do {                                                    \
3972     vam->result_ready = 0;                              \
3973     mp = vl_msg_api_alloc_as_if_client(sizeof(*mp));    \
3974     memset (mp, 0, sizeof (*mp));                       \
3975     mp->_vl_msg_id = ntohs (VL_API_##T);                \
3976     mp->client_index = vam->my_client_index;            \
3977 } while(0);
3978
3979 #define M2(T,t,n)                                               \
3980 do {                                                            \
3981     vam->result_ready = 0;                                      \
3982     mp = vl_msg_api_alloc_as_if_client(sizeof(*mp)+(n));        \
3983     memset (mp, 0, sizeof (*mp));                               \
3984     mp->_vl_msg_id = ntohs (VL_API_##T);                        \
3985     mp->client_index = vam->my_client_index;                    \
3986 } while(0);
3987
3988
3989 /* S: send a message */
3990 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3991
3992 /* W: wait for results, with timeout */
3993 #define W                                       \
3994 do {                                            \
3995     timeout = vat_time_now (vam) + 1.0;         \
3996                                                 \
3997     while (vat_time_now (vam) < timeout) {      \
3998         if (vam->result_ready == 1) {           \
3999             return (vam->retval);               \
4000         }                                       \
4001         vat_suspend (vam->vlib_main, 1e-3);     \
4002     }                                           \
4003     return -99;                                 \
4004 } while(0);
4005
4006 /* W2: wait for results, with timeout */
4007 #define W2(body)                                \
4008 do {                                            \
4009     timeout = vat_time_now (vam) + 1.0;         \
4010                                                 \
4011     while (vat_time_now (vam) < timeout) {      \
4012         if (vam->result_ready == 1) {           \
4013           (body);                               \
4014           return (vam->retval);                 \
4015         }                                       \
4016         vat_suspend (vam->vlib_main, 1e-3);     \
4017     }                                           \
4018     return -99;                                 \
4019 } while(0);
4020
4021 typedef struct
4022 {
4023   u8 *name;
4024   u32 value;
4025 } name_sort_t;
4026
4027
4028 #define STR_VTR_OP_CASE(op)     \
4029     case L2_VTR_ ## op:         \
4030         return "" # op;
4031
4032 static const char *
4033 str_vtr_op (u32 vtr_op)
4034 {
4035   switch (vtr_op)
4036     {
4037       STR_VTR_OP_CASE (DISABLED);
4038       STR_VTR_OP_CASE (PUSH_1);
4039       STR_VTR_OP_CASE (PUSH_2);
4040       STR_VTR_OP_CASE (POP_1);
4041       STR_VTR_OP_CASE (POP_2);
4042       STR_VTR_OP_CASE (TRANSLATE_1_1);
4043       STR_VTR_OP_CASE (TRANSLATE_1_2);
4044       STR_VTR_OP_CASE (TRANSLATE_2_1);
4045       STR_VTR_OP_CASE (TRANSLATE_2_2);
4046     }
4047
4048   return "UNKNOWN";
4049 }
4050
4051 static int
4052 dump_sub_interface_table (vat_main_t * vam)
4053 {
4054   const sw_interface_subif_t *sub = NULL;
4055
4056   if (vam->json_output)
4057     {
4058       clib_warning
4059         ("JSON output supported only for VPE API calls and dump_stats_table");
4060       return -99;
4061     }
4062
4063   print (vam->ofp,
4064          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
4065          "Interface", "sw_if_index",
4066          "sub id", "dot1ad", "tags", "outer id",
4067          "inner id", "exact", "default", "outer any", "inner any");
4068
4069   vec_foreach (sub, vam->sw_if_subif_table)
4070   {
4071     print (vam->ofp,
4072            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
4073            sub->interface_name,
4074            sub->sw_if_index,
4075            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4076            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4077            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4078            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4079     if (sub->vtr_op != L2_VTR_DISABLED)
4080       {
4081         print (vam->ofp,
4082                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4083                "tag1: %d tag2: %d ]",
4084                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4085                sub->vtr_tag1, sub->vtr_tag2);
4086       }
4087   }
4088
4089   return 0;
4090 }
4091
4092 static int
4093 name_sort_cmp (void *a1, void *a2)
4094 {
4095   name_sort_t *n1 = a1;
4096   name_sort_t *n2 = a2;
4097
4098   return strcmp ((char *) n1->name, (char *) n2->name);
4099 }
4100
4101 static int
4102 dump_interface_table (vat_main_t * vam)
4103 {
4104   hash_pair_t *p;
4105   name_sort_t *nses = 0, *ns;
4106
4107   if (vam->json_output)
4108     {
4109       clib_warning
4110         ("JSON output supported only for VPE API calls and dump_stats_table");
4111       return -99;
4112     }
4113
4114   /* *INDENT-OFF* */
4115   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4116   ({
4117     vec_add2 (nses, ns, 1);
4118     ns->name = (u8 *)(p->key);
4119     ns->value = (u32) p->value[0];
4120   }));
4121   /* *INDENT-ON* */
4122
4123   vec_sort_with_function (nses, name_sort_cmp);
4124
4125   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4126   vec_foreach (ns, nses)
4127   {
4128     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4129   }
4130   vec_free (nses);
4131   return 0;
4132 }
4133
4134 static int
4135 dump_ip_table (vat_main_t * vam, int is_ipv6)
4136 {
4137   const ip_details_t *det = NULL;
4138   const ip_address_details_t *address = NULL;
4139   u32 i = ~0;
4140
4141   print (vam->ofp, "%-12s", "sw_if_index");
4142
4143   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4144   {
4145     i++;
4146     if (!det->present)
4147       {
4148         continue;
4149       }
4150     print (vam->ofp, "%-12d", i);
4151     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4152     if (!det->addr)
4153       {
4154         continue;
4155       }
4156     vec_foreach (address, det->addr)
4157     {
4158       print (vam->ofp,
4159              "            %-30U%-13d",
4160              is_ipv6 ? format_ip6_address : format_ip4_address,
4161              address->ip, address->prefix_length);
4162     }
4163   }
4164
4165   return 0;
4166 }
4167
4168 static int
4169 dump_ipv4_table (vat_main_t * vam)
4170 {
4171   if (vam->json_output)
4172     {
4173       clib_warning
4174         ("JSON output supported only for VPE API calls and dump_stats_table");
4175       return -99;
4176     }
4177
4178   return dump_ip_table (vam, 0);
4179 }
4180
4181 static int
4182 dump_ipv6_table (vat_main_t * vam)
4183 {
4184   if (vam->json_output)
4185     {
4186       clib_warning
4187         ("JSON output supported only for VPE API calls and dump_stats_table");
4188       return -99;
4189     }
4190
4191   return dump_ip_table (vam, 1);
4192 }
4193
4194 static char *
4195 counter_type_to_str (u8 counter_type, u8 is_combined)
4196 {
4197   if (!is_combined)
4198     {
4199       switch (counter_type)
4200         {
4201         case VNET_INTERFACE_COUNTER_DROP:
4202           return "drop";
4203         case VNET_INTERFACE_COUNTER_PUNT:
4204           return "punt";
4205         case VNET_INTERFACE_COUNTER_IP4:
4206           return "ip4";
4207         case VNET_INTERFACE_COUNTER_IP6:
4208           return "ip6";
4209         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4210           return "rx-no-buf";
4211         case VNET_INTERFACE_COUNTER_RX_MISS:
4212           return "rx-miss";
4213         case VNET_INTERFACE_COUNTER_RX_ERROR:
4214           return "rx-error";
4215         case VNET_INTERFACE_COUNTER_TX_ERROR:
4216           return "tx-error";
4217         default:
4218           return "INVALID-COUNTER-TYPE";
4219         }
4220     }
4221   else
4222     {
4223       switch (counter_type)
4224         {
4225         case VNET_INTERFACE_COUNTER_RX:
4226           return "rx";
4227         case VNET_INTERFACE_COUNTER_TX:
4228           return "tx";
4229         default:
4230           return "INVALID-COUNTER-TYPE";
4231         }
4232     }
4233 }
4234
4235 static int
4236 dump_stats_table (vat_main_t * vam)
4237 {
4238   vat_json_node_t node;
4239   vat_json_node_t *msg_array;
4240   vat_json_node_t *msg;
4241   vat_json_node_t *counter_array;
4242   vat_json_node_t *counter;
4243   interface_counter_t c;
4244   u64 packets;
4245   ip4_fib_counter_t *c4;
4246   ip6_fib_counter_t *c6;
4247   int i, j;
4248
4249   if (!vam->json_output)
4250     {
4251       clib_warning ("dump_stats_table supported only in JSON format");
4252       return -99;
4253     }
4254
4255   vat_json_init_object (&node);
4256
4257   /* interface counters */
4258   msg_array = vat_json_object_add (&node, "interface_counters");
4259   vat_json_init_array (msg_array);
4260   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4261     {
4262       msg = vat_json_array_add (msg_array);
4263       vat_json_init_object (msg);
4264       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4265                                        (u8 *) counter_type_to_str (i, 0));
4266       vat_json_object_add_int (msg, "is_combined", 0);
4267       counter_array = vat_json_object_add (msg, "data");
4268       vat_json_init_array (counter_array);
4269       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4270         {
4271           packets = vam->simple_interface_counters[i][j];
4272           vat_json_array_add_uint (counter_array, packets);
4273         }
4274     }
4275   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4276     {
4277       msg = vat_json_array_add (msg_array);
4278       vat_json_init_object (msg);
4279       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4280                                        (u8 *) counter_type_to_str (i, 1));
4281       vat_json_object_add_int (msg, "is_combined", 1);
4282       counter_array = vat_json_object_add (msg, "data");
4283       vat_json_init_array (counter_array);
4284       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4285         {
4286           c = vam->combined_interface_counters[i][j];
4287           counter = vat_json_array_add (counter_array);
4288           vat_json_init_object (counter);
4289           vat_json_object_add_uint (counter, "packets", c.packets);
4290           vat_json_object_add_uint (counter, "bytes", c.bytes);
4291         }
4292     }
4293
4294   /* ip4 fib counters */
4295   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4296   vat_json_init_array (msg_array);
4297   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4298     {
4299       msg = vat_json_array_add (msg_array);
4300       vat_json_init_object (msg);
4301       vat_json_object_add_uint (msg, "vrf_id",
4302                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4303       counter_array = vat_json_object_add (msg, "c");
4304       vat_json_init_array (counter_array);
4305       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4306         {
4307           counter = vat_json_array_add (counter_array);
4308           vat_json_init_object (counter);
4309           c4 = &vam->ip4_fib_counters[i][j];
4310           vat_json_object_add_ip4 (counter, "address", c4->address);
4311           vat_json_object_add_uint (counter, "address_length",
4312                                     c4->address_length);
4313           vat_json_object_add_uint (counter, "packets", c4->packets);
4314           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4315         }
4316     }
4317
4318   /* ip6 fib counters */
4319   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4320   vat_json_init_array (msg_array);
4321   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4322     {
4323       msg = vat_json_array_add (msg_array);
4324       vat_json_init_object (msg);
4325       vat_json_object_add_uint (msg, "vrf_id",
4326                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4327       counter_array = vat_json_object_add (msg, "c");
4328       vat_json_init_array (counter_array);
4329       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4330         {
4331           counter = vat_json_array_add (counter_array);
4332           vat_json_init_object (counter);
4333           c6 = &vam->ip6_fib_counters[i][j];
4334           vat_json_object_add_ip6 (counter, "address", c6->address);
4335           vat_json_object_add_uint (counter, "address_length",
4336                                     c6->address_length);
4337           vat_json_object_add_uint (counter, "packets", c6->packets);
4338           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4339         }
4340     }
4341
4342   vat_json_print (vam->ofp, &node);
4343   vat_json_free (&node);
4344
4345   return 0;
4346 }
4347
4348 int
4349 exec (vat_main_t * vam)
4350 {
4351   api_main_t *am = &api_main;
4352   vl_api_cli_request_t *mp;
4353   f64 timeout;
4354   void *oldheap;
4355   u8 *cmd = 0;
4356   unformat_input_t *i = vam->input;
4357
4358   if (vec_len (i->buffer) == 0)
4359     return -1;
4360
4361   if (vam->exec_mode == 0 && unformat (i, "mode"))
4362     {
4363       vam->exec_mode = 1;
4364       return 0;
4365     }
4366   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4367     {
4368       vam->exec_mode = 0;
4369       return 0;
4370     }
4371
4372
4373   M (CLI_REQUEST, cli_request);
4374
4375   /*
4376    * Copy cmd into shared memory.
4377    * In order for the CLI command to work, it
4378    * must be a vector ending in \n, not a C-string ending
4379    * in \n\0.
4380    */
4381   pthread_mutex_lock (&am->vlib_rp->mutex);
4382   oldheap = svm_push_data_heap (am->vlib_rp);
4383
4384   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4385   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4386
4387   svm_pop_heap (oldheap);
4388   pthread_mutex_unlock (&am->vlib_rp->mutex);
4389
4390   mp->cmd_in_shmem = (u64) cmd;
4391   S;
4392   timeout = vat_time_now (vam) + 10.0;
4393
4394   while (vat_time_now (vam) < timeout)
4395     {
4396       if (vam->result_ready == 1)
4397         {
4398           u8 *free_me;
4399           if (vam->shmem_result != NULL)
4400             print (vam->ofp, "%s", vam->shmem_result);
4401           pthread_mutex_lock (&am->vlib_rp->mutex);
4402           oldheap = svm_push_data_heap (am->vlib_rp);
4403
4404           free_me = (u8 *) vam->shmem_result;
4405           vec_free (free_me);
4406
4407           svm_pop_heap (oldheap);
4408           pthread_mutex_unlock (&am->vlib_rp->mutex);
4409           return 0;
4410         }
4411     }
4412   return -99;
4413 }
4414
4415 /*
4416  * Future replacement of exec() that passes CLI buffers directly in
4417  * the API messages instead of an additional shared memory area.
4418  */
4419 static int
4420 exec_inband (vat_main_t * vam)
4421 {
4422   vl_api_cli_inband_t *mp;
4423   f64 timeout;
4424   unformat_input_t *i = vam->input;
4425
4426   if (vec_len (i->buffer) == 0)
4427     return -1;
4428
4429   if (vam->exec_mode == 0 && unformat (i, "mode"))
4430     {
4431       vam->exec_mode = 1;
4432       return 0;
4433     }
4434   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4435     {
4436       vam->exec_mode = 0;
4437       return 0;
4438     }
4439
4440   /*
4441    * In order for the CLI command to work, it
4442    * must be a vector ending in \n, not a C-string ending
4443    * in \n\0.
4444    */
4445   u32 len = vec_len (vam->input->buffer);
4446   M2 (CLI_INBAND, cli_inband, len);
4447   clib_memcpy (mp->cmd, vam->input->buffer, len);
4448   mp->length = htonl (len);
4449
4450   S;
4451   W2 (print (vam->ofp, "%s", vam->cmd_reply));
4452 }
4453
4454 static int
4455 api_create_loopback (vat_main_t * vam)
4456 {
4457   unformat_input_t *i = vam->input;
4458   vl_api_create_loopback_t *mp;
4459   f64 timeout;
4460   u8 mac_address[6];
4461   u8 mac_set = 0;
4462
4463   memset (mac_address, 0, sizeof (mac_address));
4464
4465   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4466     {
4467       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4468         mac_set = 1;
4469       else
4470         break;
4471     }
4472
4473   /* Construct the API message */
4474   M (CREATE_LOOPBACK, create_loopback);
4475   if (mac_set)
4476     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4477
4478   S;
4479   W;
4480 }
4481
4482 static int
4483 api_delete_loopback (vat_main_t * vam)
4484 {
4485   unformat_input_t *i = vam->input;
4486   vl_api_delete_loopback_t *mp;
4487   f64 timeout;
4488   u32 sw_if_index = ~0;
4489
4490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4491     {
4492       if (unformat (i, "sw_if_index %d", &sw_if_index))
4493         ;
4494       else
4495         break;
4496     }
4497
4498   if (sw_if_index == ~0)
4499     {
4500       errmsg ("missing sw_if_index");
4501       return -99;
4502     }
4503
4504   /* Construct the API message */
4505   M (DELETE_LOOPBACK, delete_loopback);
4506   mp->sw_if_index = ntohl (sw_if_index);
4507
4508   S;
4509   W;
4510 }
4511
4512 static int
4513 api_want_stats (vat_main_t * vam)
4514 {
4515   unformat_input_t *i = vam->input;
4516   vl_api_want_stats_t *mp;
4517   f64 timeout;
4518   int enable = -1;
4519
4520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4521     {
4522       if (unformat (i, "enable"))
4523         enable = 1;
4524       else if (unformat (i, "disable"))
4525         enable = 0;
4526       else
4527         break;
4528     }
4529
4530   if (enable == -1)
4531     {
4532       errmsg ("missing enable|disable");
4533       return -99;
4534     }
4535
4536   M (WANT_STATS, want_stats);
4537   mp->enable_disable = enable;
4538
4539   S;
4540   W;
4541 }
4542
4543 static int
4544 api_want_interface_events (vat_main_t * vam)
4545 {
4546   unformat_input_t *i = vam->input;
4547   vl_api_want_interface_events_t *mp;
4548   f64 timeout;
4549   int enable = -1;
4550
4551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4552     {
4553       if (unformat (i, "enable"))
4554         enable = 1;
4555       else if (unformat (i, "disable"))
4556         enable = 0;
4557       else
4558         break;
4559     }
4560
4561   if (enable == -1)
4562     {
4563       errmsg ("missing enable|disable");
4564       return -99;
4565     }
4566
4567   M (WANT_INTERFACE_EVENTS, want_interface_events);
4568   mp->enable_disable = enable;
4569
4570   vam->interface_event_display = enable;
4571
4572   S;
4573   W;
4574 }
4575
4576
4577 /* Note: non-static, called once to set up the initial intfc table */
4578 int
4579 api_sw_interface_dump (vat_main_t * vam)
4580 {
4581   vl_api_sw_interface_dump_t *mp;
4582   f64 timeout;
4583   hash_pair_t *p;
4584   name_sort_t *nses = 0, *ns;
4585   sw_interface_subif_t *sub = NULL;
4586
4587   /* Toss the old name table */
4588   /* *INDENT-OFF* */
4589   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4590   ({
4591     vec_add2 (nses, ns, 1);
4592     ns->name = (u8 *)(p->key);
4593     ns->value = (u32) p->value[0];
4594   }));
4595   /* *INDENT-ON* */
4596
4597   hash_free (vam->sw_if_index_by_interface_name);
4598
4599   vec_foreach (ns, nses) vec_free (ns->name);
4600
4601   vec_free (nses);
4602
4603   vec_foreach (sub, vam->sw_if_subif_table)
4604   {
4605     vec_free (sub->interface_name);
4606   }
4607   vec_free (vam->sw_if_subif_table);
4608
4609   /* recreate the interface name hash table */
4610   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4611
4612   /* Get list of ethernets */
4613   M (SW_INTERFACE_DUMP, sw_interface_dump);
4614   mp->name_filter_valid = 1;
4615   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4616   S;
4617
4618   /* and local / loopback interfaces */
4619   M (SW_INTERFACE_DUMP, sw_interface_dump);
4620   mp->name_filter_valid = 1;
4621   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4622   S;
4623
4624   /* and packet-generator interfaces */
4625   M (SW_INTERFACE_DUMP, sw_interface_dump);
4626   mp->name_filter_valid = 1;
4627   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4628   S;
4629
4630   /* and vxlan-gpe tunnel interfaces */
4631   M (SW_INTERFACE_DUMP, sw_interface_dump);
4632   mp->name_filter_valid = 1;
4633   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4634            sizeof (mp->name_filter) - 1);
4635   S;
4636
4637   /* and vxlan tunnel interfaces */
4638   M (SW_INTERFACE_DUMP, sw_interface_dump);
4639   mp->name_filter_valid = 1;
4640   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4641   S;
4642
4643   /* and host (af_packet) interfaces */
4644   M (SW_INTERFACE_DUMP, sw_interface_dump);
4645   mp->name_filter_valid = 1;
4646   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4647   S;
4648
4649   /* and l2tpv3 tunnel interfaces */
4650   M (SW_INTERFACE_DUMP, sw_interface_dump);
4651   mp->name_filter_valid = 1;
4652   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4653            sizeof (mp->name_filter) - 1);
4654   S;
4655
4656   /* and GRE tunnel interfaces */
4657   M (SW_INTERFACE_DUMP, sw_interface_dump);
4658   mp->name_filter_valid = 1;
4659   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4660   S;
4661
4662   /* and LISP-GPE interfaces */
4663   M (SW_INTERFACE_DUMP, sw_interface_dump);
4664   mp->name_filter_valid = 1;
4665   strncpy ((char *) mp->name_filter, "lisp_gpe",
4666            sizeof (mp->name_filter) - 1);
4667   S;
4668
4669   /* and IPSEC tunnel interfaces */
4670   M (SW_INTERFACE_DUMP, sw_interface_dump);
4671   mp->name_filter_valid = 1;
4672   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4673   S;
4674
4675   /* Use a control ping for synchronization */
4676   {
4677     vl_api_control_ping_t *mp;
4678     M (CONTROL_PING, control_ping);
4679     S;
4680   }
4681   W;
4682 }
4683
4684 static int
4685 api_sw_interface_set_flags (vat_main_t * vam)
4686 {
4687   unformat_input_t *i = vam->input;
4688   vl_api_sw_interface_set_flags_t *mp;
4689   f64 timeout;
4690   u32 sw_if_index;
4691   u8 sw_if_index_set = 0;
4692   u8 admin_up = 0, link_up = 0;
4693
4694   /* Parse args required to build the message */
4695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4696     {
4697       if (unformat (i, "admin-up"))
4698         admin_up = 1;
4699       else if (unformat (i, "admin-down"))
4700         admin_up = 0;
4701       else if (unformat (i, "link-up"))
4702         link_up = 1;
4703       else if (unformat (i, "link-down"))
4704         link_up = 0;
4705       else
4706         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4707         sw_if_index_set = 1;
4708       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4709         sw_if_index_set = 1;
4710       else
4711         break;
4712     }
4713
4714   if (sw_if_index_set == 0)
4715     {
4716       errmsg ("missing interface name or sw_if_index");
4717       return -99;
4718     }
4719
4720   /* Construct the API message */
4721   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4722   mp->sw_if_index = ntohl (sw_if_index);
4723   mp->admin_up_down = admin_up;
4724   mp->link_up_down = link_up;
4725
4726   /* send it... */
4727   S;
4728
4729   /* Wait for a reply, return the good/bad news... */
4730   W;
4731 }
4732
4733 static int
4734 api_sw_interface_clear_stats (vat_main_t * vam)
4735 {
4736   unformat_input_t *i = vam->input;
4737   vl_api_sw_interface_clear_stats_t *mp;
4738   f64 timeout;
4739   u32 sw_if_index;
4740   u8 sw_if_index_set = 0;
4741
4742   /* Parse args required to build the message */
4743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4744     {
4745       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4746         sw_if_index_set = 1;
4747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4748         sw_if_index_set = 1;
4749       else
4750         break;
4751     }
4752
4753   /* Construct the API message */
4754   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4755
4756   if (sw_if_index_set == 1)
4757     mp->sw_if_index = ntohl (sw_if_index);
4758   else
4759     mp->sw_if_index = ~0;
4760
4761   /* send it... */
4762   S;
4763
4764   /* Wait for a reply, return the good/bad news... */
4765   W;
4766 }
4767
4768 #if DPDK >0
4769 static int
4770 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4771 {
4772   unformat_input_t *i = vam->input;
4773   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4774   f64 timeout;
4775   u32 sw_if_index;
4776   u8 sw_if_index_set = 0;
4777   u32 subport;
4778   u8 subport_set = 0;
4779   u32 pipe;
4780   u8 pipe_set = 0;
4781   u32 profile;
4782   u8 profile_set = 0;
4783
4784   /* Parse args required to build the message */
4785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4786     {
4787       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4788         sw_if_index_set = 1;
4789       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4790         sw_if_index_set = 1;
4791       else if (unformat (i, "subport %u", &subport))
4792         subport_set = 1;
4793       else
4794         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4795         sw_if_index_set = 1;
4796       else if (unformat (i, "pipe %u", &pipe))
4797         pipe_set = 1;
4798       else if (unformat (i, "profile %u", &profile))
4799         profile_set = 1;
4800       else
4801         break;
4802     }
4803
4804   if (sw_if_index_set == 0)
4805     {
4806       errmsg ("missing interface name or sw_if_index");
4807       return -99;
4808     }
4809
4810   if (subport_set == 0)
4811     {
4812       errmsg ("missing subport ");
4813       return -99;
4814     }
4815
4816   if (pipe_set == 0)
4817     {
4818       errmsg ("missing pipe");
4819       return -99;
4820     }
4821
4822   if (profile_set == 0)
4823     {
4824       errmsg ("missing profile");
4825       return -99;
4826     }
4827
4828   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4829
4830   mp->sw_if_index = ntohl (sw_if_index);
4831   mp->subport = ntohl (subport);
4832   mp->pipe = ntohl (pipe);
4833   mp->profile = ntohl (profile);
4834
4835
4836   S;
4837   W;
4838   /* NOTREACHED */
4839   return 0;
4840 }
4841
4842 static int
4843 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4844 {
4845   unformat_input_t *i = vam->input;
4846   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4847   f64 timeout;
4848   u32 sw_if_index;
4849   u8 sw_if_index_set = 0;
4850   u32 subport;
4851   u8 subport_set = 0;
4852   u32 tb_rate = 1250000000;     /* 10GbE */
4853   u32 tb_size = 1000000;
4854   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4855   u32 tc_period = 10;
4856
4857   /* Parse args required to build the message */
4858   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4859     {
4860       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4861         sw_if_index_set = 1;
4862       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4863         sw_if_index_set = 1;
4864       else if (unformat (i, "subport %u", &subport))
4865         subport_set = 1;
4866       else
4867         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4868         sw_if_index_set = 1;
4869       else if (unformat (i, "rate %u", &tb_rate))
4870         {
4871           u32 tc_id;
4872
4873           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4874                tc_id++)
4875             tc_rate[tc_id] = tb_rate;
4876         }
4877       else if (unformat (i, "bktsize %u", &tb_size))
4878         ;
4879       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4880         ;
4881       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4882         ;
4883       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4884         ;
4885       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4886         ;
4887       else if (unformat (i, "period %u", &tc_period))
4888         ;
4889       else
4890         break;
4891     }
4892
4893   if (sw_if_index_set == 0)
4894     {
4895       errmsg ("missing interface name or sw_if_index");
4896       return -99;
4897     }
4898
4899   if (subport_set == 0)
4900     {
4901       errmsg ("missing subport ");
4902       return -99;
4903     }
4904
4905   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4906
4907   mp->sw_if_index = ntohl (sw_if_index);
4908   mp->subport = ntohl (subport);
4909   mp->tb_rate = ntohl (tb_rate);
4910   mp->tb_size = ntohl (tb_size);
4911   mp->tc_rate[0] = ntohl (tc_rate[0]);
4912   mp->tc_rate[1] = ntohl (tc_rate[1]);
4913   mp->tc_rate[2] = ntohl (tc_rate[2]);
4914   mp->tc_rate[3] = ntohl (tc_rate[3]);
4915   mp->tc_period = ntohl (tc_period);
4916
4917   S;
4918   W;
4919   /* NOTREACHED */
4920   return 0;
4921 }
4922
4923 static int
4924 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4925 {
4926   unformat_input_t *i = vam->input;
4927   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4928   f64 timeout;
4929   u32 sw_if_index;
4930   u8 sw_if_index_set = 0;
4931   u8 entry_set = 0;
4932   u8 tc_set = 0;
4933   u8 queue_set = 0;
4934   u32 entry, tc, queue;
4935
4936   /* Parse args required to build the message */
4937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4938     {
4939       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4940         sw_if_index_set = 1;
4941       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4942         sw_if_index_set = 1;
4943       else if (unformat (i, "entry %d", &entry))
4944         entry_set = 1;
4945       else if (unformat (i, "tc %d", &tc))
4946         tc_set = 1;
4947       else if (unformat (i, "queue %d", &queue))
4948         queue_set = 1;
4949       else
4950         break;
4951     }
4952
4953   if (sw_if_index_set == 0)
4954     {
4955       errmsg ("missing interface name or sw_if_index");
4956       return -99;
4957     }
4958
4959   if (entry_set == 0)
4960     {
4961       errmsg ("missing entry ");
4962       return -99;
4963     }
4964
4965   if (tc_set == 0)
4966     {
4967       errmsg ("missing traffic class ");
4968       return -99;
4969     }
4970
4971   if (queue_set == 0)
4972     {
4973       errmsg ("missing queue ");
4974       return -99;
4975     }
4976
4977   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4978
4979   mp->sw_if_index = ntohl (sw_if_index);
4980   mp->entry = ntohl (entry);
4981   mp->tc = ntohl (tc);
4982   mp->queue = ntohl (queue);
4983
4984   S;
4985   W;
4986   /* NOTREACHED */
4987   return 0;
4988 }
4989 #endif
4990
4991 static int
4992 api_sw_interface_add_del_address (vat_main_t * vam)
4993 {
4994   unformat_input_t *i = vam->input;
4995   vl_api_sw_interface_add_del_address_t *mp;
4996   f64 timeout;
4997   u32 sw_if_index;
4998   u8 sw_if_index_set = 0;
4999   u8 is_add = 1, del_all = 0;
5000   u32 address_length = 0;
5001   u8 v4_address_set = 0;
5002   u8 v6_address_set = 0;
5003   ip4_address_t v4address;
5004   ip6_address_t v6address;
5005
5006   /* Parse args required to build the message */
5007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5008     {
5009       if (unformat (i, "del-all"))
5010         del_all = 1;
5011       else if (unformat (i, "del"))
5012         is_add = 0;
5013       else
5014         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5015         sw_if_index_set = 1;
5016       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5017         sw_if_index_set = 1;
5018       else if (unformat (i, "%U/%d",
5019                          unformat_ip4_address, &v4address, &address_length))
5020         v4_address_set = 1;
5021       else if (unformat (i, "%U/%d",
5022                          unformat_ip6_address, &v6address, &address_length))
5023         v6_address_set = 1;
5024       else
5025         break;
5026     }
5027
5028   if (sw_if_index_set == 0)
5029     {
5030       errmsg ("missing interface name or sw_if_index");
5031       return -99;
5032     }
5033   if (v4_address_set && v6_address_set)
5034     {
5035       errmsg ("both v4 and v6 addresses set");
5036       return -99;
5037     }
5038   if (!v4_address_set && !v6_address_set && !del_all)
5039     {
5040       errmsg ("no addresses set");
5041       return -99;
5042     }
5043
5044   /* Construct the API message */
5045   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
5046
5047   mp->sw_if_index = ntohl (sw_if_index);
5048   mp->is_add = is_add;
5049   mp->del_all = del_all;
5050   if (v6_address_set)
5051     {
5052       mp->is_ipv6 = 1;
5053       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5054     }
5055   else
5056     {
5057       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5058     }
5059   mp->address_length = address_length;
5060
5061   /* send it... */
5062   S;
5063
5064   /* Wait for a reply, return good/bad news  */
5065   W;
5066 }
5067
5068 static int
5069 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5070 {
5071   unformat_input_t *i = vam->input;
5072   vl_api_sw_interface_set_mpls_enable_t *mp;
5073   f64 timeout;
5074   u32 sw_if_index;
5075   u8 sw_if_index_set = 0;
5076   u8 enable = 1;
5077
5078   /* Parse args required to build the message */
5079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5080     {
5081       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5082         sw_if_index_set = 1;
5083       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5084         sw_if_index_set = 1;
5085       else if (unformat (i, "disable"))
5086         enable = 0;
5087       else if (unformat (i, "dis"))
5088         enable = 0;
5089       else
5090         break;
5091     }
5092
5093   if (sw_if_index_set == 0)
5094     {
5095       errmsg ("missing interface name or sw_if_index");
5096       return -99;
5097     }
5098
5099   /* Construct the API message */
5100   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
5101
5102   mp->sw_if_index = ntohl (sw_if_index);
5103   mp->enable = enable;
5104
5105   /* send it... */
5106   S;
5107
5108   /* Wait for a reply... */
5109   W;
5110 }
5111
5112 static int
5113 api_sw_interface_set_table (vat_main_t * vam)
5114 {
5115   unformat_input_t *i = vam->input;
5116   vl_api_sw_interface_set_table_t *mp;
5117   f64 timeout;
5118   u32 sw_if_index, vrf_id = 0;
5119   u8 sw_if_index_set = 0;
5120   u8 is_ipv6 = 0;
5121
5122   /* Parse args required to build the message */
5123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5124     {
5125       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5126         sw_if_index_set = 1;
5127       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5128         sw_if_index_set = 1;
5129       else if (unformat (i, "vrf %d", &vrf_id))
5130         ;
5131       else if (unformat (i, "ipv6"))
5132         is_ipv6 = 1;
5133       else
5134         break;
5135     }
5136
5137   if (sw_if_index_set == 0)
5138     {
5139       errmsg ("missing interface name or sw_if_index");
5140       return -99;
5141     }
5142
5143   /* Construct the API message */
5144   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
5145
5146   mp->sw_if_index = ntohl (sw_if_index);
5147   mp->is_ipv6 = is_ipv6;
5148   mp->vrf_id = ntohl (vrf_id);
5149
5150   /* send it... */
5151   S;
5152
5153   /* Wait for a reply... */
5154   W;
5155 }
5156
5157 static void vl_api_sw_interface_get_table_reply_t_handler
5158   (vl_api_sw_interface_get_table_reply_t * mp)
5159 {
5160   vat_main_t *vam = &vat_main;
5161
5162   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5163
5164   vam->retval = ntohl (mp->retval);
5165   vam->result_ready = 1;
5166
5167 }
5168
5169 static void vl_api_sw_interface_get_table_reply_t_handler_json
5170   (vl_api_sw_interface_get_table_reply_t * mp)
5171 {
5172   vat_main_t *vam = &vat_main;
5173   vat_json_node_t node;
5174
5175   vat_json_init_object (&node);
5176   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5177   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5178
5179   vat_json_print (vam->ofp, &node);
5180   vat_json_free (&node);
5181
5182   vam->retval = ntohl (mp->retval);
5183   vam->result_ready = 1;
5184 }
5185
5186 static int
5187 api_sw_interface_get_table (vat_main_t * vam)
5188 {
5189   unformat_input_t *i = vam->input;
5190   vl_api_sw_interface_get_table_t *mp;
5191   u32 sw_if_index;
5192   u8 sw_if_index_set = 0;
5193   u8 is_ipv6 = 0;
5194   f64 timeout;
5195
5196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5197     {
5198       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5199         sw_if_index_set = 1;
5200       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5201         sw_if_index_set = 1;
5202       else if (unformat (i, "ipv6"))
5203         is_ipv6 = 1;
5204       else
5205         break;
5206     }
5207
5208   if (sw_if_index_set == 0)
5209     {
5210       errmsg ("missing interface name or sw_if_index");
5211       return -99;
5212     }
5213
5214   M (SW_INTERFACE_GET_TABLE, sw_interface_get_table);
5215   mp->sw_if_index = htonl (sw_if_index);
5216   mp->is_ipv6 = is_ipv6;
5217
5218   S;
5219   W;
5220 }
5221
5222 static int
5223 api_sw_interface_set_vpath (vat_main_t * vam)
5224 {
5225   unformat_input_t *i = vam->input;
5226   vl_api_sw_interface_set_vpath_t *mp;
5227   f64 timeout;
5228   u32 sw_if_index = 0;
5229   u8 sw_if_index_set = 0;
5230   u8 is_enable = 0;
5231
5232   /* Parse args required to build the message */
5233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5234     {
5235       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5236         sw_if_index_set = 1;
5237       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5238         sw_if_index_set = 1;
5239       else if (unformat (i, "enable"))
5240         is_enable = 1;
5241       else if (unformat (i, "disable"))
5242         is_enable = 0;
5243       else
5244         break;
5245     }
5246
5247   if (sw_if_index_set == 0)
5248     {
5249       errmsg ("missing interface name or sw_if_index");
5250       return -99;
5251     }
5252
5253   /* Construct the API message */
5254   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5255
5256   mp->sw_if_index = ntohl (sw_if_index);
5257   mp->enable = is_enable;
5258
5259   /* send it... */
5260   S;
5261
5262   /* Wait for a reply... */
5263   W;
5264 }
5265
5266 static int
5267 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5268 {
5269   unformat_input_t *i = vam->input;
5270   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5271   f64 timeout;
5272   u32 sw_if_index = 0;
5273   u8 sw_if_index_set = 0;
5274   u8 is_enable = 0;
5275   u8 is_ipv6 = 0;
5276
5277   /* Parse args required to build the message */
5278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5279     {
5280       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5281         sw_if_index_set = 1;
5282       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5283         sw_if_index_set = 1;
5284       else if (unformat (i, "enable"))
5285         is_enable = 1;
5286       else if (unformat (i, "disable"))
5287         is_enable = 0;
5288       else if (unformat (i, "ip4"))
5289         is_ipv6 = 0;
5290       else if (unformat (i, "ip6"))
5291         is_ipv6 = 1;
5292       else
5293         break;
5294     }
5295
5296   if (sw_if_index_set == 0)
5297     {
5298       errmsg ("missing interface name or sw_if_index");
5299       return -99;
5300     }
5301
5302   /* Construct the API message */
5303   M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5304
5305   mp->sw_if_index = ntohl (sw_if_index);
5306   mp->enable = is_enable;
5307   mp->is_ipv6 = is_ipv6;
5308
5309   /* send it... */
5310   S;
5311
5312   /* Wait for a reply... */
5313   W;
5314 }
5315
5316 static int
5317 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5318 {
5319   unformat_input_t *i = vam->input;
5320   vl_api_sw_interface_set_l2_xconnect_t *mp;
5321   f64 timeout;
5322   u32 rx_sw_if_index;
5323   u8 rx_sw_if_index_set = 0;
5324   u32 tx_sw_if_index;
5325   u8 tx_sw_if_index_set = 0;
5326   u8 enable = 1;
5327
5328   /* Parse args required to build the message */
5329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5330     {
5331       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5332         rx_sw_if_index_set = 1;
5333       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5334         tx_sw_if_index_set = 1;
5335       else if (unformat (i, "rx"))
5336         {
5337           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5338             {
5339               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5340                             &rx_sw_if_index))
5341                 rx_sw_if_index_set = 1;
5342             }
5343           else
5344             break;
5345         }
5346       else if (unformat (i, "tx"))
5347         {
5348           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5349             {
5350               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5351                             &tx_sw_if_index))
5352                 tx_sw_if_index_set = 1;
5353             }
5354           else
5355             break;
5356         }
5357       else if (unformat (i, "enable"))
5358         enable = 1;
5359       else if (unformat (i, "disable"))
5360         enable = 0;
5361       else
5362         break;
5363     }
5364
5365   if (rx_sw_if_index_set == 0)
5366     {
5367       errmsg ("missing rx interface name or rx_sw_if_index");
5368       return -99;
5369     }
5370
5371   if (enable && (tx_sw_if_index_set == 0))
5372     {
5373       errmsg ("missing tx interface name or tx_sw_if_index");
5374       return -99;
5375     }
5376
5377   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5378
5379   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5380   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5381   mp->enable = enable;
5382
5383   S;
5384   W;
5385   /* NOTREACHED */
5386   return 0;
5387 }
5388
5389 static int
5390 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5391 {
5392   unformat_input_t *i = vam->input;
5393   vl_api_sw_interface_set_l2_bridge_t *mp;
5394   f64 timeout;
5395   u32 rx_sw_if_index;
5396   u8 rx_sw_if_index_set = 0;
5397   u32 bd_id;
5398   u8 bd_id_set = 0;
5399   u8 bvi = 0;
5400   u32 shg = 0;
5401   u8 enable = 1;
5402
5403   /* Parse args required to build the message */
5404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5405     {
5406       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5407         rx_sw_if_index_set = 1;
5408       else if (unformat (i, "bd_id %d", &bd_id))
5409         bd_id_set = 1;
5410       else
5411         if (unformat
5412             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5413         rx_sw_if_index_set = 1;
5414       else if (unformat (i, "shg %d", &shg))
5415         ;
5416       else if (unformat (i, "bvi"))
5417         bvi = 1;
5418       else if (unformat (i, "enable"))
5419         enable = 1;
5420       else if (unformat (i, "disable"))
5421         enable = 0;
5422       else
5423         break;
5424     }
5425
5426   if (rx_sw_if_index_set == 0)
5427     {
5428       errmsg ("missing rx interface name or sw_if_index");
5429       return -99;
5430     }
5431
5432   if (enable && (bd_id_set == 0))
5433     {
5434       errmsg ("missing bridge domain");
5435       return -99;
5436     }
5437
5438   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5439
5440   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5441   mp->bd_id = ntohl (bd_id);
5442   mp->shg = (u8) shg;
5443   mp->bvi = bvi;
5444   mp->enable = enable;
5445
5446   S;
5447   W;
5448   /* NOTREACHED */
5449   return 0;
5450 }
5451
5452 static int
5453 api_bridge_domain_dump (vat_main_t * vam)
5454 {
5455   unformat_input_t *i = vam->input;
5456   vl_api_bridge_domain_dump_t *mp;
5457   f64 timeout;
5458   u32 bd_id = ~0;
5459
5460   /* Parse args required to build the message */
5461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5462     {
5463       if (unformat (i, "bd_id %d", &bd_id))
5464         ;
5465       else
5466         break;
5467     }
5468
5469   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5470   mp->bd_id = ntohl (bd_id);
5471   S;
5472
5473   /* Use a control ping for synchronization */
5474   {
5475     vl_api_control_ping_t *mp;
5476     M (CONTROL_PING, control_ping);
5477     S;
5478   }
5479
5480   W;
5481   /* NOTREACHED */
5482   return 0;
5483 }
5484
5485 static int
5486 api_bridge_domain_add_del (vat_main_t * vam)
5487 {
5488   unformat_input_t *i = vam->input;
5489   vl_api_bridge_domain_add_del_t *mp;
5490   f64 timeout;
5491   u32 bd_id = ~0;
5492   u8 is_add = 1;
5493   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5494   u32 mac_age = 0;
5495
5496   /* Parse args required to build the message */
5497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5498     {
5499       if (unformat (i, "bd_id %d", &bd_id))
5500         ;
5501       else if (unformat (i, "flood %d", &flood))
5502         ;
5503       else if (unformat (i, "uu-flood %d", &uu_flood))
5504         ;
5505       else if (unformat (i, "forward %d", &forward))
5506         ;
5507       else if (unformat (i, "learn %d", &learn))
5508         ;
5509       else if (unformat (i, "arp-term %d", &arp_term))
5510         ;
5511       else if (unformat (i, "mac-age %d", &mac_age))
5512         ;
5513       else if (unformat (i, "del"))
5514         {
5515           is_add = 0;
5516           flood = uu_flood = forward = learn = 0;
5517         }
5518       else
5519         break;
5520     }
5521
5522   if (bd_id == ~0)
5523     {
5524       errmsg ("missing bridge domain");
5525       return -99;
5526     }
5527
5528   if (mac_age > 255)
5529     {
5530       errmsg ("mac age must be less than 256 ");
5531       return -99;
5532     }
5533
5534   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5535
5536   mp->bd_id = ntohl (bd_id);
5537   mp->flood = flood;
5538   mp->uu_flood = uu_flood;
5539   mp->forward = forward;
5540   mp->learn = learn;
5541   mp->arp_term = arp_term;
5542   mp->is_add = is_add;
5543   mp->mac_age = (u8) mac_age;
5544
5545   S;
5546   W;
5547   /* NOTREACHED */
5548   return 0;
5549 }
5550
5551 static int
5552 api_l2fib_add_del (vat_main_t * vam)
5553 {
5554   unformat_input_t *i = vam->input;
5555   vl_api_l2fib_add_del_t *mp;
5556   f64 timeout;
5557   u64 mac = 0;
5558   u8 mac_set = 0;
5559   u32 bd_id;
5560   u8 bd_id_set = 0;
5561   u32 sw_if_index = ~0;
5562   u8 sw_if_index_set = 0;
5563   u8 is_add = 1;
5564   u8 static_mac = 0;
5565   u8 filter_mac = 0;
5566   u8 bvi_mac = 0;
5567   int count = 1;
5568   f64 before = 0;
5569   int j;
5570
5571   /* Parse args required to build the message */
5572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5573     {
5574       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5575         mac_set = 1;
5576       else if (unformat (i, "bd_id %d", &bd_id))
5577         bd_id_set = 1;
5578       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5579         sw_if_index_set = 1;
5580       else if (unformat (i, "sw_if"))
5581         {
5582           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5583             {
5584               if (unformat
5585                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5586                 sw_if_index_set = 1;
5587             }
5588           else
5589             break;
5590         }
5591       else if (unformat (i, "static"))
5592         static_mac = 1;
5593       else if (unformat (i, "filter"))
5594         {
5595           filter_mac = 1;
5596           static_mac = 1;
5597         }
5598       else if (unformat (i, "bvi"))
5599         {
5600           bvi_mac = 1;
5601           static_mac = 1;
5602         }
5603       else if (unformat (i, "del"))
5604         is_add = 0;
5605       else if (unformat (i, "count %d", &count))
5606         ;
5607       else
5608         break;
5609     }
5610
5611   if (mac_set == 0)
5612     {
5613       errmsg ("missing mac address");
5614       return -99;
5615     }
5616
5617   if (bd_id_set == 0)
5618     {
5619       errmsg ("missing bridge domain");
5620       return -99;
5621     }
5622
5623   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5624     {
5625       errmsg ("missing interface name or sw_if_index");
5626       return -99;
5627     }
5628
5629   if (count > 1)
5630     {
5631       /* Turn on async mode */
5632       vam->async_mode = 1;
5633       vam->async_errors = 0;
5634       before = vat_time_now (vam);
5635     }
5636
5637   for (j = 0; j < count; j++)
5638     {
5639       M (L2FIB_ADD_DEL, l2fib_add_del);
5640
5641       mp->mac = mac;
5642       mp->bd_id = ntohl (bd_id);
5643       mp->is_add = is_add;
5644
5645       if (is_add)
5646         {
5647           mp->sw_if_index = ntohl (sw_if_index);
5648           mp->static_mac = static_mac;
5649           mp->filter_mac = filter_mac;
5650           mp->bvi_mac = bvi_mac;
5651         }
5652       increment_mac_address (&mac);
5653       /* send it... */
5654       S;
5655     }
5656
5657   if (count > 1)
5658     {
5659       vl_api_control_ping_t *mp;
5660       f64 after;
5661
5662       /* Shut off async mode */
5663       vam->async_mode = 0;
5664
5665       M (CONTROL_PING, control_ping);
5666       S;
5667
5668       timeout = vat_time_now (vam) + 1.0;
5669       while (vat_time_now (vam) < timeout)
5670         if (vam->result_ready == 1)
5671           goto out;
5672       vam->retval = -99;
5673
5674     out:
5675       if (vam->retval == -99)
5676         errmsg ("timeout");
5677
5678       if (vam->async_errors > 0)
5679         {
5680           errmsg ("%d asynchronous errors", vam->async_errors);
5681           vam->retval = -98;
5682         }
5683       vam->async_errors = 0;
5684       after = vat_time_now (vam);
5685
5686       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5687              count, after - before, count / (after - before));
5688     }
5689   else
5690     {
5691       /* Wait for a reply... */
5692       W;
5693     }
5694   /* Return the good/bad news */
5695   return (vam->retval);
5696 }
5697
5698 static int
5699 api_l2_flags (vat_main_t * vam)
5700 {
5701   unformat_input_t *i = vam->input;
5702   vl_api_l2_flags_t *mp;
5703   f64 timeout;
5704   u32 sw_if_index;
5705   u32 feature_bitmap = 0;
5706   u8 sw_if_index_set = 0;
5707
5708   /* Parse args required to build the message */
5709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5710     {
5711       if (unformat (i, "sw_if_index %d", &sw_if_index))
5712         sw_if_index_set = 1;
5713       else if (unformat (i, "sw_if"))
5714         {
5715           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5716             {
5717               if (unformat
5718                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5719                 sw_if_index_set = 1;
5720             }
5721           else
5722             break;
5723         }
5724       else if (unformat (i, "learn"))
5725         feature_bitmap |= L2INPUT_FEAT_LEARN;
5726       else if (unformat (i, "forward"))
5727         feature_bitmap |= L2INPUT_FEAT_FWD;
5728       else if (unformat (i, "flood"))
5729         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5730       else if (unformat (i, "uu-flood"))
5731         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5732       else
5733         break;
5734     }
5735
5736   if (sw_if_index_set == 0)
5737     {
5738       errmsg ("missing interface name or sw_if_index");
5739       return -99;
5740     }
5741
5742   M (L2_FLAGS, l2_flags);
5743
5744   mp->sw_if_index = ntohl (sw_if_index);
5745   mp->feature_bitmap = ntohl (feature_bitmap);
5746
5747   S;
5748   W;
5749   /* NOTREACHED */
5750   return 0;
5751 }
5752
5753 static int
5754 api_bridge_flags (vat_main_t * vam)
5755 {
5756   unformat_input_t *i = vam->input;
5757   vl_api_bridge_flags_t *mp;
5758   f64 timeout;
5759   u32 bd_id;
5760   u8 bd_id_set = 0;
5761   u8 is_set = 1;
5762   u32 flags = 0;
5763
5764   /* Parse args required to build the message */
5765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5766     {
5767       if (unformat (i, "bd_id %d", &bd_id))
5768         bd_id_set = 1;
5769       else if (unformat (i, "learn"))
5770         flags |= L2_LEARN;
5771       else if (unformat (i, "forward"))
5772         flags |= L2_FWD;
5773       else if (unformat (i, "flood"))
5774         flags |= L2_FLOOD;
5775       else if (unformat (i, "uu-flood"))
5776         flags |= L2_UU_FLOOD;
5777       else if (unformat (i, "arp-term"))
5778         flags |= L2_ARP_TERM;
5779       else if (unformat (i, "off"))
5780         is_set = 0;
5781       else if (unformat (i, "disable"))
5782         is_set = 0;
5783       else
5784         break;
5785     }
5786
5787   if (bd_id_set == 0)
5788     {
5789       errmsg ("missing bridge domain");
5790       return -99;
5791     }
5792
5793   M (BRIDGE_FLAGS, bridge_flags);
5794
5795   mp->bd_id = ntohl (bd_id);
5796   mp->feature_bitmap = ntohl (flags);
5797   mp->is_set = is_set;
5798
5799   S;
5800   W;
5801   /* NOTREACHED */
5802   return 0;
5803 }
5804
5805 static int
5806 api_bd_ip_mac_add_del (vat_main_t * vam)
5807 {
5808   unformat_input_t *i = vam->input;
5809   vl_api_bd_ip_mac_add_del_t *mp;
5810   f64 timeout;
5811   u32 bd_id;
5812   u8 is_ipv6 = 0;
5813   u8 is_add = 1;
5814   u8 bd_id_set = 0;
5815   u8 ip_set = 0;
5816   u8 mac_set = 0;
5817   ip4_address_t v4addr;
5818   ip6_address_t v6addr;
5819   u8 macaddr[6];
5820
5821
5822   /* Parse args required to build the message */
5823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5824     {
5825       if (unformat (i, "bd_id %d", &bd_id))
5826         {
5827           bd_id_set++;
5828         }
5829       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5830         {
5831           ip_set++;
5832         }
5833       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5834         {
5835           ip_set++;
5836           is_ipv6++;
5837         }
5838       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5839         {
5840           mac_set++;
5841         }
5842       else if (unformat (i, "del"))
5843         is_add = 0;
5844       else
5845         break;
5846     }
5847
5848   if (bd_id_set == 0)
5849     {
5850       errmsg ("missing bridge domain");
5851       return -99;
5852     }
5853   else if (ip_set == 0)
5854     {
5855       errmsg ("missing IP address");
5856       return -99;
5857     }
5858   else if (mac_set == 0)
5859     {
5860       errmsg ("missing MAC address");
5861       return -99;
5862     }
5863
5864   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5865
5866   mp->bd_id = ntohl (bd_id);
5867   mp->is_ipv6 = is_ipv6;
5868   mp->is_add = is_add;
5869   if (is_ipv6)
5870     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5871   else
5872     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5873   clib_memcpy (mp->mac_address, macaddr, 6);
5874   S;
5875   W;
5876   /* NOTREACHED */
5877   return 0;
5878 }
5879
5880 static int
5881 api_tap_connect (vat_main_t * vam)
5882 {
5883   unformat_input_t *i = vam->input;
5884   vl_api_tap_connect_t *mp;
5885   f64 timeout;
5886   u8 mac_address[6];
5887   u8 random_mac = 1;
5888   u8 name_set = 0;
5889   u8 *tap_name;
5890   u8 *tag = 0;
5891
5892   memset (mac_address, 0, sizeof (mac_address));
5893
5894   /* Parse args required to build the message */
5895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5896     {
5897       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5898         {
5899           random_mac = 0;
5900         }
5901       else if (unformat (i, "random-mac"))
5902         random_mac = 1;
5903       else if (unformat (i, "tapname %s", &tap_name))
5904         name_set = 1;
5905       else if (unformat (i, "tag %s", &tag))
5906         ;
5907       else
5908         break;
5909     }
5910
5911   if (name_set == 0)
5912     {
5913       errmsg ("missing tap name");
5914       return -99;
5915     }
5916   if (vec_len (tap_name) > 63)
5917     {
5918       errmsg ("tap name too long");
5919       return -99;
5920     }
5921   vec_add1 (tap_name, 0);
5922
5923   if (vec_len (tag) > 63)
5924     {
5925       errmsg ("tag too long");
5926       return -99;
5927     }
5928
5929   /* Construct the API message */
5930   M (TAP_CONNECT, tap_connect);
5931
5932   mp->use_random_mac = random_mac;
5933   clib_memcpy (mp->mac_address, mac_address, 6);
5934   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5935   if (tag)
5936     clib_memcpy (mp->tag, tag, vec_len (tag));
5937
5938   vec_free (tap_name);
5939   vec_free (tag);
5940
5941   /* send it... */
5942   S;
5943
5944   /* Wait for a reply... */
5945   W;
5946 }
5947
5948 static int
5949 api_tap_modify (vat_main_t * vam)
5950 {
5951   unformat_input_t *i = vam->input;
5952   vl_api_tap_modify_t *mp;
5953   f64 timeout;
5954   u8 mac_address[6];
5955   u8 random_mac = 1;
5956   u8 name_set = 0;
5957   u8 *tap_name;
5958   u32 sw_if_index = ~0;
5959   u8 sw_if_index_set = 0;
5960
5961   memset (mac_address, 0, sizeof (mac_address));
5962
5963   /* Parse args required to build the message */
5964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5965     {
5966       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5967         sw_if_index_set = 1;
5968       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5969         sw_if_index_set = 1;
5970       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5971         {
5972           random_mac = 0;
5973         }
5974       else if (unformat (i, "random-mac"))
5975         random_mac = 1;
5976       else if (unformat (i, "tapname %s", &tap_name))
5977         name_set = 1;
5978       else
5979         break;
5980     }
5981
5982   if (sw_if_index_set == 0)
5983     {
5984       errmsg ("missing vpp interface name");
5985       return -99;
5986     }
5987   if (name_set == 0)
5988     {
5989       errmsg ("missing tap name");
5990       return -99;
5991     }
5992   if (vec_len (tap_name) > 63)
5993     {
5994       errmsg ("tap name too long");
5995     }
5996   vec_add1 (tap_name, 0);
5997
5998   /* Construct the API message */
5999   M (TAP_MODIFY, tap_modify);
6000
6001   mp->use_random_mac = random_mac;
6002   mp->sw_if_index = ntohl (sw_if_index);
6003   clib_memcpy (mp->mac_address, mac_address, 6);
6004   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
6005   vec_free (tap_name);
6006
6007   /* send it... */
6008   S;
6009
6010   /* Wait for a reply... */
6011   W;
6012 }
6013
6014 static int
6015 api_tap_delete (vat_main_t * vam)
6016 {
6017   unformat_input_t *i = vam->input;
6018   vl_api_tap_delete_t *mp;
6019   f64 timeout;
6020   u32 sw_if_index = ~0;
6021   u8 sw_if_index_set = 0;
6022
6023   /* Parse args required to build the message */
6024   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6025     {
6026       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6027         sw_if_index_set = 1;
6028       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6029         sw_if_index_set = 1;
6030       else
6031         break;
6032     }
6033
6034   if (sw_if_index_set == 0)
6035     {
6036       errmsg ("missing vpp interface name");
6037       return -99;
6038     }
6039
6040   /* Construct the API message */
6041   M (TAP_DELETE, tap_delete);
6042
6043   mp->sw_if_index = ntohl (sw_if_index);
6044
6045   /* send it... */
6046   S;
6047
6048   /* Wait for a reply... */
6049   W;
6050 }
6051
6052 static int
6053 api_ip_add_del_route (vat_main_t * vam)
6054 {
6055   unformat_input_t *i = vam->input;
6056   vl_api_ip_add_del_route_t *mp;
6057   f64 timeout;
6058   u32 sw_if_index = ~0, vrf_id = 0;
6059   u8 is_ipv6 = 0;
6060   u8 is_local = 0, is_drop = 0;
6061   u8 is_unreach = 0, is_prohibit = 0;
6062   u8 create_vrf_if_needed = 0;
6063   u8 is_add = 1;
6064   u32 next_hop_weight = 1;
6065   u8 not_last = 0;
6066   u8 is_multipath = 0;
6067   u8 address_set = 0;
6068   u8 address_length_set = 0;
6069   u32 next_hop_table_id = 0;
6070   u32 resolve_attempts = 0;
6071   u32 dst_address_length = 0;
6072   u8 next_hop_set = 0;
6073   ip4_address_t v4_dst_address, v4_next_hop_address;
6074   ip6_address_t v6_dst_address, v6_next_hop_address;
6075   int count = 1;
6076   int j;
6077   f64 before = 0;
6078   u32 random_add_del = 0;
6079   u32 *random_vector = 0;
6080   uword *random_hash;
6081   u32 random_seed = 0xdeaddabe;
6082   u32 classify_table_index = ~0;
6083   u8 is_classify = 0;
6084   u8 resolve_host = 0, resolve_attached = 0;
6085   mpls_label_t *next_hop_out_label_stack = NULL;
6086   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6087   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6088
6089   /* Parse args required to build the message */
6090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6091     {
6092       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6093         ;
6094       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6095         ;
6096       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6097         {
6098           address_set = 1;
6099           is_ipv6 = 0;
6100         }
6101       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6102         {
6103           address_set = 1;
6104           is_ipv6 = 1;
6105         }
6106       else if (unformat (i, "/%d", &dst_address_length))
6107         {
6108           address_length_set = 1;
6109         }
6110
6111       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6112                                          &v4_next_hop_address))
6113         {
6114           next_hop_set = 1;
6115         }
6116       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6117                                          &v6_next_hop_address))
6118         {
6119           next_hop_set = 1;
6120         }
6121       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6122         ;
6123       else if (unformat (i, "weight %d", &next_hop_weight))
6124         ;
6125       else if (unformat (i, "drop"))
6126         {
6127           is_drop = 1;
6128         }
6129       else if (unformat (i, "null-send-unreach"))
6130         {
6131           is_unreach = 1;
6132         }
6133       else if (unformat (i, "null-send-prohibit"))
6134         {
6135           is_prohibit = 1;
6136         }
6137       else if (unformat (i, "local"))
6138         {
6139           is_local = 1;
6140         }
6141       else if (unformat (i, "classify %d", &classify_table_index))
6142         {
6143           is_classify = 1;
6144         }
6145       else if (unformat (i, "del"))
6146         is_add = 0;
6147       else if (unformat (i, "add"))
6148         is_add = 1;
6149       else if (unformat (i, "not-last"))
6150         not_last = 1;
6151       else if (unformat (i, "resolve-via-host"))
6152         resolve_host = 1;
6153       else if (unformat (i, "resolve-via-attached"))
6154         resolve_attached = 1;
6155       else if (unformat (i, "multipath"))
6156         is_multipath = 1;
6157       else if (unformat (i, "vrf %d", &vrf_id))
6158         ;
6159       else if (unformat (i, "create-vrf"))
6160         create_vrf_if_needed = 1;
6161       else if (unformat (i, "count %d", &count))
6162         ;
6163       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6164         ;
6165       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6166         ;
6167       else if (unformat (i, "out-label %d", &next_hop_out_label))
6168         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6169       else if (unformat (i, "via-label %d", &next_hop_via_label))
6170         ;
6171       else if (unformat (i, "random"))
6172         random_add_del = 1;
6173       else if (unformat (i, "seed %d", &random_seed))
6174         ;
6175       else
6176         {
6177           clib_warning ("parse error '%U'", format_unformat_error, i);
6178           return -99;
6179         }
6180     }
6181
6182   if (!next_hop_set && !is_drop && !is_local &&
6183       !is_classify && !is_unreach && !is_prohibit &&
6184       MPLS_LABEL_INVALID == next_hop_via_label)
6185     {
6186       errmsg
6187         ("next hop / local / drop / unreach / prohibit / classify not set");
6188       return -99;
6189     }
6190
6191   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6192     {
6193       errmsg ("next hop and next-hop via label set");
6194       return -99;
6195     }
6196   if (address_set == 0)
6197     {
6198       errmsg ("missing addresses");
6199       return -99;
6200     }
6201
6202   if (address_length_set == 0)
6203     {
6204       errmsg ("missing address length");
6205       return -99;
6206     }
6207
6208   /* Generate a pile of unique, random routes */
6209   if (random_add_del)
6210     {
6211       u32 this_random_address;
6212       random_hash = hash_create (count, sizeof (uword));
6213
6214       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6215       for (j = 0; j <= count; j++)
6216         {
6217           do
6218             {
6219               this_random_address = random_u32 (&random_seed);
6220               this_random_address =
6221                 clib_host_to_net_u32 (this_random_address);
6222             }
6223           while (hash_get (random_hash, this_random_address));
6224           vec_add1 (random_vector, this_random_address);
6225           hash_set (random_hash, this_random_address, 1);
6226         }
6227       hash_free (random_hash);
6228       v4_dst_address.as_u32 = random_vector[0];
6229     }
6230
6231   if (count > 1)
6232     {
6233       /* Turn on async mode */
6234       vam->async_mode = 1;
6235       vam->async_errors = 0;
6236       before = vat_time_now (vam);
6237     }
6238
6239   for (j = 0; j < count; j++)
6240     {
6241       /* Construct the API message */
6242       M2 (IP_ADD_DEL_ROUTE, ip_add_del_route,
6243           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6244
6245       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6246       mp->table_id = ntohl (vrf_id);
6247       mp->create_vrf_if_needed = create_vrf_if_needed;
6248
6249       mp->is_add = is_add;
6250       mp->is_drop = is_drop;
6251       mp->is_unreach = is_unreach;
6252       mp->is_prohibit = is_prohibit;
6253       mp->is_ipv6 = is_ipv6;
6254       mp->is_local = is_local;
6255       mp->is_classify = is_classify;
6256       mp->is_multipath = is_multipath;
6257       mp->is_resolve_host = resolve_host;
6258       mp->is_resolve_attached = resolve_attached;
6259       mp->not_last = not_last;
6260       mp->next_hop_weight = next_hop_weight;
6261       mp->dst_address_length = dst_address_length;
6262       mp->next_hop_table_id = ntohl (next_hop_table_id);
6263       mp->classify_table_index = ntohl (classify_table_index);
6264       mp->next_hop_via_label = ntohl (next_hop_via_label);
6265       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6266       if (0 != mp->next_hop_n_out_labels)
6267         {
6268           memcpy (mp->next_hop_out_label_stack,
6269                   next_hop_out_label_stack,
6270                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6271           vec_free (next_hop_out_label_stack);
6272         }
6273
6274       if (is_ipv6)
6275         {
6276           clib_memcpy (mp->dst_address, &v6_dst_address,
6277                        sizeof (v6_dst_address));
6278           if (next_hop_set)
6279             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6280                          sizeof (v6_next_hop_address));
6281           increment_v6_address (&v6_dst_address);
6282         }
6283       else
6284         {
6285           clib_memcpy (mp->dst_address, &v4_dst_address,
6286                        sizeof (v4_dst_address));
6287           if (next_hop_set)
6288             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6289                          sizeof (v4_next_hop_address));
6290           if (random_add_del)
6291             v4_dst_address.as_u32 = random_vector[j + 1];
6292           else
6293             increment_v4_address (&v4_dst_address);
6294         }
6295       /* send it... */
6296       S;
6297       /* If we receive SIGTERM, stop now... */
6298       if (vam->do_exit)
6299         break;
6300     }
6301
6302   /* When testing multiple add/del ops, use a control-ping to sync */
6303   if (count > 1)
6304     {
6305       vl_api_control_ping_t *mp;
6306       f64 after;
6307
6308       /* Shut off async mode */
6309       vam->async_mode = 0;
6310
6311       M (CONTROL_PING, control_ping);
6312       S;
6313
6314       timeout = vat_time_now (vam) + 1.0;
6315       while (vat_time_now (vam) < timeout)
6316         if (vam->result_ready == 1)
6317           goto out;
6318       vam->retval = -99;
6319
6320     out:
6321       if (vam->retval == -99)
6322         errmsg ("timeout");
6323
6324       if (vam->async_errors > 0)
6325         {
6326           errmsg ("%d asynchronous errors", vam->async_errors);
6327           vam->retval = -98;
6328         }
6329       vam->async_errors = 0;
6330       after = vat_time_now (vam);
6331
6332       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6333       if (j > 0)
6334         count = j;
6335
6336       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6337              count, after - before, count / (after - before));
6338     }
6339   else
6340     {
6341       /* Wait for a reply... */
6342       W;
6343     }
6344
6345   /* Return the good/bad news */
6346   return (vam->retval);
6347 }
6348
6349 static int
6350 api_mpls_route_add_del (vat_main_t * vam)
6351 {
6352   unformat_input_t *i = vam->input;
6353   vl_api_mpls_route_add_del_t *mp;
6354   f64 timeout;
6355   u32 sw_if_index = ~0, table_id = 0;
6356   u8 create_table_if_needed = 0;
6357   u8 is_add = 1;
6358   u32 next_hop_weight = 1;
6359   u8 is_multipath = 0;
6360   u32 next_hop_table_id = 0;
6361   u8 next_hop_set = 0;
6362   ip4_address_t v4_next_hop_address = {
6363     .as_u32 = 0,
6364   };
6365   ip6_address_t v6_next_hop_address = { {0} };
6366   int count = 1;
6367   int j;
6368   f64 before = 0;
6369   u32 classify_table_index = ~0;
6370   u8 is_classify = 0;
6371   u8 resolve_host = 0, resolve_attached = 0;
6372   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6373   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6374   mpls_label_t *next_hop_out_label_stack = NULL;
6375   mpls_label_t local_label = MPLS_LABEL_INVALID;
6376   u8 is_eos = 0;
6377   u8 next_hop_proto_is_ip4 = 1;
6378
6379   /* Parse args required to build the message */
6380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6381     {
6382       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6383         ;
6384       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6385         ;
6386       else if (unformat (i, "%d", &local_label))
6387         ;
6388       else if (unformat (i, "eos"))
6389         is_eos = 1;
6390       else if (unformat (i, "non-eos"))
6391         is_eos = 0;
6392       else if (unformat (i, "via %U", unformat_ip4_address,
6393                          &v4_next_hop_address))
6394         {
6395           next_hop_set = 1;
6396           next_hop_proto_is_ip4 = 1;
6397         }
6398       else if (unformat (i, "via %U", unformat_ip6_address,
6399                          &v6_next_hop_address))
6400         {
6401           next_hop_set = 1;
6402           next_hop_proto_is_ip4 = 0;
6403         }
6404       else if (unformat (i, "weight %d", &next_hop_weight))
6405         ;
6406       else if (unformat (i, "create-table"))
6407         create_table_if_needed = 1;
6408       else if (unformat (i, "classify %d", &classify_table_index))
6409         {
6410           is_classify = 1;
6411         }
6412       else if (unformat (i, "del"))
6413         is_add = 0;
6414       else if (unformat (i, "add"))
6415         is_add = 1;
6416       else if (unformat (i, "resolve-via-host"))
6417         resolve_host = 1;
6418       else if (unformat (i, "resolve-via-attached"))
6419         resolve_attached = 1;
6420       else if (unformat (i, "multipath"))
6421         is_multipath = 1;
6422       else if (unformat (i, "count %d", &count))
6423         ;
6424       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6425         {
6426           next_hop_set = 1;
6427           next_hop_proto_is_ip4 = 1;
6428         }
6429       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6430         {
6431           next_hop_set = 1;
6432           next_hop_proto_is_ip4 = 0;
6433         }
6434       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6435         ;
6436       else if (unformat (i, "via-label %d", &next_hop_via_label))
6437         ;
6438       else if (unformat (i, "out-label %d", &next_hop_out_label))
6439         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6440       else
6441         {
6442           clib_warning ("parse error '%U'", format_unformat_error, i);
6443           return -99;
6444         }
6445     }
6446
6447   if (!next_hop_set && !is_classify)
6448     {
6449       errmsg ("next hop / classify not set");
6450       return -99;
6451     }
6452
6453   if (MPLS_LABEL_INVALID == local_label)
6454     {
6455       errmsg ("missing label");
6456       return -99;
6457     }
6458
6459   if (count > 1)
6460     {
6461       /* Turn on async mode */
6462       vam->async_mode = 1;
6463       vam->async_errors = 0;
6464       before = vat_time_now (vam);
6465     }
6466
6467   for (j = 0; j < count; j++)
6468     {
6469       /* Construct the API message */
6470       M2 (MPLS_ROUTE_ADD_DEL, mpls_route_add_del,
6471           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6472
6473       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6474       mp->mr_table_id = ntohl (table_id);
6475       mp->mr_create_table_if_needed = create_table_if_needed;
6476
6477       mp->mr_is_add = is_add;
6478       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6479       mp->mr_is_classify = is_classify;
6480       mp->mr_is_multipath = is_multipath;
6481       mp->mr_is_resolve_host = resolve_host;
6482       mp->mr_is_resolve_attached = resolve_attached;
6483       mp->mr_next_hop_weight = next_hop_weight;
6484       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6485       mp->mr_classify_table_index = ntohl (classify_table_index);
6486       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6487       mp->mr_label = ntohl (local_label);
6488       mp->mr_eos = is_eos;
6489
6490       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6491       if (0 != mp->mr_next_hop_n_out_labels)
6492         {
6493           memcpy (mp->mr_next_hop_out_label_stack,
6494                   next_hop_out_label_stack,
6495                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6496           vec_free (next_hop_out_label_stack);
6497         }
6498
6499       if (next_hop_set)
6500         {
6501           if (next_hop_proto_is_ip4)
6502             {
6503               clib_memcpy (mp->mr_next_hop,
6504                            &v4_next_hop_address,
6505                            sizeof (v4_next_hop_address));
6506             }
6507           else
6508             {
6509               clib_memcpy (mp->mr_next_hop,
6510                            &v6_next_hop_address,
6511                            sizeof (v6_next_hop_address));
6512             }
6513         }
6514       local_label++;
6515
6516       /* send it... */
6517       S;
6518       /* If we receive SIGTERM, stop now... */
6519       if (vam->do_exit)
6520         break;
6521     }
6522
6523   /* When testing multiple add/del ops, use a control-ping to sync */
6524   if (count > 1)
6525     {
6526       vl_api_control_ping_t *mp;
6527       f64 after;
6528
6529       /* Shut off async mode */
6530       vam->async_mode = 0;
6531
6532       M (CONTROL_PING, control_ping);
6533       S;
6534
6535       timeout = vat_time_now (vam) + 1.0;
6536       while (vat_time_now (vam) < timeout)
6537         if (vam->result_ready == 1)
6538           goto out;
6539       vam->retval = -99;
6540
6541     out:
6542       if (vam->retval == -99)
6543         errmsg ("timeout");
6544
6545       if (vam->async_errors > 0)
6546         {
6547           errmsg ("%d asynchronous errors", vam->async_errors);
6548           vam->retval = -98;
6549         }
6550       vam->async_errors = 0;
6551       after = vat_time_now (vam);
6552
6553       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6554       if (j > 0)
6555         count = j;
6556
6557       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6558              count, after - before, count / (after - before));
6559     }
6560   else
6561     {
6562       /* Wait for a reply... */
6563       W;
6564     }
6565
6566   /* Return the good/bad news */
6567   return (vam->retval);
6568 }
6569
6570 static int
6571 api_mpls_ip_bind_unbind (vat_main_t * vam)
6572 {
6573   unformat_input_t *i = vam->input;
6574   vl_api_mpls_ip_bind_unbind_t *mp;
6575   f64 timeout;
6576   u32 ip_table_id = 0;
6577   u8 create_table_if_needed = 0;
6578   u8 is_bind = 1;
6579   u8 is_ip4 = 1;
6580   ip4_address_t v4_address;
6581   ip6_address_t v6_address;
6582   u32 address_length;
6583   u8 address_set = 0;
6584   mpls_label_t local_label = MPLS_LABEL_INVALID;
6585
6586   /* Parse args required to build the message */
6587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6588     {
6589       if (unformat (i, "%U/%d", unformat_ip4_address,
6590                     &v4_address, &address_length))
6591         {
6592           is_ip4 = 1;
6593           address_set = 1;
6594         }
6595       else if (unformat (i, "%U/%d", unformat_ip6_address,
6596                          &v6_address, &address_length))
6597         {
6598           is_ip4 = 0;
6599           address_set = 1;
6600         }
6601       else if (unformat (i, "%d", &local_label))
6602         ;
6603       else if (unformat (i, "create-table"))
6604         create_table_if_needed = 1;
6605       else if (unformat (i, "table-id %d", &ip_table_id))
6606         ;
6607       else if (unformat (i, "unbind"))
6608         is_bind = 0;
6609       else if (unformat (i, "bind"))
6610         is_bind = 1;
6611       else
6612         {
6613           clib_warning ("parse error '%U'", format_unformat_error, i);
6614           return -99;
6615         }
6616     }
6617
6618   if (!address_set)
6619     {
6620       errmsg ("IP addres not set");
6621       return -99;
6622     }
6623
6624   if (MPLS_LABEL_INVALID == local_label)
6625     {
6626       errmsg ("missing label");
6627       return -99;
6628     }
6629
6630   /* Construct the API message */
6631   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6632
6633   mp->mb_create_table_if_needed = create_table_if_needed;
6634   mp->mb_is_bind = is_bind;
6635   mp->mb_is_ip4 = is_ip4;
6636   mp->mb_ip_table_id = ntohl (ip_table_id);
6637   mp->mb_mpls_table_id = 0;
6638   mp->mb_label = ntohl (local_label);
6639   mp->mb_address_length = address_length;
6640
6641   if (is_ip4)
6642     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6643   else
6644     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6645
6646   /* send it... */
6647   S;
6648
6649   /* Wait for a reply... */
6650   W;
6651 }
6652
6653 static int
6654 api_proxy_arp_add_del (vat_main_t * vam)
6655 {
6656   unformat_input_t *i = vam->input;
6657   vl_api_proxy_arp_add_del_t *mp;
6658   f64 timeout;
6659   u32 vrf_id = 0;
6660   u8 is_add = 1;
6661   ip4_address_t lo, hi;
6662   u8 range_set = 0;
6663
6664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6665     {
6666       if (unformat (i, "vrf %d", &vrf_id))
6667         ;
6668       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6669                          unformat_ip4_address, &hi))
6670         range_set = 1;
6671       else if (unformat (i, "del"))
6672         is_add = 0;
6673       else
6674         {
6675           clib_warning ("parse error '%U'", format_unformat_error, i);
6676           return -99;
6677         }
6678     }
6679
6680   if (range_set == 0)
6681     {
6682       errmsg ("address range not set");
6683       return -99;
6684     }
6685
6686   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6687
6688   mp->vrf_id = ntohl (vrf_id);
6689   mp->is_add = is_add;
6690   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6691   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6692
6693   S;
6694   W;
6695   /* NOTREACHED */
6696   return 0;
6697 }
6698
6699 static int
6700 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6701 {
6702   unformat_input_t *i = vam->input;
6703   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6704   f64 timeout;
6705   u32 sw_if_index;
6706   u8 enable = 1;
6707   u8 sw_if_index_set = 0;
6708
6709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6710     {
6711       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6712         sw_if_index_set = 1;
6713       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6714         sw_if_index_set = 1;
6715       else if (unformat (i, "enable"))
6716         enable = 1;
6717       else if (unformat (i, "disable"))
6718         enable = 0;
6719       else
6720         {
6721           clib_warning ("parse error '%U'", format_unformat_error, i);
6722           return -99;
6723         }
6724     }
6725
6726   if (sw_if_index_set == 0)
6727     {
6728       errmsg ("missing interface name or sw_if_index");
6729       return -99;
6730     }
6731
6732   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6733
6734   mp->sw_if_index = ntohl (sw_if_index);
6735   mp->enable_disable = enable;
6736
6737   S;
6738   W;
6739   /* NOTREACHED */
6740   return 0;
6741 }
6742
6743 static int
6744 api_mpls_tunnel_add_del (vat_main_t * vam)
6745 {
6746   unformat_input_t *i = vam->input;
6747   vl_api_mpls_tunnel_add_del_t *mp;
6748   f64 timeout;
6749
6750   u8 is_add = 1;
6751   u8 l2_only = 0;
6752   u32 sw_if_index = ~0;
6753   u32 next_hop_sw_if_index = ~0;
6754   u32 next_hop_proto_is_ip4 = 1;
6755
6756   u32 next_hop_table_id = 0;
6757   ip4_address_t v4_next_hop_address = {
6758     .as_u32 = 0,
6759   };
6760   ip6_address_t v6_next_hop_address = { {0} };
6761   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6762
6763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6764     {
6765       if (unformat (i, "add"))
6766         is_add = 1;
6767       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6768         is_add = 0;
6769       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6770         ;
6771       else if (unformat (i, "via %U",
6772                          unformat_ip4_address, &v4_next_hop_address))
6773         {
6774           next_hop_proto_is_ip4 = 1;
6775         }
6776       else if (unformat (i, "via %U",
6777                          unformat_ip6_address, &v6_next_hop_address))
6778         {
6779           next_hop_proto_is_ip4 = 0;
6780         }
6781       else if (unformat (i, "l2-only"))
6782         l2_only = 1;
6783       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6784         ;
6785       else if (unformat (i, "out-label %d", &next_hop_out_label))
6786         vec_add1 (labels, ntohl (next_hop_out_label));
6787       else
6788         {
6789           clib_warning ("parse error '%U'", format_unformat_error, i);
6790           return -99;
6791         }
6792     }
6793
6794   M2 (MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del,
6795       sizeof (mpls_label_t) * vec_len (labels));
6796
6797   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
6798   mp->mt_sw_if_index = ntohl (sw_if_index);
6799   mp->mt_is_add = is_add;
6800   mp->mt_l2_only = l2_only;
6801   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
6802   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6803
6804   mp->mt_next_hop_n_out_labels = vec_len (labels);
6805
6806   if (0 != mp->mt_next_hop_n_out_labels)
6807     {
6808       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
6809                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
6810       vec_free (labels);
6811     }
6812
6813   if (next_hop_proto_is_ip4)
6814     {
6815       clib_memcpy (mp->mt_next_hop,
6816                    &v4_next_hop_address, sizeof (v4_next_hop_address));
6817     }
6818   else
6819     {
6820       clib_memcpy (mp->mt_next_hop,
6821                    &v6_next_hop_address, sizeof (v6_next_hop_address));
6822     }
6823
6824   S;
6825   W;
6826   /* NOTREACHED */
6827   return 0;
6828 }
6829
6830 static int
6831 api_sw_interface_set_unnumbered (vat_main_t * vam)
6832 {
6833   unformat_input_t *i = vam->input;
6834   vl_api_sw_interface_set_unnumbered_t *mp;
6835   f64 timeout;
6836   u32 sw_if_index;
6837   u32 unnum_sw_index = ~0;
6838   u8 is_add = 1;
6839   u8 sw_if_index_set = 0;
6840
6841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6842     {
6843       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6844         sw_if_index_set = 1;
6845       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6846         sw_if_index_set = 1;
6847       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6848         ;
6849       else if (unformat (i, "del"))
6850         is_add = 0;
6851       else
6852         {
6853           clib_warning ("parse error '%U'", format_unformat_error, i);
6854           return -99;
6855         }
6856     }
6857
6858   if (sw_if_index_set == 0)
6859     {
6860       errmsg ("missing interface name or sw_if_index");
6861       return -99;
6862     }
6863
6864   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6865
6866   mp->sw_if_index = ntohl (sw_if_index);
6867   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6868   mp->is_add = is_add;
6869
6870   S;
6871   W;
6872   /* NOTREACHED */
6873   return 0;
6874 }
6875
6876 static int
6877 api_ip_neighbor_add_del (vat_main_t * vam)
6878 {
6879   unformat_input_t *i = vam->input;
6880   vl_api_ip_neighbor_add_del_t *mp;
6881   f64 timeout;
6882   u32 sw_if_index;
6883   u8 sw_if_index_set = 0;
6884   u32 vrf_id = 0;
6885   u8 is_add = 1;
6886   u8 is_static = 0;
6887   u8 mac_address[6];
6888   u8 mac_set = 0;
6889   u8 v4_address_set = 0;
6890   u8 v6_address_set = 0;
6891   ip4_address_t v4address;
6892   ip6_address_t v6address;
6893
6894   memset (mac_address, 0, sizeof (mac_address));
6895
6896   /* Parse args required to build the message */
6897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6898     {
6899       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6900         {
6901           mac_set = 1;
6902         }
6903       else if (unformat (i, "del"))
6904         is_add = 0;
6905       else
6906         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6907         sw_if_index_set = 1;
6908       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6909         sw_if_index_set = 1;
6910       else if (unformat (i, "is_static"))
6911         is_static = 1;
6912       else if (unformat (i, "vrf %d", &vrf_id))
6913         ;
6914       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6915         v4_address_set = 1;
6916       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6917         v6_address_set = 1;
6918       else
6919         {
6920           clib_warning ("parse error '%U'", format_unformat_error, i);
6921           return -99;
6922         }
6923     }
6924
6925   if (sw_if_index_set == 0)
6926     {
6927       errmsg ("missing interface name or sw_if_index");
6928       return -99;
6929     }
6930   if (v4_address_set && v6_address_set)
6931     {
6932       errmsg ("both v4 and v6 addresses set");
6933       return -99;
6934     }
6935   if (!v4_address_set && !v6_address_set)
6936     {
6937       errmsg ("no address set");
6938       return -99;
6939     }
6940
6941   /* Construct the API message */
6942   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6943
6944   mp->sw_if_index = ntohl (sw_if_index);
6945   mp->is_add = is_add;
6946   mp->vrf_id = ntohl (vrf_id);
6947   mp->is_static = is_static;
6948   if (mac_set)
6949     clib_memcpy (mp->mac_address, mac_address, 6);
6950   if (v6_address_set)
6951     {
6952       mp->is_ipv6 = 1;
6953       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6954     }
6955   else
6956     {
6957       /* mp->is_ipv6 = 0; via memset in M macro above */
6958       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6959     }
6960
6961   /* send it... */
6962   S;
6963
6964   /* Wait for a reply, return good/bad news  */
6965   W;
6966
6967   /* NOTREACHED */
6968   return 0;
6969 }
6970
6971 static int
6972 api_reset_vrf (vat_main_t * vam)
6973 {
6974   unformat_input_t *i = vam->input;
6975   vl_api_reset_vrf_t *mp;
6976   f64 timeout;
6977   u32 vrf_id = 0;
6978   u8 is_ipv6 = 0;
6979   u8 vrf_id_set = 0;
6980
6981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6982     {
6983       if (unformat (i, "vrf %d", &vrf_id))
6984         vrf_id_set = 1;
6985       else if (unformat (i, "ipv6"))
6986         is_ipv6 = 1;
6987       else
6988         {
6989           clib_warning ("parse error '%U'", format_unformat_error, i);
6990           return -99;
6991         }
6992     }
6993
6994   if (vrf_id_set == 0)
6995     {
6996       errmsg ("missing vrf id");
6997       return -99;
6998     }
6999
7000   M (RESET_VRF, reset_vrf);
7001
7002   mp->vrf_id = ntohl (vrf_id);
7003   mp->is_ipv6 = is_ipv6;
7004
7005   S;
7006   W;
7007   /* NOTREACHED */
7008   return 0;
7009 }
7010
7011 static int
7012 api_create_vlan_subif (vat_main_t * vam)
7013 {
7014   unformat_input_t *i = vam->input;
7015   vl_api_create_vlan_subif_t *mp;
7016   f64 timeout;
7017   u32 sw_if_index;
7018   u8 sw_if_index_set = 0;
7019   u32 vlan_id;
7020   u8 vlan_id_set = 0;
7021
7022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7023     {
7024       if (unformat (i, "sw_if_index %d", &sw_if_index))
7025         sw_if_index_set = 1;
7026       else
7027         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7028         sw_if_index_set = 1;
7029       else if (unformat (i, "vlan %d", &vlan_id))
7030         vlan_id_set = 1;
7031       else
7032         {
7033           clib_warning ("parse error '%U'", format_unformat_error, i);
7034           return -99;
7035         }
7036     }
7037
7038   if (sw_if_index_set == 0)
7039     {
7040       errmsg ("missing interface name or sw_if_index");
7041       return -99;
7042     }
7043
7044   if (vlan_id_set == 0)
7045     {
7046       errmsg ("missing vlan_id");
7047       return -99;
7048     }
7049   M (CREATE_VLAN_SUBIF, create_vlan_subif);
7050
7051   mp->sw_if_index = ntohl (sw_if_index);
7052   mp->vlan_id = ntohl (vlan_id);
7053
7054   S;
7055   W;
7056   /* NOTREACHED */
7057   return 0;
7058 }
7059
7060 #define foreach_create_subif_bit                \
7061 _(no_tags)                                      \
7062 _(one_tag)                                      \
7063 _(two_tags)                                     \
7064 _(dot1ad)                                       \
7065 _(exact_match)                                  \
7066 _(default_sub)                                  \
7067 _(outer_vlan_id_any)                            \
7068 _(inner_vlan_id_any)
7069
7070 static int
7071 api_create_subif (vat_main_t * vam)
7072 {
7073   unformat_input_t *i = vam->input;
7074   vl_api_create_subif_t *mp;
7075   f64 timeout;
7076   u32 sw_if_index;
7077   u8 sw_if_index_set = 0;
7078   u32 sub_id;
7079   u8 sub_id_set = 0;
7080   u32 no_tags = 0;
7081   u32 one_tag = 0;
7082   u32 two_tags = 0;
7083   u32 dot1ad = 0;
7084   u32 exact_match = 0;
7085   u32 default_sub = 0;
7086   u32 outer_vlan_id_any = 0;
7087   u32 inner_vlan_id_any = 0;
7088   u32 tmp;
7089   u16 outer_vlan_id = 0;
7090   u16 inner_vlan_id = 0;
7091
7092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7093     {
7094       if (unformat (i, "sw_if_index %d", &sw_if_index))
7095         sw_if_index_set = 1;
7096       else
7097         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7098         sw_if_index_set = 1;
7099       else if (unformat (i, "sub_id %d", &sub_id))
7100         sub_id_set = 1;
7101       else if (unformat (i, "outer_vlan_id %d", &tmp))
7102         outer_vlan_id = tmp;
7103       else if (unformat (i, "inner_vlan_id %d", &tmp))
7104         inner_vlan_id = tmp;
7105
7106 #define _(a) else if (unformat (i, #a)) a = 1 ;
7107       foreach_create_subif_bit
7108 #undef _
7109         else
7110         {
7111           clib_warning ("parse error '%U'", format_unformat_error, i);
7112           return -99;
7113         }
7114     }
7115
7116   if (sw_if_index_set == 0)
7117     {
7118       errmsg ("missing interface name or sw_if_index");
7119       return -99;
7120     }
7121
7122   if (sub_id_set == 0)
7123     {
7124       errmsg ("missing sub_id");
7125       return -99;
7126     }
7127   M (CREATE_SUBIF, create_subif);
7128
7129   mp->sw_if_index = ntohl (sw_if_index);
7130   mp->sub_id = ntohl (sub_id);
7131
7132 #define _(a) mp->a = a;
7133   foreach_create_subif_bit;
7134 #undef _
7135
7136   mp->outer_vlan_id = ntohs (outer_vlan_id);
7137   mp->inner_vlan_id = ntohs (inner_vlan_id);
7138
7139   S;
7140   W;
7141   /* NOTREACHED */
7142   return 0;
7143 }
7144
7145 static int
7146 api_oam_add_del (vat_main_t * vam)
7147 {
7148   unformat_input_t *i = vam->input;
7149   vl_api_oam_add_del_t *mp;
7150   f64 timeout;
7151   u32 vrf_id = 0;
7152   u8 is_add = 1;
7153   ip4_address_t src, dst;
7154   u8 src_set = 0;
7155   u8 dst_set = 0;
7156
7157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7158     {
7159       if (unformat (i, "vrf %d", &vrf_id))
7160         ;
7161       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7162         src_set = 1;
7163       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7164         dst_set = 1;
7165       else if (unformat (i, "del"))
7166         is_add = 0;
7167       else
7168         {
7169           clib_warning ("parse error '%U'", format_unformat_error, i);
7170           return -99;
7171         }
7172     }
7173
7174   if (src_set == 0)
7175     {
7176       errmsg ("missing src addr");
7177       return -99;
7178     }
7179
7180   if (dst_set == 0)
7181     {
7182       errmsg ("missing dst addr");
7183       return -99;
7184     }
7185
7186   M (OAM_ADD_DEL, oam_add_del);
7187
7188   mp->vrf_id = ntohl (vrf_id);
7189   mp->is_add = is_add;
7190   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7191   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7192
7193   S;
7194   W;
7195   /* NOTREACHED */
7196   return 0;
7197 }
7198
7199 static int
7200 api_reset_fib (vat_main_t * vam)
7201 {
7202   unformat_input_t *i = vam->input;
7203   vl_api_reset_fib_t *mp;
7204   f64 timeout;
7205   u32 vrf_id = 0;
7206   u8 is_ipv6 = 0;
7207   u8 vrf_id_set = 0;
7208
7209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7210     {
7211       if (unformat (i, "vrf %d", &vrf_id))
7212         vrf_id_set = 1;
7213       else if (unformat (i, "ipv6"))
7214         is_ipv6 = 1;
7215       else
7216         {
7217           clib_warning ("parse error '%U'", format_unformat_error, i);
7218           return -99;
7219         }
7220     }
7221
7222   if (vrf_id_set == 0)
7223     {
7224       errmsg ("missing vrf id");
7225       return -99;
7226     }
7227
7228   M (RESET_FIB, reset_fib);
7229
7230   mp->vrf_id = ntohl (vrf_id);
7231   mp->is_ipv6 = is_ipv6;
7232
7233   S;
7234   W;
7235   /* NOTREACHED */
7236   return 0;
7237 }
7238
7239 static int
7240 api_dhcp_proxy_config (vat_main_t * vam)
7241 {
7242   unformat_input_t *i = vam->input;
7243   vl_api_dhcp_proxy_config_t *mp;
7244   f64 timeout;
7245   u32 vrf_id = 0;
7246   u8 is_add = 1;
7247   u8 insert_cid = 1;
7248   u8 v4_address_set = 0;
7249   u8 v6_address_set = 0;
7250   ip4_address_t v4address;
7251   ip6_address_t v6address;
7252   u8 v4_src_address_set = 0;
7253   u8 v6_src_address_set = 0;
7254   ip4_address_t v4srcaddress;
7255   ip6_address_t v6srcaddress;
7256
7257   /* Parse args required to build the message */
7258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7259     {
7260       if (unformat (i, "del"))
7261         is_add = 0;
7262       else if (unformat (i, "vrf %d", &vrf_id))
7263         ;
7264       else if (unformat (i, "insert-cid %d", &insert_cid))
7265         ;
7266       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7267         v4_address_set = 1;
7268       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7269         v6_address_set = 1;
7270       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7271         v4_src_address_set = 1;
7272       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7273         v6_src_address_set = 1;
7274       else
7275         break;
7276     }
7277
7278   if (v4_address_set && v6_address_set)
7279     {
7280       errmsg ("both v4 and v6 server addresses set");
7281       return -99;
7282     }
7283   if (!v4_address_set && !v6_address_set)
7284     {
7285       errmsg ("no server addresses set");
7286       return -99;
7287     }
7288
7289   if (v4_src_address_set && v6_src_address_set)
7290     {
7291       errmsg ("both v4 and v6  src addresses set");
7292       return -99;
7293     }
7294   if (!v4_src_address_set && !v6_src_address_set)
7295     {
7296       errmsg ("no src addresses set");
7297       return -99;
7298     }
7299
7300   if (!(v4_src_address_set && v4_address_set) &&
7301       !(v6_src_address_set && v6_address_set))
7302     {
7303       errmsg ("no matching server and src addresses set");
7304       return -99;
7305     }
7306
7307   /* Construct the API message */
7308   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7309
7310   mp->insert_circuit_id = insert_cid;
7311   mp->is_add = is_add;
7312   mp->vrf_id = ntohl (vrf_id);
7313   if (v6_address_set)
7314     {
7315       mp->is_ipv6 = 1;
7316       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7317       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7318     }
7319   else
7320     {
7321       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7322       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7323     }
7324
7325   /* send it... */
7326   S;
7327
7328   /* Wait for a reply, return good/bad news  */
7329   W;
7330   /* NOTREACHED */
7331   return 0;
7332 }
7333
7334 static int
7335 api_dhcp_proxy_config_2 (vat_main_t * vam)
7336 {
7337   unformat_input_t *i = vam->input;
7338   vl_api_dhcp_proxy_config_2_t *mp;
7339   f64 timeout;
7340   u32 rx_vrf_id = 0;
7341   u32 server_vrf_id = 0;
7342   u8 is_add = 1;
7343   u8 insert_cid = 1;
7344   u8 v4_address_set = 0;
7345   u8 v6_address_set = 0;
7346   ip4_address_t v4address;
7347   ip6_address_t v6address;
7348   u8 v4_src_address_set = 0;
7349   u8 v6_src_address_set = 0;
7350   ip4_address_t v4srcaddress;
7351   ip6_address_t v6srcaddress;
7352
7353   /* Parse args required to build the message */
7354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7355     {
7356       if (unformat (i, "del"))
7357         is_add = 0;
7358       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7359         ;
7360       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7361         ;
7362       else if (unformat (i, "insert-cid %d", &insert_cid))
7363         ;
7364       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7365         v4_address_set = 1;
7366       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7367         v6_address_set = 1;
7368       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7369         v4_src_address_set = 1;
7370       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7371         v6_src_address_set = 1;
7372       else
7373         break;
7374     }
7375
7376   if (v4_address_set && v6_address_set)
7377     {
7378       errmsg ("both v4 and v6 server addresses set");
7379       return -99;
7380     }
7381   if (!v4_address_set && !v6_address_set)
7382     {
7383       errmsg ("no server addresses set");
7384       return -99;
7385     }
7386
7387   if (v4_src_address_set && v6_src_address_set)
7388     {
7389       errmsg ("both v4 and v6  src addresses set");
7390       return -99;
7391     }
7392   if (!v4_src_address_set && !v6_src_address_set)
7393     {
7394       errmsg ("no src addresses set");
7395       return -99;
7396     }
7397
7398   if (!(v4_src_address_set && v4_address_set) &&
7399       !(v6_src_address_set && v6_address_set))
7400     {
7401       errmsg ("no matching server and src addresses set");
7402       return -99;
7403     }
7404
7405   /* Construct the API message */
7406   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7407
7408   mp->insert_circuit_id = insert_cid;
7409   mp->is_add = is_add;
7410   mp->rx_vrf_id = ntohl (rx_vrf_id);
7411   mp->server_vrf_id = ntohl (server_vrf_id);
7412   if (v6_address_set)
7413     {
7414       mp->is_ipv6 = 1;
7415       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7416       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7417     }
7418   else
7419     {
7420       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7421       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7422     }
7423
7424   /* send it... */
7425   S;
7426
7427   /* Wait for a reply, return good/bad news  */
7428   W;
7429   /* NOTREACHED */
7430   return 0;
7431 }
7432
7433 static int
7434 api_dhcp_proxy_set_vss (vat_main_t * vam)
7435 {
7436   unformat_input_t *i = vam->input;
7437   vl_api_dhcp_proxy_set_vss_t *mp;
7438   f64 timeout;
7439   u8 is_ipv6 = 0;
7440   u8 is_add = 1;
7441   u32 tbl_id;
7442   u8 tbl_id_set = 0;
7443   u32 oui;
7444   u8 oui_set = 0;
7445   u32 fib_id;
7446   u8 fib_id_set = 0;
7447
7448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7449     {
7450       if (unformat (i, "tbl_id %d", &tbl_id))
7451         tbl_id_set = 1;
7452       if (unformat (i, "fib_id %d", &fib_id))
7453         fib_id_set = 1;
7454       if (unformat (i, "oui %d", &oui))
7455         oui_set = 1;
7456       else if (unformat (i, "ipv6"))
7457         is_ipv6 = 1;
7458       else if (unformat (i, "del"))
7459         is_add = 0;
7460       else
7461         {
7462           clib_warning ("parse error '%U'", format_unformat_error, i);
7463           return -99;
7464         }
7465     }
7466
7467   if (tbl_id_set == 0)
7468     {
7469       errmsg ("missing tbl id");
7470       return -99;
7471     }
7472
7473   if (fib_id_set == 0)
7474     {
7475       errmsg ("missing fib id");
7476       return -99;
7477     }
7478   if (oui_set == 0)
7479     {
7480       errmsg ("missing oui");
7481       return -99;
7482     }
7483
7484   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7485   mp->tbl_id = ntohl (tbl_id);
7486   mp->fib_id = ntohl (fib_id);
7487   mp->oui = ntohl (oui);
7488   mp->is_ipv6 = is_ipv6;
7489   mp->is_add = is_add;
7490
7491   S;
7492   W;
7493   /* NOTREACHED */
7494   return 0;
7495 }
7496
7497 static int
7498 api_dhcp_client_config (vat_main_t * vam)
7499 {
7500   unformat_input_t *i = vam->input;
7501   vl_api_dhcp_client_config_t *mp;
7502   f64 timeout;
7503   u32 sw_if_index;
7504   u8 sw_if_index_set = 0;
7505   u8 is_add = 1;
7506   u8 *hostname = 0;
7507   u8 disable_event = 0;
7508
7509   /* Parse args required to build the message */
7510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7511     {
7512       if (unformat (i, "del"))
7513         is_add = 0;
7514       else
7515         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7516         sw_if_index_set = 1;
7517       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7518         sw_if_index_set = 1;
7519       else if (unformat (i, "hostname %s", &hostname))
7520         ;
7521       else if (unformat (i, "disable_event"))
7522         disable_event = 1;
7523       else
7524         break;
7525     }
7526
7527   if (sw_if_index_set == 0)
7528     {
7529       errmsg ("missing interface name or sw_if_index");
7530       return -99;
7531     }
7532
7533   if (vec_len (hostname) > 63)
7534     {
7535       errmsg ("hostname too long");
7536     }
7537   vec_add1 (hostname, 0);
7538
7539   /* Construct the API message */
7540   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7541
7542   mp->sw_if_index = ntohl (sw_if_index);
7543   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7544   vec_free (hostname);
7545   mp->is_add = is_add;
7546   mp->want_dhcp_event = disable_event ? 0 : 1;
7547   mp->pid = getpid ();
7548
7549   /* send it... */
7550   S;
7551
7552   /* Wait for a reply, return good/bad news  */
7553   W;
7554   /* NOTREACHED */
7555   return 0;
7556 }
7557
7558 static int
7559 api_set_ip_flow_hash (vat_main_t * vam)
7560 {
7561   unformat_input_t *i = vam->input;
7562   vl_api_set_ip_flow_hash_t *mp;
7563   f64 timeout;
7564   u32 vrf_id = 0;
7565   u8 is_ipv6 = 0;
7566   u8 vrf_id_set = 0;
7567   u8 src = 0;
7568   u8 dst = 0;
7569   u8 sport = 0;
7570   u8 dport = 0;
7571   u8 proto = 0;
7572   u8 reverse = 0;
7573
7574   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7575     {
7576       if (unformat (i, "vrf %d", &vrf_id))
7577         vrf_id_set = 1;
7578       else if (unformat (i, "ipv6"))
7579         is_ipv6 = 1;
7580       else if (unformat (i, "src"))
7581         src = 1;
7582       else if (unformat (i, "dst"))
7583         dst = 1;
7584       else if (unformat (i, "sport"))
7585         sport = 1;
7586       else if (unformat (i, "dport"))
7587         dport = 1;
7588       else if (unformat (i, "proto"))
7589         proto = 1;
7590       else if (unformat (i, "reverse"))
7591         reverse = 1;
7592
7593       else
7594         {
7595           clib_warning ("parse error '%U'", format_unformat_error, i);
7596           return -99;
7597         }
7598     }
7599
7600   if (vrf_id_set == 0)
7601     {
7602       errmsg ("missing vrf id");
7603       return -99;
7604     }
7605
7606   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7607   mp->src = src;
7608   mp->dst = dst;
7609   mp->sport = sport;
7610   mp->dport = dport;
7611   mp->proto = proto;
7612   mp->reverse = reverse;
7613   mp->vrf_id = ntohl (vrf_id);
7614   mp->is_ipv6 = is_ipv6;
7615
7616   S;
7617   W;
7618   /* NOTREACHED */
7619   return 0;
7620 }
7621
7622 static int
7623 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7624 {
7625   unformat_input_t *i = vam->input;
7626   vl_api_sw_interface_ip6_enable_disable_t *mp;
7627   f64 timeout;
7628   u32 sw_if_index;
7629   u8 sw_if_index_set = 0;
7630   u8 enable = 0;
7631
7632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7633     {
7634       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7635         sw_if_index_set = 1;
7636       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7637         sw_if_index_set = 1;
7638       else if (unformat (i, "enable"))
7639         enable = 1;
7640       else if (unformat (i, "disable"))
7641         enable = 0;
7642       else
7643         {
7644           clib_warning ("parse error '%U'", format_unformat_error, i);
7645           return -99;
7646         }
7647     }
7648
7649   if (sw_if_index_set == 0)
7650     {
7651       errmsg ("missing interface name or sw_if_index");
7652       return -99;
7653     }
7654
7655   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7656
7657   mp->sw_if_index = ntohl (sw_if_index);
7658   mp->enable = enable;
7659
7660   S;
7661   W;
7662   /* NOTREACHED */
7663   return 0;
7664 }
7665
7666 static int
7667 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7668 {
7669   unformat_input_t *i = vam->input;
7670   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7671   f64 timeout;
7672   u32 sw_if_index;
7673   u8 sw_if_index_set = 0;
7674   u8 v6_address_set = 0;
7675   ip6_address_t v6address;
7676
7677   /* Parse args required to build the message */
7678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7679     {
7680       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7681         sw_if_index_set = 1;
7682       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7683         sw_if_index_set = 1;
7684       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
7685         v6_address_set = 1;
7686       else
7687         break;
7688     }
7689
7690   if (sw_if_index_set == 0)
7691     {
7692       errmsg ("missing interface name or sw_if_index");
7693       return -99;
7694     }
7695   if (!v6_address_set)
7696     {
7697       errmsg ("no address set");
7698       return -99;
7699     }
7700
7701   /* Construct the API message */
7702   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7703      sw_interface_ip6_set_link_local_address);
7704
7705   mp->sw_if_index = ntohl (sw_if_index);
7706   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7707
7708   /* send it... */
7709   S;
7710
7711   /* Wait for a reply, return good/bad news  */
7712   W;
7713
7714   /* NOTREACHED */
7715   return 0;
7716 }
7717
7718
7719 static int
7720 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7721 {
7722   unformat_input_t *i = vam->input;
7723   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7724   f64 timeout;
7725   u32 sw_if_index;
7726   u8 sw_if_index_set = 0;
7727   u32 address_length = 0;
7728   u8 v6_address_set = 0;
7729   ip6_address_t v6address;
7730   u8 use_default = 0;
7731   u8 no_advertise = 0;
7732   u8 off_link = 0;
7733   u8 no_autoconfig = 0;
7734   u8 no_onlink = 0;
7735   u8 is_no = 0;
7736   u32 val_lifetime = 0;
7737   u32 pref_lifetime = 0;
7738
7739   /* Parse args required to build the message */
7740   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7741     {
7742       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7743         sw_if_index_set = 1;
7744       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7745         sw_if_index_set = 1;
7746       else if (unformat (i, "%U/%d",
7747                          unformat_ip6_address, &v6address, &address_length))
7748         v6_address_set = 1;
7749       else if (unformat (i, "val_life %d", &val_lifetime))
7750         ;
7751       else if (unformat (i, "pref_life %d", &pref_lifetime))
7752         ;
7753       else if (unformat (i, "def"))
7754         use_default = 1;
7755       else if (unformat (i, "noadv"))
7756         no_advertise = 1;
7757       else if (unformat (i, "offl"))
7758         off_link = 1;
7759       else if (unformat (i, "noauto"))
7760         no_autoconfig = 1;
7761       else if (unformat (i, "nolink"))
7762         no_onlink = 1;
7763       else if (unformat (i, "isno"))
7764         is_no = 1;
7765       else
7766         {
7767           clib_warning ("parse error '%U'", format_unformat_error, i);
7768           return -99;
7769         }
7770     }
7771
7772   if (sw_if_index_set == 0)
7773     {
7774       errmsg ("missing interface name or sw_if_index");
7775       return -99;
7776     }
7777   if (!v6_address_set)
7778     {
7779       errmsg ("no address set");
7780       return -99;
7781     }
7782
7783   /* Construct the API message */
7784   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7785
7786   mp->sw_if_index = ntohl (sw_if_index);
7787   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7788   mp->address_length = address_length;
7789   mp->use_default = use_default;
7790   mp->no_advertise = no_advertise;
7791   mp->off_link = off_link;
7792   mp->no_autoconfig = no_autoconfig;
7793   mp->no_onlink = no_onlink;
7794   mp->is_no = is_no;
7795   mp->val_lifetime = ntohl (val_lifetime);
7796   mp->pref_lifetime = ntohl (pref_lifetime);
7797
7798   /* send it... */
7799   S;
7800
7801   /* Wait for a reply, return good/bad news  */
7802   W;
7803
7804   /* NOTREACHED */
7805   return 0;
7806 }
7807
7808 static int
7809 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7810 {
7811   unformat_input_t *i = vam->input;
7812   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7813   f64 timeout;
7814   u32 sw_if_index;
7815   u8 sw_if_index_set = 0;
7816   u8 suppress = 0;
7817   u8 managed = 0;
7818   u8 other = 0;
7819   u8 ll_option = 0;
7820   u8 send_unicast = 0;
7821   u8 cease = 0;
7822   u8 is_no = 0;
7823   u8 default_router = 0;
7824   u32 max_interval = 0;
7825   u32 min_interval = 0;
7826   u32 lifetime = 0;
7827   u32 initial_count = 0;
7828   u32 initial_interval = 0;
7829
7830
7831   /* Parse args required to build the message */
7832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7833     {
7834       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7835         sw_if_index_set = 1;
7836       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7837         sw_if_index_set = 1;
7838       else if (unformat (i, "maxint %d", &max_interval))
7839         ;
7840       else if (unformat (i, "minint %d", &min_interval))
7841         ;
7842       else if (unformat (i, "life %d", &lifetime))
7843         ;
7844       else if (unformat (i, "count %d", &initial_count))
7845         ;
7846       else if (unformat (i, "interval %d", &initial_interval))
7847         ;
7848       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7849         suppress = 1;
7850       else if (unformat (i, "managed"))
7851         managed = 1;
7852       else if (unformat (i, "other"))
7853         other = 1;
7854       else if (unformat (i, "ll"))
7855         ll_option = 1;
7856       else if (unformat (i, "send"))
7857         send_unicast = 1;
7858       else if (unformat (i, "cease"))
7859         cease = 1;
7860       else if (unformat (i, "isno"))
7861         is_no = 1;
7862       else if (unformat (i, "def"))
7863         default_router = 1;
7864       else
7865         {
7866           clib_warning ("parse error '%U'", format_unformat_error, i);
7867           return -99;
7868         }
7869     }
7870
7871   if (sw_if_index_set == 0)
7872     {
7873       errmsg ("missing interface name or sw_if_index");
7874       return -99;
7875     }
7876
7877   /* Construct the API message */
7878   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7879
7880   mp->sw_if_index = ntohl (sw_if_index);
7881   mp->max_interval = ntohl (max_interval);
7882   mp->min_interval = ntohl (min_interval);
7883   mp->lifetime = ntohl (lifetime);
7884   mp->initial_count = ntohl (initial_count);
7885   mp->initial_interval = ntohl (initial_interval);
7886   mp->suppress = suppress;
7887   mp->managed = managed;
7888   mp->other = other;
7889   mp->ll_option = ll_option;
7890   mp->send_unicast = send_unicast;
7891   mp->cease = cease;
7892   mp->is_no = is_no;
7893   mp->default_router = default_router;
7894
7895   /* send it... */
7896   S;
7897
7898   /* Wait for a reply, return good/bad news  */
7899   W;
7900
7901   /* NOTREACHED */
7902   return 0;
7903 }
7904
7905 static int
7906 api_set_arp_neighbor_limit (vat_main_t * vam)
7907 {
7908   unformat_input_t *i = vam->input;
7909   vl_api_set_arp_neighbor_limit_t *mp;
7910   f64 timeout;
7911   u32 arp_nbr_limit;
7912   u8 limit_set = 0;
7913   u8 is_ipv6 = 0;
7914
7915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7916     {
7917       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7918         limit_set = 1;
7919       else if (unformat (i, "ipv6"))
7920         is_ipv6 = 1;
7921       else
7922         {
7923           clib_warning ("parse error '%U'", format_unformat_error, i);
7924           return -99;
7925         }
7926     }
7927
7928   if (limit_set == 0)
7929     {
7930       errmsg ("missing limit value");
7931       return -99;
7932     }
7933
7934   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7935
7936   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7937   mp->is_ipv6 = is_ipv6;
7938
7939   S;
7940   W;
7941   /* NOTREACHED */
7942   return 0;
7943 }
7944
7945 static int
7946 api_l2_patch_add_del (vat_main_t * vam)
7947 {
7948   unformat_input_t *i = vam->input;
7949   vl_api_l2_patch_add_del_t *mp;
7950   f64 timeout;
7951   u32 rx_sw_if_index;
7952   u8 rx_sw_if_index_set = 0;
7953   u32 tx_sw_if_index;
7954   u8 tx_sw_if_index_set = 0;
7955   u8 is_add = 1;
7956
7957   /* Parse args required to build the message */
7958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7959     {
7960       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7961         rx_sw_if_index_set = 1;
7962       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7963         tx_sw_if_index_set = 1;
7964       else if (unformat (i, "rx"))
7965         {
7966           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7967             {
7968               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7969                             &rx_sw_if_index))
7970                 rx_sw_if_index_set = 1;
7971             }
7972           else
7973             break;
7974         }
7975       else if (unformat (i, "tx"))
7976         {
7977           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7978             {
7979               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7980                             &tx_sw_if_index))
7981                 tx_sw_if_index_set = 1;
7982             }
7983           else
7984             break;
7985         }
7986       else if (unformat (i, "del"))
7987         is_add = 0;
7988       else
7989         break;
7990     }
7991
7992   if (rx_sw_if_index_set == 0)
7993     {
7994       errmsg ("missing rx interface name or rx_sw_if_index");
7995       return -99;
7996     }
7997
7998   if (tx_sw_if_index_set == 0)
7999     {
8000       errmsg ("missing tx interface name or tx_sw_if_index");
8001       return -99;
8002     }
8003
8004   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
8005
8006   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
8007   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
8008   mp->is_add = is_add;
8009
8010   S;
8011   W;
8012   /* NOTREACHED */
8013   return 0;
8014 }
8015
8016 static int
8017 api_ioam_enable (vat_main_t * vam)
8018 {
8019   unformat_input_t *input = vam->input;
8020   vl_api_ioam_enable_t *mp;
8021   f64 timeout;
8022   u32 id = 0;
8023   int has_trace_option = 0;
8024   int has_pot_option = 0;
8025   int has_seqno_option = 0;
8026   int has_analyse_option = 0;
8027
8028   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8029     {
8030       if (unformat (input, "trace"))
8031         has_trace_option = 1;
8032       else if (unformat (input, "pot"))
8033         has_pot_option = 1;
8034       else if (unformat (input, "seqno"))
8035         has_seqno_option = 1;
8036       else if (unformat (input, "analyse"))
8037         has_analyse_option = 1;
8038       else
8039         break;
8040     }
8041   M (IOAM_ENABLE, ioam_enable);
8042   mp->id = htons (id);
8043   mp->seqno = has_seqno_option;
8044   mp->analyse = has_analyse_option;
8045   mp->pot_enable = has_pot_option;
8046   mp->trace_enable = has_trace_option;
8047
8048   S;
8049   W;
8050
8051   return (0);
8052
8053 }
8054
8055
8056 static int
8057 api_ioam_disable (vat_main_t * vam)
8058 {
8059   vl_api_ioam_disable_t *mp;
8060   f64 timeout;
8061
8062   M (IOAM_DISABLE, ioam_disable);
8063   S;
8064   W;
8065   return 0;
8066 }
8067
8068 static int
8069 api_sr_tunnel_add_del (vat_main_t * vam)
8070 {
8071   unformat_input_t *i = vam->input;
8072   vl_api_sr_tunnel_add_del_t *mp;
8073   f64 timeout;
8074   int is_del = 0;
8075   int pl_index;
8076   ip6_address_t src_address;
8077   int src_address_set = 0;
8078   ip6_address_t dst_address;
8079   u32 dst_mask_width;
8080   int dst_address_set = 0;
8081   u16 flags = 0;
8082   u32 rx_table_id = 0;
8083   u32 tx_table_id = 0;
8084   ip6_address_t *segments = 0;
8085   ip6_address_t *this_seg;
8086   ip6_address_t *tags = 0;
8087   ip6_address_t *this_tag;
8088   ip6_address_t next_address, tag;
8089   u8 *name = 0;
8090   u8 *policy_name = 0;
8091
8092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8093     {
8094       if (unformat (i, "del"))
8095         is_del = 1;
8096       else if (unformat (i, "name %s", &name))
8097         ;
8098       else if (unformat (i, "policy %s", &policy_name))
8099         ;
8100       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8101         ;
8102       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8103         ;
8104       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8105         src_address_set = 1;
8106       else if (unformat (i, "dst %U/%d",
8107                          unformat_ip6_address, &dst_address, &dst_mask_width))
8108         dst_address_set = 1;
8109       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8110         {
8111           vec_add2 (segments, this_seg, 1);
8112           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8113                        sizeof (*this_seg));
8114         }
8115       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8116         {
8117           vec_add2 (tags, this_tag, 1);
8118           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8119         }
8120       else if (unformat (i, "clean"))
8121         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8122       else if (unformat (i, "protected"))
8123         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8124       else if (unformat (i, "InPE %d", &pl_index))
8125         {
8126           if (pl_index <= 0 || pl_index > 4)
8127             {
8128             pl_index_range_error:
8129               errmsg ("pl index %d out of range", pl_index);
8130               return -99;
8131             }
8132           flags |=
8133             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8134         }
8135       else if (unformat (i, "EgPE %d", &pl_index))
8136         {
8137           if (pl_index <= 0 || pl_index > 4)
8138             goto pl_index_range_error;
8139           flags |=
8140             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8141         }
8142       else if (unformat (i, "OrgSrc %d", &pl_index))
8143         {
8144           if (pl_index <= 0 || pl_index > 4)
8145             goto pl_index_range_error;
8146           flags |=
8147             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8148         }
8149       else
8150         break;
8151     }
8152
8153   if (!src_address_set)
8154     {
8155       errmsg ("src address required");
8156       return -99;
8157     }
8158
8159   if (!dst_address_set)
8160     {
8161       errmsg ("dst address required");
8162       return -99;
8163     }
8164
8165   if (!segments)
8166     {
8167       errmsg ("at least one sr segment required");
8168       return -99;
8169     }
8170
8171   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
8172       vec_len (segments) * sizeof (ip6_address_t)
8173       + vec_len (tags) * sizeof (ip6_address_t));
8174
8175   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8176   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8177   mp->dst_mask_width = dst_mask_width;
8178   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8179   mp->n_segments = vec_len (segments);
8180   mp->n_tags = vec_len (tags);
8181   mp->is_add = is_del == 0;
8182   clib_memcpy (mp->segs_and_tags, segments,
8183                vec_len (segments) * sizeof (ip6_address_t));
8184   clib_memcpy (mp->segs_and_tags +
8185                vec_len (segments) * sizeof (ip6_address_t), tags,
8186                vec_len (tags) * sizeof (ip6_address_t));
8187
8188   mp->outer_vrf_id = ntohl (rx_table_id);
8189   mp->inner_vrf_id = ntohl (tx_table_id);
8190   memcpy (mp->name, name, vec_len (name));
8191   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8192
8193   vec_free (segments);
8194   vec_free (tags);
8195
8196   S;
8197   W;
8198   /* NOTREACHED */
8199 }
8200
8201 static int
8202 api_sr_policy_add_del (vat_main_t * vam)
8203 {
8204   unformat_input_t *input = vam->input;
8205   vl_api_sr_policy_add_del_t *mp;
8206   f64 timeout;
8207   int is_del = 0;
8208   u8 *name = 0;
8209   u8 *tunnel_name = 0;
8210   u8 **tunnel_names = 0;
8211
8212   int name_set = 0;
8213   int tunnel_set = 0;
8214   int j = 0;
8215   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8216   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8217
8218   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8219     {
8220       if (unformat (input, "del"))
8221         is_del = 1;
8222       else if (unformat (input, "name %s", &name))
8223         name_set = 1;
8224       else if (unformat (input, "tunnel %s", &tunnel_name))
8225         {
8226           if (tunnel_name)
8227             {
8228               vec_add1 (tunnel_names, tunnel_name);
8229               /* For serializer:
8230                  - length = #bytes to store in serial vector
8231                  - +1 = byte to store that length
8232                */
8233               tunnel_names_length += (vec_len (tunnel_name) + 1);
8234               tunnel_set = 1;
8235               tunnel_name = 0;
8236             }
8237         }
8238       else
8239         break;
8240     }
8241
8242   if (!name_set)
8243     {
8244       errmsg ("policy name required");
8245       return -99;
8246     }
8247
8248   if ((!tunnel_set) && (!is_del))
8249     {
8250       errmsg ("tunnel name required");
8251       return -99;
8252     }
8253
8254   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8255
8256
8257
8258   mp->is_add = !is_del;
8259
8260   memcpy (mp->name, name, vec_len (name));
8261   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8262   u8 *serial_orig = 0;
8263   vec_validate (serial_orig, tunnel_names_length);
8264   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8265   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8266
8267   for (j = 0; j < vec_len (tunnel_names); j++)
8268     {
8269       tun_name_len = vec_len (tunnel_names[j]);
8270       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8271       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8272       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8273       serial_orig += tun_name_len;      // Advance past the copy
8274     }
8275   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8276
8277   vec_free (tunnel_names);
8278   vec_free (tunnel_name);
8279
8280   S;
8281   W;
8282   /* NOTREACHED */
8283 }
8284
8285 static int
8286 api_sr_multicast_map_add_del (vat_main_t * vam)
8287 {
8288   unformat_input_t *input = vam->input;
8289   vl_api_sr_multicast_map_add_del_t *mp;
8290   f64 timeout;
8291   int is_del = 0;
8292   ip6_address_t multicast_address;
8293   u8 *policy_name = 0;
8294   int multicast_address_set = 0;
8295
8296   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8297     {
8298       if (unformat (input, "del"))
8299         is_del = 1;
8300       else
8301         if (unformat
8302             (input, "address %U", unformat_ip6_address, &multicast_address))
8303         multicast_address_set = 1;
8304       else if (unformat (input, "sr-policy %s", &policy_name))
8305         ;
8306       else
8307         break;
8308     }
8309
8310   if (!is_del && !policy_name)
8311     {
8312       errmsg ("sr-policy name required");
8313       return -99;
8314     }
8315
8316
8317   if (!multicast_address_set)
8318     {
8319       errmsg ("address required");
8320       return -99;
8321     }
8322
8323   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8324
8325   mp->is_add = !is_del;
8326   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8327   clib_memcpy (mp->multicast_address, &multicast_address,
8328                sizeof (mp->multicast_address));
8329
8330
8331   vec_free (policy_name);
8332
8333   S;
8334   W;
8335   /* NOTREACHED */
8336 }
8337
8338
8339 #define foreach_tcp_proto_field                 \
8340 _(src_port)                                     \
8341 _(dst_port)
8342
8343 #define foreach_udp_proto_field                 \
8344 _(src_port)                                     \
8345 _(dst_port)
8346
8347 #define foreach_ip4_proto_field                 \
8348 _(src_address)                                  \
8349 _(dst_address)                                  \
8350 _(tos)                                          \
8351 _(length)                                       \
8352 _(fragment_id)                                  \
8353 _(ttl)                                          \
8354 _(protocol)                                     \
8355 _(checksum)
8356
8357 uword
8358 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8359 {
8360   u8 **maskp = va_arg (*args, u8 **);
8361   u8 *mask = 0;
8362   u8 found_something = 0;
8363   tcp_header_t *tcp;
8364
8365 #define _(a) u8 a=0;
8366   foreach_tcp_proto_field;
8367 #undef _
8368
8369   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8370     {
8371       if (0);
8372 #define _(a) else if (unformat (input, #a)) a=1;
8373       foreach_tcp_proto_field
8374 #undef _
8375         else
8376         break;
8377     }
8378
8379 #define _(a) found_something += a;
8380   foreach_tcp_proto_field;
8381 #undef _
8382
8383   if (found_something == 0)
8384     return 0;
8385
8386   vec_validate (mask, sizeof (*tcp) - 1);
8387
8388   tcp = (tcp_header_t *) mask;
8389
8390 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8391   foreach_tcp_proto_field;
8392 #undef _
8393
8394   *maskp = mask;
8395   return 1;
8396 }
8397
8398 uword
8399 unformat_udp_mask (unformat_input_t * input, va_list * args)
8400 {
8401   u8 **maskp = va_arg (*args, u8 **);
8402   u8 *mask = 0;
8403   u8 found_something = 0;
8404   udp_header_t *udp;
8405
8406 #define _(a) u8 a=0;
8407   foreach_udp_proto_field;
8408 #undef _
8409
8410   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8411     {
8412       if (0);
8413 #define _(a) else if (unformat (input, #a)) a=1;
8414       foreach_udp_proto_field
8415 #undef _
8416         else
8417         break;
8418     }
8419
8420 #define _(a) found_something += a;
8421   foreach_udp_proto_field;
8422 #undef _
8423
8424   if (found_something == 0)
8425     return 0;
8426
8427   vec_validate (mask, sizeof (*udp) - 1);
8428
8429   udp = (udp_header_t *) mask;
8430
8431 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8432   foreach_udp_proto_field;
8433 #undef _
8434
8435   *maskp = mask;
8436   return 1;
8437 }
8438
8439 typedef struct
8440 {
8441   u16 src_port, dst_port;
8442 } tcpudp_header_t;
8443
8444 uword
8445 unformat_l4_mask (unformat_input_t * input, va_list * args)
8446 {
8447   u8 **maskp = va_arg (*args, u8 **);
8448   u16 src_port = 0, dst_port = 0;
8449   tcpudp_header_t *tcpudp;
8450
8451   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8452     {
8453       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8454         return 1;
8455       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8456         return 1;
8457       else if (unformat (input, "src_port"))
8458         src_port = 0xFFFF;
8459       else if (unformat (input, "dst_port"))
8460         dst_port = 0xFFFF;
8461       else
8462         return 0;
8463     }
8464
8465   if (!src_port && !dst_port)
8466     return 0;
8467
8468   u8 *mask = 0;
8469   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8470
8471   tcpudp = (tcpudp_header_t *) mask;
8472   tcpudp->src_port = src_port;
8473   tcpudp->dst_port = dst_port;
8474
8475   *maskp = mask;
8476
8477   return 1;
8478 }
8479
8480 uword
8481 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8482 {
8483   u8 **maskp = va_arg (*args, u8 **);
8484   u8 *mask = 0;
8485   u8 found_something = 0;
8486   ip4_header_t *ip;
8487
8488 #define _(a) u8 a=0;
8489   foreach_ip4_proto_field;
8490 #undef _
8491   u8 version = 0;
8492   u8 hdr_length = 0;
8493
8494
8495   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8496     {
8497       if (unformat (input, "version"))
8498         version = 1;
8499       else if (unformat (input, "hdr_length"))
8500         hdr_length = 1;
8501       else if (unformat (input, "src"))
8502         src_address = 1;
8503       else if (unformat (input, "dst"))
8504         dst_address = 1;
8505       else if (unformat (input, "proto"))
8506         protocol = 1;
8507
8508 #define _(a) else if (unformat (input, #a)) a=1;
8509       foreach_ip4_proto_field
8510 #undef _
8511         else
8512         break;
8513     }
8514
8515 #define _(a) found_something += a;
8516   foreach_ip4_proto_field;
8517 #undef _
8518
8519   if (found_something == 0)
8520     return 0;
8521
8522   vec_validate (mask, sizeof (*ip) - 1);
8523
8524   ip = (ip4_header_t *) mask;
8525
8526 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8527   foreach_ip4_proto_field;
8528 #undef _
8529
8530   ip->ip_version_and_header_length = 0;
8531
8532   if (version)
8533     ip->ip_version_and_header_length |= 0xF0;
8534
8535   if (hdr_length)
8536     ip->ip_version_and_header_length |= 0x0F;
8537
8538   *maskp = mask;
8539   return 1;
8540 }
8541
8542 #define foreach_ip6_proto_field                 \
8543 _(src_address)                                  \
8544 _(dst_address)                                  \
8545 _(payload_length)                               \
8546 _(hop_limit)                                    \
8547 _(protocol)
8548
8549 uword
8550 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8551 {
8552   u8 **maskp = va_arg (*args, u8 **);
8553   u8 *mask = 0;
8554   u8 found_something = 0;
8555   ip6_header_t *ip;
8556   u32 ip_version_traffic_class_and_flow_label;
8557
8558 #define _(a) u8 a=0;
8559   foreach_ip6_proto_field;
8560 #undef _
8561   u8 version = 0;
8562   u8 traffic_class = 0;
8563   u8 flow_label = 0;
8564
8565   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8566     {
8567       if (unformat (input, "version"))
8568         version = 1;
8569       else if (unformat (input, "traffic-class"))
8570         traffic_class = 1;
8571       else if (unformat (input, "flow-label"))
8572         flow_label = 1;
8573       else if (unformat (input, "src"))
8574         src_address = 1;
8575       else if (unformat (input, "dst"))
8576         dst_address = 1;
8577       else if (unformat (input, "proto"))
8578         protocol = 1;
8579
8580 #define _(a) else if (unformat (input, #a)) a=1;
8581       foreach_ip6_proto_field
8582 #undef _
8583         else
8584         break;
8585     }
8586
8587 #define _(a) found_something += a;
8588   foreach_ip6_proto_field;
8589 #undef _
8590
8591   if (found_something == 0)
8592     return 0;
8593
8594   vec_validate (mask, sizeof (*ip) - 1);
8595
8596   ip = (ip6_header_t *) mask;
8597
8598 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8599   foreach_ip6_proto_field;
8600 #undef _
8601
8602   ip_version_traffic_class_and_flow_label = 0;
8603
8604   if (version)
8605     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8606
8607   if (traffic_class)
8608     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8609
8610   if (flow_label)
8611     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8612
8613   ip->ip_version_traffic_class_and_flow_label =
8614     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8615
8616   *maskp = mask;
8617   return 1;
8618 }
8619
8620 uword
8621 unformat_l3_mask (unformat_input_t * input, va_list * args)
8622 {
8623   u8 **maskp = va_arg (*args, u8 **);
8624
8625   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8626     {
8627       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8628         return 1;
8629       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8630         return 1;
8631       else
8632         break;
8633     }
8634   return 0;
8635 }
8636
8637 uword
8638 unformat_l2_mask (unformat_input_t * input, va_list * args)
8639 {
8640   u8 **maskp = va_arg (*args, u8 **);
8641   u8 *mask = 0;
8642   u8 src = 0;
8643   u8 dst = 0;
8644   u8 proto = 0;
8645   u8 tag1 = 0;
8646   u8 tag2 = 0;
8647   u8 ignore_tag1 = 0;
8648   u8 ignore_tag2 = 0;
8649   u8 cos1 = 0;
8650   u8 cos2 = 0;
8651   u8 dot1q = 0;
8652   u8 dot1ad = 0;
8653   int len = 14;
8654
8655   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8656     {
8657       if (unformat (input, "src"))
8658         src = 1;
8659       else if (unformat (input, "dst"))
8660         dst = 1;
8661       else if (unformat (input, "proto"))
8662         proto = 1;
8663       else if (unformat (input, "tag1"))
8664         tag1 = 1;
8665       else if (unformat (input, "tag2"))
8666         tag2 = 1;
8667       else if (unformat (input, "ignore-tag1"))
8668         ignore_tag1 = 1;
8669       else if (unformat (input, "ignore-tag2"))
8670         ignore_tag2 = 1;
8671       else if (unformat (input, "cos1"))
8672         cos1 = 1;
8673       else if (unformat (input, "cos2"))
8674         cos2 = 1;
8675       else if (unformat (input, "dot1q"))
8676         dot1q = 1;
8677       else if (unformat (input, "dot1ad"))
8678         dot1ad = 1;
8679       else
8680         break;
8681     }
8682   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8683        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8684     return 0;
8685
8686   if (tag1 || ignore_tag1 || cos1 || dot1q)
8687     len = 18;
8688   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8689     len = 22;
8690
8691   vec_validate (mask, len - 1);
8692
8693   if (dst)
8694     memset (mask, 0xff, 6);
8695
8696   if (src)
8697     memset (mask + 6, 0xff, 6);
8698
8699   if (tag2 || dot1ad)
8700     {
8701       /* inner vlan tag */
8702       if (tag2)
8703         {
8704           mask[19] = 0xff;
8705           mask[18] = 0x0f;
8706         }
8707       if (cos2)
8708         mask[18] |= 0xe0;
8709       if (proto)
8710         mask[21] = mask[20] = 0xff;
8711       if (tag1)
8712         {
8713           mask[15] = 0xff;
8714           mask[14] = 0x0f;
8715         }
8716       if (cos1)
8717         mask[14] |= 0xe0;
8718       *maskp = mask;
8719       return 1;
8720     }
8721   if (tag1 | dot1q)
8722     {
8723       if (tag1)
8724         {
8725           mask[15] = 0xff;
8726           mask[14] = 0x0f;
8727         }
8728       if (cos1)
8729         mask[14] |= 0xe0;
8730       if (proto)
8731         mask[16] = mask[17] = 0xff;
8732
8733       *maskp = mask;
8734       return 1;
8735     }
8736   if (cos2)
8737     mask[18] |= 0xe0;
8738   if (cos1)
8739     mask[14] |= 0xe0;
8740   if (proto)
8741     mask[12] = mask[13] = 0xff;
8742
8743   *maskp = mask;
8744   return 1;
8745 }
8746
8747 uword
8748 unformat_classify_mask (unformat_input_t * input, va_list * args)
8749 {
8750   u8 **maskp = va_arg (*args, u8 **);
8751   u32 *skipp = va_arg (*args, u32 *);
8752   u32 *matchp = va_arg (*args, u32 *);
8753   u32 match;
8754   u8 *mask = 0;
8755   u8 *l2 = 0;
8756   u8 *l3 = 0;
8757   u8 *l4 = 0;
8758   int i;
8759
8760   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8761     {
8762       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8763         ;
8764       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8765         ;
8766       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8767         ;
8768       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8769         ;
8770       else
8771         break;
8772     }
8773
8774   if (l4 && !l3)
8775     {
8776       vec_free (mask);
8777       vec_free (l2);
8778       vec_free (l4);
8779       return 0;
8780     }
8781
8782   if (mask || l2 || l3 || l4)
8783     {
8784       if (l2 || l3 || l4)
8785         {
8786           /* "With a free Ethernet header in every package" */
8787           if (l2 == 0)
8788             vec_validate (l2, 13);
8789           mask = l2;
8790           if (vec_len (l3))
8791             {
8792               vec_append (mask, l3);
8793               vec_free (l3);
8794             }
8795           if (vec_len (l4))
8796             {
8797               vec_append (mask, l4);
8798               vec_free (l4);
8799             }
8800         }
8801
8802       /* Scan forward looking for the first significant mask octet */
8803       for (i = 0; i < vec_len (mask); i++)
8804         if (mask[i])
8805           break;
8806
8807       /* compute (skip, match) params */
8808       *skipp = i / sizeof (u32x4);
8809       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8810
8811       /* Pad mask to an even multiple of the vector size */
8812       while (vec_len (mask) % sizeof (u32x4))
8813         vec_add1 (mask, 0);
8814
8815       match = vec_len (mask) / sizeof (u32x4);
8816
8817       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8818         {
8819           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8820           if (*tmp || *(tmp + 1))
8821             break;
8822           match--;
8823         }
8824       if (match == 0)
8825         clib_warning ("BUG: match 0");
8826
8827       _vec_len (mask) = match * sizeof (u32x4);
8828
8829       *matchp = match;
8830       *maskp = mask;
8831
8832       return 1;
8833     }
8834
8835   return 0;
8836 }
8837
8838 #define foreach_l2_next                         \
8839 _(drop, DROP)                                   \
8840 _(ethernet, ETHERNET_INPUT)                     \
8841 _(ip4, IP4_INPUT)                               \
8842 _(ip6, IP6_INPUT)
8843
8844 uword
8845 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8846 {
8847   u32 *miss_next_indexp = va_arg (*args, u32 *);
8848   u32 next_index = 0;
8849   u32 tmp;
8850
8851 #define _(n,N) \
8852   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8853   foreach_l2_next;
8854 #undef _
8855
8856   if (unformat (input, "%d", &tmp))
8857     {
8858       next_index = tmp;
8859       goto out;
8860     }
8861
8862   return 0;
8863
8864 out:
8865   *miss_next_indexp = next_index;
8866   return 1;
8867 }
8868
8869 #define foreach_ip_next                         \
8870 _(drop, DROP)                                   \
8871 _(local, LOCAL)                                 \
8872 _(rewrite, REWRITE)
8873
8874 uword
8875 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8876 {
8877   u32 *miss_next_indexp = va_arg (*args, u32 *);
8878   u32 next_index = 0;
8879   u32 tmp;
8880
8881 #define _(n,N) \
8882   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8883   foreach_ip_next;
8884 #undef _
8885
8886   if (unformat (input, "%d", &tmp))
8887     {
8888       next_index = tmp;
8889       goto out;
8890     }
8891
8892   return 0;
8893
8894 out:
8895   *miss_next_indexp = next_index;
8896   return 1;
8897 }
8898
8899 #define foreach_acl_next                        \
8900 _(deny, DENY)
8901
8902 uword
8903 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8904 {
8905   u32 *miss_next_indexp = va_arg (*args, u32 *);
8906   u32 next_index = 0;
8907   u32 tmp;
8908
8909 #define _(n,N) \
8910   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8911   foreach_acl_next;
8912 #undef _
8913
8914   if (unformat (input, "permit"))
8915     {
8916       next_index = ~0;
8917       goto out;
8918     }
8919   else if (unformat (input, "%d", &tmp))
8920     {
8921       next_index = tmp;
8922       goto out;
8923     }
8924
8925   return 0;
8926
8927 out:
8928   *miss_next_indexp = next_index;
8929   return 1;
8930 }
8931
8932 uword
8933 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8934 {
8935   u32 *r = va_arg (*args, u32 *);
8936
8937   if (unformat (input, "conform-color"))
8938     *r = POLICE_CONFORM;
8939   else if (unformat (input, "exceed-color"))
8940     *r = POLICE_EXCEED;
8941   else
8942     return 0;
8943
8944   return 1;
8945 }
8946
8947 static int
8948 api_classify_add_del_table (vat_main_t * vam)
8949 {
8950   unformat_input_t *i = vam->input;
8951   vl_api_classify_add_del_table_t *mp;
8952
8953   u32 nbuckets = 2;
8954   u32 skip = ~0;
8955   u32 match = ~0;
8956   int is_add = 1;
8957   int del_chain = 0;
8958   u32 table_index = ~0;
8959   u32 next_table_index = ~0;
8960   u32 miss_next_index = ~0;
8961   u32 memory_size = 32 << 20;
8962   u8 *mask = 0;
8963   f64 timeout;
8964   u32 current_data_flag = 0;
8965   int current_data_offset = 0;
8966
8967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8968     {
8969       if (unformat (i, "del"))
8970         is_add = 0;
8971       else if (unformat (i, "del-chain"))
8972         {
8973           is_add = 0;
8974           del_chain = 1;
8975         }
8976       else if (unformat (i, "buckets %d", &nbuckets))
8977         ;
8978       else if (unformat (i, "memory_size %d", &memory_size))
8979         ;
8980       else if (unformat (i, "skip %d", &skip))
8981         ;
8982       else if (unformat (i, "match %d", &match))
8983         ;
8984       else if (unformat (i, "table %d", &table_index))
8985         ;
8986       else if (unformat (i, "mask %U", unformat_classify_mask,
8987                          &mask, &skip, &match))
8988         ;
8989       else if (unformat (i, "next-table %d", &next_table_index))
8990         ;
8991       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8992                          &miss_next_index))
8993         ;
8994       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8995                          &miss_next_index))
8996         ;
8997       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8998                          &miss_next_index))
8999         ;
9000       else if (unformat (i, "current-data-flag %d", &current_data_flag))
9001         ;
9002       else if (unformat (i, "current-data-offset %d", &current_data_offset))
9003         ;
9004       else
9005         break;
9006     }
9007
9008   if (is_add && mask == 0)
9009     {
9010       errmsg ("Mask required");
9011       return -99;
9012     }
9013
9014   if (is_add && skip == ~0)
9015     {
9016       errmsg ("skip count required");
9017       return -99;
9018     }
9019
9020   if (is_add && match == ~0)
9021     {
9022       errmsg ("match count required");
9023       return -99;
9024     }
9025
9026   if (!is_add && table_index == ~0)
9027     {
9028       errmsg ("table index required for delete");
9029       return -99;
9030     }
9031
9032   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
9033
9034   mp->is_add = is_add;
9035   mp->del_chain = del_chain;
9036   mp->table_index = ntohl (table_index);
9037   mp->nbuckets = ntohl (nbuckets);
9038   mp->memory_size = ntohl (memory_size);
9039   mp->skip_n_vectors = ntohl (skip);
9040   mp->match_n_vectors = ntohl (match);
9041   mp->next_table_index = ntohl (next_table_index);
9042   mp->miss_next_index = ntohl (miss_next_index);
9043   mp->current_data_flag = ntohl (current_data_flag);
9044   mp->current_data_offset = ntohl (current_data_offset);
9045   clib_memcpy (mp->mask, mask, vec_len (mask));
9046
9047   vec_free (mask);
9048
9049   S;
9050   W;
9051   /* NOTREACHED */
9052 }
9053
9054 uword
9055 unformat_l4_match (unformat_input_t * input, va_list * args)
9056 {
9057   u8 **matchp = va_arg (*args, u8 **);
9058
9059   u8 *proto_header = 0;
9060   int src_port = 0;
9061   int dst_port = 0;
9062
9063   tcpudp_header_t h;
9064
9065   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9066     {
9067       if (unformat (input, "src_port %d", &src_port))
9068         ;
9069       else if (unformat (input, "dst_port %d", &dst_port))
9070         ;
9071       else
9072         return 0;
9073     }
9074
9075   h.src_port = clib_host_to_net_u16 (src_port);
9076   h.dst_port = clib_host_to_net_u16 (dst_port);
9077   vec_validate (proto_header, sizeof (h) - 1);
9078   memcpy (proto_header, &h, sizeof (h));
9079
9080   *matchp = proto_header;
9081
9082   return 1;
9083 }
9084
9085 uword
9086 unformat_ip4_match (unformat_input_t * input, va_list * args)
9087 {
9088   u8 **matchp = va_arg (*args, u8 **);
9089   u8 *match = 0;
9090   ip4_header_t *ip;
9091   int version = 0;
9092   u32 version_val;
9093   int hdr_length = 0;
9094   u32 hdr_length_val;
9095   int src = 0, dst = 0;
9096   ip4_address_t src_val, dst_val;
9097   int proto = 0;
9098   u32 proto_val;
9099   int tos = 0;
9100   u32 tos_val;
9101   int length = 0;
9102   u32 length_val;
9103   int fragment_id = 0;
9104   u32 fragment_id_val;
9105   int ttl = 0;
9106   int ttl_val;
9107   int checksum = 0;
9108   u32 checksum_val;
9109
9110   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9111     {
9112       if (unformat (input, "version %d", &version_val))
9113         version = 1;
9114       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9115         hdr_length = 1;
9116       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9117         src = 1;
9118       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9119         dst = 1;
9120       else if (unformat (input, "proto %d", &proto_val))
9121         proto = 1;
9122       else if (unformat (input, "tos %d", &tos_val))
9123         tos = 1;
9124       else if (unformat (input, "length %d", &length_val))
9125         length = 1;
9126       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9127         fragment_id = 1;
9128       else if (unformat (input, "ttl %d", &ttl_val))
9129         ttl = 1;
9130       else if (unformat (input, "checksum %d", &checksum_val))
9131         checksum = 1;
9132       else
9133         break;
9134     }
9135
9136   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9137       + ttl + checksum == 0)
9138     return 0;
9139
9140   /*
9141    * Aligned because we use the real comparison functions
9142    */
9143   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9144
9145   ip = (ip4_header_t *) match;
9146
9147   /* These are realistically matched in practice */
9148   if (src)
9149     ip->src_address.as_u32 = src_val.as_u32;
9150
9151   if (dst)
9152     ip->dst_address.as_u32 = dst_val.as_u32;
9153
9154   if (proto)
9155     ip->protocol = proto_val;
9156
9157
9158   /* These are not, but they're included for completeness */
9159   if (version)
9160     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9161
9162   if (hdr_length)
9163     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9164
9165   if (tos)
9166     ip->tos = tos_val;
9167
9168   if (length)
9169     ip->length = clib_host_to_net_u16 (length_val);
9170
9171   if (ttl)
9172     ip->ttl = ttl_val;
9173
9174   if (checksum)
9175     ip->checksum = clib_host_to_net_u16 (checksum_val);
9176
9177   *matchp = match;
9178   return 1;
9179 }
9180
9181 uword
9182 unformat_ip6_match (unformat_input_t * input, va_list * args)
9183 {
9184   u8 **matchp = va_arg (*args, u8 **);
9185   u8 *match = 0;
9186   ip6_header_t *ip;
9187   int version = 0;
9188   u32 version_val;
9189   u8 traffic_class = 0;
9190   u32 traffic_class_val = 0;
9191   u8 flow_label = 0;
9192   u8 flow_label_val;
9193   int src = 0, dst = 0;
9194   ip6_address_t src_val, dst_val;
9195   int proto = 0;
9196   u32 proto_val;
9197   int payload_length = 0;
9198   u32 payload_length_val;
9199   int hop_limit = 0;
9200   int hop_limit_val;
9201   u32 ip_version_traffic_class_and_flow_label;
9202
9203   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9204     {
9205       if (unformat (input, "version %d", &version_val))
9206         version = 1;
9207       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9208         traffic_class = 1;
9209       else if (unformat (input, "flow_label %d", &flow_label_val))
9210         flow_label = 1;
9211       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9212         src = 1;
9213       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9214         dst = 1;
9215       else if (unformat (input, "proto %d", &proto_val))
9216         proto = 1;
9217       else if (unformat (input, "payload_length %d", &payload_length_val))
9218         payload_length = 1;
9219       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9220         hop_limit = 1;
9221       else
9222         break;
9223     }
9224
9225   if (version + traffic_class + flow_label + src + dst + proto +
9226       payload_length + hop_limit == 0)
9227     return 0;
9228
9229   /*
9230    * Aligned because we use the real comparison functions
9231    */
9232   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9233
9234   ip = (ip6_header_t *) match;
9235
9236   if (src)
9237     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9238
9239   if (dst)
9240     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9241
9242   if (proto)
9243     ip->protocol = proto_val;
9244
9245   ip_version_traffic_class_and_flow_label = 0;
9246
9247   if (version)
9248     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9249
9250   if (traffic_class)
9251     ip_version_traffic_class_and_flow_label |=
9252       (traffic_class_val & 0xFF) << 20;
9253
9254   if (flow_label)
9255     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9256
9257   ip->ip_version_traffic_class_and_flow_label =
9258     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9259
9260   if (payload_length)
9261     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9262
9263   if (hop_limit)
9264     ip->hop_limit = hop_limit_val;
9265
9266   *matchp = match;
9267   return 1;
9268 }
9269
9270 uword
9271 unformat_l3_match (unformat_input_t * input, va_list * args)
9272 {
9273   u8 **matchp = va_arg (*args, u8 **);
9274
9275   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9276     {
9277       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9278         return 1;
9279       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9280         return 1;
9281       else
9282         break;
9283     }
9284   return 0;
9285 }
9286
9287 uword
9288 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9289 {
9290   u8 *tagp = va_arg (*args, u8 *);
9291   u32 tag;
9292
9293   if (unformat (input, "%d", &tag))
9294     {
9295       tagp[0] = (tag >> 8) & 0x0F;
9296       tagp[1] = tag & 0xFF;
9297       return 1;
9298     }
9299
9300   return 0;
9301 }
9302
9303 uword
9304 unformat_l2_match (unformat_input_t * input, va_list * args)
9305 {
9306   u8 **matchp = va_arg (*args, u8 **);
9307   u8 *match = 0;
9308   u8 src = 0;
9309   u8 src_val[6];
9310   u8 dst = 0;
9311   u8 dst_val[6];
9312   u8 proto = 0;
9313   u16 proto_val;
9314   u8 tag1 = 0;
9315   u8 tag1_val[2];
9316   u8 tag2 = 0;
9317   u8 tag2_val[2];
9318   int len = 14;
9319   u8 ignore_tag1 = 0;
9320   u8 ignore_tag2 = 0;
9321   u8 cos1 = 0;
9322   u8 cos2 = 0;
9323   u32 cos1_val = 0;
9324   u32 cos2_val = 0;
9325
9326   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9327     {
9328       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9329         src = 1;
9330       else
9331         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9332         dst = 1;
9333       else if (unformat (input, "proto %U",
9334                          unformat_ethernet_type_host_byte_order, &proto_val))
9335         proto = 1;
9336       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9337         tag1 = 1;
9338       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9339         tag2 = 1;
9340       else if (unformat (input, "ignore-tag1"))
9341         ignore_tag1 = 1;
9342       else if (unformat (input, "ignore-tag2"))
9343         ignore_tag2 = 1;
9344       else if (unformat (input, "cos1 %d", &cos1_val))
9345         cos1 = 1;
9346       else if (unformat (input, "cos2 %d", &cos2_val))
9347         cos2 = 1;
9348       else
9349         break;
9350     }
9351   if ((src + dst + proto + tag1 + tag2 +
9352        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9353     return 0;
9354
9355   if (tag1 || ignore_tag1 || cos1)
9356     len = 18;
9357   if (tag2 || ignore_tag2 || cos2)
9358     len = 22;
9359
9360   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9361
9362   if (dst)
9363     clib_memcpy (match, dst_val, 6);
9364
9365   if (src)
9366     clib_memcpy (match + 6, src_val, 6);
9367
9368   if (tag2)
9369     {
9370       /* inner vlan tag */
9371       match[19] = tag2_val[1];
9372       match[18] = tag2_val[0];
9373       if (cos2)
9374         match[18] |= (cos2_val & 0x7) << 5;
9375       if (proto)
9376         {
9377           match[21] = proto_val & 0xff;
9378           match[20] = proto_val >> 8;
9379         }
9380       if (tag1)
9381         {
9382           match[15] = tag1_val[1];
9383           match[14] = tag1_val[0];
9384         }
9385       if (cos1)
9386         match[14] |= (cos1_val & 0x7) << 5;
9387       *matchp = match;
9388       return 1;
9389     }
9390   if (tag1)
9391     {
9392       match[15] = tag1_val[1];
9393       match[14] = tag1_val[0];
9394       if (proto)
9395         {
9396           match[17] = proto_val & 0xff;
9397           match[16] = proto_val >> 8;
9398         }
9399       if (cos1)
9400         match[14] |= (cos1_val & 0x7) << 5;
9401
9402       *matchp = match;
9403       return 1;
9404     }
9405   if (cos2)
9406     match[18] |= (cos2_val & 0x7) << 5;
9407   if (cos1)
9408     match[14] |= (cos1_val & 0x7) << 5;
9409   if (proto)
9410     {
9411       match[13] = proto_val & 0xff;
9412       match[12] = proto_val >> 8;
9413     }
9414
9415   *matchp = match;
9416   return 1;
9417 }
9418
9419
9420 uword
9421 unformat_classify_match (unformat_input_t * input, va_list * args)
9422 {
9423   u8 **matchp = va_arg (*args, u8 **);
9424   u32 skip_n_vectors = va_arg (*args, u32);
9425   u32 match_n_vectors = va_arg (*args, u32);
9426
9427   u8 *match = 0;
9428   u8 *l2 = 0;
9429   u8 *l3 = 0;
9430   u8 *l4 = 0;
9431
9432   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9433     {
9434       if (unformat (input, "hex %U", unformat_hex_string, &match))
9435         ;
9436       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9437         ;
9438       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9439         ;
9440       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9441         ;
9442       else
9443         break;
9444     }
9445
9446   if (l4 && !l3)
9447     {
9448       vec_free (match);
9449       vec_free (l2);
9450       vec_free (l4);
9451       return 0;
9452     }
9453
9454   if (match || l2 || l3 || l4)
9455     {
9456       if (l2 || l3 || l4)
9457         {
9458           /* "Win a free Ethernet header in every packet" */
9459           if (l2 == 0)
9460             vec_validate_aligned (l2, 13, sizeof (u32x4));
9461           match = l2;
9462           if (vec_len (l3))
9463             {
9464               vec_append_aligned (match, l3, sizeof (u32x4));
9465               vec_free (l3);
9466             }
9467           if (vec_len (l4))
9468             {
9469               vec_append_aligned (match, l4, sizeof (u32x4));
9470               vec_free (l4);
9471             }
9472         }
9473
9474       /* Make sure the vector is big enough even if key is all 0's */
9475       vec_validate_aligned
9476         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9477          sizeof (u32x4));
9478
9479       /* Set size, include skipped vectors */
9480       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9481
9482       *matchp = match;
9483
9484       return 1;
9485     }
9486
9487   return 0;
9488 }
9489
9490 static int
9491 api_classify_add_del_session (vat_main_t * vam)
9492 {
9493   unformat_input_t *i = vam->input;
9494   vl_api_classify_add_del_session_t *mp;
9495   int is_add = 1;
9496   u32 table_index = ~0;
9497   u32 hit_next_index = ~0;
9498   u32 opaque_index = ~0;
9499   u8 *match = 0;
9500   i32 advance = 0;
9501   f64 timeout;
9502   u32 skip_n_vectors = 0;
9503   u32 match_n_vectors = 0;
9504   u32 action = 0;
9505   u32 metadata = 0;
9506
9507   /*
9508    * Warning: you have to supply skip_n and match_n
9509    * because the API client cant simply look at the classify
9510    * table object.
9511    */
9512
9513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9514     {
9515       if (unformat (i, "del"))
9516         is_add = 0;
9517       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9518                          &hit_next_index))
9519         ;
9520       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9521                          &hit_next_index))
9522         ;
9523       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9524                          &hit_next_index))
9525         ;
9526       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9527         ;
9528       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9529         ;
9530       else if (unformat (i, "opaque-index %d", &opaque_index))
9531         ;
9532       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9533         ;
9534       else if (unformat (i, "match_n %d", &match_n_vectors))
9535         ;
9536       else if (unformat (i, "match %U", unformat_classify_match,
9537                          &match, skip_n_vectors, match_n_vectors))
9538         ;
9539       else if (unformat (i, "advance %d", &advance))
9540         ;
9541       else if (unformat (i, "table-index %d", &table_index))
9542         ;
9543       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9544         action = 1;
9545       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9546         action = 2;
9547       else if (unformat (i, "action %d", &action))
9548         ;
9549       else if (unformat (i, "metadata %d", &metadata))
9550         ;
9551       else
9552         break;
9553     }
9554
9555   if (table_index == ~0)
9556     {
9557       errmsg ("Table index required");
9558       return -99;
9559     }
9560
9561   if (is_add && match == 0)
9562     {
9563       errmsg ("Match value required");
9564       return -99;
9565     }
9566
9567   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9568
9569   mp->is_add = is_add;
9570   mp->table_index = ntohl (table_index);
9571   mp->hit_next_index = ntohl (hit_next_index);
9572   mp->opaque_index = ntohl (opaque_index);
9573   mp->advance = ntohl (advance);
9574   mp->action = action;
9575   mp->metadata = ntohl (metadata);
9576   clib_memcpy (mp->match, match, vec_len (match));
9577   vec_free (match);
9578
9579   S;
9580   W;
9581   /* NOTREACHED */
9582 }
9583
9584 static int
9585 api_classify_set_interface_ip_table (vat_main_t * vam)
9586 {
9587   unformat_input_t *i = vam->input;
9588   vl_api_classify_set_interface_ip_table_t *mp;
9589   f64 timeout;
9590   u32 sw_if_index;
9591   int sw_if_index_set;
9592   u32 table_index = ~0;
9593   u8 is_ipv6 = 0;
9594
9595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9596     {
9597       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9598         sw_if_index_set = 1;
9599       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9600         sw_if_index_set = 1;
9601       else if (unformat (i, "table %d", &table_index))
9602         ;
9603       else
9604         {
9605           clib_warning ("parse error '%U'", format_unformat_error, i);
9606           return -99;
9607         }
9608     }
9609
9610   if (sw_if_index_set == 0)
9611     {
9612       errmsg ("missing interface name or sw_if_index");
9613       return -99;
9614     }
9615
9616
9617   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9618
9619   mp->sw_if_index = ntohl (sw_if_index);
9620   mp->table_index = ntohl (table_index);
9621   mp->is_ipv6 = is_ipv6;
9622
9623   S;
9624   W;
9625   /* NOTREACHED */
9626   return 0;
9627 }
9628
9629 static int
9630 api_classify_set_interface_l2_tables (vat_main_t * vam)
9631 {
9632   unformat_input_t *i = vam->input;
9633   vl_api_classify_set_interface_l2_tables_t *mp;
9634   f64 timeout;
9635   u32 sw_if_index;
9636   int sw_if_index_set;
9637   u32 ip4_table_index = ~0;
9638   u32 ip6_table_index = ~0;
9639   u32 other_table_index = ~0;
9640   u32 is_input = 1;
9641
9642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9643     {
9644       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9645         sw_if_index_set = 1;
9646       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9647         sw_if_index_set = 1;
9648       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9649         ;
9650       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9651         ;
9652       else if (unformat (i, "other-table %d", &other_table_index))
9653         ;
9654       else if (unformat (i, "is-input %d", &is_input))
9655         ;
9656       else
9657         {
9658           clib_warning ("parse error '%U'", format_unformat_error, i);
9659           return -99;
9660         }
9661     }
9662
9663   if (sw_if_index_set == 0)
9664     {
9665       errmsg ("missing interface name or sw_if_index");
9666       return -99;
9667     }
9668
9669
9670   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9671
9672   mp->sw_if_index = ntohl (sw_if_index);
9673   mp->ip4_table_index = ntohl (ip4_table_index);
9674   mp->ip6_table_index = ntohl (ip6_table_index);
9675   mp->other_table_index = ntohl (other_table_index);
9676   mp->is_input = (u8) is_input;
9677
9678   S;
9679   W;
9680   /* NOTREACHED */
9681   return 0;
9682 }
9683
9684 static int
9685 api_set_ipfix_exporter (vat_main_t * vam)
9686 {
9687   unformat_input_t *i = vam->input;
9688   vl_api_set_ipfix_exporter_t *mp;
9689   ip4_address_t collector_address;
9690   u8 collector_address_set = 0;
9691   u32 collector_port = ~0;
9692   ip4_address_t src_address;
9693   u8 src_address_set = 0;
9694   u32 vrf_id = ~0;
9695   u32 path_mtu = ~0;
9696   u32 template_interval = ~0;
9697   u8 udp_checksum = 0;
9698   f64 timeout;
9699
9700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9701     {
9702       if (unformat (i, "collector_address %U", unformat_ip4_address,
9703                     &collector_address))
9704         collector_address_set = 1;
9705       else if (unformat (i, "collector_port %d", &collector_port))
9706         ;
9707       else if (unformat (i, "src_address %U", unformat_ip4_address,
9708                          &src_address))
9709         src_address_set = 1;
9710       else if (unformat (i, "vrf_id %d", &vrf_id))
9711         ;
9712       else if (unformat (i, "path_mtu %d", &path_mtu))
9713         ;
9714       else if (unformat (i, "template_interval %d", &template_interval))
9715         ;
9716       else if (unformat (i, "udp_checksum"))
9717         udp_checksum = 1;
9718       else
9719         break;
9720     }
9721
9722   if (collector_address_set == 0)
9723     {
9724       errmsg ("collector_address required");
9725       return -99;
9726     }
9727
9728   if (src_address_set == 0)
9729     {
9730       errmsg ("src_address required");
9731       return -99;
9732     }
9733
9734   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9735
9736   memcpy (mp->collector_address, collector_address.data,
9737           sizeof (collector_address.data));
9738   mp->collector_port = htons ((u16) collector_port);
9739   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9740   mp->vrf_id = htonl (vrf_id);
9741   mp->path_mtu = htonl (path_mtu);
9742   mp->template_interval = htonl (template_interval);
9743   mp->udp_checksum = udp_checksum;
9744
9745   S;
9746   W;
9747   /* NOTREACHED */
9748 }
9749
9750 static int
9751 api_set_ipfix_classify_stream (vat_main_t * vam)
9752 {
9753   unformat_input_t *i = vam->input;
9754   vl_api_set_ipfix_classify_stream_t *mp;
9755   u32 domain_id = 0;
9756   u32 src_port = UDP_DST_PORT_ipfix;
9757   f64 timeout;
9758
9759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9760     {
9761       if (unformat (i, "domain %d", &domain_id))
9762         ;
9763       else if (unformat (i, "src_port %d", &src_port))
9764         ;
9765       else
9766         {
9767           errmsg ("unknown input `%U'", format_unformat_error, i);
9768           return -99;
9769         }
9770     }
9771
9772   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9773
9774   mp->domain_id = htonl (domain_id);
9775   mp->src_port = htons ((u16) src_port);
9776
9777   S;
9778   W;
9779   /* NOTREACHED */
9780 }
9781
9782 static int
9783 api_ipfix_classify_table_add_del (vat_main_t * vam)
9784 {
9785   unformat_input_t *i = vam->input;
9786   vl_api_ipfix_classify_table_add_del_t *mp;
9787   int is_add = -1;
9788   u32 classify_table_index = ~0;
9789   u8 ip_version = 0;
9790   u8 transport_protocol = 255;
9791   f64 timeout;
9792
9793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9794     {
9795       if (unformat (i, "add"))
9796         is_add = 1;
9797       else if (unformat (i, "del"))
9798         is_add = 0;
9799       else if (unformat (i, "table %d", &classify_table_index))
9800         ;
9801       else if (unformat (i, "ip4"))
9802         ip_version = 4;
9803       else if (unformat (i, "ip6"))
9804         ip_version = 6;
9805       else if (unformat (i, "tcp"))
9806         transport_protocol = 6;
9807       else if (unformat (i, "udp"))
9808         transport_protocol = 17;
9809       else
9810         {
9811           errmsg ("unknown input `%U'", format_unformat_error, i);
9812           return -99;
9813         }
9814     }
9815
9816   if (is_add == -1)
9817     {
9818       errmsg ("expecting: add|del");
9819       return -99;
9820     }
9821   if (classify_table_index == ~0)
9822     {
9823       errmsg ("classifier table not specified");
9824       return -99;
9825     }
9826   if (ip_version == 0)
9827     {
9828       errmsg ("IP version not specified");
9829       return -99;
9830     }
9831
9832   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9833
9834   mp->is_add = is_add;
9835   mp->table_id = htonl (classify_table_index);
9836   mp->ip_version = ip_version;
9837   mp->transport_protocol = transport_protocol;
9838
9839   S;
9840   W;
9841   /* NOTREACHED */
9842 }
9843
9844 static int
9845 api_get_node_index (vat_main_t * vam)
9846 {
9847   unformat_input_t *i = vam->input;
9848   vl_api_get_node_index_t *mp;
9849   f64 timeout;
9850   u8 *name = 0;
9851
9852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9853     {
9854       if (unformat (i, "node %s", &name))
9855         ;
9856       else
9857         break;
9858     }
9859   if (name == 0)
9860     {
9861       errmsg ("node name required");
9862       return -99;
9863     }
9864   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9865     {
9866       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9867       return -99;
9868     }
9869
9870   M (GET_NODE_INDEX, get_node_index);
9871   clib_memcpy (mp->node_name, name, vec_len (name));
9872   vec_free (name);
9873
9874   S;
9875   W;
9876   /* NOTREACHED */
9877   return 0;
9878 }
9879
9880 static int
9881 api_get_next_index (vat_main_t * vam)
9882 {
9883   unformat_input_t *i = vam->input;
9884   vl_api_get_next_index_t *mp;
9885   f64 timeout;
9886   u8 *node_name = 0, *next_node_name = 0;
9887
9888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9889     {
9890       if (unformat (i, "node-name %s", &node_name))
9891         ;
9892       else if (unformat (i, "next-node-name %s", &next_node_name))
9893         break;
9894     }
9895
9896   if (node_name == 0)
9897     {
9898       errmsg ("node name required");
9899       return -99;
9900     }
9901   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9902     {
9903       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9904       return -99;
9905     }
9906
9907   if (next_node_name == 0)
9908     {
9909       errmsg ("next node name required");
9910       return -99;
9911     }
9912   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9913     {
9914       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9915       return -99;
9916     }
9917
9918   M (GET_NEXT_INDEX, get_next_index);
9919   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9920   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9921   vec_free (node_name);
9922   vec_free (next_node_name);
9923
9924   S;
9925   W;
9926   /* NOTREACHED */
9927   return 0;
9928 }
9929
9930 static int
9931 api_add_node_next (vat_main_t * vam)
9932 {
9933   unformat_input_t *i = vam->input;
9934   vl_api_add_node_next_t *mp;
9935   f64 timeout;
9936   u8 *name = 0;
9937   u8 *next = 0;
9938
9939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9940     {
9941       if (unformat (i, "node %s", &name))
9942         ;
9943       else if (unformat (i, "next %s", &next))
9944         ;
9945       else
9946         break;
9947     }
9948   if (name == 0)
9949     {
9950       errmsg ("node name required");
9951       return -99;
9952     }
9953   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9954     {
9955       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9956       return -99;
9957     }
9958   if (next == 0)
9959     {
9960       errmsg ("next node required");
9961       return -99;
9962     }
9963   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9964     {
9965       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9966       return -99;
9967     }
9968
9969   M (ADD_NODE_NEXT, add_node_next);
9970   clib_memcpy (mp->node_name, name, vec_len (name));
9971   clib_memcpy (mp->next_name, next, vec_len (next));
9972   vec_free (name);
9973   vec_free (next);
9974
9975   S;
9976   W;
9977   /* NOTREACHED */
9978   return 0;
9979 }
9980
9981 static int
9982 api_l2tpv3_create_tunnel (vat_main_t * vam)
9983 {
9984   unformat_input_t *i = vam->input;
9985   ip6_address_t client_address, our_address;
9986   int client_address_set = 0;
9987   int our_address_set = 0;
9988   u32 local_session_id = 0;
9989   u32 remote_session_id = 0;
9990   u64 local_cookie = 0;
9991   u64 remote_cookie = 0;
9992   u8 l2_sublayer_present = 0;
9993   vl_api_l2tpv3_create_tunnel_t *mp;
9994   f64 timeout;
9995
9996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9997     {
9998       if (unformat (i, "client_address %U", unformat_ip6_address,
9999                     &client_address))
10000         client_address_set = 1;
10001       else if (unformat (i, "our_address %U", unformat_ip6_address,
10002                          &our_address))
10003         our_address_set = 1;
10004       else if (unformat (i, "local_session_id %d", &local_session_id))
10005         ;
10006       else if (unformat (i, "remote_session_id %d", &remote_session_id))
10007         ;
10008       else if (unformat (i, "local_cookie %lld", &local_cookie))
10009         ;
10010       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
10011         ;
10012       else if (unformat (i, "l2-sublayer-present"))
10013         l2_sublayer_present = 1;
10014       else
10015         break;
10016     }
10017
10018   if (client_address_set == 0)
10019     {
10020       errmsg ("client_address required");
10021       return -99;
10022     }
10023
10024   if (our_address_set == 0)
10025     {
10026       errmsg ("our_address required");
10027       return -99;
10028     }
10029
10030   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
10031
10032   clib_memcpy (mp->client_address, client_address.as_u8,
10033                sizeof (mp->client_address));
10034
10035   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
10036
10037   mp->local_session_id = ntohl (local_session_id);
10038   mp->remote_session_id = ntohl (remote_session_id);
10039   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
10040   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
10041   mp->l2_sublayer_present = l2_sublayer_present;
10042   mp->is_ipv6 = 1;
10043
10044   S;
10045   W;
10046   /* NOTREACHED */
10047   return 0;
10048 }
10049
10050 static int
10051 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
10052 {
10053   unformat_input_t *i = vam->input;
10054   u32 sw_if_index;
10055   u8 sw_if_index_set = 0;
10056   u64 new_local_cookie = 0;
10057   u64 new_remote_cookie = 0;
10058   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
10059   f64 timeout;
10060
10061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10062     {
10063       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10064         sw_if_index_set = 1;
10065       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10066         sw_if_index_set = 1;
10067       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
10068         ;
10069       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10070         ;
10071       else
10072         break;
10073     }
10074
10075   if (sw_if_index_set == 0)
10076     {
10077       errmsg ("missing interface name or sw_if_index");
10078       return -99;
10079     }
10080
10081   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
10082
10083   mp->sw_if_index = ntohl (sw_if_index);
10084   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10085   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10086
10087   S;
10088   W;
10089   /* NOTREACHED */
10090   return 0;
10091 }
10092
10093 static int
10094 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10095 {
10096   unformat_input_t *i = vam->input;
10097   vl_api_l2tpv3_interface_enable_disable_t *mp;
10098   f64 timeout;
10099   u32 sw_if_index;
10100   u8 sw_if_index_set = 0;
10101   u8 enable_disable = 1;
10102
10103   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10104     {
10105       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10106         sw_if_index_set = 1;
10107       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10108         sw_if_index_set = 1;
10109       else if (unformat (i, "enable"))
10110         enable_disable = 1;
10111       else if (unformat (i, "disable"))
10112         enable_disable = 0;
10113       else
10114         break;
10115     }
10116
10117   if (sw_if_index_set == 0)
10118     {
10119       errmsg ("missing interface name or sw_if_index");
10120       return -99;
10121     }
10122
10123   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
10124
10125   mp->sw_if_index = ntohl (sw_if_index);
10126   mp->enable_disable = enable_disable;
10127
10128   S;
10129   W;
10130   /* NOTREACHED */
10131   return 0;
10132 }
10133
10134 static int
10135 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10136 {
10137   unformat_input_t *i = vam->input;
10138   vl_api_l2tpv3_set_lookup_key_t *mp;
10139   f64 timeout;
10140   u8 key = ~0;
10141
10142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10143     {
10144       if (unformat (i, "lookup_v6_src"))
10145         key = L2T_LOOKUP_SRC_ADDRESS;
10146       else if (unformat (i, "lookup_v6_dst"))
10147         key = L2T_LOOKUP_DST_ADDRESS;
10148       else if (unformat (i, "lookup_session_id"))
10149         key = L2T_LOOKUP_SESSION_ID;
10150       else
10151         break;
10152     }
10153
10154   if (key == (u8) ~ 0)
10155     {
10156       errmsg ("l2tp session lookup key unset");
10157       return -99;
10158     }
10159
10160   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
10161
10162   mp->key = key;
10163
10164   S;
10165   W;
10166   /* NOTREACHED */
10167   return 0;
10168 }
10169
10170 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10171   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10172 {
10173   vat_main_t *vam = &vat_main;
10174
10175   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10176          format_ip6_address, mp->our_address,
10177          format_ip6_address, mp->client_address,
10178          clib_net_to_host_u32 (mp->sw_if_index));
10179
10180   print (vam->ofp,
10181          "   local cookies %016llx %016llx remote cookie %016llx",
10182          clib_net_to_host_u64 (mp->local_cookie[0]),
10183          clib_net_to_host_u64 (mp->local_cookie[1]),
10184          clib_net_to_host_u64 (mp->remote_cookie));
10185
10186   print (vam->ofp, "   local session-id %d remote session-id %d",
10187          clib_net_to_host_u32 (mp->local_session_id),
10188          clib_net_to_host_u32 (mp->remote_session_id));
10189
10190   print (vam->ofp, "   l2 specific sublayer %s\n",
10191          mp->l2_sublayer_present ? "preset" : "absent");
10192
10193 }
10194
10195 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10196   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10197 {
10198   vat_main_t *vam = &vat_main;
10199   vat_json_node_t *node = NULL;
10200   struct in6_addr addr;
10201
10202   if (VAT_JSON_ARRAY != vam->json_tree.type)
10203     {
10204       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10205       vat_json_init_array (&vam->json_tree);
10206     }
10207   node = vat_json_array_add (&vam->json_tree);
10208
10209   vat_json_init_object (node);
10210
10211   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10212   vat_json_object_add_ip6 (node, "our_address", addr);
10213   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10214   vat_json_object_add_ip6 (node, "client_address", addr);
10215
10216   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10217   vat_json_init_array (lc);
10218   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10219   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10220   vat_json_object_add_uint (node, "remote_cookie",
10221                             clib_net_to_host_u64 (mp->remote_cookie));
10222
10223   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10224   vat_json_object_add_uint (node, "local_session_id",
10225                             clib_net_to_host_u32 (mp->local_session_id));
10226   vat_json_object_add_uint (node, "remote_session_id",
10227                             clib_net_to_host_u32 (mp->remote_session_id));
10228   vat_json_object_add_string_copy (node, "l2_sublayer",
10229                                    mp->l2_sublayer_present ? (u8 *) "present"
10230                                    : (u8 *) "absent");
10231 }
10232
10233 static int
10234 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10235 {
10236   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10237   f64 timeout;
10238
10239   /* Get list of l2tpv3-tunnel interfaces */
10240   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10241   S;
10242
10243   /* Use a control ping for synchronization */
10244   {
10245     vl_api_control_ping_t *mp;
10246     M (CONTROL_PING, control_ping);
10247     S;
10248   }
10249   W;
10250 }
10251
10252
10253 static void vl_api_sw_interface_tap_details_t_handler
10254   (vl_api_sw_interface_tap_details_t * mp)
10255 {
10256   vat_main_t *vam = &vat_main;
10257
10258   print (vam->ofp, "%-16s %d",
10259          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10260 }
10261
10262 static void vl_api_sw_interface_tap_details_t_handler_json
10263   (vl_api_sw_interface_tap_details_t * mp)
10264 {
10265   vat_main_t *vam = &vat_main;
10266   vat_json_node_t *node = NULL;
10267
10268   if (VAT_JSON_ARRAY != vam->json_tree.type)
10269     {
10270       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10271       vat_json_init_array (&vam->json_tree);
10272     }
10273   node = vat_json_array_add (&vam->json_tree);
10274
10275   vat_json_init_object (node);
10276   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10277   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10278 }
10279
10280 static int
10281 api_sw_interface_tap_dump (vat_main_t * vam)
10282 {
10283   vl_api_sw_interface_tap_dump_t *mp;
10284   f64 timeout;
10285
10286   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10287   /* Get list of tap interfaces */
10288   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10289   S;
10290
10291   /* Use a control ping for synchronization */
10292   {
10293     vl_api_control_ping_t *mp;
10294     M (CONTROL_PING, control_ping);
10295     S;
10296   }
10297   W;
10298 }
10299
10300 static uword unformat_vxlan_decap_next
10301   (unformat_input_t * input, va_list * args)
10302 {
10303   u32 *result = va_arg (*args, u32 *);
10304   u32 tmp;
10305
10306   if (unformat (input, "l2"))
10307     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10308   else if (unformat (input, "%d", &tmp))
10309     *result = tmp;
10310   else
10311     return 0;
10312   return 1;
10313 }
10314
10315 static int
10316 api_vxlan_add_del_tunnel (vat_main_t * vam)
10317 {
10318   unformat_input_t *line_input = vam->input;
10319   vl_api_vxlan_add_del_tunnel_t *mp;
10320   f64 timeout;
10321   ip46_address_t src, dst;
10322   u8 is_add = 1;
10323   u8 ipv4_set = 0, ipv6_set = 0;
10324   u8 src_set = 0;
10325   u8 dst_set = 0;
10326   u8 grp_set = 0;
10327   u32 mcast_sw_if_index = ~0;
10328   u32 encap_vrf_id = 0;
10329   u32 decap_next_index = ~0;
10330   u32 vni = 0;
10331
10332   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10333   memset (&src, 0, sizeof src);
10334   memset (&dst, 0, sizeof dst);
10335
10336   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10337     {
10338       if (unformat (line_input, "del"))
10339         is_add = 0;
10340       else
10341         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10342         {
10343           ipv4_set = 1;
10344           src_set = 1;
10345         }
10346       else
10347         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10348         {
10349           ipv4_set = 1;
10350           dst_set = 1;
10351         }
10352       else
10353         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10354         {
10355           ipv6_set = 1;
10356           src_set = 1;
10357         }
10358       else
10359         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10360         {
10361           ipv6_set = 1;
10362           dst_set = 1;
10363         }
10364       else if (unformat (line_input, "group %U %U",
10365                          unformat_ip4_address, &dst.ip4,
10366                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10367         {
10368           grp_set = dst_set = 1;
10369           ipv4_set = 1;
10370         }
10371       else if (unformat (line_input, "group %U",
10372                          unformat_ip4_address, &dst.ip4))
10373         {
10374           grp_set = dst_set = 1;
10375           ipv4_set = 1;
10376         }
10377       else if (unformat (line_input, "group %U %U",
10378                          unformat_ip6_address, &dst.ip6,
10379                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10380         {
10381           grp_set = dst_set = 1;
10382           ipv6_set = 1;
10383         }
10384       else if (unformat (line_input, "group %U",
10385                          unformat_ip6_address, &dst.ip6))
10386         {
10387           grp_set = dst_set = 1;
10388           ipv6_set = 1;
10389         }
10390       else
10391         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10392         ;
10393       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10394         ;
10395       else if (unformat (line_input, "decap-next %U",
10396                          unformat_vxlan_decap_next, &decap_next_index))
10397         ;
10398       else if (unformat (line_input, "vni %d", &vni))
10399         ;
10400       else
10401         {
10402           errmsg ("parse error '%U'", format_unformat_error, line_input);
10403           return -99;
10404         }
10405     }
10406
10407   if (src_set == 0)
10408     {
10409       errmsg ("tunnel src address not specified");
10410       return -99;
10411     }
10412   if (dst_set == 0)
10413     {
10414       errmsg ("tunnel dst address not specified");
10415       return -99;
10416     }
10417
10418   if (grp_set && !ip46_address_is_multicast (&dst))
10419     {
10420       errmsg ("tunnel group address not multicast");
10421       return -99;
10422     }
10423   if (grp_set && mcast_sw_if_index == ~0)
10424     {
10425       errmsg ("tunnel nonexistent multicast device");
10426       return -99;
10427     }
10428   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10429     {
10430       errmsg ("tunnel dst address must be unicast");
10431       return -99;
10432     }
10433
10434
10435   if (ipv4_set && ipv6_set)
10436     {
10437       errmsg ("both IPv4 and IPv6 addresses specified");
10438       return -99;
10439     }
10440
10441   if ((vni == 0) || (vni >> 24))
10442     {
10443       errmsg ("vni not specified or out of range");
10444       return -99;
10445     }
10446
10447   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10448
10449   if (ipv6_set)
10450     {
10451       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10452       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10453     }
10454   else
10455     {
10456       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10457       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10458     }
10459   mp->encap_vrf_id = ntohl (encap_vrf_id);
10460   mp->decap_next_index = ntohl (decap_next_index);
10461   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10462   mp->vni = ntohl (vni);
10463   mp->is_add = is_add;
10464   mp->is_ipv6 = ipv6_set;
10465
10466   S;
10467   W;
10468   /* NOTREACHED */
10469   return 0;
10470 }
10471
10472 static void vl_api_vxlan_tunnel_details_t_handler
10473   (vl_api_vxlan_tunnel_details_t * mp)
10474 {
10475   vat_main_t *vam = &vat_main;
10476   ip46_address_t src, dst;
10477
10478   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10479   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10480
10481   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10482          ntohl (mp->sw_if_index),
10483          format_ip46_address, &src, IP46_TYPE_ANY,
10484          format_ip46_address, &dst, IP46_TYPE_ANY,
10485          ntohl (mp->encap_vrf_id),
10486          ntohl (mp->decap_next_index), ntohl (mp->vni),
10487          ntohl (mp->mcast_sw_if_index));
10488 }
10489
10490 static void vl_api_vxlan_tunnel_details_t_handler_json
10491   (vl_api_vxlan_tunnel_details_t * mp)
10492 {
10493   vat_main_t *vam = &vat_main;
10494   vat_json_node_t *node = NULL;
10495
10496   if (VAT_JSON_ARRAY != vam->json_tree.type)
10497     {
10498       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10499       vat_json_init_array (&vam->json_tree);
10500     }
10501   node = vat_json_array_add (&vam->json_tree);
10502
10503   vat_json_init_object (node);
10504   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10505   if (mp->is_ipv6)
10506     {
10507       struct in6_addr ip6;
10508
10509       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10510       vat_json_object_add_ip6 (node, "src_address", ip6);
10511       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10512       vat_json_object_add_ip6 (node, "dst_address", ip6);
10513     }
10514   else
10515     {
10516       struct in_addr ip4;
10517
10518       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10519       vat_json_object_add_ip4 (node, "src_address", ip4);
10520       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10521       vat_json_object_add_ip4 (node, "dst_address", ip4);
10522     }
10523   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10524   vat_json_object_add_uint (node, "decap_next_index",
10525                             ntohl (mp->decap_next_index));
10526   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10527   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10528   vat_json_object_add_uint (node, "mcast_sw_if_index",
10529                             ntohl (mp->mcast_sw_if_index));
10530 }
10531
10532 static int
10533 api_vxlan_tunnel_dump (vat_main_t * vam)
10534 {
10535   unformat_input_t *i = vam->input;
10536   vl_api_vxlan_tunnel_dump_t *mp;
10537   f64 timeout;
10538   u32 sw_if_index;
10539   u8 sw_if_index_set = 0;
10540
10541   /* Parse args required to build the message */
10542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10543     {
10544       if (unformat (i, "sw_if_index %d", &sw_if_index))
10545         sw_if_index_set = 1;
10546       else
10547         break;
10548     }
10549
10550   if (sw_if_index_set == 0)
10551     {
10552       sw_if_index = ~0;
10553     }
10554
10555   if (!vam->json_output)
10556     {
10557       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10558              "sw_if_index", "src_address", "dst_address",
10559              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10560     }
10561
10562   /* Get list of vxlan-tunnel interfaces */
10563   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10564
10565   mp->sw_if_index = htonl (sw_if_index);
10566
10567   S;
10568
10569   /* Use a control ping for synchronization */
10570   {
10571     vl_api_control_ping_t *mp;
10572     M (CONTROL_PING, control_ping);
10573     S;
10574   }
10575   W;
10576 }
10577
10578 static int
10579 api_gre_add_del_tunnel (vat_main_t * vam)
10580 {
10581   unformat_input_t *line_input = vam->input;
10582   vl_api_gre_add_del_tunnel_t *mp;
10583   f64 timeout;
10584   ip4_address_t src4, dst4;
10585   u8 is_add = 1;
10586   u8 teb = 0;
10587   u8 src_set = 0;
10588   u8 dst_set = 0;
10589   u32 outer_fib_id = 0;
10590
10591   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10592     {
10593       if (unformat (line_input, "del"))
10594         is_add = 0;
10595       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10596         src_set = 1;
10597       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10598         dst_set = 1;
10599       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10600         ;
10601       else if (unformat (line_input, "teb"))
10602         teb = 1;
10603       else
10604         {
10605           errmsg ("parse error '%U'", format_unformat_error, line_input);
10606           return -99;
10607         }
10608     }
10609
10610   if (src_set == 0)
10611     {
10612       errmsg ("tunnel src address not specified");
10613       return -99;
10614     }
10615   if (dst_set == 0)
10616     {
10617       errmsg ("tunnel dst address not specified");
10618       return -99;
10619     }
10620
10621
10622   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10623
10624   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10625   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10626   mp->outer_fib_id = ntohl (outer_fib_id);
10627   mp->is_add = is_add;
10628   mp->teb = teb;
10629
10630   S;
10631   W;
10632   /* NOTREACHED */
10633   return 0;
10634 }
10635
10636 static void vl_api_gre_tunnel_details_t_handler
10637   (vl_api_gre_tunnel_details_t * mp)
10638 {
10639   vat_main_t *vam = &vat_main;
10640
10641   print (vam->ofp, "%11d%15U%15U%6d%14d",
10642          ntohl (mp->sw_if_index),
10643          format_ip4_address, &mp->src_address,
10644          format_ip4_address, &mp->dst_address,
10645          mp->teb, ntohl (mp->outer_fib_id));
10646 }
10647
10648 static void vl_api_gre_tunnel_details_t_handler_json
10649   (vl_api_gre_tunnel_details_t * mp)
10650 {
10651   vat_main_t *vam = &vat_main;
10652   vat_json_node_t *node = NULL;
10653   struct in_addr ip4;
10654
10655   if (VAT_JSON_ARRAY != vam->json_tree.type)
10656     {
10657       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10658       vat_json_init_array (&vam->json_tree);
10659     }
10660   node = vat_json_array_add (&vam->json_tree);
10661
10662   vat_json_init_object (node);
10663   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10664   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10665   vat_json_object_add_ip4 (node, "src_address", ip4);
10666   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10667   vat_json_object_add_ip4 (node, "dst_address", ip4);
10668   vat_json_object_add_uint (node, "teb", mp->teb);
10669   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10670 }
10671
10672 static int
10673 api_gre_tunnel_dump (vat_main_t * vam)
10674 {
10675   unformat_input_t *i = vam->input;
10676   vl_api_gre_tunnel_dump_t *mp;
10677   f64 timeout;
10678   u32 sw_if_index;
10679   u8 sw_if_index_set = 0;
10680
10681   /* Parse args required to build the message */
10682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10683     {
10684       if (unformat (i, "sw_if_index %d", &sw_if_index))
10685         sw_if_index_set = 1;
10686       else
10687         break;
10688     }
10689
10690   if (sw_if_index_set == 0)
10691     {
10692       sw_if_index = ~0;
10693     }
10694
10695   if (!vam->json_output)
10696     {
10697       print (vam->ofp, "%11s%15s%15s%6s%14s",
10698              "sw_if_index", "src_address", "dst_address", "teb",
10699              "outer_fib_id");
10700     }
10701
10702   /* Get list of gre-tunnel interfaces */
10703   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10704
10705   mp->sw_if_index = htonl (sw_if_index);
10706
10707   S;
10708
10709   /* Use a control ping for synchronization */
10710   {
10711     vl_api_control_ping_t *mp;
10712     M (CONTROL_PING, control_ping);
10713     S;
10714   }
10715   W;
10716 }
10717
10718 static int
10719 api_l2_fib_clear_table (vat_main_t * vam)
10720 {
10721 //  unformat_input_t * i = vam->input;
10722   vl_api_l2_fib_clear_table_t *mp;
10723   f64 timeout;
10724
10725   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10726
10727   S;
10728   W;
10729   /* NOTREACHED */
10730   return 0;
10731 }
10732
10733 static int
10734 api_l2_interface_efp_filter (vat_main_t * vam)
10735 {
10736   unformat_input_t *i = vam->input;
10737   vl_api_l2_interface_efp_filter_t *mp;
10738   f64 timeout;
10739   u32 sw_if_index;
10740   u8 enable = 1;
10741   u8 sw_if_index_set = 0;
10742
10743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10744     {
10745       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10746         sw_if_index_set = 1;
10747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10748         sw_if_index_set = 1;
10749       else if (unformat (i, "enable"))
10750         enable = 1;
10751       else if (unformat (i, "disable"))
10752         enable = 0;
10753       else
10754         {
10755           clib_warning ("parse error '%U'", format_unformat_error, i);
10756           return -99;
10757         }
10758     }
10759
10760   if (sw_if_index_set == 0)
10761     {
10762       errmsg ("missing sw_if_index");
10763       return -99;
10764     }
10765
10766   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10767
10768   mp->sw_if_index = ntohl (sw_if_index);
10769   mp->enable_disable = enable;
10770
10771   S;
10772   W;
10773   /* NOTREACHED */
10774   return 0;
10775 }
10776
10777 #define foreach_vtr_op                          \
10778 _("disable",  L2_VTR_DISABLED)                  \
10779 _("push-1",  L2_VTR_PUSH_1)                     \
10780 _("push-2",  L2_VTR_PUSH_2)                     \
10781 _("pop-1",  L2_VTR_POP_1)                       \
10782 _("pop-2",  L2_VTR_POP_2)                       \
10783 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10784 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10785 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10786 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10787
10788 static int
10789 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10790 {
10791   unformat_input_t *i = vam->input;
10792   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10793   f64 timeout;
10794   u32 sw_if_index;
10795   u8 sw_if_index_set = 0;
10796   u8 vtr_op_set = 0;
10797   u32 vtr_op = 0;
10798   u32 push_dot1q = 1;
10799   u32 tag1 = ~0;
10800   u32 tag2 = ~0;
10801
10802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10803     {
10804       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10805         sw_if_index_set = 1;
10806       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10807         sw_if_index_set = 1;
10808       else if (unformat (i, "vtr_op %d", &vtr_op))
10809         vtr_op_set = 1;
10810 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10811       foreach_vtr_op
10812 #undef _
10813         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10814         ;
10815       else if (unformat (i, "tag1 %d", &tag1))
10816         ;
10817       else if (unformat (i, "tag2 %d", &tag2))
10818         ;
10819       else
10820         {
10821           clib_warning ("parse error '%U'", format_unformat_error, i);
10822           return -99;
10823         }
10824     }
10825
10826   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10827     {
10828       errmsg ("missing vtr operation or sw_if_index");
10829       return -99;
10830     }
10831
10832   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10833     mp->sw_if_index = ntohl (sw_if_index);
10834   mp->vtr_op = ntohl (vtr_op);
10835   mp->push_dot1q = ntohl (push_dot1q);
10836   mp->tag1 = ntohl (tag1);
10837   mp->tag2 = ntohl (tag2);
10838
10839   S;
10840   W;
10841   /* NOTREACHED */
10842   return 0;
10843 }
10844
10845 static int
10846 api_create_vhost_user_if (vat_main_t * vam)
10847 {
10848   unformat_input_t *i = vam->input;
10849   vl_api_create_vhost_user_if_t *mp;
10850   f64 timeout;
10851   u8 *file_name;
10852   u8 is_server = 0;
10853   u8 file_name_set = 0;
10854   u32 custom_dev_instance = ~0;
10855   u8 hwaddr[6];
10856   u8 use_custom_mac = 0;
10857   u8 *tag = 0;
10858
10859   /* Shut up coverity */
10860   memset (hwaddr, 0, sizeof (hwaddr));
10861
10862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10863     {
10864       if (unformat (i, "socket %s", &file_name))
10865         {
10866           file_name_set = 1;
10867         }
10868       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10869         ;
10870       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10871         use_custom_mac = 1;
10872       else if (unformat (i, "server"))
10873         is_server = 1;
10874       else if (unformat (i, "tag %s", &tag))
10875         ;
10876       else
10877         break;
10878     }
10879
10880   if (file_name_set == 0)
10881     {
10882       errmsg ("missing socket file name");
10883       return -99;
10884     }
10885
10886   if (vec_len (file_name) > 255)
10887     {
10888       errmsg ("socket file name too long");
10889       return -99;
10890     }
10891   vec_add1 (file_name, 0);
10892
10893   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10894
10895   mp->is_server = is_server;
10896   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10897   vec_free (file_name);
10898   if (custom_dev_instance != ~0)
10899     {
10900       mp->renumber = 1;
10901       mp->custom_dev_instance = ntohl (custom_dev_instance);
10902     }
10903   mp->use_custom_mac = use_custom_mac;
10904   clib_memcpy (mp->mac_address, hwaddr, 6);
10905   if (tag)
10906     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10907   vec_free (tag);
10908
10909   S;
10910   W;
10911   /* NOTREACHED */
10912   return 0;
10913 }
10914
10915 static int
10916 api_modify_vhost_user_if (vat_main_t * vam)
10917 {
10918   unformat_input_t *i = vam->input;
10919   vl_api_modify_vhost_user_if_t *mp;
10920   f64 timeout;
10921   u8 *file_name;
10922   u8 is_server = 0;
10923   u8 file_name_set = 0;
10924   u32 custom_dev_instance = ~0;
10925   u8 sw_if_index_set = 0;
10926   u32 sw_if_index = (u32) ~ 0;
10927
10928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10929     {
10930       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10931         sw_if_index_set = 1;
10932       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10933         sw_if_index_set = 1;
10934       else if (unformat (i, "socket %s", &file_name))
10935         {
10936           file_name_set = 1;
10937         }
10938       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10939         ;
10940       else if (unformat (i, "server"))
10941         is_server = 1;
10942       else
10943         break;
10944     }
10945
10946   if (sw_if_index_set == 0)
10947     {
10948       errmsg ("missing sw_if_index or interface name");
10949       return -99;
10950     }
10951
10952   if (file_name_set == 0)
10953     {
10954       errmsg ("missing socket file name");
10955       return -99;
10956     }
10957
10958   if (vec_len (file_name) > 255)
10959     {
10960       errmsg ("socket file name too long");
10961       return -99;
10962     }
10963   vec_add1 (file_name, 0);
10964
10965   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10966
10967   mp->sw_if_index = ntohl (sw_if_index);
10968   mp->is_server = is_server;
10969   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10970   vec_free (file_name);
10971   if (custom_dev_instance != ~0)
10972     {
10973       mp->renumber = 1;
10974       mp->custom_dev_instance = ntohl (custom_dev_instance);
10975     }
10976
10977   S;
10978   W;
10979   /* NOTREACHED */
10980   return 0;
10981 }
10982
10983 static int
10984 api_delete_vhost_user_if (vat_main_t * vam)
10985 {
10986   unformat_input_t *i = vam->input;
10987   vl_api_delete_vhost_user_if_t *mp;
10988   f64 timeout;
10989   u32 sw_if_index = ~0;
10990   u8 sw_if_index_set = 0;
10991
10992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10993     {
10994       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10995         sw_if_index_set = 1;
10996       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10997         sw_if_index_set = 1;
10998       else
10999         break;
11000     }
11001
11002   if (sw_if_index_set == 0)
11003     {
11004       errmsg ("missing sw_if_index or interface name");
11005       return -99;
11006     }
11007
11008
11009   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
11010
11011   mp->sw_if_index = ntohl (sw_if_index);
11012
11013   S;
11014   W;
11015   /* NOTREACHED */
11016   return 0;
11017 }
11018
11019 static void vl_api_sw_interface_vhost_user_details_t_handler
11020   (vl_api_sw_interface_vhost_user_details_t * mp)
11021 {
11022   vat_main_t *vam = &vat_main;
11023
11024   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
11025          (char *) mp->interface_name,
11026          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
11027          clib_net_to_host_u64 (mp->features), mp->is_server,
11028          ntohl (mp->num_regions), (char *) mp->sock_filename);
11029   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
11030 }
11031
11032 static void vl_api_sw_interface_vhost_user_details_t_handler_json
11033   (vl_api_sw_interface_vhost_user_details_t * mp)
11034 {
11035   vat_main_t *vam = &vat_main;
11036   vat_json_node_t *node = NULL;
11037
11038   if (VAT_JSON_ARRAY != vam->json_tree.type)
11039     {
11040       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11041       vat_json_init_array (&vam->json_tree);
11042     }
11043   node = vat_json_array_add (&vam->json_tree);
11044
11045   vat_json_init_object (node);
11046   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11047   vat_json_object_add_string_copy (node, "interface_name",
11048                                    mp->interface_name);
11049   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
11050                             ntohl (mp->virtio_net_hdr_sz));
11051   vat_json_object_add_uint (node, "features",
11052                             clib_net_to_host_u64 (mp->features));
11053   vat_json_object_add_uint (node, "is_server", mp->is_server);
11054   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
11055   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
11056   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
11057 }
11058
11059 static int
11060 api_sw_interface_vhost_user_dump (vat_main_t * vam)
11061 {
11062   vl_api_sw_interface_vhost_user_dump_t *mp;
11063   f64 timeout;
11064   print (vam->ofp,
11065          "Interface name           idx hdr_sz features server regions filename");
11066
11067   /* Get list of vhost-user interfaces */
11068   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
11069   S;
11070
11071   /* Use a control ping for synchronization */
11072   {
11073     vl_api_control_ping_t *mp;
11074     M (CONTROL_PING, control_ping);
11075     S;
11076   }
11077   W;
11078 }
11079
11080 static int
11081 api_show_version (vat_main_t * vam)
11082 {
11083   vl_api_show_version_t *mp;
11084   f64 timeout;
11085
11086   M (SHOW_VERSION, show_version);
11087
11088   S;
11089   W;
11090   /* NOTREACHED */
11091   return 0;
11092 }
11093
11094
11095 static int
11096 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11097 {
11098   unformat_input_t *line_input = vam->input;
11099   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11100   f64 timeout;
11101   ip4_address_t local4, remote4;
11102   ip6_address_t local6, remote6;
11103   u8 is_add = 1;
11104   u8 ipv4_set = 0, ipv6_set = 0;
11105   u8 local_set = 0;
11106   u8 remote_set = 0;
11107   u32 encap_vrf_id = 0;
11108   u32 decap_vrf_id = 0;
11109   u8 protocol = ~0;
11110   u32 vni;
11111   u8 vni_set = 0;
11112
11113   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11114     {
11115       if (unformat (line_input, "del"))
11116         is_add = 0;
11117       else if (unformat (line_input, "local %U",
11118                          unformat_ip4_address, &local4))
11119         {
11120           local_set = 1;
11121           ipv4_set = 1;
11122         }
11123       else if (unformat (line_input, "remote %U",
11124                          unformat_ip4_address, &remote4))
11125         {
11126           remote_set = 1;
11127           ipv4_set = 1;
11128         }
11129       else if (unformat (line_input, "local %U",
11130                          unformat_ip6_address, &local6))
11131         {
11132           local_set = 1;
11133           ipv6_set = 1;
11134         }
11135       else if (unformat (line_input, "remote %U",
11136                          unformat_ip6_address, &remote6))
11137         {
11138           remote_set = 1;
11139           ipv6_set = 1;
11140         }
11141       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11142         ;
11143       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11144         ;
11145       else if (unformat (line_input, "vni %d", &vni))
11146         vni_set = 1;
11147       else if (unformat (line_input, "next-ip4"))
11148         protocol = 1;
11149       else if (unformat (line_input, "next-ip6"))
11150         protocol = 2;
11151       else if (unformat (line_input, "next-ethernet"))
11152         protocol = 3;
11153       else if (unformat (line_input, "next-nsh"))
11154         protocol = 4;
11155       else
11156         {
11157           errmsg ("parse error '%U'", format_unformat_error, line_input);
11158           return -99;
11159         }
11160     }
11161
11162   if (local_set == 0)
11163     {
11164       errmsg ("tunnel local address not specified");
11165       return -99;
11166     }
11167   if (remote_set == 0)
11168     {
11169       errmsg ("tunnel remote address not specified");
11170       return -99;
11171     }
11172   if (ipv4_set && ipv6_set)
11173     {
11174       errmsg ("both IPv4 and IPv6 addresses specified");
11175       return -99;
11176     }
11177
11178   if (vni_set == 0)
11179     {
11180       errmsg ("vni not specified");
11181       return -99;
11182     }
11183
11184   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
11185
11186
11187   if (ipv6_set)
11188     {
11189       clib_memcpy (&mp->local, &local6, sizeof (local6));
11190       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11191     }
11192   else
11193     {
11194       clib_memcpy (&mp->local, &local4, sizeof (local4));
11195       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11196     }
11197
11198   mp->encap_vrf_id = ntohl (encap_vrf_id);
11199   mp->decap_vrf_id = ntohl (decap_vrf_id);
11200   mp->protocol = protocol;
11201   mp->vni = ntohl (vni);
11202   mp->is_add = is_add;
11203   mp->is_ipv6 = ipv6_set;
11204
11205   S;
11206   W;
11207   /* NOTREACHED */
11208   return 0;
11209 }
11210
11211 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11212   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11213 {
11214   vat_main_t *vam = &vat_main;
11215
11216   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11217          ntohl (mp->sw_if_index),
11218          format_ip46_address, &(mp->local[0]),
11219          format_ip46_address, &(mp->remote[0]),
11220          ntohl (mp->vni),
11221          ntohl (mp->protocol),
11222          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11223 }
11224
11225 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11226   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11227 {
11228   vat_main_t *vam = &vat_main;
11229   vat_json_node_t *node = NULL;
11230   struct in_addr ip4;
11231   struct in6_addr ip6;
11232
11233   if (VAT_JSON_ARRAY != vam->json_tree.type)
11234     {
11235       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11236       vat_json_init_array (&vam->json_tree);
11237     }
11238   node = vat_json_array_add (&vam->json_tree);
11239
11240   vat_json_init_object (node);
11241   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11242   if (mp->is_ipv6)
11243     {
11244       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11245       vat_json_object_add_ip6 (node, "local", ip6);
11246       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11247       vat_json_object_add_ip6 (node, "remote", ip6);
11248     }
11249   else
11250     {
11251       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11252       vat_json_object_add_ip4 (node, "local", ip4);
11253       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11254       vat_json_object_add_ip4 (node, "remote", ip4);
11255     }
11256   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11257   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11258   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11259   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11260   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11261 }
11262
11263 static int
11264 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11265 {
11266   unformat_input_t *i = vam->input;
11267   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11268   f64 timeout;
11269   u32 sw_if_index;
11270   u8 sw_if_index_set = 0;
11271
11272   /* Parse args required to build the message */
11273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11274     {
11275       if (unformat (i, "sw_if_index %d", &sw_if_index))
11276         sw_if_index_set = 1;
11277       else
11278         break;
11279     }
11280
11281   if (sw_if_index_set == 0)
11282     {
11283       sw_if_index = ~0;
11284     }
11285
11286   if (!vam->json_output)
11287     {
11288       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11289              "sw_if_index", "local", "remote", "vni",
11290              "protocol", "encap_vrf_id", "decap_vrf_id");
11291     }
11292
11293   /* Get list of vxlan-tunnel interfaces */
11294   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11295
11296   mp->sw_if_index = htonl (sw_if_index);
11297
11298   S;
11299
11300   /* Use a control ping for synchronization */
11301   {
11302     vl_api_control_ping_t *mp;
11303     M (CONTROL_PING, control_ping);
11304     S;
11305   }
11306   W;
11307 }
11308
11309 u8 *
11310 format_l2_fib_mac_address (u8 * s, va_list * args)
11311 {
11312   u8 *a = va_arg (*args, u8 *);
11313
11314   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11315                  a[2], a[3], a[4], a[5], a[6], a[7]);
11316 }
11317
11318 static void vl_api_l2_fib_table_entry_t_handler
11319   (vl_api_l2_fib_table_entry_t * mp)
11320 {
11321   vat_main_t *vam = &vat_main;
11322
11323   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11324          "       %d       %d     %d",
11325          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11326          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11327          mp->bvi_mac);
11328 }
11329
11330 static void vl_api_l2_fib_table_entry_t_handler_json
11331   (vl_api_l2_fib_table_entry_t * mp)
11332 {
11333   vat_main_t *vam = &vat_main;
11334   vat_json_node_t *node = NULL;
11335
11336   if (VAT_JSON_ARRAY != vam->json_tree.type)
11337     {
11338       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11339       vat_json_init_array (&vam->json_tree);
11340     }
11341   node = vat_json_array_add (&vam->json_tree);
11342
11343   vat_json_init_object (node);
11344   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11345   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11346   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11347   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11348   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11349   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11350 }
11351
11352 static int
11353 api_l2_fib_table_dump (vat_main_t * vam)
11354 {
11355   unformat_input_t *i = vam->input;
11356   vl_api_l2_fib_table_dump_t *mp;
11357   f64 timeout;
11358   u32 bd_id;
11359   u8 bd_id_set = 0;
11360
11361   /* Parse args required to build the message */
11362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11363     {
11364       if (unformat (i, "bd_id %d", &bd_id))
11365         bd_id_set = 1;
11366       else
11367         break;
11368     }
11369
11370   if (bd_id_set == 0)
11371     {
11372       errmsg ("missing bridge domain");
11373       return -99;
11374     }
11375
11376   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11377
11378   /* Get list of l2 fib entries */
11379   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11380
11381   mp->bd_id = ntohl (bd_id);
11382   S;
11383
11384   /* Use a control ping for synchronization */
11385   {
11386     vl_api_control_ping_t *mp;
11387     M (CONTROL_PING, control_ping);
11388     S;
11389   }
11390   W;
11391 }
11392
11393
11394 static int
11395 api_interface_name_renumber (vat_main_t * vam)
11396 {
11397   unformat_input_t *line_input = vam->input;
11398   vl_api_interface_name_renumber_t *mp;
11399   u32 sw_if_index = ~0;
11400   f64 timeout;
11401   u32 new_show_dev_instance = ~0;
11402
11403   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11404     {
11405       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11406                     &sw_if_index))
11407         ;
11408       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11409         ;
11410       else if (unformat (line_input, "new_show_dev_instance %d",
11411                          &new_show_dev_instance))
11412         ;
11413       else
11414         break;
11415     }
11416
11417   if (sw_if_index == ~0)
11418     {
11419       errmsg ("missing interface name or sw_if_index");
11420       return -99;
11421     }
11422
11423   if (new_show_dev_instance == ~0)
11424     {
11425       errmsg ("missing new_show_dev_instance");
11426       return -99;
11427     }
11428
11429   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11430
11431   mp->sw_if_index = ntohl (sw_if_index);
11432   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11433
11434   S;
11435   W;
11436 }
11437
11438 static int
11439 api_want_ip4_arp_events (vat_main_t * vam)
11440 {
11441   unformat_input_t *line_input = vam->input;
11442   vl_api_want_ip4_arp_events_t *mp;
11443   f64 timeout;
11444   ip4_address_t address;
11445   int address_set = 0;
11446   u32 enable_disable = 1;
11447
11448   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11449     {
11450       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11451         address_set = 1;
11452       else if (unformat (line_input, "del"))
11453         enable_disable = 0;
11454       else
11455         break;
11456     }
11457
11458   if (address_set == 0)
11459     {
11460       errmsg ("missing addresses");
11461       return -99;
11462     }
11463
11464   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11465   mp->enable_disable = enable_disable;
11466   mp->pid = getpid ();
11467   mp->address = address.as_u32;
11468
11469   S;
11470   W;
11471 }
11472
11473 static int
11474 api_want_ip6_nd_events (vat_main_t * vam)
11475 {
11476   unformat_input_t *line_input = vam->input;
11477   vl_api_want_ip6_nd_events_t *mp;
11478   f64 timeout;
11479   ip6_address_t address;
11480   int address_set = 0;
11481   u32 enable_disable = 1;
11482
11483   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11484     {
11485       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11486         address_set = 1;
11487       else if (unformat (line_input, "del"))
11488         enable_disable = 0;
11489       else
11490         break;
11491     }
11492
11493   if (address_set == 0)
11494     {
11495       errmsg ("missing addresses");
11496       return -99;
11497     }
11498
11499   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11500   mp->enable_disable = enable_disable;
11501   mp->pid = getpid ();
11502   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11503
11504   S;
11505   W;
11506 }
11507
11508 static int
11509 api_input_acl_set_interface (vat_main_t * vam)
11510 {
11511   unformat_input_t *i = vam->input;
11512   vl_api_input_acl_set_interface_t *mp;
11513   f64 timeout;
11514   u32 sw_if_index;
11515   int sw_if_index_set;
11516   u32 ip4_table_index = ~0;
11517   u32 ip6_table_index = ~0;
11518   u32 l2_table_index = ~0;
11519   u8 is_add = 1;
11520
11521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11522     {
11523       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11524         sw_if_index_set = 1;
11525       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11526         sw_if_index_set = 1;
11527       else if (unformat (i, "del"))
11528         is_add = 0;
11529       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11530         ;
11531       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11532         ;
11533       else if (unformat (i, "l2-table %d", &l2_table_index))
11534         ;
11535       else
11536         {
11537           clib_warning ("parse error '%U'", format_unformat_error, i);
11538           return -99;
11539         }
11540     }
11541
11542   if (sw_if_index_set == 0)
11543     {
11544       errmsg ("missing interface name or sw_if_index");
11545       return -99;
11546     }
11547
11548   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11549
11550   mp->sw_if_index = ntohl (sw_if_index);
11551   mp->ip4_table_index = ntohl (ip4_table_index);
11552   mp->ip6_table_index = ntohl (ip6_table_index);
11553   mp->l2_table_index = ntohl (l2_table_index);
11554   mp->is_add = is_add;
11555
11556   S;
11557   W;
11558   /* NOTREACHED */
11559   return 0;
11560 }
11561
11562 static int
11563 api_ip_address_dump (vat_main_t * vam)
11564 {
11565   unformat_input_t *i = vam->input;
11566   vl_api_ip_address_dump_t *mp;
11567   u32 sw_if_index = ~0;
11568   u8 sw_if_index_set = 0;
11569   u8 ipv4_set = 0;
11570   u8 ipv6_set = 0;
11571   f64 timeout;
11572
11573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11574     {
11575       if (unformat (i, "sw_if_index %d", &sw_if_index))
11576         sw_if_index_set = 1;
11577       else
11578         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11579         sw_if_index_set = 1;
11580       else if (unformat (i, "ipv4"))
11581         ipv4_set = 1;
11582       else if (unformat (i, "ipv6"))
11583         ipv6_set = 1;
11584       else
11585         break;
11586     }
11587
11588   if (ipv4_set && ipv6_set)
11589     {
11590       errmsg ("ipv4 and ipv6 flags cannot be both set");
11591       return -99;
11592     }
11593
11594   if ((!ipv4_set) && (!ipv6_set))
11595     {
11596       errmsg ("no ipv4 nor ipv6 flag set");
11597       return -99;
11598     }
11599
11600   if (sw_if_index_set == 0)
11601     {
11602       errmsg ("missing interface name or sw_if_index");
11603       return -99;
11604     }
11605
11606   vam->current_sw_if_index = sw_if_index;
11607   vam->is_ipv6 = ipv6_set;
11608
11609   M (IP_ADDRESS_DUMP, ip_address_dump);
11610   mp->sw_if_index = ntohl (sw_if_index);
11611   mp->is_ipv6 = ipv6_set;
11612   S;
11613
11614   /* Use a control ping for synchronization */
11615   {
11616     vl_api_control_ping_t *mp;
11617     M (CONTROL_PING, control_ping);
11618     S;
11619   }
11620   W;
11621 }
11622
11623 static int
11624 api_ip_dump (vat_main_t * vam)
11625 {
11626   vl_api_ip_dump_t *mp;
11627   unformat_input_t *in = vam->input;
11628   int ipv4_set = 0;
11629   int ipv6_set = 0;
11630   int is_ipv6;
11631   f64 timeout;
11632   int i;
11633
11634   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11635     {
11636       if (unformat (in, "ipv4"))
11637         ipv4_set = 1;
11638       else if (unformat (in, "ipv6"))
11639         ipv6_set = 1;
11640       else
11641         break;
11642     }
11643
11644   if (ipv4_set && ipv6_set)
11645     {
11646       errmsg ("ipv4 and ipv6 flags cannot be both set");
11647       return -99;
11648     }
11649
11650   if ((!ipv4_set) && (!ipv6_set))
11651     {
11652       errmsg ("no ipv4 nor ipv6 flag set");
11653       return -99;
11654     }
11655
11656   is_ipv6 = ipv6_set;
11657   vam->is_ipv6 = is_ipv6;
11658
11659   /* free old data */
11660   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11661     {
11662       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11663     }
11664   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11665
11666   M (IP_DUMP, ip_dump);
11667   mp->is_ipv6 = ipv6_set;
11668   S;
11669
11670   /* Use a control ping for synchronization */
11671   {
11672     vl_api_control_ping_t *mp;
11673     M (CONTROL_PING, control_ping);
11674     S;
11675   }
11676   W;
11677 }
11678
11679 static int
11680 api_ipsec_spd_add_del (vat_main_t * vam)
11681 {
11682   unformat_input_t *i = vam->input;
11683   vl_api_ipsec_spd_add_del_t *mp;
11684   f64 timeout;
11685   u32 spd_id = ~0;
11686   u8 is_add = 1;
11687
11688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11689     {
11690       if (unformat (i, "spd_id %d", &spd_id))
11691         ;
11692       else if (unformat (i, "del"))
11693         is_add = 0;
11694       else
11695         {
11696           clib_warning ("parse error '%U'", format_unformat_error, i);
11697           return -99;
11698         }
11699     }
11700   if (spd_id == ~0)
11701     {
11702       errmsg ("spd_id must be set");
11703       return -99;
11704     }
11705
11706   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11707
11708   mp->spd_id = ntohl (spd_id);
11709   mp->is_add = is_add;
11710
11711   S;
11712   W;
11713   /* NOTREACHED */
11714   return 0;
11715 }
11716
11717 static int
11718 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11719 {
11720   unformat_input_t *i = vam->input;
11721   vl_api_ipsec_interface_add_del_spd_t *mp;
11722   f64 timeout;
11723   u32 sw_if_index;
11724   u8 sw_if_index_set = 0;
11725   u32 spd_id = (u32) ~ 0;
11726   u8 is_add = 1;
11727
11728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11729     {
11730       if (unformat (i, "del"))
11731         is_add = 0;
11732       else if (unformat (i, "spd_id %d", &spd_id))
11733         ;
11734       else
11735         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11736         sw_if_index_set = 1;
11737       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11738         sw_if_index_set = 1;
11739       else
11740         {
11741           clib_warning ("parse error '%U'", format_unformat_error, i);
11742           return -99;
11743         }
11744
11745     }
11746
11747   if (spd_id == (u32) ~ 0)
11748     {
11749       errmsg ("spd_id must be set");
11750       return -99;
11751     }
11752
11753   if (sw_if_index_set == 0)
11754     {
11755       errmsg ("missing interface name or sw_if_index");
11756       return -99;
11757     }
11758
11759   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11760
11761   mp->spd_id = ntohl (spd_id);
11762   mp->sw_if_index = ntohl (sw_if_index);
11763   mp->is_add = is_add;
11764
11765   S;
11766   W;
11767   /* NOTREACHED */
11768   return 0;
11769 }
11770
11771 static int
11772 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11773 {
11774   unformat_input_t *i = vam->input;
11775   vl_api_ipsec_spd_add_del_entry_t *mp;
11776   f64 timeout;
11777   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11778   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11779   i32 priority = 0;
11780   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11781   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11782   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11783   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11784
11785   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11786   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11787   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11788   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11789   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11790   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11791
11792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11793     {
11794       if (unformat (i, "del"))
11795         is_add = 0;
11796       if (unformat (i, "outbound"))
11797         is_outbound = 1;
11798       if (unformat (i, "inbound"))
11799         is_outbound = 0;
11800       else if (unformat (i, "spd_id %d", &spd_id))
11801         ;
11802       else if (unformat (i, "sa_id %d", &sa_id))
11803         ;
11804       else if (unformat (i, "priority %d", &priority))
11805         ;
11806       else if (unformat (i, "protocol %d", &protocol))
11807         ;
11808       else if (unformat (i, "lport_start %d", &lport_start))
11809         ;
11810       else if (unformat (i, "lport_stop %d", &lport_stop))
11811         ;
11812       else if (unformat (i, "rport_start %d", &rport_start))
11813         ;
11814       else if (unformat (i, "rport_stop %d", &rport_stop))
11815         ;
11816       else
11817         if (unformat
11818             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11819         {
11820           is_ipv6 = 0;
11821           is_ip_any = 0;
11822         }
11823       else
11824         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11825         {
11826           is_ipv6 = 0;
11827           is_ip_any = 0;
11828         }
11829       else
11830         if (unformat
11831             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11832         {
11833           is_ipv6 = 0;
11834           is_ip_any = 0;
11835         }
11836       else
11837         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11838         {
11839           is_ipv6 = 0;
11840           is_ip_any = 0;
11841         }
11842       else
11843         if (unformat
11844             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11845         {
11846           is_ipv6 = 1;
11847           is_ip_any = 0;
11848         }
11849       else
11850         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11851         {
11852           is_ipv6 = 1;
11853           is_ip_any = 0;
11854         }
11855       else
11856         if (unformat
11857             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11858         {
11859           is_ipv6 = 1;
11860           is_ip_any = 0;
11861         }
11862       else
11863         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11864         {
11865           is_ipv6 = 1;
11866           is_ip_any = 0;
11867         }
11868       else
11869         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11870         {
11871           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11872             {
11873               clib_warning ("unsupported action: 'resolve'");
11874               return -99;
11875             }
11876         }
11877       else
11878         {
11879           clib_warning ("parse error '%U'", format_unformat_error, i);
11880           return -99;
11881         }
11882
11883     }
11884
11885   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11886
11887   mp->spd_id = ntohl (spd_id);
11888   mp->priority = ntohl (priority);
11889   mp->is_outbound = is_outbound;
11890
11891   mp->is_ipv6 = is_ipv6;
11892   if (is_ipv6 || is_ip_any)
11893     {
11894       clib_memcpy (mp->remote_address_start, &raddr6_start,
11895                    sizeof (ip6_address_t));
11896       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11897                    sizeof (ip6_address_t));
11898       clib_memcpy (mp->local_address_start, &laddr6_start,
11899                    sizeof (ip6_address_t));
11900       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11901                    sizeof (ip6_address_t));
11902     }
11903   else
11904     {
11905       clib_memcpy (mp->remote_address_start, &raddr4_start,
11906                    sizeof (ip4_address_t));
11907       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11908                    sizeof (ip4_address_t));
11909       clib_memcpy (mp->local_address_start, &laddr4_start,
11910                    sizeof (ip4_address_t));
11911       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11912                    sizeof (ip4_address_t));
11913     }
11914   mp->protocol = (u8) protocol;
11915   mp->local_port_start = ntohs ((u16) lport_start);
11916   mp->local_port_stop = ntohs ((u16) lport_stop);
11917   mp->remote_port_start = ntohs ((u16) rport_start);
11918   mp->remote_port_stop = ntohs ((u16) rport_stop);
11919   mp->policy = (u8) policy;
11920   mp->sa_id = ntohl (sa_id);
11921   mp->is_add = is_add;
11922   mp->is_ip_any = is_ip_any;
11923   S;
11924   W;
11925   /* NOTREACHED */
11926   return 0;
11927 }
11928
11929 static int
11930 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11931 {
11932   unformat_input_t *i = vam->input;
11933   vl_api_ipsec_sad_add_del_entry_t *mp;
11934   f64 timeout;
11935   u32 sad_id = 0, spi = 0;
11936   u8 *ck = 0, *ik = 0;
11937   u8 is_add = 1;
11938
11939   u8 protocol = IPSEC_PROTOCOL_AH;
11940   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11941   u32 crypto_alg = 0, integ_alg = 0;
11942   ip4_address_t tun_src4;
11943   ip4_address_t tun_dst4;
11944   ip6_address_t tun_src6;
11945   ip6_address_t tun_dst6;
11946
11947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11948     {
11949       if (unformat (i, "del"))
11950         is_add = 0;
11951       else if (unformat (i, "sad_id %d", &sad_id))
11952         ;
11953       else if (unformat (i, "spi %d", &spi))
11954         ;
11955       else if (unformat (i, "esp"))
11956         protocol = IPSEC_PROTOCOL_ESP;
11957       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11958         {
11959           is_tunnel = 1;
11960           is_tunnel_ipv6 = 0;
11961         }
11962       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11963         {
11964           is_tunnel = 1;
11965           is_tunnel_ipv6 = 0;
11966         }
11967       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11968         {
11969           is_tunnel = 1;
11970           is_tunnel_ipv6 = 1;
11971         }
11972       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11973         {
11974           is_tunnel = 1;
11975           is_tunnel_ipv6 = 1;
11976         }
11977       else
11978         if (unformat
11979             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11980         {
11981           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11982               crypto_alg >= IPSEC_CRYPTO_N_ALG)
11983             {
11984               clib_warning ("unsupported crypto-alg: '%U'",
11985                             format_ipsec_crypto_alg, crypto_alg);
11986               return -99;
11987             }
11988         }
11989       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11990         ;
11991       else
11992         if (unformat
11993             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11994         {
11995 #if DPDK_CRYPTO==1
11996           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
11997 #else
11998           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11999 #endif
12000               integ_alg >= IPSEC_INTEG_N_ALG)
12001             {
12002               clib_warning ("unsupported integ-alg: '%U'",
12003                             format_ipsec_integ_alg, integ_alg);
12004               return -99;
12005             }
12006         }
12007       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12008         ;
12009       else
12010         {
12011           clib_warning ("parse error '%U'", format_unformat_error, i);
12012           return -99;
12013         }
12014
12015     }
12016
12017 #if DPDK_CRYPTO==1
12018   /*Special cases, aes-gcm-128 encryption */
12019   if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
12020     {
12021       if (integ_alg != IPSEC_INTEG_ALG_NONE
12022           && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
12023         {
12024           clib_warning
12025             ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
12026           return -99;
12027         }
12028       else                      /*set integ-alg internally to aes-gcm-128 */
12029         integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
12030     }
12031   else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
12032     {
12033       clib_warning ("unsupported integ-alg: aes-gcm-128");
12034       return -99;
12035     }
12036   else if (integ_alg == IPSEC_INTEG_ALG_NONE)
12037     {
12038       clib_warning ("unsupported integ-alg: none");
12039       return -99;
12040     }
12041 #endif
12042
12043
12044   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
12045
12046   mp->sad_id = ntohl (sad_id);
12047   mp->is_add = is_add;
12048   mp->protocol = protocol;
12049   mp->spi = ntohl (spi);
12050   mp->is_tunnel = is_tunnel;
12051   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
12052   mp->crypto_algorithm = crypto_alg;
12053   mp->integrity_algorithm = integ_alg;
12054   mp->crypto_key_length = vec_len (ck);
12055   mp->integrity_key_length = vec_len (ik);
12056
12057   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12058     mp->crypto_key_length = sizeof (mp->crypto_key);
12059
12060   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12061     mp->integrity_key_length = sizeof (mp->integrity_key);
12062
12063   if (ck)
12064     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12065   if (ik)
12066     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12067
12068   if (is_tunnel)
12069     {
12070       if (is_tunnel_ipv6)
12071         {
12072           clib_memcpy (mp->tunnel_src_address, &tun_src6,
12073                        sizeof (ip6_address_t));
12074           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12075                        sizeof (ip6_address_t));
12076         }
12077       else
12078         {
12079           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12080                        sizeof (ip4_address_t));
12081           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12082                        sizeof (ip4_address_t));
12083         }
12084     }
12085
12086   S;
12087   W;
12088   /* NOTREACHED */
12089   return 0;
12090 }
12091
12092 static int
12093 api_ipsec_sa_set_key (vat_main_t * vam)
12094 {
12095   unformat_input_t *i = vam->input;
12096   vl_api_ipsec_sa_set_key_t *mp;
12097   f64 timeout;
12098   u32 sa_id;
12099   u8 *ck = 0, *ik = 0;
12100
12101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12102     {
12103       if (unformat (i, "sa_id %d", &sa_id))
12104         ;
12105       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12106         ;
12107       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12108         ;
12109       else
12110         {
12111           clib_warning ("parse error '%U'", format_unformat_error, i);
12112           return -99;
12113         }
12114     }
12115
12116   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
12117
12118   mp->sa_id = ntohl (sa_id);
12119   mp->crypto_key_length = vec_len (ck);
12120   mp->integrity_key_length = vec_len (ik);
12121
12122   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12123     mp->crypto_key_length = sizeof (mp->crypto_key);
12124
12125   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12126     mp->integrity_key_length = sizeof (mp->integrity_key);
12127
12128   if (ck)
12129     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12130   if (ik)
12131     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12132
12133   S;
12134   W;
12135   /* NOTREACHED */
12136   return 0;
12137 }
12138
12139 static int
12140 api_ikev2_profile_add_del (vat_main_t * vam)
12141 {
12142   unformat_input_t *i = vam->input;
12143   vl_api_ikev2_profile_add_del_t *mp;
12144   f64 timeout;
12145   u8 is_add = 1;
12146   u8 *name = 0;
12147
12148   const char *valid_chars = "a-zA-Z0-9_";
12149
12150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12151     {
12152       if (unformat (i, "del"))
12153         is_add = 0;
12154       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12155         vec_add1 (name, 0);
12156       else
12157         {
12158           errmsg ("parse error '%U'", format_unformat_error, i);
12159           return -99;
12160         }
12161     }
12162
12163   if (!vec_len (name))
12164     {
12165       errmsg ("profile name must be specified");
12166       return -99;
12167     }
12168
12169   if (vec_len (name) > 64)
12170     {
12171       errmsg ("profile name too long");
12172       return -99;
12173     }
12174
12175   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12176
12177   clib_memcpy (mp->name, name, vec_len (name));
12178   mp->is_add = is_add;
12179   vec_free (name);
12180
12181   S;
12182   W;
12183   /* NOTREACHED */
12184   return 0;
12185 }
12186
12187 static int
12188 api_ikev2_profile_set_auth (vat_main_t * vam)
12189 {
12190   unformat_input_t *i = vam->input;
12191   vl_api_ikev2_profile_set_auth_t *mp;
12192   f64 timeout;
12193   u8 *name = 0;
12194   u8 *data = 0;
12195   u32 auth_method = 0;
12196   u8 is_hex = 0;
12197
12198   const char *valid_chars = "a-zA-Z0-9_";
12199
12200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12201     {
12202       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12203         vec_add1 (name, 0);
12204       else if (unformat (i, "auth_method %U",
12205                          unformat_ikev2_auth_method, &auth_method))
12206         ;
12207       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12208         is_hex = 1;
12209       else if (unformat (i, "auth_data %v", &data))
12210         ;
12211       else
12212         {
12213           errmsg ("parse error '%U'", format_unformat_error, i);
12214           return -99;
12215         }
12216     }
12217
12218   if (!vec_len (name))
12219     {
12220       errmsg ("profile name must be specified");
12221       return -99;
12222     }
12223
12224   if (vec_len (name) > 64)
12225     {
12226       errmsg ("profile name too long");
12227       return -99;
12228     }
12229
12230   if (!vec_len (data))
12231     {
12232       errmsg ("auth_data must be specified");
12233       return -99;
12234     }
12235
12236   if (!auth_method)
12237     {
12238       errmsg ("auth_method must be specified");
12239       return -99;
12240     }
12241
12242   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12243
12244   mp->is_hex = is_hex;
12245   mp->auth_method = (u8) auth_method;
12246   mp->data_len = vec_len (data);
12247   clib_memcpy (mp->name, name, vec_len (name));
12248   clib_memcpy (mp->data, data, vec_len (data));
12249   vec_free (name);
12250   vec_free (data);
12251
12252   S;
12253   W;
12254   /* NOTREACHED */
12255   return 0;
12256 }
12257
12258 static int
12259 api_ikev2_profile_set_id (vat_main_t * vam)
12260 {
12261   unformat_input_t *i = vam->input;
12262   vl_api_ikev2_profile_set_id_t *mp;
12263   f64 timeout;
12264   u8 *name = 0;
12265   u8 *data = 0;
12266   u8 is_local = 0;
12267   u32 id_type = 0;
12268   ip4_address_t ip4;
12269
12270   const char *valid_chars = "a-zA-Z0-9_";
12271
12272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12273     {
12274       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12275         vec_add1 (name, 0);
12276       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12277         ;
12278       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12279         {
12280           data = vec_new (u8, 4);
12281           clib_memcpy (data, ip4.as_u8, 4);
12282         }
12283       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12284         ;
12285       else if (unformat (i, "id_data %v", &data))
12286         ;
12287       else if (unformat (i, "local"))
12288         is_local = 1;
12289       else if (unformat (i, "remote"))
12290         is_local = 0;
12291       else
12292         {
12293           errmsg ("parse error '%U'", format_unformat_error, i);
12294           return -99;
12295         }
12296     }
12297
12298   if (!vec_len (name))
12299     {
12300       errmsg ("profile name must be specified");
12301       return -99;
12302     }
12303
12304   if (vec_len (name) > 64)
12305     {
12306       errmsg ("profile name too long");
12307       return -99;
12308     }
12309
12310   if (!vec_len (data))
12311     {
12312       errmsg ("id_data must be specified");
12313       return -99;
12314     }
12315
12316   if (!id_type)
12317     {
12318       errmsg ("id_type must be specified");
12319       return -99;
12320     }
12321
12322   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12323
12324   mp->is_local = is_local;
12325   mp->id_type = (u8) id_type;
12326   mp->data_len = vec_len (data);
12327   clib_memcpy (mp->name, name, vec_len (name));
12328   clib_memcpy (mp->data, data, vec_len (data));
12329   vec_free (name);
12330   vec_free (data);
12331
12332   S;
12333   W;
12334   /* NOTREACHED */
12335   return 0;
12336 }
12337
12338 static int
12339 api_ikev2_profile_set_ts (vat_main_t * vam)
12340 {
12341   unformat_input_t *i = vam->input;
12342   vl_api_ikev2_profile_set_ts_t *mp;
12343   f64 timeout;
12344   u8 *name = 0;
12345   u8 is_local = 0;
12346   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12347   ip4_address_t start_addr, end_addr;
12348
12349   const char *valid_chars = "a-zA-Z0-9_";
12350
12351   start_addr.as_u32 = 0;
12352   end_addr.as_u32 = (u32) ~ 0;
12353
12354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12355     {
12356       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12357         vec_add1 (name, 0);
12358       else if (unformat (i, "protocol %d", &proto))
12359         ;
12360       else if (unformat (i, "start_port %d", &start_port))
12361         ;
12362       else if (unformat (i, "end_port %d", &end_port))
12363         ;
12364       else
12365         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12366         ;
12367       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12368         ;
12369       else if (unformat (i, "local"))
12370         is_local = 1;
12371       else if (unformat (i, "remote"))
12372         is_local = 0;
12373       else
12374         {
12375           errmsg ("parse error '%U'", format_unformat_error, i);
12376           return -99;
12377         }
12378     }
12379
12380   if (!vec_len (name))
12381     {
12382       errmsg ("profile name must be specified");
12383       return -99;
12384     }
12385
12386   if (vec_len (name) > 64)
12387     {
12388       errmsg ("profile name too long");
12389       return -99;
12390     }
12391
12392   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12393
12394   mp->is_local = is_local;
12395   mp->proto = (u8) proto;
12396   mp->start_port = (u16) start_port;
12397   mp->end_port = (u16) end_port;
12398   mp->start_addr = start_addr.as_u32;
12399   mp->end_addr = end_addr.as_u32;
12400   clib_memcpy (mp->name, name, vec_len (name));
12401   vec_free (name);
12402
12403   S;
12404   W;
12405   /* NOTREACHED */
12406   return 0;
12407 }
12408
12409 static int
12410 api_ikev2_set_local_key (vat_main_t * vam)
12411 {
12412   unformat_input_t *i = vam->input;
12413   vl_api_ikev2_set_local_key_t *mp;
12414   f64 timeout;
12415   u8 *file = 0;
12416
12417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12418     {
12419       if (unformat (i, "file %v", &file))
12420         vec_add1 (file, 0);
12421       else
12422         {
12423           errmsg ("parse error '%U'", format_unformat_error, i);
12424           return -99;
12425         }
12426     }
12427
12428   if (!vec_len (file))
12429     {
12430       errmsg ("RSA key file must be specified");
12431       return -99;
12432     }
12433
12434   if (vec_len (file) > 256)
12435     {
12436       errmsg ("file name too long");
12437       return -99;
12438     }
12439
12440   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12441
12442   clib_memcpy (mp->key_file, file, vec_len (file));
12443   vec_free (file);
12444
12445   S;
12446   W;
12447   /* NOTREACHED */
12448   return 0;
12449 }
12450
12451 /*
12452  * MAP
12453  */
12454 static int
12455 api_map_add_domain (vat_main_t * vam)
12456 {
12457   unformat_input_t *i = vam->input;
12458   vl_api_map_add_domain_t *mp;
12459   f64 timeout;
12460
12461   ip4_address_t ip4_prefix;
12462   ip6_address_t ip6_prefix;
12463   ip6_address_t ip6_src;
12464   u32 num_m_args = 0;
12465   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12466     0, psid_length = 0;
12467   u8 is_translation = 0;
12468   u32 mtu = 0;
12469   u32 ip6_src_len = 128;
12470
12471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12472     {
12473       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12474                     &ip4_prefix, &ip4_prefix_len))
12475         num_m_args++;
12476       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12477                          &ip6_prefix, &ip6_prefix_len))
12478         num_m_args++;
12479       else
12480         if (unformat
12481             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12482              &ip6_src_len))
12483         num_m_args++;
12484       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12485         num_m_args++;
12486       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12487         num_m_args++;
12488       else if (unformat (i, "psid-offset %d", &psid_offset))
12489         num_m_args++;
12490       else if (unformat (i, "psid-len %d", &psid_length))
12491         num_m_args++;
12492       else if (unformat (i, "mtu %d", &mtu))
12493         num_m_args++;
12494       else if (unformat (i, "map-t"))
12495         is_translation = 1;
12496       else
12497         {
12498           clib_warning ("parse error '%U'", format_unformat_error, i);
12499           return -99;
12500         }
12501     }
12502
12503   if (num_m_args < 3)
12504     {
12505       errmsg ("mandatory argument(s) missing");
12506       return -99;
12507     }
12508
12509   /* Construct the API message */
12510   M (MAP_ADD_DOMAIN, map_add_domain);
12511
12512   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12513   mp->ip4_prefix_len = ip4_prefix_len;
12514
12515   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12516   mp->ip6_prefix_len = ip6_prefix_len;
12517
12518   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12519   mp->ip6_src_prefix_len = ip6_src_len;
12520
12521   mp->ea_bits_len = ea_bits_len;
12522   mp->psid_offset = psid_offset;
12523   mp->psid_length = psid_length;
12524   mp->is_translation = is_translation;
12525   mp->mtu = htons (mtu);
12526
12527   /* send it... */
12528   S;
12529
12530   /* Wait for a reply, return good/bad news  */
12531   W;
12532 }
12533
12534 static int
12535 api_map_del_domain (vat_main_t * vam)
12536 {
12537   unformat_input_t *i = vam->input;
12538   vl_api_map_del_domain_t *mp;
12539   f64 timeout;
12540
12541   u32 num_m_args = 0;
12542   u32 index;
12543
12544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12545     {
12546       if (unformat (i, "index %d", &index))
12547         num_m_args++;
12548       else
12549         {
12550           clib_warning ("parse error '%U'", format_unformat_error, i);
12551           return -99;
12552         }
12553     }
12554
12555   if (num_m_args != 1)
12556     {
12557       errmsg ("mandatory argument(s) missing");
12558       return -99;
12559     }
12560
12561   /* Construct the API message */
12562   M (MAP_DEL_DOMAIN, map_del_domain);
12563
12564   mp->index = ntohl (index);
12565
12566   /* send it... */
12567   S;
12568
12569   /* Wait for a reply, return good/bad news  */
12570   W;
12571 }
12572
12573 static int
12574 api_map_add_del_rule (vat_main_t * vam)
12575 {
12576   unformat_input_t *i = vam->input;
12577   vl_api_map_add_del_rule_t *mp;
12578   f64 timeout;
12579   u8 is_add = 1;
12580   ip6_address_t ip6_dst;
12581   u32 num_m_args = 0, index, psid = 0;
12582
12583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12584     {
12585       if (unformat (i, "index %d", &index))
12586         num_m_args++;
12587       else if (unformat (i, "psid %d", &psid))
12588         num_m_args++;
12589       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12590         num_m_args++;
12591       else if (unformat (i, "del"))
12592         {
12593           is_add = 0;
12594         }
12595       else
12596         {
12597           clib_warning ("parse error '%U'", format_unformat_error, i);
12598           return -99;
12599         }
12600     }
12601
12602   /* Construct the API message */
12603   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12604
12605   mp->index = ntohl (index);
12606   mp->is_add = is_add;
12607   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12608   mp->psid = ntohs (psid);
12609
12610   /* send it... */
12611   S;
12612
12613   /* Wait for a reply, return good/bad news  */
12614   W;
12615 }
12616
12617 static int
12618 api_map_domain_dump (vat_main_t * vam)
12619 {
12620   vl_api_map_domain_dump_t *mp;
12621   f64 timeout;
12622
12623   /* Construct the API message */
12624   M (MAP_DOMAIN_DUMP, map_domain_dump);
12625
12626   /* send it... */
12627   S;
12628
12629   /* Use a control ping for synchronization */
12630   {
12631     vl_api_control_ping_t *mp;
12632     M (CONTROL_PING, control_ping);
12633     S;
12634   }
12635   W;
12636 }
12637
12638 static int
12639 api_map_rule_dump (vat_main_t * vam)
12640 {
12641   unformat_input_t *i = vam->input;
12642   vl_api_map_rule_dump_t *mp;
12643   f64 timeout;
12644   u32 domain_index = ~0;
12645
12646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12647     {
12648       if (unformat (i, "index %u", &domain_index))
12649         ;
12650       else
12651         break;
12652     }
12653
12654   if (domain_index == ~0)
12655     {
12656       clib_warning ("parse error: domain index expected");
12657       return -99;
12658     }
12659
12660   /* Construct the API message */
12661   M (MAP_RULE_DUMP, map_rule_dump);
12662
12663   mp->domain_index = htonl (domain_index);
12664
12665   /* send it... */
12666   S;
12667
12668   /* Use a control ping for synchronization */
12669   {
12670     vl_api_control_ping_t *mp;
12671     M (CONTROL_PING, control_ping);
12672     S;
12673   }
12674   W;
12675 }
12676
12677 static void vl_api_map_add_domain_reply_t_handler
12678   (vl_api_map_add_domain_reply_t * mp)
12679 {
12680   vat_main_t *vam = &vat_main;
12681   i32 retval = ntohl (mp->retval);
12682
12683   if (vam->async_mode)
12684     {
12685       vam->async_errors += (retval < 0);
12686     }
12687   else
12688     {
12689       vam->retval = retval;
12690       vam->result_ready = 1;
12691     }
12692 }
12693
12694 static void vl_api_map_add_domain_reply_t_handler_json
12695   (vl_api_map_add_domain_reply_t * mp)
12696 {
12697   vat_main_t *vam = &vat_main;
12698   vat_json_node_t node;
12699
12700   vat_json_init_object (&node);
12701   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12702   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12703
12704   vat_json_print (vam->ofp, &node);
12705   vat_json_free (&node);
12706
12707   vam->retval = ntohl (mp->retval);
12708   vam->result_ready = 1;
12709 }
12710
12711 static int
12712 api_get_first_msg_id (vat_main_t * vam)
12713 {
12714   vl_api_get_first_msg_id_t *mp;
12715   f64 timeout;
12716   unformat_input_t *i = vam->input;
12717   u8 *name;
12718   u8 name_set = 0;
12719
12720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12721     {
12722       if (unformat (i, "client %s", &name))
12723         name_set = 1;
12724       else
12725         break;
12726     }
12727
12728   if (name_set == 0)
12729     {
12730       errmsg ("missing client name");
12731       return -99;
12732     }
12733   vec_add1 (name, 0);
12734
12735   if (vec_len (name) > 63)
12736     {
12737       errmsg ("client name too long");
12738       return -99;
12739     }
12740
12741   M (GET_FIRST_MSG_ID, get_first_msg_id);
12742   clib_memcpy (mp->name, name, vec_len (name));
12743   S;
12744   W;
12745   /* NOTREACHED */
12746   return 0;
12747 }
12748
12749 static int
12750 api_cop_interface_enable_disable (vat_main_t * vam)
12751 {
12752   unformat_input_t *line_input = vam->input;
12753   vl_api_cop_interface_enable_disable_t *mp;
12754   f64 timeout;
12755   u32 sw_if_index = ~0;
12756   u8 enable_disable = 1;
12757
12758   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12759     {
12760       if (unformat (line_input, "disable"))
12761         enable_disable = 0;
12762       if (unformat (line_input, "enable"))
12763         enable_disable = 1;
12764       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12765                          vam, &sw_if_index))
12766         ;
12767       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12768         ;
12769       else
12770         break;
12771     }
12772
12773   if (sw_if_index == ~0)
12774     {
12775       errmsg ("missing interface name or sw_if_index");
12776       return -99;
12777     }
12778
12779   /* Construct the API message */
12780   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12781   mp->sw_if_index = ntohl (sw_if_index);
12782   mp->enable_disable = enable_disable;
12783
12784   /* send it... */
12785   S;
12786   /* Wait for the reply */
12787   W;
12788 }
12789
12790 static int
12791 api_cop_whitelist_enable_disable (vat_main_t * vam)
12792 {
12793   unformat_input_t *line_input = vam->input;
12794   vl_api_cop_whitelist_enable_disable_t *mp;
12795   f64 timeout;
12796   u32 sw_if_index = ~0;
12797   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12798   u32 fib_id = 0;
12799
12800   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12801     {
12802       if (unformat (line_input, "ip4"))
12803         ip4 = 1;
12804       else if (unformat (line_input, "ip6"))
12805         ip6 = 1;
12806       else if (unformat (line_input, "default"))
12807         default_cop = 1;
12808       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12809                          vam, &sw_if_index))
12810         ;
12811       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12812         ;
12813       else if (unformat (line_input, "fib-id %d", &fib_id))
12814         ;
12815       else
12816         break;
12817     }
12818
12819   if (sw_if_index == ~0)
12820     {
12821       errmsg ("missing interface name or sw_if_index");
12822       return -99;
12823     }
12824
12825   /* Construct the API message */
12826   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12827   mp->sw_if_index = ntohl (sw_if_index);
12828   mp->fib_id = ntohl (fib_id);
12829   mp->ip4 = ip4;
12830   mp->ip6 = ip6;
12831   mp->default_cop = default_cop;
12832
12833   /* send it... */
12834   S;
12835   /* Wait for the reply */
12836   W;
12837 }
12838
12839 static int
12840 api_get_node_graph (vat_main_t * vam)
12841 {
12842   vl_api_get_node_graph_t *mp;
12843   f64 timeout;
12844
12845   M (GET_NODE_GRAPH, get_node_graph);
12846
12847   /* send it... */
12848   S;
12849   /* Wait for the reply */
12850   W;
12851 }
12852
12853 /* *INDENT-OFF* */
12854 /** Used for parsing LISP eids */
12855 typedef CLIB_PACKED(struct{
12856   u8 addr[16];   /**< eid address */
12857   u32 len;       /**< prefix length if IP */
12858   u8 type;      /**< type of eid */
12859 }) lisp_eid_vat_t;
12860 /* *INDENT-ON* */
12861
12862 static uword
12863 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12864 {
12865   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12866
12867   memset (a, 0, sizeof (a[0]));
12868
12869   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12870     {
12871       a->type = 0;              /* ipv4 type */
12872     }
12873   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12874     {
12875       a->type = 1;              /* ipv6 type */
12876     }
12877   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12878     {
12879       a->type = 2;              /* mac type */
12880     }
12881   else
12882     {
12883       return 0;
12884     }
12885
12886   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12887     {
12888       return 0;
12889     }
12890
12891   return 1;
12892 }
12893
12894 static int
12895 lisp_eid_size_vat (u8 type)
12896 {
12897   switch (type)
12898     {
12899     case 0:
12900       return 4;
12901     case 1:
12902       return 16;
12903     case 2:
12904       return 6;
12905     }
12906   return 0;
12907 }
12908
12909 static void
12910 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12911 {
12912   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12913 }
12914
12915 /* *INDENT-OFF* */
12916 /** Used for transferring locators via VPP API */
12917 typedef CLIB_PACKED(struct
12918 {
12919   u32 sw_if_index; /**< locator sw_if_index */
12920   u8 priority; /**< locator priority */
12921   u8 weight;   /**< locator weight */
12922 }) ls_locator_t;
12923 /* *INDENT-ON* */
12924
12925 static int
12926 api_lisp_add_del_locator_set (vat_main_t * vam)
12927 {
12928   unformat_input_t *input = vam->input;
12929   vl_api_lisp_add_del_locator_set_t *mp;
12930   f64 timeout = ~0;
12931   u8 is_add = 1;
12932   u8 *locator_set_name = NULL;
12933   u8 locator_set_name_set = 0;
12934   ls_locator_t locator, *locators = 0;
12935   u32 sw_if_index, priority, weight;
12936   u32 data_len = 0;
12937
12938   /* Parse args required to build the message */
12939   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12940     {
12941       if (unformat (input, "del"))
12942         {
12943           is_add = 0;
12944         }
12945       else if (unformat (input, "locator-set %s", &locator_set_name))
12946         {
12947           locator_set_name_set = 1;
12948         }
12949       else if (unformat (input, "sw_if_index %u p %u w %u",
12950                          &sw_if_index, &priority, &weight))
12951         {
12952           locator.sw_if_index = htonl (sw_if_index);
12953           locator.priority = priority;
12954           locator.weight = weight;
12955           vec_add1 (locators, locator);
12956         }
12957       else
12958         if (unformat
12959             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
12960              &sw_if_index, &priority, &weight))
12961         {
12962           locator.sw_if_index = htonl (sw_if_index);
12963           locator.priority = priority;
12964           locator.weight = weight;
12965           vec_add1 (locators, locator);
12966         }
12967       else
12968         break;
12969     }
12970
12971   if (locator_set_name_set == 0)
12972     {
12973       errmsg ("missing locator-set name");
12974       vec_free (locators);
12975       return -99;
12976     }
12977
12978   if (vec_len (locator_set_name) > 64)
12979     {
12980       errmsg ("locator-set name too long");
12981       vec_free (locator_set_name);
12982       vec_free (locators);
12983       return -99;
12984     }
12985   vec_add1 (locator_set_name, 0);
12986
12987   data_len = sizeof (ls_locator_t) * vec_len (locators);
12988
12989   /* Construct the API message */
12990   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12991
12992   mp->is_add = is_add;
12993   clib_memcpy (mp->locator_set_name, locator_set_name,
12994                vec_len (locator_set_name));
12995   vec_free (locator_set_name);
12996
12997   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12998   if (locators)
12999     clib_memcpy (mp->locators, locators, data_len);
13000   vec_free (locators);
13001
13002   /* send it... */
13003   S;
13004
13005   /* Wait for a reply... */
13006   W;
13007
13008   /* NOTREACHED */
13009   return 0;
13010 }
13011
13012 static int
13013 api_lisp_add_del_locator (vat_main_t * vam)
13014 {
13015   unformat_input_t *input = vam->input;
13016   vl_api_lisp_add_del_locator_t *mp;
13017   f64 timeout = ~0;
13018   u32 tmp_if_index = ~0;
13019   u32 sw_if_index = ~0;
13020   u8 sw_if_index_set = 0;
13021   u8 sw_if_index_if_name_set = 0;
13022   u32 priority = ~0;
13023   u8 priority_set = 0;
13024   u32 weight = ~0;
13025   u8 weight_set = 0;
13026   u8 is_add = 1;
13027   u8 *locator_set_name = NULL;
13028   u8 locator_set_name_set = 0;
13029
13030   /* Parse args required to build the message */
13031   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13032     {
13033       if (unformat (input, "del"))
13034         {
13035           is_add = 0;
13036         }
13037       else if (unformat (input, "locator-set %s", &locator_set_name))
13038         {
13039           locator_set_name_set = 1;
13040         }
13041       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
13042                          &tmp_if_index))
13043         {
13044           sw_if_index_if_name_set = 1;
13045           sw_if_index = tmp_if_index;
13046         }
13047       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
13048         {
13049           sw_if_index_set = 1;
13050           sw_if_index = tmp_if_index;
13051         }
13052       else if (unformat (input, "p %d", &priority))
13053         {
13054           priority_set = 1;
13055         }
13056       else if (unformat (input, "w %d", &weight))
13057         {
13058           weight_set = 1;
13059         }
13060       else
13061         break;
13062     }
13063
13064   if (locator_set_name_set == 0)
13065     {
13066       errmsg ("missing locator-set name");
13067       return -99;
13068     }
13069
13070   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
13071     {
13072       errmsg ("missing sw_if_index");
13073       vec_free (locator_set_name);
13074       return -99;
13075     }
13076
13077   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13078     {
13079       errmsg ("cannot use both params interface name and sw_if_index");
13080       vec_free (locator_set_name);
13081       return -99;
13082     }
13083
13084   if (priority_set == 0)
13085     {
13086       errmsg ("missing locator-set priority");
13087       vec_free (locator_set_name);
13088       return -99;
13089     }
13090
13091   if (weight_set == 0)
13092     {
13093       errmsg ("missing locator-set weight");
13094       vec_free (locator_set_name);
13095       return -99;
13096     }
13097
13098   if (vec_len (locator_set_name) > 64)
13099     {
13100       errmsg ("locator-set name too long");
13101       vec_free (locator_set_name);
13102       return -99;
13103     }
13104   vec_add1 (locator_set_name, 0);
13105
13106   /* Construct the API message */
13107   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
13108
13109   mp->is_add = is_add;
13110   mp->sw_if_index = ntohl (sw_if_index);
13111   mp->priority = priority;
13112   mp->weight = weight;
13113   clib_memcpy (mp->locator_set_name, locator_set_name,
13114                vec_len (locator_set_name));
13115   vec_free (locator_set_name);
13116
13117   /* send it... */
13118   S;
13119
13120   /* Wait for a reply... */
13121   W;
13122
13123   /* NOTREACHED */
13124   return 0;
13125 }
13126
13127 uword
13128 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13129 {
13130   u32 *key_id = va_arg (*args, u32 *);
13131   u8 *s = 0;
13132
13133   if (unformat (input, "%s", &s))
13134     {
13135       if (!strcmp ((char *) s, "sha1"))
13136         key_id[0] = HMAC_SHA_1_96;
13137       else if (!strcmp ((char *) s, "sha256"))
13138         key_id[0] = HMAC_SHA_256_128;
13139       else
13140         {
13141           clib_warning ("invalid key_id: '%s'", s);
13142           key_id[0] = HMAC_NO_KEY;
13143         }
13144     }
13145   else
13146     return 0;
13147
13148   vec_free (s);
13149   return 1;
13150 }
13151
13152 static int
13153 api_lisp_add_del_local_eid (vat_main_t * vam)
13154 {
13155   unformat_input_t *input = vam->input;
13156   vl_api_lisp_add_del_local_eid_t *mp;
13157   f64 timeout = ~0;
13158   u8 is_add = 1;
13159   u8 eid_set = 0;
13160   lisp_eid_vat_t _eid, *eid = &_eid;
13161   u8 *locator_set_name = 0;
13162   u8 locator_set_name_set = 0;
13163   u32 vni = 0;
13164   u16 key_id = 0;
13165   u8 *key = 0;
13166
13167   /* Parse args required to build the message */
13168   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13169     {
13170       if (unformat (input, "del"))
13171         {
13172           is_add = 0;
13173         }
13174       else if (unformat (input, "vni %d", &vni))
13175         {
13176           ;
13177         }
13178       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13179         {
13180           eid_set = 1;
13181         }
13182       else if (unformat (input, "locator-set %s", &locator_set_name))
13183         {
13184           locator_set_name_set = 1;
13185         }
13186       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13187         ;
13188       else if (unformat (input, "secret-key %_%v%_", &key))
13189         ;
13190       else
13191         break;
13192     }
13193
13194   if (locator_set_name_set == 0)
13195     {
13196       errmsg ("missing locator-set name");
13197       return -99;
13198     }
13199
13200   if (0 == eid_set)
13201     {
13202       errmsg ("EID address not set!");
13203       vec_free (locator_set_name);
13204       return -99;
13205     }
13206
13207   if (key && (0 == key_id))
13208     {
13209       errmsg ("invalid key_id!");
13210       return -99;
13211     }
13212
13213   if (vec_len (key) > 64)
13214     {
13215       errmsg ("key too long");
13216       vec_free (key);
13217       return -99;
13218     }
13219
13220   if (vec_len (locator_set_name) > 64)
13221     {
13222       errmsg ("locator-set name too long");
13223       vec_free (locator_set_name);
13224       return -99;
13225     }
13226   vec_add1 (locator_set_name, 0);
13227
13228   /* Construct the API message */
13229   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13230
13231   mp->is_add = is_add;
13232   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13233   mp->eid_type = eid->type;
13234   mp->prefix_len = eid->len;
13235   mp->vni = clib_host_to_net_u32 (vni);
13236   mp->key_id = clib_host_to_net_u16 (key_id);
13237   clib_memcpy (mp->locator_set_name, locator_set_name,
13238                vec_len (locator_set_name));
13239   clib_memcpy (mp->key, key, vec_len (key));
13240
13241   vec_free (locator_set_name);
13242   vec_free (key);
13243
13244   /* send it... */
13245   S;
13246
13247   /* Wait for a reply... */
13248   W;
13249
13250   /* NOTREACHED */
13251   return 0;
13252 }
13253
13254 /* *INDENT-OFF* */
13255 /** Used for transferring locators via VPP API */
13256 typedef CLIB_PACKED(struct
13257 {
13258   u8 is_ip4; /**< is locator an IPv4 address? */
13259   u8 priority; /**< locator priority */
13260   u8 weight;   /**< locator weight */
13261   u8 addr[16]; /**< IPv4/IPv6 address */
13262 }) rloc_t;
13263 /* *INDENT-ON* */
13264
13265 static int
13266 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13267 {
13268   unformat_input_t *input = vam->input;
13269   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13270   f64 timeout = ~0;
13271   u8 is_add = 1;
13272   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13273   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13274   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13275   u32 action = ~0, p, w;
13276   ip4_address_t rmt_rloc4, lcl_rloc4;
13277   ip6_address_t rmt_rloc6, lcl_rloc6;
13278   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13279
13280   memset (&rloc, 0, sizeof (rloc));
13281
13282   /* Parse args required to build the message */
13283   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13284     {
13285       if (unformat (input, "del"))
13286         {
13287           is_add = 0;
13288         }
13289       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
13290         {
13291           rmt_eid_set = 1;
13292         }
13293       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
13294         {
13295           lcl_eid_set = 1;
13296         }
13297       else if (unformat (input, "p %d w %d", &p, &w))
13298         {
13299           if (!curr_rloc)
13300             {
13301               errmsg ("No RLOC configured for setting priority/weight!");
13302               return -99;
13303             }
13304           curr_rloc->priority = p;
13305           curr_rloc->weight = w;
13306         }
13307       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13308                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13309         {
13310           rloc.is_ip4 = 1;
13311
13312           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13313           rloc.priority = rloc.weight = 0;
13314           vec_add1 (lcl_locs, rloc);
13315
13316           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13317           vec_add1 (rmt_locs, rloc);
13318           /* priority and weight saved in rmt loc */
13319           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13320         }
13321       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13322                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13323         {
13324           rloc.is_ip4 = 0;
13325           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13326           rloc.priority = rloc.weight = 0;
13327           vec_add1 (lcl_locs, rloc);
13328
13329           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13330           vec_add1 (rmt_locs, rloc);
13331           /* priority and weight saved in rmt loc */
13332           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13333         }
13334       else if (unformat (input, "action %d", &action))
13335         {
13336           ;
13337         }
13338       else
13339         {
13340           clib_warning ("parse error '%U'", format_unformat_error, input);
13341           return -99;
13342         }
13343     }
13344
13345   if (!rmt_eid_set)
13346     {
13347       errmsg ("remote eid addresses not set");
13348       return -99;
13349     }
13350
13351   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13352     {
13353       errmsg ("eid types don't match");
13354       return -99;
13355     }
13356
13357   if (0 == rmt_locs && (u32) ~ 0 == action)
13358     {
13359       errmsg ("action not set for negative mapping");
13360       return -99;
13361     }
13362
13363   /* Construct the API message */
13364   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13365
13366   mp->is_add = is_add;
13367   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13368   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13369   mp->eid_type = rmt_eid->type;
13370   mp->rmt_len = rmt_eid->len;
13371   mp->lcl_len = lcl_eid->len;
13372   mp->action = action;
13373
13374   if (0 != rmt_locs && 0 != lcl_locs)
13375     {
13376       mp->loc_num = vec_len (rmt_locs);
13377       clib_memcpy (mp->lcl_locs, lcl_locs,
13378                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13379       clib_memcpy (mp->rmt_locs, rmt_locs,
13380                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13381     }
13382   vec_free (lcl_locs);
13383   vec_free (rmt_locs);
13384
13385   /* send it... */
13386   S;
13387
13388   /* Wait for a reply... */
13389   W;
13390
13391   /* NOTREACHED */
13392   return 0;
13393 }
13394
13395 static int
13396 api_lisp_add_del_map_server (vat_main_t * vam)
13397 {
13398   unformat_input_t *input = vam->input;
13399   vl_api_lisp_add_del_map_server_t *mp;
13400   f64 timeout = ~0;
13401   u8 is_add = 1;
13402   u8 ipv4_set = 0;
13403   u8 ipv6_set = 0;
13404   ip4_address_t ipv4;
13405   ip6_address_t ipv6;
13406
13407   /* Parse args required to build the message */
13408   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13409     {
13410       if (unformat (input, "del"))
13411         {
13412           is_add = 0;
13413         }
13414       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13415         {
13416           ipv4_set = 1;
13417         }
13418       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13419         {
13420           ipv6_set = 1;
13421         }
13422       else
13423         break;
13424     }
13425
13426   if (ipv4_set && ipv6_set)
13427     {
13428       errmsg ("both eid v4 and v6 addresses set");
13429       return -99;
13430     }
13431
13432   if (!ipv4_set && !ipv6_set)
13433     {
13434       errmsg ("eid addresses not set");
13435       return -99;
13436     }
13437
13438   /* Construct the API message */
13439   M (LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server);
13440
13441   mp->is_add = is_add;
13442   if (ipv6_set)
13443     {
13444       mp->is_ipv6 = 1;
13445       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13446     }
13447   else
13448     {
13449       mp->is_ipv6 = 0;
13450       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13451     }
13452
13453   /* send it... */
13454   S;
13455
13456   /* Wait for a reply... */
13457   W;
13458
13459   /* NOTREACHED */
13460   return 0;
13461 }
13462
13463 static int
13464 api_lisp_add_del_map_resolver (vat_main_t * vam)
13465 {
13466   unformat_input_t *input = vam->input;
13467   vl_api_lisp_add_del_map_resolver_t *mp;
13468   f64 timeout = ~0;
13469   u8 is_add = 1;
13470   u8 ipv4_set = 0;
13471   u8 ipv6_set = 0;
13472   ip4_address_t ipv4;
13473   ip6_address_t ipv6;
13474
13475   /* Parse args required to build the message */
13476   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13477     {
13478       if (unformat (input, "del"))
13479         {
13480           is_add = 0;
13481         }
13482       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13483         {
13484           ipv4_set = 1;
13485         }
13486       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13487         {
13488           ipv6_set = 1;
13489         }
13490       else
13491         break;
13492     }
13493
13494   if (ipv4_set && ipv6_set)
13495     {
13496       errmsg ("both eid v4 and v6 addresses set");
13497       return -99;
13498     }
13499
13500   if (!ipv4_set && !ipv6_set)
13501     {
13502       errmsg ("eid addresses not set");
13503       return -99;
13504     }
13505
13506   /* Construct the API message */
13507   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13508
13509   mp->is_add = is_add;
13510   if (ipv6_set)
13511     {
13512       mp->is_ipv6 = 1;
13513       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13514     }
13515   else
13516     {
13517       mp->is_ipv6 = 0;
13518       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13519     }
13520
13521   /* send it... */
13522   S;
13523
13524   /* Wait for a reply... */
13525   W;
13526
13527   /* NOTREACHED */
13528   return 0;
13529 }
13530
13531 static int
13532 api_lisp_gpe_enable_disable (vat_main_t * vam)
13533 {
13534   unformat_input_t *input = vam->input;
13535   vl_api_lisp_gpe_enable_disable_t *mp;
13536   f64 timeout = ~0;
13537   u8 is_set = 0;
13538   u8 is_en = 1;
13539
13540   /* Parse args required to build the message */
13541   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13542     {
13543       if (unformat (input, "enable"))
13544         {
13545           is_set = 1;
13546           is_en = 1;
13547         }
13548       else if (unformat (input, "disable"))
13549         {
13550           is_set = 1;
13551           is_en = 0;
13552         }
13553       else
13554         break;
13555     }
13556
13557   if (is_set == 0)
13558     {
13559       errmsg ("Value not set");
13560       return -99;
13561     }
13562
13563   /* Construct the API message */
13564   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13565
13566   mp->is_en = is_en;
13567
13568   /* send it... */
13569   S;
13570
13571   /* Wait for a reply... */
13572   W;
13573
13574   /* NOTREACHED */
13575   return 0;
13576 }
13577
13578 static int
13579 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13580 {
13581   unformat_input_t *input = vam->input;
13582   vl_api_lisp_rloc_probe_enable_disable_t *mp;
13583   f64 timeout = ~0;
13584   u8 is_set = 0;
13585   u8 is_en = 0;
13586
13587   /* Parse args required to build the message */
13588   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13589     {
13590       if (unformat (input, "enable"))
13591         {
13592           is_set = 1;
13593           is_en = 1;
13594         }
13595       else if (unformat (input, "disable"))
13596         is_set = 1;
13597       else
13598         break;
13599     }
13600
13601   if (!is_set)
13602     {
13603       errmsg ("Value not set");
13604       return -99;
13605     }
13606
13607   /* Construct the API message */
13608   M (LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable);
13609
13610   mp->is_enabled = is_en;
13611
13612   /* send it... */
13613   S;
13614
13615   /* Wait for a reply... */
13616   W;
13617
13618   /* NOTREACHED */
13619   return 0;
13620 }
13621
13622 static int
13623 api_lisp_map_register_enable_disable (vat_main_t * vam)
13624 {
13625   unformat_input_t *input = vam->input;
13626   vl_api_lisp_map_register_enable_disable_t *mp;
13627   f64 timeout = ~0;
13628   u8 is_set = 0;
13629   u8 is_en = 0;
13630
13631   /* Parse args required to build the message */
13632   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13633     {
13634       if (unformat (input, "enable"))
13635         {
13636           is_set = 1;
13637           is_en = 1;
13638         }
13639       else if (unformat (input, "disable"))
13640         is_set = 1;
13641       else
13642         break;
13643     }
13644
13645   if (!is_set)
13646     {
13647       errmsg ("Value not set");
13648       return -99;
13649     }
13650
13651   /* Construct the API message */
13652   M (LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable);
13653
13654   mp->is_enabled = is_en;
13655
13656   /* send it... */
13657   S;
13658
13659   /* Wait for a reply... */
13660   W;
13661
13662   /* NOTREACHED */
13663   return 0;
13664 }
13665
13666 static int
13667 api_lisp_enable_disable (vat_main_t * vam)
13668 {
13669   unformat_input_t *input = vam->input;
13670   vl_api_lisp_enable_disable_t *mp;
13671   f64 timeout = ~0;
13672   u8 is_set = 0;
13673   u8 is_en = 0;
13674
13675   /* Parse args required to build the message */
13676   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13677     {
13678       if (unformat (input, "enable"))
13679         {
13680           is_set = 1;
13681           is_en = 1;
13682         }
13683       else if (unformat (input, "disable"))
13684         {
13685           is_set = 1;
13686         }
13687       else
13688         break;
13689     }
13690
13691   if (!is_set)
13692     {
13693       errmsg ("Value not set");
13694       return -99;
13695     }
13696
13697   /* Construct the API message */
13698   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13699
13700   mp->is_en = is_en;
13701
13702   /* send it... */
13703   S;
13704
13705   /* Wait for a reply... */
13706   W;
13707
13708   /* NOTREACHED */
13709   return 0;
13710 }
13711
13712 static int
13713 api_show_lisp_map_register_state (vat_main_t * vam)
13714 {
13715   f64 timeout = ~0;
13716   vl_api_show_lisp_map_register_state_t *mp;
13717
13718   M (SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state);
13719
13720   /* send */
13721   S;
13722
13723   /* wait for reply */
13724   W;
13725
13726   return 0;
13727 }
13728
13729 static int
13730 api_show_lisp_rloc_probe_state (vat_main_t * vam)
13731 {
13732   f64 timeout = ~0;
13733   vl_api_show_lisp_rloc_probe_state_t *mp;
13734
13735   M (SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state);
13736
13737   /* send */
13738   S;
13739
13740   /* wait for reply */
13741   W;
13742
13743   return 0;
13744 }
13745
13746 static int
13747 api_show_lisp_map_request_mode (vat_main_t * vam)
13748 {
13749   f64 timeout = ~0;
13750   vl_api_show_lisp_map_request_mode_t *mp;
13751
13752   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13753
13754   /* send */
13755   S;
13756
13757   /* wait for reply */
13758   W;
13759
13760   return 0;
13761 }
13762
13763 static int
13764 api_lisp_map_request_mode (vat_main_t * vam)
13765 {
13766   f64 timeout = ~0;
13767   unformat_input_t *input = vam->input;
13768   vl_api_lisp_map_request_mode_t *mp;
13769   u8 mode = 0;
13770
13771   /* Parse args required to build the message */
13772   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13773     {
13774       if (unformat (input, "dst-only"))
13775         mode = 0;
13776       else if (unformat (input, "src-dst"))
13777         mode = 1;
13778       else
13779         {
13780           errmsg ("parse error '%U'", format_unformat_error, input);
13781           return -99;
13782         }
13783     }
13784
13785   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13786
13787   mp->mode = mode;
13788
13789   /* send */
13790   S;
13791
13792   /* wait for reply */
13793   W;
13794
13795   /* notreached */
13796   return 0;
13797 }
13798
13799 /**
13800  * Enable/disable LISP proxy ITR.
13801  *
13802  * @param vam vpp API test context
13803  * @return return code
13804  */
13805 static int
13806 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13807 {
13808   f64 timeout = ~0;
13809   u8 ls_name_set = 0;
13810   unformat_input_t *input = vam->input;
13811   vl_api_lisp_pitr_set_locator_set_t *mp;
13812   u8 is_add = 1;
13813   u8 *ls_name = 0;
13814
13815   /* Parse args required to build the message */
13816   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13817     {
13818       if (unformat (input, "del"))
13819         is_add = 0;
13820       else if (unformat (input, "locator-set %s", &ls_name))
13821         ls_name_set = 1;
13822       else
13823         {
13824           errmsg ("parse error '%U'", format_unformat_error, input);
13825           return -99;
13826         }
13827     }
13828
13829   if (!ls_name_set)
13830     {
13831       errmsg ("locator-set name not set!");
13832       return -99;
13833     }
13834
13835   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13836
13837   mp->is_add = is_add;
13838   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13839   vec_free (ls_name);
13840
13841   /* send */
13842   S;
13843
13844   /* wait for reply */
13845   W;
13846
13847   /* notreached */
13848   return 0;
13849 }
13850
13851 static int
13852 api_show_lisp_pitr (vat_main_t * vam)
13853 {
13854   vl_api_show_lisp_pitr_t *mp;
13855   f64 timeout = ~0;
13856
13857   if (!vam->json_output)
13858     {
13859       print (vam->ofp, "%=20s", "lisp status:");
13860     }
13861
13862   M (SHOW_LISP_PITR, show_lisp_pitr);
13863   /* send it... */
13864   S;
13865
13866   /* Wait for a reply... */
13867   W;
13868
13869   /* NOTREACHED */
13870   return 0;
13871 }
13872
13873 /**
13874  * Add/delete mapping between vni and vrf
13875  */
13876 static int
13877 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13878 {
13879   f64 timeout = ~0;
13880   unformat_input_t *input = vam->input;
13881   vl_api_lisp_eid_table_add_del_map_t *mp;
13882   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13883   u32 vni, vrf, bd_index;
13884
13885   /* Parse args required to build the message */
13886   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13887     {
13888       if (unformat (input, "del"))
13889         is_add = 0;
13890       else if (unformat (input, "vrf %d", &vrf))
13891         vrf_set = 1;
13892       else if (unformat (input, "bd_index %d", &bd_index))
13893         bd_index_set = 1;
13894       else if (unformat (input, "vni %d", &vni))
13895         vni_set = 1;
13896       else
13897         break;
13898     }
13899
13900   if (!vni_set || (!vrf_set && !bd_index_set))
13901     {
13902       errmsg ("missing arguments!");
13903       return -99;
13904     }
13905
13906   if (vrf_set && bd_index_set)
13907     {
13908       errmsg ("error: both vrf and bd entered!");
13909       return -99;
13910     }
13911
13912   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13913
13914   mp->is_add = is_add;
13915   mp->vni = htonl (vni);
13916   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13917   mp->is_l2 = bd_index_set;
13918
13919   /* send */
13920   S;
13921
13922   /* wait for reply */
13923   W;
13924
13925   /* notreached */
13926   return 0;
13927 }
13928
13929 uword
13930 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13931 {
13932   u32 *action = va_arg (*args, u32 *);
13933   u8 *s = 0;
13934
13935   if (unformat (input, "%s", &s))
13936     {
13937       if (!strcmp ((char *) s, "no-action"))
13938         action[0] = 0;
13939       else if (!strcmp ((char *) s, "natively-forward"))
13940         action[0] = 1;
13941       else if (!strcmp ((char *) s, "send-map-request"))
13942         action[0] = 2;
13943       else if (!strcmp ((char *) s, "drop"))
13944         action[0] = 3;
13945       else
13946         {
13947           clib_warning ("invalid action: '%s'", s);
13948           action[0] = 3;
13949         }
13950     }
13951   else
13952     return 0;
13953
13954   vec_free (s);
13955   return 1;
13956 }
13957
13958 /**
13959  * Add/del remote mapping to/from LISP control plane
13960  *
13961  * @param vam vpp API test context
13962  * @return return code
13963  */
13964 static int
13965 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13966 {
13967   unformat_input_t *input = vam->input;
13968   vl_api_lisp_add_del_remote_mapping_t *mp;
13969   f64 timeout = ~0;
13970   u32 vni = 0;
13971   lisp_eid_vat_t _eid, *eid = &_eid;
13972   lisp_eid_vat_t _seid, *seid = &_seid;
13973   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13974   u32 action = ~0, p, w, data_len;
13975   ip4_address_t rloc4;
13976   ip6_address_t rloc6;
13977   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13978
13979   memset (&rloc, 0, sizeof (rloc));
13980
13981   /* Parse args required to build the message */
13982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13983     {
13984       if (unformat (input, "del-all"))
13985         {
13986           del_all = 1;
13987         }
13988       else if (unformat (input, "del"))
13989         {
13990           is_add = 0;
13991         }
13992       else if (unformat (input, "add"))
13993         {
13994           is_add = 1;
13995         }
13996       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13997         {
13998           eid_set = 1;
13999         }
14000       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
14001         {
14002           seid_set = 1;
14003         }
14004       else if (unformat (input, "vni %d", &vni))
14005         {
14006           ;
14007         }
14008       else if (unformat (input, "p %d w %d", &p, &w))
14009         {
14010           if (!curr_rloc)
14011             {
14012               errmsg ("No RLOC configured for setting priority/weight!");
14013               return -99;
14014             }
14015           curr_rloc->priority = p;
14016           curr_rloc->weight = w;
14017         }
14018       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
14019         {
14020           rloc.is_ip4 = 1;
14021           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
14022           vec_add1 (rlocs, rloc);
14023           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14024         }
14025       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
14026         {
14027           rloc.is_ip4 = 0;
14028           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
14029           vec_add1 (rlocs, rloc);
14030           curr_rloc = &rlocs[vec_len (rlocs) - 1];
14031         }
14032       else if (unformat (input, "action %U",
14033                          unformat_negative_mapping_action, &action))
14034         {
14035           ;
14036         }
14037       else
14038         {
14039           clib_warning ("parse error '%U'", format_unformat_error, input);
14040           return -99;
14041         }
14042     }
14043
14044   if (0 == eid_set)
14045     {
14046       errmsg ("missing params!");
14047       return -99;
14048     }
14049
14050   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
14051     {
14052       errmsg ("no action set for negative map-reply!");
14053       return -99;
14054     }
14055
14056   data_len = vec_len (rlocs) * sizeof (rloc_t);
14057
14058   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
14059   mp->is_add = is_add;
14060   mp->vni = htonl (vni);
14061   mp->action = (u8) action;
14062   mp->is_src_dst = seid_set;
14063   mp->eid_len = eid->len;
14064   mp->seid_len = seid->len;
14065   mp->del_all = del_all;
14066   mp->eid_type = eid->type;
14067   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14068   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
14069
14070   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
14071   clib_memcpy (mp->rlocs, rlocs, data_len);
14072   vec_free (rlocs);
14073
14074   /* send it... */
14075   S;
14076
14077   /* Wait for a reply... */
14078   W;
14079
14080   /* NOTREACHED */
14081   return 0;
14082 }
14083
14084 /**
14085  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14086  * forwarding entries in data-plane accordingly.
14087  *
14088  * @param vam vpp API test context
14089  * @return return code
14090  */
14091 static int
14092 api_lisp_add_del_adjacency (vat_main_t * vam)
14093 {
14094   unformat_input_t *input = vam->input;
14095   vl_api_lisp_add_del_adjacency_t *mp;
14096   f64 timeout = ~0;
14097   u32 vni = 0;
14098   ip4_address_t leid4, reid4;
14099   ip6_address_t leid6, reid6;
14100   u8 reid_mac[6] = { 0 };
14101   u8 leid_mac[6] = { 0 };
14102   u8 reid_type, leid_type;
14103   u32 leid_len = 0, reid_len = 0, len;
14104   u8 is_add = 1;
14105
14106   leid_type = reid_type = (u8) ~ 0;
14107
14108   /* Parse args required to build the message */
14109   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14110     {
14111       if (unformat (input, "del"))
14112         {
14113           is_add = 0;
14114         }
14115       else if (unformat (input, "add"))
14116         {
14117           is_add = 1;
14118         }
14119       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14120                          &reid4, &len))
14121         {
14122           reid_type = 0;        /* ipv4 */
14123           reid_len = len;
14124         }
14125       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14126                          &reid6, &len))
14127         {
14128           reid_type = 1;        /* ipv6 */
14129           reid_len = len;
14130         }
14131       else if (unformat (input, "reid %U", unformat_ethernet_address,
14132                          reid_mac))
14133         {
14134           reid_type = 2;        /* mac */
14135         }
14136       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14137                          &leid4, &len))
14138         {
14139           leid_type = 0;        /* ipv4 */
14140           leid_len = len;
14141         }
14142       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14143                          &leid6, &len))
14144         {
14145           leid_type = 1;        /* ipv6 */
14146           leid_len = len;
14147         }
14148       else if (unformat (input, "leid %U", unformat_ethernet_address,
14149                          leid_mac))
14150         {
14151           leid_type = 2;        /* mac */
14152         }
14153       else if (unformat (input, "vni %d", &vni))
14154         {
14155           ;
14156         }
14157       else
14158         {
14159           errmsg ("parse error '%U'", format_unformat_error, input);
14160           return -99;
14161         }
14162     }
14163
14164   if ((u8) ~ 0 == reid_type)
14165     {
14166       errmsg ("missing params!");
14167       return -99;
14168     }
14169
14170   if (leid_type != reid_type)
14171     {
14172       errmsg ("remote and local EIDs are of different types!");
14173       return -99;
14174     }
14175
14176   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
14177   mp->is_add = is_add;
14178   mp->vni = htonl (vni);
14179   mp->leid_len = leid_len;
14180   mp->reid_len = reid_len;
14181   mp->eid_type = reid_type;
14182
14183   switch (mp->eid_type)
14184     {
14185     case 0:
14186       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14187       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14188       break;
14189     case 1:
14190       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14191       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14192       break;
14193     case 2:
14194       clib_memcpy (mp->leid, leid_mac, 6);
14195       clib_memcpy (mp->reid, reid_mac, 6);
14196       break;
14197     default:
14198       errmsg ("unknown EID type %d!", mp->eid_type);
14199       return 0;
14200     }
14201
14202   /* send it... */
14203   S;
14204
14205   /* Wait for a reply... */
14206   W;
14207
14208   /* NOTREACHED */
14209   return 0;
14210 }
14211
14212 static int
14213 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14214 {
14215   unformat_input_t *input = vam->input;
14216   vl_api_lisp_gpe_add_del_iface_t *mp;
14217   f64 timeout = ~0;
14218   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14219   u32 dp_table = 0, vni = 0;
14220
14221   /* Parse args required to build the message */
14222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14223     {
14224       if (unformat (input, "up"))
14225         {
14226           action_set = 1;
14227           is_add = 1;
14228         }
14229       else if (unformat (input, "down"))
14230         {
14231           action_set = 1;
14232           is_add = 0;
14233         }
14234       else if (unformat (input, "table_id %d", &dp_table))
14235         {
14236           dp_table_set = 1;
14237         }
14238       else if (unformat (input, "bd_id %d", &dp_table))
14239         {
14240           dp_table_set = 1;
14241           is_l2 = 1;
14242         }
14243       else if (unformat (input, "vni %d", &vni))
14244         {
14245           vni_set = 1;
14246         }
14247       else
14248         break;
14249     }
14250
14251   if (action_set == 0)
14252     {
14253       errmsg ("Action not set");
14254       return -99;
14255     }
14256   if (dp_table_set == 0 || vni_set == 0)
14257     {
14258       errmsg ("vni and dp_table must be set");
14259       return -99;
14260     }
14261
14262   /* Construct the API message */
14263   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
14264
14265   mp->is_add = is_add;
14266   mp->dp_table = dp_table;
14267   mp->is_l2 = is_l2;
14268   mp->vni = vni;
14269
14270   /* send it... */
14271   S;
14272
14273   /* Wait for a reply... */
14274   W;
14275
14276   /* NOTREACHED */
14277   return 0;
14278 }
14279
14280 /**
14281  * Add/del map request itr rlocs from LISP control plane and updates
14282  *
14283  * @param vam vpp API test context
14284  * @return return code
14285  */
14286 static int
14287 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14288 {
14289   unformat_input_t *input = vam->input;
14290   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14291   f64 timeout = ~0;
14292   u8 *locator_set_name = 0;
14293   u8 locator_set_name_set = 0;
14294   u8 is_add = 1;
14295
14296   /* Parse args required to build the message */
14297   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14298     {
14299       if (unformat (input, "del"))
14300         {
14301           is_add = 0;
14302         }
14303       else if (unformat (input, "%_%v%_", &locator_set_name))
14304         {
14305           locator_set_name_set = 1;
14306         }
14307       else
14308         {
14309           clib_warning ("parse error '%U'", format_unformat_error, input);
14310           return -99;
14311         }
14312     }
14313
14314   if (is_add && !locator_set_name_set)
14315     {
14316       errmsg ("itr-rloc is not set!");
14317       return -99;
14318     }
14319
14320   if (is_add && vec_len (locator_set_name) > 64)
14321     {
14322       errmsg ("itr-rloc locator-set name too long");
14323       vec_free (locator_set_name);
14324       return -99;
14325     }
14326
14327   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
14328   mp->is_add = is_add;
14329   if (is_add)
14330     {
14331       clib_memcpy (mp->locator_set_name, locator_set_name,
14332                    vec_len (locator_set_name));
14333     }
14334   else
14335     {
14336       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14337     }
14338   vec_free (locator_set_name);
14339
14340   /* send it... */
14341   S;
14342
14343   /* Wait for a reply... */
14344   W;
14345
14346   /* NOTREACHED */
14347   return 0;
14348 }
14349
14350 static int
14351 api_lisp_locator_dump (vat_main_t * vam)
14352 {
14353   unformat_input_t *input = vam->input;
14354   vl_api_lisp_locator_dump_t *mp;
14355   f64 timeout = ~0;
14356   u8 is_index_set = 0, is_name_set = 0;
14357   u8 *ls_name = 0;
14358   u32 ls_index = ~0;
14359
14360   /* Parse args required to build the message */
14361   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14362     {
14363       if (unformat (input, "ls_name %_%v%_", &ls_name))
14364         {
14365           is_name_set = 1;
14366         }
14367       else if (unformat (input, "ls_index %d", &ls_index))
14368         {
14369           is_index_set = 1;
14370         }
14371       else
14372         {
14373           errmsg ("parse error '%U'", format_unformat_error, input);
14374           return -99;
14375         }
14376     }
14377
14378   if (!is_index_set && !is_name_set)
14379     {
14380       errmsg ("error: expected one of index or name!");
14381       return -99;
14382     }
14383
14384   if (is_index_set && is_name_set)
14385     {
14386       errmsg ("error: only one param expected!");
14387       return -99;
14388     }
14389
14390   if (vec_len (ls_name) > 62)
14391     {
14392       errmsg ("error: locator set name too long!");
14393       return -99;
14394     }
14395
14396   if (!vam->json_output)
14397     {
14398       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14399     }
14400
14401   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
14402   mp->is_index_set = is_index_set;
14403
14404   if (is_index_set)
14405     mp->ls_index = clib_host_to_net_u32 (ls_index);
14406   else
14407     {
14408       vec_add1 (ls_name, 0);
14409       strncpy ((char *) mp->ls_name, (char *) ls_name,
14410                sizeof (mp->ls_name) - 1);
14411     }
14412
14413   /* send it... */
14414   S;
14415
14416   /* Use a control ping for synchronization */
14417   {
14418     vl_api_control_ping_t *mp;
14419     M (CONTROL_PING, control_ping);
14420     S;
14421   }
14422   /* Wait for a reply... */
14423   W;
14424
14425   /* NOTREACHED */
14426   return 0;
14427 }
14428
14429 static int
14430 api_lisp_locator_set_dump (vat_main_t * vam)
14431 {
14432   vl_api_lisp_locator_set_dump_t *mp;
14433   unformat_input_t *input = vam->input;
14434   f64 timeout = ~0;
14435   u8 filter = 0;
14436
14437   /* Parse args required to build the message */
14438   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14439     {
14440       if (unformat (input, "local"))
14441         {
14442           filter = 1;
14443         }
14444       else if (unformat (input, "remote"))
14445         {
14446           filter = 2;
14447         }
14448       else
14449         {
14450           errmsg ("parse error '%U'", format_unformat_error, input);
14451           return -99;
14452         }
14453     }
14454
14455   if (!vam->json_output)
14456     {
14457       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14458     }
14459
14460   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14461
14462   mp->filter = filter;
14463
14464   /* send it... */
14465   S;
14466
14467   /* Use a control ping for synchronization */
14468   {
14469     vl_api_control_ping_t *mp;
14470     M (CONTROL_PING, control_ping);
14471     S;
14472   }
14473   /* Wait for a reply... */
14474   W;
14475
14476   /* NOTREACHED */
14477   return 0;
14478 }
14479
14480 static int
14481 api_lisp_eid_table_map_dump (vat_main_t * vam)
14482 {
14483   u8 is_l2 = 0;
14484   u8 mode_set = 0;
14485   unformat_input_t *input = vam->input;
14486   vl_api_lisp_eid_table_map_dump_t *mp;
14487   f64 timeout = ~0;
14488
14489   /* Parse args required to build the message */
14490   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14491     {
14492       if (unformat (input, "l2"))
14493         {
14494           is_l2 = 1;
14495           mode_set = 1;
14496         }
14497       else if (unformat (input, "l3"))
14498         {
14499           is_l2 = 0;
14500           mode_set = 1;
14501         }
14502       else
14503         {
14504           errmsg ("parse error '%U'", format_unformat_error, input);
14505           return -99;
14506         }
14507     }
14508
14509   if (!mode_set)
14510     {
14511       errmsg ("expected one of 'l2' or 'l3' parameter!");
14512       return -99;
14513     }
14514
14515   if (!vam->json_output)
14516     {
14517       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14518     }
14519
14520   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14521   mp->is_l2 = is_l2;
14522
14523   /* send it... */
14524   S;
14525
14526   /* Use a control ping for synchronization */
14527   {
14528     vl_api_control_ping_t *mp;
14529     M (CONTROL_PING, control_ping);
14530     S;
14531   }
14532   /* Wait for a reply... */
14533   W;
14534
14535   /* NOTREACHED */
14536   return 0;
14537 }
14538
14539 static int
14540 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14541 {
14542   vl_api_lisp_eid_table_vni_dump_t *mp;
14543   f64 timeout = ~0;
14544
14545   if (!vam->json_output)
14546     {
14547       print (vam->ofp, "VNI");
14548     }
14549
14550   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14551
14552   /* send it... */
14553   S;
14554
14555   /* Use a control ping for synchronization */
14556   {
14557     vl_api_control_ping_t *mp;
14558     M (CONTROL_PING, control_ping);
14559     S;
14560   }
14561   /* Wait for a reply... */
14562   W;
14563
14564   /* NOTREACHED */
14565   return 0;
14566 }
14567
14568 static int
14569 api_lisp_eid_table_dump (vat_main_t * vam)
14570 {
14571   unformat_input_t *i = vam->input;
14572   vl_api_lisp_eid_table_dump_t *mp;
14573   f64 timeout = ~0;
14574   struct in_addr ip4;
14575   struct in6_addr ip6;
14576   u8 mac[6];
14577   u8 eid_type = ~0, eid_set = 0;
14578   u32 prefix_length = ~0, t, vni = 0;
14579   u8 filter = 0;
14580
14581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14582     {
14583       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14584         {
14585           eid_set = 1;
14586           eid_type = 0;
14587           prefix_length = t;
14588         }
14589       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14590         {
14591           eid_set = 1;
14592           eid_type = 1;
14593           prefix_length = t;
14594         }
14595       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14596         {
14597           eid_set = 1;
14598           eid_type = 2;
14599         }
14600       else if (unformat (i, "vni %d", &t))
14601         {
14602           vni = t;
14603         }
14604       else if (unformat (i, "local"))
14605         {
14606           filter = 1;
14607         }
14608       else if (unformat (i, "remote"))
14609         {
14610           filter = 2;
14611         }
14612       else
14613         {
14614           errmsg ("parse error '%U'", format_unformat_error, i);
14615           return -99;
14616         }
14617     }
14618
14619   if (!vam->json_output)
14620     {
14621       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
14622              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14623     }
14624
14625   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14626
14627   mp->filter = filter;
14628   if (eid_set)
14629     {
14630       mp->eid_set = 1;
14631       mp->vni = htonl (vni);
14632       mp->eid_type = eid_type;
14633       switch (eid_type)
14634         {
14635         case 0:
14636           mp->prefix_length = prefix_length;
14637           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14638           break;
14639         case 1:
14640           mp->prefix_length = prefix_length;
14641           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14642           break;
14643         case 2:
14644           clib_memcpy (mp->eid, mac, sizeof (mac));
14645           break;
14646         default:
14647           errmsg ("unknown EID type %d!", eid_type);
14648           return -99;
14649         }
14650     }
14651
14652   /* send it... */
14653   S;
14654
14655   /* Use a control ping for synchronization */
14656   {
14657     vl_api_control_ping_t *mp;
14658     M (CONTROL_PING, control_ping);
14659     S;
14660   }
14661
14662   /* Wait for a reply... */
14663   W;
14664
14665   /* NOTREACHED */
14666   return 0;
14667 }
14668
14669 static int
14670 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14671 {
14672   vl_api_lisp_gpe_tunnel_dump_t *mp;
14673   f64 timeout = ~0;
14674
14675   if (!vam->json_output)
14676     {
14677       print (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14678              "%=16s%=16s%=16s%=16s%=16s",
14679              "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14680              "Decap next", "Lisp version", "Flags", "Next protocol",
14681              "ver_res", "res", "iid");
14682     }
14683
14684   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14685   /* send it... */
14686   S;
14687
14688   /* Use a control ping for synchronization */
14689   {
14690     vl_api_control_ping_t *mp;
14691     M (CONTROL_PING, control_ping);
14692     S;
14693   }
14694   /* Wait for a reply... */
14695   W;
14696
14697   /* NOTREACHED */
14698   return 0;
14699 }
14700
14701 static int
14702 api_lisp_adjacencies_get (vat_main_t * vam)
14703 {
14704   unformat_input_t *i = vam->input;
14705   vl_api_lisp_adjacencies_get_t *mp;
14706   f64 timeout = ~0;
14707   u8 vni_set = 0;
14708   u32 vni = ~0;
14709
14710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14711     {
14712       if (unformat (i, "vni %d", &vni))
14713         {
14714           vni_set = 1;
14715         }
14716       else
14717         {
14718           errmsg ("parse error '%U'", format_unformat_error, i);
14719           return -99;
14720         }
14721     }
14722
14723   if (!vni_set)
14724     {
14725       errmsg ("vni not set!");
14726       return -99;
14727     }
14728
14729   if (!vam->json_output)
14730     {
14731       print (vam->ofp, "%s %40s", "leid", "reid");
14732     }
14733
14734   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14735   mp->vni = clib_host_to_net_u32 (vni);
14736
14737   /* send it... */
14738   S;
14739
14740   /* Wait for a reply... */
14741   W;
14742
14743   /* NOTREACHED */
14744   return 0;
14745 }
14746
14747 static int
14748 api_lisp_map_server_dump (vat_main_t * vam)
14749 {
14750   vl_api_lisp_map_server_dump_t *mp;
14751   f64 timeout = ~0;
14752
14753   if (!vam->json_output)
14754     {
14755       print (vam->ofp, "%=20s", "Map server");
14756     }
14757
14758   M (LISP_MAP_SERVER_DUMP, lisp_map_server_dump);
14759   /* send it... */
14760   S;
14761
14762   /* Use a control ping for synchronization */
14763   {
14764     vl_api_control_ping_t *mp;
14765     M (CONTROL_PING, control_ping);
14766     S;
14767   }
14768   /* Wait for a reply... */
14769   W;
14770
14771   /* NOTREACHED */
14772   return 0;
14773 }
14774
14775 static int
14776 api_lisp_map_resolver_dump (vat_main_t * vam)
14777 {
14778   vl_api_lisp_map_resolver_dump_t *mp;
14779   f64 timeout = ~0;
14780
14781   if (!vam->json_output)
14782     {
14783       print (vam->ofp, "%=20s", "Map resolver");
14784     }
14785
14786   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14787   /* send it... */
14788   S;
14789
14790   /* Use a control ping for synchronization */
14791   {
14792     vl_api_control_ping_t *mp;
14793     M (CONTROL_PING, control_ping);
14794     S;
14795   }
14796   /* Wait for a reply... */
14797   W;
14798
14799   /* NOTREACHED */
14800   return 0;
14801 }
14802
14803 static int
14804 api_show_lisp_status (vat_main_t * vam)
14805 {
14806   vl_api_show_lisp_status_t *mp;
14807   f64 timeout = ~0;
14808
14809   if (!vam->json_output)
14810     {
14811       print (vam->ofp, "%-20s%-16s", "lisp status", "locator-set");
14812     }
14813
14814   M (SHOW_LISP_STATUS, show_lisp_status);
14815   /* send it... */
14816   S;
14817   /* Wait for a reply... */
14818   W;
14819
14820   /* NOTREACHED */
14821   return 0;
14822 }
14823
14824 static int
14825 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14826 {
14827   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14828   f64 timeout = ~0;
14829
14830   if (!vam->json_output)
14831     {
14832       print (vam->ofp, "%=20s", "itr-rlocs:");
14833     }
14834
14835   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14836   /* send it... */
14837   S;
14838   /* Wait for a reply... */
14839   W;
14840
14841   /* NOTREACHED */
14842   return 0;
14843 }
14844
14845 static int
14846 api_af_packet_create (vat_main_t * vam)
14847 {
14848   unformat_input_t *i = vam->input;
14849   vl_api_af_packet_create_t *mp;
14850   f64 timeout;
14851   u8 *host_if_name = 0;
14852   u8 hw_addr[6];
14853   u8 random_hw_addr = 1;
14854
14855   memset (hw_addr, 0, sizeof (hw_addr));
14856
14857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14858     {
14859       if (unformat (i, "name %s", &host_if_name))
14860         vec_add1 (host_if_name, 0);
14861       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14862         random_hw_addr = 0;
14863       else
14864         break;
14865     }
14866
14867   if (!vec_len (host_if_name))
14868     {
14869       errmsg ("host-interface name must be specified");
14870       return -99;
14871     }
14872
14873   if (vec_len (host_if_name) > 64)
14874     {
14875       errmsg ("host-interface name too long");
14876       return -99;
14877     }
14878
14879   M (AF_PACKET_CREATE, af_packet_create);
14880
14881   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14882   clib_memcpy (mp->hw_addr, hw_addr, 6);
14883   mp->use_random_hw_addr = random_hw_addr;
14884   vec_free (host_if_name);
14885
14886   S;
14887   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14888   /* NOTREACHED */
14889   return 0;
14890 }
14891
14892 static int
14893 api_af_packet_delete (vat_main_t * vam)
14894 {
14895   unformat_input_t *i = vam->input;
14896   vl_api_af_packet_delete_t *mp;
14897   f64 timeout;
14898   u8 *host_if_name = 0;
14899
14900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14901     {
14902       if (unformat (i, "name %s", &host_if_name))
14903         vec_add1 (host_if_name, 0);
14904       else
14905         break;
14906     }
14907
14908   if (!vec_len (host_if_name))
14909     {
14910       errmsg ("host-interface name must be specified");
14911       return -99;
14912     }
14913
14914   if (vec_len (host_if_name) > 64)
14915     {
14916       errmsg ("host-interface name too long");
14917       return -99;
14918     }
14919
14920   M (AF_PACKET_DELETE, af_packet_delete);
14921
14922   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14923   vec_free (host_if_name);
14924
14925   S;
14926   W;
14927   /* NOTREACHED */
14928   return 0;
14929 }
14930
14931 static int
14932 api_policer_add_del (vat_main_t * vam)
14933 {
14934   unformat_input_t *i = vam->input;
14935   vl_api_policer_add_del_t *mp;
14936   f64 timeout;
14937   u8 is_add = 1;
14938   u8 *name = 0;
14939   u32 cir = 0;
14940   u32 eir = 0;
14941   u64 cb = 0;
14942   u64 eb = 0;
14943   u8 rate_type = 0;
14944   u8 round_type = 0;
14945   u8 type = 0;
14946   u8 color_aware = 0;
14947   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14948
14949   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14950   conform_action.dscp = 0;
14951   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14952   exceed_action.dscp = 0;
14953   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14954   violate_action.dscp = 0;
14955
14956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14957     {
14958       if (unformat (i, "del"))
14959         is_add = 0;
14960       else if (unformat (i, "name %s", &name))
14961         vec_add1 (name, 0);
14962       else if (unformat (i, "cir %u", &cir))
14963         ;
14964       else if (unformat (i, "eir %u", &eir))
14965         ;
14966       else if (unformat (i, "cb %u", &cb))
14967         ;
14968       else if (unformat (i, "eb %u", &eb))
14969         ;
14970       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14971                          &rate_type))
14972         ;
14973       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14974                          &round_type))
14975         ;
14976       else if (unformat (i, "type %U", unformat_policer_type, &type))
14977         ;
14978       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14979                          &conform_action))
14980         ;
14981       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14982                          &exceed_action))
14983         ;
14984       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14985                          &violate_action))
14986         ;
14987       else if (unformat (i, "color-aware"))
14988         color_aware = 1;
14989       else
14990         break;
14991     }
14992
14993   if (!vec_len (name))
14994     {
14995       errmsg ("policer name must be specified");
14996       return -99;
14997     }
14998
14999   if (vec_len (name) > 64)
15000     {
15001       errmsg ("policer name too long");
15002       return -99;
15003     }
15004
15005   M (POLICER_ADD_DEL, policer_add_del);
15006
15007   clib_memcpy (mp->name, name, vec_len (name));
15008   vec_free (name);
15009   mp->is_add = is_add;
15010   mp->cir = cir;
15011   mp->eir = eir;
15012   mp->cb = cb;
15013   mp->eb = eb;
15014   mp->rate_type = rate_type;
15015   mp->round_type = round_type;
15016   mp->type = type;
15017   mp->conform_action_type = conform_action.action_type;
15018   mp->conform_dscp = conform_action.dscp;
15019   mp->exceed_action_type = exceed_action.action_type;
15020   mp->exceed_dscp = exceed_action.dscp;
15021   mp->violate_action_type = violate_action.action_type;
15022   mp->violate_dscp = violate_action.dscp;
15023   mp->color_aware = color_aware;
15024
15025   S;
15026   W;
15027   /* NOTREACHED */
15028   return 0;
15029 }
15030
15031 static int
15032 api_policer_dump (vat_main_t * vam)
15033 {
15034   unformat_input_t *i = vam->input;
15035   vl_api_policer_dump_t *mp;
15036   f64 timeout = ~0;
15037   u8 *match_name = 0;
15038   u8 match_name_valid = 0;
15039
15040   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15041     {
15042       if (unformat (i, "name %s", &match_name))
15043         {
15044           vec_add1 (match_name, 0);
15045           match_name_valid = 1;
15046         }
15047       else
15048         break;
15049     }
15050
15051   M (POLICER_DUMP, policer_dump);
15052   mp->match_name_valid = match_name_valid;
15053   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
15054   vec_free (match_name);
15055   /* send it... */
15056   S;
15057
15058   /* Use a control ping for synchronization */
15059   {
15060     vl_api_control_ping_t *mp;
15061     M (CONTROL_PING, control_ping);
15062     S;
15063   }
15064   /* Wait for a reply... */
15065   W;
15066
15067   /* NOTREACHED */
15068   return 0;
15069 }
15070
15071 static int
15072 api_policer_classify_set_interface (vat_main_t * vam)
15073 {
15074   unformat_input_t *i = vam->input;
15075   vl_api_policer_classify_set_interface_t *mp;
15076   f64 timeout;
15077   u32 sw_if_index;
15078   int sw_if_index_set;
15079   u32 ip4_table_index = ~0;
15080   u32 ip6_table_index = ~0;
15081   u32 l2_table_index = ~0;
15082   u8 is_add = 1;
15083
15084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15085     {
15086       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15087         sw_if_index_set = 1;
15088       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15089         sw_if_index_set = 1;
15090       else if (unformat (i, "del"))
15091         is_add = 0;
15092       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15093         ;
15094       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15095         ;
15096       else if (unformat (i, "l2-table %d", &l2_table_index))
15097         ;
15098       else
15099         {
15100           clib_warning ("parse error '%U'", format_unformat_error, i);
15101           return -99;
15102         }
15103     }
15104
15105   if (sw_if_index_set == 0)
15106     {
15107       errmsg ("missing interface name or sw_if_index");
15108       return -99;
15109     }
15110
15111   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
15112
15113   mp->sw_if_index = ntohl (sw_if_index);
15114   mp->ip4_table_index = ntohl (ip4_table_index);
15115   mp->ip6_table_index = ntohl (ip6_table_index);
15116   mp->l2_table_index = ntohl (l2_table_index);
15117   mp->is_add = is_add;
15118
15119   S;
15120   W;
15121   /* NOTREACHED */
15122   return 0;
15123 }
15124
15125 static int
15126 api_policer_classify_dump (vat_main_t * vam)
15127 {
15128   unformat_input_t *i = vam->input;
15129   vl_api_policer_classify_dump_t *mp;
15130   f64 timeout = ~0;
15131   u8 type = POLICER_CLASSIFY_N_TABLES;
15132
15133   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15134     ;
15135   else
15136     {
15137       errmsg ("classify table type must be specified");
15138       return -99;
15139     }
15140
15141   if (!vam->json_output)
15142     {
15143       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15144     }
15145
15146   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
15147   mp->type = type;
15148   /* send it... */
15149   S;
15150
15151   /* Use a control ping for synchronization */
15152   {
15153     vl_api_control_ping_t *mp;
15154     M (CONTROL_PING, control_ping);
15155     S;
15156   }
15157   /* Wait for a reply... */
15158   W;
15159
15160   /* NOTREACHED */
15161   return 0;
15162 }
15163
15164 static int
15165 api_netmap_create (vat_main_t * vam)
15166 {
15167   unformat_input_t *i = vam->input;
15168   vl_api_netmap_create_t *mp;
15169   f64 timeout;
15170   u8 *if_name = 0;
15171   u8 hw_addr[6];
15172   u8 random_hw_addr = 1;
15173   u8 is_pipe = 0;
15174   u8 is_master = 0;
15175
15176   memset (hw_addr, 0, sizeof (hw_addr));
15177
15178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15179     {
15180       if (unformat (i, "name %s", &if_name))
15181         vec_add1 (if_name, 0);
15182       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15183         random_hw_addr = 0;
15184       else if (unformat (i, "pipe"))
15185         is_pipe = 1;
15186       else if (unformat (i, "master"))
15187         is_master = 1;
15188       else if (unformat (i, "slave"))
15189         is_master = 0;
15190       else
15191         break;
15192     }
15193
15194   if (!vec_len (if_name))
15195     {
15196       errmsg ("interface name must be specified");
15197       return -99;
15198     }
15199
15200   if (vec_len (if_name) > 64)
15201     {
15202       errmsg ("interface name too long");
15203       return -99;
15204     }
15205
15206   M (NETMAP_CREATE, netmap_create);
15207
15208   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15209   clib_memcpy (mp->hw_addr, hw_addr, 6);
15210   mp->use_random_hw_addr = random_hw_addr;
15211   mp->is_pipe = is_pipe;
15212   mp->is_master = is_master;
15213   vec_free (if_name);
15214
15215   S;
15216   W;
15217   /* NOTREACHED */
15218   return 0;
15219 }
15220
15221 static int
15222 api_netmap_delete (vat_main_t * vam)
15223 {
15224   unformat_input_t *i = vam->input;
15225   vl_api_netmap_delete_t *mp;
15226   f64 timeout;
15227   u8 *if_name = 0;
15228
15229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15230     {
15231       if (unformat (i, "name %s", &if_name))
15232         vec_add1 (if_name, 0);
15233       else
15234         break;
15235     }
15236
15237   if (!vec_len (if_name))
15238     {
15239       errmsg ("interface name must be specified");
15240       return -99;
15241     }
15242
15243   if (vec_len (if_name) > 64)
15244     {
15245       errmsg ("interface name too long");
15246       return -99;
15247     }
15248
15249   M (NETMAP_DELETE, netmap_delete);
15250
15251   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15252   vec_free (if_name);
15253
15254   S;
15255   W;
15256   /* NOTREACHED */
15257   return 0;
15258 }
15259
15260 static void vl_api_mpls_tunnel_details_t_handler
15261   (vl_api_mpls_tunnel_details_t * mp)
15262 {
15263   vat_main_t *vam = &vat_main;
15264   i32 len = mp->mt_next_hop_n_labels;
15265   i32 i;
15266
15267   print (vam->ofp, "[%d]: via %U %d labels ",
15268          mp->tunnel_index,
15269          format_ip4_address, mp->mt_next_hop,
15270          ntohl (mp->mt_next_hop_sw_if_index));
15271   for (i = 0; i < len; i++)
15272     {
15273       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15274     }
15275   print (vam->ofp, "");
15276 }
15277
15278 static void vl_api_mpls_tunnel_details_t_handler_json
15279   (vl_api_mpls_tunnel_details_t * mp)
15280 {
15281   vat_main_t *vam = &vat_main;
15282   vat_json_node_t *node = NULL;
15283   struct in_addr ip4;
15284   i32 i;
15285   i32 len = mp->mt_next_hop_n_labels;
15286
15287   if (VAT_JSON_ARRAY != vam->json_tree.type)
15288     {
15289       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15290       vat_json_init_array (&vam->json_tree);
15291     }
15292   node = vat_json_array_add (&vam->json_tree);
15293
15294   vat_json_init_object (node);
15295   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15296   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15297   vat_json_object_add_ip4 (node, "next_hop", ip4);
15298   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15299                             ntohl (mp->mt_next_hop_sw_if_index));
15300   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15301   vat_json_object_add_uint (node, "label_count", len);
15302   for (i = 0; i < len; i++)
15303     {
15304       vat_json_object_add_uint (node, "label",
15305                                 ntohl (mp->mt_next_hop_out_labels[i]));
15306     }
15307 }
15308
15309 static int
15310 api_mpls_tunnel_dump (vat_main_t * vam)
15311 {
15312   vl_api_mpls_tunnel_dump_t *mp;
15313   f64 timeout;
15314   i32 index = -1;
15315
15316   /* Parse args required to build the message */
15317   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15318     {
15319       if (!unformat (vam->input, "tunnel_index %d", &index))
15320         {
15321           index = -1;
15322           break;
15323         }
15324     }
15325
15326   print (vam->ofp, "  tunnel_index %d", index);
15327
15328   M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
15329   mp->tunnel_index = htonl (index);
15330   S;
15331
15332   /* Use a control ping for synchronization */
15333   {
15334     vl_api_control_ping_t *mp;
15335     M (CONTROL_PING, control_ping);
15336     S;
15337   }
15338   W;
15339 }
15340
15341 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15342 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15343
15344 static void
15345 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15346 {
15347   vat_main_t *vam = &vat_main;
15348   int count = ntohl (mp->count);
15349   vl_api_fib_path2_t *fp;
15350   int i;
15351
15352   print (vam->ofp,
15353          "table-id %d, label %u, ess_bit %u",
15354          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15355   fp = mp->path;
15356   for (i = 0; i < count; i++)
15357     {
15358       if (fp->afi == IP46_TYPE_IP6)
15359         print (vam->ofp,
15360                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15361                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15362                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15363                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15364                format_ip6_address, fp->next_hop);
15365       else if (fp->afi == IP46_TYPE_IP4)
15366         print (vam->ofp,
15367                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15368                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15369                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15370                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15371                format_ip4_address, fp->next_hop);
15372       fp++;
15373     }
15374 }
15375
15376 static void vl_api_mpls_fib_details_t_handler_json
15377   (vl_api_mpls_fib_details_t * mp)
15378 {
15379   vat_main_t *vam = &vat_main;
15380   int count = ntohl (mp->count);
15381   vat_json_node_t *node = NULL;
15382   struct in_addr ip4;
15383   struct in6_addr ip6;
15384   vl_api_fib_path2_t *fp;
15385   int i;
15386
15387   if (VAT_JSON_ARRAY != vam->json_tree.type)
15388     {
15389       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15390       vat_json_init_array (&vam->json_tree);
15391     }
15392   node = vat_json_array_add (&vam->json_tree);
15393
15394   vat_json_init_object (node);
15395   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15396   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15397   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15398   vat_json_object_add_uint (node, "path_count", count);
15399   fp = mp->path;
15400   for (i = 0; i < count; i++)
15401     {
15402       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15403       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15404       vat_json_object_add_uint (node, "is_local", fp->is_local);
15405       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15406       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15407       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15408       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15409       if (fp->afi == IP46_TYPE_IP4)
15410         {
15411           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15412           vat_json_object_add_ip4 (node, "next_hop", ip4);
15413         }
15414       else if (fp->afi == IP46_TYPE_IP6)
15415         {
15416           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15417           vat_json_object_add_ip6 (node, "next_hop", ip6);
15418         }
15419     }
15420 }
15421
15422 static int
15423 api_mpls_fib_dump (vat_main_t * vam)
15424 {
15425   vl_api_mpls_fib_dump_t *mp;
15426   f64 timeout;
15427
15428   M (MPLS_FIB_DUMP, mpls_fib_dump);
15429   S;
15430
15431   /* Use a control ping for synchronization */
15432   {
15433     vl_api_control_ping_t *mp;
15434     M (CONTROL_PING, control_ping);
15435     S;
15436   }
15437   W;
15438 }
15439
15440 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15441 #define vl_api_ip_fib_details_t_print vl_noop_handler
15442
15443 static void
15444 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15445 {
15446   vat_main_t *vam = &vat_main;
15447   int count = ntohl (mp->count);
15448   vl_api_fib_path_t *fp;
15449   int i;
15450
15451   print (vam->ofp,
15452          "table-id %d, prefix %U/%d",
15453          ntohl (mp->table_id), format_ip4_address, mp->address,
15454          mp->address_length);
15455   fp = mp->path;
15456   for (i = 0; i < count; i++)
15457     {
15458       if (fp->afi == IP46_TYPE_IP6)
15459         print (vam->ofp,
15460                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15461                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15462                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15463                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15464                format_ip6_address, fp->next_hop);
15465       else if (fp->afi == IP46_TYPE_IP4)
15466         print (vam->ofp,
15467                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15468                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15469                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15470                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15471                format_ip4_address, fp->next_hop);
15472       fp++;
15473     }
15474 }
15475
15476 static void vl_api_ip_fib_details_t_handler_json
15477   (vl_api_ip_fib_details_t * mp)
15478 {
15479   vat_main_t *vam = &vat_main;
15480   int count = ntohl (mp->count);
15481   vat_json_node_t *node = NULL;
15482   struct in_addr ip4;
15483   struct in6_addr ip6;
15484   vl_api_fib_path_t *fp;
15485   int i;
15486
15487   if (VAT_JSON_ARRAY != vam->json_tree.type)
15488     {
15489       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15490       vat_json_init_array (&vam->json_tree);
15491     }
15492   node = vat_json_array_add (&vam->json_tree);
15493
15494   vat_json_init_object (node);
15495   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15496   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15497   vat_json_object_add_ip4 (node, "prefix", ip4);
15498   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15499   vat_json_object_add_uint (node, "path_count", count);
15500   fp = mp->path;
15501   for (i = 0; i < count; i++)
15502     {
15503       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15504       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15505       vat_json_object_add_uint (node, "is_local", fp->is_local);
15506       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15507       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15508       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15509       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15510       if (fp->afi == IP46_TYPE_IP4)
15511         {
15512           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15513           vat_json_object_add_ip4 (node, "next_hop", ip4);
15514         }
15515       else if (fp->afi == IP46_TYPE_IP6)
15516         {
15517           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15518           vat_json_object_add_ip6 (node, "next_hop", ip6);
15519         }
15520     }
15521 }
15522
15523 static int
15524 api_ip_fib_dump (vat_main_t * vam)
15525 {
15526   vl_api_ip_fib_dump_t *mp;
15527   f64 timeout;
15528
15529   M (IP_FIB_DUMP, ip_fib_dump);
15530   S;
15531
15532   /* Use a control ping for synchronization */
15533   {
15534     vl_api_control_ping_t *mp;
15535     M (CONTROL_PING, control_ping);
15536     S;
15537   }
15538   W;
15539 }
15540
15541 static void vl_api_ip_neighbor_details_t_handler
15542   (vl_api_ip_neighbor_details_t * mp)
15543 {
15544   vat_main_t *vam = &vat_main;
15545
15546   print (vam->ofp, "%c %U %U",
15547          (mp->is_static) ? 'S' : 'D',
15548          format_ethernet_address, &mp->mac_address,
15549          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15550          &mp->ip_address);
15551 }
15552
15553 static void vl_api_ip_neighbor_details_t_handler_json
15554   (vl_api_ip_neighbor_details_t * mp)
15555 {
15556
15557   vat_main_t *vam = &vat_main;
15558   vat_json_node_t *node;
15559   struct in_addr ip4;
15560   struct in6_addr ip6;
15561
15562   if (VAT_JSON_ARRAY != vam->json_tree.type)
15563     {
15564       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15565       vat_json_init_array (&vam->json_tree);
15566     }
15567   node = vat_json_array_add (&vam->json_tree);
15568
15569   vat_json_init_object (node);
15570   vat_json_object_add_string_copy (node, "flag",
15571                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15572                                    "dynamic");
15573
15574   vat_json_object_add_string_copy (node, "link_layer",
15575                                    format (0, "%U", format_ethernet_address,
15576                                            &mp->mac_address));
15577
15578   if (mp->is_ipv6)
15579     {
15580       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15581       vat_json_object_add_ip6 (node, "ip_address", ip6);
15582     }
15583   else
15584     {
15585       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15586       vat_json_object_add_ip4 (node, "ip_address", ip4);
15587     }
15588 }
15589
15590 static int
15591 api_ip_neighbor_dump (vat_main_t * vam)
15592 {
15593   unformat_input_t *i = vam->input;
15594   vl_api_ip_neighbor_dump_t *mp;
15595   f64 timeout;
15596   u8 is_ipv6 = 0;
15597   u32 sw_if_index = ~0;
15598
15599   /* Parse args required to build the message */
15600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15601     {
15602       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15603         ;
15604       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15605         ;
15606       else if (unformat (i, "ip6"))
15607         is_ipv6 = 1;
15608       else
15609         break;
15610     }
15611
15612   if (sw_if_index == ~0)
15613     {
15614       errmsg ("missing interface name or sw_if_index");
15615       return -99;
15616     }
15617
15618   M (IP_NEIGHBOR_DUMP, ip_neighbor_dump);
15619   mp->is_ipv6 = (u8) is_ipv6;
15620   mp->sw_if_index = ntohl (sw_if_index);
15621   S;
15622
15623   /* Use a control ping for synchronization */
15624   {
15625     vl_api_control_ping_t *mp;
15626     M (CONTROL_PING, control_ping);
15627     S;
15628   }
15629   W;
15630 }
15631
15632 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15633 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15634
15635 static void
15636 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15637 {
15638   vat_main_t *vam = &vat_main;
15639   int count = ntohl (mp->count);
15640   vl_api_fib_path_t *fp;
15641   int i;
15642
15643   print (vam->ofp,
15644          "table-id %d, prefix %U/%d",
15645          ntohl (mp->table_id), format_ip6_address, mp->address,
15646          mp->address_length);
15647   fp = mp->path;
15648   for (i = 0; i < count; i++)
15649     {
15650       if (fp->afi == IP46_TYPE_IP6)
15651         print (vam->ofp,
15652                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15653                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15654                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15655                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15656                format_ip6_address, fp->next_hop);
15657       else if (fp->afi == IP46_TYPE_IP4)
15658         print (vam->ofp,
15659                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15660                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15661                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15662                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15663                format_ip4_address, fp->next_hop);
15664       fp++;
15665     }
15666 }
15667
15668 static void vl_api_ip6_fib_details_t_handler_json
15669   (vl_api_ip6_fib_details_t * mp)
15670 {
15671   vat_main_t *vam = &vat_main;
15672   int count = ntohl (mp->count);
15673   vat_json_node_t *node = NULL;
15674   struct in_addr ip4;
15675   struct in6_addr ip6;
15676   vl_api_fib_path_t *fp;
15677   int i;
15678
15679   if (VAT_JSON_ARRAY != vam->json_tree.type)
15680     {
15681       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15682       vat_json_init_array (&vam->json_tree);
15683     }
15684   node = vat_json_array_add (&vam->json_tree);
15685
15686   vat_json_init_object (node);
15687   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15688   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15689   vat_json_object_add_ip6 (node, "prefix", ip6);
15690   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15691   vat_json_object_add_uint (node, "path_count", count);
15692   fp = mp->path;
15693   for (i = 0; i < count; i++)
15694     {
15695       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15696       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15697       vat_json_object_add_uint (node, "is_local", fp->is_local);
15698       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15699       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15700       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15701       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15702       if (fp->afi == IP46_TYPE_IP4)
15703         {
15704           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15705           vat_json_object_add_ip4 (node, "next_hop", ip4);
15706         }
15707       else if (fp->afi == IP46_TYPE_IP6)
15708         {
15709           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15710           vat_json_object_add_ip6 (node, "next_hop", ip6);
15711         }
15712     }
15713 }
15714
15715 static int
15716 api_ip6_fib_dump (vat_main_t * vam)
15717 {
15718   vl_api_ip6_fib_dump_t *mp;
15719   f64 timeout;
15720
15721   M (IP6_FIB_DUMP, ip6_fib_dump);
15722   S;
15723
15724   /* Use a control ping for synchronization */
15725   {
15726     vl_api_control_ping_t *mp;
15727     M (CONTROL_PING, control_ping);
15728     S;
15729   }
15730   W;
15731 }
15732
15733 int
15734 api_classify_table_ids (vat_main_t * vam)
15735 {
15736   vl_api_classify_table_ids_t *mp;
15737   f64 timeout;
15738
15739   /* Construct the API message */
15740   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15741   mp->context = 0;
15742
15743   S;
15744   W;
15745   /* NOTREACHED */
15746   return 0;
15747 }
15748
15749 int
15750 api_classify_table_by_interface (vat_main_t * vam)
15751 {
15752   unformat_input_t *input = vam->input;
15753   vl_api_classify_table_by_interface_t *mp;
15754   f64 timeout;
15755
15756   u32 sw_if_index = ~0;
15757   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15758     {
15759       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15760         ;
15761       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15762         ;
15763       else
15764         break;
15765     }
15766   if (sw_if_index == ~0)
15767     {
15768       errmsg ("missing interface name or sw_if_index");
15769       return -99;
15770     }
15771
15772   /* Construct the API message */
15773   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15774   mp->context = 0;
15775   mp->sw_if_index = ntohl (sw_if_index);
15776
15777   S;
15778   W;
15779   /* NOTREACHED */
15780   return 0;
15781 }
15782
15783 int
15784 api_classify_table_info (vat_main_t * vam)
15785 {
15786   unformat_input_t *input = vam->input;
15787   vl_api_classify_table_info_t *mp;
15788   f64 timeout;
15789
15790   u32 table_id = ~0;
15791   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15792     {
15793       if (unformat (input, "table_id %d", &table_id))
15794         ;
15795       else
15796         break;
15797     }
15798   if (table_id == ~0)
15799     {
15800       errmsg ("missing table id");
15801       return -99;
15802     }
15803
15804   /* Construct the API message */
15805   M (CLASSIFY_TABLE_INFO, classify_table_info);
15806   mp->context = 0;
15807   mp->table_id = ntohl (table_id);
15808
15809   S;
15810   W;
15811   /* NOTREACHED */
15812   return 0;
15813 }
15814
15815 int
15816 api_classify_session_dump (vat_main_t * vam)
15817 {
15818   unformat_input_t *input = vam->input;
15819   vl_api_classify_session_dump_t *mp;
15820   f64 timeout;
15821
15822   u32 table_id = ~0;
15823   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15824     {
15825       if (unformat (input, "table_id %d", &table_id))
15826         ;
15827       else
15828         break;
15829     }
15830   if (table_id == ~0)
15831     {
15832       errmsg ("missing table id");
15833       return -99;
15834     }
15835
15836   /* Construct the API message */
15837   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15838   mp->context = 0;
15839   mp->table_id = ntohl (table_id);
15840   S;
15841
15842   /* Use a control ping for synchronization */
15843   {
15844     vl_api_control_ping_t *mp;
15845     M (CONTROL_PING, control_ping);
15846     S;
15847   }
15848   W;
15849   /* NOTREACHED */
15850   return 0;
15851 }
15852
15853 static void
15854 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15855 {
15856   vat_main_t *vam = &vat_main;
15857
15858   print (vam->ofp, "collector_address %U, collector_port %d, "
15859          "src_address %U, vrf_id %d, path_mtu %u, "
15860          "template_interval %u, udp_checksum %d",
15861          format_ip4_address, mp->collector_address,
15862          ntohs (mp->collector_port),
15863          format_ip4_address, mp->src_address,
15864          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15865          ntohl (mp->template_interval), mp->udp_checksum);
15866
15867   vam->retval = 0;
15868   vam->result_ready = 1;
15869 }
15870
15871 static void
15872   vl_api_ipfix_exporter_details_t_handler_json
15873   (vl_api_ipfix_exporter_details_t * mp)
15874 {
15875   vat_main_t *vam = &vat_main;
15876   vat_json_node_t node;
15877   struct in_addr collector_address;
15878   struct in_addr src_address;
15879
15880   vat_json_init_object (&node);
15881   clib_memcpy (&collector_address, &mp->collector_address,
15882                sizeof (collector_address));
15883   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15884   vat_json_object_add_uint (&node, "collector_port",
15885                             ntohs (mp->collector_port));
15886   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15887   vat_json_object_add_ip4 (&node, "src_address", src_address);
15888   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15889   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15890   vat_json_object_add_uint (&node, "template_interval",
15891                             ntohl (mp->template_interval));
15892   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15893
15894   vat_json_print (vam->ofp, &node);
15895   vat_json_free (&node);
15896   vam->retval = 0;
15897   vam->result_ready = 1;
15898 }
15899
15900 int
15901 api_ipfix_exporter_dump (vat_main_t * vam)
15902 {
15903   vl_api_ipfix_exporter_dump_t *mp;
15904   f64 timeout;
15905
15906   /* Construct the API message */
15907   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15908   mp->context = 0;
15909
15910   S;
15911   W;
15912   /* NOTREACHED */
15913   return 0;
15914 }
15915
15916 static int
15917 api_ipfix_classify_stream_dump (vat_main_t * vam)
15918 {
15919   vl_api_ipfix_classify_stream_dump_t *mp;
15920   f64 timeout;
15921
15922   /* Construct the API message */
15923   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15924   mp->context = 0;
15925
15926   S;
15927   W;
15928   /* NOTREACHED */
15929   return 0;
15930 }
15931
15932 static void
15933   vl_api_ipfix_classify_stream_details_t_handler
15934   (vl_api_ipfix_classify_stream_details_t * mp)
15935 {
15936   vat_main_t *vam = &vat_main;
15937   print (vam->ofp, "domain_id %d, src_port %d",
15938          ntohl (mp->domain_id), ntohs (mp->src_port));
15939   vam->retval = 0;
15940   vam->result_ready = 1;
15941 }
15942
15943 static void
15944   vl_api_ipfix_classify_stream_details_t_handler_json
15945   (vl_api_ipfix_classify_stream_details_t * mp)
15946 {
15947   vat_main_t *vam = &vat_main;
15948   vat_json_node_t node;
15949
15950   vat_json_init_object (&node);
15951   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15952   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15953
15954   vat_json_print (vam->ofp, &node);
15955   vat_json_free (&node);
15956   vam->retval = 0;
15957   vam->result_ready = 1;
15958 }
15959
15960 static int
15961 api_ipfix_classify_table_dump (vat_main_t * vam)
15962 {
15963   vl_api_ipfix_classify_table_dump_t *mp;
15964   f64 timeout;
15965
15966   if (!vam->json_output)
15967     {
15968       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
15969              "transport_protocol");
15970     }
15971
15972   /* Construct the API message */
15973   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15974
15975   /* send it... */
15976   S;
15977
15978   /* Use a control ping for synchronization */
15979   {
15980     vl_api_control_ping_t *mp;
15981     M (CONTROL_PING, control_ping);
15982     S;
15983   }
15984   W;
15985 }
15986
15987 static void
15988   vl_api_ipfix_classify_table_details_t_handler
15989   (vl_api_ipfix_classify_table_details_t * mp)
15990 {
15991   vat_main_t *vam = &vat_main;
15992   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
15993          mp->transport_protocol);
15994 }
15995
15996 static void
15997   vl_api_ipfix_classify_table_details_t_handler_json
15998   (vl_api_ipfix_classify_table_details_t * mp)
15999 {
16000   vat_json_node_t *node = NULL;
16001   vat_main_t *vam = &vat_main;
16002
16003   if (VAT_JSON_ARRAY != vam->json_tree.type)
16004     {
16005       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16006       vat_json_init_array (&vam->json_tree);
16007     }
16008
16009   node = vat_json_array_add (&vam->json_tree);
16010   vat_json_init_object (node);
16011
16012   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
16013   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
16014   vat_json_object_add_uint (node, "transport_protocol",
16015                             mp->transport_protocol);
16016 }
16017
16018 static int
16019 api_sw_interface_span_enable_disable (vat_main_t * vam)
16020 {
16021   unformat_input_t *i = vam->input;
16022   vl_api_sw_interface_span_enable_disable_t *mp;
16023   f64 timeout;
16024   u32 src_sw_if_index = ~0;
16025   u32 dst_sw_if_index = ~0;
16026   u8 state = 3;
16027
16028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16029     {
16030       if (unformat
16031           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
16032         ;
16033       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
16034         ;
16035       else
16036         if (unformat
16037             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
16038         ;
16039       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
16040         ;
16041       else if (unformat (i, "disable"))
16042         state = 0;
16043       else if (unformat (i, "rx"))
16044         state = 1;
16045       else if (unformat (i, "tx"))
16046         state = 2;
16047       else if (unformat (i, "both"))
16048         state = 3;
16049       else
16050         break;
16051     }
16052
16053   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
16054
16055   mp->sw_if_index_from = htonl (src_sw_if_index);
16056   mp->sw_if_index_to = htonl (dst_sw_if_index);
16057   mp->state = state;
16058
16059   S;
16060   W;
16061   /* NOTREACHED */
16062   return 0;
16063 }
16064
16065 static void
16066 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
16067                                             * mp)
16068 {
16069   vat_main_t *vam = &vat_main;
16070   u8 *sw_if_from_name = 0;
16071   u8 *sw_if_to_name = 0;
16072   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16073   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16074   char *states[] = { "none", "rx", "tx", "both" };
16075   hash_pair_t *p;
16076
16077   /* *INDENT-OFF* */
16078   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16079   ({
16080     if ((u32) p->value[0] == sw_if_index_from)
16081       {
16082         sw_if_from_name = (u8 *)(p->key);
16083         if (sw_if_to_name)
16084           break;
16085       }
16086     if ((u32) p->value[0] == sw_if_index_to)
16087       {
16088         sw_if_to_name = (u8 *)(p->key);
16089         if (sw_if_from_name)
16090           break;
16091       }
16092   }));
16093   /* *INDENT-ON* */
16094   print (vam->ofp, "%20s => %20s (%s)",
16095          sw_if_from_name, sw_if_to_name, states[mp->state]);
16096 }
16097
16098 static void
16099   vl_api_sw_interface_span_details_t_handler_json
16100   (vl_api_sw_interface_span_details_t * mp)
16101 {
16102   vat_main_t *vam = &vat_main;
16103   vat_json_node_t *node = NULL;
16104   u8 *sw_if_from_name = 0;
16105   u8 *sw_if_to_name = 0;
16106   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16107   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16108   hash_pair_t *p;
16109
16110   /* *INDENT-OFF* */
16111   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16112   ({
16113     if ((u32) p->value[0] == sw_if_index_from)
16114       {
16115         sw_if_from_name = (u8 *)(p->key);
16116         if (sw_if_to_name)
16117           break;
16118       }
16119     if ((u32) p->value[0] == sw_if_index_to)
16120       {
16121         sw_if_to_name = (u8 *)(p->key);
16122         if (sw_if_from_name)
16123           break;
16124       }
16125   }));
16126   /* *INDENT-ON* */
16127
16128   if (VAT_JSON_ARRAY != vam->json_tree.type)
16129     {
16130       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16131       vat_json_init_array (&vam->json_tree);
16132     }
16133   node = vat_json_array_add (&vam->json_tree);
16134
16135   vat_json_init_object (node);
16136   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16137   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16138   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16139   vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16140   vat_json_object_add_uint (node, "state", mp->state);
16141 }
16142
16143 static int
16144 api_sw_interface_span_dump (vat_main_t * vam)
16145 {
16146   vl_api_sw_interface_span_dump_t *mp;
16147   f64 timeout;
16148
16149   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
16150   S;
16151
16152   /* Use a control ping for synchronization */
16153   {
16154     vl_api_control_ping_t *mp;
16155     M (CONTROL_PING, control_ping);
16156     S;
16157   }
16158   W;
16159 }
16160
16161 int
16162 api_pg_create_interface (vat_main_t * vam)
16163 {
16164   unformat_input_t *input = vam->input;
16165   vl_api_pg_create_interface_t *mp;
16166   f64 timeout;
16167
16168   u32 if_id = ~0;
16169   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16170     {
16171       if (unformat (input, "if_id %d", &if_id))
16172         ;
16173       else
16174         break;
16175     }
16176   if (if_id == ~0)
16177     {
16178       errmsg ("missing pg interface index");
16179       return -99;
16180     }
16181
16182   /* Construct the API message */
16183   M (PG_CREATE_INTERFACE, pg_create_interface);
16184   mp->context = 0;
16185   mp->interface_id = ntohl (if_id);
16186
16187   S;
16188   W;
16189   /* NOTREACHED */
16190   return 0;
16191 }
16192
16193 int
16194 api_pg_capture (vat_main_t * vam)
16195 {
16196   unformat_input_t *input = vam->input;
16197   vl_api_pg_capture_t *mp;
16198   f64 timeout;
16199
16200   u32 if_id = ~0;
16201   u8 enable = 1;
16202   u32 count = 1;
16203   u8 pcap_file_set = 0;
16204   u8 *pcap_file = 0;
16205   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16206     {
16207       if (unformat (input, "if_id %d", &if_id))
16208         ;
16209       else if (unformat (input, "pcap %s", &pcap_file))
16210         pcap_file_set = 1;
16211       else if (unformat (input, "count %d", &count))
16212         ;
16213       else if (unformat (input, "disable"))
16214         enable = 0;
16215       else
16216         break;
16217     }
16218   if (if_id == ~0)
16219     {
16220       errmsg ("missing pg interface index");
16221       return -99;
16222     }
16223   if (pcap_file_set > 0)
16224     {
16225       if (vec_len (pcap_file) > 255)
16226         {
16227           errmsg ("pcap file name is too long");
16228           return -99;
16229         }
16230     }
16231
16232   u32 name_len = vec_len (pcap_file);
16233   /* Construct the API message */
16234   M (PG_CAPTURE, pg_capture);
16235   mp->context = 0;
16236   mp->interface_id = ntohl (if_id);
16237   mp->is_enabled = enable;
16238   mp->count = ntohl (count);
16239   mp->pcap_name_length = ntohl (name_len);
16240   if (pcap_file_set != 0)
16241     {
16242       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16243     }
16244   vec_free (pcap_file);
16245
16246   S;
16247   W;
16248   /* NOTREACHED */
16249   return 0;
16250 }
16251
16252 int
16253 api_pg_enable_disable (vat_main_t * vam)
16254 {
16255   unformat_input_t *input = vam->input;
16256   vl_api_pg_enable_disable_t *mp;
16257   f64 timeout;
16258
16259   u8 enable = 1;
16260   u8 stream_name_set = 0;
16261   u8 *stream_name = 0;
16262   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16263     {
16264       if (unformat (input, "stream %s", &stream_name))
16265         stream_name_set = 1;
16266       else if (unformat (input, "disable"))
16267         enable = 0;
16268       else
16269         break;
16270     }
16271
16272   if (stream_name_set > 0)
16273     {
16274       if (vec_len (stream_name) > 255)
16275         {
16276           errmsg ("stream name too long");
16277           return -99;
16278         }
16279     }
16280
16281   u32 name_len = vec_len (stream_name);
16282   /* Construct the API message */
16283   M (PG_ENABLE_DISABLE, pg_enable_disable);
16284   mp->context = 0;
16285   mp->is_enabled = enable;
16286   if (stream_name_set != 0)
16287     {
16288       mp->stream_name_length = ntohl (name_len);
16289       clib_memcpy (mp->stream_name, stream_name, name_len);
16290     }
16291   vec_free (stream_name);
16292
16293   S;
16294   W;
16295   /* NOTREACHED */
16296   return 0;
16297 }
16298
16299 int
16300 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16301 {
16302   unformat_input_t *input = vam->input;
16303   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16304   f64 timeout;
16305
16306   u16 *low_ports = 0;
16307   u16 *high_ports = 0;
16308   u16 this_low;
16309   u16 this_hi;
16310   ip4_address_t ip4_addr;
16311   ip6_address_t ip6_addr;
16312   u32 length;
16313   u32 tmp, tmp2;
16314   u8 prefix_set = 0;
16315   u32 vrf_id = ~0;
16316   u8 is_add = 1;
16317   u8 is_ipv6 = 0;
16318
16319   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16320     {
16321       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16322         {
16323           prefix_set = 1;
16324         }
16325       else
16326         if (unformat
16327             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16328         {
16329           prefix_set = 1;
16330           is_ipv6 = 1;
16331         }
16332       else if (unformat (input, "vrf %d", &vrf_id))
16333         ;
16334       else if (unformat (input, "del"))
16335         is_add = 0;
16336       else if (unformat (input, "port %d", &tmp))
16337         {
16338           if (tmp == 0 || tmp > 65535)
16339             {
16340               errmsg ("port %d out of range", tmp);
16341               return -99;
16342             }
16343           this_low = tmp;
16344           this_hi = this_low + 1;
16345           vec_add1 (low_ports, this_low);
16346           vec_add1 (high_ports, this_hi);
16347         }
16348       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16349         {
16350           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16351             {
16352               errmsg ("incorrect range parameters");
16353               return -99;
16354             }
16355           this_low = tmp;
16356           /* Note: in debug CLI +1 is added to high before
16357              passing to real fn that does "the work"
16358              (ip_source_and_port_range_check_add_del).
16359              This fn is a wrapper around the binary API fn a
16360              control plane will call, which expects this increment
16361              to have occurred. Hence letting the binary API control
16362              plane fn do the increment for consistency between VAT
16363              and other control planes.
16364            */
16365           this_hi = tmp2;
16366           vec_add1 (low_ports, this_low);
16367           vec_add1 (high_ports, this_hi);
16368         }
16369       else
16370         break;
16371     }
16372
16373   if (prefix_set == 0)
16374     {
16375       errmsg ("<address>/<mask> not specified");
16376       return -99;
16377     }
16378
16379   if (vrf_id == ~0)
16380     {
16381       errmsg ("VRF ID required, not specified");
16382       return -99;
16383     }
16384
16385   if (vrf_id == 0)
16386     {
16387       errmsg
16388         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16389       return -99;
16390     }
16391
16392   if (vec_len (low_ports) == 0)
16393     {
16394       errmsg ("At least one port or port range required");
16395       return -99;
16396     }
16397
16398   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
16399      ip_source_and_port_range_check_add_del);
16400
16401   mp->is_add = is_add;
16402
16403   if (is_ipv6)
16404     {
16405       mp->is_ipv6 = 1;
16406       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16407     }
16408   else
16409     {
16410       mp->is_ipv6 = 0;
16411       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16412     }
16413
16414   mp->mask_length = length;
16415   mp->number_of_ranges = vec_len (low_ports);
16416
16417   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16418   vec_free (low_ports);
16419
16420   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16421   vec_free (high_ports);
16422
16423   mp->vrf_id = ntohl (vrf_id);
16424
16425   S;
16426   W;
16427   /* NOTREACHED */
16428   return 0;
16429 }
16430
16431 int
16432 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16433 {
16434   unformat_input_t *input = vam->input;
16435   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16436   f64 timeout;
16437   u32 sw_if_index = ~0;
16438   int vrf_set = 0;
16439   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16440   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16441   u8 is_add = 1;
16442
16443   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16444     {
16445       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16446         ;
16447       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16448         ;
16449       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16450         vrf_set = 1;
16451       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16452         vrf_set = 1;
16453       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16454         vrf_set = 1;
16455       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16456         vrf_set = 1;
16457       else if (unformat (input, "del"))
16458         is_add = 0;
16459       else
16460         break;
16461     }
16462
16463   if (sw_if_index == ~0)
16464     {
16465       errmsg ("Interface required but not specified");
16466       return -99;
16467     }
16468
16469   if (vrf_set == 0)
16470     {
16471       errmsg ("VRF ID required but not specified");
16472       return -99;
16473     }
16474
16475   if (tcp_out_vrf_id == 0
16476       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16477     {
16478       errmsg
16479         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16480       return -99;
16481     }
16482
16483   /* Construct the API message */
16484   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
16485      ip_source_and_port_range_check_interface_add_del);
16486
16487   mp->sw_if_index = ntohl (sw_if_index);
16488   mp->is_add = is_add;
16489   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16490   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16491   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16492   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16493
16494   /* send it... */
16495   S;
16496
16497   /* Wait for a reply... */
16498   W;
16499 }
16500
16501 static int
16502 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16503 {
16504   unformat_input_t *i = vam->input;
16505   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16506   f64 timeout;
16507   u32 local_sa_id = 0;
16508   u32 remote_sa_id = 0;
16509   ip4_address_t src_address;
16510   ip4_address_t dst_address;
16511   u8 is_add = 1;
16512
16513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16514     {
16515       if (unformat (i, "local_sa %d", &local_sa_id))
16516         ;
16517       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16518         ;
16519       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16520         ;
16521       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16522         ;
16523       else if (unformat (i, "del"))
16524         is_add = 0;
16525       else
16526         {
16527           clib_warning ("parse error '%U'", format_unformat_error, i);
16528           return -99;
16529         }
16530     }
16531
16532   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16533
16534   mp->local_sa_id = ntohl (local_sa_id);
16535   mp->remote_sa_id = ntohl (remote_sa_id);
16536   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16537   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16538   mp->is_add = is_add;
16539
16540   S;
16541   W;
16542   /* NOTREACHED */
16543   return 0;
16544 }
16545
16546 static int
16547 api_punt (vat_main_t * vam)
16548 {
16549   unformat_input_t *i = vam->input;
16550   vl_api_punt_t *mp;
16551   f64 timeout;
16552   u32 ipv = ~0;
16553   u32 protocol = ~0;
16554   u32 port = ~0;
16555   int is_add = 1;
16556
16557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16558     {
16559       if (unformat (i, "ip %d", &ipv))
16560         ;
16561       else if (unformat (i, "protocol %d", &protocol))
16562         ;
16563       else if (unformat (i, "port %d", &port))
16564         ;
16565       else if (unformat (i, "del"))
16566         is_add = 0;
16567       else
16568         {
16569           clib_warning ("parse error '%U'", format_unformat_error, i);
16570           return -99;
16571         }
16572     }
16573
16574   M (PUNT, punt);
16575
16576   mp->is_add = (u8) is_add;
16577   mp->ipv = (u8) ipv;
16578   mp->l4_protocol = (u8) protocol;
16579   mp->l4_port = htons ((u16) port);
16580
16581   S;
16582   W;
16583   /* NOTREACHED */
16584   return 0;
16585 }
16586
16587 static void vl_api_ipsec_gre_tunnel_details_t_handler
16588   (vl_api_ipsec_gre_tunnel_details_t * mp)
16589 {
16590   vat_main_t *vam = &vat_main;
16591
16592   print (vam->ofp, "%11d%15U%15U%14d%14d",
16593          ntohl (mp->sw_if_index),
16594          format_ip4_address, &mp->src_address,
16595          format_ip4_address, &mp->dst_address,
16596          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16597 }
16598
16599 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16600   (vl_api_ipsec_gre_tunnel_details_t * mp)
16601 {
16602   vat_main_t *vam = &vat_main;
16603   vat_json_node_t *node = NULL;
16604   struct in_addr ip4;
16605
16606   if (VAT_JSON_ARRAY != vam->json_tree.type)
16607     {
16608       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16609       vat_json_init_array (&vam->json_tree);
16610     }
16611   node = vat_json_array_add (&vam->json_tree);
16612
16613   vat_json_init_object (node);
16614   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16615   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16616   vat_json_object_add_ip4 (node, "src_address", ip4);
16617   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16618   vat_json_object_add_ip4 (node, "dst_address", ip4);
16619   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16620   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16621 }
16622
16623 static int
16624 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16625 {
16626   unformat_input_t *i = vam->input;
16627   vl_api_ipsec_gre_tunnel_dump_t *mp;
16628   f64 timeout;
16629   u32 sw_if_index;
16630   u8 sw_if_index_set = 0;
16631
16632   /* Parse args required to build the message */
16633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16634     {
16635       if (unformat (i, "sw_if_index %d", &sw_if_index))
16636         sw_if_index_set = 1;
16637       else
16638         break;
16639     }
16640
16641   if (sw_if_index_set == 0)
16642     {
16643       sw_if_index = ~0;
16644     }
16645
16646   if (!vam->json_output)
16647     {
16648       print (vam->ofp, "%11s%15s%15s%14s%14s",
16649              "sw_if_index", "src_address", "dst_address",
16650              "local_sa_id", "remote_sa_id");
16651     }
16652
16653   /* Get list of gre-tunnel interfaces */
16654   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16655
16656   mp->sw_if_index = htonl (sw_if_index);
16657
16658   S;
16659
16660   /* Use a control ping for synchronization */
16661   {
16662     vl_api_control_ping_t *mp;
16663     M (CONTROL_PING, control_ping);
16664     S;
16665   }
16666   W;
16667 }
16668
16669 static int
16670 api_delete_subif (vat_main_t * vam)
16671 {
16672   unformat_input_t *i = vam->input;
16673   vl_api_delete_subif_t *mp;
16674   f64 timeout;
16675   u32 sw_if_index = ~0;
16676
16677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16678     {
16679       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16680         ;
16681       if (unformat (i, "sw_if_index %d", &sw_if_index))
16682         ;
16683       else
16684         break;
16685     }
16686
16687   if (sw_if_index == ~0)
16688     {
16689       errmsg ("missing sw_if_index");
16690       return -99;
16691     }
16692
16693   /* Construct the API message */
16694   M (DELETE_SUBIF, delete_subif);
16695   mp->sw_if_index = ntohl (sw_if_index);
16696
16697   S;
16698   W;
16699 }
16700
16701 #define foreach_pbb_vtr_op      \
16702 _("disable",  L2_VTR_DISABLED)  \
16703 _("pop",  L2_VTR_POP_2)         \
16704 _("push",  L2_VTR_PUSH_2)
16705
16706 static int
16707 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16708 {
16709   unformat_input_t *i = vam->input;
16710   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16711   f64 timeout;
16712   u32 sw_if_index = ~0, vtr_op = ~0;
16713   u16 outer_tag = ~0;
16714   u8 dmac[6], smac[6];
16715   u8 dmac_set = 0, smac_set = 0;
16716   u16 vlanid = 0;
16717   u32 sid = ~0;
16718   u32 tmp;
16719
16720   /* Shut up coverity */
16721   memset (dmac, 0, sizeof (dmac));
16722   memset (smac, 0, sizeof (smac));
16723
16724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16725     {
16726       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16727         ;
16728       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16729         ;
16730       else if (unformat (i, "vtr_op %d", &vtr_op))
16731         ;
16732 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16733       foreach_pbb_vtr_op
16734 #undef _
16735         else if (unformat (i, "translate_pbb_stag"))
16736         {
16737           if (unformat (i, "%d", &tmp))
16738             {
16739               vtr_op = L2_VTR_TRANSLATE_2_1;
16740               outer_tag = tmp;
16741             }
16742           else
16743             {
16744               errmsg
16745                 ("translate_pbb_stag operation requires outer tag definition");
16746               return -99;
16747             }
16748         }
16749       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16750         dmac_set++;
16751       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16752         smac_set++;
16753       else if (unformat (i, "sid %d", &sid))
16754         ;
16755       else if (unformat (i, "vlanid %d", &tmp))
16756         vlanid = tmp;
16757       else
16758         {
16759           clib_warning ("parse error '%U'", format_unformat_error, i);
16760           return -99;
16761         }
16762     }
16763
16764   if ((sw_if_index == ~0) || (vtr_op == ~0))
16765     {
16766       errmsg ("missing sw_if_index or vtr operation");
16767       return -99;
16768     }
16769   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16770       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16771     {
16772       errmsg
16773         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
16774       return -99;
16775     }
16776
16777   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16778   mp->sw_if_index = ntohl (sw_if_index);
16779   mp->vtr_op = ntohl (vtr_op);
16780   mp->outer_tag = ntohs (outer_tag);
16781   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16782   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16783   mp->b_vlanid = ntohs (vlanid);
16784   mp->i_sid = ntohl (sid);
16785
16786   S;
16787   W;
16788   /* NOTREACHED */
16789   return 0;
16790 }
16791
16792 static int
16793 api_flow_classify_set_interface (vat_main_t * vam)
16794 {
16795   unformat_input_t *i = vam->input;
16796   vl_api_flow_classify_set_interface_t *mp;
16797   f64 timeout;
16798   u32 sw_if_index;
16799   int sw_if_index_set;
16800   u32 ip4_table_index = ~0;
16801   u32 ip6_table_index = ~0;
16802   u8 is_add = 1;
16803
16804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16805     {
16806       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16807         sw_if_index_set = 1;
16808       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16809         sw_if_index_set = 1;
16810       else if (unformat (i, "del"))
16811         is_add = 0;
16812       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16813         ;
16814       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16815         ;
16816       else
16817         {
16818           clib_warning ("parse error '%U'", format_unformat_error, i);
16819           return -99;
16820         }
16821     }
16822
16823   if (sw_if_index_set == 0)
16824     {
16825       errmsg ("missing interface name or sw_if_index");
16826       return -99;
16827     }
16828
16829   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16830
16831   mp->sw_if_index = ntohl (sw_if_index);
16832   mp->ip4_table_index = ntohl (ip4_table_index);
16833   mp->ip6_table_index = ntohl (ip6_table_index);
16834   mp->is_add = is_add;
16835
16836   S;
16837   W;
16838   /* NOTREACHED */
16839   return 0;
16840 }
16841
16842 static int
16843 api_flow_classify_dump (vat_main_t * vam)
16844 {
16845   unformat_input_t *i = vam->input;
16846   vl_api_flow_classify_dump_t *mp;
16847   f64 timeout = ~0;
16848   u8 type = FLOW_CLASSIFY_N_TABLES;
16849
16850   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16851     ;
16852   else
16853     {
16854       errmsg ("classify table type must be specified");
16855       return -99;
16856     }
16857
16858   if (!vam->json_output)
16859     {
16860       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16861     }
16862
16863   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16864   mp->type = type;
16865   /* send it... */
16866   S;
16867
16868   /* Use a control ping for synchronization */
16869   {
16870     vl_api_control_ping_t *mp;
16871     M (CONTROL_PING, control_ping);
16872     S;
16873   }
16874   /* Wait for a reply... */
16875   W;
16876
16877   /* NOTREACHED */
16878   return 0;
16879 }
16880
16881 static int
16882 api_feature_enable_disable (vat_main_t * vam)
16883 {
16884   unformat_input_t *i = vam->input;
16885   vl_api_feature_enable_disable_t *mp;
16886   f64 timeout;
16887   u8 *arc_name = 0;
16888   u8 *feature_name = 0;
16889   u32 sw_if_index = ~0;
16890   u8 enable = 1;
16891
16892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16893     {
16894       if (unformat (i, "arc_name %s", &arc_name))
16895         ;
16896       else if (unformat (i, "feature_name %s", &feature_name))
16897         ;
16898       else
16899         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16900         ;
16901       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16902         ;
16903       else if (unformat (i, "disable"))
16904         enable = 0;
16905       else
16906         break;
16907     }
16908
16909   if (arc_name == 0)
16910     {
16911       errmsg ("missing arc name");
16912       return -99;
16913     }
16914   if (vec_len (arc_name) > 63)
16915     {
16916       errmsg ("arc name too long");
16917     }
16918
16919   if (feature_name == 0)
16920     {
16921       errmsg ("missing feature name");
16922       return -99;
16923     }
16924   if (vec_len (feature_name) > 63)
16925     {
16926       errmsg ("feature name too long");
16927     }
16928
16929   if (sw_if_index == ~0)
16930     {
16931       errmsg ("missing interface name or sw_if_index");
16932       return -99;
16933     }
16934
16935   /* Construct the API message */
16936   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16937   mp->sw_if_index = ntohl (sw_if_index);
16938   mp->enable = enable;
16939   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16940   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16941   vec_free (arc_name);
16942   vec_free (feature_name);
16943
16944   S;
16945   W;
16946 }
16947
16948 static int
16949 api_sw_interface_tag_add_del (vat_main_t * vam)
16950 {
16951   unformat_input_t *i = vam->input;
16952   vl_api_sw_interface_tag_add_del_t *mp;
16953   f64 timeout;
16954   u32 sw_if_index = ~0;
16955   u8 *tag = 0;
16956   u8 enable = 1;
16957
16958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16959     {
16960       if (unformat (i, "tag %s", &tag))
16961         ;
16962       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16963         ;
16964       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16965         ;
16966       else if (unformat (i, "del"))
16967         enable = 0;
16968       else
16969         break;
16970     }
16971
16972   if (sw_if_index == ~0)
16973     {
16974       errmsg ("missing interface name or sw_if_index");
16975       return -99;
16976     }
16977
16978   if (enable && (tag == 0))
16979     {
16980       errmsg ("no tag specified");
16981       return -99;
16982     }
16983
16984   /* Construct the API message */
16985   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
16986   mp->sw_if_index = ntohl (sw_if_index);
16987   mp->is_add = enable;
16988   if (enable)
16989     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
16990   vec_free (tag);
16991
16992   S;
16993   W;
16994 }
16995
16996 static void vl_api_l2_xconnect_details_t_handler
16997   (vl_api_l2_xconnect_details_t * mp)
16998 {
16999   vat_main_t *vam = &vat_main;
17000
17001   print (vam->ofp, "%15d%15d",
17002          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
17003 }
17004
17005 static void vl_api_l2_xconnect_details_t_handler_json
17006   (vl_api_l2_xconnect_details_t * mp)
17007 {
17008   vat_main_t *vam = &vat_main;
17009   vat_json_node_t *node = NULL;
17010
17011   if (VAT_JSON_ARRAY != vam->json_tree.type)
17012     {
17013       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17014       vat_json_init_array (&vam->json_tree);
17015     }
17016   node = vat_json_array_add (&vam->json_tree);
17017
17018   vat_json_init_object (node);
17019   vat_json_object_add_uint (node, "rx_sw_if_index",
17020                             ntohl (mp->rx_sw_if_index));
17021   vat_json_object_add_uint (node, "tx_sw_if_index",
17022                             ntohl (mp->tx_sw_if_index));
17023 }
17024
17025 static int
17026 api_l2_xconnect_dump (vat_main_t * vam)
17027 {
17028   vl_api_l2_xconnect_dump_t *mp;
17029   f64 timeout;
17030
17031   if (!vam->json_output)
17032     {
17033       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
17034     }
17035
17036   M (L2_XCONNECT_DUMP, l2_xconnect_dump);
17037
17038   S;
17039
17040   /* Use a control ping for synchronization */
17041   {
17042     vl_api_control_ping_t *mp;
17043     M (CONTROL_PING, control_ping);
17044     S;
17045   }
17046   W;
17047 }
17048
17049 static int
17050 api_sw_interface_set_mtu (vat_main_t * vam)
17051 {
17052   unformat_input_t *i = vam->input;
17053   vl_api_sw_interface_set_mtu_t *mp;
17054   f64 timeout;
17055   u32 sw_if_index = ~0;
17056   u32 mtu = 0;
17057
17058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17059     {
17060       if (unformat (i, "mtu %d", &mtu))
17061         ;
17062       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17063         ;
17064       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17065         ;
17066       else
17067         break;
17068     }
17069
17070   if (sw_if_index == ~0)
17071     {
17072       errmsg ("missing interface name or sw_if_index");
17073       return -99;
17074     }
17075
17076   if (mtu == 0)
17077     {
17078       errmsg ("no mtu specified");
17079       return -99;
17080     }
17081
17082   /* Construct the API message */
17083   M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
17084   mp->sw_if_index = ntohl (sw_if_index);
17085   mp->mtu = ntohs ((u16) mtu);
17086
17087   S;
17088   W;
17089 }
17090
17091
17092 static int
17093 q_or_quit (vat_main_t * vam)
17094 {
17095   longjmp (vam->jump_buf, 1);
17096   return 0;                     /* not so much */
17097 }
17098
17099 static int
17100 q (vat_main_t * vam)
17101 {
17102   return q_or_quit (vam);
17103 }
17104
17105 static int
17106 quit (vat_main_t * vam)
17107 {
17108   return q_or_quit (vam);
17109 }
17110
17111 static int
17112 comment (vat_main_t * vam)
17113 {
17114   return 0;
17115 }
17116
17117 static int
17118 cmd_cmp (void *a1, void *a2)
17119 {
17120   u8 **c1 = a1;
17121   u8 **c2 = a2;
17122
17123   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17124 }
17125
17126 static int
17127 help (vat_main_t * vam)
17128 {
17129   u8 **cmds = 0;
17130   u8 *name = 0;
17131   hash_pair_t *p;
17132   unformat_input_t *i = vam->input;
17133   int j;
17134
17135   if (unformat (i, "%s", &name))
17136     {
17137       uword *hs;
17138
17139       vec_add1 (name, 0);
17140
17141       hs = hash_get_mem (vam->help_by_name, name);
17142       if (hs)
17143         print (vam->ofp, "usage: %s %s", name, hs[0]);
17144       else
17145         print (vam->ofp, "No such msg / command '%s'", name);
17146       vec_free (name);
17147       return 0;
17148     }
17149
17150   print (vam->ofp, "Help is available for the following:");
17151
17152     /* *INDENT-OFF* */
17153     hash_foreach_pair (p, vam->function_by_name,
17154     ({
17155       vec_add1 (cmds, (u8 *)(p->key));
17156     }));
17157     /* *INDENT-ON* */
17158
17159   vec_sort_with_function (cmds, cmd_cmp);
17160
17161   for (j = 0; j < vec_len (cmds); j++)
17162     print (vam->ofp, "%s", cmds[j]);
17163
17164   vec_free (cmds);
17165   return 0;
17166 }
17167
17168 static int
17169 set (vat_main_t * vam)
17170 {
17171   u8 *name = 0, *value = 0;
17172   unformat_input_t *i = vam->input;
17173
17174   if (unformat (i, "%s", &name))
17175     {
17176       /* The input buffer is a vector, not a string. */
17177       value = vec_dup (i->buffer);
17178       vec_delete (value, i->index, 0);
17179       /* Almost certainly has a trailing newline */
17180       if (value[vec_len (value) - 1] == '\n')
17181         value[vec_len (value) - 1] = 0;
17182       /* Make sure it's a proper string, one way or the other */
17183       vec_add1 (value, 0);
17184       (void) clib_macro_set_value (&vam->macro_main,
17185                                    (char *) name, (char *) value);
17186     }
17187   else
17188     errmsg ("usage: set <name> <value>");
17189
17190   vec_free (name);
17191   vec_free (value);
17192   return 0;
17193 }
17194
17195 static int
17196 unset (vat_main_t * vam)
17197 {
17198   u8 *name = 0;
17199
17200   if (unformat (vam->input, "%s", &name))
17201     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17202       errmsg ("unset: %s wasn't set", name);
17203   vec_free (name);
17204   return 0;
17205 }
17206
17207 typedef struct
17208 {
17209   u8 *name;
17210   u8 *value;
17211 } macro_sort_t;
17212
17213
17214 static int
17215 macro_sort_cmp (void *a1, void *a2)
17216 {
17217   macro_sort_t *s1 = a1;
17218   macro_sort_t *s2 = a2;
17219
17220   return strcmp ((char *) (s1->name), (char *) (s2->name));
17221 }
17222
17223 static int
17224 dump_macro_table (vat_main_t * vam)
17225 {
17226   macro_sort_t *sort_me = 0, *sm;
17227   int i;
17228   hash_pair_t *p;
17229
17230     /* *INDENT-OFF* */
17231     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17232     ({
17233       vec_add2 (sort_me, sm, 1);
17234       sm->name = (u8 *)(p->key);
17235       sm->value = (u8 *) (p->value[0]);
17236     }));
17237     /* *INDENT-ON* */
17238
17239   vec_sort_with_function (sort_me, macro_sort_cmp);
17240
17241   if (vec_len (sort_me))
17242     print (vam->ofp, "%-15s%s", "Name", "Value");
17243   else
17244     print (vam->ofp, "The macro table is empty...");
17245
17246   for (i = 0; i < vec_len (sort_me); i++)
17247     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17248   return 0;
17249 }
17250
17251 static int
17252 dump_node_table (vat_main_t * vam)
17253 {
17254   int i, j;
17255   vlib_node_t *node, *next_node;
17256
17257   if (vec_len (vam->graph_nodes) == 0)
17258     {
17259       print (vam->ofp, "Node table empty, issue get_node_graph...");
17260       return 0;
17261     }
17262
17263   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17264     {
17265       node = vam->graph_nodes[i];
17266       print (vam->ofp, "[%d] %s", i, node->name);
17267       for (j = 0; j < vec_len (node->next_nodes); j++)
17268         {
17269           if (node->next_nodes[j] != ~0)
17270             {
17271               next_node = vam->graph_nodes[node->next_nodes[j]];
17272               print (vam->ofp, "  [%d] %s", j, next_node->name);
17273             }
17274         }
17275     }
17276   return 0;
17277 }
17278
17279 static int
17280 value_sort_cmp (void *a1, void *a2)
17281 {
17282   name_sort_t *n1 = a1;
17283   name_sort_t *n2 = a2;
17284
17285   if (n1->value < n2->value)
17286     return -1;
17287   if (n1->value > n2->value)
17288     return 1;
17289   return 0;
17290 }
17291
17292
17293 static int
17294 dump_msg_api_table (vat_main_t * vam)
17295 {
17296   api_main_t *am = &api_main;
17297   name_sort_t *nses = 0, *ns;
17298   hash_pair_t *hp;
17299   int i;
17300
17301   /* *INDENT-OFF* */
17302   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17303   ({
17304     vec_add2 (nses, ns, 1);
17305     ns->name = (u8 *)(hp->key);
17306     ns->value = (u32) hp->value[0];
17307   }));
17308   /* *INDENT-ON* */
17309
17310   vec_sort_with_function (nses, value_sort_cmp);
17311
17312   for (i = 0; i < vec_len (nses); i++)
17313     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17314   vec_free (nses);
17315   return 0;
17316 }
17317
17318 static int
17319 get_msg_id (vat_main_t * vam)
17320 {
17321   u8 *name_and_crc;
17322   u32 message_index;
17323
17324   if (unformat (vam->input, "%s", &name_and_crc))
17325     {
17326       message_index = vl_api_get_msg_index (name_and_crc);
17327       if (message_index == ~0)
17328         {
17329           print (vam->ofp, " '%s' not found", name_and_crc);
17330           return 0;
17331         }
17332       print (vam->ofp, " '%s' has message index %d",
17333              name_and_crc, message_index);
17334       return 0;
17335     }
17336   errmsg ("name_and_crc required...");
17337   return 0;
17338 }
17339
17340 static int
17341 search_node_table (vat_main_t * vam)
17342 {
17343   unformat_input_t *line_input = vam->input;
17344   u8 *node_to_find;
17345   int j;
17346   vlib_node_t *node, *next_node;
17347   uword *p;
17348
17349   if (vam->graph_node_index_by_name == 0)
17350     {
17351       print (vam->ofp, "Node table empty, issue get_node_graph...");
17352       return 0;
17353     }
17354
17355   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17356     {
17357       if (unformat (line_input, "%s", &node_to_find))
17358         {
17359           vec_add1 (node_to_find, 0);
17360           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17361           if (p == 0)
17362             {
17363               print (vam->ofp, "%s not found...", node_to_find);
17364               goto out;
17365             }
17366           node = vam->graph_nodes[p[0]];
17367           print (vam->ofp, "[%d] %s", p[0], node->name);
17368           for (j = 0; j < vec_len (node->next_nodes); j++)
17369             {
17370               if (node->next_nodes[j] != ~0)
17371                 {
17372                   next_node = vam->graph_nodes[node->next_nodes[j]];
17373                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17374                 }
17375             }
17376         }
17377
17378       else
17379         {
17380           clib_warning ("parse error '%U'", format_unformat_error,
17381                         line_input);
17382           return -99;
17383         }
17384
17385     out:
17386       vec_free (node_to_find);
17387
17388     }
17389
17390   return 0;
17391 }
17392
17393
17394 static int
17395 script (vat_main_t * vam)
17396 {
17397 #if (VPP_API_TEST_BUILTIN==0)
17398   u8 *s = 0;
17399   char *save_current_file;
17400   unformat_input_t save_input;
17401   jmp_buf save_jump_buf;
17402   u32 save_line_number;
17403
17404   FILE *new_fp, *save_ifp;
17405
17406   if (unformat (vam->input, "%s", &s))
17407     {
17408       new_fp = fopen ((char *) s, "r");
17409       if (new_fp == 0)
17410         {
17411           errmsg ("Couldn't open script file %s", s);
17412           vec_free (s);
17413           return -99;
17414         }
17415     }
17416   else
17417     {
17418       errmsg ("Missing script name");
17419       return -99;
17420     }
17421
17422   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17423   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17424   save_ifp = vam->ifp;
17425   save_line_number = vam->input_line_number;
17426   save_current_file = (char *) vam->current_file;
17427
17428   vam->input_line_number = 0;
17429   vam->ifp = new_fp;
17430   vam->current_file = s;
17431   do_one_file (vam);
17432
17433   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17434   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17435   vam->ifp = save_ifp;
17436   vam->input_line_number = save_line_number;
17437   vam->current_file = (u8 *) save_current_file;
17438   vec_free (s);
17439
17440   return 0;
17441 #else
17442   clib_warning ("use the exec command...");
17443   return -99;
17444 #endif
17445 }
17446
17447 static int
17448 echo (vat_main_t * vam)
17449 {
17450   print (vam->ofp, "%v", vam->input->buffer);
17451   return 0;
17452 }
17453
17454 /* List of API message constructors, CLI names map to api_xxx */
17455 #define foreach_vpe_api_msg                                             \
17456 _(create_loopback,"[mac <mac-addr>]")                                   \
17457 _(sw_interface_dump,"")                                                 \
17458 _(sw_interface_set_flags,                                               \
17459   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17460 _(sw_interface_add_del_address,                                         \
17461   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17462 _(sw_interface_set_table,                                               \
17463   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17464 _(sw_interface_set_mpls_enable,                                         \
17465   "<intfc> | sw_if_index [disable | dis]")                              \
17466 _(sw_interface_set_vpath,                                               \
17467   "<intfc> | sw_if_index <id> enable | disable")                        \
17468 _(sw_interface_set_vxlan_bypass,                                        \
17469   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")            \
17470 _(sw_interface_set_l2_xconnect,                                         \
17471   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17472   "enable | disable")                                                   \
17473 _(sw_interface_set_l2_bridge,                                           \
17474   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
17475   "[shg <split-horizon-group>] [bvi]\n"                                 \
17476   "enable | disable")                                                   \
17477 _(bridge_domain_add_del,                                                \
17478   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
17479 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
17480 _(l2fib_add_del,                                                        \
17481   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17482 _(l2_flags,                                                             \
17483   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
17484 _(bridge_flags,                                                         \
17485   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17486 _(tap_connect,                                                          \
17487   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17488 _(tap_modify,                                                           \
17489   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17490 _(tap_delete,                                                           \
17491   "<vpp-if-name> | sw_if_index <id>")                                   \
17492 _(sw_interface_tap_dump, "")                                            \
17493 _(ip_add_del_route,                                                     \
17494   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17495   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17496   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17497   "[multipath] [count <n>]")                                            \
17498 _(mpls_route_add_del,                                                   \
17499   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17500   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17501   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17502   "[multipath] [count <n>]")                                            \
17503 _(mpls_ip_bind_unbind,                                                  \
17504   "<label> <addr/len>")                                                 \
17505 _(mpls_tunnel_add_del,                                                  \
17506   " via <addr> [table-id <n>]\n"                                        \
17507   "sw_if_index <id>] [l2]  [del]")                                      \
17508 _(proxy_arp_add_del,                                                    \
17509   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17510 _(proxy_arp_intfc_enable_disable,                                       \
17511   "<intfc> | sw_if_index <id> enable | disable")                        \
17512 _(sw_interface_set_unnumbered,                                          \
17513   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17514 _(ip_neighbor_add_del,                                                  \
17515   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17516   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17517 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17518 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17519 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17520   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17521   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17522   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17523 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17524 _(reset_fib, "vrf <n> [ipv6]")                                          \
17525 _(dhcp_proxy_config,                                                    \
17526   "svr <v46-address> src <v46-address>\n"                               \
17527    "insert-cid <n> [del]")                                              \
17528 _(dhcp_proxy_config_2,                                                  \
17529   "svr <v46-address> src <v46-address>\n"                               \
17530    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
17531 _(dhcp_proxy_set_vss,                                                   \
17532   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17533 _(dhcp_client_config,                                                   \
17534   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17535 _(set_ip_flow_hash,                                                     \
17536   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17537 _(sw_interface_ip6_enable_disable,                                      \
17538   "<intfc> | sw_if_index <id> enable | disable")                        \
17539 _(sw_interface_ip6_set_link_local_address,                              \
17540   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17541 _(sw_interface_ip6nd_ra_prefix,                                         \
17542   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17543   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17544   "[nolink] [isno]")                                                    \
17545 _(sw_interface_ip6nd_ra_config,                                         \
17546   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17547   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17548   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17549 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17550 _(l2_patch_add_del,                                                     \
17551   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17552   "enable | disable")                                                   \
17553 _(sr_tunnel_add_del,                                                    \
17554   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
17555   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
17556   "[policy <policy_name>]")                                             \
17557 _(sr_policy_add_del,                                                    \
17558   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
17559 _(sr_multicast_map_add_del,                                             \
17560   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
17561 _(classify_add_del_table,                                               \
17562   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17563   " [del] [del-chain] mask <mask-value>\n"                              \
17564   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17565   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17566 _(classify_add_del_session,                                             \
17567   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17568   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17569   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17570   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17571 _(classify_set_interface_ip_table,                                      \
17572   "<intfc> | sw_if_index <nn> table <nn>")                              \
17573 _(classify_set_interface_l2_tables,                                     \
17574   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17575   "  [other-table <nn>]")                                               \
17576 _(get_node_index, "node <node-name")                                    \
17577 _(add_node_next, "node <node-name> next <next-node-name>")              \
17578 _(l2tpv3_create_tunnel,                                                 \
17579   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17580   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
17581   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17582 _(l2tpv3_set_tunnel_cookies,                                            \
17583   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17584   "[new_remote_cookie <nn>]\n")                                         \
17585 _(l2tpv3_interface_enable_disable,                                      \
17586   "<intfc> | sw_if_index <nn> enable | disable")                        \
17587 _(l2tpv3_set_lookup_key,                                                \
17588   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17589 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17590 _(vxlan_add_del_tunnel,                                                 \
17591   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17592   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17593   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17594 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17595 _(gre_add_del_tunnel,                                                   \
17596   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
17597 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
17598 _(l2_fib_clear_table, "")                                               \
17599 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
17600 _(l2_interface_vlan_tag_rewrite,                                        \
17601   "<intfc> | sw_if_index <nn> \n"                                       \
17602   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
17603   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
17604 _(create_vhost_user_if,                                                 \
17605         "socket <filename> [server] [renumber <dev_instance>] "         \
17606         "[mac <mac_address>]")                                          \
17607 _(modify_vhost_user_if,                                                 \
17608         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
17609         "[server] [renumber <dev_instance>]")                           \
17610 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
17611 _(sw_interface_vhost_user_dump, "")                                     \
17612 _(show_version, "")                                                     \
17613 _(vxlan_gpe_add_del_tunnel,                                             \
17614   "local <addr> remote <addr> vni <nn>\n"                               \
17615     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
17616   "[next-ethernet] [next-nsh]\n")                                       \
17617 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
17618 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
17619 _(interface_name_renumber,                                              \
17620   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
17621 _(input_acl_set_interface,                                              \
17622   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17623   "  [l2-table <nn>] [del]")                                            \
17624 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
17625 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
17626 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
17627 _(ip_dump, "ipv4 | ipv6")                                               \
17628 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
17629 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
17630   "  spid_id <n> ")                                                     \
17631 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
17632   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
17633   "  integ_alg <alg> integ_key <hex>")                                  \
17634 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
17635   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
17636   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17637   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
17638 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
17639 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
17640 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
17641   "(auth_data 0x<data> | auth_data <data>)")                            \
17642 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
17643   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
17644 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
17645   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17646   "(local|remote)")                                                     \
17647 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
17648 _(delete_loopback,"sw_if_index <nn>")                                   \
17649 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17650 _(map_add_domain,                                                       \
17651   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
17652   "ip6-src <ip6addr> "                                                  \
17653   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
17654 _(map_del_domain, "index <n>")                                          \
17655 _(map_add_del_rule,                                                     \
17656   "index <n> psid <n> dst <ip6addr> [del]")                             \
17657 _(map_domain_dump, "")                                                  \
17658 _(map_rule_dump, "index <map-domain>")                                  \
17659 _(want_interface_events,  "enable|disable")                             \
17660 _(want_stats,"enable|disable")                                          \
17661 _(get_first_msg_id, "client <name>")                                    \
17662 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17663 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
17664   "fib-id <nn> [ip4][ip6][default]")                                    \
17665 _(get_node_graph, " ")                                                  \
17666 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
17667 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
17668 _(ioam_disable, "")                                                     \
17669 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
17670                             " sw_if_index <sw_if_index> p <priority> "  \
17671                             "w <weight>] [del]")                        \
17672 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
17673                         "iface <intf> | sw_if_index <sw_if_index> "     \
17674                         "p <priority> w <weight> [del]")                \
17675 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
17676                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
17677                          "locator-set <locator_name> [del]"             \
17678                          "[key-id sha1|sha256 secret-key <secret-key>]") \
17679 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
17680   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
17681 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
17682 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
17683 _(lisp_gpe_enable_disable, "enable|disable")                            \
17684 _(lisp_enable_disable, "enable|disable")                                \
17685 _(lisp_map_register_enable_disable, "enable|disable")                   \
17686 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
17687 _(lisp_gpe_add_del_iface, "up|down")                                    \
17688 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17689                                "[seid <seid>] "                         \
17690                                "rloc <locator> p <prio> "               \
17691                                "w <weight> [rloc <loc> ... ] "          \
17692                                "action <action> [del-all]")             \
17693 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17694                           "<local-eid>")                                \
17695 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
17696 _(lisp_map_request_mode, "src-dst|dst-only")                            \
17697 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
17698 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
17699 _(lisp_locator_set_dump, "[local | remote]")                            \
17700 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
17701 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
17702                        "[local] | [remote]")                            \
17703 _(lisp_eid_table_vni_dump, "")                                          \
17704 _(lisp_eid_table_map_dump, "l2|l3")                                     \
17705 _(lisp_gpe_tunnel_dump, "")                                             \
17706 _(lisp_map_resolver_dump, "")                                           \
17707 _(lisp_map_server_dump, "")                                             \
17708 _(lisp_adjacencies_get, "vni <vni>")                                    \
17709 _(show_lisp_rloc_probe_state, "")                                       \
17710 _(show_lisp_map_register_state, "")                                     \
17711 _(show_lisp_status, "")                                                 \
17712 _(lisp_get_map_request_itr_rlocs, "")                                   \
17713 _(show_lisp_pitr, "")                                                   \
17714 _(show_lisp_map_request_mode, "")                                       \
17715 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
17716 _(af_packet_delete, "name <host interface name>")                       \
17717 _(policer_add_del, "name <policer name> <params> [del]")                \
17718 _(policer_dump, "[name <policer name>]")                                \
17719 _(policer_classify_set_interface,                                       \
17720   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17721   "  [l2-table <nn>] [del]")                                            \
17722 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
17723 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
17724     "[master|slave]")                                                   \
17725 _(netmap_delete, "name <interface name>")                               \
17726 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
17727 _(mpls_fib_dump, "")                                                    \
17728 _(classify_table_ids, "")                                               \
17729 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
17730 _(classify_table_info, "table_id <nn>")                                 \
17731 _(classify_session_dump, "table_id <nn>")                               \
17732 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
17733     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
17734     "[template_interval <nn>] [udp_checksum]")                          \
17735 _(ipfix_exporter_dump, "")                                              \
17736 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17737 _(ipfix_classify_stream_dump, "")                                       \
17738 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
17739 _(ipfix_classify_table_dump, "")                                        \
17740 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
17741 _(sw_interface_span_dump, "")                                           \
17742 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17743 _(pg_create_interface, "if_id <nn>")                                    \
17744 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17745 _(pg_enable_disable, "[stream <id>] disable")                           \
17746 _(ip_source_and_port_range_check_add_del,                               \
17747   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17748 _(ip_source_and_port_range_check_interface_add_del,                     \
17749   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17750   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17751 _(ipsec_gre_add_del_tunnel,                                             \
17752   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17753 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17754 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17755 _(l2_interface_pbb_tag_rewrite,                                         \
17756   "<intfc> | sw_if_index <nn> \n"                                       \
17757   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17758   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17759 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17760 _(flow_classify_set_interface,                                          \
17761   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17762 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17763 _(ip_fib_dump, "")                                                      \
17764 _(ip6_fib_dump, "")                                                     \
17765 _(feature_enable_disable, "arc_name <arc_name> "                        \
17766   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
17767 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
17768 "[disable]")                                                            \
17769 _(l2_xconnect_dump, "")                                                 \
17770 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
17771 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
17772 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
17773
17774 #if DPDK > 0
17775 #define foreach_vpe_dpdk_api_msg                                        \
17776 _(sw_interface_set_dpdk_hqos_pipe,                                      \
17777   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
17778   "profile <profile-id>\n")                                             \
17779 _(sw_interface_set_dpdk_hqos_subport,                                   \
17780   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
17781   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
17782 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
17783   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
17784 #endif
17785
17786 /* List of command functions, CLI names map directly to functions */
17787 #define foreach_cli_function                                    \
17788 _(comment, "usage: comment <ignore-rest-of-line>")              \
17789 _(dump_interface_table, "usage: dump_interface_table")          \
17790 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17791 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17792 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17793 _(dump_stats_table, "usage: dump_stats_table")                  \
17794 _(dump_macro_table, "usage: dump_macro_table ")                 \
17795 _(dump_node_table, "usage: dump_node_table")                    \
17796 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17797 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17798 _(echo, "usage: echo <message>")                                \
17799 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17800 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17801 _(help, "usage: help")                                          \
17802 _(q, "usage: quit")                                             \
17803 _(quit, "usage: quit")                                          \
17804 _(search_node_table, "usage: search_node_table <name>...")      \
17805 _(set, "usage: set <variable-name> <value>")                    \
17806 _(script, "usage: script <file-name>")                          \
17807 _(unset, "usage: unset <variable-name>")
17808
17809 #define _(N,n)                                  \
17810     static void vl_api_##n##_t_handler_uni      \
17811     (vl_api_##n##_t * mp)                       \
17812     {                                           \
17813         vat_main_t * vam = &vat_main;           \
17814         if (vam->json_output) {                 \
17815             vl_api_##n##_t_handler_json(mp);    \
17816         } else {                                \
17817             vl_api_##n##_t_handler(mp);         \
17818         }                                       \
17819     }
17820 foreach_vpe_api_reply_msg;
17821 #undef _
17822
17823 #if DPDK > 0
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_dpdk_api_reply_msg;
17836 #undef _
17837 #endif
17838
17839 void
17840 vat_api_hookup (vat_main_t * vam)
17841 {
17842 #define _(N,n)                                                  \
17843     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17844                            vl_api_##n##_t_handler_uni,          \
17845                            vl_noop_handler,                     \
17846                            vl_api_##n##_t_endian,               \
17847                            vl_api_##n##_t_print,                \
17848                            sizeof(vl_api_##n##_t), 1);
17849   foreach_vpe_api_reply_msg;
17850 #undef _
17851
17852 #if DPDK > 0
17853 #define _(N,n)                                                  \
17854     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17855                            vl_api_##n##_t_handler_uni,          \
17856                            vl_noop_handler,                     \
17857                            vl_api_##n##_t_endian,               \
17858                            vl_api_##n##_t_print,                \
17859                            sizeof(vl_api_##n##_t), 1);
17860   foreach_vpe_dpdk_api_reply_msg;
17861 #undef _
17862 #endif
17863
17864 #if (VPP_API_TEST_BUILTIN==0)
17865   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17866 #endif
17867
17868   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17869
17870   vam->function_by_name = hash_create_string (0, sizeof (uword));
17871
17872   vam->help_by_name = hash_create_string (0, sizeof (uword));
17873
17874   /* API messages we can send */
17875 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17876   foreach_vpe_api_msg;
17877 #undef _
17878 #if DPDK >0
17879 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17880   foreach_vpe_dpdk_api_msg;
17881 #undef _
17882 #endif
17883
17884   /* Help strings */
17885 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17886   foreach_vpe_api_msg;
17887 #undef _
17888 #if DPDK >0
17889 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17890   foreach_vpe_dpdk_api_msg;
17891 #undef _
17892 #endif
17893
17894   /* CLI functions */
17895 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17896   foreach_cli_function;
17897 #undef _
17898
17899   /* Help strings */
17900 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17901   foreach_cli_function;
17902 #undef _
17903 }
17904
17905 /*
17906  * fd.io coding-style-patch-verification: ON
17907  *
17908  * Local Variables:
17909  * eval: (c-set-style "gnu")
17910  * End:
17911  */