LISP: Fix gpe API
[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 void
2456   vl_api_show_lisp_map_register_state_reply_t_handler
2457   (vl_api_show_lisp_map_register_state_reply_t * mp)
2458 {
2459   vat_main_t *vam = &vat_main;
2460   int retval = clib_net_to_host_u32 (mp->retval);
2461
2462   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2463
2464   vam->retval = retval;
2465   vam->result_ready = 1;
2466 }
2467
2468 static void
2469   vl_api_show_lisp_map_register_state_reply_t_handler_json
2470   (vl_api_show_lisp_map_register_state_reply_t * mp)
2471 {
2472   vat_main_t *vam = &vat_main;
2473   vat_json_node_t _node, *node = &_node;
2474   int retval = clib_net_to_host_u32 (mp->retval);
2475
2476   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2477
2478   vat_json_init_object (node);
2479   vat_json_object_add_string_copy (node, "state", s);
2480
2481   vat_json_print (vam->ofp, node);
2482   vat_json_free (node);
2483
2484   vam->retval = retval;
2485   vam->result_ready = 1;
2486   vec_free (s);
2487 }
2488
2489 static void
2490   vl_api_show_lisp_rloc_probe_state_reply_t_handler
2491   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2492 {
2493   vat_main_t *vam = &vat_main;
2494   int retval = clib_net_to_host_u32 (mp->retval);
2495
2496   if (retval)
2497     goto end;
2498
2499   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
2500 end:
2501   vam->retval = retval;
2502   vam->result_ready = 1;
2503 }
2504
2505 static void
2506   vl_api_show_lisp_rloc_probe_state_reply_t_handler_json
2507   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2508 {
2509   vat_main_t *vam = &vat_main;
2510   vat_json_node_t _node, *node = &_node;
2511   int retval = clib_net_to_host_u32 (mp->retval);
2512
2513   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2514   vat_json_init_object (node);
2515   vat_json_object_add_string_copy (node, "state", s);
2516
2517   vat_json_print (vam->ofp, node);
2518   vat_json_free (node);
2519
2520   vam->retval = retval;
2521   vam->result_ready = 1;
2522   vec_free (s);
2523 }
2524
2525 static void
2526   vl_api_lisp_adjacencies_get_reply_t_handler
2527   (vl_api_lisp_adjacencies_get_reply_t * mp)
2528 {
2529   vat_main_t *vam = &vat_main;
2530   u32 i, n;
2531   int retval = clib_net_to_host_u32 (mp->retval);
2532   vl_api_lisp_adjacency_t *a;
2533
2534   if (retval)
2535     goto end;
2536
2537   n = clib_net_to_host_u32 (mp->count);
2538
2539   for (i = 0; i < n; i++)
2540     {
2541       a = &mp->adjacencies[i];
2542       print (vam->ofp, "%U %40U",
2543              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2544              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
2545     }
2546
2547 end:
2548   vam->retval = retval;
2549   vam->result_ready = 1;
2550 }
2551
2552 static void
2553   vl_api_lisp_adjacencies_get_reply_t_handler_json
2554   (vl_api_lisp_adjacencies_get_reply_t * mp)
2555 {
2556   u8 *s = 0;
2557   vat_main_t *vam = &vat_main;
2558   vat_json_node_t *e = 0, root;
2559   u32 i, n;
2560   int retval = clib_net_to_host_u32 (mp->retval);
2561   vl_api_lisp_adjacency_t *a;
2562
2563   if (retval)
2564     goto end;
2565
2566   n = clib_net_to_host_u32 (mp->count);
2567   vat_json_init_array (&root);
2568
2569   for (i = 0; i < n; i++)
2570     {
2571       e = vat_json_array_add (&root);
2572       a = &mp->adjacencies[i];
2573
2574       vat_json_init_object (e);
2575       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2576                   a->leid_prefix_len);
2577       vec_add1 (s, 0);
2578       vat_json_object_add_string_copy (e, "leid", s);
2579       vec_free (s);
2580
2581       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2582                   a->reid_prefix_len);
2583       vec_add1 (s, 0);
2584       vat_json_object_add_string_copy (e, "reid", s);
2585       vec_free (s);
2586     }
2587
2588   vat_json_print (vam->ofp, &root);
2589   vat_json_free (&root);
2590
2591 end:
2592   vam->retval = retval;
2593   vam->result_ready = 1;
2594 }
2595
2596 static void
2597 vl_api_lisp_map_server_details_t_handler (vl_api_lisp_map_server_details_t
2598                                           * mp)
2599 {
2600   vat_main_t *vam = &vat_main;
2601
2602   print (vam->ofp, "%=20U",
2603          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2604          mp->ip_address);
2605 }
2606
2607 static void
2608   vl_api_lisp_map_server_details_t_handler_json
2609   (vl_api_lisp_map_server_details_t * mp)
2610 {
2611   vat_main_t *vam = &vat_main;
2612   vat_json_node_t *node = NULL;
2613   struct in6_addr ip6;
2614   struct in_addr ip4;
2615
2616   if (VAT_JSON_ARRAY != vam->json_tree.type)
2617     {
2618       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2619       vat_json_init_array (&vam->json_tree);
2620     }
2621   node = vat_json_array_add (&vam->json_tree);
2622
2623   vat_json_init_object (node);
2624   if (mp->is_ipv6)
2625     {
2626       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2627       vat_json_object_add_ip6 (node, "map-server", ip6);
2628     }
2629   else
2630     {
2631       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2632       vat_json_object_add_ip4 (node, "map-server", ip4);
2633     }
2634 }
2635
2636 static void
2637 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2638                                             * mp)
2639 {
2640   vat_main_t *vam = &vat_main;
2641
2642   print (vam->ofp, "%=20U",
2643          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2644          mp->ip_address);
2645 }
2646
2647 static void
2648   vl_api_lisp_map_resolver_details_t_handler_json
2649   (vl_api_lisp_map_resolver_details_t * mp)
2650 {
2651   vat_main_t *vam = &vat_main;
2652   vat_json_node_t *node = NULL;
2653   struct in6_addr ip6;
2654   struct in_addr ip4;
2655
2656   if (VAT_JSON_ARRAY != vam->json_tree.type)
2657     {
2658       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2659       vat_json_init_array (&vam->json_tree);
2660     }
2661   node = vat_json_array_add (&vam->json_tree);
2662
2663   vat_json_init_object (node);
2664   if (mp->is_ipv6)
2665     {
2666       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2667       vat_json_object_add_ip6 (node, "map resolver", ip6);
2668     }
2669   else
2670     {
2671       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2672       vat_json_object_add_ip4 (node, "map resolver", ip4);
2673     }
2674 }
2675
2676 static void
2677   vl_api_show_lisp_status_reply_t_handler
2678   (vl_api_show_lisp_status_reply_t * mp)
2679 {
2680   vat_main_t *vam = &vat_main;
2681   i32 retval = ntohl (mp->retval);
2682
2683   if (0 <= retval)
2684     {
2685       print (vam->ofp, "feature: %s\ngpe: %s",
2686              mp->feature_status ? "enabled" : "disabled",
2687              mp->gpe_status ? "enabled" : "disabled");
2688     }
2689
2690   vam->retval = retval;
2691   vam->result_ready = 1;
2692 }
2693
2694 static void
2695   vl_api_show_lisp_status_reply_t_handler_json
2696   (vl_api_show_lisp_status_reply_t * mp)
2697 {
2698   vat_main_t *vam = &vat_main;
2699   vat_json_node_t node;
2700   u8 *gpe_status = NULL;
2701   u8 *feature_status = NULL;
2702
2703   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2704   feature_status = format (0, "%s",
2705                            mp->feature_status ? "enabled" : "disabled");
2706   vec_add1 (gpe_status, 0);
2707   vec_add1 (feature_status, 0);
2708
2709   vat_json_init_object (&node);
2710   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2711   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2712
2713   vec_free (gpe_status);
2714   vec_free (feature_status);
2715
2716   vat_json_print (vam->ofp, &node);
2717   vat_json_free (&node);
2718
2719   vam->retval = ntohl (mp->retval);
2720   vam->result_ready = 1;
2721 }
2722
2723 static void
2724   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2725   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2726 {
2727   vat_main_t *vam = &vat_main;
2728   i32 retval = ntohl (mp->retval);
2729
2730   if (retval >= 0)
2731     {
2732       print (vam->ofp, "%=20s", mp->locator_set_name);
2733     }
2734
2735   vam->retval = retval;
2736   vam->result_ready = 1;
2737 }
2738
2739 static void
2740   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2741   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2742 {
2743   vat_main_t *vam = &vat_main;
2744   vat_json_node_t *node = NULL;
2745
2746   if (VAT_JSON_ARRAY != vam->json_tree.type)
2747     {
2748       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2749       vat_json_init_array (&vam->json_tree);
2750     }
2751   node = vat_json_array_add (&vam->json_tree);
2752
2753   vat_json_init_object (node);
2754   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2755
2756   vat_json_print (vam->ofp, node);
2757   vat_json_free (node);
2758
2759   vam->retval = ntohl (mp->retval);
2760   vam->result_ready = 1;
2761 }
2762
2763 static u8 *
2764 format_lisp_map_request_mode (u8 * s, va_list * args)
2765 {
2766   u32 mode = va_arg (*args, u32);
2767
2768   switch (mode)
2769     {
2770     case 0:
2771       return format (0, "dst-only");
2772     case 1:
2773       return format (0, "src-dst");
2774     }
2775   return 0;
2776 }
2777
2778 static void
2779   vl_api_show_lisp_map_request_mode_reply_t_handler
2780   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2781 {
2782   vat_main_t *vam = &vat_main;
2783   i32 retval = ntohl (mp->retval);
2784
2785   if (0 <= retval)
2786     {
2787       u32 mode = mp->mode;
2788       print (vam->ofp, "map_request_mode: %U",
2789              format_lisp_map_request_mode, mode);
2790     }
2791
2792   vam->retval = retval;
2793   vam->result_ready = 1;
2794 }
2795
2796 static void
2797   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2798   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2799 {
2800   vat_main_t *vam = &vat_main;
2801   vat_json_node_t node;
2802   u8 *s = 0;
2803   u32 mode;
2804
2805   mode = mp->mode;
2806   s = format (0, "%U", format_lisp_map_request_mode, mode);
2807   vec_add1 (s, 0);
2808
2809   vat_json_init_object (&node);
2810   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2811   vat_json_print (vam->ofp, &node);
2812   vat_json_free (&node);
2813
2814   vec_free (s);
2815   vam->retval = ntohl (mp->retval);
2816   vam->result_ready = 1;
2817 }
2818
2819 static void
2820 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2821 {
2822   vat_main_t *vam = &vat_main;
2823   i32 retval = ntohl (mp->retval);
2824
2825   if (0 <= retval)
2826     {
2827       print (vam->ofp, "%-20s%-16s",
2828              mp->status ? "enabled" : "disabled",
2829              mp->status ? (char *) mp->locator_set_name : "");
2830     }
2831
2832   vam->retval = retval;
2833   vam->result_ready = 1;
2834 }
2835
2836 static void
2837 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2838                                             mp)
2839 {
2840   vat_main_t *vam = &vat_main;
2841   vat_json_node_t node;
2842   u8 *status = 0;
2843
2844   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2845   vec_add1 (status, 0);
2846
2847   vat_json_init_object (&node);
2848   vat_json_object_add_string_copy (&node, "status", status);
2849   if (mp->status)
2850     {
2851       vat_json_object_add_string_copy (&node, "locator_set",
2852                                        mp->locator_set_name);
2853     }
2854
2855   vec_free (status);
2856
2857   vat_json_print (vam->ofp, &node);
2858   vat_json_free (&node);
2859
2860   vam->retval = ntohl (mp->retval);
2861   vam->result_ready = 1;
2862 }
2863
2864 static u8 *
2865 format_policer_type (u8 * s, va_list * va)
2866 {
2867   u32 i = va_arg (*va, u32);
2868
2869   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2870     s = format (s, "1r2c");
2871   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2872     s = format (s, "1r3c");
2873   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2874     s = format (s, "2r3c-2698");
2875   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2876     s = format (s, "2r3c-4115");
2877   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2878     s = format (s, "2r3c-mef5cf1");
2879   else
2880     s = format (s, "ILLEGAL");
2881   return s;
2882 }
2883
2884 static u8 *
2885 format_policer_rate_type (u8 * s, va_list * va)
2886 {
2887   u32 i = va_arg (*va, u32);
2888
2889   if (i == SSE2_QOS_RATE_KBPS)
2890     s = format (s, "kbps");
2891   else if (i == SSE2_QOS_RATE_PPS)
2892     s = format (s, "pps");
2893   else
2894     s = format (s, "ILLEGAL");
2895   return s;
2896 }
2897
2898 static u8 *
2899 format_policer_round_type (u8 * s, va_list * va)
2900 {
2901   u32 i = va_arg (*va, u32);
2902
2903   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2904     s = format (s, "closest");
2905   else if (i == SSE2_QOS_ROUND_TO_UP)
2906     s = format (s, "up");
2907   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2908     s = format (s, "down");
2909   else
2910     s = format (s, "ILLEGAL");
2911   return s;
2912 }
2913
2914 static u8 *
2915 format_policer_action_type (u8 * s, va_list * va)
2916 {
2917   u32 i = va_arg (*va, u32);
2918
2919   if (i == SSE2_QOS_ACTION_DROP)
2920     s = format (s, "drop");
2921   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2922     s = format (s, "transmit");
2923   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2924     s = format (s, "mark-and-transmit");
2925   else
2926     s = format (s, "ILLEGAL");
2927   return s;
2928 }
2929
2930 static u8 *
2931 format_dscp (u8 * s, va_list * va)
2932 {
2933   u32 i = va_arg (*va, u32);
2934   char *t = 0;
2935
2936   switch (i)
2937     {
2938 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2939       foreach_vnet_dscp
2940 #undef _
2941     default:
2942       return format (s, "ILLEGAL");
2943     }
2944   s = format (s, "%s", t);
2945   return s;
2946 }
2947
2948 static void
2949 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2950 {
2951   vat_main_t *vam = &vat_main;
2952   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2953
2954   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2955     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2956   else
2957     conform_dscp_str = format (0, "");
2958
2959   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2960     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2961   else
2962     exceed_dscp_str = format (0, "");
2963
2964   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2965     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2966   else
2967     violate_dscp_str = format (0, "");
2968
2969   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2970          "rate type %U, round type %U, %s rate, %s color-aware, "
2971          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2972          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2973          "conform action %U%s, exceed action %U%s, violate action %U%s",
2974          mp->name,
2975          format_policer_type, mp->type,
2976          ntohl (mp->cir),
2977          ntohl (mp->eir),
2978          clib_net_to_host_u64 (mp->cb),
2979          clib_net_to_host_u64 (mp->eb),
2980          format_policer_rate_type, mp->rate_type,
2981          format_policer_round_type, mp->round_type,
2982          mp->single_rate ? "single" : "dual",
2983          mp->color_aware ? "is" : "not",
2984          ntohl (mp->cir_tokens_per_period),
2985          ntohl (mp->pir_tokens_per_period),
2986          ntohl (mp->scale),
2987          ntohl (mp->current_limit),
2988          ntohl (mp->current_bucket),
2989          ntohl (mp->extended_limit),
2990          ntohl (mp->extended_bucket),
2991          clib_net_to_host_u64 (mp->last_update_time),
2992          format_policer_action_type, mp->conform_action_type,
2993          conform_dscp_str,
2994          format_policer_action_type, mp->exceed_action_type,
2995          exceed_dscp_str,
2996          format_policer_action_type, mp->violate_action_type,
2997          violate_dscp_str);
2998
2999   vec_free (conform_dscp_str);
3000   vec_free (exceed_dscp_str);
3001   vec_free (violate_dscp_str);
3002 }
3003
3004 static void vl_api_policer_details_t_handler_json
3005   (vl_api_policer_details_t * mp)
3006 {
3007   vat_main_t *vam = &vat_main;
3008   vat_json_node_t *node;
3009   u8 *rate_type_str, *round_type_str, *type_str;
3010   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3011
3012   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3013   round_type_str =
3014     format (0, "%U", format_policer_round_type, mp->round_type);
3015   type_str = format (0, "%U", format_policer_type, mp->type);
3016   conform_action_str = format (0, "%U", format_policer_action_type,
3017                                mp->conform_action_type);
3018   exceed_action_str = format (0, "%U", format_policer_action_type,
3019                               mp->exceed_action_type);
3020   violate_action_str = format (0, "%U", format_policer_action_type,
3021                                mp->violate_action_type);
3022
3023   if (VAT_JSON_ARRAY != vam->json_tree.type)
3024     {
3025       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3026       vat_json_init_array (&vam->json_tree);
3027     }
3028   node = vat_json_array_add (&vam->json_tree);
3029
3030   vat_json_init_object (node);
3031   vat_json_object_add_string_copy (node, "name", mp->name);
3032   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3033   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3034   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3035   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3036   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3037   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3038   vat_json_object_add_string_copy (node, "type", type_str);
3039   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3040   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3041   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3042   vat_json_object_add_uint (node, "cir_tokens_per_period",
3043                             ntohl (mp->cir_tokens_per_period));
3044   vat_json_object_add_uint (node, "eir_tokens_per_period",
3045                             ntohl (mp->pir_tokens_per_period));
3046   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3047   vat_json_object_add_uint (node, "current_bucket",
3048                             ntohl (mp->current_bucket));
3049   vat_json_object_add_uint (node, "extended_limit",
3050                             ntohl (mp->extended_limit));
3051   vat_json_object_add_uint (node, "extended_bucket",
3052                             ntohl (mp->extended_bucket));
3053   vat_json_object_add_uint (node, "last_update_time",
3054                             ntohl (mp->last_update_time));
3055   vat_json_object_add_string_copy (node, "conform_action",
3056                                    conform_action_str);
3057   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3058     {
3059       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3060       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3061       vec_free (dscp_str);
3062     }
3063   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3064   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3065     {
3066       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3067       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3068       vec_free (dscp_str);
3069     }
3070   vat_json_object_add_string_copy (node, "violate_action",
3071                                    violate_action_str);
3072   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3073     {
3074       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3075       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3076       vec_free (dscp_str);
3077     }
3078
3079   vec_free (rate_type_str);
3080   vec_free (round_type_str);
3081   vec_free (type_str);
3082   vec_free (conform_action_str);
3083   vec_free (exceed_action_str);
3084   vec_free (violate_action_str);
3085 }
3086
3087 static void
3088 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3089                                            mp)
3090 {
3091   vat_main_t *vam = &vat_main;
3092   int i, count = ntohl (mp->count);
3093
3094   if (count > 0)
3095     print (vam->ofp, "classify table ids (%d) : ", count);
3096   for (i = 0; i < count; i++)
3097     {
3098       print (vam->ofp, "%d", ntohl (mp->ids[i]));
3099       print (vam->ofp, (i < count - 1) ? "," : "");
3100     }
3101   vam->retval = ntohl (mp->retval);
3102   vam->result_ready = 1;
3103 }
3104
3105 static void
3106   vl_api_classify_table_ids_reply_t_handler_json
3107   (vl_api_classify_table_ids_reply_t * mp)
3108 {
3109   vat_main_t *vam = &vat_main;
3110   int i, count = ntohl (mp->count);
3111
3112   if (count > 0)
3113     {
3114       vat_json_node_t node;
3115
3116       vat_json_init_object (&node);
3117       for (i = 0; i < count; i++)
3118         {
3119           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3120         }
3121       vat_json_print (vam->ofp, &node);
3122       vat_json_free (&node);
3123     }
3124   vam->retval = ntohl (mp->retval);
3125   vam->result_ready = 1;
3126 }
3127
3128 static void
3129   vl_api_classify_table_by_interface_reply_t_handler
3130   (vl_api_classify_table_by_interface_reply_t * mp)
3131 {
3132   vat_main_t *vam = &vat_main;
3133   u32 table_id;
3134
3135   table_id = ntohl (mp->l2_table_id);
3136   if (table_id != ~0)
3137     print (vam->ofp, "l2 table id : %d", table_id);
3138   else
3139     print (vam->ofp, "l2 table id : No input ACL tables configured");
3140   table_id = ntohl (mp->ip4_table_id);
3141   if (table_id != ~0)
3142     print (vam->ofp, "ip4 table id : %d", table_id);
3143   else
3144     print (vam->ofp, "ip4 table id : No input ACL tables configured");
3145   table_id = ntohl (mp->ip6_table_id);
3146   if (table_id != ~0)
3147     print (vam->ofp, "ip6 table id : %d", table_id);
3148   else
3149     print (vam->ofp, "ip6 table id : No input ACL tables configured");
3150   vam->retval = ntohl (mp->retval);
3151   vam->result_ready = 1;
3152 }
3153
3154 static void
3155   vl_api_classify_table_by_interface_reply_t_handler_json
3156   (vl_api_classify_table_by_interface_reply_t * mp)
3157 {
3158   vat_main_t *vam = &vat_main;
3159   vat_json_node_t node;
3160
3161   vat_json_init_object (&node);
3162
3163   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3164   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3165   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3166
3167   vat_json_print (vam->ofp, &node);
3168   vat_json_free (&node);
3169
3170   vam->retval = ntohl (mp->retval);
3171   vam->result_ready = 1;
3172 }
3173
3174 static void vl_api_policer_add_del_reply_t_handler
3175   (vl_api_policer_add_del_reply_t * mp)
3176 {
3177   vat_main_t *vam = &vat_main;
3178   i32 retval = ntohl (mp->retval);
3179   if (vam->async_mode)
3180     {
3181       vam->async_errors += (retval < 0);
3182     }
3183   else
3184     {
3185       vam->retval = retval;
3186       vam->result_ready = 1;
3187       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3188         /*
3189          * Note: this is just barely thread-safe, depends on
3190          * the main thread spinning waiting for an answer...
3191          */
3192         errmsg ("policer index %d", ntohl (mp->policer_index));
3193     }
3194 }
3195
3196 static void vl_api_policer_add_del_reply_t_handler_json
3197   (vl_api_policer_add_del_reply_t * mp)
3198 {
3199   vat_main_t *vam = &vat_main;
3200   vat_json_node_t node;
3201
3202   vat_json_init_object (&node);
3203   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3204   vat_json_object_add_uint (&node, "policer_index",
3205                             ntohl (mp->policer_index));
3206
3207   vat_json_print (vam->ofp, &node);
3208   vat_json_free (&node);
3209
3210   vam->retval = ntohl (mp->retval);
3211   vam->result_ready = 1;
3212 }
3213
3214 /* Format hex dump. */
3215 u8 *
3216 format_hex_bytes (u8 * s, va_list * va)
3217 {
3218   u8 *bytes = va_arg (*va, u8 *);
3219   int n_bytes = va_arg (*va, int);
3220   uword i;
3221
3222   /* Print short or long form depending on byte count. */
3223   uword short_form = n_bytes <= 32;
3224   uword indent = format_get_indent (s);
3225
3226   if (n_bytes == 0)
3227     return s;
3228
3229   for (i = 0; i < n_bytes; i++)
3230     {
3231       if (!short_form && (i % 32) == 0)
3232         s = format (s, "%08x: ", i);
3233       s = format (s, "%02x", bytes[i]);
3234       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3235         s = format (s, "\n%U", format_white_space, indent);
3236     }
3237
3238   return s;
3239 }
3240
3241 static void
3242 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3243                                             * mp)
3244 {
3245   vat_main_t *vam = &vat_main;
3246   i32 retval = ntohl (mp->retval);
3247   if (retval == 0)
3248     {
3249       print (vam->ofp, "classify table info :");
3250       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3251              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3252              ntohl (mp->miss_next_index));
3253       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3254              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3255              ntohl (mp->match_n_vectors));
3256       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3257              ntohl (mp->mask_length));
3258     }
3259   vam->retval = retval;
3260   vam->result_ready = 1;
3261 }
3262
3263 static void
3264   vl_api_classify_table_info_reply_t_handler_json
3265   (vl_api_classify_table_info_reply_t * mp)
3266 {
3267   vat_main_t *vam = &vat_main;
3268   vat_json_node_t node;
3269
3270   i32 retval = ntohl (mp->retval);
3271   if (retval == 0)
3272     {
3273       vat_json_init_object (&node);
3274
3275       vat_json_object_add_int (&node, "sessions",
3276                                ntohl (mp->active_sessions));
3277       vat_json_object_add_int (&node, "nexttbl",
3278                                ntohl (mp->next_table_index));
3279       vat_json_object_add_int (&node, "nextnode",
3280                                ntohl (mp->miss_next_index));
3281       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3282       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3283       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3284       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3285                       ntohl (mp->mask_length), 0);
3286       vat_json_object_add_string_copy (&node, "mask", s);
3287
3288       vat_json_print (vam->ofp, &node);
3289       vat_json_free (&node);
3290     }
3291   vam->retval = ntohl (mp->retval);
3292   vam->result_ready = 1;
3293 }
3294
3295 static void
3296 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3297                                            mp)
3298 {
3299   vat_main_t *vam = &vat_main;
3300
3301   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3302          ntohl (mp->hit_next_index), ntohl (mp->advance),
3303          ntohl (mp->opaque_index));
3304   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3305          ntohl (mp->match_length));
3306 }
3307
3308 static void
3309   vl_api_classify_session_details_t_handler_json
3310   (vl_api_classify_session_details_t * mp)
3311 {
3312   vat_main_t *vam = &vat_main;
3313   vat_json_node_t *node = NULL;
3314
3315   if (VAT_JSON_ARRAY != vam->json_tree.type)
3316     {
3317       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3318       vat_json_init_array (&vam->json_tree);
3319     }
3320   node = vat_json_array_add (&vam->json_tree);
3321
3322   vat_json_init_object (node);
3323   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3324   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3325   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3326   u8 *s =
3327     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3328             0);
3329   vat_json_object_add_string_copy (node, "match", s);
3330 }
3331
3332 static void vl_api_pg_create_interface_reply_t_handler
3333   (vl_api_pg_create_interface_reply_t * mp)
3334 {
3335   vat_main_t *vam = &vat_main;
3336
3337   vam->retval = ntohl (mp->retval);
3338   vam->result_ready = 1;
3339 }
3340
3341 static void vl_api_pg_create_interface_reply_t_handler_json
3342   (vl_api_pg_create_interface_reply_t * mp)
3343 {
3344   vat_main_t *vam = &vat_main;
3345   vat_json_node_t node;
3346
3347   i32 retval = ntohl (mp->retval);
3348   if (retval == 0)
3349     {
3350       vat_json_init_object (&node);
3351
3352       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3353
3354       vat_json_print (vam->ofp, &node);
3355       vat_json_free (&node);
3356     }
3357   vam->retval = ntohl (mp->retval);
3358   vam->result_ready = 1;
3359 }
3360
3361 static void vl_api_policer_classify_details_t_handler
3362   (vl_api_policer_classify_details_t * mp)
3363 {
3364   vat_main_t *vam = &vat_main;
3365
3366   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3367          ntohl (mp->table_index));
3368 }
3369
3370 static void vl_api_policer_classify_details_t_handler_json
3371   (vl_api_policer_classify_details_t * mp)
3372 {
3373   vat_main_t *vam = &vat_main;
3374   vat_json_node_t *node;
3375
3376   if (VAT_JSON_ARRAY != vam->json_tree.type)
3377     {
3378       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3379       vat_json_init_array (&vam->json_tree);
3380     }
3381   node = vat_json_array_add (&vam->json_tree);
3382
3383   vat_json_init_object (node);
3384   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3385   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3386 }
3387
3388 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3389   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3390 {
3391   vat_main_t *vam = &vat_main;
3392   i32 retval = ntohl (mp->retval);
3393   if (vam->async_mode)
3394     {
3395       vam->async_errors += (retval < 0);
3396     }
3397   else
3398     {
3399       vam->retval = retval;
3400       vam->sw_if_index = ntohl (mp->sw_if_index);
3401       vam->result_ready = 1;
3402     }
3403 }
3404
3405 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3406   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3407 {
3408   vat_main_t *vam = &vat_main;
3409   vat_json_node_t node;
3410
3411   vat_json_init_object (&node);
3412   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3413   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3414
3415   vat_json_print (vam->ofp, &node);
3416   vat_json_free (&node);
3417
3418   vam->retval = ntohl (mp->retval);
3419   vam->result_ready = 1;
3420 }
3421
3422 static void vl_api_flow_classify_details_t_handler
3423   (vl_api_flow_classify_details_t * mp)
3424 {
3425   vat_main_t *vam = &vat_main;
3426
3427   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3428          ntohl (mp->table_index));
3429 }
3430
3431 static void vl_api_flow_classify_details_t_handler_json
3432   (vl_api_flow_classify_details_t * mp)
3433 {
3434   vat_main_t *vam = &vat_main;
3435   vat_json_node_t *node;
3436
3437   if (VAT_JSON_ARRAY != vam->json_tree.type)
3438     {
3439       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3440       vat_json_init_array (&vam->json_tree);
3441     }
3442   node = vat_json_array_add (&vam->json_tree);
3443
3444   vat_json_init_object (node);
3445   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3446   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3447 }
3448
3449
3450
3451 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3452 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3453 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3454 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3455 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3456 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3457
3458 /*
3459  * Generate boilerplate reply handlers, which
3460  * dig the return value out of the xxx_reply_t API message,
3461  * stick it into vam->retval, and set vam->result_ready
3462  *
3463  * Could also do this by pointing N message decode slots at
3464  * a single function, but that could break in subtle ways.
3465  */
3466
3467 #define foreach_standard_reply_retval_handler           \
3468 _(sw_interface_set_flags_reply)                         \
3469 _(sw_interface_add_del_address_reply)                   \
3470 _(sw_interface_set_table_reply)                         \
3471 _(sw_interface_set_mpls_enable_reply)                   \
3472 _(sw_interface_set_vpath_reply)                         \
3473 _(sw_interface_set_vxlan_bypass_reply)                  \
3474 _(sw_interface_set_l2_bridge_reply)                     \
3475 _(bridge_domain_add_del_reply)                          \
3476 _(sw_interface_set_l2_xconnect_reply)                   \
3477 _(l2fib_add_del_reply)                                  \
3478 _(ip_add_del_route_reply)                               \
3479 _(mpls_route_add_del_reply)                             \
3480 _(mpls_ip_bind_unbind_reply)                            \
3481 _(proxy_arp_add_del_reply)                              \
3482 _(proxy_arp_intfc_enable_disable_reply)                 \
3483 _(sw_interface_set_unnumbered_reply)                    \
3484 _(ip_neighbor_add_del_reply)                            \
3485 _(reset_vrf_reply)                                      \
3486 _(oam_add_del_reply)                                    \
3487 _(reset_fib_reply)                                      \
3488 _(dhcp_proxy_config_reply)                              \
3489 _(dhcp_proxy_config_2_reply)                            \
3490 _(dhcp_proxy_set_vss_reply)                             \
3491 _(dhcp_client_config_reply)                             \
3492 _(set_ip_flow_hash_reply)                               \
3493 _(sw_interface_ip6_enable_disable_reply)                \
3494 _(sw_interface_ip6_set_link_local_address_reply)        \
3495 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3496 _(sw_interface_ip6nd_ra_config_reply)                   \
3497 _(set_arp_neighbor_limit_reply)                         \
3498 _(l2_patch_add_del_reply)                               \
3499 _(sr_tunnel_add_del_reply)                              \
3500 _(sr_policy_add_del_reply)                              \
3501 _(sr_multicast_map_add_del_reply)                       \
3502 _(classify_add_del_session_reply)                       \
3503 _(classify_set_interface_ip_table_reply)                \
3504 _(classify_set_interface_l2_tables_reply)               \
3505 _(l2tpv3_set_tunnel_cookies_reply)                      \
3506 _(l2tpv3_interface_enable_disable_reply)                \
3507 _(l2tpv3_set_lookup_key_reply)                          \
3508 _(l2_fib_clear_table_reply)                             \
3509 _(l2_interface_efp_filter_reply)                        \
3510 _(l2_interface_vlan_tag_rewrite_reply)                  \
3511 _(modify_vhost_user_if_reply)                           \
3512 _(delete_vhost_user_if_reply)                           \
3513 _(want_ip4_arp_events_reply)                            \
3514 _(want_ip6_nd_events_reply)                             \
3515 _(input_acl_set_interface_reply)                        \
3516 _(ipsec_spd_add_del_reply)                              \
3517 _(ipsec_interface_add_del_spd_reply)                    \
3518 _(ipsec_spd_add_del_entry_reply)                        \
3519 _(ipsec_sad_add_del_entry_reply)                        \
3520 _(ipsec_sa_set_key_reply)                               \
3521 _(ikev2_profile_add_del_reply)                          \
3522 _(ikev2_profile_set_auth_reply)                         \
3523 _(ikev2_profile_set_id_reply)                           \
3524 _(ikev2_profile_set_ts_reply)                           \
3525 _(ikev2_set_local_key_reply)                            \
3526 _(delete_loopback_reply)                                \
3527 _(bd_ip_mac_add_del_reply)                              \
3528 _(map_del_domain_reply)                                 \
3529 _(map_add_del_rule_reply)                               \
3530 _(want_interface_events_reply)                          \
3531 _(want_stats_reply)                                     \
3532 _(cop_interface_enable_disable_reply)                   \
3533 _(cop_whitelist_enable_disable_reply)                   \
3534 _(sw_interface_clear_stats_reply)                       \
3535 _(ioam_enable_reply)                              \
3536 _(ioam_disable_reply)                              \
3537 _(lisp_add_del_locator_reply)                           \
3538 _(lisp_add_del_local_eid_reply)                         \
3539 _(lisp_add_del_remote_mapping_reply)                    \
3540 _(lisp_add_del_adjacency_reply)                         \
3541 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3542 _(lisp_add_del_map_resolver_reply)                      \
3543 _(lisp_add_del_map_server_reply)                        \
3544 _(lisp_gpe_enable_disable_reply)                        \
3545 _(lisp_gpe_add_del_iface_reply)                         \
3546 _(lisp_enable_disable_reply)                            \
3547 _(lisp_rloc_probe_enable_disable_reply)                 \
3548 _(lisp_map_register_enable_disable_reply)               \
3549 _(lisp_pitr_set_locator_set_reply)                      \
3550 _(lisp_map_request_mode_reply)                          \
3551 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3552 _(lisp_eid_table_add_del_map_reply)                     \
3553 _(vxlan_gpe_add_del_tunnel_reply)                       \
3554 _(af_packet_delete_reply)                               \
3555 _(policer_classify_set_interface_reply)                 \
3556 _(netmap_create_reply)                                  \
3557 _(netmap_delete_reply)                                  \
3558 _(set_ipfix_exporter_reply)                             \
3559 _(set_ipfix_classify_stream_reply)                      \
3560 _(ipfix_classify_table_add_del_reply)                   \
3561 _(flow_classify_set_interface_reply)                    \
3562 _(sw_interface_span_enable_disable_reply)               \
3563 _(pg_capture_reply)                                     \
3564 _(pg_enable_disable_reply)                              \
3565 _(ip_source_and_port_range_check_add_del_reply)         \
3566 _(ip_source_and_port_range_check_interface_add_del_reply)\
3567 _(delete_subif_reply)                                   \
3568 _(l2_interface_pbb_tag_rewrite_reply)                   \
3569 _(punt_reply)                                           \
3570 _(feature_enable_disable_reply)                         \
3571 _(sw_interface_tag_add_del_reply)                       \
3572 _(sw_interface_set_mtu_reply)
3573
3574 #if DPDK > 0
3575 #define foreach_standard_dpdk_reply_retval_handler      \
3576 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3577 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3578 _(sw_interface_set_dpdk_hqos_tctbl_reply)
3579 #endif
3580
3581 #define _(n)                                    \
3582     static void vl_api_##n##_t_handler          \
3583     (vl_api_##n##_t * mp)                       \
3584     {                                           \
3585         vat_main_t * vam = &vat_main;           \
3586         i32 retval = ntohl(mp->retval);         \
3587         if (vam->async_mode) {                  \
3588             vam->async_errors += (retval < 0);  \
3589         } else {                                \
3590             vam->retval = retval;               \
3591             vam->result_ready = 1;              \
3592         }                                       \
3593     }
3594 foreach_standard_reply_retval_handler;
3595 #undef _
3596
3597 #define _(n)                                    \
3598     static void vl_api_##n##_t_handler_json     \
3599     (vl_api_##n##_t * mp)                       \
3600     {                                           \
3601         vat_main_t * vam = &vat_main;           \
3602         vat_json_node_t node;                   \
3603         vat_json_init_object(&node);            \
3604         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3605         vat_json_print(vam->ofp, &node);        \
3606         vam->retval = ntohl(mp->retval);        \
3607         vam->result_ready = 1;                  \
3608     }
3609 foreach_standard_reply_retval_handler;
3610 #undef _
3611
3612 #if DPDK > 0
3613 #define _(n)                                    \
3614     static void vl_api_##n##_t_handler          \
3615     (vl_api_##n##_t * mp)                       \
3616     {                                           \
3617         vat_main_t * vam = &vat_main;           \
3618         i32 retval = ntohl(mp->retval);         \
3619         if (vam->async_mode) {                  \
3620             vam->async_errors += (retval < 0);  \
3621         } else {                                \
3622             vam->retval = retval;               \
3623             vam->result_ready = 1;              \
3624         }                                       \
3625     }
3626 foreach_standard_dpdk_reply_retval_handler;
3627 #undef _
3628
3629 #define _(n)                                    \
3630     static void vl_api_##n##_t_handler_json     \
3631     (vl_api_##n##_t * mp)                       \
3632     {                                           \
3633         vat_main_t * vam = &vat_main;           \
3634         vat_json_node_t node;                   \
3635         vat_json_init_object(&node);            \
3636         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3637         vat_json_print(vam->ofp, &node);        \
3638         vam->retval = ntohl(mp->retval);        \
3639         vam->result_ready = 1;                  \
3640     }
3641 foreach_standard_dpdk_reply_retval_handler;
3642 #undef _
3643 #endif
3644
3645 /*
3646  * Table of message reply handlers, must include boilerplate handlers
3647  * we just generated
3648  */
3649
3650 #define foreach_vpe_api_reply_msg                                       \
3651 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3652 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3653 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3654 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3655 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3656 _(CLI_REPLY, cli_reply)                                                 \
3657 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3658 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3659   sw_interface_add_del_address_reply)                                   \
3660 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3661 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3662 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3663 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3664 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3665   sw_interface_set_l2_xconnect_reply)                                   \
3666 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3667   sw_interface_set_l2_bridge_reply)                                     \
3668 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3669 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3670 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3671 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3672 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3673 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3674 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3675 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3676 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3677 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3678 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3679 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3680 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3681 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3682 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3683   proxy_arp_intfc_enable_disable_reply)                                 \
3684 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
3685 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3686   sw_interface_set_unnumbered_reply)                                    \
3687 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3688 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3689 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3690 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3691 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3692 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3693 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3694 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3695 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3696 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3697 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3698 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3699   sw_interface_ip6_enable_disable_reply)                                \
3700 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3701   sw_interface_ip6_set_link_local_address_reply)                        \
3702 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3703   sw_interface_ip6nd_ra_prefix_reply)                                   \
3704 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3705   sw_interface_ip6nd_ra_config_reply)                                   \
3706 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3707 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3708 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3709 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3710 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3711 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3712 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3713 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3714 classify_set_interface_ip_table_reply)                                  \
3715 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3716   classify_set_interface_l2_tables_reply)                               \
3717 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3718 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3719 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3720 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3721 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3722   l2tpv3_interface_enable_disable_reply)                                \
3723 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3724 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3725 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3726 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3727 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3728 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3729 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3730 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3731 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3732 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3733 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3734 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3735 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3736 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3737 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3738 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3739 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3740 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3741 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3742 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3743 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3744 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3745 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3746 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3747 _(IP_DETAILS, ip_details)                                               \
3748 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3749 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3750 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3751 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3752 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3753 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3754 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3755 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3756 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3757 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3758 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3759 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3760 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3761 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3762 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3763 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3764 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3765 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3766 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3767 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3768 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3769 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3770 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3771 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3772 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3773 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3774 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3775 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3776 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3777 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3778 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3779 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3780 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3781 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3782 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3783 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3784 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3785 _(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply)         \
3786 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3787 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3788 _(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY,                               \
3789   lisp_map_register_enable_disable_reply)                               \
3790 _(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                 \
3791   lisp_rloc_probe_enable_disable_reply)                                 \
3792 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3793 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3794 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3795 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3796 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3797 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3798 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3799 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3800 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3801 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3802 _(LISP_MAP_SERVER_DETAILS, lisp_map_server_details)                     \
3803 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3804 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3805 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3806   lisp_add_del_map_request_itr_rlocs_reply)                             \
3807 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3808   lisp_get_map_request_itr_rlocs_reply)                                 \
3809 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3810 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3811 _(SHOW_LISP_RLOC_PROBE_STATE_REPLY, show_lisp_rloc_probe_state_reply)   \
3812 _(SHOW_LISP_MAP_REGISTER_STATE_REPLY,                                   \
3813   show_lisp_map_register_state_reply)                                   \
3814 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3815 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3816 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3817 _(POLICER_DETAILS, policer_details)                                     \
3818 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3819 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3820 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3821 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3822 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
3823 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3824 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3825 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3826 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3827 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3828 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3829 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3830 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3831 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3832 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3833 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3834 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3835 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3836 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3837 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3838 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3839 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3840 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3841 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3842 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3843  ip_source_and_port_range_check_add_del_reply)                          \
3844 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3845  ip_source_and_port_range_check_interface_add_del_reply)                \
3846 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3847 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3848 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3849 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3850 _(PUNT_REPLY, punt_reply)                                               \
3851 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3852 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3853 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
3854 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
3855 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
3856 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
3857 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
3858 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
3859
3860 #if DPDK > 0
3861 #define foreach_vpe_dpdk_api_reply_msg                                  \
3862 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3863   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3864 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3865   sw_interface_set_dpdk_hqos_subport_reply)                             \
3866 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3867   sw_interface_set_dpdk_hqos_tctbl_reply)
3868 #endif
3869
3870 /* M: construct, but don't yet send a message */
3871
3872 #define M(T,t)                                          \
3873 do {                                                    \
3874     vam->result_ready = 0;                              \
3875     mp = vl_msg_api_alloc_as_if_client(sizeof(*mp));    \
3876     memset (mp, 0, sizeof (*mp));                       \
3877     mp->_vl_msg_id = ntohs (VL_API_##T);                \
3878     mp->client_index = vam->my_client_index;            \
3879 } while(0);
3880
3881 #define M2(T,t,n)                                               \
3882 do {                                                            \
3883     vam->result_ready = 0;                                      \
3884     mp = vl_msg_api_alloc_as_if_client(sizeof(*mp)+(n));        \
3885     memset (mp, 0, sizeof (*mp));                               \
3886     mp->_vl_msg_id = ntohs (VL_API_##T);                        \
3887     mp->client_index = vam->my_client_index;                    \
3888 } while(0);
3889
3890
3891 /* S: send a message */
3892 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3893
3894 /* W: wait for results, with timeout */
3895 #define W                                       \
3896 do {                                            \
3897     timeout = vat_time_now (vam) + 1.0;         \
3898                                                 \
3899     while (vat_time_now (vam) < timeout) {      \
3900         if (vam->result_ready == 1) {           \
3901             return (vam->retval);               \
3902         }                                       \
3903         vat_suspend (vam->vlib_main, 1e-3);     \
3904     }                                           \
3905     return -99;                                 \
3906 } while(0);
3907
3908 /* W2: wait for results, with timeout */
3909 #define W2(body)                                \
3910 do {                                            \
3911     timeout = vat_time_now (vam) + 1.0;         \
3912                                                 \
3913     while (vat_time_now (vam) < timeout) {      \
3914         if (vam->result_ready == 1) {           \
3915           (body);                               \
3916           return (vam->retval);                 \
3917         }                                       \
3918         vat_suspend (vam->vlib_main, 1e-3);     \
3919     }                                           \
3920     return -99;                                 \
3921 } while(0);
3922
3923 typedef struct
3924 {
3925   u8 *name;
3926   u32 value;
3927 } name_sort_t;
3928
3929
3930 #define STR_VTR_OP_CASE(op)     \
3931     case L2_VTR_ ## op:         \
3932         return "" # op;
3933
3934 static const char *
3935 str_vtr_op (u32 vtr_op)
3936 {
3937   switch (vtr_op)
3938     {
3939       STR_VTR_OP_CASE (DISABLED);
3940       STR_VTR_OP_CASE (PUSH_1);
3941       STR_VTR_OP_CASE (PUSH_2);
3942       STR_VTR_OP_CASE (POP_1);
3943       STR_VTR_OP_CASE (POP_2);
3944       STR_VTR_OP_CASE (TRANSLATE_1_1);
3945       STR_VTR_OP_CASE (TRANSLATE_1_2);
3946       STR_VTR_OP_CASE (TRANSLATE_2_1);
3947       STR_VTR_OP_CASE (TRANSLATE_2_2);
3948     }
3949
3950   return "UNKNOWN";
3951 }
3952
3953 static int
3954 dump_sub_interface_table (vat_main_t * vam)
3955 {
3956   const sw_interface_subif_t *sub = NULL;
3957
3958   if (vam->json_output)
3959     {
3960       clib_warning
3961         ("JSON output supported only for VPE API calls and dump_stats_table");
3962       return -99;
3963     }
3964
3965   print (vam->ofp,
3966          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
3967          "Interface", "sw_if_index",
3968          "sub id", "dot1ad", "tags", "outer id",
3969          "inner id", "exact", "default", "outer any", "inner any");
3970
3971   vec_foreach (sub, vam->sw_if_subif_table)
3972   {
3973     print (vam->ofp,
3974            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
3975            sub->interface_name,
3976            sub->sw_if_index,
3977            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3978            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3979            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3980            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3981     if (sub->vtr_op != L2_VTR_DISABLED)
3982       {
3983         print (vam->ofp,
3984                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3985                "tag1: %d tag2: %d ]",
3986                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3987                sub->vtr_tag1, sub->vtr_tag2);
3988       }
3989   }
3990
3991   return 0;
3992 }
3993
3994 static int
3995 name_sort_cmp (void *a1, void *a2)
3996 {
3997   name_sort_t *n1 = a1;
3998   name_sort_t *n2 = a2;
3999
4000   return strcmp ((char *) n1->name, (char *) n2->name);
4001 }
4002
4003 static int
4004 dump_interface_table (vat_main_t * vam)
4005 {
4006   hash_pair_t *p;
4007   name_sort_t *nses = 0, *ns;
4008
4009   if (vam->json_output)
4010     {
4011       clib_warning
4012         ("JSON output supported only for VPE API calls and dump_stats_table");
4013       return -99;
4014     }
4015
4016   /* *INDENT-OFF* */
4017   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4018   ({
4019     vec_add2 (nses, ns, 1);
4020     ns->name = (u8 *)(p->key);
4021     ns->value = (u32) p->value[0];
4022   }));
4023   /* *INDENT-ON* */
4024
4025   vec_sort_with_function (nses, name_sort_cmp);
4026
4027   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
4028   vec_foreach (ns, nses)
4029   {
4030     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
4031   }
4032   vec_free (nses);
4033   return 0;
4034 }
4035
4036 static int
4037 dump_ip_table (vat_main_t * vam, int is_ipv6)
4038 {
4039   const ip_details_t *det = NULL;
4040   const ip_address_details_t *address = NULL;
4041   u32 i = ~0;
4042
4043   print (vam->ofp, "%-12s", "sw_if_index");
4044
4045   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4046   {
4047     i++;
4048     if (!det->present)
4049       {
4050         continue;
4051       }
4052     print (vam->ofp, "%-12d", i);
4053     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
4054     if (!det->addr)
4055       {
4056         continue;
4057       }
4058     vec_foreach (address, det->addr)
4059     {
4060       print (vam->ofp,
4061              "            %-30U%-13d",
4062              is_ipv6 ? format_ip6_address : format_ip4_address,
4063              address->ip, address->prefix_length);
4064     }
4065   }
4066
4067   return 0;
4068 }
4069
4070 static int
4071 dump_ipv4_table (vat_main_t * vam)
4072 {
4073   if (vam->json_output)
4074     {
4075       clib_warning
4076         ("JSON output supported only for VPE API calls and dump_stats_table");
4077       return -99;
4078     }
4079
4080   return dump_ip_table (vam, 0);
4081 }
4082
4083 static int
4084 dump_ipv6_table (vat_main_t * vam)
4085 {
4086   if (vam->json_output)
4087     {
4088       clib_warning
4089         ("JSON output supported only for VPE API calls and dump_stats_table");
4090       return -99;
4091     }
4092
4093   return dump_ip_table (vam, 1);
4094 }
4095
4096 static char *
4097 counter_type_to_str (u8 counter_type, u8 is_combined)
4098 {
4099   if (!is_combined)
4100     {
4101       switch (counter_type)
4102         {
4103         case VNET_INTERFACE_COUNTER_DROP:
4104           return "drop";
4105         case VNET_INTERFACE_COUNTER_PUNT:
4106           return "punt";
4107         case VNET_INTERFACE_COUNTER_IP4:
4108           return "ip4";
4109         case VNET_INTERFACE_COUNTER_IP6:
4110           return "ip6";
4111         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4112           return "rx-no-buf";
4113         case VNET_INTERFACE_COUNTER_RX_MISS:
4114           return "rx-miss";
4115         case VNET_INTERFACE_COUNTER_RX_ERROR:
4116           return "rx-error";
4117         case VNET_INTERFACE_COUNTER_TX_ERROR:
4118           return "tx-error";
4119         default:
4120           return "INVALID-COUNTER-TYPE";
4121         }
4122     }
4123   else
4124     {
4125       switch (counter_type)
4126         {
4127         case VNET_INTERFACE_COUNTER_RX:
4128           return "rx";
4129         case VNET_INTERFACE_COUNTER_TX:
4130           return "tx";
4131         default:
4132           return "INVALID-COUNTER-TYPE";
4133         }
4134     }
4135 }
4136
4137 static int
4138 dump_stats_table (vat_main_t * vam)
4139 {
4140   vat_json_node_t node;
4141   vat_json_node_t *msg_array;
4142   vat_json_node_t *msg;
4143   vat_json_node_t *counter_array;
4144   vat_json_node_t *counter;
4145   interface_counter_t c;
4146   u64 packets;
4147   ip4_fib_counter_t *c4;
4148   ip6_fib_counter_t *c6;
4149   int i, j;
4150
4151   if (!vam->json_output)
4152     {
4153       clib_warning ("dump_stats_table supported only in JSON format");
4154       return -99;
4155     }
4156
4157   vat_json_init_object (&node);
4158
4159   /* interface counters */
4160   msg_array = vat_json_object_add (&node, "interface_counters");
4161   vat_json_init_array (msg_array);
4162   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4163     {
4164       msg = vat_json_array_add (msg_array);
4165       vat_json_init_object (msg);
4166       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4167                                        (u8 *) counter_type_to_str (i, 0));
4168       vat_json_object_add_int (msg, "is_combined", 0);
4169       counter_array = vat_json_object_add (msg, "data");
4170       vat_json_init_array (counter_array);
4171       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4172         {
4173           packets = vam->simple_interface_counters[i][j];
4174           vat_json_array_add_uint (counter_array, packets);
4175         }
4176     }
4177   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4178     {
4179       msg = vat_json_array_add (msg_array);
4180       vat_json_init_object (msg);
4181       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4182                                        (u8 *) counter_type_to_str (i, 1));
4183       vat_json_object_add_int (msg, "is_combined", 1);
4184       counter_array = vat_json_object_add (msg, "data");
4185       vat_json_init_array (counter_array);
4186       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4187         {
4188           c = vam->combined_interface_counters[i][j];
4189           counter = vat_json_array_add (counter_array);
4190           vat_json_init_object (counter);
4191           vat_json_object_add_uint (counter, "packets", c.packets);
4192           vat_json_object_add_uint (counter, "bytes", c.bytes);
4193         }
4194     }
4195
4196   /* ip4 fib counters */
4197   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4198   vat_json_init_array (msg_array);
4199   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4200     {
4201       msg = vat_json_array_add (msg_array);
4202       vat_json_init_object (msg);
4203       vat_json_object_add_uint (msg, "vrf_id",
4204                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4205       counter_array = vat_json_object_add (msg, "c");
4206       vat_json_init_array (counter_array);
4207       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4208         {
4209           counter = vat_json_array_add (counter_array);
4210           vat_json_init_object (counter);
4211           c4 = &vam->ip4_fib_counters[i][j];
4212           vat_json_object_add_ip4 (counter, "address", c4->address);
4213           vat_json_object_add_uint (counter, "address_length",
4214                                     c4->address_length);
4215           vat_json_object_add_uint (counter, "packets", c4->packets);
4216           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4217         }
4218     }
4219
4220   /* ip6 fib counters */
4221   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4222   vat_json_init_array (msg_array);
4223   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4224     {
4225       msg = vat_json_array_add (msg_array);
4226       vat_json_init_object (msg);
4227       vat_json_object_add_uint (msg, "vrf_id",
4228                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4229       counter_array = vat_json_object_add (msg, "c");
4230       vat_json_init_array (counter_array);
4231       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4232         {
4233           counter = vat_json_array_add (counter_array);
4234           vat_json_init_object (counter);
4235           c6 = &vam->ip6_fib_counters[i][j];
4236           vat_json_object_add_ip6 (counter, "address", c6->address);
4237           vat_json_object_add_uint (counter, "address_length",
4238                                     c6->address_length);
4239           vat_json_object_add_uint (counter, "packets", c6->packets);
4240           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4241         }
4242     }
4243
4244   vat_json_print (vam->ofp, &node);
4245   vat_json_free (&node);
4246
4247   return 0;
4248 }
4249
4250 int
4251 exec (vat_main_t * vam)
4252 {
4253   api_main_t *am = &api_main;
4254   vl_api_cli_request_t *mp;
4255   f64 timeout;
4256   void *oldheap;
4257   u8 *cmd = 0;
4258   unformat_input_t *i = vam->input;
4259
4260   if (vec_len (i->buffer) == 0)
4261     return -1;
4262
4263   if (vam->exec_mode == 0 && unformat (i, "mode"))
4264     {
4265       vam->exec_mode = 1;
4266       return 0;
4267     }
4268   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4269     {
4270       vam->exec_mode = 0;
4271       return 0;
4272     }
4273
4274
4275   M (CLI_REQUEST, cli_request);
4276
4277   /*
4278    * Copy cmd into shared memory.
4279    * In order for the CLI command to work, it
4280    * must be a vector ending in \n, not a C-string ending
4281    * in \n\0.
4282    */
4283   pthread_mutex_lock (&am->vlib_rp->mutex);
4284   oldheap = svm_push_data_heap (am->vlib_rp);
4285
4286   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4287   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4288
4289   svm_pop_heap (oldheap);
4290   pthread_mutex_unlock (&am->vlib_rp->mutex);
4291
4292   mp->cmd_in_shmem = (u64) cmd;
4293   S;
4294   timeout = vat_time_now (vam) + 10.0;
4295
4296   while (vat_time_now (vam) < timeout)
4297     {
4298       if (vam->result_ready == 1)
4299         {
4300           u8 *free_me;
4301           if (vam->shmem_result != NULL)
4302             print (vam->ofp, "%s", vam->shmem_result);
4303           pthread_mutex_lock (&am->vlib_rp->mutex);
4304           oldheap = svm_push_data_heap (am->vlib_rp);
4305
4306           free_me = (u8 *) vam->shmem_result;
4307           vec_free (free_me);
4308
4309           svm_pop_heap (oldheap);
4310           pthread_mutex_unlock (&am->vlib_rp->mutex);
4311           return 0;
4312         }
4313     }
4314   return -99;
4315 }
4316
4317 /*
4318  * Future replacement of exec() that passes CLI buffers directly in
4319  * the API messages instead of an additional shared memory area.
4320  */
4321 static int
4322 exec_inband (vat_main_t * vam)
4323 {
4324   vl_api_cli_inband_t *mp;
4325   f64 timeout;
4326   unformat_input_t *i = vam->input;
4327
4328   if (vec_len (i->buffer) == 0)
4329     return -1;
4330
4331   if (vam->exec_mode == 0 && unformat (i, "mode"))
4332     {
4333       vam->exec_mode = 1;
4334       return 0;
4335     }
4336   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4337     {
4338       vam->exec_mode = 0;
4339       return 0;
4340     }
4341
4342   /*
4343    * In order for the CLI command to work, it
4344    * must be a vector ending in \n, not a C-string ending
4345    * in \n\0.
4346    */
4347   u32 len = vec_len (vam->input->buffer);
4348   M2 (CLI_INBAND, cli_inband, len);
4349   clib_memcpy (mp->cmd, vam->input->buffer, len);
4350   mp->length = htonl (len);
4351
4352   S;
4353   W2 (print (vam->ofp, "%s", vam->cmd_reply));
4354 }
4355
4356 static int
4357 api_create_loopback (vat_main_t * vam)
4358 {
4359   unformat_input_t *i = vam->input;
4360   vl_api_create_loopback_t *mp;
4361   f64 timeout;
4362   u8 mac_address[6];
4363   u8 mac_set = 0;
4364
4365   memset (mac_address, 0, sizeof (mac_address));
4366
4367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4368     {
4369       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4370         mac_set = 1;
4371       else
4372         break;
4373     }
4374
4375   /* Construct the API message */
4376   M (CREATE_LOOPBACK, create_loopback);
4377   if (mac_set)
4378     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4379
4380   S;
4381   W;
4382 }
4383
4384 static int
4385 api_delete_loopback (vat_main_t * vam)
4386 {
4387   unformat_input_t *i = vam->input;
4388   vl_api_delete_loopback_t *mp;
4389   f64 timeout;
4390   u32 sw_if_index = ~0;
4391
4392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4393     {
4394       if (unformat (i, "sw_if_index %d", &sw_if_index))
4395         ;
4396       else
4397         break;
4398     }
4399
4400   if (sw_if_index == ~0)
4401     {
4402       errmsg ("missing sw_if_index");
4403       return -99;
4404     }
4405
4406   /* Construct the API message */
4407   M (DELETE_LOOPBACK, delete_loopback);
4408   mp->sw_if_index = ntohl (sw_if_index);
4409
4410   S;
4411   W;
4412 }
4413
4414 static int
4415 api_want_stats (vat_main_t * vam)
4416 {
4417   unformat_input_t *i = vam->input;
4418   vl_api_want_stats_t *mp;
4419   f64 timeout;
4420   int enable = -1;
4421
4422   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4423     {
4424       if (unformat (i, "enable"))
4425         enable = 1;
4426       else if (unformat (i, "disable"))
4427         enable = 0;
4428       else
4429         break;
4430     }
4431
4432   if (enable == -1)
4433     {
4434       errmsg ("missing enable|disable");
4435       return -99;
4436     }
4437
4438   M (WANT_STATS, want_stats);
4439   mp->enable_disable = enable;
4440
4441   S;
4442   W;
4443 }
4444
4445 static int
4446 api_want_interface_events (vat_main_t * vam)
4447 {
4448   unformat_input_t *i = vam->input;
4449   vl_api_want_interface_events_t *mp;
4450   f64 timeout;
4451   int enable = -1;
4452
4453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4454     {
4455       if (unformat (i, "enable"))
4456         enable = 1;
4457       else if (unformat (i, "disable"))
4458         enable = 0;
4459       else
4460         break;
4461     }
4462
4463   if (enable == -1)
4464     {
4465       errmsg ("missing enable|disable");
4466       return -99;
4467     }
4468
4469   M (WANT_INTERFACE_EVENTS, want_interface_events);
4470   mp->enable_disable = enable;
4471
4472   vam->interface_event_display = enable;
4473
4474   S;
4475   W;
4476 }
4477
4478
4479 /* Note: non-static, called once to set up the initial intfc table */
4480 int
4481 api_sw_interface_dump (vat_main_t * vam)
4482 {
4483   vl_api_sw_interface_dump_t *mp;
4484   f64 timeout;
4485   hash_pair_t *p;
4486   name_sort_t *nses = 0, *ns;
4487   sw_interface_subif_t *sub = NULL;
4488
4489   /* Toss the old name table */
4490   /* *INDENT-OFF* */
4491   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4492   ({
4493     vec_add2 (nses, ns, 1);
4494     ns->name = (u8 *)(p->key);
4495     ns->value = (u32) p->value[0];
4496   }));
4497   /* *INDENT-ON* */
4498
4499   hash_free (vam->sw_if_index_by_interface_name);
4500
4501   vec_foreach (ns, nses) vec_free (ns->name);
4502
4503   vec_free (nses);
4504
4505   vec_foreach (sub, vam->sw_if_subif_table)
4506   {
4507     vec_free (sub->interface_name);
4508   }
4509   vec_free (vam->sw_if_subif_table);
4510
4511   /* recreate the interface name hash table */
4512   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4513
4514   /* Get list of ethernets */
4515   M (SW_INTERFACE_DUMP, sw_interface_dump);
4516   mp->name_filter_valid = 1;
4517   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4518   S;
4519
4520   /* and local / loopback interfaces */
4521   M (SW_INTERFACE_DUMP, sw_interface_dump);
4522   mp->name_filter_valid = 1;
4523   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4524   S;
4525
4526   /* and packet-generator interfaces */
4527   M (SW_INTERFACE_DUMP, sw_interface_dump);
4528   mp->name_filter_valid = 1;
4529   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4530   S;
4531
4532   /* and vxlan-gpe tunnel interfaces */
4533   M (SW_INTERFACE_DUMP, sw_interface_dump);
4534   mp->name_filter_valid = 1;
4535   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4536            sizeof (mp->name_filter) - 1);
4537   S;
4538
4539   /* and vxlan tunnel interfaces */
4540   M (SW_INTERFACE_DUMP, sw_interface_dump);
4541   mp->name_filter_valid = 1;
4542   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4543   S;
4544
4545   /* and host (af_packet) interfaces */
4546   M (SW_INTERFACE_DUMP, sw_interface_dump);
4547   mp->name_filter_valid = 1;
4548   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4549   S;
4550
4551   /* and l2tpv3 tunnel interfaces */
4552   M (SW_INTERFACE_DUMP, sw_interface_dump);
4553   mp->name_filter_valid = 1;
4554   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4555            sizeof (mp->name_filter) - 1);
4556   S;
4557
4558   /* and GRE tunnel interfaces */
4559   M (SW_INTERFACE_DUMP, sw_interface_dump);
4560   mp->name_filter_valid = 1;
4561   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4562   S;
4563
4564   /* and LISP-GPE interfaces */
4565   M (SW_INTERFACE_DUMP, sw_interface_dump);
4566   mp->name_filter_valid = 1;
4567   strncpy ((char *) mp->name_filter, "lisp_gpe",
4568            sizeof (mp->name_filter) - 1);
4569   S;
4570
4571   /* and IPSEC tunnel interfaces */
4572   M (SW_INTERFACE_DUMP, sw_interface_dump);
4573   mp->name_filter_valid = 1;
4574   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4575   S;
4576
4577   /* Use a control ping for synchronization */
4578   {
4579     vl_api_control_ping_t *mp;
4580     M (CONTROL_PING, control_ping);
4581     S;
4582   }
4583   W;
4584 }
4585
4586 static int
4587 api_sw_interface_set_flags (vat_main_t * vam)
4588 {
4589   unformat_input_t *i = vam->input;
4590   vl_api_sw_interface_set_flags_t *mp;
4591   f64 timeout;
4592   u32 sw_if_index;
4593   u8 sw_if_index_set = 0;
4594   u8 admin_up = 0, link_up = 0;
4595
4596   /* Parse args required to build the message */
4597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4598     {
4599       if (unformat (i, "admin-up"))
4600         admin_up = 1;
4601       else if (unformat (i, "admin-down"))
4602         admin_up = 0;
4603       else if (unformat (i, "link-up"))
4604         link_up = 1;
4605       else if (unformat (i, "link-down"))
4606         link_up = 0;
4607       else
4608         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4609         sw_if_index_set = 1;
4610       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4611         sw_if_index_set = 1;
4612       else
4613         break;
4614     }
4615
4616   if (sw_if_index_set == 0)
4617     {
4618       errmsg ("missing interface name or sw_if_index");
4619       return -99;
4620     }
4621
4622   /* Construct the API message */
4623   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4624   mp->sw_if_index = ntohl (sw_if_index);
4625   mp->admin_up_down = admin_up;
4626   mp->link_up_down = link_up;
4627
4628   /* send it... */
4629   S;
4630
4631   /* Wait for a reply, return the good/bad news... */
4632   W;
4633 }
4634
4635 static int
4636 api_sw_interface_clear_stats (vat_main_t * vam)
4637 {
4638   unformat_input_t *i = vam->input;
4639   vl_api_sw_interface_clear_stats_t *mp;
4640   f64 timeout;
4641   u32 sw_if_index;
4642   u8 sw_if_index_set = 0;
4643
4644   /* Parse args required to build the message */
4645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4646     {
4647       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4648         sw_if_index_set = 1;
4649       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4650         sw_if_index_set = 1;
4651       else
4652         break;
4653     }
4654
4655   /* Construct the API message */
4656   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4657
4658   if (sw_if_index_set == 1)
4659     mp->sw_if_index = ntohl (sw_if_index);
4660   else
4661     mp->sw_if_index = ~0;
4662
4663   /* send it... */
4664   S;
4665
4666   /* Wait for a reply, return the good/bad news... */
4667   W;
4668 }
4669
4670 #if DPDK >0
4671 static int
4672 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4673 {
4674   unformat_input_t *i = vam->input;
4675   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4676   f64 timeout;
4677   u32 sw_if_index;
4678   u8 sw_if_index_set = 0;
4679   u32 subport;
4680   u8 subport_set = 0;
4681   u32 pipe;
4682   u8 pipe_set = 0;
4683   u32 profile;
4684   u8 profile_set = 0;
4685
4686   /* Parse args required to build the message */
4687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4688     {
4689       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4690         sw_if_index_set = 1;
4691       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4692         sw_if_index_set = 1;
4693       else if (unformat (i, "subport %u", &subport))
4694         subport_set = 1;
4695       else
4696         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4697         sw_if_index_set = 1;
4698       else if (unformat (i, "pipe %u", &pipe))
4699         pipe_set = 1;
4700       else if (unformat (i, "profile %u", &profile))
4701         profile_set = 1;
4702       else
4703         break;
4704     }
4705
4706   if (sw_if_index_set == 0)
4707     {
4708       errmsg ("missing interface name or sw_if_index");
4709       return -99;
4710     }
4711
4712   if (subport_set == 0)
4713     {
4714       errmsg ("missing subport ");
4715       return -99;
4716     }
4717
4718   if (pipe_set == 0)
4719     {
4720       errmsg ("missing pipe");
4721       return -99;
4722     }
4723
4724   if (profile_set == 0)
4725     {
4726       errmsg ("missing profile");
4727       return -99;
4728     }
4729
4730   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4731
4732   mp->sw_if_index = ntohl (sw_if_index);
4733   mp->subport = ntohl (subport);
4734   mp->pipe = ntohl (pipe);
4735   mp->profile = ntohl (profile);
4736
4737
4738   S;
4739   W;
4740   /* NOTREACHED */
4741   return 0;
4742 }
4743
4744 static int
4745 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4746 {
4747   unformat_input_t *i = vam->input;
4748   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4749   f64 timeout;
4750   u32 sw_if_index;
4751   u8 sw_if_index_set = 0;
4752   u32 subport;
4753   u8 subport_set = 0;
4754   u32 tb_rate = 1250000000;     /* 10GbE */
4755   u32 tb_size = 1000000;
4756   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4757   u32 tc_period = 10;
4758
4759   /* Parse args required to build the message */
4760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4761     {
4762       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4763         sw_if_index_set = 1;
4764       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4765         sw_if_index_set = 1;
4766       else if (unformat (i, "subport %u", &subport))
4767         subport_set = 1;
4768       else
4769         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4770         sw_if_index_set = 1;
4771       else if (unformat (i, "rate %u", &tb_rate))
4772         {
4773           u32 tc_id;
4774
4775           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4776                tc_id++)
4777             tc_rate[tc_id] = tb_rate;
4778         }
4779       else if (unformat (i, "bktsize %u", &tb_size))
4780         ;
4781       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4782         ;
4783       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4784         ;
4785       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4786         ;
4787       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4788         ;
4789       else if (unformat (i, "period %u", &tc_period))
4790         ;
4791       else
4792         break;
4793     }
4794
4795   if (sw_if_index_set == 0)
4796     {
4797       errmsg ("missing interface name or sw_if_index");
4798       return -99;
4799     }
4800
4801   if (subport_set == 0)
4802     {
4803       errmsg ("missing subport ");
4804       return -99;
4805     }
4806
4807   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4808
4809   mp->sw_if_index = ntohl (sw_if_index);
4810   mp->subport = ntohl (subport);
4811   mp->tb_rate = ntohl (tb_rate);
4812   mp->tb_size = ntohl (tb_size);
4813   mp->tc_rate[0] = ntohl (tc_rate[0]);
4814   mp->tc_rate[1] = ntohl (tc_rate[1]);
4815   mp->tc_rate[2] = ntohl (tc_rate[2]);
4816   mp->tc_rate[3] = ntohl (tc_rate[3]);
4817   mp->tc_period = ntohl (tc_period);
4818
4819   S;
4820   W;
4821   /* NOTREACHED */
4822   return 0;
4823 }
4824
4825 static int
4826 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4827 {
4828   unformat_input_t *i = vam->input;
4829   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4830   f64 timeout;
4831   u32 sw_if_index;
4832   u8 sw_if_index_set = 0;
4833   u8 entry_set = 0;
4834   u8 tc_set = 0;
4835   u8 queue_set = 0;
4836   u32 entry, tc, queue;
4837
4838   /* Parse args required to build the message */
4839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4840     {
4841       if (unformat (i, "rx %U", api_unformat_sw_if_index, vam, &sw_if_index))
4842         sw_if_index_set = 1;
4843       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4844         sw_if_index_set = 1;
4845       else if (unformat (i, "entry %d", &entry))
4846         entry_set = 1;
4847       else if (unformat (i, "tc %d", &tc))
4848         tc_set = 1;
4849       else if (unformat (i, "queue %d", &queue))
4850         queue_set = 1;
4851       else
4852         break;
4853     }
4854
4855   if (sw_if_index_set == 0)
4856     {
4857       errmsg ("missing interface name or sw_if_index");
4858       return -99;
4859     }
4860
4861   if (entry_set == 0)
4862     {
4863       errmsg ("missing entry ");
4864       return -99;
4865     }
4866
4867   if (tc_set == 0)
4868     {
4869       errmsg ("missing traffic class ");
4870       return -99;
4871     }
4872
4873   if (queue_set == 0)
4874     {
4875       errmsg ("missing queue ");
4876       return -99;
4877     }
4878
4879   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4880
4881   mp->sw_if_index = ntohl (sw_if_index);
4882   mp->entry = ntohl (entry);
4883   mp->tc = ntohl (tc);
4884   mp->queue = ntohl (queue);
4885
4886   S;
4887   W;
4888   /* NOTREACHED */
4889   return 0;
4890 }
4891 #endif
4892
4893 static int
4894 api_sw_interface_add_del_address (vat_main_t * vam)
4895 {
4896   unformat_input_t *i = vam->input;
4897   vl_api_sw_interface_add_del_address_t *mp;
4898   f64 timeout;
4899   u32 sw_if_index;
4900   u8 sw_if_index_set = 0;
4901   u8 is_add = 1, del_all = 0;
4902   u32 address_length = 0;
4903   u8 v4_address_set = 0;
4904   u8 v6_address_set = 0;
4905   ip4_address_t v4address;
4906   ip6_address_t v6address;
4907
4908   /* Parse args required to build the message */
4909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4910     {
4911       if (unformat (i, "del-all"))
4912         del_all = 1;
4913       else if (unformat (i, "del"))
4914         is_add = 0;
4915       else
4916         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4917         sw_if_index_set = 1;
4918       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4919         sw_if_index_set = 1;
4920       else if (unformat (i, "%U/%d",
4921                          unformat_ip4_address, &v4address, &address_length))
4922         v4_address_set = 1;
4923       else if (unformat (i, "%U/%d",
4924                          unformat_ip6_address, &v6address, &address_length))
4925         v6_address_set = 1;
4926       else
4927         break;
4928     }
4929
4930   if (sw_if_index_set == 0)
4931     {
4932       errmsg ("missing interface name or sw_if_index");
4933       return -99;
4934     }
4935   if (v4_address_set && v6_address_set)
4936     {
4937       errmsg ("both v4 and v6 addresses set");
4938       return -99;
4939     }
4940   if (!v4_address_set && !v6_address_set && !del_all)
4941     {
4942       errmsg ("no addresses set");
4943       return -99;
4944     }
4945
4946   /* Construct the API message */
4947   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4948
4949   mp->sw_if_index = ntohl (sw_if_index);
4950   mp->is_add = is_add;
4951   mp->del_all = del_all;
4952   if (v6_address_set)
4953     {
4954       mp->is_ipv6 = 1;
4955       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4956     }
4957   else
4958     {
4959       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4960     }
4961   mp->address_length = address_length;
4962
4963   /* send it... */
4964   S;
4965
4966   /* Wait for a reply, return good/bad news  */
4967   W;
4968 }
4969
4970 static int
4971 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4972 {
4973   unformat_input_t *i = vam->input;
4974   vl_api_sw_interface_set_mpls_enable_t *mp;
4975   f64 timeout;
4976   u32 sw_if_index;
4977   u8 sw_if_index_set = 0;
4978   u8 enable = 1;
4979
4980   /* Parse args required to build the message */
4981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4982     {
4983       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4984         sw_if_index_set = 1;
4985       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4986         sw_if_index_set = 1;
4987       else if (unformat (i, "disable"))
4988         enable = 0;
4989       else if (unformat (i, "dis"))
4990         enable = 0;
4991       else
4992         break;
4993     }
4994
4995   if (sw_if_index_set == 0)
4996     {
4997       errmsg ("missing interface name or sw_if_index");
4998       return -99;
4999     }
5000
5001   /* Construct the API message */
5002   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
5003
5004   mp->sw_if_index = ntohl (sw_if_index);
5005   mp->enable = enable;
5006
5007   /* send it... */
5008   S;
5009
5010   /* Wait for a reply... */
5011   W;
5012 }
5013
5014 static int
5015 api_sw_interface_set_table (vat_main_t * vam)
5016 {
5017   unformat_input_t *i = vam->input;
5018   vl_api_sw_interface_set_table_t *mp;
5019   f64 timeout;
5020   u32 sw_if_index, vrf_id = 0;
5021   u8 sw_if_index_set = 0;
5022   u8 is_ipv6 = 0;
5023
5024   /* Parse args required to build the message */
5025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5026     {
5027       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5028         sw_if_index_set = 1;
5029       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5030         sw_if_index_set = 1;
5031       else if (unformat (i, "vrf %d", &vrf_id))
5032         ;
5033       else if (unformat (i, "ipv6"))
5034         is_ipv6 = 1;
5035       else
5036         break;
5037     }
5038
5039   if (sw_if_index_set == 0)
5040     {
5041       errmsg ("missing interface name or sw_if_index");
5042       return -99;
5043     }
5044
5045   /* Construct the API message */
5046   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
5047
5048   mp->sw_if_index = ntohl (sw_if_index);
5049   mp->is_ipv6 = is_ipv6;
5050   mp->vrf_id = ntohl (vrf_id);
5051
5052   /* send it... */
5053   S;
5054
5055   /* Wait for a reply... */
5056   W;
5057 }
5058
5059 static void vl_api_sw_interface_get_table_reply_t_handler
5060   (vl_api_sw_interface_get_table_reply_t * mp)
5061 {
5062   vat_main_t *vam = &vat_main;
5063
5064   print (vam->ofp, "%d", ntohl (mp->vrf_id));
5065
5066   vam->retval = ntohl (mp->retval);
5067   vam->result_ready = 1;
5068
5069 }
5070
5071 static void vl_api_sw_interface_get_table_reply_t_handler_json
5072   (vl_api_sw_interface_get_table_reply_t * mp)
5073 {
5074   vat_main_t *vam = &vat_main;
5075   vat_json_node_t node;
5076
5077   vat_json_init_object (&node);
5078   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5079   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5080
5081   vat_json_print (vam->ofp, &node);
5082   vat_json_free (&node);
5083
5084   vam->retval = ntohl (mp->retval);
5085   vam->result_ready = 1;
5086 }
5087
5088 static int
5089 api_sw_interface_get_table (vat_main_t * vam)
5090 {
5091   unformat_input_t *i = vam->input;
5092   vl_api_sw_interface_get_table_t *mp;
5093   u32 sw_if_index;
5094   u8 sw_if_index_set = 0;
5095   u8 is_ipv6 = 0;
5096   f64 timeout;
5097
5098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5099     {
5100       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5101         sw_if_index_set = 1;
5102       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5103         sw_if_index_set = 1;
5104       else if (unformat (i, "ipv6"))
5105         is_ipv6 = 1;
5106       else
5107         break;
5108     }
5109
5110   if (sw_if_index_set == 0)
5111     {
5112       errmsg ("missing interface name or sw_if_index");
5113       return -99;
5114     }
5115
5116   M (SW_INTERFACE_GET_TABLE, sw_interface_get_table);
5117   mp->sw_if_index = htonl (sw_if_index);
5118   mp->is_ipv6 = is_ipv6;
5119
5120   S;
5121   W;
5122 }
5123
5124 static int
5125 api_sw_interface_set_vpath (vat_main_t * vam)
5126 {
5127   unformat_input_t *i = vam->input;
5128   vl_api_sw_interface_set_vpath_t *mp;
5129   f64 timeout;
5130   u32 sw_if_index = 0;
5131   u8 sw_if_index_set = 0;
5132   u8 is_enable = 0;
5133
5134   /* Parse args required to build the message */
5135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5136     {
5137       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5138         sw_if_index_set = 1;
5139       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5140         sw_if_index_set = 1;
5141       else if (unformat (i, "enable"))
5142         is_enable = 1;
5143       else if (unformat (i, "disable"))
5144         is_enable = 0;
5145       else
5146         break;
5147     }
5148
5149   if (sw_if_index_set == 0)
5150     {
5151       errmsg ("missing interface name or sw_if_index");
5152       return -99;
5153     }
5154
5155   /* Construct the API message */
5156   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5157
5158   mp->sw_if_index = ntohl (sw_if_index);
5159   mp->enable = is_enable;
5160
5161   /* send it... */
5162   S;
5163
5164   /* Wait for a reply... */
5165   W;
5166 }
5167
5168 static int
5169 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5170 {
5171   unformat_input_t *i = vam->input;
5172   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5173   f64 timeout;
5174   u32 sw_if_index = 0;
5175   u8 sw_if_index_set = 0;
5176   u8 is_enable = 0;
5177   u8 is_ipv6 = 0;
5178
5179   /* Parse args required to build the message */
5180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5181     {
5182       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5183         sw_if_index_set = 1;
5184       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5185         sw_if_index_set = 1;
5186       else if (unformat (i, "enable"))
5187         is_enable = 1;
5188       else if (unformat (i, "disable"))
5189         is_enable = 0;
5190       else if (unformat (i, "ip4"))
5191         is_ipv6 = 0;
5192       else if (unformat (i, "ip6"))
5193         is_ipv6 = 1;
5194       else
5195         break;
5196     }
5197
5198   if (sw_if_index_set == 0)
5199     {
5200       errmsg ("missing interface name or sw_if_index");
5201       return -99;
5202     }
5203
5204   /* Construct the API message */
5205   M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5206
5207   mp->sw_if_index = ntohl (sw_if_index);
5208   mp->enable = is_enable;
5209   mp->is_ipv6 = is_ipv6;
5210
5211   /* send it... */
5212   S;
5213
5214   /* Wait for a reply... */
5215   W;
5216 }
5217
5218 static int
5219 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5220 {
5221   unformat_input_t *i = vam->input;
5222   vl_api_sw_interface_set_l2_xconnect_t *mp;
5223   f64 timeout;
5224   u32 rx_sw_if_index;
5225   u8 rx_sw_if_index_set = 0;
5226   u32 tx_sw_if_index;
5227   u8 tx_sw_if_index_set = 0;
5228   u8 enable = 1;
5229
5230   /* Parse args required to build the message */
5231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5232     {
5233       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5234         rx_sw_if_index_set = 1;
5235       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5236         tx_sw_if_index_set = 1;
5237       else if (unformat (i, "rx"))
5238         {
5239           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5240             {
5241               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5242                             &rx_sw_if_index))
5243                 rx_sw_if_index_set = 1;
5244             }
5245           else
5246             break;
5247         }
5248       else if (unformat (i, "tx"))
5249         {
5250           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5251             {
5252               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
5253                             &tx_sw_if_index))
5254                 tx_sw_if_index_set = 1;
5255             }
5256           else
5257             break;
5258         }
5259       else if (unformat (i, "enable"))
5260         enable = 1;
5261       else if (unformat (i, "disable"))
5262         enable = 0;
5263       else
5264         break;
5265     }
5266
5267   if (rx_sw_if_index_set == 0)
5268     {
5269       errmsg ("missing rx interface name or rx_sw_if_index");
5270       return -99;
5271     }
5272
5273   if (enable && (tx_sw_if_index_set == 0))
5274     {
5275       errmsg ("missing tx interface name or tx_sw_if_index");
5276       return -99;
5277     }
5278
5279   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5280
5281   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5282   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5283   mp->enable = enable;
5284
5285   S;
5286   W;
5287   /* NOTREACHED */
5288   return 0;
5289 }
5290
5291 static int
5292 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5293 {
5294   unformat_input_t *i = vam->input;
5295   vl_api_sw_interface_set_l2_bridge_t *mp;
5296   f64 timeout;
5297   u32 rx_sw_if_index;
5298   u8 rx_sw_if_index_set = 0;
5299   u32 bd_id;
5300   u8 bd_id_set = 0;
5301   u8 bvi = 0;
5302   u32 shg = 0;
5303   u8 enable = 1;
5304
5305   /* Parse args required to build the message */
5306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5307     {
5308       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5309         rx_sw_if_index_set = 1;
5310       else if (unformat (i, "bd_id %d", &bd_id))
5311         bd_id_set = 1;
5312       else
5313         if (unformat
5314             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
5315         rx_sw_if_index_set = 1;
5316       else if (unformat (i, "shg %d", &shg))
5317         ;
5318       else if (unformat (i, "bvi"))
5319         bvi = 1;
5320       else if (unformat (i, "enable"))
5321         enable = 1;
5322       else if (unformat (i, "disable"))
5323         enable = 0;
5324       else
5325         break;
5326     }
5327
5328   if (rx_sw_if_index_set == 0)
5329     {
5330       errmsg ("missing rx interface name or sw_if_index");
5331       return -99;
5332     }
5333
5334   if (enable && (bd_id_set == 0))
5335     {
5336       errmsg ("missing bridge domain");
5337       return -99;
5338     }
5339
5340   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5341
5342   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5343   mp->bd_id = ntohl (bd_id);
5344   mp->shg = (u8) shg;
5345   mp->bvi = bvi;
5346   mp->enable = enable;
5347
5348   S;
5349   W;
5350   /* NOTREACHED */
5351   return 0;
5352 }
5353
5354 static int
5355 api_bridge_domain_dump (vat_main_t * vam)
5356 {
5357   unformat_input_t *i = vam->input;
5358   vl_api_bridge_domain_dump_t *mp;
5359   f64 timeout;
5360   u32 bd_id = ~0;
5361
5362   /* Parse args required to build the message */
5363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5364     {
5365       if (unformat (i, "bd_id %d", &bd_id))
5366         ;
5367       else
5368         break;
5369     }
5370
5371   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5372   mp->bd_id = ntohl (bd_id);
5373   S;
5374
5375   /* Use a control ping for synchronization */
5376   {
5377     vl_api_control_ping_t *mp;
5378     M (CONTROL_PING, control_ping);
5379     S;
5380   }
5381
5382   W;
5383   /* NOTREACHED */
5384   return 0;
5385 }
5386
5387 static int
5388 api_bridge_domain_add_del (vat_main_t * vam)
5389 {
5390   unformat_input_t *i = vam->input;
5391   vl_api_bridge_domain_add_del_t *mp;
5392   f64 timeout;
5393   u32 bd_id = ~0;
5394   u8 is_add = 1;
5395   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5396   u32 mac_age = 0;
5397
5398   /* Parse args required to build the message */
5399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5400     {
5401       if (unformat (i, "bd_id %d", &bd_id))
5402         ;
5403       else if (unformat (i, "flood %d", &flood))
5404         ;
5405       else if (unformat (i, "uu-flood %d", &uu_flood))
5406         ;
5407       else if (unformat (i, "forward %d", &forward))
5408         ;
5409       else if (unformat (i, "learn %d", &learn))
5410         ;
5411       else if (unformat (i, "arp-term %d", &arp_term))
5412         ;
5413       else if (unformat (i, "mac-age %d", &mac_age))
5414         ;
5415       else if (unformat (i, "del"))
5416         {
5417           is_add = 0;
5418           flood = uu_flood = forward = learn = 0;
5419         }
5420       else
5421         break;
5422     }
5423
5424   if (bd_id == ~0)
5425     {
5426       errmsg ("missing bridge domain");
5427       return -99;
5428     }
5429
5430   if (mac_age > 255)
5431     {
5432       errmsg ("mac age must be less than 256 ");
5433       return -99;
5434     }
5435
5436   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5437
5438   mp->bd_id = ntohl (bd_id);
5439   mp->flood = flood;
5440   mp->uu_flood = uu_flood;
5441   mp->forward = forward;
5442   mp->learn = learn;
5443   mp->arp_term = arp_term;
5444   mp->is_add = is_add;
5445   mp->mac_age = (u8) mac_age;
5446
5447   S;
5448   W;
5449   /* NOTREACHED */
5450   return 0;
5451 }
5452
5453 static int
5454 api_l2fib_add_del (vat_main_t * vam)
5455 {
5456   unformat_input_t *i = vam->input;
5457   vl_api_l2fib_add_del_t *mp;
5458   f64 timeout;
5459   u64 mac = 0;
5460   u8 mac_set = 0;
5461   u32 bd_id;
5462   u8 bd_id_set = 0;
5463   u32 sw_if_index = ~0;
5464   u8 sw_if_index_set = 0;
5465   u8 is_add = 1;
5466   u8 static_mac = 0;
5467   u8 filter_mac = 0;
5468   u8 bvi_mac = 0;
5469   int count = 1;
5470   f64 before = 0;
5471   int j;
5472
5473   /* Parse args required to build the message */
5474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5475     {
5476       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5477         mac_set = 1;
5478       else if (unformat (i, "bd_id %d", &bd_id))
5479         bd_id_set = 1;
5480       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5481         sw_if_index_set = 1;
5482       else if (unformat (i, "sw_if"))
5483         {
5484           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5485             {
5486               if (unformat
5487                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5488                 sw_if_index_set = 1;
5489             }
5490           else
5491             break;
5492         }
5493       else if (unformat (i, "static"))
5494         static_mac = 1;
5495       else if (unformat (i, "filter"))
5496         {
5497           filter_mac = 1;
5498           static_mac = 1;
5499         }
5500       else if (unformat (i, "bvi"))
5501         {
5502           bvi_mac = 1;
5503           static_mac = 1;
5504         }
5505       else if (unformat (i, "del"))
5506         is_add = 0;
5507       else if (unformat (i, "count %d", &count))
5508         ;
5509       else
5510         break;
5511     }
5512
5513   if (mac_set == 0)
5514     {
5515       errmsg ("missing mac address");
5516       return -99;
5517     }
5518
5519   if (bd_id_set == 0)
5520     {
5521       errmsg ("missing bridge domain");
5522       return -99;
5523     }
5524
5525   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5526     {
5527       errmsg ("missing interface name or sw_if_index");
5528       return -99;
5529     }
5530
5531   if (count > 1)
5532     {
5533       /* Turn on async mode */
5534       vam->async_mode = 1;
5535       vam->async_errors = 0;
5536       before = vat_time_now (vam);
5537     }
5538
5539   for (j = 0; j < count; j++)
5540     {
5541       M (L2FIB_ADD_DEL, l2fib_add_del);
5542
5543       mp->mac = mac;
5544       mp->bd_id = ntohl (bd_id);
5545       mp->is_add = is_add;
5546
5547       if (is_add)
5548         {
5549           mp->sw_if_index = ntohl (sw_if_index);
5550           mp->static_mac = static_mac;
5551           mp->filter_mac = filter_mac;
5552           mp->bvi_mac = bvi_mac;
5553         }
5554       increment_mac_address (&mac);
5555       /* send it... */
5556       S;
5557     }
5558
5559   if (count > 1)
5560     {
5561       vl_api_control_ping_t *mp;
5562       f64 after;
5563
5564       /* Shut off async mode */
5565       vam->async_mode = 0;
5566
5567       M (CONTROL_PING, control_ping);
5568       S;
5569
5570       timeout = vat_time_now (vam) + 1.0;
5571       while (vat_time_now (vam) < timeout)
5572         if (vam->result_ready == 1)
5573           goto out;
5574       vam->retval = -99;
5575
5576     out:
5577       if (vam->retval == -99)
5578         errmsg ("timeout");
5579
5580       if (vam->async_errors > 0)
5581         {
5582           errmsg ("%d asynchronous errors", vam->async_errors);
5583           vam->retval = -98;
5584         }
5585       vam->async_errors = 0;
5586       after = vat_time_now (vam);
5587
5588       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
5589              count, after - before, count / (after - before));
5590     }
5591   else
5592     {
5593       /* Wait for a reply... */
5594       W;
5595     }
5596   /* Return the good/bad news */
5597   return (vam->retval);
5598 }
5599
5600 static int
5601 api_l2_flags (vat_main_t * vam)
5602 {
5603   unformat_input_t *i = vam->input;
5604   vl_api_l2_flags_t *mp;
5605   f64 timeout;
5606   u32 sw_if_index;
5607   u32 feature_bitmap = 0;
5608   u8 sw_if_index_set = 0;
5609
5610   /* Parse args required to build the message */
5611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5612     {
5613       if (unformat (i, "sw_if_index %d", &sw_if_index))
5614         sw_if_index_set = 1;
5615       else if (unformat (i, "sw_if"))
5616         {
5617           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5618             {
5619               if (unformat
5620                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5621                 sw_if_index_set = 1;
5622             }
5623           else
5624             break;
5625         }
5626       else if (unformat (i, "learn"))
5627         feature_bitmap |= L2INPUT_FEAT_LEARN;
5628       else if (unformat (i, "forward"))
5629         feature_bitmap |= L2INPUT_FEAT_FWD;
5630       else if (unformat (i, "flood"))
5631         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5632       else if (unformat (i, "uu-flood"))
5633         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5634       else
5635         break;
5636     }
5637
5638   if (sw_if_index_set == 0)
5639     {
5640       errmsg ("missing interface name or sw_if_index");
5641       return -99;
5642     }
5643
5644   M (L2_FLAGS, l2_flags);
5645
5646   mp->sw_if_index = ntohl (sw_if_index);
5647   mp->feature_bitmap = ntohl (feature_bitmap);
5648
5649   S;
5650   W;
5651   /* NOTREACHED */
5652   return 0;
5653 }
5654
5655 static int
5656 api_bridge_flags (vat_main_t * vam)
5657 {
5658   unformat_input_t *i = vam->input;
5659   vl_api_bridge_flags_t *mp;
5660   f64 timeout;
5661   u32 bd_id;
5662   u8 bd_id_set = 0;
5663   u8 is_set = 1;
5664   u32 flags = 0;
5665
5666   /* Parse args required to build the message */
5667   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5668     {
5669       if (unformat (i, "bd_id %d", &bd_id))
5670         bd_id_set = 1;
5671       else if (unformat (i, "learn"))
5672         flags |= L2_LEARN;
5673       else if (unformat (i, "forward"))
5674         flags |= L2_FWD;
5675       else if (unformat (i, "flood"))
5676         flags |= L2_FLOOD;
5677       else if (unformat (i, "uu-flood"))
5678         flags |= L2_UU_FLOOD;
5679       else if (unformat (i, "arp-term"))
5680         flags |= L2_ARP_TERM;
5681       else if (unformat (i, "off"))
5682         is_set = 0;
5683       else if (unformat (i, "disable"))
5684         is_set = 0;
5685       else
5686         break;
5687     }
5688
5689   if (bd_id_set == 0)
5690     {
5691       errmsg ("missing bridge domain");
5692       return -99;
5693     }
5694
5695   M (BRIDGE_FLAGS, bridge_flags);
5696
5697   mp->bd_id = ntohl (bd_id);
5698   mp->feature_bitmap = ntohl (flags);
5699   mp->is_set = is_set;
5700
5701   S;
5702   W;
5703   /* NOTREACHED */
5704   return 0;
5705 }
5706
5707 static int
5708 api_bd_ip_mac_add_del (vat_main_t * vam)
5709 {
5710   unformat_input_t *i = vam->input;
5711   vl_api_bd_ip_mac_add_del_t *mp;
5712   f64 timeout;
5713   u32 bd_id;
5714   u8 is_ipv6 = 0;
5715   u8 is_add = 1;
5716   u8 bd_id_set = 0;
5717   u8 ip_set = 0;
5718   u8 mac_set = 0;
5719   ip4_address_t v4addr;
5720   ip6_address_t v6addr;
5721   u8 macaddr[6];
5722
5723
5724   /* Parse args required to build the message */
5725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5726     {
5727       if (unformat (i, "bd_id %d", &bd_id))
5728         {
5729           bd_id_set++;
5730         }
5731       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5732         {
5733           ip_set++;
5734         }
5735       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5736         {
5737           ip_set++;
5738           is_ipv6++;
5739         }
5740       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5741         {
5742           mac_set++;
5743         }
5744       else if (unformat (i, "del"))
5745         is_add = 0;
5746       else
5747         break;
5748     }
5749
5750   if (bd_id_set == 0)
5751     {
5752       errmsg ("missing bridge domain");
5753       return -99;
5754     }
5755   else if (ip_set == 0)
5756     {
5757       errmsg ("missing IP address");
5758       return -99;
5759     }
5760   else if (mac_set == 0)
5761     {
5762       errmsg ("missing MAC address");
5763       return -99;
5764     }
5765
5766   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5767
5768   mp->bd_id = ntohl (bd_id);
5769   mp->is_ipv6 = is_ipv6;
5770   mp->is_add = is_add;
5771   if (is_ipv6)
5772     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5773   else
5774     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5775   clib_memcpy (mp->mac_address, macaddr, 6);
5776   S;
5777   W;
5778   /* NOTREACHED */
5779   return 0;
5780 }
5781
5782 static int
5783 api_tap_connect (vat_main_t * vam)
5784 {
5785   unformat_input_t *i = vam->input;
5786   vl_api_tap_connect_t *mp;
5787   f64 timeout;
5788   u8 mac_address[6];
5789   u8 random_mac = 1;
5790   u8 name_set = 0;
5791   u8 *tap_name;
5792   u8 *tag = 0;
5793
5794   memset (mac_address, 0, sizeof (mac_address));
5795
5796   /* Parse args required to build the message */
5797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5798     {
5799       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5800         {
5801           random_mac = 0;
5802         }
5803       else if (unformat (i, "random-mac"))
5804         random_mac = 1;
5805       else if (unformat (i, "tapname %s", &tap_name))
5806         name_set = 1;
5807       else if (unformat (i, "tag %s", &tag))
5808         ;
5809       else
5810         break;
5811     }
5812
5813   if (name_set == 0)
5814     {
5815       errmsg ("missing tap name");
5816       return -99;
5817     }
5818   if (vec_len (tap_name) > 63)
5819     {
5820       errmsg ("tap name too long");
5821       return -99;
5822     }
5823   vec_add1 (tap_name, 0);
5824
5825   if (vec_len (tag) > 63)
5826     {
5827       errmsg ("tag too long");
5828       return -99;
5829     }
5830
5831   /* Construct the API message */
5832   M (TAP_CONNECT, tap_connect);
5833
5834   mp->use_random_mac = random_mac;
5835   clib_memcpy (mp->mac_address, mac_address, 6);
5836   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5837   if (tag)
5838     clib_memcpy (mp->tag, tag, vec_len (tag));
5839
5840   vec_free (tap_name);
5841   vec_free (tag);
5842
5843   /* send it... */
5844   S;
5845
5846   /* Wait for a reply... */
5847   W;
5848 }
5849
5850 static int
5851 api_tap_modify (vat_main_t * vam)
5852 {
5853   unformat_input_t *i = vam->input;
5854   vl_api_tap_modify_t *mp;
5855   f64 timeout;
5856   u8 mac_address[6];
5857   u8 random_mac = 1;
5858   u8 name_set = 0;
5859   u8 *tap_name;
5860   u32 sw_if_index = ~0;
5861   u8 sw_if_index_set = 0;
5862
5863   memset (mac_address, 0, sizeof (mac_address));
5864
5865   /* Parse args required to build the message */
5866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5867     {
5868       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5869         sw_if_index_set = 1;
5870       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5871         sw_if_index_set = 1;
5872       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5873         {
5874           random_mac = 0;
5875         }
5876       else if (unformat (i, "random-mac"))
5877         random_mac = 1;
5878       else if (unformat (i, "tapname %s", &tap_name))
5879         name_set = 1;
5880       else
5881         break;
5882     }
5883
5884   if (sw_if_index_set == 0)
5885     {
5886       errmsg ("missing vpp interface name");
5887       return -99;
5888     }
5889   if (name_set == 0)
5890     {
5891       errmsg ("missing tap name");
5892       return -99;
5893     }
5894   if (vec_len (tap_name) > 63)
5895     {
5896       errmsg ("tap name too long");
5897     }
5898   vec_add1 (tap_name, 0);
5899
5900   /* Construct the API message */
5901   M (TAP_MODIFY, tap_modify);
5902
5903   mp->use_random_mac = random_mac;
5904   mp->sw_if_index = ntohl (sw_if_index);
5905   clib_memcpy (mp->mac_address, mac_address, 6);
5906   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5907   vec_free (tap_name);
5908
5909   /* send it... */
5910   S;
5911
5912   /* Wait for a reply... */
5913   W;
5914 }
5915
5916 static int
5917 api_tap_delete (vat_main_t * vam)
5918 {
5919   unformat_input_t *i = vam->input;
5920   vl_api_tap_delete_t *mp;
5921   f64 timeout;
5922   u32 sw_if_index = ~0;
5923   u8 sw_if_index_set = 0;
5924
5925   /* Parse args required to build the message */
5926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5927     {
5928       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5929         sw_if_index_set = 1;
5930       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5931         sw_if_index_set = 1;
5932       else
5933         break;
5934     }
5935
5936   if (sw_if_index_set == 0)
5937     {
5938       errmsg ("missing vpp interface name");
5939       return -99;
5940     }
5941
5942   /* Construct the API message */
5943   M (TAP_DELETE, tap_delete);
5944
5945   mp->sw_if_index = ntohl (sw_if_index);
5946
5947   /* send it... */
5948   S;
5949
5950   /* Wait for a reply... */
5951   W;
5952 }
5953
5954 static int
5955 api_ip_add_del_route (vat_main_t * vam)
5956 {
5957   unformat_input_t *i = vam->input;
5958   vl_api_ip_add_del_route_t *mp;
5959   f64 timeout;
5960   u32 sw_if_index = ~0, vrf_id = 0;
5961   u8 is_ipv6 = 0;
5962   u8 is_local = 0, is_drop = 0;
5963   u8 is_unreach = 0, is_prohibit = 0;
5964   u8 create_vrf_if_needed = 0;
5965   u8 is_add = 1;
5966   u32 next_hop_weight = 1;
5967   u8 not_last = 0;
5968   u8 is_multipath = 0;
5969   u8 address_set = 0;
5970   u8 address_length_set = 0;
5971   u32 next_hop_table_id = 0;
5972   u32 resolve_attempts = 0;
5973   u32 dst_address_length = 0;
5974   u8 next_hop_set = 0;
5975   ip4_address_t v4_dst_address, v4_next_hop_address;
5976   ip6_address_t v6_dst_address, v6_next_hop_address;
5977   int count = 1;
5978   int j;
5979   f64 before = 0;
5980   u32 random_add_del = 0;
5981   u32 *random_vector = 0;
5982   uword *random_hash;
5983   u32 random_seed = 0xdeaddabe;
5984   u32 classify_table_index = ~0;
5985   u8 is_classify = 0;
5986   u8 resolve_host = 0, resolve_attached = 0;
5987   mpls_label_t *next_hop_out_label_stack = NULL;
5988   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5989   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
5990
5991   /* Parse args required to build the message */
5992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5993     {
5994       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5995         ;
5996       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5997         ;
5998       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5999         {
6000           address_set = 1;
6001           is_ipv6 = 0;
6002         }
6003       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6004         {
6005           address_set = 1;
6006           is_ipv6 = 1;
6007         }
6008       else if (unformat (i, "/%d", &dst_address_length))
6009         {
6010           address_length_set = 1;
6011         }
6012
6013       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6014                                          &v4_next_hop_address))
6015         {
6016           next_hop_set = 1;
6017         }
6018       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6019                                          &v6_next_hop_address))
6020         {
6021           next_hop_set = 1;
6022         }
6023       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6024         ;
6025       else if (unformat (i, "weight %d", &next_hop_weight))
6026         ;
6027       else if (unformat (i, "drop"))
6028         {
6029           is_drop = 1;
6030         }
6031       else if (unformat (i, "null-send-unreach"))
6032         {
6033           is_unreach = 1;
6034         }
6035       else if (unformat (i, "null-send-prohibit"))
6036         {
6037           is_prohibit = 1;
6038         }
6039       else if (unformat (i, "local"))
6040         {
6041           is_local = 1;
6042         }
6043       else if (unformat (i, "classify %d", &classify_table_index))
6044         {
6045           is_classify = 1;
6046         }
6047       else if (unformat (i, "del"))
6048         is_add = 0;
6049       else if (unformat (i, "add"))
6050         is_add = 1;
6051       else if (unformat (i, "not-last"))
6052         not_last = 1;
6053       else if (unformat (i, "resolve-via-host"))
6054         resolve_host = 1;
6055       else if (unformat (i, "resolve-via-attached"))
6056         resolve_attached = 1;
6057       else if (unformat (i, "multipath"))
6058         is_multipath = 1;
6059       else if (unformat (i, "vrf %d", &vrf_id))
6060         ;
6061       else if (unformat (i, "create-vrf"))
6062         create_vrf_if_needed = 1;
6063       else if (unformat (i, "count %d", &count))
6064         ;
6065       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6066         ;
6067       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6068         ;
6069       else if (unformat (i, "out-label %d", &next_hop_out_label))
6070         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6071       else if (unformat (i, "via-label %d", &next_hop_via_label))
6072         ;
6073       else if (unformat (i, "random"))
6074         random_add_del = 1;
6075       else if (unformat (i, "seed %d", &random_seed))
6076         ;
6077       else
6078         {
6079           clib_warning ("parse error '%U'", format_unformat_error, i);
6080           return -99;
6081         }
6082     }
6083
6084   if (!next_hop_set && !is_drop && !is_local &&
6085       !is_classify && !is_unreach && !is_prohibit &&
6086       MPLS_LABEL_INVALID == next_hop_via_label)
6087     {
6088       errmsg
6089         ("next hop / local / drop / unreach / prohibit / classify not set");
6090       return -99;
6091     }
6092
6093   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6094     {
6095       errmsg ("next hop and next-hop via label set");
6096       return -99;
6097     }
6098   if (address_set == 0)
6099     {
6100       errmsg ("missing addresses");
6101       return -99;
6102     }
6103
6104   if (address_length_set == 0)
6105     {
6106       errmsg ("missing address length");
6107       return -99;
6108     }
6109
6110   /* Generate a pile of unique, random routes */
6111   if (random_add_del)
6112     {
6113       u32 this_random_address;
6114       random_hash = hash_create (count, sizeof (uword));
6115
6116       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6117       for (j = 0; j <= count; j++)
6118         {
6119           do
6120             {
6121               this_random_address = random_u32 (&random_seed);
6122               this_random_address =
6123                 clib_host_to_net_u32 (this_random_address);
6124             }
6125           while (hash_get (random_hash, this_random_address));
6126           vec_add1 (random_vector, this_random_address);
6127           hash_set (random_hash, this_random_address, 1);
6128         }
6129       hash_free (random_hash);
6130       v4_dst_address.as_u32 = random_vector[0];
6131     }
6132
6133   if (count > 1)
6134     {
6135       /* Turn on async mode */
6136       vam->async_mode = 1;
6137       vam->async_errors = 0;
6138       before = vat_time_now (vam);
6139     }
6140
6141   for (j = 0; j < count; j++)
6142     {
6143       /* Construct the API message */
6144       M2 (IP_ADD_DEL_ROUTE, ip_add_del_route,
6145           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6146
6147       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6148       mp->table_id = ntohl (vrf_id);
6149       mp->create_vrf_if_needed = create_vrf_if_needed;
6150
6151       mp->is_add = is_add;
6152       mp->is_drop = is_drop;
6153       mp->is_unreach = is_unreach;
6154       mp->is_prohibit = is_prohibit;
6155       mp->is_ipv6 = is_ipv6;
6156       mp->is_local = is_local;
6157       mp->is_classify = is_classify;
6158       mp->is_multipath = is_multipath;
6159       mp->is_resolve_host = resolve_host;
6160       mp->is_resolve_attached = resolve_attached;
6161       mp->not_last = not_last;
6162       mp->next_hop_weight = next_hop_weight;
6163       mp->dst_address_length = dst_address_length;
6164       mp->next_hop_table_id = ntohl (next_hop_table_id);
6165       mp->classify_table_index = ntohl (classify_table_index);
6166       mp->next_hop_via_label = ntohl (next_hop_via_label);
6167       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6168       if (0 != mp->next_hop_n_out_labels)
6169         {
6170           memcpy (mp->next_hop_out_label_stack,
6171                   next_hop_out_label_stack,
6172                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6173           vec_free (next_hop_out_label_stack);
6174         }
6175
6176       if (is_ipv6)
6177         {
6178           clib_memcpy (mp->dst_address, &v6_dst_address,
6179                        sizeof (v6_dst_address));
6180           if (next_hop_set)
6181             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6182                          sizeof (v6_next_hop_address));
6183           increment_v6_address (&v6_dst_address);
6184         }
6185       else
6186         {
6187           clib_memcpy (mp->dst_address, &v4_dst_address,
6188                        sizeof (v4_dst_address));
6189           if (next_hop_set)
6190             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6191                          sizeof (v4_next_hop_address));
6192           if (random_add_del)
6193             v4_dst_address.as_u32 = random_vector[j + 1];
6194           else
6195             increment_v4_address (&v4_dst_address);
6196         }
6197       /* send it... */
6198       S;
6199       /* If we receive SIGTERM, stop now... */
6200       if (vam->do_exit)
6201         break;
6202     }
6203
6204   /* When testing multiple add/del ops, use a control-ping to sync */
6205   if (count > 1)
6206     {
6207       vl_api_control_ping_t *mp;
6208       f64 after;
6209
6210       /* Shut off async mode */
6211       vam->async_mode = 0;
6212
6213       M (CONTROL_PING, control_ping);
6214       S;
6215
6216       timeout = vat_time_now (vam) + 1.0;
6217       while (vat_time_now (vam) < timeout)
6218         if (vam->result_ready == 1)
6219           goto out;
6220       vam->retval = -99;
6221
6222     out:
6223       if (vam->retval == -99)
6224         errmsg ("timeout");
6225
6226       if (vam->async_errors > 0)
6227         {
6228           errmsg ("%d asynchronous errors", vam->async_errors);
6229           vam->retval = -98;
6230         }
6231       vam->async_errors = 0;
6232       after = vat_time_now (vam);
6233
6234       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6235       if (j > 0)
6236         count = j;
6237
6238       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6239              count, after - before, count / (after - before));
6240     }
6241   else
6242     {
6243       /* Wait for a reply... */
6244       W;
6245     }
6246
6247   /* Return the good/bad news */
6248   return (vam->retval);
6249 }
6250
6251 static int
6252 api_mpls_route_add_del (vat_main_t * vam)
6253 {
6254   unformat_input_t *i = vam->input;
6255   vl_api_mpls_route_add_del_t *mp;
6256   f64 timeout;
6257   u32 sw_if_index = ~0, table_id = 0;
6258   u8 create_table_if_needed = 0;
6259   u8 is_add = 1;
6260   u32 next_hop_weight = 1;
6261   u8 is_multipath = 0;
6262   u32 next_hop_table_id = 0;
6263   u8 next_hop_set = 0;
6264   ip4_address_t v4_next_hop_address = {
6265     .as_u32 = 0,
6266   };
6267   ip6_address_t v6_next_hop_address = { {0} };
6268   int count = 1;
6269   int j;
6270   f64 before = 0;
6271   u32 classify_table_index = ~0;
6272   u8 is_classify = 0;
6273   u8 resolve_host = 0, resolve_attached = 0;
6274   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6275   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6276   mpls_label_t *next_hop_out_label_stack = NULL;
6277   mpls_label_t local_label = MPLS_LABEL_INVALID;
6278   u8 is_eos = 0;
6279   u8 next_hop_proto_is_ip4 = 1;
6280
6281   /* Parse args required to build the message */
6282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6283     {
6284       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6285         ;
6286       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6287         ;
6288       else if (unformat (i, "%d", &local_label))
6289         ;
6290       else if (unformat (i, "eos"))
6291         is_eos = 1;
6292       else if (unformat (i, "non-eos"))
6293         is_eos = 0;
6294       else if (unformat (i, "via %U", unformat_ip4_address,
6295                          &v4_next_hop_address))
6296         {
6297           next_hop_set = 1;
6298           next_hop_proto_is_ip4 = 1;
6299         }
6300       else if (unformat (i, "via %U", unformat_ip6_address,
6301                          &v6_next_hop_address))
6302         {
6303           next_hop_set = 1;
6304           next_hop_proto_is_ip4 = 0;
6305         }
6306       else if (unformat (i, "weight %d", &next_hop_weight))
6307         ;
6308       else if (unformat (i, "create-table"))
6309         create_table_if_needed = 1;
6310       else if (unformat (i, "classify %d", &classify_table_index))
6311         {
6312           is_classify = 1;
6313         }
6314       else if (unformat (i, "del"))
6315         is_add = 0;
6316       else if (unformat (i, "add"))
6317         is_add = 1;
6318       else if (unformat (i, "resolve-via-host"))
6319         resolve_host = 1;
6320       else if (unformat (i, "resolve-via-attached"))
6321         resolve_attached = 1;
6322       else if (unformat (i, "multipath"))
6323         is_multipath = 1;
6324       else if (unformat (i, "count %d", &count))
6325         ;
6326       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6327         {
6328           next_hop_set = 1;
6329           next_hop_proto_is_ip4 = 1;
6330         }
6331       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6332         {
6333           next_hop_set = 1;
6334           next_hop_proto_is_ip4 = 0;
6335         }
6336       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6337         ;
6338       else if (unformat (i, "via-label %d", &next_hop_via_label))
6339         ;
6340       else if (unformat (i, "out-label %d", &next_hop_out_label))
6341         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6342       else
6343         {
6344           clib_warning ("parse error '%U'", format_unformat_error, i);
6345           return -99;
6346         }
6347     }
6348
6349   if (!next_hop_set && !is_classify)
6350     {
6351       errmsg ("next hop / classify not set");
6352       return -99;
6353     }
6354
6355   if (MPLS_LABEL_INVALID == local_label)
6356     {
6357       errmsg ("missing label");
6358       return -99;
6359     }
6360
6361   if (count > 1)
6362     {
6363       /* Turn on async mode */
6364       vam->async_mode = 1;
6365       vam->async_errors = 0;
6366       before = vat_time_now (vam);
6367     }
6368
6369   for (j = 0; j < count; j++)
6370     {
6371       /* Construct the API message */
6372       M2 (MPLS_ROUTE_ADD_DEL, mpls_route_add_del,
6373           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6374
6375       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6376       mp->mr_table_id = ntohl (table_id);
6377       mp->mr_create_table_if_needed = create_table_if_needed;
6378
6379       mp->mr_is_add = is_add;
6380       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6381       mp->mr_is_classify = is_classify;
6382       mp->mr_is_multipath = is_multipath;
6383       mp->mr_is_resolve_host = resolve_host;
6384       mp->mr_is_resolve_attached = resolve_attached;
6385       mp->mr_next_hop_weight = next_hop_weight;
6386       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6387       mp->mr_classify_table_index = ntohl (classify_table_index);
6388       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6389       mp->mr_label = ntohl (local_label);
6390       mp->mr_eos = is_eos;
6391
6392       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6393       if (0 != mp->mr_next_hop_n_out_labels)
6394         {
6395           memcpy (mp->mr_next_hop_out_label_stack,
6396                   next_hop_out_label_stack,
6397                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6398           vec_free (next_hop_out_label_stack);
6399         }
6400
6401       if (next_hop_set)
6402         {
6403           if (next_hop_proto_is_ip4)
6404             {
6405               clib_memcpy (mp->mr_next_hop,
6406                            &v4_next_hop_address,
6407                            sizeof (v4_next_hop_address));
6408             }
6409           else
6410             {
6411               clib_memcpy (mp->mr_next_hop,
6412                            &v6_next_hop_address,
6413                            sizeof (v6_next_hop_address));
6414             }
6415         }
6416       local_label++;
6417
6418       /* send it... */
6419       S;
6420       /* If we receive SIGTERM, stop now... */
6421       if (vam->do_exit)
6422         break;
6423     }
6424
6425   /* When testing multiple add/del ops, use a control-ping to sync */
6426   if (count > 1)
6427     {
6428       vl_api_control_ping_t *mp;
6429       f64 after;
6430
6431       /* Shut off async mode */
6432       vam->async_mode = 0;
6433
6434       M (CONTROL_PING, control_ping);
6435       S;
6436
6437       timeout = vat_time_now (vam) + 1.0;
6438       while (vat_time_now (vam) < timeout)
6439         if (vam->result_ready == 1)
6440           goto out;
6441       vam->retval = -99;
6442
6443     out:
6444       if (vam->retval == -99)
6445         errmsg ("timeout");
6446
6447       if (vam->async_errors > 0)
6448         {
6449           errmsg ("%d asynchronous errors", vam->async_errors);
6450           vam->retval = -98;
6451         }
6452       vam->async_errors = 0;
6453       after = vat_time_now (vam);
6454
6455       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6456       if (j > 0)
6457         count = j;
6458
6459       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6460              count, after - before, count / (after - before));
6461     }
6462   else
6463     {
6464       /* Wait for a reply... */
6465       W;
6466     }
6467
6468   /* Return the good/bad news */
6469   return (vam->retval);
6470 }
6471
6472 static int
6473 api_mpls_ip_bind_unbind (vat_main_t * vam)
6474 {
6475   unformat_input_t *i = vam->input;
6476   vl_api_mpls_ip_bind_unbind_t *mp;
6477   f64 timeout;
6478   u32 ip_table_id = 0;
6479   u8 create_table_if_needed = 0;
6480   u8 is_bind = 1;
6481   u8 is_ip4 = 1;
6482   ip4_address_t v4_address;
6483   ip6_address_t v6_address;
6484   u32 address_length;
6485   u8 address_set = 0;
6486   mpls_label_t local_label = MPLS_LABEL_INVALID;
6487
6488   /* Parse args required to build the message */
6489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6490     {
6491       if (unformat (i, "%U/%d", unformat_ip4_address,
6492                     &v4_address, &address_length))
6493         {
6494           is_ip4 = 1;
6495           address_set = 1;
6496         }
6497       else if (unformat (i, "%U/%d", unformat_ip6_address,
6498                          &v6_address, &address_length))
6499         {
6500           is_ip4 = 0;
6501           address_set = 1;
6502         }
6503       else if (unformat (i, "%d", &local_label))
6504         ;
6505       else if (unformat (i, "create-table"))
6506         create_table_if_needed = 1;
6507       else if (unformat (i, "table-id %d", &ip_table_id))
6508         ;
6509       else if (unformat (i, "unbind"))
6510         is_bind = 0;
6511       else if (unformat (i, "bind"))
6512         is_bind = 1;
6513       else
6514         {
6515           clib_warning ("parse error '%U'", format_unformat_error, i);
6516           return -99;
6517         }
6518     }
6519
6520   if (!address_set)
6521     {
6522       errmsg ("IP addres not set");
6523       return -99;
6524     }
6525
6526   if (MPLS_LABEL_INVALID == local_label)
6527     {
6528       errmsg ("missing label");
6529       return -99;
6530     }
6531
6532   /* Construct the API message */
6533   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6534
6535   mp->mb_create_table_if_needed = create_table_if_needed;
6536   mp->mb_is_bind = is_bind;
6537   mp->mb_is_ip4 = is_ip4;
6538   mp->mb_ip_table_id = ntohl (ip_table_id);
6539   mp->mb_mpls_table_id = 0;
6540   mp->mb_label = ntohl (local_label);
6541   mp->mb_address_length = address_length;
6542
6543   if (is_ip4)
6544     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6545   else
6546     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6547
6548   /* send it... */
6549   S;
6550
6551   /* Wait for a reply... */
6552   W;
6553 }
6554
6555 static int
6556 api_proxy_arp_add_del (vat_main_t * vam)
6557 {
6558   unformat_input_t *i = vam->input;
6559   vl_api_proxy_arp_add_del_t *mp;
6560   f64 timeout;
6561   u32 vrf_id = 0;
6562   u8 is_add = 1;
6563   ip4_address_t lo, hi;
6564   u8 range_set = 0;
6565
6566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6567     {
6568       if (unformat (i, "vrf %d", &vrf_id))
6569         ;
6570       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6571                          unformat_ip4_address, &hi))
6572         range_set = 1;
6573       else if (unformat (i, "del"))
6574         is_add = 0;
6575       else
6576         {
6577           clib_warning ("parse error '%U'", format_unformat_error, i);
6578           return -99;
6579         }
6580     }
6581
6582   if (range_set == 0)
6583     {
6584       errmsg ("address range not set");
6585       return -99;
6586     }
6587
6588   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6589
6590   mp->vrf_id = ntohl (vrf_id);
6591   mp->is_add = is_add;
6592   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6593   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6594
6595   S;
6596   W;
6597   /* NOTREACHED */
6598   return 0;
6599 }
6600
6601 static int
6602 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6603 {
6604   unformat_input_t *i = vam->input;
6605   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6606   f64 timeout;
6607   u32 sw_if_index;
6608   u8 enable = 1;
6609   u8 sw_if_index_set = 0;
6610
6611   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6612     {
6613       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6614         sw_if_index_set = 1;
6615       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6616         sw_if_index_set = 1;
6617       else if (unformat (i, "enable"))
6618         enable = 1;
6619       else if (unformat (i, "disable"))
6620         enable = 0;
6621       else
6622         {
6623           clib_warning ("parse error '%U'", format_unformat_error, i);
6624           return -99;
6625         }
6626     }
6627
6628   if (sw_if_index_set == 0)
6629     {
6630       errmsg ("missing interface name or sw_if_index");
6631       return -99;
6632     }
6633
6634   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6635
6636   mp->sw_if_index = ntohl (sw_if_index);
6637   mp->enable_disable = enable;
6638
6639   S;
6640   W;
6641   /* NOTREACHED */
6642   return 0;
6643 }
6644
6645 static int
6646 api_mpls_tunnel_add_del (vat_main_t * vam)
6647 {
6648   unformat_input_t *i = vam->input;
6649   vl_api_mpls_tunnel_add_del_t *mp;
6650   f64 timeout;
6651
6652   u8 is_add = 1;
6653   u8 l2_only = 0;
6654   u32 sw_if_index = ~0;
6655   u32 next_hop_sw_if_index = ~0;
6656   u32 next_hop_proto_is_ip4 = 1;
6657
6658   u32 next_hop_table_id = 0;
6659   ip4_address_t v4_next_hop_address = {
6660     .as_u32 = 0,
6661   };
6662   ip6_address_t v6_next_hop_address = { {0} };
6663   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6664
6665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6666     {
6667       if (unformat (i, "add"))
6668         is_add = 1;
6669       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6670         is_add = 0;
6671       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6672         ;
6673       else if (unformat (i, "via %U",
6674                          unformat_ip4_address, &v4_next_hop_address))
6675         {
6676           next_hop_proto_is_ip4 = 1;
6677         }
6678       else if (unformat (i, "via %U",
6679                          unformat_ip6_address, &v6_next_hop_address))
6680         {
6681           next_hop_proto_is_ip4 = 0;
6682         }
6683       else if (unformat (i, "l2-only"))
6684         l2_only = 1;
6685       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6686         ;
6687       else if (unformat (i, "out-label %d", &next_hop_out_label))
6688         vec_add1 (labels, ntohl (next_hop_out_label));
6689       else
6690         {
6691           clib_warning ("parse error '%U'", format_unformat_error, i);
6692           return -99;
6693         }
6694     }
6695
6696   M2 (MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del,
6697       sizeof (mpls_label_t) * vec_len (labels));
6698
6699   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
6700   mp->mt_sw_if_index = ntohl (sw_if_index);
6701   mp->mt_is_add = is_add;
6702   mp->mt_l2_only = l2_only;
6703   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
6704   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6705
6706   mp->mt_next_hop_n_out_labels = vec_len (labels);
6707
6708   if (0 != mp->mt_next_hop_n_out_labels)
6709     {
6710       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
6711                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
6712       vec_free (labels);
6713     }
6714
6715   if (next_hop_proto_is_ip4)
6716     {
6717       clib_memcpy (mp->mt_next_hop,
6718                    &v4_next_hop_address, sizeof (v4_next_hop_address));
6719     }
6720   else
6721     {
6722       clib_memcpy (mp->mt_next_hop,
6723                    &v6_next_hop_address, sizeof (v6_next_hop_address));
6724     }
6725
6726   S;
6727   W;
6728   /* NOTREACHED */
6729   return 0;
6730 }
6731
6732 static int
6733 api_sw_interface_set_unnumbered (vat_main_t * vam)
6734 {
6735   unformat_input_t *i = vam->input;
6736   vl_api_sw_interface_set_unnumbered_t *mp;
6737   f64 timeout;
6738   u32 sw_if_index;
6739   u32 unnum_sw_index = ~0;
6740   u8 is_add = 1;
6741   u8 sw_if_index_set = 0;
6742
6743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6744     {
6745       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6746         sw_if_index_set = 1;
6747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6748         sw_if_index_set = 1;
6749       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6750         ;
6751       else if (unformat (i, "del"))
6752         is_add = 0;
6753       else
6754         {
6755           clib_warning ("parse error '%U'", format_unformat_error, i);
6756           return -99;
6757         }
6758     }
6759
6760   if (sw_if_index_set == 0)
6761     {
6762       errmsg ("missing interface name or sw_if_index");
6763       return -99;
6764     }
6765
6766   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6767
6768   mp->sw_if_index = ntohl (sw_if_index);
6769   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6770   mp->is_add = is_add;
6771
6772   S;
6773   W;
6774   /* NOTREACHED */
6775   return 0;
6776 }
6777
6778 static int
6779 api_ip_neighbor_add_del (vat_main_t * vam)
6780 {
6781   unformat_input_t *i = vam->input;
6782   vl_api_ip_neighbor_add_del_t *mp;
6783   f64 timeout;
6784   u32 sw_if_index;
6785   u8 sw_if_index_set = 0;
6786   u32 vrf_id = 0;
6787   u8 is_add = 1;
6788   u8 is_static = 0;
6789   u8 mac_address[6];
6790   u8 mac_set = 0;
6791   u8 v4_address_set = 0;
6792   u8 v6_address_set = 0;
6793   ip4_address_t v4address;
6794   ip6_address_t v6address;
6795
6796   memset (mac_address, 0, sizeof (mac_address));
6797
6798   /* Parse args required to build the message */
6799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6800     {
6801       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6802         {
6803           mac_set = 1;
6804         }
6805       else if (unformat (i, "del"))
6806         is_add = 0;
6807       else
6808         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6809         sw_if_index_set = 1;
6810       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6811         sw_if_index_set = 1;
6812       else if (unformat (i, "is_static"))
6813         is_static = 1;
6814       else if (unformat (i, "vrf %d", &vrf_id))
6815         ;
6816       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6817         v4_address_set = 1;
6818       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6819         v6_address_set = 1;
6820       else
6821         {
6822           clib_warning ("parse error '%U'", format_unformat_error, i);
6823           return -99;
6824         }
6825     }
6826
6827   if (sw_if_index_set == 0)
6828     {
6829       errmsg ("missing interface name or sw_if_index");
6830       return -99;
6831     }
6832   if (v4_address_set && v6_address_set)
6833     {
6834       errmsg ("both v4 and v6 addresses set");
6835       return -99;
6836     }
6837   if (!v4_address_set && !v6_address_set)
6838     {
6839       errmsg ("no address set");
6840       return -99;
6841     }
6842
6843   /* Construct the API message */
6844   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6845
6846   mp->sw_if_index = ntohl (sw_if_index);
6847   mp->is_add = is_add;
6848   mp->vrf_id = ntohl (vrf_id);
6849   mp->is_static = is_static;
6850   if (mac_set)
6851     clib_memcpy (mp->mac_address, mac_address, 6);
6852   if (v6_address_set)
6853     {
6854       mp->is_ipv6 = 1;
6855       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6856     }
6857   else
6858     {
6859       /* mp->is_ipv6 = 0; via memset in M macro above */
6860       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6861     }
6862
6863   /* send it... */
6864   S;
6865
6866   /* Wait for a reply, return good/bad news  */
6867   W;
6868
6869   /* NOTREACHED */
6870   return 0;
6871 }
6872
6873 static int
6874 api_reset_vrf (vat_main_t * vam)
6875 {
6876   unformat_input_t *i = vam->input;
6877   vl_api_reset_vrf_t *mp;
6878   f64 timeout;
6879   u32 vrf_id = 0;
6880   u8 is_ipv6 = 0;
6881   u8 vrf_id_set = 0;
6882
6883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6884     {
6885       if (unformat (i, "vrf %d", &vrf_id))
6886         vrf_id_set = 1;
6887       else if (unformat (i, "ipv6"))
6888         is_ipv6 = 1;
6889       else
6890         {
6891           clib_warning ("parse error '%U'", format_unformat_error, i);
6892           return -99;
6893         }
6894     }
6895
6896   if (vrf_id_set == 0)
6897     {
6898       errmsg ("missing vrf id");
6899       return -99;
6900     }
6901
6902   M (RESET_VRF, reset_vrf);
6903
6904   mp->vrf_id = ntohl (vrf_id);
6905   mp->is_ipv6 = is_ipv6;
6906
6907   S;
6908   W;
6909   /* NOTREACHED */
6910   return 0;
6911 }
6912
6913 static int
6914 api_create_vlan_subif (vat_main_t * vam)
6915 {
6916   unformat_input_t *i = vam->input;
6917   vl_api_create_vlan_subif_t *mp;
6918   f64 timeout;
6919   u32 sw_if_index;
6920   u8 sw_if_index_set = 0;
6921   u32 vlan_id;
6922   u8 vlan_id_set = 0;
6923
6924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6925     {
6926       if (unformat (i, "sw_if_index %d", &sw_if_index))
6927         sw_if_index_set = 1;
6928       else
6929         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6930         sw_if_index_set = 1;
6931       else if (unformat (i, "vlan %d", &vlan_id))
6932         vlan_id_set = 1;
6933       else
6934         {
6935           clib_warning ("parse error '%U'", format_unformat_error, i);
6936           return -99;
6937         }
6938     }
6939
6940   if (sw_if_index_set == 0)
6941     {
6942       errmsg ("missing interface name or sw_if_index");
6943       return -99;
6944     }
6945
6946   if (vlan_id_set == 0)
6947     {
6948       errmsg ("missing vlan_id");
6949       return -99;
6950     }
6951   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6952
6953   mp->sw_if_index = ntohl (sw_if_index);
6954   mp->vlan_id = ntohl (vlan_id);
6955
6956   S;
6957   W;
6958   /* NOTREACHED */
6959   return 0;
6960 }
6961
6962 #define foreach_create_subif_bit                \
6963 _(no_tags)                                      \
6964 _(one_tag)                                      \
6965 _(two_tags)                                     \
6966 _(dot1ad)                                       \
6967 _(exact_match)                                  \
6968 _(default_sub)                                  \
6969 _(outer_vlan_id_any)                            \
6970 _(inner_vlan_id_any)
6971
6972 static int
6973 api_create_subif (vat_main_t * vam)
6974 {
6975   unformat_input_t *i = vam->input;
6976   vl_api_create_subif_t *mp;
6977   f64 timeout;
6978   u32 sw_if_index;
6979   u8 sw_if_index_set = 0;
6980   u32 sub_id;
6981   u8 sub_id_set = 0;
6982   u32 no_tags = 0;
6983   u32 one_tag = 0;
6984   u32 two_tags = 0;
6985   u32 dot1ad = 0;
6986   u32 exact_match = 0;
6987   u32 default_sub = 0;
6988   u32 outer_vlan_id_any = 0;
6989   u32 inner_vlan_id_any = 0;
6990   u32 tmp;
6991   u16 outer_vlan_id = 0;
6992   u16 inner_vlan_id = 0;
6993
6994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6995     {
6996       if (unformat (i, "sw_if_index %d", &sw_if_index))
6997         sw_if_index_set = 1;
6998       else
6999         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7000         sw_if_index_set = 1;
7001       else if (unformat (i, "sub_id %d", &sub_id))
7002         sub_id_set = 1;
7003       else if (unformat (i, "outer_vlan_id %d", &tmp))
7004         outer_vlan_id = tmp;
7005       else if (unformat (i, "inner_vlan_id %d", &tmp))
7006         inner_vlan_id = tmp;
7007
7008 #define _(a) else if (unformat (i, #a)) a = 1 ;
7009       foreach_create_subif_bit
7010 #undef _
7011         else
7012         {
7013           clib_warning ("parse error '%U'", format_unformat_error, i);
7014           return -99;
7015         }
7016     }
7017
7018   if (sw_if_index_set == 0)
7019     {
7020       errmsg ("missing interface name or sw_if_index");
7021       return -99;
7022     }
7023
7024   if (sub_id_set == 0)
7025     {
7026       errmsg ("missing sub_id");
7027       return -99;
7028     }
7029   M (CREATE_SUBIF, create_subif);
7030
7031   mp->sw_if_index = ntohl (sw_if_index);
7032   mp->sub_id = ntohl (sub_id);
7033
7034 #define _(a) mp->a = a;
7035   foreach_create_subif_bit;
7036 #undef _
7037
7038   mp->outer_vlan_id = ntohs (outer_vlan_id);
7039   mp->inner_vlan_id = ntohs (inner_vlan_id);
7040
7041   S;
7042   W;
7043   /* NOTREACHED */
7044   return 0;
7045 }
7046
7047 static int
7048 api_oam_add_del (vat_main_t * vam)
7049 {
7050   unformat_input_t *i = vam->input;
7051   vl_api_oam_add_del_t *mp;
7052   f64 timeout;
7053   u32 vrf_id = 0;
7054   u8 is_add = 1;
7055   ip4_address_t src, dst;
7056   u8 src_set = 0;
7057   u8 dst_set = 0;
7058
7059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7060     {
7061       if (unformat (i, "vrf %d", &vrf_id))
7062         ;
7063       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7064         src_set = 1;
7065       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7066         dst_set = 1;
7067       else if (unformat (i, "del"))
7068         is_add = 0;
7069       else
7070         {
7071           clib_warning ("parse error '%U'", format_unformat_error, i);
7072           return -99;
7073         }
7074     }
7075
7076   if (src_set == 0)
7077     {
7078       errmsg ("missing src addr");
7079       return -99;
7080     }
7081
7082   if (dst_set == 0)
7083     {
7084       errmsg ("missing dst addr");
7085       return -99;
7086     }
7087
7088   M (OAM_ADD_DEL, oam_add_del);
7089
7090   mp->vrf_id = ntohl (vrf_id);
7091   mp->is_add = is_add;
7092   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7093   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7094
7095   S;
7096   W;
7097   /* NOTREACHED */
7098   return 0;
7099 }
7100
7101 static int
7102 api_reset_fib (vat_main_t * vam)
7103 {
7104   unformat_input_t *i = vam->input;
7105   vl_api_reset_fib_t *mp;
7106   f64 timeout;
7107   u32 vrf_id = 0;
7108   u8 is_ipv6 = 0;
7109   u8 vrf_id_set = 0;
7110
7111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7112     {
7113       if (unformat (i, "vrf %d", &vrf_id))
7114         vrf_id_set = 1;
7115       else if (unformat (i, "ipv6"))
7116         is_ipv6 = 1;
7117       else
7118         {
7119           clib_warning ("parse error '%U'", format_unformat_error, i);
7120           return -99;
7121         }
7122     }
7123
7124   if (vrf_id_set == 0)
7125     {
7126       errmsg ("missing vrf id");
7127       return -99;
7128     }
7129
7130   M (RESET_FIB, reset_fib);
7131
7132   mp->vrf_id = ntohl (vrf_id);
7133   mp->is_ipv6 = is_ipv6;
7134
7135   S;
7136   W;
7137   /* NOTREACHED */
7138   return 0;
7139 }
7140
7141 static int
7142 api_dhcp_proxy_config (vat_main_t * vam)
7143 {
7144   unformat_input_t *i = vam->input;
7145   vl_api_dhcp_proxy_config_t *mp;
7146   f64 timeout;
7147   u32 vrf_id = 0;
7148   u8 is_add = 1;
7149   u8 insert_cid = 1;
7150   u8 v4_address_set = 0;
7151   u8 v6_address_set = 0;
7152   ip4_address_t v4address;
7153   ip6_address_t v6address;
7154   u8 v4_src_address_set = 0;
7155   u8 v6_src_address_set = 0;
7156   ip4_address_t v4srcaddress;
7157   ip6_address_t v6srcaddress;
7158
7159   /* Parse args required to build the message */
7160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7161     {
7162       if (unformat (i, "del"))
7163         is_add = 0;
7164       else if (unformat (i, "vrf %d", &vrf_id))
7165         ;
7166       else if (unformat (i, "insert-cid %d", &insert_cid))
7167         ;
7168       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7169         v4_address_set = 1;
7170       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7171         v6_address_set = 1;
7172       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7173         v4_src_address_set = 1;
7174       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7175         v6_src_address_set = 1;
7176       else
7177         break;
7178     }
7179
7180   if (v4_address_set && v6_address_set)
7181     {
7182       errmsg ("both v4 and v6 server addresses set");
7183       return -99;
7184     }
7185   if (!v4_address_set && !v6_address_set)
7186     {
7187       errmsg ("no server addresses set");
7188       return -99;
7189     }
7190
7191   if (v4_src_address_set && v6_src_address_set)
7192     {
7193       errmsg ("both v4 and v6  src addresses set");
7194       return -99;
7195     }
7196   if (!v4_src_address_set && !v6_src_address_set)
7197     {
7198       errmsg ("no src addresses set");
7199       return -99;
7200     }
7201
7202   if (!(v4_src_address_set && v4_address_set) &&
7203       !(v6_src_address_set && v6_address_set))
7204     {
7205       errmsg ("no matching server and src addresses set");
7206       return -99;
7207     }
7208
7209   /* Construct the API message */
7210   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7211
7212   mp->insert_circuit_id = insert_cid;
7213   mp->is_add = is_add;
7214   mp->vrf_id = ntohl (vrf_id);
7215   if (v6_address_set)
7216     {
7217       mp->is_ipv6 = 1;
7218       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7219       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7220     }
7221   else
7222     {
7223       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7224       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7225     }
7226
7227   /* send it... */
7228   S;
7229
7230   /* Wait for a reply, return good/bad news  */
7231   W;
7232   /* NOTREACHED */
7233   return 0;
7234 }
7235
7236 static int
7237 api_dhcp_proxy_config_2 (vat_main_t * vam)
7238 {
7239   unformat_input_t *i = vam->input;
7240   vl_api_dhcp_proxy_config_2_t *mp;
7241   f64 timeout;
7242   u32 rx_vrf_id = 0;
7243   u32 server_vrf_id = 0;
7244   u8 is_add = 1;
7245   u8 insert_cid = 1;
7246   u8 v4_address_set = 0;
7247   u8 v6_address_set = 0;
7248   ip4_address_t v4address;
7249   ip6_address_t v6address;
7250   u8 v4_src_address_set = 0;
7251   u8 v6_src_address_set = 0;
7252   ip4_address_t v4srcaddress;
7253   ip6_address_t v6srcaddress;
7254
7255   /* Parse args required to build the message */
7256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7257     {
7258       if (unformat (i, "del"))
7259         is_add = 0;
7260       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7261         ;
7262       else if (unformat (i, "server_vrf_id %d", &server_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_2, dhcp_proxy_config_2);
7309
7310   mp->insert_circuit_id = insert_cid;
7311   mp->is_add = is_add;
7312   mp->rx_vrf_id = ntohl (rx_vrf_id);
7313   mp->server_vrf_id = ntohl (server_vrf_id);
7314   if (v6_address_set)
7315     {
7316       mp->is_ipv6 = 1;
7317       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7318       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7319     }
7320   else
7321     {
7322       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7323       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7324     }
7325
7326   /* send it... */
7327   S;
7328
7329   /* Wait for a reply, return good/bad news  */
7330   W;
7331   /* NOTREACHED */
7332   return 0;
7333 }
7334
7335 static int
7336 api_dhcp_proxy_set_vss (vat_main_t * vam)
7337 {
7338   unformat_input_t *i = vam->input;
7339   vl_api_dhcp_proxy_set_vss_t *mp;
7340   f64 timeout;
7341   u8 is_ipv6 = 0;
7342   u8 is_add = 1;
7343   u32 tbl_id;
7344   u8 tbl_id_set = 0;
7345   u32 oui;
7346   u8 oui_set = 0;
7347   u32 fib_id;
7348   u8 fib_id_set = 0;
7349
7350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7351     {
7352       if (unformat (i, "tbl_id %d", &tbl_id))
7353         tbl_id_set = 1;
7354       if (unformat (i, "fib_id %d", &fib_id))
7355         fib_id_set = 1;
7356       if (unformat (i, "oui %d", &oui))
7357         oui_set = 1;
7358       else if (unformat (i, "ipv6"))
7359         is_ipv6 = 1;
7360       else if (unformat (i, "del"))
7361         is_add = 0;
7362       else
7363         {
7364           clib_warning ("parse error '%U'", format_unformat_error, i);
7365           return -99;
7366         }
7367     }
7368
7369   if (tbl_id_set == 0)
7370     {
7371       errmsg ("missing tbl id");
7372       return -99;
7373     }
7374
7375   if (fib_id_set == 0)
7376     {
7377       errmsg ("missing fib id");
7378       return -99;
7379     }
7380   if (oui_set == 0)
7381     {
7382       errmsg ("missing oui");
7383       return -99;
7384     }
7385
7386   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7387   mp->tbl_id = ntohl (tbl_id);
7388   mp->fib_id = ntohl (fib_id);
7389   mp->oui = ntohl (oui);
7390   mp->is_ipv6 = is_ipv6;
7391   mp->is_add = is_add;
7392
7393   S;
7394   W;
7395   /* NOTREACHED */
7396   return 0;
7397 }
7398
7399 static int
7400 api_dhcp_client_config (vat_main_t * vam)
7401 {
7402   unformat_input_t *i = vam->input;
7403   vl_api_dhcp_client_config_t *mp;
7404   f64 timeout;
7405   u32 sw_if_index;
7406   u8 sw_if_index_set = 0;
7407   u8 is_add = 1;
7408   u8 *hostname = 0;
7409   u8 disable_event = 0;
7410
7411   /* Parse args required to build the message */
7412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7413     {
7414       if (unformat (i, "del"))
7415         is_add = 0;
7416       else
7417         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7418         sw_if_index_set = 1;
7419       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7420         sw_if_index_set = 1;
7421       else if (unformat (i, "hostname %s", &hostname))
7422         ;
7423       else if (unformat (i, "disable_event"))
7424         disable_event = 1;
7425       else
7426         break;
7427     }
7428
7429   if (sw_if_index_set == 0)
7430     {
7431       errmsg ("missing interface name or sw_if_index");
7432       return -99;
7433     }
7434
7435   if (vec_len (hostname) > 63)
7436     {
7437       errmsg ("hostname too long");
7438     }
7439   vec_add1 (hostname, 0);
7440
7441   /* Construct the API message */
7442   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7443
7444   mp->sw_if_index = ntohl (sw_if_index);
7445   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7446   vec_free (hostname);
7447   mp->is_add = is_add;
7448   mp->want_dhcp_event = disable_event ? 0 : 1;
7449   mp->pid = getpid ();
7450
7451   /* send it... */
7452   S;
7453
7454   /* Wait for a reply, return good/bad news  */
7455   W;
7456   /* NOTREACHED */
7457   return 0;
7458 }
7459
7460 static int
7461 api_set_ip_flow_hash (vat_main_t * vam)
7462 {
7463   unformat_input_t *i = vam->input;
7464   vl_api_set_ip_flow_hash_t *mp;
7465   f64 timeout;
7466   u32 vrf_id = 0;
7467   u8 is_ipv6 = 0;
7468   u8 vrf_id_set = 0;
7469   u8 src = 0;
7470   u8 dst = 0;
7471   u8 sport = 0;
7472   u8 dport = 0;
7473   u8 proto = 0;
7474   u8 reverse = 0;
7475
7476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7477     {
7478       if (unformat (i, "vrf %d", &vrf_id))
7479         vrf_id_set = 1;
7480       else if (unformat (i, "ipv6"))
7481         is_ipv6 = 1;
7482       else if (unformat (i, "src"))
7483         src = 1;
7484       else if (unformat (i, "dst"))
7485         dst = 1;
7486       else if (unformat (i, "sport"))
7487         sport = 1;
7488       else if (unformat (i, "dport"))
7489         dport = 1;
7490       else if (unformat (i, "proto"))
7491         proto = 1;
7492       else if (unformat (i, "reverse"))
7493         reverse = 1;
7494
7495       else
7496         {
7497           clib_warning ("parse error '%U'", format_unformat_error, i);
7498           return -99;
7499         }
7500     }
7501
7502   if (vrf_id_set == 0)
7503     {
7504       errmsg ("missing vrf id");
7505       return -99;
7506     }
7507
7508   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7509   mp->src = src;
7510   mp->dst = dst;
7511   mp->sport = sport;
7512   mp->dport = dport;
7513   mp->proto = proto;
7514   mp->reverse = reverse;
7515   mp->vrf_id = ntohl (vrf_id);
7516   mp->is_ipv6 = is_ipv6;
7517
7518   S;
7519   W;
7520   /* NOTREACHED */
7521   return 0;
7522 }
7523
7524 static int
7525 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7526 {
7527   unformat_input_t *i = vam->input;
7528   vl_api_sw_interface_ip6_enable_disable_t *mp;
7529   f64 timeout;
7530   u32 sw_if_index;
7531   u8 sw_if_index_set = 0;
7532   u8 enable = 0;
7533
7534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7535     {
7536       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7537         sw_if_index_set = 1;
7538       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7539         sw_if_index_set = 1;
7540       else if (unformat (i, "enable"))
7541         enable = 1;
7542       else if (unformat (i, "disable"))
7543         enable = 0;
7544       else
7545         {
7546           clib_warning ("parse error '%U'", format_unformat_error, i);
7547           return -99;
7548         }
7549     }
7550
7551   if (sw_if_index_set == 0)
7552     {
7553       errmsg ("missing interface name or sw_if_index");
7554       return -99;
7555     }
7556
7557   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7558
7559   mp->sw_if_index = ntohl (sw_if_index);
7560   mp->enable = enable;
7561
7562   S;
7563   W;
7564   /* NOTREACHED */
7565   return 0;
7566 }
7567
7568 static int
7569 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7570 {
7571   unformat_input_t *i = vam->input;
7572   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7573   f64 timeout;
7574   u32 sw_if_index;
7575   u8 sw_if_index_set = 0;
7576   u8 v6_address_set = 0;
7577   ip6_address_t v6address;
7578
7579   /* Parse args required to build the message */
7580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7581     {
7582       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7583         sw_if_index_set = 1;
7584       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7585         sw_if_index_set = 1;
7586       else if (unformat (i, "%U", unformat_ip6_address, &v6address))
7587         v6_address_set = 1;
7588       else
7589         break;
7590     }
7591
7592   if (sw_if_index_set == 0)
7593     {
7594       errmsg ("missing interface name or sw_if_index");
7595       return -99;
7596     }
7597   if (!v6_address_set)
7598     {
7599       errmsg ("no address set");
7600       return -99;
7601     }
7602
7603   /* Construct the API message */
7604   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7605      sw_interface_ip6_set_link_local_address);
7606
7607   mp->sw_if_index = ntohl (sw_if_index);
7608   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7609
7610   /* send it... */
7611   S;
7612
7613   /* Wait for a reply, return good/bad news  */
7614   W;
7615
7616   /* NOTREACHED */
7617   return 0;
7618 }
7619
7620
7621 static int
7622 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7623 {
7624   unformat_input_t *i = vam->input;
7625   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7626   f64 timeout;
7627   u32 sw_if_index;
7628   u8 sw_if_index_set = 0;
7629   u32 address_length = 0;
7630   u8 v6_address_set = 0;
7631   ip6_address_t v6address;
7632   u8 use_default = 0;
7633   u8 no_advertise = 0;
7634   u8 off_link = 0;
7635   u8 no_autoconfig = 0;
7636   u8 no_onlink = 0;
7637   u8 is_no = 0;
7638   u32 val_lifetime = 0;
7639   u32 pref_lifetime = 0;
7640
7641   /* Parse args required to build the message */
7642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7643     {
7644       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7645         sw_if_index_set = 1;
7646       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7647         sw_if_index_set = 1;
7648       else if (unformat (i, "%U/%d",
7649                          unformat_ip6_address, &v6address, &address_length))
7650         v6_address_set = 1;
7651       else if (unformat (i, "val_life %d", &val_lifetime))
7652         ;
7653       else if (unformat (i, "pref_life %d", &pref_lifetime))
7654         ;
7655       else if (unformat (i, "def"))
7656         use_default = 1;
7657       else if (unformat (i, "noadv"))
7658         no_advertise = 1;
7659       else if (unformat (i, "offl"))
7660         off_link = 1;
7661       else if (unformat (i, "noauto"))
7662         no_autoconfig = 1;
7663       else if (unformat (i, "nolink"))
7664         no_onlink = 1;
7665       else if (unformat (i, "isno"))
7666         is_no = 1;
7667       else
7668         {
7669           clib_warning ("parse error '%U'", format_unformat_error, i);
7670           return -99;
7671         }
7672     }
7673
7674   if (sw_if_index_set == 0)
7675     {
7676       errmsg ("missing interface name or sw_if_index");
7677       return -99;
7678     }
7679   if (!v6_address_set)
7680     {
7681       errmsg ("no address set");
7682       return -99;
7683     }
7684
7685   /* Construct the API message */
7686   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7687
7688   mp->sw_if_index = ntohl (sw_if_index);
7689   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7690   mp->address_length = address_length;
7691   mp->use_default = use_default;
7692   mp->no_advertise = no_advertise;
7693   mp->off_link = off_link;
7694   mp->no_autoconfig = no_autoconfig;
7695   mp->no_onlink = no_onlink;
7696   mp->is_no = is_no;
7697   mp->val_lifetime = ntohl (val_lifetime);
7698   mp->pref_lifetime = ntohl (pref_lifetime);
7699
7700   /* send it... */
7701   S;
7702
7703   /* Wait for a reply, return good/bad news  */
7704   W;
7705
7706   /* NOTREACHED */
7707   return 0;
7708 }
7709
7710 static int
7711 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7712 {
7713   unformat_input_t *i = vam->input;
7714   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7715   f64 timeout;
7716   u32 sw_if_index;
7717   u8 sw_if_index_set = 0;
7718   u8 suppress = 0;
7719   u8 managed = 0;
7720   u8 other = 0;
7721   u8 ll_option = 0;
7722   u8 send_unicast = 0;
7723   u8 cease = 0;
7724   u8 is_no = 0;
7725   u8 default_router = 0;
7726   u32 max_interval = 0;
7727   u32 min_interval = 0;
7728   u32 lifetime = 0;
7729   u32 initial_count = 0;
7730   u32 initial_interval = 0;
7731
7732
7733   /* Parse args required to build the message */
7734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7735     {
7736       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7737         sw_if_index_set = 1;
7738       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7739         sw_if_index_set = 1;
7740       else if (unformat (i, "maxint %d", &max_interval))
7741         ;
7742       else if (unformat (i, "minint %d", &min_interval))
7743         ;
7744       else if (unformat (i, "life %d", &lifetime))
7745         ;
7746       else if (unformat (i, "count %d", &initial_count))
7747         ;
7748       else if (unformat (i, "interval %d", &initial_interval))
7749         ;
7750       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7751         suppress = 1;
7752       else if (unformat (i, "managed"))
7753         managed = 1;
7754       else if (unformat (i, "other"))
7755         other = 1;
7756       else if (unformat (i, "ll"))
7757         ll_option = 1;
7758       else if (unformat (i, "send"))
7759         send_unicast = 1;
7760       else if (unformat (i, "cease"))
7761         cease = 1;
7762       else if (unformat (i, "isno"))
7763         is_no = 1;
7764       else if (unformat (i, "def"))
7765         default_router = 1;
7766       else
7767         {
7768           clib_warning ("parse error '%U'", format_unformat_error, i);
7769           return -99;
7770         }
7771     }
7772
7773   if (sw_if_index_set == 0)
7774     {
7775       errmsg ("missing interface name or sw_if_index");
7776       return -99;
7777     }
7778
7779   /* Construct the API message */
7780   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7781
7782   mp->sw_if_index = ntohl (sw_if_index);
7783   mp->max_interval = ntohl (max_interval);
7784   mp->min_interval = ntohl (min_interval);
7785   mp->lifetime = ntohl (lifetime);
7786   mp->initial_count = ntohl (initial_count);
7787   mp->initial_interval = ntohl (initial_interval);
7788   mp->suppress = suppress;
7789   mp->managed = managed;
7790   mp->other = other;
7791   mp->ll_option = ll_option;
7792   mp->send_unicast = send_unicast;
7793   mp->cease = cease;
7794   mp->is_no = is_no;
7795   mp->default_router = default_router;
7796
7797   /* send it... */
7798   S;
7799
7800   /* Wait for a reply, return good/bad news  */
7801   W;
7802
7803   /* NOTREACHED */
7804   return 0;
7805 }
7806
7807 static int
7808 api_set_arp_neighbor_limit (vat_main_t * vam)
7809 {
7810   unformat_input_t *i = vam->input;
7811   vl_api_set_arp_neighbor_limit_t *mp;
7812   f64 timeout;
7813   u32 arp_nbr_limit;
7814   u8 limit_set = 0;
7815   u8 is_ipv6 = 0;
7816
7817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7818     {
7819       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7820         limit_set = 1;
7821       else if (unformat (i, "ipv6"))
7822         is_ipv6 = 1;
7823       else
7824         {
7825           clib_warning ("parse error '%U'", format_unformat_error, i);
7826           return -99;
7827         }
7828     }
7829
7830   if (limit_set == 0)
7831     {
7832       errmsg ("missing limit value");
7833       return -99;
7834     }
7835
7836   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7837
7838   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7839   mp->is_ipv6 = is_ipv6;
7840
7841   S;
7842   W;
7843   /* NOTREACHED */
7844   return 0;
7845 }
7846
7847 static int
7848 api_l2_patch_add_del (vat_main_t * vam)
7849 {
7850   unformat_input_t *i = vam->input;
7851   vl_api_l2_patch_add_del_t *mp;
7852   f64 timeout;
7853   u32 rx_sw_if_index;
7854   u8 rx_sw_if_index_set = 0;
7855   u32 tx_sw_if_index;
7856   u8 tx_sw_if_index_set = 0;
7857   u8 is_add = 1;
7858
7859   /* Parse args required to build the message */
7860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7861     {
7862       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7863         rx_sw_if_index_set = 1;
7864       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7865         tx_sw_if_index_set = 1;
7866       else if (unformat (i, "rx"))
7867         {
7868           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7869             {
7870               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7871                             &rx_sw_if_index))
7872                 rx_sw_if_index_set = 1;
7873             }
7874           else
7875             break;
7876         }
7877       else if (unformat (i, "tx"))
7878         {
7879           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7880             {
7881               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7882                             &tx_sw_if_index))
7883                 tx_sw_if_index_set = 1;
7884             }
7885           else
7886             break;
7887         }
7888       else if (unformat (i, "del"))
7889         is_add = 0;
7890       else
7891         break;
7892     }
7893
7894   if (rx_sw_if_index_set == 0)
7895     {
7896       errmsg ("missing rx interface name or rx_sw_if_index");
7897       return -99;
7898     }
7899
7900   if (tx_sw_if_index_set == 0)
7901     {
7902       errmsg ("missing tx interface name or tx_sw_if_index");
7903       return -99;
7904     }
7905
7906   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7907
7908   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7909   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7910   mp->is_add = is_add;
7911
7912   S;
7913   W;
7914   /* NOTREACHED */
7915   return 0;
7916 }
7917
7918 static int
7919 api_ioam_enable (vat_main_t * vam)
7920 {
7921   unformat_input_t *input = vam->input;
7922   vl_api_ioam_enable_t *mp;
7923   f64 timeout;
7924   u32 id = 0;
7925   int has_trace_option = 0;
7926   int has_pot_option = 0;
7927   int has_seqno_option = 0;
7928   int has_analyse_option = 0;
7929
7930   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7931     {
7932       if (unformat (input, "trace"))
7933         has_trace_option = 1;
7934       else if (unformat (input, "pot"))
7935         has_pot_option = 1;
7936       else if (unformat (input, "seqno"))
7937         has_seqno_option = 1;
7938       else if (unformat (input, "analyse"))
7939         has_analyse_option = 1;
7940       else
7941         break;
7942     }
7943   M (IOAM_ENABLE, ioam_enable);
7944   mp->id = htons (id);
7945   mp->seqno = has_seqno_option;
7946   mp->analyse = has_analyse_option;
7947   mp->pot_enable = has_pot_option;
7948   mp->trace_enable = has_trace_option;
7949
7950   S;
7951   W;
7952
7953   return (0);
7954
7955 }
7956
7957
7958 static int
7959 api_ioam_disable (vat_main_t * vam)
7960 {
7961   vl_api_ioam_disable_t *mp;
7962   f64 timeout;
7963
7964   M (IOAM_DISABLE, ioam_disable);
7965   S;
7966   W;
7967   return 0;
7968 }
7969
7970 static int
7971 api_sr_tunnel_add_del (vat_main_t * vam)
7972 {
7973   unformat_input_t *i = vam->input;
7974   vl_api_sr_tunnel_add_del_t *mp;
7975   f64 timeout;
7976   int is_del = 0;
7977   int pl_index;
7978   ip6_address_t src_address;
7979   int src_address_set = 0;
7980   ip6_address_t dst_address;
7981   u32 dst_mask_width;
7982   int dst_address_set = 0;
7983   u16 flags = 0;
7984   u32 rx_table_id = 0;
7985   u32 tx_table_id = 0;
7986   ip6_address_t *segments = 0;
7987   ip6_address_t *this_seg;
7988   ip6_address_t *tags = 0;
7989   ip6_address_t *this_tag;
7990   ip6_address_t next_address, tag;
7991   u8 *name = 0;
7992   u8 *policy_name = 0;
7993
7994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7995     {
7996       if (unformat (i, "del"))
7997         is_del = 1;
7998       else if (unformat (i, "name %s", &name))
7999         ;
8000       else if (unformat (i, "policy %s", &policy_name))
8001         ;
8002       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8003         ;
8004       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8005         ;
8006       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8007         src_address_set = 1;
8008       else if (unformat (i, "dst %U/%d",
8009                          unformat_ip6_address, &dst_address, &dst_mask_width))
8010         dst_address_set = 1;
8011       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8012         {
8013           vec_add2 (segments, this_seg, 1);
8014           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8015                        sizeof (*this_seg));
8016         }
8017       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8018         {
8019           vec_add2 (tags, this_tag, 1);
8020           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8021         }
8022       else if (unformat (i, "clean"))
8023         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8024       else if (unformat (i, "protected"))
8025         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8026       else if (unformat (i, "InPE %d", &pl_index))
8027         {
8028           if (pl_index <= 0 || pl_index > 4)
8029             {
8030             pl_index_range_error:
8031               errmsg ("pl index %d out of range", pl_index);
8032               return -99;
8033             }
8034           flags |=
8035             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8036         }
8037       else if (unformat (i, "EgPE %d", &pl_index))
8038         {
8039           if (pl_index <= 0 || pl_index > 4)
8040             goto pl_index_range_error;
8041           flags |=
8042             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8043         }
8044       else if (unformat (i, "OrgSrc %d", &pl_index))
8045         {
8046           if (pl_index <= 0 || pl_index > 4)
8047             goto pl_index_range_error;
8048           flags |=
8049             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8050         }
8051       else
8052         break;
8053     }
8054
8055   if (!src_address_set)
8056     {
8057       errmsg ("src address required");
8058       return -99;
8059     }
8060
8061   if (!dst_address_set)
8062     {
8063       errmsg ("dst address required");
8064       return -99;
8065     }
8066
8067   if (!segments)
8068     {
8069       errmsg ("at least one sr segment required");
8070       return -99;
8071     }
8072
8073   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
8074       vec_len (segments) * sizeof (ip6_address_t)
8075       + vec_len (tags) * sizeof (ip6_address_t));
8076
8077   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8078   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8079   mp->dst_mask_width = dst_mask_width;
8080   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8081   mp->n_segments = vec_len (segments);
8082   mp->n_tags = vec_len (tags);
8083   mp->is_add = is_del == 0;
8084   clib_memcpy (mp->segs_and_tags, segments,
8085                vec_len (segments) * sizeof (ip6_address_t));
8086   clib_memcpy (mp->segs_and_tags +
8087                vec_len (segments) * sizeof (ip6_address_t), tags,
8088                vec_len (tags) * sizeof (ip6_address_t));
8089
8090   mp->outer_vrf_id = ntohl (rx_table_id);
8091   mp->inner_vrf_id = ntohl (tx_table_id);
8092   memcpy (mp->name, name, vec_len (name));
8093   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8094
8095   vec_free (segments);
8096   vec_free (tags);
8097
8098   S;
8099   W;
8100   /* NOTREACHED */
8101 }
8102
8103 static int
8104 api_sr_policy_add_del (vat_main_t * vam)
8105 {
8106   unformat_input_t *input = vam->input;
8107   vl_api_sr_policy_add_del_t *mp;
8108   f64 timeout;
8109   int is_del = 0;
8110   u8 *name = 0;
8111   u8 *tunnel_name = 0;
8112   u8 **tunnel_names = 0;
8113
8114   int name_set = 0;
8115   int tunnel_set = 0;
8116   int j = 0;
8117   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8118   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8119
8120   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8121     {
8122       if (unformat (input, "del"))
8123         is_del = 1;
8124       else if (unformat (input, "name %s", &name))
8125         name_set = 1;
8126       else if (unformat (input, "tunnel %s", &tunnel_name))
8127         {
8128           if (tunnel_name)
8129             {
8130               vec_add1 (tunnel_names, tunnel_name);
8131               /* For serializer:
8132                  - length = #bytes to store in serial vector
8133                  - +1 = byte to store that length
8134                */
8135               tunnel_names_length += (vec_len (tunnel_name) + 1);
8136               tunnel_set = 1;
8137               tunnel_name = 0;
8138             }
8139         }
8140       else
8141         break;
8142     }
8143
8144   if (!name_set)
8145     {
8146       errmsg ("policy name required");
8147       return -99;
8148     }
8149
8150   if ((!tunnel_set) && (!is_del))
8151     {
8152       errmsg ("tunnel name required");
8153       return -99;
8154     }
8155
8156   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8157
8158
8159
8160   mp->is_add = !is_del;
8161
8162   memcpy (mp->name, name, vec_len (name));
8163   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8164   u8 *serial_orig = 0;
8165   vec_validate (serial_orig, tunnel_names_length);
8166   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8167   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8168
8169   for (j = 0; j < vec_len (tunnel_names); j++)
8170     {
8171       tun_name_len = vec_len (tunnel_names[j]);
8172       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8173       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8174       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8175       serial_orig += tun_name_len;      // Advance past the copy
8176     }
8177   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8178
8179   vec_free (tunnel_names);
8180   vec_free (tunnel_name);
8181
8182   S;
8183   W;
8184   /* NOTREACHED */
8185 }
8186
8187 static int
8188 api_sr_multicast_map_add_del (vat_main_t * vam)
8189 {
8190   unformat_input_t *input = vam->input;
8191   vl_api_sr_multicast_map_add_del_t *mp;
8192   f64 timeout;
8193   int is_del = 0;
8194   ip6_address_t multicast_address;
8195   u8 *policy_name = 0;
8196   int multicast_address_set = 0;
8197
8198   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8199     {
8200       if (unformat (input, "del"))
8201         is_del = 1;
8202       else
8203         if (unformat
8204             (input, "address %U", unformat_ip6_address, &multicast_address))
8205         multicast_address_set = 1;
8206       else if (unformat (input, "sr-policy %s", &policy_name))
8207         ;
8208       else
8209         break;
8210     }
8211
8212   if (!is_del && !policy_name)
8213     {
8214       errmsg ("sr-policy name required");
8215       return -99;
8216     }
8217
8218
8219   if (!multicast_address_set)
8220     {
8221       errmsg ("address required");
8222       return -99;
8223     }
8224
8225   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8226
8227   mp->is_add = !is_del;
8228   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8229   clib_memcpy (mp->multicast_address, &multicast_address,
8230                sizeof (mp->multicast_address));
8231
8232
8233   vec_free (policy_name);
8234
8235   S;
8236   W;
8237   /* NOTREACHED */
8238 }
8239
8240
8241 #define foreach_tcp_proto_field                 \
8242 _(src_port)                                     \
8243 _(dst_port)
8244
8245 #define foreach_udp_proto_field                 \
8246 _(src_port)                                     \
8247 _(dst_port)
8248
8249 #define foreach_ip4_proto_field                 \
8250 _(src_address)                                  \
8251 _(dst_address)                                  \
8252 _(tos)                                          \
8253 _(length)                                       \
8254 _(fragment_id)                                  \
8255 _(ttl)                                          \
8256 _(protocol)                                     \
8257 _(checksum)
8258
8259 uword
8260 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8261 {
8262   u8 **maskp = va_arg (*args, u8 **);
8263   u8 *mask = 0;
8264   u8 found_something = 0;
8265   tcp_header_t *tcp;
8266
8267 #define _(a) u8 a=0;
8268   foreach_tcp_proto_field;
8269 #undef _
8270
8271   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8272     {
8273       if (0);
8274 #define _(a) else if (unformat (input, #a)) a=1;
8275       foreach_tcp_proto_field
8276 #undef _
8277         else
8278         break;
8279     }
8280
8281 #define _(a) found_something += a;
8282   foreach_tcp_proto_field;
8283 #undef _
8284
8285   if (found_something == 0)
8286     return 0;
8287
8288   vec_validate (mask, sizeof (*tcp) - 1);
8289
8290   tcp = (tcp_header_t *) mask;
8291
8292 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8293   foreach_tcp_proto_field;
8294 #undef _
8295
8296   *maskp = mask;
8297   return 1;
8298 }
8299
8300 uword
8301 unformat_udp_mask (unformat_input_t * input, va_list * args)
8302 {
8303   u8 **maskp = va_arg (*args, u8 **);
8304   u8 *mask = 0;
8305   u8 found_something = 0;
8306   udp_header_t *udp;
8307
8308 #define _(a) u8 a=0;
8309   foreach_udp_proto_field;
8310 #undef _
8311
8312   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8313     {
8314       if (0);
8315 #define _(a) else if (unformat (input, #a)) a=1;
8316       foreach_udp_proto_field
8317 #undef _
8318         else
8319         break;
8320     }
8321
8322 #define _(a) found_something += a;
8323   foreach_udp_proto_field;
8324 #undef _
8325
8326   if (found_something == 0)
8327     return 0;
8328
8329   vec_validate (mask, sizeof (*udp) - 1);
8330
8331   udp = (udp_header_t *) mask;
8332
8333 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8334   foreach_udp_proto_field;
8335 #undef _
8336
8337   *maskp = mask;
8338   return 1;
8339 }
8340
8341 typedef struct
8342 {
8343   u16 src_port, dst_port;
8344 } tcpudp_header_t;
8345
8346 uword
8347 unformat_l4_mask (unformat_input_t * input, va_list * args)
8348 {
8349   u8 **maskp = va_arg (*args, u8 **);
8350   u16 src_port = 0, dst_port = 0;
8351   tcpudp_header_t *tcpudp;
8352
8353   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8354     {
8355       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8356         return 1;
8357       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8358         return 1;
8359       else if (unformat (input, "src_port"))
8360         src_port = 0xFFFF;
8361       else if (unformat (input, "dst_port"))
8362         dst_port = 0xFFFF;
8363       else
8364         return 0;
8365     }
8366
8367   if (!src_port && !dst_port)
8368     return 0;
8369
8370   u8 *mask = 0;
8371   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8372
8373   tcpudp = (tcpudp_header_t *) mask;
8374   tcpudp->src_port = src_port;
8375   tcpudp->dst_port = dst_port;
8376
8377   *maskp = mask;
8378
8379   return 1;
8380 }
8381
8382 uword
8383 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8384 {
8385   u8 **maskp = va_arg (*args, u8 **);
8386   u8 *mask = 0;
8387   u8 found_something = 0;
8388   ip4_header_t *ip;
8389
8390 #define _(a) u8 a=0;
8391   foreach_ip4_proto_field;
8392 #undef _
8393   u8 version = 0;
8394   u8 hdr_length = 0;
8395
8396
8397   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8398     {
8399       if (unformat (input, "version"))
8400         version = 1;
8401       else if (unformat (input, "hdr_length"))
8402         hdr_length = 1;
8403       else if (unformat (input, "src"))
8404         src_address = 1;
8405       else if (unformat (input, "dst"))
8406         dst_address = 1;
8407       else if (unformat (input, "proto"))
8408         protocol = 1;
8409
8410 #define _(a) else if (unformat (input, #a)) a=1;
8411       foreach_ip4_proto_field
8412 #undef _
8413         else
8414         break;
8415     }
8416
8417 #define _(a) found_something += a;
8418   foreach_ip4_proto_field;
8419 #undef _
8420
8421   if (found_something == 0)
8422     return 0;
8423
8424   vec_validate (mask, sizeof (*ip) - 1);
8425
8426   ip = (ip4_header_t *) mask;
8427
8428 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8429   foreach_ip4_proto_field;
8430 #undef _
8431
8432   ip->ip_version_and_header_length = 0;
8433
8434   if (version)
8435     ip->ip_version_and_header_length |= 0xF0;
8436
8437   if (hdr_length)
8438     ip->ip_version_and_header_length |= 0x0F;
8439
8440   *maskp = mask;
8441   return 1;
8442 }
8443
8444 #define foreach_ip6_proto_field                 \
8445 _(src_address)                                  \
8446 _(dst_address)                                  \
8447 _(payload_length)                               \
8448 _(hop_limit)                                    \
8449 _(protocol)
8450
8451 uword
8452 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8453 {
8454   u8 **maskp = va_arg (*args, u8 **);
8455   u8 *mask = 0;
8456   u8 found_something = 0;
8457   ip6_header_t *ip;
8458   u32 ip_version_traffic_class_and_flow_label;
8459
8460 #define _(a) u8 a=0;
8461   foreach_ip6_proto_field;
8462 #undef _
8463   u8 version = 0;
8464   u8 traffic_class = 0;
8465   u8 flow_label = 0;
8466
8467   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8468     {
8469       if (unformat (input, "version"))
8470         version = 1;
8471       else if (unformat (input, "traffic-class"))
8472         traffic_class = 1;
8473       else if (unformat (input, "flow-label"))
8474         flow_label = 1;
8475       else if (unformat (input, "src"))
8476         src_address = 1;
8477       else if (unformat (input, "dst"))
8478         dst_address = 1;
8479       else if (unformat (input, "proto"))
8480         protocol = 1;
8481
8482 #define _(a) else if (unformat (input, #a)) a=1;
8483       foreach_ip6_proto_field
8484 #undef _
8485         else
8486         break;
8487     }
8488
8489 #define _(a) found_something += a;
8490   foreach_ip6_proto_field;
8491 #undef _
8492
8493   if (found_something == 0)
8494     return 0;
8495
8496   vec_validate (mask, sizeof (*ip) - 1);
8497
8498   ip = (ip6_header_t *) mask;
8499
8500 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8501   foreach_ip6_proto_field;
8502 #undef _
8503
8504   ip_version_traffic_class_and_flow_label = 0;
8505
8506   if (version)
8507     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8508
8509   if (traffic_class)
8510     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8511
8512   if (flow_label)
8513     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8514
8515   ip->ip_version_traffic_class_and_flow_label =
8516     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8517
8518   *maskp = mask;
8519   return 1;
8520 }
8521
8522 uword
8523 unformat_l3_mask (unformat_input_t * input, va_list * args)
8524 {
8525   u8 **maskp = va_arg (*args, u8 **);
8526
8527   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8528     {
8529       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8530         return 1;
8531       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8532         return 1;
8533       else
8534         break;
8535     }
8536   return 0;
8537 }
8538
8539 uword
8540 unformat_l2_mask (unformat_input_t * input, va_list * args)
8541 {
8542   u8 **maskp = va_arg (*args, u8 **);
8543   u8 *mask = 0;
8544   u8 src = 0;
8545   u8 dst = 0;
8546   u8 proto = 0;
8547   u8 tag1 = 0;
8548   u8 tag2 = 0;
8549   u8 ignore_tag1 = 0;
8550   u8 ignore_tag2 = 0;
8551   u8 cos1 = 0;
8552   u8 cos2 = 0;
8553   u8 dot1q = 0;
8554   u8 dot1ad = 0;
8555   int len = 14;
8556
8557   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8558     {
8559       if (unformat (input, "src"))
8560         src = 1;
8561       else if (unformat (input, "dst"))
8562         dst = 1;
8563       else if (unformat (input, "proto"))
8564         proto = 1;
8565       else if (unformat (input, "tag1"))
8566         tag1 = 1;
8567       else if (unformat (input, "tag2"))
8568         tag2 = 1;
8569       else if (unformat (input, "ignore-tag1"))
8570         ignore_tag1 = 1;
8571       else if (unformat (input, "ignore-tag2"))
8572         ignore_tag2 = 1;
8573       else if (unformat (input, "cos1"))
8574         cos1 = 1;
8575       else if (unformat (input, "cos2"))
8576         cos2 = 1;
8577       else if (unformat (input, "dot1q"))
8578         dot1q = 1;
8579       else if (unformat (input, "dot1ad"))
8580         dot1ad = 1;
8581       else
8582         break;
8583     }
8584   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8585        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8586     return 0;
8587
8588   if (tag1 || ignore_tag1 || cos1 || dot1q)
8589     len = 18;
8590   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8591     len = 22;
8592
8593   vec_validate (mask, len - 1);
8594
8595   if (dst)
8596     memset (mask, 0xff, 6);
8597
8598   if (src)
8599     memset (mask + 6, 0xff, 6);
8600
8601   if (tag2 || dot1ad)
8602     {
8603       /* inner vlan tag */
8604       if (tag2)
8605         {
8606           mask[19] = 0xff;
8607           mask[18] = 0x0f;
8608         }
8609       if (cos2)
8610         mask[18] |= 0xe0;
8611       if (proto)
8612         mask[21] = mask[20] = 0xff;
8613       if (tag1)
8614         {
8615           mask[15] = 0xff;
8616           mask[14] = 0x0f;
8617         }
8618       if (cos1)
8619         mask[14] |= 0xe0;
8620       *maskp = mask;
8621       return 1;
8622     }
8623   if (tag1 | dot1q)
8624     {
8625       if (tag1)
8626         {
8627           mask[15] = 0xff;
8628           mask[14] = 0x0f;
8629         }
8630       if (cos1)
8631         mask[14] |= 0xe0;
8632       if (proto)
8633         mask[16] = mask[17] = 0xff;
8634
8635       *maskp = mask;
8636       return 1;
8637     }
8638   if (cos2)
8639     mask[18] |= 0xe0;
8640   if (cos1)
8641     mask[14] |= 0xe0;
8642   if (proto)
8643     mask[12] = mask[13] = 0xff;
8644
8645   *maskp = mask;
8646   return 1;
8647 }
8648
8649 uword
8650 unformat_classify_mask (unformat_input_t * input, va_list * args)
8651 {
8652   u8 **maskp = va_arg (*args, u8 **);
8653   u32 *skipp = va_arg (*args, u32 *);
8654   u32 *matchp = va_arg (*args, u32 *);
8655   u32 match;
8656   u8 *mask = 0;
8657   u8 *l2 = 0;
8658   u8 *l3 = 0;
8659   u8 *l4 = 0;
8660   int i;
8661
8662   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8663     {
8664       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8665         ;
8666       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8667         ;
8668       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8669         ;
8670       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8671         ;
8672       else
8673         break;
8674     }
8675
8676   if (l4 && !l3)
8677     {
8678       vec_free (mask);
8679       vec_free (l2);
8680       vec_free (l4);
8681       return 0;
8682     }
8683
8684   if (mask || l2 || l3 || l4)
8685     {
8686       if (l2 || l3 || l4)
8687         {
8688           /* "With a free Ethernet header in every package" */
8689           if (l2 == 0)
8690             vec_validate (l2, 13);
8691           mask = l2;
8692           if (vec_len (l3))
8693             {
8694               vec_append (mask, l3);
8695               vec_free (l3);
8696             }
8697           if (vec_len (l4))
8698             {
8699               vec_append (mask, l4);
8700               vec_free (l4);
8701             }
8702         }
8703
8704       /* Scan forward looking for the first significant mask octet */
8705       for (i = 0; i < vec_len (mask); i++)
8706         if (mask[i])
8707           break;
8708
8709       /* compute (skip, match) params */
8710       *skipp = i / sizeof (u32x4);
8711       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8712
8713       /* Pad mask to an even multiple of the vector size */
8714       while (vec_len (mask) % sizeof (u32x4))
8715         vec_add1 (mask, 0);
8716
8717       match = vec_len (mask) / sizeof (u32x4);
8718
8719       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8720         {
8721           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8722           if (*tmp || *(tmp + 1))
8723             break;
8724           match--;
8725         }
8726       if (match == 0)
8727         clib_warning ("BUG: match 0");
8728
8729       _vec_len (mask) = match * sizeof (u32x4);
8730
8731       *matchp = match;
8732       *maskp = mask;
8733
8734       return 1;
8735     }
8736
8737   return 0;
8738 }
8739
8740 #define foreach_l2_next                         \
8741 _(drop, DROP)                                   \
8742 _(ethernet, ETHERNET_INPUT)                     \
8743 _(ip4, IP4_INPUT)                               \
8744 _(ip6, IP6_INPUT)
8745
8746 uword
8747 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8748 {
8749   u32 *miss_next_indexp = va_arg (*args, u32 *);
8750   u32 next_index = 0;
8751   u32 tmp;
8752
8753 #define _(n,N) \
8754   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8755   foreach_l2_next;
8756 #undef _
8757
8758   if (unformat (input, "%d", &tmp))
8759     {
8760       next_index = tmp;
8761       goto out;
8762     }
8763
8764   return 0;
8765
8766 out:
8767   *miss_next_indexp = next_index;
8768   return 1;
8769 }
8770
8771 #define foreach_ip_next                         \
8772 _(drop, DROP)                                   \
8773 _(local, LOCAL)                                 \
8774 _(rewrite, REWRITE)
8775
8776 uword
8777 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8778 {
8779   u32 *miss_next_indexp = va_arg (*args, u32 *);
8780   u32 next_index = 0;
8781   u32 tmp;
8782
8783 #define _(n,N) \
8784   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8785   foreach_ip_next;
8786 #undef _
8787
8788   if (unformat (input, "%d", &tmp))
8789     {
8790       next_index = tmp;
8791       goto out;
8792     }
8793
8794   return 0;
8795
8796 out:
8797   *miss_next_indexp = next_index;
8798   return 1;
8799 }
8800
8801 #define foreach_acl_next                        \
8802 _(deny, DENY)
8803
8804 uword
8805 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8806 {
8807   u32 *miss_next_indexp = va_arg (*args, u32 *);
8808   u32 next_index = 0;
8809   u32 tmp;
8810
8811 #define _(n,N) \
8812   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8813   foreach_acl_next;
8814 #undef _
8815
8816   if (unformat (input, "permit"))
8817     {
8818       next_index = ~0;
8819       goto out;
8820     }
8821   else if (unformat (input, "%d", &tmp))
8822     {
8823       next_index = tmp;
8824       goto out;
8825     }
8826
8827   return 0;
8828
8829 out:
8830   *miss_next_indexp = next_index;
8831   return 1;
8832 }
8833
8834 uword
8835 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8836 {
8837   u32 *r = va_arg (*args, u32 *);
8838
8839   if (unformat (input, "conform-color"))
8840     *r = POLICE_CONFORM;
8841   else if (unformat (input, "exceed-color"))
8842     *r = POLICE_EXCEED;
8843   else
8844     return 0;
8845
8846   return 1;
8847 }
8848
8849 static int
8850 api_classify_add_del_table (vat_main_t * vam)
8851 {
8852   unformat_input_t *i = vam->input;
8853   vl_api_classify_add_del_table_t *mp;
8854
8855   u32 nbuckets = 2;
8856   u32 skip = ~0;
8857   u32 match = ~0;
8858   int is_add = 1;
8859   int del_chain = 0;
8860   u32 table_index = ~0;
8861   u32 next_table_index = ~0;
8862   u32 miss_next_index = ~0;
8863   u32 memory_size = 32 << 20;
8864   u8 *mask = 0;
8865   f64 timeout;
8866   u32 current_data_flag = 0;
8867   int current_data_offset = 0;
8868
8869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8870     {
8871       if (unformat (i, "del"))
8872         is_add = 0;
8873       else if (unformat (i, "del-chain"))
8874         {
8875           is_add = 0;
8876           del_chain = 1;
8877         }
8878       else if (unformat (i, "buckets %d", &nbuckets))
8879         ;
8880       else if (unformat (i, "memory_size %d", &memory_size))
8881         ;
8882       else if (unformat (i, "skip %d", &skip))
8883         ;
8884       else if (unformat (i, "match %d", &match))
8885         ;
8886       else if (unformat (i, "table %d", &table_index))
8887         ;
8888       else if (unformat (i, "mask %U", unformat_classify_mask,
8889                          &mask, &skip, &match))
8890         ;
8891       else if (unformat (i, "next-table %d", &next_table_index))
8892         ;
8893       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8894                          &miss_next_index))
8895         ;
8896       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8897                          &miss_next_index))
8898         ;
8899       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8900                          &miss_next_index))
8901         ;
8902       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8903         ;
8904       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8905         ;
8906       else
8907         break;
8908     }
8909
8910   if (is_add && mask == 0)
8911     {
8912       errmsg ("Mask required");
8913       return -99;
8914     }
8915
8916   if (is_add && skip == ~0)
8917     {
8918       errmsg ("skip count required");
8919       return -99;
8920     }
8921
8922   if (is_add && match == ~0)
8923     {
8924       errmsg ("match count required");
8925       return -99;
8926     }
8927
8928   if (!is_add && table_index == ~0)
8929     {
8930       errmsg ("table index required for delete");
8931       return -99;
8932     }
8933
8934   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8935
8936   mp->is_add = is_add;
8937   mp->del_chain = del_chain;
8938   mp->table_index = ntohl (table_index);
8939   mp->nbuckets = ntohl (nbuckets);
8940   mp->memory_size = ntohl (memory_size);
8941   mp->skip_n_vectors = ntohl (skip);
8942   mp->match_n_vectors = ntohl (match);
8943   mp->next_table_index = ntohl (next_table_index);
8944   mp->miss_next_index = ntohl (miss_next_index);
8945   mp->current_data_flag = ntohl (current_data_flag);
8946   mp->current_data_offset = ntohl (current_data_offset);
8947   clib_memcpy (mp->mask, mask, vec_len (mask));
8948
8949   vec_free (mask);
8950
8951   S;
8952   W;
8953   /* NOTREACHED */
8954 }
8955
8956 uword
8957 unformat_l4_match (unformat_input_t * input, va_list * args)
8958 {
8959   u8 **matchp = va_arg (*args, u8 **);
8960
8961   u8 *proto_header = 0;
8962   int src_port = 0;
8963   int dst_port = 0;
8964
8965   tcpudp_header_t h;
8966
8967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8968     {
8969       if (unformat (input, "src_port %d", &src_port))
8970         ;
8971       else if (unformat (input, "dst_port %d", &dst_port))
8972         ;
8973       else
8974         return 0;
8975     }
8976
8977   h.src_port = clib_host_to_net_u16 (src_port);
8978   h.dst_port = clib_host_to_net_u16 (dst_port);
8979   vec_validate (proto_header, sizeof (h) - 1);
8980   memcpy (proto_header, &h, sizeof (h));
8981
8982   *matchp = proto_header;
8983
8984   return 1;
8985 }
8986
8987 uword
8988 unformat_ip4_match (unformat_input_t * input, va_list * args)
8989 {
8990   u8 **matchp = va_arg (*args, u8 **);
8991   u8 *match = 0;
8992   ip4_header_t *ip;
8993   int version = 0;
8994   u32 version_val;
8995   int hdr_length = 0;
8996   u32 hdr_length_val;
8997   int src = 0, dst = 0;
8998   ip4_address_t src_val, dst_val;
8999   int proto = 0;
9000   u32 proto_val;
9001   int tos = 0;
9002   u32 tos_val;
9003   int length = 0;
9004   u32 length_val;
9005   int fragment_id = 0;
9006   u32 fragment_id_val;
9007   int ttl = 0;
9008   int ttl_val;
9009   int checksum = 0;
9010   u32 checksum_val;
9011
9012   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9013     {
9014       if (unformat (input, "version %d", &version_val))
9015         version = 1;
9016       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9017         hdr_length = 1;
9018       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9019         src = 1;
9020       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9021         dst = 1;
9022       else if (unformat (input, "proto %d", &proto_val))
9023         proto = 1;
9024       else if (unformat (input, "tos %d", &tos_val))
9025         tos = 1;
9026       else if (unformat (input, "length %d", &length_val))
9027         length = 1;
9028       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9029         fragment_id = 1;
9030       else if (unformat (input, "ttl %d", &ttl_val))
9031         ttl = 1;
9032       else if (unformat (input, "checksum %d", &checksum_val))
9033         checksum = 1;
9034       else
9035         break;
9036     }
9037
9038   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9039       + ttl + checksum == 0)
9040     return 0;
9041
9042   /*
9043    * Aligned because we use the real comparison functions
9044    */
9045   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9046
9047   ip = (ip4_header_t *) match;
9048
9049   /* These are realistically matched in practice */
9050   if (src)
9051     ip->src_address.as_u32 = src_val.as_u32;
9052
9053   if (dst)
9054     ip->dst_address.as_u32 = dst_val.as_u32;
9055
9056   if (proto)
9057     ip->protocol = proto_val;
9058
9059
9060   /* These are not, but they're included for completeness */
9061   if (version)
9062     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9063
9064   if (hdr_length)
9065     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9066
9067   if (tos)
9068     ip->tos = tos_val;
9069
9070   if (length)
9071     ip->length = clib_host_to_net_u16 (length_val);
9072
9073   if (ttl)
9074     ip->ttl = ttl_val;
9075
9076   if (checksum)
9077     ip->checksum = clib_host_to_net_u16 (checksum_val);
9078
9079   *matchp = match;
9080   return 1;
9081 }
9082
9083 uword
9084 unformat_ip6_match (unformat_input_t * input, va_list * args)
9085 {
9086   u8 **matchp = va_arg (*args, u8 **);
9087   u8 *match = 0;
9088   ip6_header_t *ip;
9089   int version = 0;
9090   u32 version_val;
9091   u8 traffic_class = 0;
9092   u32 traffic_class_val = 0;
9093   u8 flow_label = 0;
9094   u8 flow_label_val;
9095   int src = 0, dst = 0;
9096   ip6_address_t src_val, dst_val;
9097   int proto = 0;
9098   u32 proto_val;
9099   int payload_length = 0;
9100   u32 payload_length_val;
9101   int hop_limit = 0;
9102   int hop_limit_val;
9103   u32 ip_version_traffic_class_and_flow_label;
9104
9105   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9106     {
9107       if (unformat (input, "version %d", &version_val))
9108         version = 1;
9109       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9110         traffic_class = 1;
9111       else if (unformat (input, "flow_label %d", &flow_label_val))
9112         flow_label = 1;
9113       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9114         src = 1;
9115       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9116         dst = 1;
9117       else if (unformat (input, "proto %d", &proto_val))
9118         proto = 1;
9119       else if (unformat (input, "payload_length %d", &payload_length_val))
9120         payload_length = 1;
9121       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9122         hop_limit = 1;
9123       else
9124         break;
9125     }
9126
9127   if (version + traffic_class + flow_label + src + dst + proto +
9128       payload_length + hop_limit == 0)
9129     return 0;
9130
9131   /*
9132    * Aligned because we use the real comparison functions
9133    */
9134   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9135
9136   ip = (ip6_header_t *) match;
9137
9138   if (src)
9139     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9140
9141   if (dst)
9142     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9143
9144   if (proto)
9145     ip->protocol = proto_val;
9146
9147   ip_version_traffic_class_and_flow_label = 0;
9148
9149   if (version)
9150     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9151
9152   if (traffic_class)
9153     ip_version_traffic_class_and_flow_label |=
9154       (traffic_class_val & 0xFF) << 20;
9155
9156   if (flow_label)
9157     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9158
9159   ip->ip_version_traffic_class_and_flow_label =
9160     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9161
9162   if (payload_length)
9163     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9164
9165   if (hop_limit)
9166     ip->hop_limit = hop_limit_val;
9167
9168   *matchp = match;
9169   return 1;
9170 }
9171
9172 uword
9173 unformat_l3_match (unformat_input_t * input, va_list * args)
9174 {
9175   u8 **matchp = va_arg (*args, u8 **);
9176
9177   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9178     {
9179       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9180         return 1;
9181       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9182         return 1;
9183       else
9184         break;
9185     }
9186   return 0;
9187 }
9188
9189 uword
9190 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9191 {
9192   u8 *tagp = va_arg (*args, u8 *);
9193   u32 tag;
9194
9195   if (unformat (input, "%d", &tag))
9196     {
9197       tagp[0] = (tag >> 8) & 0x0F;
9198       tagp[1] = tag & 0xFF;
9199       return 1;
9200     }
9201
9202   return 0;
9203 }
9204
9205 uword
9206 unformat_l2_match (unformat_input_t * input, va_list * args)
9207 {
9208   u8 **matchp = va_arg (*args, u8 **);
9209   u8 *match = 0;
9210   u8 src = 0;
9211   u8 src_val[6];
9212   u8 dst = 0;
9213   u8 dst_val[6];
9214   u8 proto = 0;
9215   u16 proto_val;
9216   u8 tag1 = 0;
9217   u8 tag1_val[2];
9218   u8 tag2 = 0;
9219   u8 tag2_val[2];
9220   int len = 14;
9221   u8 ignore_tag1 = 0;
9222   u8 ignore_tag2 = 0;
9223   u8 cos1 = 0;
9224   u8 cos2 = 0;
9225   u32 cos1_val = 0;
9226   u32 cos2_val = 0;
9227
9228   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9229     {
9230       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9231         src = 1;
9232       else
9233         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9234         dst = 1;
9235       else if (unformat (input, "proto %U",
9236                          unformat_ethernet_type_host_byte_order, &proto_val))
9237         proto = 1;
9238       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9239         tag1 = 1;
9240       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9241         tag2 = 1;
9242       else if (unformat (input, "ignore-tag1"))
9243         ignore_tag1 = 1;
9244       else if (unformat (input, "ignore-tag2"))
9245         ignore_tag2 = 1;
9246       else if (unformat (input, "cos1 %d", &cos1_val))
9247         cos1 = 1;
9248       else if (unformat (input, "cos2 %d", &cos2_val))
9249         cos2 = 1;
9250       else
9251         break;
9252     }
9253   if ((src + dst + proto + tag1 + tag2 +
9254        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9255     return 0;
9256
9257   if (tag1 || ignore_tag1 || cos1)
9258     len = 18;
9259   if (tag2 || ignore_tag2 || cos2)
9260     len = 22;
9261
9262   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9263
9264   if (dst)
9265     clib_memcpy (match, dst_val, 6);
9266
9267   if (src)
9268     clib_memcpy (match + 6, src_val, 6);
9269
9270   if (tag2)
9271     {
9272       /* inner vlan tag */
9273       match[19] = tag2_val[1];
9274       match[18] = tag2_val[0];
9275       if (cos2)
9276         match[18] |= (cos2_val & 0x7) << 5;
9277       if (proto)
9278         {
9279           match[21] = proto_val & 0xff;
9280           match[20] = proto_val >> 8;
9281         }
9282       if (tag1)
9283         {
9284           match[15] = tag1_val[1];
9285           match[14] = tag1_val[0];
9286         }
9287       if (cos1)
9288         match[14] |= (cos1_val & 0x7) << 5;
9289       *matchp = match;
9290       return 1;
9291     }
9292   if (tag1)
9293     {
9294       match[15] = tag1_val[1];
9295       match[14] = tag1_val[0];
9296       if (proto)
9297         {
9298           match[17] = proto_val & 0xff;
9299           match[16] = proto_val >> 8;
9300         }
9301       if (cos1)
9302         match[14] |= (cos1_val & 0x7) << 5;
9303
9304       *matchp = match;
9305       return 1;
9306     }
9307   if (cos2)
9308     match[18] |= (cos2_val & 0x7) << 5;
9309   if (cos1)
9310     match[14] |= (cos1_val & 0x7) << 5;
9311   if (proto)
9312     {
9313       match[13] = proto_val & 0xff;
9314       match[12] = proto_val >> 8;
9315     }
9316
9317   *matchp = match;
9318   return 1;
9319 }
9320
9321
9322 uword
9323 unformat_classify_match (unformat_input_t * input, va_list * args)
9324 {
9325   u8 **matchp = va_arg (*args, u8 **);
9326   u32 skip_n_vectors = va_arg (*args, u32);
9327   u32 match_n_vectors = va_arg (*args, u32);
9328
9329   u8 *match = 0;
9330   u8 *l2 = 0;
9331   u8 *l3 = 0;
9332   u8 *l4 = 0;
9333
9334   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9335     {
9336       if (unformat (input, "hex %U", unformat_hex_string, &match))
9337         ;
9338       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9339         ;
9340       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9341         ;
9342       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9343         ;
9344       else
9345         break;
9346     }
9347
9348   if (l4 && !l3)
9349     {
9350       vec_free (match);
9351       vec_free (l2);
9352       vec_free (l4);
9353       return 0;
9354     }
9355
9356   if (match || l2 || l3 || l4)
9357     {
9358       if (l2 || l3 || l4)
9359         {
9360           /* "Win a free Ethernet header in every packet" */
9361           if (l2 == 0)
9362             vec_validate_aligned (l2, 13, sizeof (u32x4));
9363           match = l2;
9364           if (vec_len (l3))
9365             {
9366               vec_append_aligned (match, l3, sizeof (u32x4));
9367               vec_free (l3);
9368             }
9369           if (vec_len (l4))
9370             {
9371               vec_append_aligned (match, l4, sizeof (u32x4));
9372               vec_free (l4);
9373             }
9374         }
9375
9376       /* Make sure the vector is big enough even if key is all 0's */
9377       vec_validate_aligned
9378         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9379          sizeof (u32x4));
9380
9381       /* Set size, include skipped vectors */
9382       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9383
9384       *matchp = match;
9385
9386       return 1;
9387     }
9388
9389   return 0;
9390 }
9391
9392 static int
9393 api_classify_add_del_session (vat_main_t * vam)
9394 {
9395   unformat_input_t *i = vam->input;
9396   vl_api_classify_add_del_session_t *mp;
9397   int is_add = 1;
9398   u32 table_index = ~0;
9399   u32 hit_next_index = ~0;
9400   u32 opaque_index = ~0;
9401   u8 *match = 0;
9402   i32 advance = 0;
9403   f64 timeout;
9404   u32 skip_n_vectors = 0;
9405   u32 match_n_vectors = 0;
9406   u32 action = 0;
9407   u32 metadata = 0;
9408
9409   /*
9410    * Warning: you have to supply skip_n and match_n
9411    * because the API client cant simply look at the classify
9412    * table object.
9413    */
9414
9415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9416     {
9417       if (unformat (i, "del"))
9418         is_add = 0;
9419       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9420                          &hit_next_index))
9421         ;
9422       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9423                          &hit_next_index))
9424         ;
9425       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9426                          &hit_next_index))
9427         ;
9428       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9429         ;
9430       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9431         ;
9432       else if (unformat (i, "opaque-index %d", &opaque_index))
9433         ;
9434       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9435         ;
9436       else if (unformat (i, "match_n %d", &match_n_vectors))
9437         ;
9438       else if (unformat (i, "match %U", unformat_classify_match,
9439                          &match, skip_n_vectors, match_n_vectors))
9440         ;
9441       else if (unformat (i, "advance %d", &advance))
9442         ;
9443       else if (unformat (i, "table-index %d", &table_index))
9444         ;
9445       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9446         action = 1;
9447       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9448         action = 2;
9449       else if (unformat (i, "action %d", &action))
9450         ;
9451       else if (unformat (i, "metadata %d", &metadata))
9452         ;
9453       else
9454         break;
9455     }
9456
9457   if (table_index == ~0)
9458     {
9459       errmsg ("Table index required");
9460       return -99;
9461     }
9462
9463   if (is_add && match == 0)
9464     {
9465       errmsg ("Match value required");
9466       return -99;
9467     }
9468
9469   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9470
9471   mp->is_add = is_add;
9472   mp->table_index = ntohl (table_index);
9473   mp->hit_next_index = ntohl (hit_next_index);
9474   mp->opaque_index = ntohl (opaque_index);
9475   mp->advance = ntohl (advance);
9476   mp->action = action;
9477   mp->metadata = ntohl (metadata);
9478   clib_memcpy (mp->match, match, vec_len (match));
9479   vec_free (match);
9480
9481   S;
9482   W;
9483   /* NOTREACHED */
9484 }
9485
9486 static int
9487 api_classify_set_interface_ip_table (vat_main_t * vam)
9488 {
9489   unformat_input_t *i = vam->input;
9490   vl_api_classify_set_interface_ip_table_t *mp;
9491   f64 timeout;
9492   u32 sw_if_index;
9493   int sw_if_index_set;
9494   u32 table_index = ~0;
9495   u8 is_ipv6 = 0;
9496
9497   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9498     {
9499       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9500         sw_if_index_set = 1;
9501       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9502         sw_if_index_set = 1;
9503       else if (unformat (i, "table %d", &table_index))
9504         ;
9505       else
9506         {
9507           clib_warning ("parse error '%U'", format_unformat_error, i);
9508           return -99;
9509         }
9510     }
9511
9512   if (sw_if_index_set == 0)
9513     {
9514       errmsg ("missing interface name or sw_if_index");
9515       return -99;
9516     }
9517
9518
9519   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9520
9521   mp->sw_if_index = ntohl (sw_if_index);
9522   mp->table_index = ntohl (table_index);
9523   mp->is_ipv6 = is_ipv6;
9524
9525   S;
9526   W;
9527   /* NOTREACHED */
9528   return 0;
9529 }
9530
9531 static int
9532 api_classify_set_interface_l2_tables (vat_main_t * vam)
9533 {
9534   unformat_input_t *i = vam->input;
9535   vl_api_classify_set_interface_l2_tables_t *mp;
9536   f64 timeout;
9537   u32 sw_if_index;
9538   int sw_if_index_set;
9539   u32 ip4_table_index = ~0;
9540   u32 ip6_table_index = ~0;
9541   u32 other_table_index = ~0;
9542   u32 is_input = 1;
9543
9544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9545     {
9546       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9547         sw_if_index_set = 1;
9548       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9549         sw_if_index_set = 1;
9550       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9551         ;
9552       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9553         ;
9554       else if (unformat (i, "other-table %d", &other_table_index))
9555         ;
9556       else if (unformat (i, "is-input %d", &is_input))
9557         ;
9558       else
9559         {
9560           clib_warning ("parse error '%U'", format_unformat_error, i);
9561           return -99;
9562         }
9563     }
9564
9565   if (sw_if_index_set == 0)
9566     {
9567       errmsg ("missing interface name or sw_if_index");
9568       return -99;
9569     }
9570
9571
9572   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9573
9574   mp->sw_if_index = ntohl (sw_if_index);
9575   mp->ip4_table_index = ntohl (ip4_table_index);
9576   mp->ip6_table_index = ntohl (ip6_table_index);
9577   mp->other_table_index = ntohl (other_table_index);
9578   mp->is_input = (u8) is_input;
9579
9580   S;
9581   W;
9582   /* NOTREACHED */
9583   return 0;
9584 }
9585
9586 static int
9587 api_set_ipfix_exporter (vat_main_t * vam)
9588 {
9589   unformat_input_t *i = vam->input;
9590   vl_api_set_ipfix_exporter_t *mp;
9591   ip4_address_t collector_address;
9592   u8 collector_address_set = 0;
9593   u32 collector_port = ~0;
9594   ip4_address_t src_address;
9595   u8 src_address_set = 0;
9596   u32 vrf_id = ~0;
9597   u32 path_mtu = ~0;
9598   u32 template_interval = ~0;
9599   u8 udp_checksum = 0;
9600   f64 timeout;
9601
9602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9603     {
9604       if (unformat (i, "collector_address %U", unformat_ip4_address,
9605                     &collector_address))
9606         collector_address_set = 1;
9607       else if (unformat (i, "collector_port %d", &collector_port))
9608         ;
9609       else if (unformat (i, "src_address %U", unformat_ip4_address,
9610                          &src_address))
9611         src_address_set = 1;
9612       else if (unformat (i, "vrf_id %d", &vrf_id))
9613         ;
9614       else if (unformat (i, "path_mtu %d", &path_mtu))
9615         ;
9616       else if (unformat (i, "template_interval %d", &template_interval))
9617         ;
9618       else if (unformat (i, "udp_checksum"))
9619         udp_checksum = 1;
9620       else
9621         break;
9622     }
9623
9624   if (collector_address_set == 0)
9625     {
9626       errmsg ("collector_address required");
9627       return -99;
9628     }
9629
9630   if (src_address_set == 0)
9631     {
9632       errmsg ("src_address required");
9633       return -99;
9634     }
9635
9636   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9637
9638   memcpy (mp->collector_address, collector_address.data,
9639           sizeof (collector_address.data));
9640   mp->collector_port = htons ((u16) collector_port);
9641   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9642   mp->vrf_id = htonl (vrf_id);
9643   mp->path_mtu = htonl (path_mtu);
9644   mp->template_interval = htonl (template_interval);
9645   mp->udp_checksum = udp_checksum;
9646
9647   S;
9648   W;
9649   /* NOTREACHED */
9650 }
9651
9652 static int
9653 api_set_ipfix_classify_stream (vat_main_t * vam)
9654 {
9655   unformat_input_t *i = vam->input;
9656   vl_api_set_ipfix_classify_stream_t *mp;
9657   u32 domain_id = 0;
9658   u32 src_port = UDP_DST_PORT_ipfix;
9659   f64 timeout;
9660
9661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9662     {
9663       if (unformat (i, "domain %d", &domain_id))
9664         ;
9665       else if (unformat (i, "src_port %d", &src_port))
9666         ;
9667       else
9668         {
9669           errmsg ("unknown input `%U'", format_unformat_error, i);
9670           return -99;
9671         }
9672     }
9673
9674   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9675
9676   mp->domain_id = htonl (domain_id);
9677   mp->src_port = htons ((u16) src_port);
9678
9679   S;
9680   W;
9681   /* NOTREACHED */
9682 }
9683
9684 static int
9685 api_ipfix_classify_table_add_del (vat_main_t * vam)
9686 {
9687   unformat_input_t *i = vam->input;
9688   vl_api_ipfix_classify_table_add_del_t *mp;
9689   int is_add = -1;
9690   u32 classify_table_index = ~0;
9691   u8 ip_version = 0;
9692   u8 transport_protocol = 255;
9693   f64 timeout;
9694
9695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9696     {
9697       if (unformat (i, "add"))
9698         is_add = 1;
9699       else if (unformat (i, "del"))
9700         is_add = 0;
9701       else if (unformat (i, "table %d", &classify_table_index))
9702         ;
9703       else if (unformat (i, "ip4"))
9704         ip_version = 4;
9705       else if (unformat (i, "ip6"))
9706         ip_version = 6;
9707       else if (unformat (i, "tcp"))
9708         transport_protocol = 6;
9709       else if (unformat (i, "udp"))
9710         transport_protocol = 17;
9711       else
9712         {
9713           errmsg ("unknown input `%U'", format_unformat_error, i);
9714           return -99;
9715         }
9716     }
9717
9718   if (is_add == -1)
9719     {
9720       errmsg ("expecting: add|del");
9721       return -99;
9722     }
9723   if (classify_table_index == ~0)
9724     {
9725       errmsg ("classifier table not specified");
9726       return -99;
9727     }
9728   if (ip_version == 0)
9729     {
9730       errmsg ("IP version not specified");
9731       return -99;
9732     }
9733
9734   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9735
9736   mp->is_add = is_add;
9737   mp->table_id = htonl (classify_table_index);
9738   mp->ip_version = ip_version;
9739   mp->transport_protocol = transport_protocol;
9740
9741   S;
9742   W;
9743   /* NOTREACHED */
9744 }
9745
9746 static int
9747 api_get_node_index (vat_main_t * vam)
9748 {
9749   unformat_input_t *i = vam->input;
9750   vl_api_get_node_index_t *mp;
9751   f64 timeout;
9752   u8 *name = 0;
9753
9754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9755     {
9756       if (unformat (i, "node %s", &name))
9757         ;
9758       else
9759         break;
9760     }
9761   if (name == 0)
9762     {
9763       errmsg ("node name required");
9764       return -99;
9765     }
9766   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9767     {
9768       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9769       return -99;
9770     }
9771
9772   M (GET_NODE_INDEX, get_node_index);
9773   clib_memcpy (mp->node_name, name, vec_len (name));
9774   vec_free (name);
9775
9776   S;
9777   W;
9778   /* NOTREACHED */
9779   return 0;
9780 }
9781
9782 static int
9783 api_get_next_index (vat_main_t * vam)
9784 {
9785   unformat_input_t *i = vam->input;
9786   vl_api_get_next_index_t *mp;
9787   f64 timeout;
9788   u8 *node_name = 0, *next_node_name = 0;
9789
9790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9791     {
9792       if (unformat (i, "node-name %s", &node_name))
9793         ;
9794       else if (unformat (i, "next-node-name %s", &next_node_name))
9795         break;
9796     }
9797
9798   if (node_name == 0)
9799     {
9800       errmsg ("node name required");
9801       return -99;
9802     }
9803   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9804     {
9805       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9806       return -99;
9807     }
9808
9809   if (next_node_name == 0)
9810     {
9811       errmsg ("next node name required");
9812       return -99;
9813     }
9814   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9815     {
9816       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9817       return -99;
9818     }
9819
9820   M (GET_NEXT_INDEX, get_next_index);
9821   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9822   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9823   vec_free (node_name);
9824   vec_free (next_node_name);
9825
9826   S;
9827   W;
9828   /* NOTREACHED */
9829   return 0;
9830 }
9831
9832 static int
9833 api_add_node_next (vat_main_t * vam)
9834 {
9835   unformat_input_t *i = vam->input;
9836   vl_api_add_node_next_t *mp;
9837   f64 timeout;
9838   u8 *name = 0;
9839   u8 *next = 0;
9840
9841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9842     {
9843       if (unformat (i, "node %s", &name))
9844         ;
9845       else if (unformat (i, "next %s", &next))
9846         ;
9847       else
9848         break;
9849     }
9850   if (name == 0)
9851     {
9852       errmsg ("node name required");
9853       return -99;
9854     }
9855   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9856     {
9857       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9858       return -99;
9859     }
9860   if (next == 0)
9861     {
9862       errmsg ("next node required");
9863       return -99;
9864     }
9865   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9866     {
9867       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9868       return -99;
9869     }
9870
9871   M (ADD_NODE_NEXT, add_node_next);
9872   clib_memcpy (mp->node_name, name, vec_len (name));
9873   clib_memcpy (mp->next_name, next, vec_len (next));
9874   vec_free (name);
9875   vec_free (next);
9876
9877   S;
9878   W;
9879   /* NOTREACHED */
9880   return 0;
9881 }
9882
9883 static int
9884 api_l2tpv3_create_tunnel (vat_main_t * vam)
9885 {
9886   unformat_input_t *i = vam->input;
9887   ip6_address_t client_address, our_address;
9888   int client_address_set = 0;
9889   int our_address_set = 0;
9890   u32 local_session_id = 0;
9891   u32 remote_session_id = 0;
9892   u64 local_cookie = 0;
9893   u64 remote_cookie = 0;
9894   u8 l2_sublayer_present = 0;
9895   vl_api_l2tpv3_create_tunnel_t *mp;
9896   f64 timeout;
9897
9898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9899     {
9900       if (unformat (i, "client_address %U", unformat_ip6_address,
9901                     &client_address))
9902         client_address_set = 1;
9903       else if (unformat (i, "our_address %U", unformat_ip6_address,
9904                          &our_address))
9905         our_address_set = 1;
9906       else if (unformat (i, "local_session_id %d", &local_session_id))
9907         ;
9908       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9909         ;
9910       else if (unformat (i, "local_cookie %lld", &local_cookie))
9911         ;
9912       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9913         ;
9914       else if (unformat (i, "l2-sublayer-present"))
9915         l2_sublayer_present = 1;
9916       else
9917         break;
9918     }
9919
9920   if (client_address_set == 0)
9921     {
9922       errmsg ("client_address required");
9923       return -99;
9924     }
9925
9926   if (our_address_set == 0)
9927     {
9928       errmsg ("our_address required");
9929       return -99;
9930     }
9931
9932   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9933
9934   clib_memcpy (mp->client_address, client_address.as_u8,
9935                sizeof (mp->client_address));
9936
9937   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9938
9939   mp->local_session_id = ntohl (local_session_id);
9940   mp->remote_session_id = ntohl (remote_session_id);
9941   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9942   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9943   mp->l2_sublayer_present = l2_sublayer_present;
9944   mp->is_ipv6 = 1;
9945
9946   S;
9947   W;
9948   /* NOTREACHED */
9949   return 0;
9950 }
9951
9952 static int
9953 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9954 {
9955   unformat_input_t *i = vam->input;
9956   u32 sw_if_index;
9957   u8 sw_if_index_set = 0;
9958   u64 new_local_cookie = 0;
9959   u64 new_remote_cookie = 0;
9960   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9961   f64 timeout;
9962
9963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9964     {
9965       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9966         sw_if_index_set = 1;
9967       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9968         sw_if_index_set = 1;
9969       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9970         ;
9971       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9972         ;
9973       else
9974         break;
9975     }
9976
9977   if (sw_if_index_set == 0)
9978     {
9979       errmsg ("missing interface name or sw_if_index");
9980       return -99;
9981     }
9982
9983   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9984
9985   mp->sw_if_index = ntohl (sw_if_index);
9986   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9987   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9988
9989   S;
9990   W;
9991   /* NOTREACHED */
9992   return 0;
9993 }
9994
9995 static int
9996 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9997 {
9998   unformat_input_t *i = vam->input;
9999   vl_api_l2tpv3_interface_enable_disable_t *mp;
10000   f64 timeout;
10001   u32 sw_if_index;
10002   u8 sw_if_index_set = 0;
10003   u8 enable_disable = 1;
10004
10005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10006     {
10007       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10008         sw_if_index_set = 1;
10009       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10010         sw_if_index_set = 1;
10011       else if (unformat (i, "enable"))
10012         enable_disable = 1;
10013       else if (unformat (i, "disable"))
10014         enable_disable = 0;
10015       else
10016         break;
10017     }
10018
10019   if (sw_if_index_set == 0)
10020     {
10021       errmsg ("missing interface name or sw_if_index");
10022       return -99;
10023     }
10024
10025   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
10026
10027   mp->sw_if_index = ntohl (sw_if_index);
10028   mp->enable_disable = enable_disable;
10029
10030   S;
10031   W;
10032   /* NOTREACHED */
10033   return 0;
10034 }
10035
10036 static int
10037 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10038 {
10039   unformat_input_t *i = vam->input;
10040   vl_api_l2tpv3_set_lookup_key_t *mp;
10041   f64 timeout;
10042   u8 key = ~0;
10043
10044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10045     {
10046       if (unformat (i, "lookup_v6_src"))
10047         key = L2T_LOOKUP_SRC_ADDRESS;
10048       else if (unformat (i, "lookup_v6_dst"))
10049         key = L2T_LOOKUP_DST_ADDRESS;
10050       else if (unformat (i, "lookup_session_id"))
10051         key = L2T_LOOKUP_SESSION_ID;
10052       else
10053         break;
10054     }
10055
10056   if (key == (u8) ~ 0)
10057     {
10058       errmsg ("l2tp session lookup key unset");
10059       return -99;
10060     }
10061
10062   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
10063
10064   mp->key = key;
10065
10066   S;
10067   W;
10068   /* NOTREACHED */
10069   return 0;
10070 }
10071
10072 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10073   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10074 {
10075   vat_main_t *vam = &vat_main;
10076
10077   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
10078          format_ip6_address, mp->our_address,
10079          format_ip6_address, mp->client_address,
10080          clib_net_to_host_u32 (mp->sw_if_index));
10081
10082   print (vam->ofp,
10083          "   local cookies %016llx %016llx remote cookie %016llx",
10084          clib_net_to_host_u64 (mp->local_cookie[0]),
10085          clib_net_to_host_u64 (mp->local_cookie[1]),
10086          clib_net_to_host_u64 (mp->remote_cookie));
10087
10088   print (vam->ofp, "   local session-id %d remote session-id %d",
10089          clib_net_to_host_u32 (mp->local_session_id),
10090          clib_net_to_host_u32 (mp->remote_session_id));
10091
10092   print (vam->ofp, "   l2 specific sublayer %s\n",
10093          mp->l2_sublayer_present ? "preset" : "absent");
10094
10095 }
10096
10097 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10098   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10099 {
10100   vat_main_t *vam = &vat_main;
10101   vat_json_node_t *node = NULL;
10102   struct in6_addr addr;
10103
10104   if (VAT_JSON_ARRAY != vam->json_tree.type)
10105     {
10106       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10107       vat_json_init_array (&vam->json_tree);
10108     }
10109   node = vat_json_array_add (&vam->json_tree);
10110
10111   vat_json_init_object (node);
10112
10113   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10114   vat_json_object_add_ip6 (node, "our_address", addr);
10115   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10116   vat_json_object_add_ip6 (node, "client_address", addr);
10117
10118   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10119   vat_json_init_array (lc);
10120   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10121   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10122   vat_json_object_add_uint (node, "remote_cookie",
10123                             clib_net_to_host_u64 (mp->remote_cookie));
10124
10125   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10126   vat_json_object_add_uint (node, "local_session_id",
10127                             clib_net_to_host_u32 (mp->local_session_id));
10128   vat_json_object_add_uint (node, "remote_session_id",
10129                             clib_net_to_host_u32 (mp->remote_session_id));
10130   vat_json_object_add_string_copy (node, "l2_sublayer",
10131                                    mp->l2_sublayer_present ? (u8 *) "present"
10132                                    : (u8 *) "absent");
10133 }
10134
10135 static int
10136 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10137 {
10138   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10139   f64 timeout;
10140
10141   /* Get list of l2tpv3-tunnel interfaces */
10142   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10143   S;
10144
10145   /* Use a control ping for synchronization */
10146   {
10147     vl_api_control_ping_t *mp;
10148     M (CONTROL_PING, control_ping);
10149     S;
10150   }
10151   W;
10152 }
10153
10154
10155 static void vl_api_sw_interface_tap_details_t_handler
10156   (vl_api_sw_interface_tap_details_t * mp)
10157 {
10158   vat_main_t *vam = &vat_main;
10159
10160   print (vam->ofp, "%-16s %d",
10161          mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10162 }
10163
10164 static void vl_api_sw_interface_tap_details_t_handler_json
10165   (vl_api_sw_interface_tap_details_t * mp)
10166 {
10167   vat_main_t *vam = &vat_main;
10168   vat_json_node_t *node = NULL;
10169
10170   if (VAT_JSON_ARRAY != vam->json_tree.type)
10171     {
10172       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10173       vat_json_init_array (&vam->json_tree);
10174     }
10175   node = vat_json_array_add (&vam->json_tree);
10176
10177   vat_json_init_object (node);
10178   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10179   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10180 }
10181
10182 static int
10183 api_sw_interface_tap_dump (vat_main_t * vam)
10184 {
10185   vl_api_sw_interface_tap_dump_t *mp;
10186   f64 timeout;
10187
10188   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
10189   /* Get list of tap interfaces */
10190   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10191   S;
10192
10193   /* Use a control ping for synchronization */
10194   {
10195     vl_api_control_ping_t *mp;
10196     M (CONTROL_PING, control_ping);
10197     S;
10198   }
10199   W;
10200 }
10201
10202 static uword unformat_vxlan_decap_next
10203   (unformat_input_t * input, va_list * args)
10204 {
10205   u32 *result = va_arg (*args, u32 *);
10206   u32 tmp;
10207
10208   if (unformat (input, "l2"))
10209     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10210   else if (unformat (input, "%d", &tmp))
10211     *result = tmp;
10212   else
10213     return 0;
10214   return 1;
10215 }
10216
10217 static int
10218 api_vxlan_add_del_tunnel (vat_main_t * vam)
10219 {
10220   unformat_input_t *line_input = vam->input;
10221   vl_api_vxlan_add_del_tunnel_t *mp;
10222   f64 timeout;
10223   ip46_address_t src, dst;
10224   u8 is_add = 1;
10225   u8 ipv4_set = 0, ipv6_set = 0;
10226   u8 src_set = 0;
10227   u8 dst_set = 0;
10228   u8 grp_set = 0;
10229   u32 mcast_sw_if_index = ~0;
10230   u32 encap_vrf_id = 0;
10231   u32 decap_next_index = ~0;
10232   u32 vni = 0;
10233
10234   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10235   memset (&src, 0, sizeof src);
10236   memset (&dst, 0, sizeof dst);
10237
10238   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10239     {
10240       if (unformat (line_input, "del"))
10241         is_add = 0;
10242       else
10243         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10244         {
10245           ipv4_set = 1;
10246           src_set = 1;
10247         }
10248       else
10249         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10250         {
10251           ipv4_set = 1;
10252           dst_set = 1;
10253         }
10254       else
10255         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10256         {
10257           ipv6_set = 1;
10258           src_set = 1;
10259         }
10260       else
10261         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10262         {
10263           ipv6_set = 1;
10264           dst_set = 1;
10265         }
10266       else if (unformat (line_input, "group %U %U",
10267                          unformat_ip4_address, &dst.ip4,
10268                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10269         {
10270           grp_set = dst_set = 1;
10271           ipv4_set = 1;
10272         }
10273       else if (unformat (line_input, "group %U",
10274                          unformat_ip4_address, &dst.ip4))
10275         {
10276           grp_set = dst_set = 1;
10277           ipv4_set = 1;
10278         }
10279       else if (unformat (line_input, "group %U %U",
10280                          unformat_ip6_address, &dst.ip6,
10281                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10282         {
10283           grp_set = dst_set = 1;
10284           ipv6_set = 1;
10285         }
10286       else if (unformat (line_input, "group %U",
10287                          unformat_ip6_address, &dst.ip6))
10288         {
10289           grp_set = dst_set = 1;
10290           ipv6_set = 1;
10291         }
10292       else
10293         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10294         ;
10295       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10296         ;
10297       else if (unformat (line_input, "decap-next %U",
10298                          unformat_vxlan_decap_next, &decap_next_index))
10299         ;
10300       else if (unformat (line_input, "vni %d", &vni))
10301         ;
10302       else
10303         {
10304           errmsg ("parse error '%U'", format_unformat_error, line_input);
10305           return -99;
10306         }
10307     }
10308
10309   if (src_set == 0)
10310     {
10311       errmsg ("tunnel src address not specified");
10312       return -99;
10313     }
10314   if (dst_set == 0)
10315     {
10316       errmsg ("tunnel dst address not specified");
10317       return -99;
10318     }
10319
10320   if (grp_set && !ip46_address_is_multicast (&dst))
10321     {
10322       errmsg ("tunnel group address not multicast");
10323       return -99;
10324     }
10325   if (grp_set && mcast_sw_if_index == ~0)
10326     {
10327       errmsg ("tunnel nonexistent multicast device");
10328       return -99;
10329     }
10330   if (grp_set == 0 && ip46_address_is_multicast (&dst))
10331     {
10332       errmsg ("tunnel dst address must be unicast");
10333       return -99;
10334     }
10335
10336
10337   if (ipv4_set && ipv6_set)
10338     {
10339       errmsg ("both IPv4 and IPv6 addresses specified");
10340       return -99;
10341     }
10342
10343   if ((vni == 0) || (vni >> 24))
10344     {
10345       errmsg ("vni not specified or out of range");
10346       return -99;
10347     }
10348
10349   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10350
10351   if (ipv6_set)
10352     {
10353       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10354       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10355     }
10356   else
10357     {
10358       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10359       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10360     }
10361   mp->encap_vrf_id = ntohl (encap_vrf_id);
10362   mp->decap_next_index = ntohl (decap_next_index);
10363   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10364   mp->vni = ntohl (vni);
10365   mp->is_add = is_add;
10366   mp->is_ipv6 = ipv6_set;
10367
10368   S;
10369   W;
10370   /* NOTREACHED */
10371   return 0;
10372 }
10373
10374 static void vl_api_vxlan_tunnel_details_t_handler
10375   (vl_api_vxlan_tunnel_details_t * mp)
10376 {
10377   vat_main_t *vam = &vat_main;
10378   ip46_address_t src, dst;
10379
10380   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10381   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10382
10383   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
10384          ntohl (mp->sw_if_index),
10385          format_ip46_address, &src, IP46_TYPE_ANY,
10386          format_ip46_address, &dst, IP46_TYPE_ANY,
10387          ntohl (mp->encap_vrf_id),
10388          ntohl (mp->decap_next_index), ntohl (mp->vni),
10389          ntohl (mp->mcast_sw_if_index));
10390 }
10391
10392 static void vl_api_vxlan_tunnel_details_t_handler_json
10393   (vl_api_vxlan_tunnel_details_t * mp)
10394 {
10395   vat_main_t *vam = &vat_main;
10396   vat_json_node_t *node = NULL;
10397
10398   if (VAT_JSON_ARRAY != vam->json_tree.type)
10399     {
10400       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10401       vat_json_init_array (&vam->json_tree);
10402     }
10403   node = vat_json_array_add (&vam->json_tree);
10404
10405   vat_json_init_object (node);
10406   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10407   if (mp->is_ipv6)
10408     {
10409       struct in6_addr ip6;
10410
10411       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10412       vat_json_object_add_ip6 (node, "src_address", ip6);
10413       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10414       vat_json_object_add_ip6 (node, "dst_address", ip6);
10415     }
10416   else
10417     {
10418       struct in_addr ip4;
10419
10420       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10421       vat_json_object_add_ip4 (node, "src_address", ip4);
10422       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10423       vat_json_object_add_ip4 (node, "dst_address", ip4);
10424     }
10425   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10426   vat_json_object_add_uint (node, "decap_next_index",
10427                             ntohl (mp->decap_next_index));
10428   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10429   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10430   vat_json_object_add_uint (node, "mcast_sw_if_index",
10431                             ntohl (mp->mcast_sw_if_index));
10432 }
10433
10434 static int
10435 api_vxlan_tunnel_dump (vat_main_t * vam)
10436 {
10437   unformat_input_t *i = vam->input;
10438   vl_api_vxlan_tunnel_dump_t *mp;
10439   f64 timeout;
10440   u32 sw_if_index;
10441   u8 sw_if_index_set = 0;
10442
10443   /* Parse args required to build the message */
10444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10445     {
10446       if (unformat (i, "sw_if_index %d", &sw_if_index))
10447         sw_if_index_set = 1;
10448       else
10449         break;
10450     }
10451
10452   if (sw_if_index_set == 0)
10453     {
10454       sw_if_index = ~0;
10455     }
10456
10457   if (!vam->json_output)
10458     {
10459       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
10460              "sw_if_index", "src_address", "dst_address",
10461              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
10462     }
10463
10464   /* Get list of vxlan-tunnel interfaces */
10465   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10466
10467   mp->sw_if_index = htonl (sw_if_index);
10468
10469   S;
10470
10471   /* Use a control ping for synchronization */
10472   {
10473     vl_api_control_ping_t *mp;
10474     M (CONTROL_PING, control_ping);
10475     S;
10476   }
10477   W;
10478 }
10479
10480 static int
10481 api_gre_add_del_tunnel (vat_main_t * vam)
10482 {
10483   unformat_input_t *line_input = vam->input;
10484   vl_api_gre_add_del_tunnel_t *mp;
10485   f64 timeout;
10486   ip4_address_t src4, dst4;
10487   u8 is_add = 1;
10488   u8 teb = 0;
10489   u8 src_set = 0;
10490   u8 dst_set = 0;
10491   u32 outer_fib_id = 0;
10492
10493   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10494     {
10495       if (unformat (line_input, "del"))
10496         is_add = 0;
10497       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10498         src_set = 1;
10499       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10500         dst_set = 1;
10501       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10502         ;
10503       else if (unformat (line_input, "teb"))
10504         teb = 1;
10505       else
10506         {
10507           errmsg ("parse error '%U'", format_unformat_error, line_input);
10508           return -99;
10509         }
10510     }
10511
10512   if (src_set == 0)
10513     {
10514       errmsg ("tunnel src address not specified");
10515       return -99;
10516     }
10517   if (dst_set == 0)
10518     {
10519       errmsg ("tunnel dst address not specified");
10520       return -99;
10521     }
10522
10523
10524   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10525
10526   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10527   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10528   mp->outer_fib_id = ntohl (outer_fib_id);
10529   mp->is_add = is_add;
10530   mp->teb = teb;
10531
10532   S;
10533   W;
10534   /* NOTREACHED */
10535   return 0;
10536 }
10537
10538 static void vl_api_gre_tunnel_details_t_handler
10539   (vl_api_gre_tunnel_details_t * mp)
10540 {
10541   vat_main_t *vam = &vat_main;
10542
10543   print (vam->ofp, "%11d%15U%15U%6d%14d",
10544          ntohl (mp->sw_if_index),
10545          format_ip4_address, &mp->src_address,
10546          format_ip4_address, &mp->dst_address,
10547          mp->teb, ntohl (mp->outer_fib_id));
10548 }
10549
10550 static void vl_api_gre_tunnel_details_t_handler_json
10551   (vl_api_gre_tunnel_details_t * mp)
10552 {
10553   vat_main_t *vam = &vat_main;
10554   vat_json_node_t *node = NULL;
10555   struct in_addr ip4;
10556
10557   if (VAT_JSON_ARRAY != vam->json_tree.type)
10558     {
10559       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10560       vat_json_init_array (&vam->json_tree);
10561     }
10562   node = vat_json_array_add (&vam->json_tree);
10563
10564   vat_json_init_object (node);
10565   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10566   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10567   vat_json_object_add_ip4 (node, "src_address", ip4);
10568   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10569   vat_json_object_add_ip4 (node, "dst_address", ip4);
10570   vat_json_object_add_uint (node, "teb", mp->teb);
10571   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10572 }
10573
10574 static int
10575 api_gre_tunnel_dump (vat_main_t * vam)
10576 {
10577   unformat_input_t *i = vam->input;
10578   vl_api_gre_tunnel_dump_t *mp;
10579   f64 timeout;
10580   u32 sw_if_index;
10581   u8 sw_if_index_set = 0;
10582
10583   /* Parse args required to build the message */
10584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10585     {
10586       if (unformat (i, "sw_if_index %d", &sw_if_index))
10587         sw_if_index_set = 1;
10588       else
10589         break;
10590     }
10591
10592   if (sw_if_index_set == 0)
10593     {
10594       sw_if_index = ~0;
10595     }
10596
10597   if (!vam->json_output)
10598     {
10599       print (vam->ofp, "%11s%15s%15s%6s%14s",
10600              "sw_if_index", "src_address", "dst_address", "teb",
10601              "outer_fib_id");
10602     }
10603
10604   /* Get list of gre-tunnel interfaces */
10605   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10606
10607   mp->sw_if_index = htonl (sw_if_index);
10608
10609   S;
10610
10611   /* Use a control ping for synchronization */
10612   {
10613     vl_api_control_ping_t *mp;
10614     M (CONTROL_PING, control_ping);
10615     S;
10616   }
10617   W;
10618 }
10619
10620 static int
10621 api_l2_fib_clear_table (vat_main_t * vam)
10622 {
10623 //  unformat_input_t * i = vam->input;
10624   vl_api_l2_fib_clear_table_t *mp;
10625   f64 timeout;
10626
10627   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10628
10629   S;
10630   W;
10631   /* NOTREACHED */
10632   return 0;
10633 }
10634
10635 static int
10636 api_l2_interface_efp_filter (vat_main_t * vam)
10637 {
10638   unformat_input_t *i = vam->input;
10639   vl_api_l2_interface_efp_filter_t *mp;
10640   f64 timeout;
10641   u32 sw_if_index;
10642   u8 enable = 1;
10643   u8 sw_if_index_set = 0;
10644
10645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10646     {
10647       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10648         sw_if_index_set = 1;
10649       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10650         sw_if_index_set = 1;
10651       else if (unformat (i, "enable"))
10652         enable = 1;
10653       else if (unformat (i, "disable"))
10654         enable = 0;
10655       else
10656         {
10657           clib_warning ("parse error '%U'", format_unformat_error, i);
10658           return -99;
10659         }
10660     }
10661
10662   if (sw_if_index_set == 0)
10663     {
10664       errmsg ("missing sw_if_index");
10665       return -99;
10666     }
10667
10668   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10669
10670   mp->sw_if_index = ntohl (sw_if_index);
10671   mp->enable_disable = enable;
10672
10673   S;
10674   W;
10675   /* NOTREACHED */
10676   return 0;
10677 }
10678
10679 #define foreach_vtr_op                          \
10680 _("disable",  L2_VTR_DISABLED)                  \
10681 _("push-1",  L2_VTR_PUSH_1)                     \
10682 _("push-2",  L2_VTR_PUSH_2)                     \
10683 _("pop-1",  L2_VTR_POP_1)                       \
10684 _("pop-2",  L2_VTR_POP_2)                       \
10685 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10686 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10687 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10688 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10689
10690 static int
10691 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10692 {
10693   unformat_input_t *i = vam->input;
10694   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10695   f64 timeout;
10696   u32 sw_if_index;
10697   u8 sw_if_index_set = 0;
10698   u8 vtr_op_set = 0;
10699   u32 vtr_op = 0;
10700   u32 push_dot1q = 1;
10701   u32 tag1 = ~0;
10702   u32 tag2 = ~0;
10703
10704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10705     {
10706       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10707         sw_if_index_set = 1;
10708       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10709         sw_if_index_set = 1;
10710       else if (unformat (i, "vtr_op %d", &vtr_op))
10711         vtr_op_set = 1;
10712 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10713       foreach_vtr_op
10714 #undef _
10715         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10716         ;
10717       else if (unformat (i, "tag1 %d", &tag1))
10718         ;
10719       else if (unformat (i, "tag2 %d", &tag2))
10720         ;
10721       else
10722         {
10723           clib_warning ("parse error '%U'", format_unformat_error, i);
10724           return -99;
10725         }
10726     }
10727
10728   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10729     {
10730       errmsg ("missing vtr operation or sw_if_index");
10731       return -99;
10732     }
10733
10734   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10735     mp->sw_if_index = ntohl (sw_if_index);
10736   mp->vtr_op = ntohl (vtr_op);
10737   mp->push_dot1q = ntohl (push_dot1q);
10738   mp->tag1 = ntohl (tag1);
10739   mp->tag2 = ntohl (tag2);
10740
10741   S;
10742   W;
10743   /* NOTREACHED */
10744   return 0;
10745 }
10746
10747 static int
10748 api_create_vhost_user_if (vat_main_t * vam)
10749 {
10750   unformat_input_t *i = vam->input;
10751   vl_api_create_vhost_user_if_t *mp;
10752   f64 timeout;
10753   u8 *file_name;
10754   u8 is_server = 0;
10755   u8 file_name_set = 0;
10756   u32 custom_dev_instance = ~0;
10757   u8 hwaddr[6];
10758   u8 use_custom_mac = 0;
10759   u8 *tag = 0;
10760
10761   /* Shut up coverity */
10762   memset (hwaddr, 0, sizeof (hwaddr));
10763
10764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10765     {
10766       if (unformat (i, "socket %s", &file_name))
10767         {
10768           file_name_set = 1;
10769         }
10770       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10771         ;
10772       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10773         use_custom_mac = 1;
10774       else if (unformat (i, "server"))
10775         is_server = 1;
10776       else if (unformat (i, "tag %s", &tag))
10777         ;
10778       else
10779         break;
10780     }
10781
10782   if (file_name_set == 0)
10783     {
10784       errmsg ("missing socket file name");
10785       return -99;
10786     }
10787
10788   if (vec_len (file_name) > 255)
10789     {
10790       errmsg ("socket file name too long");
10791       return -99;
10792     }
10793   vec_add1 (file_name, 0);
10794
10795   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10796
10797   mp->is_server = is_server;
10798   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10799   vec_free (file_name);
10800   if (custom_dev_instance != ~0)
10801     {
10802       mp->renumber = 1;
10803       mp->custom_dev_instance = ntohl (custom_dev_instance);
10804     }
10805   mp->use_custom_mac = use_custom_mac;
10806   clib_memcpy (mp->mac_address, hwaddr, 6);
10807   if (tag)
10808     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10809   vec_free (tag);
10810
10811   S;
10812   W;
10813   /* NOTREACHED */
10814   return 0;
10815 }
10816
10817 static int
10818 api_modify_vhost_user_if (vat_main_t * vam)
10819 {
10820   unformat_input_t *i = vam->input;
10821   vl_api_modify_vhost_user_if_t *mp;
10822   f64 timeout;
10823   u8 *file_name;
10824   u8 is_server = 0;
10825   u8 file_name_set = 0;
10826   u32 custom_dev_instance = ~0;
10827   u8 sw_if_index_set = 0;
10828   u32 sw_if_index = (u32) ~ 0;
10829
10830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10831     {
10832       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10833         sw_if_index_set = 1;
10834       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10835         sw_if_index_set = 1;
10836       else if (unformat (i, "socket %s", &file_name))
10837         {
10838           file_name_set = 1;
10839         }
10840       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10841         ;
10842       else if (unformat (i, "server"))
10843         is_server = 1;
10844       else
10845         break;
10846     }
10847
10848   if (sw_if_index_set == 0)
10849     {
10850       errmsg ("missing sw_if_index or interface name");
10851       return -99;
10852     }
10853
10854   if (file_name_set == 0)
10855     {
10856       errmsg ("missing socket file name");
10857       return -99;
10858     }
10859
10860   if (vec_len (file_name) > 255)
10861     {
10862       errmsg ("socket file name too long");
10863       return -99;
10864     }
10865   vec_add1 (file_name, 0);
10866
10867   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10868
10869   mp->sw_if_index = ntohl (sw_if_index);
10870   mp->is_server = is_server;
10871   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10872   vec_free (file_name);
10873   if (custom_dev_instance != ~0)
10874     {
10875       mp->renumber = 1;
10876       mp->custom_dev_instance = ntohl (custom_dev_instance);
10877     }
10878
10879   S;
10880   W;
10881   /* NOTREACHED */
10882   return 0;
10883 }
10884
10885 static int
10886 api_delete_vhost_user_if (vat_main_t * vam)
10887 {
10888   unformat_input_t *i = vam->input;
10889   vl_api_delete_vhost_user_if_t *mp;
10890   f64 timeout;
10891   u32 sw_if_index = ~0;
10892   u8 sw_if_index_set = 0;
10893
10894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10895     {
10896       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10897         sw_if_index_set = 1;
10898       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10899         sw_if_index_set = 1;
10900       else
10901         break;
10902     }
10903
10904   if (sw_if_index_set == 0)
10905     {
10906       errmsg ("missing sw_if_index or interface name");
10907       return -99;
10908     }
10909
10910
10911   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10912
10913   mp->sw_if_index = ntohl (sw_if_index);
10914
10915   S;
10916   W;
10917   /* NOTREACHED */
10918   return 0;
10919 }
10920
10921 static void vl_api_sw_interface_vhost_user_details_t_handler
10922   (vl_api_sw_interface_vhost_user_details_t * mp)
10923 {
10924   vat_main_t *vam = &vat_main;
10925
10926   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
10927          (char *) mp->interface_name,
10928          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10929          clib_net_to_host_u64 (mp->features), mp->is_server,
10930          ntohl (mp->num_regions), (char *) mp->sock_filename);
10931   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
10932 }
10933
10934 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10935   (vl_api_sw_interface_vhost_user_details_t * mp)
10936 {
10937   vat_main_t *vam = &vat_main;
10938   vat_json_node_t *node = NULL;
10939
10940   if (VAT_JSON_ARRAY != vam->json_tree.type)
10941     {
10942       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10943       vat_json_init_array (&vam->json_tree);
10944     }
10945   node = vat_json_array_add (&vam->json_tree);
10946
10947   vat_json_init_object (node);
10948   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10949   vat_json_object_add_string_copy (node, "interface_name",
10950                                    mp->interface_name);
10951   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10952                             ntohl (mp->virtio_net_hdr_sz));
10953   vat_json_object_add_uint (node, "features",
10954                             clib_net_to_host_u64 (mp->features));
10955   vat_json_object_add_uint (node, "is_server", mp->is_server);
10956   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10957   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10958   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10959 }
10960
10961 static int
10962 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10963 {
10964   vl_api_sw_interface_vhost_user_dump_t *mp;
10965   f64 timeout;
10966   print (vam->ofp,
10967          "Interface name           idx hdr_sz features server regions filename");
10968
10969   /* Get list of vhost-user interfaces */
10970   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10971   S;
10972
10973   /* Use a control ping for synchronization */
10974   {
10975     vl_api_control_ping_t *mp;
10976     M (CONTROL_PING, control_ping);
10977     S;
10978   }
10979   W;
10980 }
10981
10982 static int
10983 api_show_version (vat_main_t * vam)
10984 {
10985   vl_api_show_version_t *mp;
10986   f64 timeout;
10987
10988   M (SHOW_VERSION, show_version);
10989
10990   S;
10991   W;
10992   /* NOTREACHED */
10993   return 0;
10994 }
10995
10996
10997 static int
10998 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10999 {
11000   unformat_input_t *line_input = vam->input;
11001   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11002   f64 timeout;
11003   ip4_address_t local4, remote4;
11004   ip6_address_t local6, remote6;
11005   u8 is_add = 1;
11006   u8 ipv4_set = 0, ipv6_set = 0;
11007   u8 local_set = 0;
11008   u8 remote_set = 0;
11009   u32 encap_vrf_id = 0;
11010   u32 decap_vrf_id = 0;
11011   u8 protocol = ~0;
11012   u32 vni;
11013   u8 vni_set = 0;
11014
11015   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11016     {
11017       if (unformat (line_input, "del"))
11018         is_add = 0;
11019       else if (unformat (line_input, "local %U",
11020                          unformat_ip4_address, &local4))
11021         {
11022           local_set = 1;
11023           ipv4_set = 1;
11024         }
11025       else if (unformat (line_input, "remote %U",
11026                          unformat_ip4_address, &remote4))
11027         {
11028           remote_set = 1;
11029           ipv4_set = 1;
11030         }
11031       else if (unformat (line_input, "local %U",
11032                          unformat_ip6_address, &local6))
11033         {
11034           local_set = 1;
11035           ipv6_set = 1;
11036         }
11037       else if (unformat (line_input, "remote %U",
11038                          unformat_ip6_address, &remote6))
11039         {
11040           remote_set = 1;
11041           ipv6_set = 1;
11042         }
11043       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11044         ;
11045       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11046         ;
11047       else if (unformat (line_input, "vni %d", &vni))
11048         vni_set = 1;
11049       else if (unformat (line_input, "next-ip4"))
11050         protocol = 1;
11051       else if (unformat (line_input, "next-ip6"))
11052         protocol = 2;
11053       else if (unformat (line_input, "next-ethernet"))
11054         protocol = 3;
11055       else if (unformat (line_input, "next-nsh"))
11056         protocol = 4;
11057       else
11058         {
11059           errmsg ("parse error '%U'", format_unformat_error, line_input);
11060           return -99;
11061         }
11062     }
11063
11064   if (local_set == 0)
11065     {
11066       errmsg ("tunnel local address not specified");
11067       return -99;
11068     }
11069   if (remote_set == 0)
11070     {
11071       errmsg ("tunnel remote address not specified");
11072       return -99;
11073     }
11074   if (ipv4_set && ipv6_set)
11075     {
11076       errmsg ("both IPv4 and IPv6 addresses specified");
11077       return -99;
11078     }
11079
11080   if (vni_set == 0)
11081     {
11082       errmsg ("vni not specified");
11083       return -99;
11084     }
11085
11086   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
11087
11088
11089   if (ipv6_set)
11090     {
11091       clib_memcpy (&mp->local, &local6, sizeof (local6));
11092       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11093     }
11094   else
11095     {
11096       clib_memcpy (&mp->local, &local4, sizeof (local4));
11097       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11098     }
11099
11100   mp->encap_vrf_id = ntohl (encap_vrf_id);
11101   mp->decap_vrf_id = ntohl (decap_vrf_id);
11102   mp->protocol = protocol;
11103   mp->vni = ntohl (vni);
11104   mp->is_add = is_add;
11105   mp->is_ipv6 = ipv6_set;
11106
11107   S;
11108   W;
11109   /* NOTREACHED */
11110   return 0;
11111 }
11112
11113 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11114   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11115 {
11116   vat_main_t *vam = &vat_main;
11117
11118   print (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d",
11119          ntohl (mp->sw_if_index),
11120          format_ip46_address, &(mp->local[0]),
11121          format_ip46_address, &(mp->remote[0]),
11122          ntohl (mp->vni),
11123          ntohl (mp->protocol),
11124          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11125 }
11126
11127 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11128   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11129 {
11130   vat_main_t *vam = &vat_main;
11131   vat_json_node_t *node = NULL;
11132   struct in_addr ip4;
11133   struct in6_addr ip6;
11134
11135   if (VAT_JSON_ARRAY != vam->json_tree.type)
11136     {
11137       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11138       vat_json_init_array (&vam->json_tree);
11139     }
11140   node = vat_json_array_add (&vam->json_tree);
11141
11142   vat_json_init_object (node);
11143   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11144   if (mp->is_ipv6)
11145     {
11146       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11147       vat_json_object_add_ip6 (node, "local", ip6);
11148       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11149       vat_json_object_add_ip6 (node, "remote", ip6);
11150     }
11151   else
11152     {
11153       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11154       vat_json_object_add_ip4 (node, "local", ip4);
11155       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11156       vat_json_object_add_ip4 (node, "remote", ip4);
11157     }
11158   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11159   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11160   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11161   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11162   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11163 }
11164
11165 static int
11166 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11167 {
11168   unformat_input_t *i = vam->input;
11169   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11170   f64 timeout;
11171   u32 sw_if_index;
11172   u8 sw_if_index_set = 0;
11173
11174   /* Parse args required to build the message */
11175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11176     {
11177       if (unformat (i, "sw_if_index %d", &sw_if_index))
11178         sw_if_index_set = 1;
11179       else
11180         break;
11181     }
11182
11183   if (sw_if_index_set == 0)
11184     {
11185       sw_if_index = ~0;
11186     }
11187
11188   if (!vam->json_output)
11189     {
11190       print (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s",
11191              "sw_if_index", "local", "remote", "vni",
11192              "protocol", "encap_vrf_id", "decap_vrf_id");
11193     }
11194
11195   /* Get list of vxlan-tunnel interfaces */
11196   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11197
11198   mp->sw_if_index = htonl (sw_if_index);
11199
11200   S;
11201
11202   /* Use a control ping for synchronization */
11203   {
11204     vl_api_control_ping_t *mp;
11205     M (CONTROL_PING, control_ping);
11206     S;
11207   }
11208   W;
11209 }
11210
11211 u8 *
11212 format_l2_fib_mac_address (u8 * s, va_list * args)
11213 {
11214   u8 *a = va_arg (*args, u8 *);
11215
11216   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11217                  a[2], a[3], a[4], a[5], a[6], a[7]);
11218 }
11219
11220 static void vl_api_l2_fib_table_entry_t_handler
11221   (vl_api_l2_fib_table_entry_t * mp)
11222 {
11223   vat_main_t *vam = &vat_main;
11224
11225   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11226          "       %d       %d     %d",
11227          ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11228          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11229          mp->bvi_mac);
11230 }
11231
11232 static void vl_api_l2_fib_table_entry_t_handler_json
11233   (vl_api_l2_fib_table_entry_t * mp)
11234 {
11235   vat_main_t *vam = &vat_main;
11236   vat_json_node_t *node = NULL;
11237
11238   if (VAT_JSON_ARRAY != vam->json_tree.type)
11239     {
11240       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11241       vat_json_init_array (&vam->json_tree);
11242     }
11243   node = vat_json_array_add (&vam->json_tree);
11244
11245   vat_json_init_object (node);
11246   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11247   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11248   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11249   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11250   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11251   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11252 }
11253
11254 static int
11255 api_l2_fib_table_dump (vat_main_t * vam)
11256 {
11257   unformat_input_t *i = vam->input;
11258   vl_api_l2_fib_table_dump_t *mp;
11259   f64 timeout;
11260   u32 bd_id;
11261   u8 bd_id_set = 0;
11262
11263   /* Parse args required to build the message */
11264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11265     {
11266       if (unformat (i, "bd_id %d", &bd_id))
11267         bd_id_set = 1;
11268       else
11269         break;
11270     }
11271
11272   if (bd_id_set == 0)
11273     {
11274       errmsg ("missing bridge domain");
11275       return -99;
11276     }
11277
11278   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
11279
11280   /* Get list of l2 fib entries */
11281   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11282
11283   mp->bd_id = ntohl (bd_id);
11284   S;
11285
11286   /* Use a control ping for synchronization */
11287   {
11288     vl_api_control_ping_t *mp;
11289     M (CONTROL_PING, control_ping);
11290     S;
11291   }
11292   W;
11293 }
11294
11295
11296 static int
11297 api_interface_name_renumber (vat_main_t * vam)
11298 {
11299   unformat_input_t *line_input = vam->input;
11300   vl_api_interface_name_renumber_t *mp;
11301   u32 sw_if_index = ~0;
11302   f64 timeout;
11303   u32 new_show_dev_instance = ~0;
11304
11305   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11306     {
11307       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
11308                     &sw_if_index))
11309         ;
11310       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11311         ;
11312       else if (unformat (line_input, "new_show_dev_instance %d",
11313                          &new_show_dev_instance))
11314         ;
11315       else
11316         break;
11317     }
11318
11319   if (sw_if_index == ~0)
11320     {
11321       errmsg ("missing interface name or sw_if_index");
11322       return -99;
11323     }
11324
11325   if (new_show_dev_instance == ~0)
11326     {
11327       errmsg ("missing new_show_dev_instance");
11328       return -99;
11329     }
11330
11331   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11332
11333   mp->sw_if_index = ntohl (sw_if_index);
11334   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11335
11336   S;
11337   W;
11338 }
11339
11340 static int
11341 api_want_ip4_arp_events (vat_main_t * vam)
11342 {
11343   unformat_input_t *line_input = vam->input;
11344   vl_api_want_ip4_arp_events_t *mp;
11345   f64 timeout;
11346   ip4_address_t address;
11347   int address_set = 0;
11348   u32 enable_disable = 1;
11349
11350   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11351     {
11352       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11353         address_set = 1;
11354       else if (unformat (line_input, "del"))
11355         enable_disable = 0;
11356       else
11357         break;
11358     }
11359
11360   if (address_set == 0)
11361     {
11362       errmsg ("missing addresses");
11363       return -99;
11364     }
11365
11366   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11367   mp->enable_disable = enable_disable;
11368   mp->pid = getpid ();
11369   mp->address = address.as_u32;
11370
11371   S;
11372   W;
11373 }
11374
11375 static int
11376 api_want_ip6_nd_events (vat_main_t * vam)
11377 {
11378   unformat_input_t *line_input = vam->input;
11379   vl_api_want_ip6_nd_events_t *mp;
11380   f64 timeout;
11381   ip6_address_t address;
11382   int address_set = 0;
11383   u32 enable_disable = 1;
11384
11385   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11386     {
11387       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11388         address_set = 1;
11389       else if (unformat (line_input, "del"))
11390         enable_disable = 0;
11391       else
11392         break;
11393     }
11394
11395   if (address_set == 0)
11396     {
11397       errmsg ("missing addresses");
11398       return -99;
11399     }
11400
11401   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11402   mp->enable_disable = enable_disable;
11403   mp->pid = getpid ();
11404   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11405
11406   S;
11407   W;
11408 }
11409
11410 static int
11411 api_input_acl_set_interface (vat_main_t * vam)
11412 {
11413   unformat_input_t *i = vam->input;
11414   vl_api_input_acl_set_interface_t *mp;
11415   f64 timeout;
11416   u32 sw_if_index;
11417   int sw_if_index_set;
11418   u32 ip4_table_index = ~0;
11419   u32 ip6_table_index = ~0;
11420   u32 l2_table_index = ~0;
11421   u8 is_add = 1;
11422
11423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11424     {
11425       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11426         sw_if_index_set = 1;
11427       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11428         sw_if_index_set = 1;
11429       else if (unformat (i, "del"))
11430         is_add = 0;
11431       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11432         ;
11433       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11434         ;
11435       else if (unformat (i, "l2-table %d", &l2_table_index))
11436         ;
11437       else
11438         {
11439           clib_warning ("parse error '%U'", format_unformat_error, i);
11440           return -99;
11441         }
11442     }
11443
11444   if (sw_if_index_set == 0)
11445     {
11446       errmsg ("missing interface name or sw_if_index");
11447       return -99;
11448     }
11449
11450   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11451
11452   mp->sw_if_index = ntohl (sw_if_index);
11453   mp->ip4_table_index = ntohl (ip4_table_index);
11454   mp->ip6_table_index = ntohl (ip6_table_index);
11455   mp->l2_table_index = ntohl (l2_table_index);
11456   mp->is_add = is_add;
11457
11458   S;
11459   W;
11460   /* NOTREACHED */
11461   return 0;
11462 }
11463
11464 static int
11465 api_ip_address_dump (vat_main_t * vam)
11466 {
11467   unformat_input_t *i = vam->input;
11468   vl_api_ip_address_dump_t *mp;
11469   u32 sw_if_index = ~0;
11470   u8 sw_if_index_set = 0;
11471   u8 ipv4_set = 0;
11472   u8 ipv6_set = 0;
11473   f64 timeout;
11474
11475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11476     {
11477       if (unformat (i, "sw_if_index %d", &sw_if_index))
11478         sw_if_index_set = 1;
11479       else
11480         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11481         sw_if_index_set = 1;
11482       else if (unformat (i, "ipv4"))
11483         ipv4_set = 1;
11484       else if (unformat (i, "ipv6"))
11485         ipv6_set = 1;
11486       else
11487         break;
11488     }
11489
11490   if (ipv4_set && ipv6_set)
11491     {
11492       errmsg ("ipv4 and ipv6 flags cannot be both set");
11493       return -99;
11494     }
11495
11496   if ((!ipv4_set) && (!ipv6_set))
11497     {
11498       errmsg ("no ipv4 nor ipv6 flag set");
11499       return -99;
11500     }
11501
11502   if (sw_if_index_set == 0)
11503     {
11504       errmsg ("missing interface name or sw_if_index");
11505       return -99;
11506     }
11507
11508   vam->current_sw_if_index = sw_if_index;
11509   vam->is_ipv6 = ipv6_set;
11510
11511   M (IP_ADDRESS_DUMP, ip_address_dump);
11512   mp->sw_if_index = ntohl (sw_if_index);
11513   mp->is_ipv6 = ipv6_set;
11514   S;
11515
11516   /* Use a control ping for synchronization */
11517   {
11518     vl_api_control_ping_t *mp;
11519     M (CONTROL_PING, control_ping);
11520     S;
11521   }
11522   W;
11523 }
11524
11525 static int
11526 api_ip_dump (vat_main_t * vam)
11527 {
11528   vl_api_ip_dump_t *mp;
11529   unformat_input_t *in = vam->input;
11530   int ipv4_set = 0;
11531   int ipv6_set = 0;
11532   int is_ipv6;
11533   f64 timeout;
11534   int i;
11535
11536   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11537     {
11538       if (unformat (in, "ipv4"))
11539         ipv4_set = 1;
11540       else if (unformat (in, "ipv6"))
11541         ipv6_set = 1;
11542       else
11543         break;
11544     }
11545
11546   if (ipv4_set && ipv6_set)
11547     {
11548       errmsg ("ipv4 and ipv6 flags cannot be both set");
11549       return -99;
11550     }
11551
11552   if ((!ipv4_set) && (!ipv6_set))
11553     {
11554       errmsg ("no ipv4 nor ipv6 flag set");
11555       return -99;
11556     }
11557
11558   is_ipv6 = ipv6_set;
11559   vam->is_ipv6 = is_ipv6;
11560
11561   /* free old data */
11562   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11563     {
11564       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11565     }
11566   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11567
11568   M (IP_DUMP, ip_dump);
11569   mp->is_ipv6 = ipv6_set;
11570   S;
11571
11572   /* Use a control ping for synchronization */
11573   {
11574     vl_api_control_ping_t *mp;
11575     M (CONTROL_PING, control_ping);
11576     S;
11577   }
11578   W;
11579 }
11580
11581 static int
11582 api_ipsec_spd_add_del (vat_main_t * vam)
11583 {
11584   unformat_input_t *i = vam->input;
11585   vl_api_ipsec_spd_add_del_t *mp;
11586   f64 timeout;
11587   u32 spd_id = ~0;
11588   u8 is_add = 1;
11589
11590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11591     {
11592       if (unformat (i, "spd_id %d", &spd_id))
11593         ;
11594       else if (unformat (i, "del"))
11595         is_add = 0;
11596       else
11597         {
11598           clib_warning ("parse error '%U'", format_unformat_error, i);
11599           return -99;
11600         }
11601     }
11602   if (spd_id == ~0)
11603     {
11604       errmsg ("spd_id must be set");
11605       return -99;
11606     }
11607
11608   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11609
11610   mp->spd_id = ntohl (spd_id);
11611   mp->is_add = is_add;
11612
11613   S;
11614   W;
11615   /* NOTREACHED */
11616   return 0;
11617 }
11618
11619 static int
11620 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11621 {
11622   unformat_input_t *i = vam->input;
11623   vl_api_ipsec_interface_add_del_spd_t *mp;
11624   f64 timeout;
11625   u32 sw_if_index;
11626   u8 sw_if_index_set = 0;
11627   u32 spd_id = (u32) ~ 0;
11628   u8 is_add = 1;
11629
11630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11631     {
11632       if (unformat (i, "del"))
11633         is_add = 0;
11634       else if (unformat (i, "spd_id %d", &spd_id))
11635         ;
11636       else
11637         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11638         sw_if_index_set = 1;
11639       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11640         sw_if_index_set = 1;
11641       else
11642         {
11643           clib_warning ("parse error '%U'", format_unformat_error, i);
11644           return -99;
11645         }
11646
11647     }
11648
11649   if (spd_id == (u32) ~ 0)
11650     {
11651       errmsg ("spd_id must be set");
11652       return -99;
11653     }
11654
11655   if (sw_if_index_set == 0)
11656     {
11657       errmsg ("missing interface name or sw_if_index");
11658       return -99;
11659     }
11660
11661   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11662
11663   mp->spd_id = ntohl (spd_id);
11664   mp->sw_if_index = ntohl (sw_if_index);
11665   mp->is_add = is_add;
11666
11667   S;
11668   W;
11669   /* NOTREACHED */
11670   return 0;
11671 }
11672
11673 static int
11674 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11675 {
11676   unformat_input_t *i = vam->input;
11677   vl_api_ipsec_spd_add_del_entry_t *mp;
11678   f64 timeout;
11679   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11680   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11681   i32 priority = 0;
11682   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11683   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11684   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11685   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11686
11687   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11688   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11689   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11690   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11691   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11692   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11693
11694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11695     {
11696       if (unformat (i, "del"))
11697         is_add = 0;
11698       if (unformat (i, "outbound"))
11699         is_outbound = 1;
11700       if (unformat (i, "inbound"))
11701         is_outbound = 0;
11702       else if (unformat (i, "spd_id %d", &spd_id))
11703         ;
11704       else if (unformat (i, "sa_id %d", &sa_id))
11705         ;
11706       else if (unformat (i, "priority %d", &priority))
11707         ;
11708       else if (unformat (i, "protocol %d", &protocol))
11709         ;
11710       else if (unformat (i, "lport_start %d", &lport_start))
11711         ;
11712       else if (unformat (i, "lport_stop %d", &lport_stop))
11713         ;
11714       else if (unformat (i, "rport_start %d", &rport_start))
11715         ;
11716       else if (unformat (i, "rport_stop %d", &rport_stop))
11717         ;
11718       else
11719         if (unformat
11720             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11721         {
11722           is_ipv6 = 0;
11723           is_ip_any = 0;
11724         }
11725       else
11726         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11727         {
11728           is_ipv6 = 0;
11729           is_ip_any = 0;
11730         }
11731       else
11732         if (unformat
11733             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11734         {
11735           is_ipv6 = 0;
11736           is_ip_any = 0;
11737         }
11738       else
11739         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11740         {
11741           is_ipv6 = 0;
11742           is_ip_any = 0;
11743         }
11744       else
11745         if (unformat
11746             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11747         {
11748           is_ipv6 = 1;
11749           is_ip_any = 0;
11750         }
11751       else
11752         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11753         {
11754           is_ipv6 = 1;
11755           is_ip_any = 0;
11756         }
11757       else
11758         if (unformat
11759             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11760         {
11761           is_ipv6 = 1;
11762           is_ip_any = 0;
11763         }
11764       else
11765         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11766         {
11767           is_ipv6 = 1;
11768           is_ip_any = 0;
11769         }
11770       else
11771         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11772         {
11773           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11774             {
11775               clib_warning ("unsupported action: 'resolve'");
11776               return -99;
11777             }
11778         }
11779       else
11780         {
11781           clib_warning ("parse error '%U'", format_unformat_error, i);
11782           return -99;
11783         }
11784
11785     }
11786
11787   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11788
11789   mp->spd_id = ntohl (spd_id);
11790   mp->priority = ntohl (priority);
11791   mp->is_outbound = is_outbound;
11792
11793   mp->is_ipv6 = is_ipv6;
11794   if (is_ipv6 || is_ip_any)
11795     {
11796       clib_memcpy (mp->remote_address_start, &raddr6_start,
11797                    sizeof (ip6_address_t));
11798       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11799                    sizeof (ip6_address_t));
11800       clib_memcpy (mp->local_address_start, &laddr6_start,
11801                    sizeof (ip6_address_t));
11802       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11803                    sizeof (ip6_address_t));
11804     }
11805   else
11806     {
11807       clib_memcpy (mp->remote_address_start, &raddr4_start,
11808                    sizeof (ip4_address_t));
11809       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11810                    sizeof (ip4_address_t));
11811       clib_memcpy (mp->local_address_start, &laddr4_start,
11812                    sizeof (ip4_address_t));
11813       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11814                    sizeof (ip4_address_t));
11815     }
11816   mp->protocol = (u8) protocol;
11817   mp->local_port_start = ntohs ((u16) lport_start);
11818   mp->local_port_stop = ntohs ((u16) lport_stop);
11819   mp->remote_port_start = ntohs ((u16) rport_start);
11820   mp->remote_port_stop = ntohs ((u16) rport_stop);
11821   mp->policy = (u8) policy;
11822   mp->sa_id = ntohl (sa_id);
11823   mp->is_add = is_add;
11824   mp->is_ip_any = is_ip_any;
11825   S;
11826   W;
11827   /* NOTREACHED */
11828   return 0;
11829 }
11830
11831 static int
11832 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11833 {
11834   unformat_input_t *i = vam->input;
11835   vl_api_ipsec_sad_add_del_entry_t *mp;
11836   f64 timeout;
11837   u32 sad_id = 0, spi = 0;
11838   u8 *ck = 0, *ik = 0;
11839   u8 is_add = 1;
11840
11841   u8 protocol = IPSEC_PROTOCOL_AH;
11842   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11843   u32 crypto_alg = 0, integ_alg = 0;
11844   ip4_address_t tun_src4;
11845   ip4_address_t tun_dst4;
11846   ip6_address_t tun_src6;
11847   ip6_address_t tun_dst6;
11848
11849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11850     {
11851       if (unformat (i, "del"))
11852         is_add = 0;
11853       else if (unformat (i, "sad_id %d", &sad_id))
11854         ;
11855       else if (unformat (i, "spi %d", &spi))
11856         ;
11857       else if (unformat (i, "esp"))
11858         protocol = IPSEC_PROTOCOL_ESP;
11859       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11860         {
11861           is_tunnel = 1;
11862           is_tunnel_ipv6 = 0;
11863         }
11864       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11865         {
11866           is_tunnel = 1;
11867           is_tunnel_ipv6 = 0;
11868         }
11869       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11870         {
11871           is_tunnel = 1;
11872           is_tunnel_ipv6 = 1;
11873         }
11874       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11875         {
11876           is_tunnel = 1;
11877           is_tunnel_ipv6 = 1;
11878         }
11879       else
11880         if (unformat
11881             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11882         {
11883           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11884               crypto_alg >= IPSEC_CRYPTO_N_ALG)
11885             {
11886               clib_warning ("unsupported crypto-alg: '%U'",
11887                             format_ipsec_crypto_alg, crypto_alg);
11888               return -99;
11889             }
11890         }
11891       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11892         ;
11893       else
11894         if (unformat
11895             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11896         {
11897 #if DPDK_CRYPTO==1
11898           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
11899 #else
11900           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11901 #endif
11902               integ_alg >= IPSEC_INTEG_N_ALG)
11903             {
11904               clib_warning ("unsupported integ-alg: '%U'",
11905                             format_ipsec_integ_alg, integ_alg);
11906               return -99;
11907             }
11908         }
11909       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11910         ;
11911       else
11912         {
11913           clib_warning ("parse error '%U'", format_unformat_error, i);
11914           return -99;
11915         }
11916
11917     }
11918
11919 #if DPDK_CRYPTO==1
11920   /*Special cases, aes-gcm-128 encryption */
11921   if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
11922     {
11923       if (integ_alg != IPSEC_INTEG_ALG_NONE
11924           && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
11925         {
11926           clib_warning
11927             ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
11928           return -99;
11929         }
11930       else                      /*set integ-alg internally to aes-gcm-128 */
11931         integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
11932     }
11933   else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
11934     {
11935       clib_warning ("unsupported integ-alg: aes-gcm-128");
11936       return -99;
11937     }
11938   else if (integ_alg == IPSEC_INTEG_ALG_NONE)
11939     {
11940       clib_warning ("unsupported integ-alg: none");
11941       return -99;
11942     }
11943 #endif
11944
11945
11946   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11947
11948   mp->sad_id = ntohl (sad_id);
11949   mp->is_add = is_add;
11950   mp->protocol = protocol;
11951   mp->spi = ntohl (spi);
11952   mp->is_tunnel = is_tunnel;
11953   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11954   mp->crypto_algorithm = crypto_alg;
11955   mp->integrity_algorithm = integ_alg;
11956   mp->crypto_key_length = vec_len (ck);
11957   mp->integrity_key_length = vec_len (ik);
11958
11959   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11960     mp->crypto_key_length = sizeof (mp->crypto_key);
11961
11962   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11963     mp->integrity_key_length = sizeof (mp->integrity_key);
11964
11965   if (ck)
11966     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11967   if (ik)
11968     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11969
11970   if (is_tunnel)
11971     {
11972       if (is_tunnel_ipv6)
11973         {
11974           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11975                        sizeof (ip6_address_t));
11976           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11977                        sizeof (ip6_address_t));
11978         }
11979       else
11980         {
11981           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11982                        sizeof (ip4_address_t));
11983           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11984                        sizeof (ip4_address_t));
11985         }
11986     }
11987
11988   S;
11989   W;
11990   /* NOTREACHED */
11991   return 0;
11992 }
11993
11994 static int
11995 api_ipsec_sa_set_key (vat_main_t * vam)
11996 {
11997   unformat_input_t *i = vam->input;
11998   vl_api_ipsec_sa_set_key_t *mp;
11999   f64 timeout;
12000   u32 sa_id;
12001   u8 *ck = 0, *ik = 0;
12002
12003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12004     {
12005       if (unformat (i, "sa_id %d", &sa_id))
12006         ;
12007       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12008         ;
12009       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12010         ;
12011       else
12012         {
12013           clib_warning ("parse error '%U'", format_unformat_error, i);
12014           return -99;
12015         }
12016     }
12017
12018   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
12019
12020   mp->sa_id = ntohl (sa_id);
12021   mp->crypto_key_length = vec_len (ck);
12022   mp->integrity_key_length = vec_len (ik);
12023
12024   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12025     mp->crypto_key_length = sizeof (mp->crypto_key);
12026
12027   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12028     mp->integrity_key_length = sizeof (mp->integrity_key);
12029
12030   if (ck)
12031     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12032   if (ik)
12033     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12034
12035   S;
12036   W;
12037   /* NOTREACHED */
12038   return 0;
12039 }
12040
12041 static int
12042 api_ikev2_profile_add_del (vat_main_t * vam)
12043 {
12044   unformat_input_t *i = vam->input;
12045   vl_api_ikev2_profile_add_del_t *mp;
12046   f64 timeout;
12047   u8 is_add = 1;
12048   u8 *name = 0;
12049
12050   const char *valid_chars = "a-zA-Z0-9_";
12051
12052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12053     {
12054       if (unformat (i, "del"))
12055         is_add = 0;
12056       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12057         vec_add1 (name, 0);
12058       else
12059         {
12060           errmsg ("parse error '%U'", format_unformat_error, i);
12061           return -99;
12062         }
12063     }
12064
12065   if (!vec_len (name))
12066     {
12067       errmsg ("profile name must be specified");
12068       return -99;
12069     }
12070
12071   if (vec_len (name) > 64)
12072     {
12073       errmsg ("profile name too long");
12074       return -99;
12075     }
12076
12077   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12078
12079   clib_memcpy (mp->name, name, vec_len (name));
12080   mp->is_add = is_add;
12081   vec_free (name);
12082
12083   S;
12084   W;
12085   /* NOTREACHED */
12086   return 0;
12087 }
12088
12089 static int
12090 api_ikev2_profile_set_auth (vat_main_t * vam)
12091 {
12092   unformat_input_t *i = vam->input;
12093   vl_api_ikev2_profile_set_auth_t *mp;
12094   f64 timeout;
12095   u8 *name = 0;
12096   u8 *data = 0;
12097   u32 auth_method = 0;
12098   u8 is_hex = 0;
12099
12100   const char *valid_chars = "a-zA-Z0-9_";
12101
12102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12103     {
12104       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12105         vec_add1 (name, 0);
12106       else if (unformat (i, "auth_method %U",
12107                          unformat_ikev2_auth_method, &auth_method))
12108         ;
12109       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12110         is_hex = 1;
12111       else if (unformat (i, "auth_data %v", &data))
12112         ;
12113       else
12114         {
12115           errmsg ("parse error '%U'", format_unformat_error, i);
12116           return -99;
12117         }
12118     }
12119
12120   if (!vec_len (name))
12121     {
12122       errmsg ("profile name must be specified");
12123       return -99;
12124     }
12125
12126   if (vec_len (name) > 64)
12127     {
12128       errmsg ("profile name too long");
12129       return -99;
12130     }
12131
12132   if (!vec_len (data))
12133     {
12134       errmsg ("auth_data must be specified");
12135       return -99;
12136     }
12137
12138   if (!auth_method)
12139     {
12140       errmsg ("auth_method must be specified");
12141       return -99;
12142     }
12143
12144   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12145
12146   mp->is_hex = is_hex;
12147   mp->auth_method = (u8) auth_method;
12148   mp->data_len = vec_len (data);
12149   clib_memcpy (mp->name, name, vec_len (name));
12150   clib_memcpy (mp->data, data, vec_len (data));
12151   vec_free (name);
12152   vec_free (data);
12153
12154   S;
12155   W;
12156   /* NOTREACHED */
12157   return 0;
12158 }
12159
12160 static int
12161 api_ikev2_profile_set_id (vat_main_t * vam)
12162 {
12163   unformat_input_t *i = vam->input;
12164   vl_api_ikev2_profile_set_id_t *mp;
12165   f64 timeout;
12166   u8 *name = 0;
12167   u8 *data = 0;
12168   u8 is_local = 0;
12169   u32 id_type = 0;
12170   ip4_address_t ip4;
12171
12172   const char *valid_chars = "a-zA-Z0-9_";
12173
12174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12175     {
12176       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12177         vec_add1 (name, 0);
12178       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12179         ;
12180       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12181         {
12182           data = vec_new (u8, 4);
12183           clib_memcpy (data, ip4.as_u8, 4);
12184         }
12185       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12186         ;
12187       else if (unformat (i, "id_data %v", &data))
12188         ;
12189       else if (unformat (i, "local"))
12190         is_local = 1;
12191       else if (unformat (i, "remote"))
12192         is_local = 0;
12193       else
12194         {
12195           errmsg ("parse error '%U'", format_unformat_error, i);
12196           return -99;
12197         }
12198     }
12199
12200   if (!vec_len (name))
12201     {
12202       errmsg ("profile name must be specified");
12203       return -99;
12204     }
12205
12206   if (vec_len (name) > 64)
12207     {
12208       errmsg ("profile name too long");
12209       return -99;
12210     }
12211
12212   if (!vec_len (data))
12213     {
12214       errmsg ("id_data must be specified");
12215       return -99;
12216     }
12217
12218   if (!id_type)
12219     {
12220       errmsg ("id_type must be specified");
12221       return -99;
12222     }
12223
12224   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12225
12226   mp->is_local = is_local;
12227   mp->id_type = (u8) id_type;
12228   mp->data_len = vec_len (data);
12229   clib_memcpy (mp->name, name, vec_len (name));
12230   clib_memcpy (mp->data, data, vec_len (data));
12231   vec_free (name);
12232   vec_free (data);
12233
12234   S;
12235   W;
12236   /* NOTREACHED */
12237   return 0;
12238 }
12239
12240 static int
12241 api_ikev2_profile_set_ts (vat_main_t * vam)
12242 {
12243   unformat_input_t *i = vam->input;
12244   vl_api_ikev2_profile_set_ts_t *mp;
12245   f64 timeout;
12246   u8 *name = 0;
12247   u8 is_local = 0;
12248   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12249   ip4_address_t start_addr, end_addr;
12250
12251   const char *valid_chars = "a-zA-Z0-9_";
12252
12253   start_addr.as_u32 = 0;
12254   end_addr.as_u32 = (u32) ~ 0;
12255
12256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12257     {
12258       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12259         vec_add1 (name, 0);
12260       else if (unformat (i, "protocol %d", &proto))
12261         ;
12262       else if (unformat (i, "start_port %d", &start_port))
12263         ;
12264       else if (unformat (i, "end_port %d", &end_port))
12265         ;
12266       else
12267         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12268         ;
12269       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12270         ;
12271       else if (unformat (i, "local"))
12272         is_local = 1;
12273       else if (unformat (i, "remote"))
12274         is_local = 0;
12275       else
12276         {
12277           errmsg ("parse error '%U'", format_unformat_error, i);
12278           return -99;
12279         }
12280     }
12281
12282   if (!vec_len (name))
12283     {
12284       errmsg ("profile name must be specified");
12285       return -99;
12286     }
12287
12288   if (vec_len (name) > 64)
12289     {
12290       errmsg ("profile name too long");
12291       return -99;
12292     }
12293
12294   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12295
12296   mp->is_local = is_local;
12297   mp->proto = (u8) proto;
12298   mp->start_port = (u16) start_port;
12299   mp->end_port = (u16) end_port;
12300   mp->start_addr = start_addr.as_u32;
12301   mp->end_addr = end_addr.as_u32;
12302   clib_memcpy (mp->name, name, vec_len (name));
12303   vec_free (name);
12304
12305   S;
12306   W;
12307   /* NOTREACHED */
12308   return 0;
12309 }
12310
12311 static int
12312 api_ikev2_set_local_key (vat_main_t * vam)
12313 {
12314   unformat_input_t *i = vam->input;
12315   vl_api_ikev2_set_local_key_t *mp;
12316   f64 timeout;
12317   u8 *file = 0;
12318
12319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12320     {
12321       if (unformat (i, "file %v", &file))
12322         vec_add1 (file, 0);
12323       else
12324         {
12325           errmsg ("parse error '%U'", format_unformat_error, i);
12326           return -99;
12327         }
12328     }
12329
12330   if (!vec_len (file))
12331     {
12332       errmsg ("RSA key file must be specified");
12333       return -99;
12334     }
12335
12336   if (vec_len (file) > 256)
12337     {
12338       errmsg ("file name too long");
12339       return -99;
12340     }
12341
12342   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12343
12344   clib_memcpy (mp->key_file, file, vec_len (file));
12345   vec_free (file);
12346
12347   S;
12348   W;
12349   /* NOTREACHED */
12350   return 0;
12351 }
12352
12353 /*
12354  * MAP
12355  */
12356 static int
12357 api_map_add_domain (vat_main_t * vam)
12358 {
12359   unformat_input_t *i = vam->input;
12360   vl_api_map_add_domain_t *mp;
12361   f64 timeout;
12362
12363   ip4_address_t ip4_prefix;
12364   ip6_address_t ip6_prefix;
12365   ip6_address_t ip6_src;
12366   u32 num_m_args = 0;
12367   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12368     0, psid_length = 0;
12369   u8 is_translation = 0;
12370   u32 mtu = 0;
12371   u32 ip6_src_len = 128;
12372
12373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12374     {
12375       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12376                     &ip4_prefix, &ip4_prefix_len))
12377         num_m_args++;
12378       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12379                          &ip6_prefix, &ip6_prefix_len))
12380         num_m_args++;
12381       else
12382         if (unformat
12383             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12384              &ip6_src_len))
12385         num_m_args++;
12386       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12387         num_m_args++;
12388       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12389         num_m_args++;
12390       else if (unformat (i, "psid-offset %d", &psid_offset))
12391         num_m_args++;
12392       else if (unformat (i, "psid-len %d", &psid_length))
12393         num_m_args++;
12394       else if (unformat (i, "mtu %d", &mtu))
12395         num_m_args++;
12396       else if (unformat (i, "map-t"))
12397         is_translation = 1;
12398       else
12399         {
12400           clib_warning ("parse error '%U'", format_unformat_error, i);
12401           return -99;
12402         }
12403     }
12404
12405   if (num_m_args < 3)
12406     {
12407       errmsg ("mandatory argument(s) missing");
12408       return -99;
12409     }
12410
12411   /* Construct the API message */
12412   M (MAP_ADD_DOMAIN, map_add_domain);
12413
12414   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12415   mp->ip4_prefix_len = ip4_prefix_len;
12416
12417   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12418   mp->ip6_prefix_len = ip6_prefix_len;
12419
12420   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12421   mp->ip6_src_prefix_len = ip6_src_len;
12422
12423   mp->ea_bits_len = ea_bits_len;
12424   mp->psid_offset = psid_offset;
12425   mp->psid_length = psid_length;
12426   mp->is_translation = is_translation;
12427   mp->mtu = htons (mtu);
12428
12429   /* send it... */
12430   S;
12431
12432   /* Wait for a reply, return good/bad news  */
12433   W;
12434 }
12435
12436 static int
12437 api_map_del_domain (vat_main_t * vam)
12438 {
12439   unformat_input_t *i = vam->input;
12440   vl_api_map_del_domain_t *mp;
12441   f64 timeout;
12442
12443   u32 num_m_args = 0;
12444   u32 index;
12445
12446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12447     {
12448       if (unformat (i, "index %d", &index))
12449         num_m_args++;
12450       else
12451         {
12452           clib_warning ("parse error '%U'", format_unformat_error, i);
12453           return -99;
12454         }
12455     }
12456
12457   if (num_m_args != 1)
12458     {
12459       errmsg ("mandatory argument(s) missing");
12460       return -99;
12461     }
12462
12463   /* Construct the API message */
12464   M (MAP_DEL_DOMAIN, map_del_domain);
12465
12466   mp->index = ntohl (index);
12467
12468   /* send it... */
12469   S;
12470
12471   /* Wait for a reply, return good/bad news  */
12472   W;
12473 }
12474
12475 static int
12476 api_map_add_del_rule (vat_main_t * vam)
12477 {
12478   unformat_input_t *i = vam->input;
12479   vl_api_map_add_del_rule_t *mp;
12480   f64 timeout;
12481   u8 is_add = 1;
12482   ip6_address_t ip6_dst;
12483   u32 num_m_args = 0, index, psid = 0;
12484
12485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12486     {
12487       if (unformat (i, "index %d", &index))
12488         num_m_args++;
12489       else if (unformat (i, "psid %d", &psid))
12490         num_m_args++;
12491       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12492         num_m_args++;
12493       else if (unformat (i, "del"))
12494         {
12495           is_add = 0;
12496         }
12497       else
12498         {
12499           clib_warning ("parse error '%U'", format_unformat_error, i);
12500           return -99;
12501         }
12502     }
12503
12504   /* Construct the API message */
12505   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12506
12507   mp->index = ntohl (index);
12508   mp->is_add = is_add;
12509   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12510   mp->psid = ntohs (psid);
12511
12512   /* send it... */
12513   S;
12514
12515   /* Wait for a reply, return good/bad news  */
12516   W;
12517 }
12518
12519 static int
12520 api_map_domain_dump (vat_main_t * vam)
12521 {
12522   vl_api_map_domain_dump_t *mp;
12523   f64 timeout;
12524
12525   /* Construct the API message */
12526   M (MAP_DOMAIN_DUMP, map_domain_dump);
12527
12528   /* send it... */
12529   S;
12530
12531   /* Use a control ping for synchronization */
12532   {
12533     vl_api_control_ping_t *mp;
12534     M (CONTROL_PING, control_ping);
12535     S;
12536   }
12537   W;
12538 }
12539
12540 static int
12541 api_map_rule_dump (vat_main_t * vam)
12542 {
12543   unformat_input_t *i = vam->input;
12544   vl_api_map_rule_dump_t *mp;
12545   f64 timeout;
12546   u32 domain_index = ~0;
12547
12548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12549     {
12550       if (unformat (i, "index %u", &domain_index))
12551         ;
12552       else
12553         break;
12554     }
12555
12556   if (domain_index == ~0)
12557     {
12558       clib_warning ("parse error: domain index expected");
12559       return -99;
12560     }
12561
12562   /* Construct the API message */
12563   M (MAP_RULE_DUMP, map_rule_dump);
12564
12565   mp->domain_index = htonl (domain_index);
12566
12567   /* send it... */
12568   S;
12569
12570   /* Use a control ping for synchronization */
12571   {
12572     vl_api_control_ping_t *mp;
12573     M (CONTROL_PING, control_ping);
12574     S;
12575   }
12576   W;
12577 }
12578
12579 static void vl_api_map_add_domain_reply_t_handler
12580   (vl_api_map_add_domain_reply_t * mp)
12581 {
12582   vat_main_t *vam = &vat_main;
12583   i32 retval = ntohl (mp->retval);
12584
12585   if (vam->async_mode)
12586     {
12587       vam->async_errors += (retval < 0);
12588     }
12589   else
12590     {
12591       vam->retval = retval;
12592       vam->result_ready = 1;
12593     }
12594 }
12595
12596 static void vl_api_map_add_domain_reply_t_handler_json
12597   (vl_api_map_add_domain_reply_t * mp)
12598 {
12599   vat_main_t *vam = &vat_main;
12600   vat_json_node_t node;
12601
12602   vat_json_init_object (&node);
12603   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12604   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12605
12606   vat_json_print (vam->ofp, &node);
12607   vat_json_free (&node);
12608
12609   vam->retval = ntohl (mp->retval);
12610   vam->result_ready = 1;
12611 }
12612
12613 static int
12614 api_get_first_msg_id (vat_main_t * vam)
12615 {
12616   vl_api_get_first_msg_id_t *mp;
12617   f64 timeout;
12618   unformat_input_t *i = vam->input;
12619   u8 *name;
12620   u8 name_set = 0;
12621
12622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12623     {
12624       if (unformat (i, "client %s", &name))
12625         name_set = 1;
12626       else
12627         break;
12628     }
12629
12630   if (name_set == 0)
12631     {
12632       errmsg ("missing client name");
12633       return -99;
12634     }
12635   vec_add1 (name, 0);
12636
12637   if (vec_len (name) > 63)
12638     {
12639       errmsg ("client name too long");
12640       return -99;
12641     }
12642
12643   M (GET_FIRST_MSG_ID, get_first_msg_id);
12644   clib_memcpy (mp->name, name, vec_len (name));
12645   S;
12646   W;
12647   /* NOTREACHED */
12648   return 0;
12649 }
12650
12651 static int
12652 api_cop_interface_enable_disable (vat_main_t * vam)
12653 {
12654   unformat_input_t *line_input = vam->input;
12655   vl_api_cop_interface_enable_disable_t *mp;
12656   f64 timeout;
12657   u32 sw_if_index = ~0;
12658   u8 enable_disable = 1;
12659
12660   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12661     {
12662       if (unformat (line_input, "disable"))
12663         enable_disable = 0;
12664       if (unformat (line_input, "enable"))
12665         enable_disable = 1;
12666       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12667                          vam, &sw_if_index))
12668         ;
12669       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12670         ;
12671       else
12672         break;
12673     }
12674
12675   if (sw_if_index == ~0)
12676     {
12677       errmsg ("missing interface name or sw_if_index");
12678       return -99;
12679     }
12680
12681   /* Construct the API message */
12682   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12683   mp->sw_if_index = ntohl (sw_if_index);
12684   mp->enable_disable = enable_disable;
12685
12686   /* send it... */
12687   S;
12688   /* Wait for the reply */
12689   W;
12690 }
12691
12692 static int
12693 api_cop_whitelist_enable_disable (vat_main_t * vam)
12694 {
12695   unformat_input_t *line_input = vam->input;
12696   vl_api_cop_whitelist_enable_disable_t *mp;
12697   f64 timeout;
12698   u32 sw_if_index = ~0;
12699   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12700   u32 fib_id = 0;
12701
12702   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12703     {
12704       if (unformat (line_input, "ip4"))
12705         ip4 = 1;
12706       else if (unformat (line_input, "ip6"))
12707         ip6 = 1;
12708       else if (unformat (line_input, "default"))
12709         default_cop = 1;
12710       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
12711                          vam, &sw_if_index))
12712         ;
12713       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12714         ;
12715       else if (unformat (line_input, "fib-id %d", &fib_id))
12716         ;
12717       else
12718         break;
12719     }
12720
12721   if (sw_if_index == ~0)
12722     {
12723       errmsg ("missing interface name or sw_if_index");
12724       return -99;
12725     }
12726
12727   /* Construct the API message */
12728   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12729   mp->sw_if_index = ntohl (sw_if_index);
12730   mp->fib_id = ntohl (fib_id);
12731   mp->ip4 = ip4;
12732   mp->ip6 = ip6;
12733   mp->default_cop = default_cop;
12734
12735   /* send it... */
12736   S;
12737   /* Wait for the reply */
12738   W;
12739 }
12740
12741 static int
12742 api_get_node_graph (vat_main_t * vam)
12743 {
12744   vl_api_get_node_graph_t *mp;
12745   f64 timeout;
12746
12747   M (GET_NODE_GRAPH, get_node_graph);
12748
12749   /* send it... */
12750   S;
12751   /* Wait for the reply */
12752   W;
12753 }
12754
12755 /* *INDENT-OFF* */
12756 /** Used for parsing LISP eids */
12757 typedef CLIB_PACKED(struct{
12758   u8 addr[16];   /**< eid address */
12759   u32 len;       /**< prefix length if IP */
12760   u8 type;      /**< type of eid */
12761 }) lisp_eid_vat_t;
12762 /* *INDENT-ON* */
12763
12764 static uword
12765 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12766 {
12767   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12768
12769   memset (a, 0, sizeof (a[0]));
12770
12771   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12772     {
12773       a->type = 0;              /* ipv4 type */
12774     }
12775   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12776     {
12777       a->type = 1;              /* ipv6 type */
12778     }
12779   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12780     {
12781       a->type = 2;              /* mac type */
12782     }
12783   else
12784     {
12785       return 0;
12786     }
12787
12788   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12789     {
12790       return 0;
12791     }
12792
12793   return 1;
12794 }
12795
12796 static int
12797 lisp_eid_size_vat (u8 type)
12798 {
12799   switch (type)
12800     {
12801     case 0:
12802       return 4;
12803     case 1:
12804       return 16;
12805     case 2:
12806       return 6;
12807     }
12808   return 0;
12809 }
12810
12811 static void
12812 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12813 {
12814   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12815 }
12816
12817 /* *INDENT-OFF* */
12818 /** Used for transferring locators via VPP API */
12819 typedef CLIB_PACKED(struct
12820 {
12821   u32 sw_if_index; /**< locator sw_if_index */
12822   u8 priority; /**< locator priority */
12823   u8 weight;   /**< locator weight */
12824 }) ls_locator_t;
12825 /* *INDENT-ON* */
12826
12827 static int
12828 api_lisp_add_del_locator_set (vat_main_t * vam)
12829 {
12830   unformat_input_t *input = vam->input;
12831   vl_api_lisp_add_del_locator_set_t *mp;
12832   f64 timeout = ~0;
12833   u8 is_add = 1;
12834   u8 *locator_set_name = NULL;
12835   u8 locator_set_name_set = 0;
12836   ls_locator_t locator, *locators = 0;
12837   u32 sw_if_index, priority, weight;
12838   u32 data_len = 0;
12839
12840   /* Parse args required to build the message */
12841   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12842     {
12843       if (unformat (input, "del"))
12844         {
12845           is_add = 0;
12846         }
12847       else if (unformat (input, "locator-set %s", &locator_set_name))
12848         {
12849           locator_set_name_set = 1;
12850         }
12851       else if (unformat (input, "sw_if_index %u p %u w %u",
12852                          &sw_if_index, &priority, &weight))
12853         {
12854           locator.sw_if_index = htonl (sw_if_index);
12855           locator.priority = priority;
12856           locator.weight = weight;
12857           vec_add1 (locators, locator);
12858         }
12859       else
12860         if (unformat
12861             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
12862              &sw_if_index, &priority, &weight))
12863         {
12864           locator.sw_if_index = htonl (sw_if_index);
12865           locator.priority = priority;
12866           locator.weight = weight;
12867           vec_add1 (locators, locator);
12868         }
12869       else
12870         break;
12871     }
12872
12873   if (locator_set_name_set == 0)
12874     {
12875       errmsg ("missing locator-set name");
12876       vec_free (locators);
12877       return -99;
12878     }
12879
12880   if (vec_len (locator_set_name) > 64)
12881     {
12882       errmsg ("locator-set name too long");
12883       vec_free (locator_set_name);
12884       vec_free (locators);
12885       return -99;
12886     }
12887   vec_add1 (locator_set_name, 0);
12888
12889   data_len = sizeof (ls_locator_t) * vec_len (locators);
12890
12891   /* Construct the API message */
12892   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12893
12894   mp->is_add = is_add;
12895   clib_memcpy (mp->locator_set_name, locator_set_name,
12896                vec_len (locator_set_name));
12897   vec_free (locator_set_name);
12898
12899   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12900   if (locators)
12901     clib_memcpy (mp->locators, locators, data_len);
12902   vec_free (locators);
12903
12904   /* send it... */
12905   S;
12906
12907   /* Wait for a reply... */
12908   W;
12909
12910   /* NOTREACHED */
12911   return 0;
12912 }
12913
12914 static int
12915 api_lisp_add_del_locator (vat_main_t * vam)
12916 {
12917   unformat_input_t *input = vam->input;
12918   vl_api_lisp_add_del_locator_t *mp;
12919   f64 timeout = ~0;
12920   u32 tmp_if_index = ~0;
12921   u32 sw_if_index = ~0;
12922   u8 sw_if_index_set = 0;
12923   u8 sw_if_index_if_name_set = 0;
12924   u32 priority = ~0;
12925   u8 priority_set = 0;
12926   u32 weight = ~0;
12927   u8 weight_set = 0;
12928   u8 is_add = 1;
12929   u8 *locator_set_name = NULL;
12930   u8 locator_set_name_set = 0;
12931
12932   /* Parse args required to build the message */
12933   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12934     {
12935       if (unformat (input, "del"))
12936         {
12937           is_add = 0;
12938         }
12939       else if (unformat (input, "locator-set %s", &locator_set_name))
12940         {
12941           locator_set_name_set = 1;
12942         }
12943       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
12944                          &tmp_if_index))
12945         {
12946           sw_if_index_if_name_set = 1;
12947           sw_if_index = tmp_if_index;
12948         }
12949       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12950         {
12951           sw_if_index_set = 1;
12952           sw_if_index = tmp_if_index;
12953         }
12954       else if (unformat (input, "p %d", &priority))
12955         {
12956           priority_set = 1;
12957         }
12958       else if (unformat (input, "w %d", &weight))
12959         {
12960           weight_set = 1;
12961         }
12962       else
12963         break;
12964     }
12965
12966   if (locator_set_name_set == 0)
12967     {
12968       errmsg ("missing locator-set name");
12969       return -99;
12970     }
12971
12972   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12973     {
12974       errmsg ("missing sw_if_index");
12975       vec_free (locator_set_name);
12976       return -99;
12977     }
12978
12979   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12980     {
12981       errmsg ("cannot use both params interface name and sw_if_index");
12982       vec_free (locator_set_name);
12983       return -99;
12984     }
12985
12986   if (priority_set == 0)
12987     {
12988       errmsg ("missing locator-set priority");
12989       vec_free (locator_set_name);
12990       return -99;
12991     }
12992
12993   if (weight_set == 0)
12994     {
12995       errmsg ("missing locator-set weight");
12996       vec_free (locator_set_name);
12997       return -99;
12998     }
12999
13000   if (vec_len (locator_set_name) > 64)
13001     {
13002       errmsg ("locator-set name too long");
13003       vec_free (locator_set_name);
13004       return -99;
13005     }
13006   vec_add1 (locator_set_name, 0);
13007
13008   /* Construct the API message */
13009   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
13010
13011   mp->is_add = is_add;
13012   mp->sw_if_index = ntohl (sw_if_index);
13013   mp->priority = priority;
13014   mp->weight = weight;
13015   clib_memcpy (mp->locator_set_name, locator_set_name,
13016                vec_len (locator_set_name));
13017   vec_free (locator_set_name);
13018
13019   /* send it... */
13020   S;
13021
13022   /* Wait for a reply... */
13023   W;
13024
13025   /* NOTREACHED */
13026   return 0;
13027 }
13028
13029 uword
13030 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13031 {
13032   u32 *key_id = va_arg (*args, u32 *);
13033   u8 *s = 0;
13034
13035   if (unformat (input, "%s", &s))
13036     {
13037       if (!strcmp ((char *) s, "sha1"))
13038         key_id[0] = HMAC_SHA_1_96;
13039       else if (!strcmp ((char *) s, "sha256"))
13040         key_id[0] = HMAC_SHA_256_128;
13041       else
13042         {
13043           clib_warning ("invalid key_id: '%s'", s);
13044           key_id[0] = HMAC_NO_KEY;
13045         }
13046     }
13047   else
13048     return 0;
13049
13050   vec_free (s);
13051   return 1;
13052 }
13053
13054 static int
13055 api_lisp_add_del_local_eid (vat_main_t * vam)
13056 {
13057   unformat_input_t *input = vam->input;
13058   vl_api_lisp_add_del_local_eid_t *mp;
13059   f64 timeout = ~0;
13060   u8 is_add = 1;
13061   u8 eid_set = 0;
13062   lisp_eid_vat_t _eid, *eid = &_eid;
13063   u8 *locator_set_name = 0;
13064   u8 locator_set_name_set = 0;
13065   u32 vni = 0;
13066   u16 key_id = 0;
13067   u8 *key = 0;
13068
13069   /* Parse args required to build the message */
13070   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13071     {
13072       if (unformat (input, "del"))
13073         {
13074           is_add = 0;
13075         }
13076       else if (unformat (input, "vni %d", &vni))
13077         {
13078           ;
13079         }
13080       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13081         {
13082           eid_set = 1;
13083         }
13084       else if (unformat (input, "locator-set %s", &locator_set_name))
13085         {
13086           locator_set_name_set = 1;
13087         }
13088       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13089         ;
13090       else if (unformat (input, "secret-key %_%v%_", &key))
13091         ;
13092       else
13093         break;
13094     }
13095
13096   if (locator_set_name_set == 0)
13097     {
13098       errmsg ("missing locator-set name");
13099       return -99;
13100     }
13101
13102   if (0 == eid_set)
13103     {
13104       errmsg ("EID address not set!");
13105       vec_free (locator_set_name);
13106       return -99;
13107     }
13108
13109   if (key && (0 == key_id))
13110     {
13111       errmsg ("invalid key_id!");
13112       return -99;
13113     }
13114
13115   if (vec_len (key) > 64)
13116     {
13117       errmsg ("key too long");
13118       vec_free (key);
13119       return -99;
13120     }
13121
13122   if (vec_len (locator_set_name) > 64)
13123     {
13124       errmsg ("locator-set name too long");
13125       vec_free (locator_set_name);
13126       return -99;
13127     }
13128   vec_add1 (locator_set_name, 0);
13129
13130   /* Construct the API message */
13131   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13132
13133   mp->is_add = is_add;
13134   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13135   mp->eid_type = eid->type;
13136   mp->prefix_len = eid->len;
13137   mp->vni = clib_host_to_net_u32 (vni);
13138   mp->key_id = clib_host_to_net_u16 (key_id);
13139   clib_memcpy (mp->locator_set_name, locator_set_name,
13140                vec_len (locator_set_name));
13141   clib_memcpy (mp->key, key, vec_len (key));
13142
13143   vec_free (locator_set_name);
13144   vec_free (key);
13145
13146   /* send it... */
13147   S;
13148
13149   /* Wait for a reply... */
13150   W;
13151
13152   /* NOTREACHED */
13153   return 0;
13154 }
13155
13156 /* *INDENT-OFF* */
13157 /** Used for transferring locators via VPP API */
13158 typedef CLIB_PACKED(struct
13159 {
13160   u8 is_ip4; /**< is locator an IPv4 address? */
13161   u8 priority; /**< locator priority */
13162   u8 weight;   /**< locator weight */
13163   u8 addr[16]; /**< IPv4/IPv6 address */
13164 }) rloc_t;
13165 /* *INDENT-ON* */
13166
13167 static int
13168 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13169 {
13170   u32 dp_table = 0, vni = 0;;
13171   unformat_input_t *input = vam->input;
13172   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13173   f64 timeout = ~0;
13174   u8 is_add = 1;
13175   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13176   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13177   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13178   u32 action = ~0, w;
13179   ip4_address_t rmt_rloc4, lcl_rloc4;
13180   ip6_address_t rmt_rloc6, lcl_rloc6;
13181   vl_api_lisp_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc =
13182     0;
13183
13184   memset (&rloc, 0, sizeof (rloc));
13185
13186   /* Parse args required to build the message */
13187   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13188     {
13189       if (unformat (input, "del"))
13190         is_add = 0;
13191       else if (unformat (input, "add"))
13192         is_add = 1;
13193       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
13194         {
13195           rmt_eid_set = 1;
13196         }
13197       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
13198         {
13199           lcl_eid_set = 1;
13200         }
13201       else if (unformat (input, "vrf %d", &dp_table))
13202         ;
13203       else if (unformat (input, "bd %d", &dp_table))
13204         ;
13205       else if (unformat (input, "vni %d", &vni))
13206         ;
13207       else if (unformat (input, "w %d", &w))
13208         {
13209           if (!curr_rloc)
13210             {
13211               errmsg ("No RLOC configured for setting priority/weight!");
13212               return -99;
13213             }
13214           curr_rloc->weight = w;
13215         }
13216       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13217                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13218         {
13219           rloc.is_ip4 = 1;
13220
13221           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13222           rloc.weight = 0;
13223           vec_add1 (lcl_locs, rloc);
13224
13225           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13226           vec_add1 (rmt_locs, rloc);
13227           /* weight saved in rmt loc */
13228           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13229         }
13230       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13231                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13232         {
13233           rloc.is_ip4 = 0;
13234           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13235           rloc.weight = 0;
13236           vec_add1 (lcl_locs, rloc);
13237
13238           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13239           vec_add1 (rmt_locs, rloc);
13240           /* weight saved in rmt loc */
13241           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13242         }
13243       else if (unformat (input, "action %d", &action))
13244         {
13245           ;
13246         }
13247       else
13248         {
13249           clib_warning ("parse error '%U'", format_unformat_error, input);
13250           return -99;
13251         }
13252     }
13253
13254   if (!rmt_eid_set)
13255     {
13256       errmsg ("remote eid addresses not set");
13257       return -99;
13258     }
13259
13260   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13261     {
13262       errmsg ("eid types don't match");
13263       return -99;
13264     }
13265
13266   if (0 == rmt_locs && (u32) ~ 0 == action)
13267     {
13268       errmsg ("action not set for negative mapping");
13269       return -99;
13270     }
13271
13272   /* Construct the API message */
13273   M2 (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry,
13274       sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs) * 2);
13275
13276   mp->is_add = is_add;
13277   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13278   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13279   mp->eid_type = rmt_eid->type;
13280   mp->dp_table = clib_host_to_net_u32 (dp_table);
13281   mp->vni = clib_host_to_net_u32 (vni);
13282   mp->rmt_len = rmt_eid->len;
13283   mp->lcl_len = lcl_eid->len;
13284   mp->action = action;
13285
13286   if (0 != rmt_locs && 0 != lcl_locs)
13287     {
13288       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
13289       clib_memcpy (mp->locs, lcl_locs,
13290                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs)));
13291
13292       u32 offset = sizeof (vl_api_lisp_gpe_locator_t) * vec_len (lcl_locs);
13293       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
13294                    (sizeof (vl_api_lisp_gpe_locator_t) * vec_len (rmt_locs)));
13295     }
13296   vec_free (lcl_locs);
13297   vec_free (rmt_locs);
13298
13299   /* send it... */
13300   S;
13301
13302   /* Wait for a reply... */
13303   W;
13304
13305   /* NOTREACHED */
13306   return 0;
13307 }
13308
13309 static int
13310 api_lisp_add_del_map_server (vat_main_t * vam)
13311 {
13312   unformat_input_t *input = vam->input;
13313   vl_api_lisp_add_del_map_server_t *mp;
13314   f64 timeout = ~0;
13315   u8 is_add = 1;
13316   u8 ipv4_set = 0;
13317   u8 ipv6_set = 0;
13318   ip4_address_t ipv4;
13319   ip6_address_t ipv6;
13320
13321   /* Parse args required to build the message */
13322   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13323     {
13324       if (unformat (input, "del"))
13325         {
13326           is_add = 0;
13327         }
13328       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13329         {
13330           ipv4_set = 1;
13331         }
13332       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13333         {
13334           ipv6_set = 1;
13335         }
13336       else
13337         break;
13338     }
13339
13340   if (ipv4_set && ipv6_set)
13341     {
13342       errmsg ("both eid v4 and v6 addresses set");
13343       return -99;
13344     }
13345
13346   if (!ipv4_set && !ipv6_set)
13347     {
13348       errmsg ("eid addresses not set");
13349       return -99;
13350     }
13351
13352   /* Construct the API message */
13353   M (LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server);
13354
13355   mp->is_add = is_add;
13356   if (ipv6_set)
13357     {
13358       mp->is_ipv6 = 1;
13359       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13360     }
13361   else
13362     {
13363       mp->is_ipv6 = 0;
13364       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13365     }
13366
13367   /* send it... */
13368   S;
13369
13370   /* Wait for a reply... */
13371   W;
13372
13373   /* NOTREACHED */
13374   return 0;
13375 }
13376
13377 static int
13378 api_lisp_add_del_map_resolver (vat_main_t * vam)
13379 {
13380   unformat_input_t *input = vam->input;
13381   vl_api_lisp_add_del_map_resolver_t *mp;
13382   f64 timeout = ~0;
13383   u8 is_add = 1;
13384   u8 ipv4_set = 0;
13385   u8 ipv6_set = 0;
13386   ip4_address_t ipv4;
13387   ip6_address_t ipv6;
13388
13389   /* Parse args required to build the message */
13390   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13391     {
13392       if (unformat (input, "del"))
13393         {
13394           is_add = 0;
13395         }
13396       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13397         {
13398           ipv4_set = 1;
13399         }
13400       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13401         {
13402           ipv6_set = 1;
13403         }
13404       else
13405         break;
13406     }
13407
13408   if (ipv4_set && ipv6_set)
13409     {
13410       errmsg ("both eid v4 and v6 addresses set");
13411       return -99;
13412     }
13413
13414   if (!ipv4_set && !ipv6_set)
13415     {
13416       errmsg ("eid addresses not set");
13417       return -99;
13418     }
13419
13420   /* Construct the API message */
13421   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13422
13423   mp->is_add = is_add;
13424   if (ipv6_set)
13425     {
13426       mp->is_ipv6 = 1;
13427       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13428     }
13429   else
13430     {
13431       mp->is_ipv6 = 0;
13432       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13433     }
13434
13435   /* send it... */
13436   S;
13437
13438   /* Wait for a reply... */
13439   W;
13440
13441   /* NOTREACHED */
13442   return 0;
13443 }
13444
13445 static int
13446 api_lisp_gpe_enable_disable (vat_main_t * vam)
13447 {
13448   unformat_input_t *input = vam->input;
13449   vl_api_lisp_gpe_enable_disable_t *mp;
13450   f64 timeout = ~0;
13451   u8 is_set = 0;
13452   u8 is_en = 1;
13453
13454   /* Parse args required to build the message */
13455   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13456     {
13457       if (unformat (input, "enable"))
13458         {
13459           is_set = 1;
13460           is_en = 1;
13461         }
13462       else if (unformat (input, "disable"))
13463         {
13464           is_set = 1;
13465           is_en = 0;
13466         }
13467       else
13468         break;
13469     }
13470
13471   if (is_set == 0)
13472     {
13473       errmsg ("Value not set");
13474       return -99;
13475     }
13476
13477   /* Construct the API message */
13478   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13479
13480   mp->is_en = is_en;
13481
13482   /* send it... */
13483   S;
13484
13485   /* Wait for a reply... */
13486   W;
13487
13488   /* NOTREACHED */
13489   return 0;
13490 }
13491
13492 static int
13493 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13494 {
13495   unformat_input_t *input = vam->input;
13496   vl_api_lisp_rloc_probe_enable_disable_t *mp;
13497   f64 timeout = ~0;
13498   u8 is_set = 0;
13499   u8 is_en = 0;
13500
13501   /* Parse args required to build the message */
13502   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13503     {
13504       if (unformat (input, "enable"))
13505         {
13506           is_set = 1;
13507           is_en = 1;
13508         }
13509       else if (unformat (input, "disable"))
13510         is_set = 1;
13511       else
13512         break;
13513     }
13514
13515   if (!is_set)
13516     {
13517       errmsg ("Value not set");
13518       return -99;
13519     }
13520
13521   /* Construct the API message */
13522   M (LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable);
13523
13524   mp->is_enabled = is_en;
13525
13526   /* send it... */
13527   S;
13528
13529   /* Wait for a reply... */
13530   W;
13531
13532   /* NOTREACHED */
13533   return 0;
13534 }
13535
13536 static int
13537 api_lisp_map_register_enable_disable (vat_main_t * vam)
13538 {
13539   unformat_input_t *input = vam->input;
13540   vl_api_lisp_map_register_enable_disable_t *mp;
13541   f64 timeout = ~0;
13542   u8 is_set = 0;
13543   u8 is_en = 0;
13544
13545   /* Parse args required to build the message */
13546   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13547     {
13548       if (unformat (input, "enable"))
13549         {
13550           is_set = 1;
13551           is_en = 1;
13552         }
13553       else if (unformat (input, "disable"))
13554         is_set = 1;
13555       else
13556         break;
13557     }
13558
13559   if (!is_set)
13560     {
13561       errmsg ("Value not set");
13562       return -99;
13563     }
13564
13565   /* Construct the API message */
13566   M (LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable);
13567
13568   mp->is_enabled = is_en;
13569
13570   /* send it... */
13571   S;
13572
13573   /* Wait for a reply... */
13574   W;
13575
13576   /* NOTREACHED */
13577   return 0;
13578 }
13579
13580 static int
13581 api_lisp_enable_disable (vat_main_t * vam)
13582 {
13583   unformat_input_t *input = vam->input;
13584   vl_api_lisp_enable_disable_t *mp;
13585   f64 timeout = ~0;
13586   u8 is_set = 0;
13587   u8 is_en = 0;
13588
13589   /* Parse args required to build the message */
13590   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13591     {
13592       if (unformat (input, "enable"))
13593         {
13594           is_set = 1;
13595           is_en = 1;
13596         }
13597       else if (unformat (input, "disable"))
13598         {
13599           is_set = 1;
13600         }
13601       else
13602         break;
13603     }
13604
13605   if (!is_set)
13606     {
13607       errmsg ("Value not set");
13608       return -99;
13609     }
13610
13611   /* Construct the API message */
13612   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13613
13614   mp->is_en = is_en;
13615
13616   /* send it... */
13617   S;
13618
13619   /* Wait for a reply... */
13620   W;
13621
13622   /* NOTREACHED */
13623   return 0;
13624 }
13625
13626 static int
13627 api_show_lisp_map_register_state (vat_main_t * vam)
13628 {
13629   f64 timeout = ~0;
13630   vl_api_show_lisp_map_register_state_t *mp;
13631
13632   M (SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state);
13633
13634   /* send */
13635   S;
13636
13637   /* wait for reply */
13638   W;
13639
13640   return 0;
13641 }
13642
13643 static int
13644 api_show_lisp_rloc_probe_state (vat_main_t * vam)
13645 {
13646   f64 timeout = ~0;
13647   vl_api_show_lisp_rloc_probe_state_t *mp;
13648
13649   M (SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state);
13650
13651   /* send */
13652   S;
13653
13654   /* wait for reply */
13655   W;
13656
13657   return 0;
13658 }
13659
13660 static int
13661 api_show_lisp_map_request_mode (vat_main_t * vam)
13662 {
13663   f64 timeout = ~0;
13664   vl_api_show_lisp_map_request_mode_t *mp;
13665
13666   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13667
13668   /* send */
13669   S;
13670
13671   /* wait for reply */
13672   W;
13673
13674   return 0;
13675 }
13676
13677 static int
13678 api_lisp_map_request_mode (vat_main_t * vam)
13679 {
13680   f64 timeout = ~0;
13681   unformat_input_t *input = vam->input;
13682   vl_api_lisp_map_request_mode_t *mp;
13683   u8 mode = 0;
13684
13685   /* Parse args required to build the message */
13686   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13687     {
13688       if (unformat (input, "dst-only"))
13689         mode = 0;
13690       else if (unformat (input, "src-dst"))
13691         mode = 1;
13692       else
13693         {
13694           errmsg ("parse error '%U'", format_unformat_error, input);
13695           return -99;
13696         }
13697     }
13698
13699   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13700
13701   mp->mode = mode;
13702
13703   /* send */
13704   S;
13705
13706   /* wait for reply */
13707   W;
13708
13709   /* notreached */
13710   return 0;
13711 }
13712
13713 /**
13714  * Enable/disable LISP proxy ITR.
13715  *
13716  * @param vam vpp API test context
13717  * @return return code
13718  */
13719 static int
13720 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13721 {
13722   f64 timeout = ~0;
13723   u8 ls_name_set = 0;
13724   unformat_input_t *input = vam->input;
13725   vl_api_lisp_pitr_set_locator_set_t *mp;
13726   u8 is_add = 1;
13727   u8 *ls_name = 0;
13728
13729   /* Parse args required to build the message */
13730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13731     {
13732       if (unformat (input, "del"))
13733         is_add = 0;
13734       else if (unformat (input, "locator-set %s", &ls_name))
13735         ls_name_set = 1;
13736       else
13737         {
13738           errmsg ("parse error '%U'", format_unformat_error, input);
13739           return -99;
13740         }
13741     }
13742
13743   if (!ls_name_set)
13744     {
13745       errmsg ("locator-set name not set!");
13746       return -99;
13747     }
13748
13749   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13750
13751   mp->is_add = is_add;
13752   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13753   vec_free (ls_name);
13754
13755   /* send */
13756   S;
13757
13758   /* wait for reply */
13759   W;
13760
13761   /* notreached */
13762   return 0;
13763 }
13764
13765 static int
13766 api_show_lisp_pitr (vat_main_t * vam)
13767 {
13768   vl_api_show_lisp_pitr_t *mp;
13769   f64 timeout = ~0;
13770
13771   if (!vam->json_output)
13772     {
13773       print (vam->ofp, "%=20s", "lisp status:");
13774     }
13775
13776   M (SHOW_LISP_PITR, show_lisp_pitr);
13777   /* send it... */
13778   S;
13779
13780   /* Wait for a reply... */
13781   W;
13782
13783   /* NOTREACHED */
13784   return 0;
13785 }
13786
13787 /**
13788  * Add/delete mapping between vni and vrf
13789  */
13790 static int
13791 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13792 {
13793   f64 timeout = ~0;
13794   unformat_input_t *input = vam->input;
13795   vl_api_lisp_eid_table_add_del_map_t *mp;
13796   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13797   u32 vni, vrf, bd_index;
13798
13799   /* Parse args required to build the message */
13800   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13801     {
13802       if (unformat (input, "del"))
13803         is_add = 0;
13804       else if (unformat (input, "vrf %d", &vrf))
13805         vrf_set = 1;
13806       else if (unformat (input, "bd_index %d", &bd_index))
13807         bd_index_set = 1;
13808       else if (unformat (input, "vni %d", &vni))
13809         vni_set = 1;
13810       else
13811         break;
13812     }
13813
13814   if (!vni_set || (!vrf_set && !bd_index_set))
13815     {
13816       errmsg ("missing arguments!");
13817       return -99;
13818     }
13819
13820   if (vrf_set && bd_index_set)
13821     {
13822       errmsg ("error: both vrf and bd entered!");
13823       return -99;
13824     }
13825
13826   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13827
13828   mp->is_add = is_add;
13829   mp->vni = htonl (vni);
13830   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13831   mp->is_l2 = bd_index_set;
13832
13833   /* send */
13834   S;
13835
13836   /* wait for reply */
13837   W;
13838
13839   /* notreached */
13840   return 0;
13841 }
13842
13843 uword
13844 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13845 {
13846   u32 *action = va_arg (*args, u32 *);
13847   u8 *s = 0;
13848
13849   if (unformat (input, "%s", &s))
13850     {
13851       if (!strcmp ((char *) s, "no-action"))
13852         action[0] = 0;
13853       else if (!strcmp ((char *) s, "natively-forward"))
13854         action[0] = 1;
13855       else if (!strcmp ((char *) s, "send-map-request"))
13856         action[0] = 2;
13857       else if (!strcmp ((char *) s, "drop"))
13858         action[0] = 3;
13859       else
13860         {
13861           clib_warning ("invalid action: '%s'", s);
13862           action[0] = 3;
13863         }
13864     }
13865   else
13866     return 0;
13867
13868   vec_free (s);
13869   return 1;
13870 }
13871
13872 /**
13873  * Add/del remote mapping to/from LISP control plane
13874  *
13875  * @param vam vpp API test context
13876  * @return return code
13877  */
13878 static int
13879 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13880 {
13881   unformat_input_t *input = vam->input;
13882   vl_api_lisp_add_del_remote_mapping_t *mp;
13883   f64 timeout = ~0;
13884   u32 vni = 0;
13885   lisp_eid_vat_t _eid, *eid = &_eid;
13886   lisp_eid_vat_t _seid, *seid = &_seid;
13887   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13888   u32 action = ~0, p, w, data_len;
13889   ip4_address_t rloc4;
13890   ip6_address_t rloc6;
13891   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13892
13893   memset (&rloc, 0, sizeof (rloc));
13894
13895   /* Parse args required to build the message */
13896   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13897     {
13898       if (unformat (input, "del-all"))
13899         {
13900           del_all = 1;
13901         }
13902       else if (unformat (input, "del"))
13903         {
13904           is_add = 0;
13905         }
13906       else if (unformat (input, "add"))
13907         {
13908           is_add = 1;
13909         }
13910       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13911         {
13912           eid_set = 1;
13913         }
13914       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13915         {
13916           seid_set = 1;
13917         }
13918       else if (unformat (input, "vni %d", &vni))
13919         {
13920           ;
13921         }
13922       else if (unformat (input, "p %d w %d", &p, &w))
13923         {
13924           if (!curr_rloc)
13925             {
13926               errmsg ("No RLOC configured for setting priority/weight!");
13927               return -99;
13928             }
13929           curr_rloc->priority = p;
13930           curr_rloc->weight = w;
13931         }
13932       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13933         {
13934           rloc.is_ip4 = 1;
13935           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13936           vec_add1 (rlocs, rloc);
13937           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13938         }
13939       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13940         {
13941           rloc.is_ip4 = 0;
13942           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13943           vec_add1 (rlocs, rloc);
13944           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13945         }
13946       else if (unformat (input, "action %U",
13947                          unformat_negative_mapping_action, &action))
13948         {
13949           ;
13950         }
13951       else
13952         {
13953           clib_warning ("parse error '%U'", format_unformat_error, input);
13954           return -99;
13955         }
13956     }
13957
13958   if (0 == eid_set)
13959     {
13960       errmsg ("missing params!");
13961       return -99;
13962     }
13963
13964   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13965     {
13966       errmsg ("no action set for negative map-reply!");
13967       return -99;
13968     }
13969
13970   data_len = vec_len (rlocs) * sizeof (rloc_t);
13971
13972   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13973   mp->is_add = is_add;
13974   mp->vni = htonl (vni);
13975   mp->action = (u8) action;
13976   mp->is_src_dst = seid_set;
13977   mp->eid_len = eid->len;
13978   mp->seid_len = seid->len;
13979   mp->del_all = del_all;
13980   mp->eid_type = eid->type;
13981   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13982   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13983
13984   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13985   clib_memcpy (mp->rlocs, rlocs, data_len);
13986   vec_free (rlocs);
13987
13988   /* send it... */
13989   S;
13990
13991   /* Wait for a reply... */
13992   W;
13993
13994   /* NOTREACHED */
13995   return 0;
13996 }
13997
13998 /**
13999  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14000  * forwarding entries in data-plane accordingly.
14001  *
14002  * @param vam vpp API test context
14003  * @return return code
14004  */
14005 static int
14006 api_lisp_add_del_adjacency (vat_main_t * vam)
14007 {
14008   unformat_input_t *input = vam->input;
14009   vl_api_lisp_add_del_adjacency_t *mp;
14010   f64 timeout = ~0;
14011   u32 vni = 0;
14012   ip4_address_t leid4, reid4;
14013   ip6_address_t leid6, reid6;
14014   u8 reid_mac[6] = { 0 };
14015   u8 leid_mac[6] = { 0 };
14016   u8 reid_type, leid_type;
14017   u32 leid_len = 0, reid_len = 0, len;
14018   u8 is_add = 1;
14019
14020   leid_type = reid_type = (u8) ~ 0;
14021
14022   /* Parse args required to build the message */
14023   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14024     {
14025       if (unformat (input, "del"))
14026         {
14027           is_add = 0;
14028         }
14029       else if (unformat (input, "add"))
14030         {
14031           is_add = 1;
14032         }
14033       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14034                          &reid4, &len))
14035         {
14036           reid_type = 0;        /* ipv4 */
14037           reid_len = len;
14038         }
14039       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14040                          &reid6, &len))
14041         {
14042           reid_type = 1;        /* ipv6 */
14043           reid_len = len;
14044         }
14045       else if (unformat (input, "reid %U", unformat_ethernet_address,
14046                          reid_mac))
14047         {
14048           reid_type = 2;        /* mac */
14049         }
14050       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14051                          &leid4, &len))
14052         {
14053           leid_type = 0;        /* ipv4 */
14054           leid_len = len;
14055         }
14056       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14057                          &leid6, &len))
14058         {
14059           leid_type = 1;        /* ipv6 */
14060           leid_len = len;
14061         }
14062       else if (unformat (input, "leid %U", unformat_ethernet_address,
14063                          leid_mac))
14064         {
14065           leid_type = 2;        /* mac */
14066         }
14067       else if (unformat (input, "vni %d", &vni))
14068         {
14069           ;
14070         }
14071       else
14072         {
14073           errmsg ("parse error '%U'", format_unformat_error, input);
14074           return -99;
14075         }
14076     }
14077
14078   if ((u8) ~ 0 == reid_type)
14079     {
14080       errmsg ("missing params!");
14081       return -99;
14082     }
14083
14084   if (leid_type != reid_type)
14085     {
14086       errmsg ("remote and local EIDs are of different types!");
14087       return -99;
14088     }
14089
14090   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
14091   mp->is_add = is_add;
14092   mp->vni = htonl (vni);
14093   mp->leid_len = leid_len;
14094   mp->reid_len = reid_len;
14095   mp->eid_type = reid_type;
14096
14097   switch (mp->eid_type)
14098     {
14099     case 0:
14100       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14101       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14102       break;
14103     case 1:
14104       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14105       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14106       break;
14107     case 2:
14108       clib_memcpy (mp->leid, leid_mac, 6);
14109       clib_memcpy (mp->reid, reid_mac, 6);
14110       break;
14111     default:
14112       errmsg ("unknown EID type %d!", mp->eid_type);
14113       return 0;
14114     }
14115
14116   /* send it... */
14117   S;
14118
14119   /* Wait for a reply... */
14120   W;
14121
14122   /* NOTREACHED */
14123   return 0;
14124 }
14125
14126 static int
14127 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14128 {
14129   unformat_input_t *input = vam->input;
14130   vl_api_lisp_gpe_add_del_iface_t *mp;
14131   f64 timeout = ~0;
14132   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14133   u32 dp_table = 0, vni = 0;
14134
14135   /* Parse args required to build the message */
14136   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14137     {
14138       if (unformat (input, "up"))
14139         {
14140           action_set = 1;
14141           is_add = 1;
14142         }
14143       else if (unformat (input, "down"))
14144         {
14145           action_set = 1;
14146           is_add = 0;
14147         }
14148       else if (unformat (input, "table_id %d", &dp_table))
14149         {
14150           dp_table_set = 1;
14151         }
14152       else if (unformat (input, "bd_id %d", &dp_table))
14153         {
14154           dp_table_set = 1;
14155           is_l2 = 1;
14156         }
14157       else if (unformat (input, "vni %d", &vni))
14158         {
14159           vni_set = 1;
14160         }
14161       else
14162         break;
14163     }
14164
14165   if (action_set == 0)
14166     {
14167       errmsg ("Action not set");
14168       return -99;
14169     }
14170   if (dp_table_set == 0 || vni_set == 0)
14171     {
14172       errmsg ("vni and dp_table must be set");
14173       return -99;
14174     }
14175
14176   /* Construct the API message */
14177   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
14178
14179   mp->is_add = is_add;
14180   mp->dp_table = dp_table;
14181   mp->is_l2 = is_l2;
14182   mp->vni = vni;
14183
14184   /* send it... */
14185   S;
14186
14187   /* Wait for a reply... */
14188   W;
14189
14190   /* NOTREACHED */
14191   return 0;
14192 }
14193
14194 /**
14195  * Add/del map request itr rlocs from LISP control plane and updates
14196  *
14197  * @param vam vpp API test context
14198  * @return return code
14199  */
14200 static int
14201 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14202 {
14203   unformat_input_t *input = vam->input;
14204   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14205   f64 timeout = ~0;
14206   u8 *locator_set_name = 0;
14207   u8 locator_set_name_set = 0;
14208   u8 is_add = 1;
14209
14210   /* Parse args required to build the message */
14211   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14212     {
14213       if (unformat (input, "del"))
14214         {
14215           is_add = 0;
14216         }
14217       else if (unformat (input, "%_%v%_", &locator_set_name))
14218         {
14219           locator_set_name_set = 1;
14220         }
14221       else
14222         {
14223           clib_warning ("parse error '%U'", format_unformat_error, input);
14224           return -99;
14225         }
14226     }
14227
14228   if (is_add && !locator_set_name_set)
14229     {
14230       errmsg ("itr-rloc is not set!");
14231       return -99;
14232     }
14233
14234   if (is_add && vec_len (locator_set_name) > 64)
14235     {
14236       errmsg ("itr-rloc locator-set name too long");
14237       vec_free (locator_set_name);
14238       return -99;
14239     }
14240
14241   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
14242   mp->is_add = is_add;
14243   if (is_add)
14244     {
14245       clib_memcpy (mp->locator_set_name, locator_set_name,
14246                    vec_len (locator_set_name));
14247     }
14248   else
14249     {
14250       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14251     }
14252   vec_free (locator_set_name);
14253
14254   /* send it... */
14255   S;
14256
14257   /* Wait for a reply... */
14258   W;
14259
14260   /* NOTREACHED */
14261   return 0;
14262 }
14263
14264 static int
14265 api_lisp_locator_dump (vat_main_t * vam)
14266 {
14267   unformat_input_t *input = vam->input;
14268   vl_api_lisp_locator_dump_t *mp;
14269   f64 timeout = ~0;
14270   u8 is_index_set = 0, is_name_set = 0;
14271   u8 *ls_name = 0;
14272   u32 ls_index = ~0;
14273
14274   /* Parse args required to build the message */
14275   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14276     {
14277       if (unformat (input, "ls_name %_%v%_", &ls_name))
14278         {
14279           is_name_set = 1;
14280         }
14281       else if (unformat (input, "ls_index %d", &ls_index))
14282         {
14283           is_index_set = 1;
14284         }
14285       else
14286         {
14287           errmsg ("parse error '%U'", format_unformat_error, input);
14288           return -99;
14289         }
14290     }
14291
14292   if (!is_index_set && !is_name_set)
14293     {
14294       errmsg ("error: expected one of index or name!");
14295       return -99;
14296     }
14297
14298   if (is_index_set && is_name_set)
14299     {
14300       errmsg ("error: only one param expected!");
14301       return -99;
14302     }
14303
14304   if (vec_len (ls_name) > 62)
14305     {
14306       errmsg ("error: locator set name too long!");
14307       return -99;
14308     }
14309
14310   if (!vam->json_output)
14311     {
14312       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
14313     }
14314
14315   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
14316   mp->is_index_set = is_index_set;
14317
14318   if (is_index_set)
14319     mp->ls_index = clib_host_to_net_u32 (ls_index);
14320   else
14321     {
14322       vec_add1 (ls_name, 0);
14323       strncpy ((char *) mp->ls_name, (char *) ls_name,
14324                sizeof (mp->ls_name) - 1);
14325     }
14326
14327   /* send it... */
14328   S;
14329
14330   /* Use a control ping for synchronization */
14331   {
14332     vl_api_control_ping_t *mp;
14333     M (CONTROL_PING, control_ping);
14334     S;
14335   }
14336   /* Wait for a reply... */
14337   W;
14338
14339   /* NOTREACHED */
14340   return 0;
14341 }
14342
14343 static int
14344 api_lisp_locator_set_dump (vat_main_t * vam)
14345 {
14346   vl_api_lisp_locator_set_dump_t *mp;
14347   unformat_input_t *input = vam->input;
14348   f64 timeout = ~0;
14349   u8 filter = 0;
14350
14351   /* Parse args required to build the message */
14352   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14353     {
14354       if (unformat (input, "local"))
14355         {
14356           filter = 1;
14357         }
14358       else if (unformat (input, "remote"))
14359         {
14360           filter = 2;
14361         }
14362       else
14363         {
14364           errmsg ("parse error '%U'", format_unformat_error, input);
14365           return -99;
14366         }
14367     }
14368
14369   if (!vam->json_output)
14370     {
14371       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
14372     }
14373
14374   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14375
14376   mp->filter = filter;
14377
14378   /* send it... */
14379   S;
14380
14381   /* Use a control ping for synchronization */
14382   {
14383     vl_api_control_ping_t *mp;
14384     M (CONTROL_PING, control_ping);
14385     S;
14386   }
14387   /* Wait for a reply... */
14388   W;
14389
14390   /* NOTREACHED */
14391   return 0;
14392 }
14393
14394 static int
14395 api_lisp_eid_table_map_dump (vat_main_t * vam)
14396 {
14397   u8 is_l2 = 0;
14398   u8 mode_set = 0;
14399   unformat_input_t *input = vam->input;
14400   vl_api_lisp_eid_table_map_dump_t *mp;
14401   f64 timeout = ~0;
14402
14403   /* Parse args required to build the message */
14404   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14405     {
14406       if (unformat (input, "l2"))
14407         {
14408           is_l2 = 1;
14409           mode_set = 1;
14410         }
14411       else if (unformat (input, "l3"))
14412         {
14413           is_l2 = 0;
14414           mode_set = 1;
14415         }
14416       else
14417         {
14418           errmsg ("parse error '%U'", format_unformat_error, input);
14419           return -99;
14420         }
14421     }
14422
14423   if (!mode_set)
14424     {
14425       errmsg ("expected one of 'l2' or 'l3' parameter!");
14426       return -99;
14427     }
14428
14429   if (!vam->json_output)
14430     {
14431       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
14432     }
14433
14434   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14435   mp->is_l2 = is_l2;
14436
14437   /* send it... */
14438   S;
14439
14440   /* Use a control ping for synchronization */
14441   {
14442     vl_api_control_ping_t *mp;
14443     M (CONTROL_PING, control_ping);
14444     S;
14445   }
14446   /* Wait for a reply... */
14447   W;
14448
14449   /* NOTREACHED */
14450   return 0;
14451 }
14452
14453 static int
14454 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14455 {
14456   vl_api_lisp_eid_table_vni_dump_t *mp;
14457   f64 timeout = ~0;
14458
14459   if (!vam->json_output)
14460     {
14461       print (vam->ofp, "VNI");
14462     }
14463
14464   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14465
14466   /* send it... */
14467   S;
14468
14469   /* Use a control ping for synchronization */
14470   {
14471     vl_api_control_ping_t *mp;
14472     M (CONTROL_PING, control_ping);
14473     S;
14474   }
14475   /* Wait for a reply... */
14476   W;
14477
14478   /* NOTREACHED */
14479   return 0;
14480 }
14481
14482 static int
14483 api_lisp_eid_table_dump (vat_main_t * vam)
14484 {
14485   unformat_input_t *i = vam->input;
14486   vl_api_lisp_eid_table_dump_t *mp;
14487   f64 timeout = ~0;
14488   struct in_addr ip4;
14489   struct in6_addr ip6;
14490   u8 mac[6];
14491   u8 eid_type = ~0, eid_set = 0;
14492   u32 prefix_length = ~0, t, vni = 0;
14493   u8 filter = 0;
14494
14495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14496     {
14497       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14498         {
14499           eid_set = 1;
14500           eid_type = 0;
14501           prefix_length = t;
14502         }
14503       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14504         {
14505           eid_set = 1;
14506           eid_type = 1;
14507           prefix_length = t;
14508         }
14509       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14510         {
14511           eid_set = 1;
14512           eid_type = 2;
14513         }
14514       else if (unformat (i, "vni %d", &t))
14515         {
14516           vni = t;
14517         }
14518       else if (unformat (i, "local"))
14519         {
14520           filter = 1;
14521         }
14522       else if (unformat (i, "remote"))
14523         {
14524           filter = 2;
14525         }
14526       else
14527         {
14528           errmsg ("parse error '%U'", format_unformat_error, i);
14529           return -99;
14530         }
14531     }
14532
14533   if (!vam->json_output)
14534     {
14535       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
14536              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14537     }
14538
14539   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14540
14541   mp->filter = filter;
14542   if (eid_set)
14543     {
14544       mp->eid_set = 1;
14545       mp->vni = htonl (vni);
14546       mp->eid_type = eid_type;
14547       switch (eid_type)
14548         {
14549         case 0:
14550           mp->prefix_length = prefix_length;
14551           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14552           break;
14553         case 1:
14554           mp->prefix_length = prefix_length;
14555           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14556           break;
14557         case 2:
14558           clib_memcpy (mp->eid, mac, sizeof (mac));
14559           break;
14560         default:
14561           errmsg ("unknown EID type %d!", eid_type);
14562           return -99;
14563         }
14564     }
14565
14566   /* send it... */
14567   S;
14568
14569   /* Use a control ping for synchronization */
14570   {
14571     vl_api_control_ping_t *mp;
14572     M (CONTROL_PING, control_ping);
14573     S;
14574   }
14575
14576   /* Wait for a reply... */
14577   W;
14578
14579   /* NOTREACHED */
14580   return 0;
14581 }
14582
14583 static int
14584 api_lisp_adjacencies_get (vat_main_t * vam)
14585 {
14586   unformat_input_t *i = vam->input;
14587   vl_api_lisp_adjacencies_get_t *mp;
14588   f64 timeout = ~0;
14589   u8 vni_set = 0;
14590   u32 vni = ~0;
14591
14592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14593     {
14594       if (unformat (i, "vni %d", &vni))
14595         {
14596           vni_set = 1;
14597         }
14598       else
14599         {
14600           errmsg ("parse error '%U'", format_unformat_error, i);
14601           return -99;
14602         }
14603     }
14604
14605   if (!vni_set)
14606     {
14607       errmsg ("vni not set!");
14608       return -99;
14609     }
14610
14611   if (!vam->json_output)
14612     {
14613       print (vam->ofp, "%s %40s", "leid", "reid");
14614     }
14615
14616   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14617   mp->vni = clib_host_to_net_u32 (vni);
14618
14619   /* send it... */
14620   S;
14621
14622   /* Wait for a reply... */
14623   W;
14624
14625   /* NOTREACHED */
14626   return 0;
14627 }
14628
14629 static int
14630 api_lisp_map_server_dump (vat_main_t * vam)
14631 {
14632   vl_api_lisp_map_server_dump_t *mp;
14633   f64 timeout = ~0;
14634
14635   if (!vam->json_output)
14636     {
14637       print (vam->ofp, "%=20s", "Map server");
14638     }
14639
14640   M (LISP_MAP_SERVER_DUMP, lisp_map_server_dump);
14641   /* send it... */
14642   S;
14643
14644   /* Use a control ping for synchronization */
14645   {
14646     vl_api_control_ping_t *mp;
14647     M (CONTROL_PING, control_ping);
14648     S;
14649   }
14650   /* Wait for a reply... */
14651   W;
14652
14653   /* NOTREACHED */
14654   return 0;
14655 }
14656
14657 static int
14658 api_lisp_map_resolver_dump (vat_main_t * vam)
14659 {
14660   vl_api_lisp_map_resolver_dump_t *mp;
14661   f64 timeout = ~0;
14662
14663   if (!vam->json_output)
14664     {
14665       print (vam->ofp, "%=20s", "Map resolver");
14666     }
14667
14668   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14669   /* send it... */
14670   S;
14671
14672   /* Use a control ping for synchronization */
14673   {
14674     vl_api_control_ping_t *mp;
14675     M (CONTROL_PING, control_ping);
14676     S;
14677   }
14678   /* Wait for a reply... */
14679   W;
14680
14681   /* NOTREACHED */
14682   return 0;
14683 }
14684
14685 static int
14686 api_show_lisp_status (vat_main_t * vam)
14687 {
14688   vl_api_show_lisp_status_t *mp;
14689   f64 timeout = ~0;
14690
14691   if (!vam->json_output)
14692     {
14693       print (vam->ofp, "%-20s%-16s", "lisp status", "locator-set");
14694     }
14695
14696   M (SHOW_LISP_STATUS, show_lisp_status);
14697   /* send it... */
14698   S;
14699   /* Wait for a reply... */
14700   W;
14701
14702   /* NOTREACHED */
14703   return 0;
14704 }
14705
14706 static int
14707 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14708 {
14709   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14710   f64 timeout = ~0;
14711
14712   if (!vam->json_output)
14713     {
14714       print (vam->ofp, "%=20s", "itr-rlocs:");
14715     }
14716
14717   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14718   /* send it... */
14719   S;
14720   /* Wait for a reply... */
14721   W;
14722
14723   /* NOTREACHED */
14724   return 0;
14725 }
14726
14727 static int
14728 api_af_packet_create (vat_main_t * vam)
14729 {
14730   unformat_input_t *i = vam->input;
14731   vl_api_af_packet_create_t *mp;
14732   f64 timeout;
14733   u8 *host_if_name = 0;
14734   u8 hw_addr[6];
14735   u8 random_hw_addr = 1;
14736
14737   memset (hw_addr, 0, sizeof (hw_addr));
14738
14739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14740     {
14741       if (unformat (i, "name %s", &host_if_name))
14742         vec_add1 (host_if_name, 0);
14743       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14744         random_hw_addr = 0;
14745       else
14746         break;
14747     }
14748
14749   if (!vec_len (host_if_name))
14750     {
14751       errmsg ("host-interface name must be specified");
14752       return -99;
14753     }
14754
14755   if (vec_len (host_if_name) > 64)
14756     {
14757       errmsg ("host-interface name too long");
14758       return -99;
14759     }
14760
14761   M (AF_PACKET_CREATE, af_packet_create);
14762
14763   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14764   clib_memcpy (mp->hw_addr, hw_addr, 6);
14765   mp->use_random_hw_addr = random_hw_addr;
14766   vec_free (host_if_name);
14767
14768   S;
14769   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14770   /* NOTREACHED */
14771   return 0;
14772 }
14773
14774 static int
14775 api_af_packet_delete (vat_main_t * vam)
14776 {
14777   unformat_input_t *i = vam->input;
14778   vl_api_af_packet_delete_t *mp;
14779   f64 timeout;
14780   u8 *host_if_name = 0;
14781
14782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14783     {
14784       if (unformat (i, "name %s", &host_if_name))
14785         vec_add1 (host_if_name, 0);
14786       else
14787         break;
14788     }
14789
14790   if (!vec_len (host_if_name))
14791     {
14792       errmsg ("host-interface name must be specified");
14793       return -99;
14794     }
14795
14796   if (vec_len (host_if_name) > 64)
14797     {
14798       errmsg ("host-interface name too long");
14799       return -99;
14800     }
14801
14802   M (AF_PACKET_DELETE, af_packet_delete);
14803
14804   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14805   vec_free (host_if_name);
14806
14807   S;
14808   W;
14809   /* NOTREACHED */
14810   return 0;
14811 }
14812
14813 static int
14814 api_policer_add_del (vat_main_t * vam)
14815 {
14816   unformat_input_t *i = vam->input;
14817   vl_api_policer_add_del_t *mp;
14818   f64 timeout;
14819   u8 is_add = 1;
14820   u8 *name = 0;
14821   u32 cir = 0;
14822   u32 eir = 0;
14823   u64 cb = 0;
14824   u64 eb = 0;
14825   u8 rate_type = 0;
14826   u8 round_type = 0;
14827   u8 type = 0;
14828   u8 color_aware = 0;
14829   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14830
14831   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14832   conform_action.dscp = 0;
14833   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14834   exceed_action.dscp = 0;
14835   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14836   violate_action.dscp = 0;
14837
14838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14839     {
14840       if (unformat (i, "del"))
14841         is_add = 0;
14842       else if (unformat (i, "name %s", &name))
14843         vec_add1 (name, 0);
14844       else if (unformat (i, "cir %u", &cir))
14845         ;
14846       else if (unformat (i, "eir %u", &eir))
14847         ;
14848       else if (unformat (i, "cb %u", &cb))
14849         ;
14850       else if (unformat (i, "eb %u", &eb))
14851         ;
14852       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14853                          &rate_type))
14854         ;
14855       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14856                          &round_type))
14857         ;
14858       else if (unformat (i, "type %U", unformat_policer_type, &type))
14859         ;
14860       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14861                          &conform_action))
14862         ;
14863       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14864                          &exceed_action))
14865         ;
14866       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14867                          &violate_action))
14868         ;
14869       else if (unformat (i, "color-aware"))
14870         color_aware = 1;
14871       else
14872         break;
14873     }
14874
14875   if (!vec_len (name))
14876     {
14877       errmsg ("policer name must be specified");
14878       return -99;
14879     }
14880
14881   if (vec_len (name) > 64)
14882     {
14883       errmsg ("policer name too long");
14884       return -99;
14885     }
14886
14887   M (POLICER_ADD_DEL, policer_add_del);
14888
14889   clib_memcpy (mp->name, name, vec_len (name));
14890   vec_free (name);
14891   mp->is_add = is_add;
14892   mp->cir = cir;
14893   mp->eir = eir;
14894   mp->cb = cb;
14895   mp->eb = eb;
14896   mp->rate_type = rate_type;
14897   mp->round_type = round_type;
14898   mp->type = type;
14899   mp->conform_action_type = conform_action.action_type;
14900   mp->conform_dscp = conform_action.dscp;
14901   mp->exceed_action_type = exceed_action.action_type;
14902   mp->exceed_dscp = exceed_action.dscp;
14903   mp->violate_action_type = violate_action.action_type;
14904   mp->violate_dscp = violate_action.dscp;
14905   mp->color_aware = color_aware;
14906
14907   S;
14908   W;
14909   /* NOTREACHED */
14910   return 0;
14911 }
14912
14913 static int
14914 api_policer_dump (vat_main_t * vam)
14915 {
14916   unformat_input_t *i = vam->input;
14917   vl_api_policer_dump_t *mp;
14918   f64 timeout = ~0;
14919   u8 *match_name = 0;
14920   u8 match_name_valid = 0;
14921
14922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14923     {
14924       if (unformat (i, "name %s", &match_name))
14925         {
14926           vec_add1 (match_name, 0);
14927           match_name_valid = 1;
14928         }
14929       else
14930         break;
14931     }
14932
14933   M (POLICER_DUMP, policer_dump);
14934   mp->match_name_valid = match_name_valid;
14935   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14936   vec_free (match_name);
14937   /* send it... */
14938   S;
14939
14940   /* Use a control ping for synchronization */
14941   {
14942     vl_api_control_ping_t *mp;
14943     M (CONTROL_PING, control_ping);
14944     S;
14945   }
14946   /* Wait for a reply... */
14947   W;
14948
14949   /* NOTREACHED */
14950   return 0;
14951 }
14952
14953 static int
14954 api_policer_classify_set_interface (vat_main_t * vam)
14955 {
14956   unformat_input_t *i = vam->input;
14957   vl_api_policer_classify_set_interface_t *mp;
14958   f64 timeout;
14959   u32 sw_if_index;
14960   int sw_if_index_set;
14961   u32 ip4_table_index = ~0;
14962   u32 ip6_table_index = ~0;
14963   u32 l2_table_index = ~0;
14964   u8 is_add = 1;
14965
14966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14967     {
14968       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14969         sw_if_index_set = 1;
14970       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14971         sw_if_index_set = 1;
14972       else if (unformat (i, "del"))
14973         is_add = 0;
14974       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14975         ;
14976       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14977         ;
14978       else if (unformat (i, "l2-table %d", &l2_table_index))
14979         ;
14980       else
14981         {
14982           clib_warning ("parse error '%U'", format_unformat_error, i);
14983           return -99;
14984         }
14985     }
14986
14987   if (sw_if_index_set == 0)
14988     {
14989       errmsg ("missing interface name or sw_if_index");
14990       return -99;
14991     }
14992
14993   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14994
14995   mp->sw_if_index = ntohl (sw_if_index);
14996   mp->ip4_table_index = ntohl (ip4_table_index);
14997   mp->ip6_table_index = ntohl (ip6_table_index);
14998   mp->l2_table_index = ntohl (l2_table_index);
14999   mp->is_add = is_add;
15000
15001   S;
15002   W;
15003   /* NOTREACHED */
15004   return 0;
15005 }
15006
15007 static int
15008 api_policer_classify_dump (vat_main_t * vam)
15009 {
15010   unformat_input_t *i = vam->input;
15011   vl_api_policer_classify_dump_t *mp;
15012   f64 timeout = ~0;
15013   u8 type = POLICER_CLASSIFY_N_TABLES;
15014
15015   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15016     ;
15017   else
15018     {
15019       errmsg ("classify table type must be specified");
15020       return -99;
15021     }
15022
15023   if (!vam->json_output)
15024     {
15025       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
15026     }
15027
15028   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
15029   mp->type = type;
15030   /* send it... */
15031   S;
15032
15033   /* Use a control ping for synchronization */
15034   {
15035     vl_api_control_ping_t *mp;
15036     M (CONTROL_PING, control_ping);
15037     S;
15038   }
15039   /* Wait for a reply... */
15040   W;
15041
15042   /* NOTREACHED */
15043   return 0;
15044 }
15045
15046 static int
15047 api_netmap_create (vat_main_t * vam)
15048 {
15049   unformat_input_t *i = vam->input;
15050   vl_api_netmap_create_t *mp;
15051   f64 timeout;
15052   u8 *if_name = 0;
15053   u8 hw_addr[6];
15054   u8 random_hw_addr = 1;
15055   u8 is_pipe = 0;
15056   u8 is_master = 0;
15057
15058   memset (hw_addr, 0, sizeof (hw_addr));
15059
15060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15061     {
15062       if (unformat (i, "name %s", &if_name))
15063         vec_add1 (if_name, 0);
15064       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15065         random_hw_addr = 0;
15066       else if (unformat (i, "pipe"))
15067         is_pipe = 1;
15068       else if (unformat (i, "master"))
15069         is_master = 1;
15070       else if (unformat (i, "slave"))
15071         is_master = 0;
15072       else
15073         break;
15074     }
15075
15076   if (!vec_len (if_name))
15077     {
15078       errmsg ("interface name must be specified");
15079       return -99;
15080     }
15081
15082   if (vec_len (if_name) > 64)
15083     {
15084       errmsg ("interface name too long");
15085       return -99;
15086     }
15087
15088   M (NETMAP_CREATE, netmap_create);
15089
15090   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15091   clib_memcpy (mp->hw_addr, hw_addr, 6);
15092   mp->use_random_hw_addr = random_hw_addr;
15093   mp->is_pipe = is_pipe;
15094   mp->is_master = is_master;
15095   vec_free (if_name);
15096
15097   S;
15098   W;
15099   /* NOTREACHED */
15100   return 0;
15101 }
15102
15103 static int
15104 api_netmap_delete (vat_main_t * vam)
15105 {
15106   unformat_input_t *i = vam->input;
15107   vl_api_netmap_delete_t *mp;
15108   f64 timeout;
15109   u8 *if_name = 0;
15110
15111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15112     {
15113       if (unformat (i, "name %s", &if_name))
15114         vec_add1 (if_name, 0);
15115       else
15116         break;
15117     }
15118
15119   if (!vec_len (if_name))
15120     {
15121       errmsg ("interface name must be specified");
15122       return -99;
15123     }
15124
15125   if (vec_len (if_name) > 64)
15126     {
15127       errmsg ("interface name too long");
15128       return -99;
15129     }
15130
15131   M (NETMAP_DELETE, netmap_delete);
15132
15133   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15134   vec_free (if_name);
15135
15136   S;
15137   W;
15138   /* NOTREACHED */
15139   return 0;
15140 }
15141
15142 static void vl_api_mpls_tunnel_details_t_handler
15143   (vl_api_mpls_tunnel_details_t * mp)
15144 {
15145   vat_main_t *vam = &vat_main;
15146   i32 len = mp->mt_next_hop_n_labels;
15147   i32 i;
15148
15149   print (vam->ofp, "[%d]: via %U %d labels ",
15150          mp->tunnel_index,
15151          format_ip4_address, mp->mt_next_hop,
15152          ntohl (mp->mt_next_hop_sw_if_index));
15153   for (i = 0; i < len; i++)
15154     {
15155       print (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15156     }
15157   print (vam->ofp, "");
15158 }
15159
15160 static void vl_api_mpls_tunnel_details_t_handler_json
15161   (vl_api_mpls_tunnel_details_t * mp)
15162 {
15163   vat_main_t *vam = &vat_main;
15164   vat_json_node_t *node = NULL;
15165   struct in_addr ip4;
15166   i32 i;
15167   i32 len = mp->mt_next_hop_n_labels;
15168
15169   if (VAT_JSON_ARRAY != vam->json_tree.type)
15170     {
15171       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15172       vat_json_init_array (&vam->json_tree);
15173     }
15174   node = vat_json_array_add (&vam->json_tree);
15175
15176   vat_json_init_object (node);
15177   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15178   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15179   vat_json_object_add_ip4 (node, "next_hop", ip4);
15180   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15181                             ntohl (mp->mt_next_hop_sw_if_index));
15182   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15183   vat_json_object_add_uint (node, "label_count", len);
15184   for (i = 0; i < len; i++)
15185     {
15186       vat_json_object_add_uint (node, "label",
15187                                 ntohl (mp->mt_next_hop_out_labels[i]));
15188     }
15189 }
15190
15191 static int
15192 api_mpls_tunnel_dump (vat_main_t * vam)
15193 {
15194   vl_api_mpls_tunnel_dump_t *mp;
15195   f64 timeout;
15196   i32 index = -1;
15197
15198   /* Parse args required to build the message */
15199   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15200     {
15201       if (!unformat (vam->input, "tunnel_index %d", &index))
15202         {
15203           index = -1;
15204           break;
15205         }
15206     }
15207
15208   print (vam->ofp, "  tunnel_index %d", index);
15209
15210   M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
15211   mp->tunnel_index = htonl (index);
15212   S;
15213
15214   /* Use a control ping for synchronization */
15215   {
15216     vl_api_control_ping_t *mp;
15217     M (CONTROL_PING, control_ping);
15218     S;
15219   }
15220   W;
15221 }
15222
15223 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15224 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15225
15226 static void
15227 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15228 {
15229   vat_main_t *vam = &vat_main;
15230   int count = ntohl (mp->count);
15231   vl_api_fib_path2_t *fp;
15232   int i;
15233
15234   print (vam->ofp,
15235          "table-id %d, label %u, ess_bit %u",
15236          ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15237   fp = mp->path;
15238   for (i = 0; i < count; i++)
15239     {
15240       if (fp->afi == IP46_TYPE_IP6)
15241         print (vam->ofp,
15242                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15243                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15244                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15245                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15246                format_ip6_address, fp->next_hop);
15247       else if (fp->afi == IP46_TYPE_IP4)
15248         print (vam->ofp,
15249                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15250                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15251                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15252                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15253                format_ip4_address, fp->next_hop);
15254       fp++;
15255     }
15256 }
15257
15258 static void vl_api_mpls_fib_details_t_handler_json
15259   (vl_api_mpls_fib_details_t * mp)
15260 {
15261   vat_main_t *vam = &vat_main;
15262   int count = ntohl (mp->count);
15263   vat_json_node_t *node = NULL;
15264   struct in_addr ip4;
15265   struct in6_addr ip6;
15266   vl_api_fib_path2_t *fp;
15267   int i;
15268
15269   if (VAT_JSON_ARRAY != vam->json_tree.type)
15270     {
15271       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15272       vat_json_init_array (&vam->json_tree);
15273     }
15274   node = vat_json_array_add (&vam->json_tree);
15275
15276   vat_json_init_object (node);
15277   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15278   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15279   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15280   vat_json_object_add_uint (node, "path_count", count);
15281   fp = mp->path;
15282   for (i = 0; i < count; i++)
15283     {
15284       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15285       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15286       vat_json_object_add_uint (node, "is_local", fp->is_local);
15287       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15288       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15289       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15290       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15291       if (fp->afi == IP46_TYPE_IP4)
15292         {
15293           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15294           vat_json_object_add_ip4 (node, "next_hop", ip4);
15295         }
15296       else if (fp->afi == IP46_TYPE_IP6)
15297         {
15298           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15299           vat_json_object_add_ip6 (node, "next_hop", ip6);
15300         }
15301     }
15302 }
15303
15304 static int
15305 api_mpls_fib_dump (vat_main_t * vam)
15306 {
15307   vl_api_mpls_fib_dump_t *mp;
15308   f64 timeout;
15309
15310   M (MPLS_FIB_DUMP, mpls_fib_dump);
15311   S;
15312
15313   /* Use a control ping for synchronization */
15314   {
15315     vl_api_control_ping_t *mp;
15316     M (CONTROL_PING, control_ping);
15317     S;
15318   }
15319   W;
15320 }
15321
15322 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15323 #define vl_api_ip_fib_details_t_print vl_noop_handler
15324
15325 static void
15326 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15327 {
15328   vat_main_t *vam = &vat_main;
15329   int count = ntohl (mp->count);
15330   vl_api_fib_path_t *fp;
15331   int i;
15332
15333   print (vam->ofp,
15334          "table-id %d, prefix %U/%d",
15335          ntohl (mp->table_id), format_ip4_address, mp->address,
15336          mp->address_length);
15337   fp = mp->path;
15338   for (i = 0; i < count; i++)
15339     {
15340       if (fp->afi == IP46_TYPE_IP6)
15341         print (vam->ofp,
15342                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15343                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15344                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15345                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15346                format_ip6_address, fp->next_hop);
15347       else if (fp->afi == IP46_TYPE_IP4)
15348         print (vam->ofp,
15349                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15350                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15351                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15352                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15353                format_ip4_address, fp->next_hop);
15354       fp++;
15355     }
15356 }
15357
15358 static void vl_api_ip_fib_details_t_handler_json
15359   (vl_api_ip_fib_details_t * mp)
15360 {
15361   vat_main_t *vam = &vat_main;
15362   int count = ntohl (mp->count);
15363   vat_json_node_t *node = NULL;
15364   struct in_addr ip4;
15365   struct in6_addr ip6;
15366   vl_api_fib_path_t *fp;
15367   int i;
15368
15369   if (VAT_JSON_ARRAY != vam->json_tree.type)
15370     {
15371       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15372       vat_json_init_array (&vam->json_tree);
15373     }
15374   node = vat_json_array_add (&vam->json_tree);
15375
15376   vat_json_init_object (node);
15377   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15378   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15379   vat_json_object_add_ip4 (node, "prefix", ip4);
15380   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15381   vat_json_object_add_uint (node, "path_count", count);
15382   fp = mp->path;
15383   for (i = 0; i < count; i++)
15384     {
15385       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15386       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15387       vat_json_object_add_uint (node, "is_local", fp->is_local);
15388       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15389       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15390       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15391       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15392       if (fp->afi == IP46_TYPE_IP4)
15393         {
15394           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15395           vat_json_object_add_ip4 (node, "next_hop", ip4);
15396         }
15397       else if (fp->afi == IP46_TYPE_IP6)
15398         {
15399           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15400           vat_json_object_add_ip6 (node, "next_hop", ip6);
15401         }
15402     }
15403 }
15404
15405 static int
15406 api_ip_fib_dump (vat_main_t * vam)
15407 {
15408   vl_api_ip_fib_dump_t *mp;
15409   f64 timeout;
15410
15411   M (IP_FIB_DUMP, ip_fib_dump);
15412   S;
15413
15414   /* Use a control ping for synchronization */
15415   {
15416     vl_api_control_ping_t *mp;
15417     M (CONTROL_PING, control_ping);
15418     S;
15419   }
15420   W;
15421 }
15422
15423 static void vl_api_ip_neighbor_details_t_handler
15424   (vl_api_ip_neighbor_details_t * mp)
15425 {
15426   vat_main_t *vam = &vat_main;
15427
15428   print (vam->ofp, "%c %U %U",
15429          (mp->is_static) ? 'S' : 'D',
15430          format_ethernet_address, &mp->mac_address,
15431          (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15432          &mp->ip_address);
15433 }
15434
15435 static void vl_api_ip_neighbor_details_t_handler_json
15436   (vl_api_ip_neighbor_details_t * mp)
15437 {
15438
15439   vat_main_t *vam = &vat_main;
15440   vat_json_node_t *node;
15441   struct in_addr ip4;
15442   struct in6_addr ip6;
15443
15444   if (VAT_JSON_ARRAY != vam->json_tree.type)
15445     {
15446       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15447       vat_json_init_array (&vam->json_tree);
15448     }
15449   node = vat_json_array_add (&vam->json_tree);
15450
15451   vat_json_init_object (node);
15452   vat_json_object_add_string_copy (node, "flag",
15453                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15454                                    "dynamic");
15455
15456   vat_json_object_add_string_copy (node, "link_layer",
15457                                    format (0, "%U", format_ethernet_address,
15458                                            &mp->mac_address));
15459
15460   if (mp->is_ipv6)
15461     {
15462       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15463       vat_json_object_add_ip6 (node, "ip_address", ip6);
15464     }
15465   else
15466     {
15467       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15468       vat_json_object_add_ip4 (node, "ip_address", ip4);
15469     }
15470 }
15471
15472 static int
15473 api_ip_neighbor_dump (vat_main_t * vam)
15474 {
15475   unformat_input_t *i = vam->input;
15476   vl_api_ip_neighbor_dump_t *mp;
15477   f64 timeout;
15478   u8 is_ipv6 = 0;
15479   u32 sw_if_index = ~0;
15480
15481   /* Parse args required to build the message */
15482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15483     {
15484       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15485         ;
15486       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15487         ;
15488       else if (unformat (i, "ip6"))
15489         is_ipv6 = 1;
15490       else
15491         break;
15492     }
15493
15494   if (sw_if_index == ~0)
15495     {
15496       errmsg ("missing interface name or sw_if_index");
15497       return -99;
15498     }
15499
15500   M (IP_NEIGHBOR_DUMP, ip_neighbor_dump);
15501   mp->is_ipv6 = (u8) is_ipv6;
15502   mp->sw_if_index = ntohl (sw_if_index);
15503   S;
15504
15505   /* Use a control ping for synchronization */
15506   {
15507     vl_api_control_ping_t *mp;
15508     M (CONTROL_PING, control_ping);
15509     S;
15510   }
15511   W;
15512 }
15513
15514 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15515 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15516
15517 static void
15518 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15519 {
15520   vat_main_t *vam = &vat_main;
15521   int count = ntohl (mp->count);
15522   vl_api_fib_path_t *fp;
15523   int i;
15524
15525   print (vam->ofp,
15526          "table-id %d, prefix %U/%d",
15527          ntohl (mp->table_id), format_ip6_address, mp->address,
15528          mp->address_length);
15529   fp = mp->path;
15530   for (i = 0; i < count; i++)
15531     {
15532       if (fp->afi == IP46_TYPE_IP6)
15533         print (vam->ofp,
15534                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15535                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15536                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15537                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15538                format_ip6_address, fp->next_hop);
15539       else if (fp->afi == IP46_TYPE_IP4)
15540         print (vam->ofp,
15541                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15542                "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U",
15543                ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15544                fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15545                format_ip4_address, fp->next_hop);
15546       fp++;
15547     }
15548 }
15549
15550 static void vl_api_ip6_fib_details_t_handler_json
15551   (vl_api_ip6_fib_details_t * mp)
15552 {
15553   vat_main_t *vam = &vat_main;
15554   int count = ntohl (mp->count);
15555   vat_json_node_t *node = NULL;
15556   struct in_addr ip4;
15557   struct in6_addr ip6;
15558   vl_api_fib_path_t *fp;
15559   int i;
15560
15561   if (VAT_JSON_ARRAY != vam->json_tree.type)
15562     {
15563       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15564       vat_json_init_array (&vam->json_tree);
15565     }
15566   node = vat_json_array_add (&vam->json_tree);
15567
15568   vat_json_init_object (node);
15569   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15570   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15571   vat_json_object_add_ip6 (node, "prefix", ip6);
15572   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15573   vat_json_object_add_uint (node, "path_count", count);
15574   fp = mp->path;
15575   for (i = 0; i < count; i++)
15576     {
15577       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15578       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15579       vat_json_object_add_uint (node, "is_local", fp->is_local);
15580       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15581       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15582       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15583       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15584       if (fp->afi == IP46_TYPE_IP4)
15585         {
15586           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15587           vat_json_object_add_ip4 (node, "next_hop", ip4);
15588         }
15589       else if (fp->afi == IP46_TYPE_IP6)
15590         {
15591           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15592           vat_json_object_add_ip6 (node, "next_hop", ip6);
15593         }
15594     }
15595 }
15596
15597 static int
15598 api_ip6_fib_dump (vat_main_t * vam)
15599 {
15600   vl_api_ip6_fib_dump_t *mp;
15601   f64 timeout;
15602
15603   M (IP6_FIB_DUMP, ip6_fib_dump);
15604   S;
15605
15606   /* Use a control ping for synchronization */
15607   {
15608     vl_api_control_ping_t *mp;
15609     M (CONTROL_PING, control_ping);
15610     S;
15611   }
15612   W;
15613 }
15614
15615 int
15616 api_classify_table_ids (vat_main_t * vam)
15617 {
15618   vl_api_classify_table_ids_t *mp;
15619   f64 timeout;
15620
15621   /* Construct the API message */
15622   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15623   mp->context = 0;
15624
15625   S;
15626   W;
15627   /* NOTREACHED */
15628   return 0;
15629 }
15630
15631 int
15632 api_classify_table_by_interface (vat_main_t * vam)
15633 {
15634   unformat_input_t *input = vam->input;
15635   vl_api_classify_table_by_interface_t *mp;
15636   f64 timeout;
15637
15638   u32 sw_if_index = ~0;
15639   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15640     {
15641       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
15642         ;
15643       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15644         ;
15645       else
15646         break;
15647     }
15648   if (sw_if_index == ~0)
15649     {
15650       errmsg ("missing interface name or sw_if_index");
15651       return -99;
15652     }
15653
15654   /* Construct the API message */
15655   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15656   mp->context = 0;
15657   mp->sw_if_index = ntohl (sw_if_index);
15658
15659   S;
15660   W;
15661   /* NOTREACHED */
15662   return 0;
15663 }
15664
15665 int
15666 api_classify_table_info (vat_main_t * vam)
15667 {
15668   unformat_input_t *input = vam->input;
15669   vl_api_classify_table_info_t *mp;
15670   f64 timeout;
15671
15672   u32 table_id = ~0;
15673   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15674     {
15675       if (unformat (input, "table_id %d", &table_id))
15676         ;
15677       else
15678         break;
15679     }
15680   if (table_id == ~0)
15681     {
15682       errmsg ("missing table id");
15683       return -99;
15684     }
15685
15686   /* Construct the API message */
15687   M (CLASSIFY_TABLE_INFO, classify_table_info);
15688   mp->context = 0;
15689   mp->table_id = ntohl (table_id);
15690
15691   S;
15692   W;
15693   /* NOTREACHED */
15694   return 0;
15695 }
15696
15697 int
15698 api_classify_session_dump (vat_main_t * vam)
15699 {
15700   unformat_input_t *input = vam->input;
15701   vl_api_classify_session_dump_t *mp;
15702   f64 timeout;
15703
15704   u32 table_id = ~0;
15705   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15706     {
15707       if (unformat (input, "table_id %d", &table_id))
15708         ;
15709       else
15710         break;
15711     }
15712   if (table_id == ~0)
15713     {
15714       errmsg ("missing table id");
15715       return -99;
15716     }
15717
15718   /* Construct the API message */
15719   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15720   mp->context = 0;
15721   mp->table_id = ntohl (table_id);
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   /* NOTREACHED */
15732   return 0;
15733 }
15734
15735 static void
15736 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15737 {
15738   vat_main_t *vam = &vat_main;
15739
15740   print (vam->ofp, "collector_address %U, collector_port %d, "
15741          "src_address %U, vrf_id %d, path_mtu %u, "
15742          "template_interval %u, udp_checksum %d",
15743          format_ip4_address, mp->collector_address,
15744          ntohs (mp->collector_port),
15745          format_ip4_address, mp->src_address,
15746          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15747          ntohl (mp->template_interval), mp->udp_checksum);
15748
15749   vam->retval = 0;
15750   vam->result_ready = 1;
15751 }
15752
15753 static void
15754   vl_api_ipfix_exporter_details_t_handler_json
15755   (vl_api_ipfix_exporter_details_t * mp)
15756 {
15757   vat_main_t *vam = &vat_main;
15758   vat_json_node_t node;
15759   struct in_addr collector_address;
15760   struct in_addr src_address;
15761
15762   vat_json_init_object (&node);
15763   clib_memcpy (&collector_address, &mp->collector_address,
15764                sizeof (collector_address));
15765   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15766   vat_json_object_add_uint (&node, "collector_port",
15767                             ntohs (mp->collector_port));
15768   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15769   vat_json_object_add_ip4 (&node, "src_address", src_address);
15770   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15771   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15772   vat_json_object_add_uint (&node, "template_interval",
15773                             ntohl (mp->template_interval));
15774   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15775
15776   vat_json_print (vam->ofp, &node);
15777   vat_json_free (&node);
15778   vam->retval = 0;
15779   vam->result_ready = 1;
15780 }
15781
15782 int
15783 api_ipfix_exporter_dump (vat_main_t * vam)
15784 {
15785   vl_api_ipfix_exporter_dump_t *mp;
15786   f64 timeout;
15787
15788   /* Construct the API message */
15789   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15790   mp->context = 0;
15791
15792   S;
15793   W;
15794   /* NOTREACHED */
15795   return 0;
15796 }
15797
15798 static int
15799 api_ipfix_classify_stream_dump (vat_main_t * vam)
15800 {
15801   vl_api_ipfix_classify_stream_dump_t *mp;
15802   f64 timeout;
15803
15804   /* Construct the API message */
15805   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15806   mp->context = 0;
15807
15808   S;
15809   W;
15810   /* NOTREACHED */
15811   return 0;
15812 }
15813
15814 static void
15815   vl_api_ipfix_classify_stream_details_t_handler
15816   (vl_api_ipfix_classify_stream_details_t * mp)
15817 {
15818   vat_main_t *vam = &vat_main;
15819   print (vam->ofp, "domain_id %d, src_port %d",
15820          ntohl (mp->domain_id), ntohs (mp->src_port));
15821   vam->retval = 0;
15822   vam->result_ready = 1;
15823 }
15824
15825 static void
15826   vl_api_ipfix_classify_stream_details_t_handler_json
15827   (vl_api_ipfix_classify_stream_details_t * mp)
15828 {
15829   vat_main_t *vam = &vat_main;
15830   vat_json_node_t node;
15831
15832   vat_json_init_object (&node);
15833   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15834   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15835
15836   vat_json_print (vam->ofp, &node);
15837   vat_json_free (&node);
15838   vam->retval = 0;
15839   vam->result_ready = 1;
15840 }
15841
15842 static int
15843 api_ipfix_classify_table_dump (vat_main_t * vam)
15844 {
15845   vl_api_ipfix_classify_table_dump_t *mp;
15846   f64 timeout;
15847
15848   if (!vam->json_output)
15849     {
15850       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
15851              "transport_protocol");
15852     }
15853
15854   /* Construct the API message */
15855   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15856
15857   /* send it... */
15858   S;
15859
15860   /* Use a control ping for synchronization */
15861   {
15862     vl_api_control_ping_t *mp;
15863     M (CONTROL_PING, control_ping);
15864     S;
15865   }
15866   W;
15867 }
15868
15869 static void
15870   vl_api_ipfix_classify_table_details_t_handler
15871   (vl_api_ipfix_classify_table_details_t * mp)
15872 {
15873   vat_main_t *vam = &vat_main;
15874   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
15875          mp->transport_protocol);
15876 }
15877
15878 static void
15879   vl_api_ipfix_classify_table_details_t_handler_json
15880   (vl_api_ipfix_classify_table_details_t * mp)
15881 {
15882   vat_json_node_t *node = NULL;
15883   vat_main_t *vam = &vat_main;
15884
15885   if (VAT_JSON_ARRAY != vam->json_tree.type)
15886     {
15887       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15888       vat_json_init_array (&vam->json_tree);
15889     }
15890
15891   node = vat_json_array_add (&vam->json_tree);
15892   vat_json_init_object (node);
15893
15894   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15895   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15896   vat_json_object_add_uint (node, "transport_protocol",
15897                             mp->transport_protocol);
15898 }
15899
15900 static int
15901 api_sw_interface_span_enable_disable (vat_main_t * vam)
15902 {
15903   unformat_input_t *i = vam->input;
15904   vl_api_sw_interface_span_enable_disable_t *mp;
15905   f64 timeout;
15906   u32 src_sw_if_index = ~0;
15907   u32 dst_sw_if_index = ~0;
15908   u8 state = 3;
15909
15910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15911     {
15912       if (unformat
15913           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
15914         ;
15915       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15916         ;
15917       else
15918         if (unformat
15919             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
15920         ;
15921       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15922         ;
15923       else if (unformat (i, "disable"))
15924         state = 0;
15925       else if (unformat (i, "rx"))
15926         state = 1;
15927       else if (unformat (i, "tx"))
15928         state = 2;
15929       else if (unformat (i, "both"))
15930         state = 3;
15931       else
15932         break;
15933     }
15934
15935   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15936
15937   mp->sw_if_index_from = htonl (src_sw_if_index);
15938   mp->sw_if_index_to = htonl (dst_sw_if_index);
15939   mp->state = state;
15940
15941   S;
15942   W;
15943   /* NOTREACHED */
15944   return 0;
15945 }
15946
15947 static void
15948 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
15949                                             * mp)
15950 {
15951   vat_main_t *vam = &vat_main;
15952   u8 *sw_if_from_name = 0;
15953   u8 *sw_if_to_name = 0;
15954   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
15955   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
15956   char *states[] = { "none", "rx", "tx", "both" };
15957   hash_pair_t *p;
15958
15959   /* *INDENT-OFF* */
15960   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
15961   ({
15962     if ((u32) p->value[0] == sw_if_index_from)
15963       {
15964         sw_if_from_name = (u8 *)(p->key);
15965         if (sw_if_to_name)
15966           break;
15967       }
15968     if ((u32) p->value[0] == sw_if_index_to)
15969       {
15970         sw_if_to_name = (u8 *)(p->key);
15971         if (sw_if_from_name)
15972           break;
15973       }
15974   }));
15975   /* *INDENT-ON* */
15976   print (vam->ofp, "%20s => %20s (%s)",
15977          sw_if_from_name, sw_if_to_name, states[mp->state]);
15978 }
15979
15980 static void
15981   vl_api_sw_interface_span_details_t_handler_json
15982   (vl_api_sw_interface_span_details_t * mp)
15983 {
15984   vat_main_t *vam = &vat_main;
15985   vat_json_node_t *node = NULL;
15986   u8 *sw_if_from_name = 0;
15987   u8 *sw_if_to_name = 0;
15988   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
15989   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
15990   hash_pair_t *p;
15991
15992   /* *INDENT-OFF* */
15993   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
15994   ({
15995     if ((u32) p->value[0] == sw_if_index_from)
15996       {
15997         sw_if_from_name = (u8 *)(p->key);
15998         if (sw_if_to_name)
15999           break;
16000       }
16001     if ((u32) p->value[0] == sw_if_index_to)
16002       {
16003         sw_if_to_name = (u8 *)(p->key);
16004         if (sw_if_from_name)
16005           break;
16006       }
16007   }));
16008   /* *INDENT-ON* */
16009
16010   if (VAT_JSON_ARRAY != vam->json_tree.type)
16011     {
16012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16013       vat_json_init_array (&vam->json_tree);
16014     }
16015   node = vat_json_array_add (&vam->json_tree);
16016
16017   vat_json_init_object (node);
16018   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16019   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16020   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16021   vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16022   vat_json_object_add_uint (node, "state", mp->state);
16023 }
16024
16025 static int
16026 api_sw_interface_span_dump (vat_main_t * vam)
16027 {
16028   vl_api_sw_interface_span_dump_t *mp;
16029   f64 timeout;
16030
16031   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
16032   S;
16033
16034   /* Use a control ping for synchronization */
16035   {
16036     vl_api_control_ping_t *mp;
16037     M (CONTROL_PING, control_ping);
16038     S;
16039   }
16040   W;
16041 }
16042
16043 int
16044 api_pg_create_interface (vat_main_t * vam)
16045 {
16046   unformat_input_t *input = vam->input;
16047   vl_api_pg_create_interface_t *mp;
16048   f64 timeout;
16049
16050   u32 if_id = ~0;
16051   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16052     {
16053       if (unformat (input, "if_id %d", &if_id))
16054         ;
16055       else
16056         break;
16057     }
16058   if (if_id == ~0)
16059     {
16060       errmsg ("missing pg interface index");
16061       return -99;
16062     }
16063
16064   /* Construct the API message */
16065   M (PG_CREATE_INTERFACE, pg_create_interface);
16066   mp->context = 0;
16067   mp->interface_id = ntohl (if_id);
16068
16069   S;
16070   W;
16071   /* NOTREACHED */
16072   return 0;
16073 }
16074
16075 int
16076 api_pg_capture (vat_main_t * vam)
16077 {
16078   unformat_input_t *input = vam->input;
16079   vl_api_pg_capture_t *mp;
16080   f64 timeout;
16081
16082   u32 if_id = ~0;
16083   u8 enable = 1;
16084   u32 count = 1;
16085   u8 pcap_file_set = 0;
16086   u8 *pcap_file = 0;
16087   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16088     {
16089       if (unformat (input, "if_id %d", &if_id))
16090         ;
16091       else if (unformat (input, "pcap %s", &pcap_file))
16092         pcap_file_set = 1;
16093       else if (unformat (input, "count %d", &count))
16094         ;
16095       else if (unformat (input, "disable"))
16096         enable = 0;
16097       else
16098         break;
16099     }
16100   if (if_id == ~0)
16101     {
16102       errmsg ("missing pg interface index");
16103       return -99;
16104     }
16105   if (pcap_file_set > 0)
16106     {
16107       if (vec_len (pcap_file) > 255)
16108         {
16109           errmsg ("pcap file name is too long");
16110           return -99;
16111         }
16112     }
16113
16114   u32 name_len = vec_len (pcap_file);
16115   /* Construct the API message */
16116   M (PG_CAPTURE, pg_capture);
16117   mp->context = 0;
16118   mp->interface_id = ntohl (if_id);
16119   mp->is_enabled = enable;
16120   mp->count = ntohl (count);
16121   mp->pcap_name_length = ntohl (name_len);
16122   if (pcap_file_set != 0)
16123     {
16124       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16125     }
16126   vec_free (pcap_file);
16127
16128   S;
16129   W;
16130   /* NOTREACHED */
16131   return 0;
16132 }
16133
16134 int
16135 api_pg_enable_disable (vat_main_t * vam)
16136 {
16137   unformat_input_t *input = vam->input;
16138   vl_api_pg_enable_disable_t *mp;
16139   f64 timeout;
16140
16141   u8 enable = 1;
16142   u8 stream_name_set = 0;
16143   u8 *stream_name = 0;
16144   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16145     {
16146       if (unformat (input, "stream %s", &stream_name))
16147         stream_name_set = 1;
16148       else if (unformat (input, "disable"))
16149         enable = 0;
16150       else
16151         break;
16152     }
16153
16154   if (stream_name_set > 0)
16155     {
16156       if (vec_len (stream_name) > 255)
16157         {
16158           errmsg ("stream name too long");
16159           return -99;
16160         }
16161     }
16162
16163   u32 name_len = vec_len (stream_name);
16164   /* Construct the API message */
16165   M (PG_ENABLE_DISABLE, pg_enable_disable);
16166   mp->context = 0;
16167   mp->is_enabled = enable;
16168   if (stream_name_set != 0)
16169     {
16170       mp->stream_name_length = ntohl (name_len);
16171       clib_memcpy (mp->stream_name, stream_name, name_len);
16172     }
16173   vec_free (stream_name);
16174
16175   S;
16176   W;
16177   /* NOTREACHED */
16178   return 0;
16179 }
16180
16181 int
16182 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16183 {
16184   unformat_input_t *input = vam->input;
16185   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16186   f64 timeout;
16187
16188   u16 *low_ports = 0;
16189   u16 *high_ports = 0;
16190   u16 this_low;
16191   u16 this_hi;
16192   ip4_address_t ip4_addr;
16193   ip6_address_t ip6_addr;
16194   u32 length;
16195   u32 tmp, tmp2;
16196   u8 prefix_set = 0;
16197   u32 vrf_id = ~0;
16198   u8 is_add = 1;
16199   u8 is_ipv6 = 0;
16200
16201   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16202     {
16203       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16204         {
16205           prefix_set = 1;
16206         }
16207       else
16208         if (unformat
16209             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16210         {
16211           prefix_set = 1;
16212           is_ipv6 = 1;
16213         }
16214       else if (unformat (input, "vrf %d", &vrf_id))
16215         ;
16216       else if (unformat (input, "del"))
16217         is_add = 0;
16218       else if (unformat (input, "port %d", &tmp))
16219         {
16220           if (tmp == 0 || tmp > 65535)
16221             {
16222               errmsg ("port %d out of range", tmp);
16223               return -99;
16224             }
16225           this_low = tmp;
16226           this_hi = this_low + 1;
16227           vec_add1 (low_ports, this_low);
16228           vec_add1 (high_ports, this_hi);
16229         }
16230       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16231         {
16232           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16233             {
16234               errmsg ("incorrect range parameters");
16235               return -99;
16236             }
16237           this_low = tmp;
16238           /* Note: in debug CLI +1 is added to high before
16239              passing to real fn that does "the work"
16240              (ip_source_and_port_range_check_add_del).
16241              This fn is a wrapper around the binary API fn a
16242              control plane will call, which expects this increment
16243              to have occurred. Hence letting the binary API control
16244              plane fn do the increment for consistency between VAT
16245              and other control planes.
16246            */
16247           this_hi = tmp2;
16248           vec_add1 (low_ports, this_low);
16249           vec_add1 (high_ports, this_hi);
16250         }
16251       else
16252         break;
16253     }
16254
16255   if (prefix_set == 0)
16256     {
16257       errmsg ("<address>/<mask> not specified");
16258       return -99;
16259     }
16260
16261   if (vrf_id == ~0)
16262     {
16263       errmsg ("VRF ID required, not specified");
16264       return -99;
16265     }
16266
16267   if (vrf_id == 0)
16268     {
16269       errmsg
16270         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16271       return -99;
16272     }
16273
16274   if (vec_len (low_ports) == 0)
16275     {
16276       errmsg ("At least one port or port range required");
16277       return -99;
16278     }
16279
16280   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
16281      ip_source_and_port_range_check_add_del);
16282
16283   mp->is_add = is_add;
16284
16285   if (is_ipv6)
16286     {
16287       mp->is_ipv6 = 1;
16288       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16289     }
16290   else
16291     {
16292       mp->is_ipv6 = 0;
16293       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16294     }
16295
16296   mp->mask_length = length;
16297   mp->number_of_ranges = vec_len (low_ports);
16298
16299   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16300   vec_free (low_ports);
16301
16302   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16303   vec_free (high_ports);
16304
16305   mp->vrf_id = ntohl (vrf_id);
16306
16307   S;
16308   W;
16309   /* NOTREACHED */
16310   return 0;
16311 }
16312
16313 int
16314 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16315 {
16316   unformat_input_t *input = vam->input;
16317   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16318   f64 timeout;
16319   u32 sw_if_index = ~0;
16320   int vrf_set = 0;
16321   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16322   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16323   u8 is_add = 1;
16324
16325   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16326     {
16327       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16328         ;
16329       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16330         ;
16331       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16332         vrf_set = 1;
16333       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16334         vrf_set = 1;
16335       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16336         vrf_set = 1;
16337       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16338         vrf_set = 1;
16339       else if (unformat (input, "del"))
16340         is_add = 0;
16341       else
16342         break;
16343     }
16344
16345   if (sw_if_index == ~0)
16346     {
16347       errmsg ("Interface required but not specified");
16348       return -99;
16349     }
16350
16351   if (vrf_set == 0)
16352     {
16353       errmsg ("VRF ID required but not specified");
16354       return -99;
16355     }
16356
16357   if (tcp_out_vrf_id == 0
16358       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16359     {
16360       errmsg
16361         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
16362       return -99;
16363     }
16364
16365   /* Construct the API message */
16366   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
16367      ip_source_and_port_range_check_interface_add_del);
16368
16369   mp->sw_if_index = ntohl (sw_if_index);
16370   mp->is_add = is_add;
16371   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16372   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16373   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16374   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16375
16376   /* send it... */
16377   S;
16378
16379   /* Wait for a reply... */
16380   W;
16381 }
16382
16383 static int
16384 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16385 {
16386   unformat_input_t *i = vam->input;
16387   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16388   f64 timeout;
16389   u32 local_sa_id = 0;
16390   u32 remote_sa_id = 0;
16391   ip4_address_t src_address;
16392   ip4_address_t dst_address;
16393   u8 is_add = 1;
16394
16395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16396     {
16397       if (unformat (i, "local_sa %d", &local_sa_id))
16398         ;
16399       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16400         ;
16401       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16402         ;
16403       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16404         ;
16405       else if (unformat (i, "del"))
16406         is_add = 0;
16407       else
16408         {
16409           clib_warning ("parse error '%U'", format_unformat_error, i);
16410           return -99;
16411         }
16412     }
16413
16414   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16415
16416   mp->local_sa_id = ntohl (local_sa_id);
16417   mp->remote_sa_id = ntohl (remote_sa_id);
16418   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16419   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16420   mp->is_add = is_add;
16421
16422   S;
16423   W;
16424   /* NOTREACHED */
16425   return 0;
16426 }
16427
16428 static int
16429 api_punt (vat_main_t * vam)
16430 {
16431   unformat_input_t *i = vam->input;
16432   vl_api_punt_t *mp;
16433   f64 timeout;
16434   u32 ipv = ~0;
16435   u32 protocol = ~0;
16436   u32 port = ~0;
16437   int is_add = 1;
16438
16439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16440     {
16441       if (unformat (i, "ip %d", &ipv))
16442         ;
16443       else if (unformat (i, "protocol %d", &protocol))
16444         ;
16445       else if (unformat (i, "port %d", &port))
16446         ;
16447       else if (unformat (i, "del"))
16448         is_add = 0;
16449       else
16450         {
16451           clib_warning ("parse error '%U'", format_unformat_error, i);
16452           return -99;
16453         }
16454     }
16455
16456   M (PUNT, punt);
16457
16458   mp->is_add = (u8) is_add;
16459   mp->ipv = (u8) ipv;
16460   mp->l4_protocol = (u8) protocol;
16461   mp->l4_port = htons ((u16) port);
16462
16463   S;
16464   W;
16465   /* NOTREACHED */
16466   return 0;
16467 }
16468
16469 static void vl_api_ipsec_gre_tunnel_details_t_handler
16470   (vl_api_ipsec_gre_tunnel_details_t * mp)
16471 {
16472   vat_main_t *vam = &vat_main;
16473
16474   print (vam->ofp, "%11d%15U%15U%14d%14d",
16475          ntohl (mp->sw_if_index),
16476          format_ip4_address, &mp->src_address,
16477          format_ip4_address, &mp->dst_address,
16478          ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16479 }
16480
16481 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16482   (vl_api_ipsec_gre_tunnel_details_t * mp)
16483 {
16484   vat_main_t *vam = &vat_main;
16485   vat_json_node_t *node = NULL;
16486   struct in_addr ip4;
16487
16488   if (VAT_JSON_ARRAY != vam->json_tree.type)
16489     {
16490       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16491       vat_json_init_array (&vam->json_tree);
16492     }
16493   node = vat_json_array_add (&vam->json_tree);
16494
16495   vat_json_init_object (node);
16496   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16497   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16498   vat_json_object_add_ip4 (node, "src_address", ip4);
16499   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16500   vat_json_object_add_ip4 (node, "dst_address", ip4);
16501   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16502   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16503 }
16504
16505 static int
16506 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16507 {
16508   unformat_input_t *i = vam->input;
16509   vl_api_ipsec_gre_tunnel_dump_t *mp;
16510   f64 timeout;
16511   u32 sw_if_index;
16512   u8 sw_if_index_set = 0;
16513
16514   /* Parse args required to build the message */
16515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16516     {
16517       if (unformat (i, "sw_if_index %d", &sw_if_index))
16518         sw_if_index_set = 1;
16519       else
16520         break;
16521     }
16522
16523   if (sw_if_index_set == 0)
16524     {
16525       sw_if_index = ~0;
16526     }
16527
16528   if (!vam->json_output)
16529     {
16530       print (vam->ofp, "%11s%15s%15s%14s%14s",
16531              "sw_if_index", "src_address", "dst_address",
16532              "local_sa_id", "remote_sa_id");
16533     }
16534
16535   /* Get list of gre-tunnel interfaces */
16536   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16537
16538   mp->sw_if_index = htonl (sw_if_index);
16539
16540   S;
16541
16542   /* Use a control ping for synchronization */
16543   {
16544     vl_api_control_ping_t *mp;
16545     M (CONTROL_PING, control_ping);
16546     S;
16547   }
16548   W;
16549 }
16550
16551 static int
16552 api_delete_subif (vat_main_t * vam)
16553 {
16554   unformat_input_t *i = vam->input;
16555   vl_api_delete_subif_t *mp;
16556   f64 timeout;
16557   u32 sw_if_index = ~0;
16558
16559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16560     {
16561       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16562         ;
16563       if (unformat (i, "sw_if_index %d", &sw_if_index))
16564         ;
16565       else
16566         break;
16567     }
16568
16569   if (sw_if_index == ~0)
16570     {
16571       errmsg ("missing sw_if_index");
16572       return -99;
16573     }
16574
16575   /* Construct the API message */
16576   M (DELETE_SUBIF, delete_subif);
16577   mp->sw_if_index = ntohl (sw_if_index);
16578
16579   S;
16580   W;
16581 }
16582
16583 #define foreach_pbb_vtr_op      \
16584 _("disable",  L2_VTR_DISABLED)  \
16585 _("pop",  L2_VTR_POP_2)         \
16586 _("push",  L2_VTR_PUSH_2)
16587
16588 static int
16589 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16590 {
16591   unformat_input_t *i = vam->input;
16592   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16593   f64 timeout;
16594   u32 sw_if_index = ~0, vtr_op = ~0;
16595   u16 outer_tag = ~0;
16596   u8 dmac[6], smac[6];
16597   u8 dmac_set = 0, smac_set = 0;
16598   u16 vlanid = 0;
16599   u32 sid = ~0;
16600   u32 tmp;
16601
16602   /* Shut up coverity */
16603   memset (dmac, 0, sizeof (dmac));
16604   memset (smac, 0, sizeof (smac));
16605
16606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16607     {
16608       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16609         ;
16610       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16611         ;
16612       else if (unformat (i, "vtr_op %d", &vtr_op))
16613         ;
16614 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16615       foreach_pbb_vtr_op
16616 #undef _
16617         else if (unformat (i, "translate_pbb_stag"))
16618         {
16619           if (unformat (i, "%d", &tmp))
16620             {
16621               vtr_op = L2_VTR_TRANSLATE_2_1;
16622               outer_tag = tmp;
16623             }
16624           else
16625             {
16626               errmsg
16627                 ("translate_pbb_stag operation requires outer tag definition");
16628               return -99;
16629             }
16630         }
16631       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16632         dmac_set++;
16633       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16634         smac_set++;
16635       else if (unformat (i, "sid %d", &sid))
16636         ;
16637       else if (unformat (i, "vlanid %d", &tmp))
16638         vlanid = tmp;
16639       else
16640         {
16641           clib_warning ("parse error '%U'", format_unformat_error, i);
16642           return -99;
16643         }
16644     }
16645
16646   if ((sw_if_index == ~0) || (vtr_op == ~0))
16647     {
16648       errmsg ("missing sw_if_index or vtr operation");
16649       return -99;
16650     }
16651   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16652       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16653     {
16654       errmsg
16655         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
16656       return -99;
16657     }
16658
16659   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16660   mp->sw_if_index = ntohl (sw_if_index);
16661   mp->vtr_op = ntohl (vtr_op);
16662   mp->outer_tag = ntohs (outer_tag);
16663   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16664   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16665   mp->b_vlanid = ntohs (vlanid);
16666   mp->i_sid = ntohl (sid);
16667
16668   S;
16669   W;
16670   /* NOTREACHED */
16671   return 0;
16672 }
16673
16674 static int
16675 api_flow_classify_set_interface (vat_main_t * vam)
16676 {
16677   unformat_input_t *i = vam->input;
16678   vl_api_flow_classify_set_interface_t *mp;
16679   f64 timeout;
16680   u32 sw_if_index;
16681   int sw_if_index_set;
16682   u32 ip4_table_index = ~0;
16683   u32 ip6_table_index = ~0;
16684   u8 is_add = 1;
16685
16686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16687     {
16688       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16689         sw_if_index_set = 1;
16690       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16691         sw_if_index_set = 1;
16692       else if (unformat (i, "del"))
16693         is_add = 0;
16694       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16695         ;
16696       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16697         ;
16698       else
16699         {
16700           clib_warning ("parse error '%U'", format_unformat_error, i);
16701           return -99;
16702         }
16703     }
16704
16705   if (sw_if_index_set == 0)
16706     {
16707       errmsg ("missing interface name or sw_if_index");
16708       return -99;
16709     }
16710
16711   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16712
16713   mp->sw_if_index = ntohl (sw_if_index);
16714   mp->ip4_table_index = ntohl (ip4_table_index);
16715   mp->ip6_table_index = ntohl (ip6_table_index);
16716   mp->is_add = is_add;
16717
16718   S;
16719   W;
16720   /* NOTREACHED */
16721   return 0;
16722 }
16723
16724 static int
16725 api_flow_classify_dump (vat_main_t * vam)
16726 {
16727   unformat_input_t *i = vam->input;
16728   vl_api_flow_classify_dump_t *mp;
16729   f64 timeout = ~0;
16730   u8 type = FLOW_CLASSIFY_N_TABLES;
16731
16732   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16733     ;
16734   else
16735     {
16736       errmsg ("classify table type must be specified");
16737       return -99;
16738     }
16739
16740   if (!vam->json_output)
16741     {
16742       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
16743     }
16744
16745   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16746   mp->type = type;
16747   /* send it... */
16748   S;
16749
16750   /* Use a control ping for synchronization */
16751   {
16752     vl_api_control_ping_t *mp;
16753     M (CONTROL_PING, control_ping);
16754     S;
16755   }
16756   /* Wait for a reply... */
16757   W;
16758
16759   /* NOTREACHED */
16760   return 0;
16761 }
16762
16763 static int
16764 api_feature_enable_disable (vat_main_t * vam)
16765 {
16766   unformat_input_t *i = vam->input;
16767   vl_api_feature_enable_disable_t *mp;
16768   f64 timeout;
16769   u8 *arc_name = 0;
16770   u8 *feature_name = 0;
16771   u32 sw_if_index = ~0;
16772   u8 enable = 1;
16773
16774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16775     {
16776       if (unformat (i, "arc_name %s", &arc_name))
16777         ;
16778       else if (unformat (i, "feature_name %s", &feature_name))
16779         ;
16780       else
16781         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16782         ;
16783       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16784         ;
16785       else if (unformat (i, "disable"))
16786         enable = 0;
16787       else
16788         break;
16789     }
16790
16791   if (arc_name == 0)
16792     {
16793       errmsg ("missing arc name");
16794       return -99;
16795     }
16796   if (vec_len (arc_name) > 63)
16797     {
16798       errmsg ("arc name too long");
16799     }
16800
16801   if (feature_name == 0)
16802     {
16803       errmsg ("missing feature name");
16804       return -99;
16805     }
16806   if (vec_len (feature_name) > 63)
16807     {
16808       errmsg ("feature name too long");
16809     }
16810
16811   if (sw_if_index == ~0)
16812     {
16813       errmsg ("missing interface name or sw_if_index");
16814       return -99;
16815     }
16816
16817   /* Construct the API message */
16818   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16819   mp->sw_if_index = ntohl (sw_if_index);
16820   mp->enable = enable;
16821   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16822   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16823   vec_free (arc_name);
16824   vec_free (feature_name);
16825
16826   S;
16827   W;
16828 }
16829
16830 static int
16831 api_sw_interface_tag_add_del (vat_main_t * vam)
16832 {
16833   unformat_input_t *i = vam->input;
16834   vl_api_sw_interface_tag_add_del_t *mp;
16835   f64 timeout;
16836   u32 sw_if_index = ~0;
16837   u8 *tag = 0;
16838   u8 enable = 1;
16839
16840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16841     {
16842       if (unformat (i, "tag %s", &tag))
16843         ;
16844       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16845         ;
16846       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16847         ;
16848       else if (unformat (i, "del"))
16849         enable = 0;
16850       else
16851         break;
16852     }
16853
16854   if (sw_if_index == ~0)
16855     {
16856       errmsg ("missing interface name or sw_if_index");
16857       return -99;
16858     }
16859
16860   if (enable && (tag == 0))
16861     {
16862       errmsg ("no tag specified");
16863       return -99;
16864     }
16865
16866   /* Construct the API message */
16867   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
16868   mp->sw_if_index = ntohl (sw_if_index);
16869   mp->is_add = enable;
16870   if (enable)
16871     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
16872   vec_free (tag);
16873
16874   S;
16875   W;
16876 }
16877
16878 static void vl_api_l2_xconnect_details_t_handler
16879   (vl_api_l2_xconnect_details_t * mp)
16880 {
16881   vat_main_t *vam = &vat_main;
16882
16883   print (vam->ofp, "%15d%15d",
16884          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
16885 }
16886
16887 static void vl_api_l2_xconnect_details_t_handler_json
16888   (vl_api_l2_xconnect_details_t * mp)
16889 {
16890   vat_main_t *vam = &vat_main;
16891   vat_json_node_t *node = NULL;
16892
16893   if (VAT_JSON_ARRAY != vam->json_tree.type)
16894     {
16895       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16896       vat_json_init_array (&vam->json_tree);
16897     }
16898   node = vat_json_array_add (&vam->json_tree);
16899
16900   vat_json_init_object (node);
16901   vat_json_object_add_uint (node, "rx_sw_if_index",
16902                             ntohl (mp->rx_sw_if_index));
16903   vat_json_object_add_uint (node, "tx_sw_if_index",
16904                             ntohl (mp->tx_sw_if_index));
16905 }
16906
16907 static int
16908 api_l2_xconnect_dump (vat_main_t * vam)
16909 {
16910   vl_api_l2_xconnect_dump_t *mp;
16911   f64 timeout;
16912
16913   if (!vam->json_output)
16914     {
16915       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
16916     }
16917
16918   M (L2_XCONNECT_DUMP, l2_xconnect_dump);
16919
16920   S;
16921
16922   /* Use a control ping for synchronization */
16923   {
16924     vl_api_control_ping_t *mp;
16925     M (CONTROL_PING, control_ping);
16926     S;
16927   }
16928   W;
16929 }
16930
16931 static int
16932 api_sw_interface_set_mtu (vat_main_t * vam)
16933 {
16934   unformat_input_t *i = vam->input;
16935   vl_api_sw_interface_set_mtu_t *mp;
16936   f64 timeout;
16937   u32 sw_if_index = ~0;
16938   u32 mtu = 0;
16939
16940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16941     {
16942       if (unformat (i, "mtu %d", &mtu))
16943         ;
16944       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
16945         ;
16946       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16947         ;
16948       else
16949         break;
16950     }
16951
16952   if (sw_if_index == ~0)
16953     {
16954       errmsg ("missing interface name or sw_if_index");
16955       return -99;
16956     }
16957
16958   if (mtu == 0)
16959     {
16960       errmsg ("no mtu specified");
16961       return -99;
16962     }
16963
16964   /* Construct the API message */
16965   M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
16966   mp->sw_if_index = ntohl (sw_if_index);
16967   mp->mtu = ntohs ((u16) mtu);
16968
16969   S;
16970   W;
16971 }
16972
16973
16974 static int
16975 q_or_quit (vat_main_t * vam)
16976 {
16977   longjmp (vam->jump_buf, 1);
16978   return 0;                     /* not so much */
16979 }
16980
16981 static int
16982 q (vat_main_t * vam)
16983 {
16984   return q_or_quit (vam);
16985 }
16986
16987 static int
16988 quit (vat_main_t * vam)
16989 {
16990   return q_or_quit (vam);
16991 }
16992
16993 static int
16994 comment (vat_main_t * vam)
16995 {
16996   return 0;
16997 }
16998
16999 static int
17000 cmd_cmp (void *a1, void *a2)
17001 {
17002   u8 **c1 = a1;
17003   u8 **c2 = a2;
17004
17005   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17006 }
17007
17008 static int
17009 help (vat_main_t * vam)
17010 {
17011   u8 **cmds = 0;
17012   u8 *name = 0;
17013   hash_pair_t *p;
17014   unformat_input_t *i = vam->input;
17015   int j;
17016
17017   if (unformat (i, "%s", &name))
17018     {
17019       uword *hs;
17020
17021       vec_add1 (name, 0);
17022
17023       hs = hash_get_mem (vam->help_by_name, name);
17024       if (hs)
17025         print (vam->ofp, "usage: %s %s", name, hs[0]);
17026       else
17027         print (vam->ofp, "No such msg / command '%s'", name);
17028       vec_free (name);
17029       return 0;
17030     }
17031
17032   print (vam->ofp, "Help is available for the following:");
17033
17034     /* *INDENT-OFF* */
17035     hash_foreach_pair (p, vam->function_by_name,
17036     ({
17037       vec_add1 (cmds, (u8 *)(p->key));
17038     }));
17039     /* *INDENT-ON* */
17040
17041   vec_sort_with_function (cmds, cmd_cmp);
17042
17043   for (j = 0; j < vec_len (cmds); j++)
17044     print (vam->ofp, "%s", cmds[j]);
17045
17046   vec_free (cmds);
17047   return 0;
17048 }
17049
17050 static int
17051 set (vat_main_t * vam)
17052 {
17053   u8 *name = 0, *value = 0;
17054   unformat_input_t *i = vam->input;
17055
17056   if (unformat (i, "%s", &name))
17057     {
17058       /* The input buffer is a vector, not a string. */
17059       value = vec_dup (i->buffer);
17060       vec_delete (value, i->index, 0);
17061       /* Almost certainly has a trailing newline */
17062       if (value[vec_len (value) - 1] == '\n')
17063         value[vec_len (value) - 1] = 0;
17064       /* Make sure it's a proper string, one way or the other */
17065       vec_add1 (value, 0);
17066       (void) clib_macro_set_value (&vam->macro_main,
17067                                    (char *) name, (char *) value);
17068     }
17069   else
17070     errmsg ("usage: set <name> <value>");
17071
17072   vec_free (name);
17073   vec_free (value);
17074   return 0;
17075 }
17076
17077 static int
17078 unset (vat_main_t * vam)
17079 {
17080   u8 *name = 0;
17081
17082   if (unformat (vam->input, "%s", &name))
17083     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17084       errmsg ("unset: %s wasn't set", name);
17085   vec_free (name);
17086   return 0;
17087 }
17088
17089 typedef struct
17090 {
17091   u8 *name;
17092   u8 *value;
17093 } macro_sort_t;
17094
17095
17096 static int
17097 macro_sort_cmp (void *a1, void *a2)
17098 {
17099   macro_sort_t *s1 = a1;
17100   macro_sort_t *s2 = a2;
17101
17102   return strcmp ((char *) (s1->name), (char *) (s2->name));
17103 }
17104
17105 static int
17106 dump_macro_table (vat_main_t * vam)
17107 {
17108   macro_sort_t *sort_me = 0, *sm;
17109   int i;
17110   hash_pair_t *p;
17111
17112     /* *INDENT-OFF* */
17113     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17114     ({
17115       vec_add2 (sort_me, sm, 1);
17116       sm->name = (u8 *)(p->key);
17117       sm->value = (u8 *) (p->value[0]);
17118     }));
17119     /* *INDENT-ON* */
17120
17121   vec_sort_with_function (sort_me, macro_sort_cmp);
17122
17123   if (vec_len (sort_me))
17124     print (vam->ofp, "%-15s%s", "Name", "Value");
17125   else
17126     print (vam->ofp, "The macro table is empty...");
17127
17128   for (i = 0; i < vec_len (sort_me); i++)
17129     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
17130   return 0;
17131 }
17132
17133 static int
17134 dump_node_table (vat_main_t * vam)
17135 {
17136   int i, j;
17137   vlib_node_t *node, *next_node;
17138
17139   if (vec_len (vam->graph_nodes) == 0)
17140     {
17141       print (vam->ofp, "Node table empty, issue get_node_graph...");
17142       return 0;
17143     }
17144
17145   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17146     {
17147       node = vam->graph_nodes[i];
17148       print (vam->ofp, "[%d] %s", i, node->name);
17149       for (j = 0; j < vec_len (node->next_nodes); j++)
17150         {
17151           if (node->next_nodes[j] != ~0)
17152             {
17153               next_node = vam->graph_nodes[node->next_nodes[j]];
17154               print (vam->ofp, "  [%d] %s", j, next_node->name);
17155             }
17156         }
17157     }
17158   return 0;
17159 }
17160
17161 static int
17162 value_sort_cmp (void *a1, void *a2)
17163 {
17164   name_sort_t *n1 = a1;
17165   name_sort_t *n2 = a2;
17166
17167   if (n1->value < n2->value)
17168     return -1;
17169   if (n1->value > n2->value)
17170     return 1;
17171   return 0;
17172 }
17173
17174
17175 static int
17176 dump_msg_api_table (vat_main_t * vam)
17177 {
17178   api_main_t *am = &api_main;
17179   name_sort_t *nses = 0, *ns;
17180   hash_pair_t *hp;
17181   int i;
17182
17183   /* *INDENT-OFF* */
17184   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17185   ({
17186     vec_add2 (nses, ns, 1);
17187     ns->name = (u8 *)(hp->key);
17188     ns->value = (u32) hp->value[0];
17189   }));
17190   /* *INDENT-ON* */
17191
17192   vec_sort_with_function (nses, value_sort_cmp);
17193
17194   for (i = 0; i < vec_len (nses); i++)
17195     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
17196   vec_free (nses);
17197   return 0;
17198 }
17199
17200 static int
17201 get_msg_id (vat_main_t * vam)
17202 {
17203   u8 *name_and_crc;
17204   u32 message_index;
17205
17206   if (unformat (vam->input, "%s", &name_and_crc))
17207     {
17208       message_index = vl_api_get_msg_index (name_and_crc);
17209       if (message_index == ~0)
17210         {
17211           print (vam->ofp, " '%s' not found", name_and_crc);
17212           return 0;
17213         }
17214       print (vam->ofp, " '%s' has message index %d",
17215              name_and_crc, message_index);
17216       return 0;
17217     }
17218   errmsg ("name_and_crc required...");
17219   return 0;
17220 }
17221
17222 static int
17223 search_node_table (vat_main_t * vam)
17224 {
17225   unformat_input_t *line_input = vam->input;
17226   u8 *node_to_find;
17227   int j;
17228   vlib_node_t *node, *next_node;
17229   uword *p;
17230
17231   if (vam->graph_node_index_by_name == 0)
17232     {
17233       print (vam->ofp, "Node table empty, issue get_node_graph...");
17234       return 0;
17235     }
17236
17237   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17238     {
17239       if (unformat (line_input, "%s", &node_to_find))
17240         {
17241           vec_add1 (node_to_find, 0);
17242           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17243           if (p == 0)
17244             {
17245               print (vam->ofp, "%s not found...", node_to_find);
17246               goto out;
17247             }
17248           node = vam->graph_nodes[p[0]];
17249           print (vam->ofp, "[%d] %s", p[0], node->name);
17250           for (j = 0; j < vec_len (node->next_nodes); j++)
17251             {
17252               if (node->next_nodes[j] != ~0)
17253                 {
17254                   next_node = vam->graph_nodes[node->next_nodes[j]];
17255                   print (vam->ofp, "  [%d] %s", j, next_node->name);
17256                 }
17257             }
17258         }
17259
17260       else
17261         {
17262           clib_warning ("parse error '%U'", format_unformat_error,
17263                         line_input);
17264           return -99;
17265         }
17266
17267     out:
17268       vec_free (node_to_find);
17269
17270     }
17271
17272   return 0;
17273 }
17274
17275
17276 static int
17277 script (vat_main_t * vam)
17278 {
17279 #if (VPP_API_TEST_BUILTIN==0)
17280   u8 *s = 0;
17281   char *save_current_file;
17282   unformat_input_t save_input;
17283   jmp_buf save_jump_buf;
17284   u32 save_line_number;
17285
17286   FILE *new_fp, *save_ifp;
17287
17288   if (unformat (vam->input, "%s", &s))
17289     {
17290       new_fp = fopen ((char *) s, "r");
17291       if (new_fp == 0)
17292         {
17293           errmsg ("Couldn't open script file %s", s);
17294           vec_free (s);
17295           return -99;
17296         }
17297     }
17298   else
17299     {
17300       errmsg ("Missing script name");
17301       return -99;
17302     }
17303
17304   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17305   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17306   save_ifp = vam->ifp;
17307   save_line_number = vam->input_line_number;
17308   save_current_file = (char *) vam->current_file;
17309
17310   vam->input_line_number = 0;
17311   vam->ifp = new_fp;
17312   vam->current_file = s;
17313   do_one_file (vam);
17314
17315   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17316   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17317   vam->ifp = save_ifp;
17318   vam->input_line_number = save_line_number;
17319   vam->current_file = (u8 *) save_current_file;
17320   vec_free (s);
17321
17322   return 0;
17323 #else
17324   clib_warning ("use the exec command...");
17325   return -99;
17326 #endif
17327 }
17328
17329 static int
17330 echo (vat_main_t * vam)
17331 {
17332   print (vam->ofp, "%v", vam->input->buffer);
17333   return 0;
17334 }
17335
17336 /* List of API message constructors, CLI names map to api_xxx */
17337 #define foreach_vpe_api_msg                                             \
17338 _(create_loopback,"[mac <mac-addr>]")                                   \
17339 _(sw_interface_dump,"")                                                 \
17340 _(sw_interface_set_flags,                                               \
17341   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17342 _(sw_interface_add_del_address,                                         \
17343   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17344 _(sw_interface_set_table,                                               \
17345   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17346 _(sw_interface_set_mpls_enable,                                         \
17347   "<intfc> | sw_if_index [disable | dis]")                              \
17348 _(sw_interface_set_vpath,                                               \
17349   "<intfc> | sw_if_index <id> enable | disable")                        \
17350 _(sw_interface_set_vxlan_bypass,                                        \
17351   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")            \
17352 _(sw_interface_set_l2_xconnect,                                         \
17353   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17354   "enable | disable")                                                   \
17355 _(sw_interface_set_l2_bridge,                                           \
17356   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"               \
17357   "[shg <split-horizon-group>] [bvi]\n"                                 \
17358   "enable | disable")                                                   \
17359 _(bridge_domain_add_del,                                                \
17360   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n") \
17361 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
17362 _(l2fib_add_del,                                                        \
17363   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17364 _(l2_flags,                                                             \
17365   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n") \
17366 _(bridge_flags,                                                         \
17367   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17368 _(tap_connect,                                                          \
17369   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17370 _(tap_modify,                                                           \
17371   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17372 _(tap_delete,                                                           \
17373   "<vpp-if-name> | sw_if_index <id>")                                   \
17374 _(sw_interface_tap_dump, "")                                            \
17375 _(ip_add_del_route,                                                     \
17376   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17377   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17378   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17379   "[multipath] [count <n>]")                                            \
17380 _(mpls_route_add_del,                                                   \
17381   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17382   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17383   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17384   "[multipath] [count <n>]")                                            \
17385 _(mpls_ip_bind_unbind,                                                  \
17386   "<label> <addr/len>")                                                 \
17387 _(mpls_tunnel_add_del,                                                  \
17388   " via <addr> [table-id <n>]\n"                                        \
17389   "sw_if_index <id>] [l2]  [del]")                                      \
17390 _(proxy_arp_add_del,                                                    \
17391   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17392 _(proxy_arp_intfc_enable_disable,                                       \
17393   "<intfc> | sw_if_index <id> enable | disable")                        \
17394 _(sw_interface_set_unnumbered,                                          \
17395   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17396 _(ip_neighbor_add_del,                                                  \
17397   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17398   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17399 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17400 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17401 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17402   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17403   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17404   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17405 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17406 _(reset_fib, "vrf <n> [ipv6]")                                          \
17407 _(dhcp_proxy_config,                                                    \
17408   "svr <v46-address> src <v46-address>\n"                               \
17409    "insert-cid <n> [del]")                                              \
17410 _(dhcp_proxy_config_2,                                                  \
17411   "svr <v46-address> src <v46-address>\n"                               \
17412    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
17413 _(dhcp_proxy_set_vss,                                                   \
17414   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17415 _(dhcp_client_config,                                                   \
17416   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17417 _(set_ip_flow_hash,                                                     \
17418   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17419 _(sw_interface_ip6_enable_disable,                                      \
17420   "<intfc> | sw_if_index <id> enable | disable")                        \
17421 _(sw_interface_ip6_set_link_local_address,                              \
17422   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17423 _(sw_interface_ip6nd_ra_prefix,                                         \
17424   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17425   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17426   "[nolink] [isno]")                                                    \
17427 _(sw_interface_ip6nd_ra_config,                                         \
17428   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17429   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17430   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17431 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17432 _(l2_patch_add_del,                                                     \
17433   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17434   "enable | disable")                                                   \
17435 _(sr_tunnel_add_del,                                                    \
17436   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
17437   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
17438   "[policy <policy_name>]")                                             \
17439 _(sr_policy_add_del,                                                    \
17440   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
17441 _(sr_multicast_map_add_del,                                             \
17442   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
17443 _(classify_add_del_table,                                               \
17444   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17445   " [del] [del-chain] mask <mask-value>\n"                              \
17446   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17447   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17448 _(classify_add_del_session,                                             \
17449   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17450   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17451   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17452   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17453 _(classify_set_interface_ip_table,                                      \
17454   "<intfc> | sw_if_index <nn> table <nn>")                              \
17455 _(classify_set_interface_l2_tables,                                     \
17456   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17457   "  [other-table <nn>]")                                               \
17458 _(get_node_index, "node <node-name")                                    \
17459 _(add_node_next, "node <node-name> next <next-node-name>")              \
17460 _(l2tpv3_create_tunnel,                                                 \
17461   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17462   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
17463   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17464 _(l2tpv3_set_tunnel_cookies,                                            \
17465   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17466   "[new_remote_cookie <nn>]\n")                                         \
17467 _(l2tpv3_interface_enable_disable,                                      \
17468   "<intfc> | sw_if_index <nn> enable | disable")                        \
17469 _(l2tpv3_set_lookup_key,                                                \
17470   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17471 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17472 _(vxlan_add_del_tunnel,                                                 \
17473   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17474   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17475   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17476 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17477 _(gre_add_del_tunnel,                                                   \
17478   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
17479 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
17480 _(l2_fib_clear_table, "")                                               \
17481 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
17482 _(l2_interface_vlan_tag_rewrite,                                        \
17483   "<intfc> | sw_if_index <nn> \n"                                       \
17484   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
17485   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
17486 _(create_vhost_user_if,                                                 \
17487         "socket <filename> [server] [renumber <dev_instance>] "         \
17488         "[mac <mac_address>]")                                          \
17489 _(modify_vhost_user_if,                                                 \
17490         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
17491         "[server] [renumber <dev_instance>]")                           \
17492 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
17493 _(sw_interface_vhost_user_dump, "")                                     \
17494 _(show_version, "")                                                     \
17495 _(vxlan_gpe_add_del_tunnel,                                             \
17496   "local <addr> remote <addr> vni <nn>\n"                               \
17497     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
17498   "[next-ethernet] [next-nsh]\n")                                       \
17499 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
17500 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
17501 _(interface_name_renumber,                                              \
17502   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
17503 _(input_acl_set_interface,                                              \
17504   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17505   "  [l2-table <nn>] [del]")                                            \
17506 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
17507 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
17508 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
17509 _(ip_dump, "ipv4 | ipv6")                                               \
17510 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
17511 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
17512   "  spid_id <n> ")                                                     \
17513 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
17514   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
17515   "  integ_alg <alg> integ_key <hex>")                                  \
17516 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
17517   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
17518   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17519   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
17520 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
17521 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
17522 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
17523   "(auth_data 0x<data> | auth_data <data>)")                            \
17524 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
17525   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
17526 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
17527   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17528   "(local|remote)")                                                     \
17529 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
17530 _(delete_loopback,"sw_if_index <nn>")                                   \
17531 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17532 _(map_add_domain,                                                       \
17533   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
17534   "ip6-src <ip6addr> "                                                  \
17535   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
17536 _(map_del_domain, "index <n>")                                          \
17537 _(map_add_del_rule,                                                     \
17538   "index <n> psid <n> dst <ip6addr> [del]")                             \
17539 _(map_domain_dump, "")                                                  \
17540 _(map_rule_dump, "index <map-domain>")                                  \
17541 _(want_interface_events,  "enable|disable")                             \
17542 _(want_stats,"enable|disable")                                          \
17543 _(get_first_msg_id, "client <name>")                                    \
17544 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17545 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
17546   "fib-id <nn> [ip4][ip6][default]")                                    \
17547 _(get_node_graph, " ")                                                  \
17548 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
17549 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
17550 _(ioam_disable, "")                                                     \
17551 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
17552                             " sw_if_index <sw_if_index> p <priority> "  \
17553                             "w <weight>] [del]")                        \
17554 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
17555                         "iface <intf> | sw_if_index <sw_if_index> "     \
17556                         "p <priority> w <weight> [del]")                \
17557 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
17558                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
17559                          "locator-set <locator_name> [del]"             \
17560                          "[key-id sha1|sha256 secret-key <secret-key>]") \
17561 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
17562   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
17563 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
17564 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
17565 _(lisp_gpe_enable_disable, "enable|disable")                            \
17566 _(lisp_enable_disable, "enable|disable")                                \
17567 _(lisp_map_register_enable_disable, "enable|disable")                   \
17568 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
17569 _(lisp_gpe_add_del_iface, "up|down")                                    \
17570 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17571                                "[seid <seid>] "                         \
17572                                "rloc <locator> p <prio> "               \
17573                                "w <weight> [rloc <loc> ... ] "          \
17574                                "action <action> [del-all]")             \
17575 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17576                           "<local-eid>")                                \
17577 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
17578 _(lisp_map_request_mode, "src-dst|dst-only")                            \
17579 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
17580 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
17581 _(lisp_locator_set_dump, "[local | remote]")                            \
17582 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
17583 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
17584                        "[local] | [remote]")                            \
17585 _(lisp_eid_table_vni_dump, "")                                          \
17586 _(lisp_eid_table_map_dump, "l2|l3")                                     \
17587 _(lisp_map_resolver_dump, "")                                           \
17588 _(lisp_map_server_dump, "")                                             \
17589 _(lisp_adjacencies_get, "vni <vni>")                                    \
17590 _(show_lisp_rloc_probe_state, "")                                       \
17591 _(show_lisp_map_register_state, "")                                     \
17592 _(show_lisp_status, "")                                                 \
17593 _(lisp_get_map_request_itr_rlocs, "")                                   \
17594 _(show_lisp_pitr, "")                                                   \
17595 _(show_lisp_map_request_mode, "")                                       \
17596 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
17597 _(af_packet_delete, "name <host interface name>")                       \
17598 _(policer_add_del, "name <policer name> <params> [del]")                \
17599 _(policer_dump, "[name <policer name>]")                                \
17600 _(policer_classify_set_interface,                                       \
17601   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17602   "  [l2-table <nn>] [del]")                                            \
17603 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
17604 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
17605     "[master|slave]")                                                   \
17606 _(netmap_delete, "name <interface name>")                               \
17607 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
17608 _(mpls_fib_dump, "")                                                    \
17609 _(classify_table_ids, "")                                               \
17610 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
17611 _(classify_table_info, "table_id <nn>")                                 \
17612 _(classify_session_dump, "table_id <nn>")                               \
17613 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
17614     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
17615     "[template_interval <nn>] [udp_checksum]")                          \
17616 _(ipfix_exporter_dump, "")                                              \
17617 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17618 _(ipfix_classify_stream_dump, "")                                       \
17619 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
17620 _(ipfix_classify_table_dump, "")                                        \
17621 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
17622 _(sw_interface_span_dump, "")                                           \
17623 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17624 _(pg_create_interface, "if_id <nn>")                                    \
17625 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17626 _(pg_enable_disable, "[stream <id>] disable")                           \
17627 _(ip_source_and_port_range_check_add_del,                               \
17628   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17629 _(ip_source_and_port_range_check_interface_add_del,                     \
17630   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17631   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17632 _(ipsec_gre_add_del_tunnel,                                             \
17633   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17634 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17635 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17636 _(l2_interface_pbb_tag_rewrite,                                         \
17637   "<intfc> | sw_if_index <nn> \n"                                       \
17638   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17639   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17640 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17641 _(flow_classify_set_interface,                                          \
17642   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17643 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17644 _(ip_fib_dump, "")                                                      \
17645 _(ip6_fib_dump, "")                                                     \
17646 _(feature_enable_disable, "arc_name <arc_name> "                        \
17647   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
17648 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
17649 "[disable]")                                                            \
17650 _(l2_xconnect_dump, "")                                                 \
17651 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
17652 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
17653 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
17654
17655 #if DPDK > 0
17656 #define foreach_vpe_dpdk_api_msg                                        \
17657 _(sw_interface_set_dpdk_hqos_pipe,                                      \
17658   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
17659   "profile <profile-id>\n")                                             \
17660 _(sw_interface_set_dpdk_hqos_subport,                                   \
17661   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
17662   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
17663 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
17664   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")
17665 #endif
17666
17667 /* List of command functions, CLI names map directly to functions */
17668 #define foreach_cli_function                                    \
17669 _(comment, "usage: comment <ignore-rest-of-line>")              \
17670 _(dump_interface_table, "usage: dump_interface_table")          \
17671 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17672 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17673 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17674 _(dump_stats_table, "usage: dump_stats_table")                  \
17675 _(dump_macro_table, "usage: dump_macro_table ")                 \
17676 _(dump_node_table, "usage: dump_node_table")                    \
17677 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17678 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17679 _(echo, "usage: echo <message>")                                \
17680 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17681 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17682 _(help, "usage: help")                                          \
17683 _(q, "usage: quit")                                             \
17684 _(quit, "usage: quit")                                          \
17685 _(search_node_table, "usage: search_node_table <name>...")      \
17686 _(set, "usage: set <variable-name> <value>")                    \
17687 _(script, "usage: script <file-name>")                          \
17688 _(unset, "usage: unset <variable-name>")
17689
17690 #define _(N,n)                                  \
17691     static void vl_api_##n##_t_handler_uni      \
17692     (vl_api_##n##_t * mp)                       \
17693     {                                           \
17694         vat_main_t * vam = &vat_main;           \
17695         if (vam->json_output) {                 \
17696             vl_api_##n##_t_handler_json(mp);    \
17697         } else {                                \
17698             vl_api_##n##_t_handler(mp);         \
17699         }                                       \
17700     }
17701 foreach_vpe_api_reply_msg;
17702 #undef _
17703
17704 #if DPDK > 0
17705 #define _(N,n)                                  \
17706     static void vl_api_##n##_t_handler_uni      \
17707     (vl_api_##n##_t * mp)                       \
17708     {                                           \
17709         vat_main_t * vam = &vat_main;           \
17710         if (vam->json_output) {                 \
17711             vl_api_##n##_t_handler_json(mp);    \
17712         } else {                                \
17713             vl_api_##n##_t_handler(mp);         \
17714         }                                       \
17715     }
17716 foreach_vpe_dpdk_api_reply_msg;
17717 #undef _
17718 #endif
17719
17720 void
17721 vat_api_hookup (vat_main_t * vam)
17722 {
17723 #define _(N,n)                                                  \
17724     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17725                            vl_api_##n##_t_handler_uni,          \
17726                            vl_noop_handler,                     \
17727                            vl_api_##n##_t_endian,               \
17728                            vl_api_##n##_t_print,                \
17729                            sizeof(vl_api_##n##_t), 1);
17730   foreach_vpe_api_reply_msg;
17731 #undef _
17732
17733 #if DPDK > 0
17734 #define _(N,n)                                                  \
17735     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17736                            vl_api_##n##_t_handler_uni,          \
17737                            vl_noop_handler,                     \
17738                            vl_api_##n##_t_endian,               \
17739                            vl_api_##n##_t_print,                \
17740                            sizeof(vl_api_##n##_t), 1);
17741   foreach_vpe_dpdk_api_reply_msg;
17742 #undef _
17743 #endif
17744
17745 #if (VPP_API_TEST_BUILTIN==0)
17746   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17747 #endif
17748
17749   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17750
17751   vam->function_by_name = hash_create_string (0, sizeof (uword));
17752
17753   vam->help_by_name = hash_create_string (0, sizeof (uword));
17754
17755   /* API messages we can send */
17756 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17757   foreach_vpe_api_msg;
17758 #undef _
17759 #if DPDK >0
17760 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17761   foreach_vpe_dpdk_api_msg;
17762 #undef _
17763 #endif
17764
17765   /* Help strings */
17766 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17767   foreach_vpe_api_msg;
17768 #undef _
17769 #if DPDK >0
17770 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17771   foreach_vpe_dpdk_api_msg;
17772 #undef _
17773 #endif
17774
17775   /* CLI functions */
17776 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17777   foreach_cli_function;
17778 #undef _
17779
17780   /* Help strings */
17781 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17782   foreach_cli_function;
17783 #undef _
17784 }
17785
17786 /*
17787  * fd.io coding-style-patch-verification: ON
17788  *
17789  * Local Variables:
17790  * eval: (c-set-style "gnu")
17791  * End:
17792  */