VPP-521: Classify API enhancement to redirect traffic to pre-defined VRF
[vpp.git] / vpp-api-test / 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 #if DPDK > 0
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #else
44 #include <inttypes.h>
45 #endif
46 #include <vnet/map/map.h>
47 #include <vnet/cop/cop.h>
48 #include <vnet/ip/ip6_hop_by_hop.h>
49 #include <vnet/ip/ip_source_and_port_range_check.h>
50 #include <vnet/policer/xlate.h>
51 #include <vnet/span/span.h>
52 #include <vnet/policer/policer.h>
53 #include <vnet/policer/police.h>
54
55 #include "vat/json_format.h"
56
57 #include <sys/stat.h>
58
59 #define vl_typedefs             /* define message structures */
60 #include <vpp-api/vpe_all_api_h.h>
61 #undef vl_typedefs
62
63 /* declare message handlers for each api */
64
65 #define vl_endianfun            /* define message structures */
66 #include <vpp-api/vpe_all_api_h.h>
67 #undef vl_endianfun
68
69 /* instantiate all the print functions we know about */
70 #define vl_print(handle, ...)
71 #define vl_printfun
72 #include <vpp-api/vpe_all_api_h.h>
73 #undef vl_printfun
74
75 uword
76 unformat_sw_if_index (unformat_input_t * input, va_list * args)
77 {
78   vat_main_t *vam = va_arg (*args, vat_main_t *);
79   u32 *result = va_arg (*args, u32 *);
80   u8 *if_name;
81   uword *p;
82
83   if (!unformat (input, "%s", &if_name))
84     return 0;
85
86   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
87   if (p == 0)
88     return 0;
89   *result = p[0];
90   return 1;
91 }
92
93 /* Parse an IP4 address %d.%d.%d.%d. */
94 uword
95 unformat_ip4_address (unformat_input_t * input, va_list * args)
96 {
97   u8 *result = va_arg (*args, u8 *);
98   unsigned a[4];
99
100   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
101     return 0;
102
103   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
104     return 0;
105
106   result[0] = a[0];
107   result[1] = a[1];
108   result[2] = a[2];
109   result[3] = a[3];
110
111   return 1;
112 }
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 #if DPDK > 0
251   u32 *r = va_arg (*args, u32 *);
252
253   if (0);
254 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
255   foreach_ipsec_policy_action
256 #undef _
257     else
258     return 0;
259   return 1;
260 #else
261   return 0;
262 #endif
263 }
264
265 uword
266 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
267 {
268 #if DPDK > 0
269   u32 *r = va_arg (*args, u32 *);
270
271   if (0);
272 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
273   foreach_ipsec_crypto_alg
274 #undef _
275     else
276     return 0;
277   return 1;
278 #else
279   return 0;
280 #endif
281 }
282
283 u8 *
284 format_ipsec_crypto_alg (u8 * s, va_list * args)
285 {
286 #if DPDK > 0
287   u32 i = va_arg (*args, u32);
288   u8 *t = 0;
289
290   switch (i)
291     {
292 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
293       foreach_ipsec_crypto_alg
294 #undef _
295     default:
296       return format (s, "unknown");
297     }
298   return format (s, "%s", t);
299 #else
300   return format (s, "Unimplemented");
301 #endif
302 }
303
304 uword
305 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
306 {
307 #if DPDK > 0
308   u32 *r = va_arg (*args, u32 *);
309
310   if (0);
311 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
312   foreach_ipsec_integ_alg
313 #undef _
314     else
315     return 0;
316   return 1;
317 #else
318   return 0;
319 #endif
320 }
321
322 u8 *
323 format_ipsec_integ_alg (u8 * s, va_list * args)
324 {
325 #if DPDK > 0
326   u32 i = va_arg (*args, u32);
327   u8 *t = 0;
328
329   switch (i)
330     {
331 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
332       foreach_ipsec_integ_alg
333 #undef _
334     default:
335       return format (s, "unknown");
336     }
337   return format (s, "%s", t);
338 #else
339   return format (s, "Unsupported");
340 #endif
341 }
342
343 uword
344 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
345 {
346 #if DPDK > 0
347   u32 *r = va_arg (*args, u32 *);
348
349   if (0);
350 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
351   foreach_ikev2_auth_method
352 #undef _
353     else
354     return 0;
355   return 1;
356 #else
357   return 0;
358 #endif
359 }
360
361 uword
362 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
363 {
364 #if DPDK > 0
365   u32 *r = va_arg (*args, u32 *);
366
367   if (0);
368 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
369   foreach_ikev2_id_type
370 #undef _
371     else
372     return 0;
373   return 1;
374 #else
375   return 0;
376 #endif
377 }
378
379 uword
380 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
381 {
382   u8 *r = va_arg (*args, u8 *);
383
384   if (unformat (input, "kbps"))
385     *r = SSE2_QOS_RATE_KBPS;
386   else if (unformat (input, "pps"))
387     *r = SSE2_QOS_RATE_PPS;
388   else
389     return 0;
390   return 1;
391 }
392
393 uword
394 unformat_policer_round_type (unformat_input_t * input, va_list * args)
395 {
396   u8 *r = va_arg (*args, u8 *);
397
398   if (unformat (input, "closest"))
399     *r = SSE2_QOS_ROUND_TO_CLOSEST;
400   else if (unformat (input, "up"))
401     *r = SSE2_QOS_ROUND_TO_UP;
402   else if (unformat (input, "down"))
403     *r = SSE2_QOS_ROUND_TO_DOWN;
404   else
405     return 0;
406   return 1;
407 }
408
409 uword
410 unformat_policer_type (unformat_input_t * input, va_list * args)
411 {
412   u8 *r = va_arg (*args, u8 *);
413
414   if (unformat (input, "1r2c"))
415     *r = SSE2_QOS_POLICER_TYPE_1R2C;
416   else if (unformat (input, "1r3c"))
417     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
418   else if (unformat (input, "2r3c-2698"))
419     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
420   else if (unformat (input, "2r3c-4115"))
421     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
422   else if (unformat (input, "2r3c-mef5cf1"))
423     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
424   else
425     return 0;
426   return 1;
427 }
428
429 uword
430 unformat_dscp (unformat_input_t * input, va_list * va)
431 {
432   u8 *r = va_arg (*va, u8 *);
433
434   if (0);
435 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
436   foreach_vnet_dscp
437 #undef _
438     else
439     return 0;
440   return 1;
441 }
442
443 uword
444 unformat_policer_action_type (unformat_input_t * input, va_list * va)
445 {
446   sse2_qos_pol_action_params_st *a
447     = va_arg (*va, sse2_qos_pol_action_params_st *);
448
449   if (unformat (input, "drop"))
450     a->action_type = SSE2_QOS_ACTION_DROP;
451   else if (unformat (input, "transmit"))
452     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
453   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
454     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
455   else
456     return 0;
457   return 1;
458 }
459
460 uword
461 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
462 {
463   u32 *r = va_arg (*va, u32 *);
464   u32 tid;
465
466   if (unformat (input, "ip4"))
467     tid = POLICER_CLASSIFY_TABLE_IP4;
468   else if (unformat (input, "ip6"))
469     tid = POLICER_CLASSIFY_TABLE_IP6;
470   else if (unformat (input, "l2"))
471     tid = POLICER_CLASSIFY_TABLE_L2;
472   else
473     return 0;
474
475   *r = tid;
476   return 1;
477 }
478
479 uword
480 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
481 {
482   u32 *r = va_arg (*va, u32 *);
483   u32 tid;
484
485   if (unformat (input, "ip4"))
486     tid = FLOW_CLASSIFY_TABLE_IP4;
487   else if (unformat (input, "ip6"))
488     tid = FLOW_CLASSIFY_TABLE_IP6;
489   else
490     return 0;
491
492   *r = tid;
493   return 1;
494 }
495
496 u8 *
497 format_ip4_address (u8 * s, va_list * args)
498 {
499   u8 *a = va_arg (*args, u8 *);
500   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
501 }
502
503 u8 *
504 format_ip6_address (u8 * s, va_list * args)
505 {
506   ip6_address_t *a = va_arg (*args, ip6_address_t *);
507   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
508
509   i_max_n_zero = ARRAY_LEN (a->as_u16);
510   max_n_zeros = 0;
511   i_first_zero = i_max_n_zero;
512   n_zeros = 0;
513   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
514     {
515       u32 is_zero = a->as_u16[i] == 0;
516       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
517         {
518           i_first_zero = i;
519           n_zeros = 0;
520         }
521       n_zeros += is_zero;
522       if ((!is_zero && n_zeros > max_n_zeros)
523           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
524         {
525           i_max_n_zero = i_first_zero;
526           max_n_zeros = n_zeros;
527           i_first_zero = ARRAY_LEN (a->as_u16);
528           n_zeros = 0;
529         }
530     }
531
532   last_double_colon = 0;
533   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
534     {
535       if (i == i_max_n_zero && max_n_zeros > 1)
536         {
537           s = format (s, "::");
538           i += max_n_zeros - 1;
539           last_double_colon = 1;
540         }
541       else
542         {
543           s = format (s, "%s%x",
544                       (last_double_colon || i == 0) ? "" : ":",
545                       clib_net_to_host_u16 (a->as_u16[i]));
546           last_double_colon = 0;
547         }
548     }
549
550   return s;
551 }
552
553 /* Format an IP46 address. */
554 u8 *
555 format_ip46_address (u8 * s, va_list * args)
556 {
557   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
558   ip46_type_t type = va_arg (*args, ip46_type_t);
559   int is_ip4 = 1;
560
561   switch (type)
562     {
563     case IP46_TYPE_ANY:
564       is_ip4 = ip46_address_is_ip4 (ip46);
565       break;
566     case IP46_TYPE_IP4:
567       is_ip4 = 1;
568       break;
569     case IP46_TYPE_IP6:
570       is_ip4 = 0;
571       break;
572     }
573
574   return is_ip4 ?
575     format (s, "%U", format_ip4_address, &ip46->ip4) :
576     format (s, "%U", format_ip6_address, &ip46->ip6);
577 }
578
579 u8 *
580 format_ethernet_address (u8 * s, va_list * args)
581 {
582   u8 *a = va_arg (*args, u8 *);
583
584   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
585                  a[0], a[1], a[2], a[3], a[4], a[5]);
586 }
587
588 void
589 increment_v4_address (ip4_address_t * a)
590 {
591   u32 v;
592
593   v = ntohl (a->as_u32) + 1;
594   a->as_u32 = ntohl (v);
595 }
596
597 void
598 increment_v6_address (ip6_address_t * a)
599 {
600   u64 v0, v1;
601
602   v0 = clib_net_to_host_u64 (a->as_u64[0]);
603   v1 = clib_net_to_host_u64 (a->as_u64[1]);
604
605   v1 += 1;
606   if (v1 == 0)
607     v0 += 1;
608   a->as_u64[0] = clib_net_to_host_u64 (v0);
609   a->as_u64[1] = clib_net_to_host_u64 (v1);
610 }
611
612 void
613 increment_mac_address (u64 * mac)
614 {
615   u64 tmp = *mac;
616
617   tmp = clib_net_to_host_u64 (tmp);
618   tmp += 1 << 16;               /* skip unused (least significant) octets */
619   tmp = clib_host_to_net_u64 (tmp);
620   *mac = tmp;
621 }
622
623 static void vl_api_create_loopback_reply_t_handler
624   (vl_api_create_loopback_reply_t * mp)
625 {
626   vat_main_t *vam = &vat_main;
627   i32 retval = ntohl (mp->retval);
628
629   vam->retval = retval;
630   vam->regenerate_interface_table = 1;
631   vam->sw_if_index = ntohl (mp->sw_if_index);
632   vam->result_ready = 1;
633 }
634
635 static void vl_api_create_loopback_reply_t_handler_json
636   (vl_api_create_loopback_reply_t * mp)
637 {
638   vat_main_t *vam = &vat_main;
639   vat_json_node_t node;
640
641   vat_json_init_object (&node);
642   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
643   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
644
645   vat_json_print (vam->ofp, &node);
646   vat_json_free (&node);
647   vam->retval = ntohl (mp->retval);
648   vam->result_ready = 1;
649 }
650
651 static void vl_api_af_packet_create_reply_t_handler
652   (vl_api_af_packet_create_reply_t * mp)
653 {
654   vat_main_t *vam = &vat_main;
655   i32 retval = ntohl (mp->retval);
656
657   vam->retval = retval;
658   vam->regenerate_interface_table = 1;
659   vam->sw_if_index = ntohl (mp->sw_if_index);
660   vam->result_ready = 1;
661 }
662
663 static void vl_api_af_packet_create_reply_t_handler_json
664   (vl_api_af_packet_create_reply_t * mp)
665 {
666   vat_main_t *vam = &vat_main;
667   vat_json_node_t node;
668
669   vat_json_init_object (&node);
670   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
671   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
672
673   vat_json_print (vam->ofp, &node);
674   vat_json_free (&node);
675
676   vam->retval = ntohl (mp->retval);
677   vam->result_ready = 1;
678 }
679
680 static void vl_api_create_vlan_subif_reply_t_handler
681   (vl_api_create_vlan_subif_reply_t * mp)
682 {
683   vat_main_t *vam = &vat_main;
684   i32 retval = ntohl (mp->retval);
685
686   vam->retval = retval;
687   vam->regenerate_interface_table = 1;
688   vam->sw_if_index = ntohl (mp->sw_if_index);
689   vam->result_ready = 1;
690 }
691
692 static void vl_api_create_vlan_subif_reply_t_handler_json
693   (vl_api_create_vlan_subif_reply_t * mp)
694 {
695   vat_main_t *vam = &vat_main;
696   vat_json_node_t node;
697
698   vat_json_init_object (&node);
699   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
700   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
701
702   vat_json_print (vam->ofp, &node);
703   vat_json_free (&node);
704
705   vam->retval = ntohl (mp->retval);
706   vam->result_ready = 1;
707 }
708
709 static void vl_api_create_subif_reply_t_handler
710   (vl_api_create_subif_reply_t * mp)
711 {
712   vat_main_t *vam = &vat_main;
713   i32 retval = ntohl (mp->retval);
714
715   vam->retval = retval;
716   vam->regenerate_interface_table = 1;
717   vam->sw_if_index = ntohl (mp->sw_if_index);
718   vam->result_ready = 1;
719 }
720
721 static void vl_api_create_subif_reply_t_handler_json
722   (vl_api_create_subif_reply_t * mp)
723 {
724   vat_main_t *vam = &vat_main;
725   vat_json_node_t node;
726
727   vat_json_init_object (&node);
728   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
729   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
730
731   vat_json_print (vam->ofp, &node);
732   vat_json_free (&node);
733
734   vam->retval = ntohl (mp->retval);
735   vam->result_ready = 1;
736 }
737
738 static void vl_api_interface_name_renumber_reply_t_handler
739   (vl_api_interface_name_renumber_reply_t * mp)
740 {
741   vat_main_t *vam = &vat_main;
742   i32 retval = ntohl (mp->retval);
743
744   vam->retval = retval;
745   vam->regenerate_interface_table = 1;
746   vam->result_ready = 1;
747 }
748
749 static void vl_api_interface_name_renumber_reply_t_handler_json
750   (vl_api_interface_name_renumber_reply_t * mp)
751 {
752   vat_main_t *vam = &vat_main;
753   vat_json_node_t node;
754
755   vat_json_init_object (&node);
756   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
757
758   vat_json_print (vam->ofp, &node);
759   vat_json_free (&node);
760
761   vam->retval = ntohl (mp->retval);
762   vam->result_ready = 1;
763 }
764
765 /*
766  * Special-case: build the interface table, maintain
767  * the next loopback sw_if_index vbl.
768  */
769 static void vl_api_sw_interface_details_t_handler
770   (vl_api_sw_interface_details_t * mp)
771 {
772   vat_main_t *vam = &vat_main;
773   u8 *s = format (0, "%s%c", mp->interface_name, 0);
774
775   hash_set_mem (vam->sw_if_index_by_interface_name, s,
776                 ntohl (mp->sw_if_index));
777
778   /* In sub interface case, fill the sub interface table entry */
779   if (mp->sw_if_index != mp->sup_sw_if_index)
780     {
781       sw_interface_subif_t *sub = NULL;
782
783       vec_add2 (vam->sw_if_subif_table, sub, 1);
784
785       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
786       strncpy ((char *) sub->interface_name, (char *) s,
787                vec_len (sub->interface_name));
788       sub->sw_if_index = ntohl (mp->sw_if_index);
789       sub->sub_id = ntohl (mp->sub_id);
790
791       sub->sub_dot1ad = mp->sub_dot1ad;
792       sub->sub_number_of_tags = mp->sub_number_of_tags;
793       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
794       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
795       sub->sub_exact_match = mp->sub_exact_match;
796       sub->sub_default = mp->sub_default;
797       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
798       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
799
800       /* vlan tag rewrite */
801       sub->vtr_op = ntohl (mp->vtr_op);
802       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
803       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
804       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
805     }
806 }
807
808 static void vl_api_sw_interface_details_t_handler_json
809   (vl_api_sw_interface_details_t * mp)
810 {
811   vat_main_t *vam = &vat_main;
812   vat_json_node_t *node = NULL;
813
814   if (VAT_JSON_ARRAY != vam->json_tree.type)
815     {
816       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
817       vat_json_init_array (&vam->json_tree);
818     }
819   node = vat_json_array_add (&vam->json_tree);
820
821   vat_json_init_object (node);
822   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
823   vat_json_object_add_uint (node, "sup_sw_if_index",
824                             ntohl (mp->sup_sw_if_index));
825   vat_json_object_add_uint (node, "l2_address_length",
826                             ntohl (mp->l2_address_length));
827   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
828                              sizeof (mp->l2_address));
829   vat_json_object_add_string_copy (node, "interface_name",
830                                    mp->interface_name);
831   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
832   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
833   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
834   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
835   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
836   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
837   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
838   vat_json_object_add_uint (node, "sub_number_of_tags",
839                             mp->sub_number_of_tags);
840   vat_json_object_add_uint (node, "sub_outer_vlan_id",
841                             ntohs (mp->sub_outer_vlan_id));
842   vat_json_object_add_uint (node, "sub_inner_vlan_id",
843                             ntohs (mp->sub_inner_vlan_id));
844   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
845   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
846   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
847                             mp->sub_outer_vlan_id_any);
848   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
849                             mp->sub_inner_vlan_id_any);
850   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
851   vat_json_object_add_uint (node, "vtr_push_dot1q",
852                             ntohl (mp->vtr_push_dot1q));
853   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
854   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
855 }
856
857 static void vl_api_sw_interface_set_flags_t_handler
858   (vl_api_sw_interface_set_flags_t * mp)
859 {
860   vat_main_t *vam = &vat_main;
861   if (vam->interface_event_display)
862     errmsg ("interface flags: sw_if_index %d %s %s\n",
863             ntohl (mp->sw_if_index),
864             mp->admin_up_down ? "admin-up" : "admin-down",
865             mp->link_up_down ? "link-up" : "link-down");
866 }
867
868 static void vl_api_sw_interface_set_flags_t_handler_json
869   (vl_api_sw_interface_set_flags_t * mp)
870 {
871   /* JSON output not supported */
872 }
873
874 static void
875 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
876 {
877   vat_main_t *vam = &vat_main;
878   i32 retval = ntohl (mp->retval);
879
880   vam->retval = retval;
881   vam->shmem_result = (u8 *) mp->reply_in_shmem;
882   vam->result_ready = 1;
883 }
884
885 static void
886 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   vat_json_node_t node;
890   api_main_t *am = &api_main;
891   void *oldheap;
892   u8 *reply;
893
894   vat_json_init_object (&node);
895   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
896   vat_json_object_add_uint (&node, "reply_in_shmem",
897                             ntohl (mp->reply_in_shmem));
898   /* Toss the shared-memory original... */
899   pthread_mutex_lock (&am->vlib_rp->mutex);
900   oldheap = svm_push_data_heap (am->vlib_rp);
901
902   reply = (u8 *) (mp->reply_in_shmem);
903   vec_free (reply);
904
905   svm_pop_heap (oldheap);
906   pthread_mutex_unlock (&am->vlib_rp->mutex);
907
908   vat_json_print (vam->ofp, &node);
909   vat_json_free (&node);
910
911   vam->retval = ntohl (mp->retval);
912   vam->result_ready = 1;
913 }
914
915 static void
916 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
917 {
918   vat_main_t *vam = &vat_main;
919   i32 retval = ntohl (mp->retval);
920
921   vam->retval = retval;
922   vam->cmd_reply = mp->reply;
923   vam->result_ready = 1;
924 }
925
926 static void
927 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
928 {
929   vat_main_t *vam = &vat_main;
930   vat_json_node_t node;
931
932   vat_json_init_object (&node);
933   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
934   vat_json_object_add_string_copy (&node, "reply", mp->reply);
935
936   vat_json_print (vam->ofp, &node);
937   vat_json_free (&node);
938
939   vam->retval = ntohl (mp->retval);
940   vam->result_ready = 1;
941 }
942
943 static void vl_api_classify_add_del_table_reply_t_handler
944   (vl_api_classify_add_del_table_reply_t * mp)
945 {
946   vat_main_t *vam = &vat_main;
947   i32 retval = ntohl (mp->retval);
948   if (vam->async_mode)
949     {
950       vam->async_errors += (retval < 0);
951     }
952   else
953     {
954       vam->retval = retval;
955       if (retval == 0 &&
956           ((mp->new_table_index != 0xFFFFFFFF) ||
957            (mp->skip_n_vectors != 0xFFFFFFFF) ||
958            (mp->match_n_vectors != 0xFFFFFFFF)))
959         /*
960          * Note: this is just barely thread-safe, depends on
961          * the main thread spinning waiting for an answer...
962          */
963         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
964                 ntohl (mp->new_table_index),
965                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
966       vam->result_ready = 1;
967     }
968 }
969
970 static void vl_api_classify_add_del_table_reply_t_handler_json
971   (vl_api_classify_add_del_table_reply_t * mp)
972 {
973   vat_main_t *vam = &vat_main;
974   vat_json_node_t node;
975
976   vat_json_init_object (&node);
977   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
978   vat_json_object_add_uint (&node, "new_table_index",
979                             ntohl (mp->new_table_index));
980   vat_json_object_add_uint (&node, "skip_n_vectors",
981                             ntohl (mp->skip_n_vectors));
982   vat_json_object_add_uint (&node, "match_n_vectors",
983                             ntohl (mp->match_n_vectors));
984
985   vat_json_print (vam->ofp, &node);
986   vat_json_free (&node);
987
988   vam->retval = ntohl (mp->retval);
989   vam->result_ready = 1;
990 }
991
992 static void vl_api_get_node_index_reply_t_handler
993   (vl_api_get_node_index_reply_t * mp)
994 {
995   vat_main_t *vam = &vat_main;
996   i32 retval = ntohl (mp->retval);
997   if (vam->async_mode)
998     {
999       vam->async_errors += (retval < 0);
1000     }
1001   else
1002     {
1003       vam->retval = retval;
1004       if (retval == 0)
1005         errmsg ("node index %d\n", ntohl (mp->node_index));
1006       vam->result_ready = 1;
1007     }
1008 }
1009
1010 static void vl_api_get_node_index_reply_t_handler_json
1011   (vl_api_get_node_index_reply_t * mp)
1012 {
1013   vat_main_t *vam = &vat_main;
1014   vat_json_node_t node;
1015
1016   vat_json_init_object (&node);
1017   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1018   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1019
1020   vat_json_print (vam->ofp, &node);
1021   vat_json_free (&node);
1022
1023   vam->retval = ntohl (mp->retval);
1024   vam->result_ready = 1;
1025 }
1026
1027 static void vl_api_get_next_index_reply_t_handler
1028   (vl_api_get_next_index_reply_t * mp)
1029 {
1030   vat_main_t *vam = &vat_main;
1031   i32 retval = ntohl (mp->retval);
1032   if (vam->async_mode)
1033     {
1034       vam->async_errors += (retval < 0);
1035     }
1036   else
1037     {
1038       vam->retval = retval;
1039       if (retval == 0)
1040         errmsg ("next node index %d\n", ntohl (mp->next_index));
1041       vam->result_ready = 1;
1042     }
1043 }
1044
1045 static void vl_api_get_next_index_reply_t_handler_json
1046   (vl_api_get_next_index_reply_t * mp)
1047 {
1048   vat_main_t *vam = &vat_main;
1049   vat_json_node_t node;
1050
1051   vat_json_init_object (&node);
1052   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1053   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1054
1055   vat_json_print (vam->ofp, &node);
1056   vat_json_free (&node);
1057
1058   vam->retval = ntohl (mp->retval);
1059   vam->result_ready = 1;
1060 }
1061
1062 static void vl_api_add_node_next_reply_t_handler
1063   (vl_api_add_node_next_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   i32 retval = ntohl (mp->retval);
1067   if (vam->async_mode)
1068     {
1069       vam->async_errors += (retval < 0);
1070     }
1071   else
1072     {
1073       vam->retval = retval;
1074       if (retval == 0)
1075         errmsg ("next index %d\n", ntohl (mp->next_index));
1076       vam->result_ready = 1;
1077     }
1078 }
1079
1080 static void vl_api_add_node_next_reply_t_handler_json
1081   (vl_api_add_node_next_reply_t * mp)
1082 {
1083   vat_main_t *vam = &vat_main;
1084   vat_json_node_t node;
1085
1086   vat_json_init_object (&node);
1087   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1088   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1089
1090   vat_json_print (vam->ofp, &node);
1091   vat_json_free (&node);
1092
1093   vam->retval = ntohl (mp->retval);
1094   vam->result_ready = 1;
1095 }
1096
1097 static void vl_api_show_version_reply_t_handler
1098   (vl_api_show_version_reply_t * mp)
1099 {
1100   vat_main_t *vam = &vat_main;
1101   i32 retval = ntohl (mp->retval);
1102
1103   if (retval >= 0)
1104     {
1105       errmsg ("        program: %s\n", mp->program);
1106       errmsg ("        version: %s\n", mp->version);
1107       errmsg ("     build date: %s\n", mp->build_date);
1108       errmsg ("build directory: %s\n", mp->build_directory);
1109     }
1110   vam->retval = retval;
1111   vam->result_ready = 1;
1112 }
1113
1114 static void vl_api_show_version_reply_t_handler_json
1115   (vl_api_show_version_reply_t * mp)
1116 {
1117   vat_main_t *vam = &vat_main;
1118   vat_json_node_t node;
1119
1120   vat_json_init_object (&node);
1121   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1122   vat_json_object_add_string_copy (&node, "program", mp->program);
1123   vat_json_object_add_string_copy (&node, "version", mp->version);
1124   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1125   vat_json_object_add_string_copy (&node, "build_directory",
1126                                    mp->build_directory);
1127
1128   vat_json_print (vam->ofp, &node);
1129   vat_json_free (&node);
1130
1131   vam->retval = ntohl (mp->retval);
1132   vam->result_ready = 1;
1133 }
1134
1135 static void
1136 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1137 {
1138   vat_main_t *vam = &vat_main;
1139   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1140           mp->mac_ip ? "mac/ip binding" : "address resolution",
1141           format_ip4_address, &mp->address,
1142           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1143 }
1144
1145 static void
1146 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1147 {
1148   /* JSON output not supported */
1149 }
1150
1151 static void
1152 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1153 {
1154   vat_main_t *vam = &vat_main;
1155   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1156           mp->mac_ip ? "mac/ip binding" : "address resolution",
1157           format_ip6_address, mp->address,
1158           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1159 }
1160
1161 static void
1162 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1163 {
1164   /* JSON output not supported */
1165 }
1166
1167 /*
1168  * Special-case: build the bridge domain table, maintain
1169  * the next bd id vbl.
1170  */
1171 static void vl_api_bridge_domain_details_t_handler
1172   (vl_api_bridge_domain_details_t * mp)
1173 {
1174   vat_main_t *vam = &vat_main;
1175   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1176
1177   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1178            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1179
1180   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1181            ntohl (mp->bd_id), mp->learn, mp->forward,
1182            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1183
1184   if (n_sw_ifs)
1185     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1186              "Interface Name");
1187 }
1188
1189 static void vl_api_bridge_domain_details_t_handler_json
1190   (vl_api_bridge_domain_details_t * mp)
1191 {
1192   vat_main_t *vam = &vat_main;
1193   vat_json_node_t *node, *array = NULL;
1194
1195   if (VAT_JSON_ARRAY != vam->json_tree.type)
1196     {
1197       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1198       vat_json_init_array (&vam->json_tree);
1199     }
1200   node = vat_json_array_add (&vam->json_tree);
1201
1202   vat_json_init_object (node);
1203   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1204   vat_json_object_add_uint (node, "flood", mp->flood);
1205   vat_json_object_add_uint (node, "forward", mp->forward);
1206   vat_json_object_add_uint (node, "learn", mp->learn);
1207   vat_json_object_add_uint (node, "bvi_sw_if_index",
1208                             ntohl (mp->bvi_sw_if_index));
1209   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1210   array = vat_json_object_add (node, "sw_if");
1211   vat_json_init_array (array);
1212 }
1213
1214 /*
1215  * Special-case: build the bridge domain sw if table.
1216  */
1217 static void vl_api_bridge_domain_sw_if_details_t_handler
1218   (vl_api_bridge_domain_sw_if_details_t * mp)
1219 {
1220   vat_main_t *vam = &vat_main;
1221   hash_pair_t *p;
1222   u8 *sw_if_name = 0;
1223   u32 sw_if_index;
1224
1225   sw_if_index = ntohl (mp->sw_if_index);
1226   /* *INDENT-OFF* */
1227   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1228   ({
1229     if ((u32) p->value[0] == sw_if_index)
1230       {
1231         sw_if_name = (u8 *)(p->key);
1232         break;
1233       }
1234   }));
1235   /* *INDENT-ON* */
1236
1237   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1238            mp->shg, sw_if_name ? (char *) sw_if_name :
1239            "sw_if_index not found!");
1240 }
1241
1242 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1243   (vl_api_bridge_domain_sw_if_details_t * mp)
1244 {
1245   vat_main_t *vam = &vat_main;
1246   vat_json_node_t *node = NULL;
1247   uword last_index = 0;
1248
1249   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1250   ASSERT (vec_len (vam->json_tree.array) >= 1);
1251   last_index = vec_len (vam->json_tree.array) - 1;
1252   node = &vam->json_tree.array[last_index];
1253   node = vat_json_object_get_element (node, "sw_if");
1254   ASSERT (NULL != node);
1255   node = vat_json_array_add (node);
1256
1257   vat_json_init_object (node);
1258   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1259   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1260   vat_json_object_add_uint (node, "shg", mp->shg);
1261 }
1262
1263 static void vl_api_control_ping_reply_t_handler
1264   (vl_api_control_ping_reply_t * mp)
1265 {
1266   vat_main_t *vam = &vat_main;
1267   i32 retval = ntohl (mp->retval);
1268   if (vam->async_mode)
1269     {
1270       vam->async_errors += (retval < 0);
1271     }
1272   else
1273     {
1274       vam->retval = retval;
1275       vam->result_ready = 1;
1276     }
1277 }
1278
1279 static void vl_api_control_ping_reply_t_handler_json
1280   (vl_api_control_ping_reply_t * mp)
1281 {
1282   vat_main_t *vam = &vat_main;
1283   i32 retval = ntohl (mp->retval);
1284
1285   if (VAT_JSON_NONE != vam->json_tree.type)
1286     {
1287       vat_json_print (vam->ofp, &vam->json_tree);
1288       vat_json_free (&vam->json_tree);
1289       vam->json_tree.type = VAT_JSON_NONE;
1290     }
1291   else
1292     {
1293       /* just print [] */
1294       vat_json_init_array (&vam->json_tree);
1295       vat_json_print (vam->ofp, &vam->json_tree);
1296       vam->json_tree.type = VAT_JSON_NONE;
1297     }
1298
1299   vam->retval = retval;
1300   vam->result_ready = 1;
1301 }
1302
1303 static void
1304 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1305 {
1306   vat_main_t *vam = &vat_main;
1307   i32 retval = ntohl (mp->retval);
1308   if (vam->async_mode)
1309     {
1310       vam->async_errors += (retval < 0);
1311     }
1312   else
1313     {
1314       vam->retval = retval;
1315       vam->result_ready = 1;
1316     }
1317 }
1318
1319 static void vl_api_l2_flags_reply_t_handler_json
1320   (vl_api_l2_flags_reply_t * mp)
1321 {
1322   vat_main_t *vam = &vat_main;
1323   vat_json_node_t node;
1324
1325   vat_json_init_object (&node);
1326   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1327   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1328                             ntohl (mp->resulting_feature_bitmap));
1329
1330   vat_json_print (vam->ofp, &node);
1331   vat_json_free (&node);
1332
1333   vam->retval = ntohl (mp->retval);
1334   vam->result_ready = 1;
1335 }
1336
1337 static void vl_api_bridge_flags_reply_t_handler
1338   (vl_api_bridge_flags_reply_t * mp)
1339 {
1340   vat_main_t *vam = &vat_main;
1341   i32 retval = ntohl (mp->retval);
1342   if (vam->async_mode)
1343     {
1344       vam->async_errors += (retval < 0);
1345     }
1346   else
1347     {
1348       vam->retval = retval;
1349       vam->result_ready = 1;
1350     }
1351 }
1352
1353 static void vl_api_bridge_flags_reply_t_handler_json
1354   (vl_api_bridge_flags_reply_t * mp)
1355 {
1356   vat_main_t *vam = &vat_main;
1357   vat_json_node_t node;
1358
1359   vat_json_init_object (&node);
1360   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1361   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1362                             ntohl (mp->resulting_feature_bitmap));
1363
1364   vat_json_print (vam->ofp, &node);
1365   vat_json_free (&node);
1366
1367   vam->retval = ntohl (mp->retval);
1368   vam->result_ready = 1;
1369 }
1370
1371 static void vl_api_tap_connect_reply_t_handler
1372   (vl_api_tap_connect_reply_t * mp)
1373 {
1374   vat_main_t *vam = &vat_main;
1375   i32 retval = ntohl (mp->retval);
1376   if (vam->async_mode)
1377     {
1378       vam->async_errors += (retval < 0);
1379     }
1380   else
1381     {
1382       vam->retval = retval;
1383       vam->sw_if_index = ntohl (mp->sw_if_index);
1384       vam->result_ready = 1;
1385     }
1386
1387 }
1388
1389 static void vl_api_tap_connect_reply_t_handler_json
1390   (vl_api_tap_connect_reply_t * mp)
1391 {
1392   vat_main_t *vam = &vat_main;
1393   vat_json_node_t node;
1394
1395   vat_json_init_object (&node);
1396   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1397   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1398
1399   vat_json_print (vam->ofp, &node);
1400   vat_json_free (&node);
1401
1402   vam->retval = ntohl (mp->retval);
1403   vam->result_ready = 1;
1404
1405 }
1406
1407 static void
1408 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1409 {
1410   vat_main_t *vam = &vat_main;
1411   i32 retval = ntohl (mp->retval);
1412   if (vam->async_mode)
1413     {
1414       vam->async_errors += (retval < 0);
1415     }
1416   else
1417     {
1418       vam->retval = retval;
1419       vam->sw_if_index = ntohl (mp->sw_if_index);
1420       vam->result_ready = 1;
1421     }
1422 }
1423
1424 static void vl_api_tap_modify_reply_t_handler_json
1425   (vl_api_tap_modify_reply_t * mp)
1426 {
1427   vat_main_t *vam = &vat_main;
1428   vat_json_node_t node;
1429
1430   vat_json_init_object (&node);
1431   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1432   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1433
1434   vat_json_print (vam->ofp, &node);
1435   vat_json_free (&node);
1436
1437   vam->retval = ntohl (mp->retval);
1438   vam->result_ready = 1;
1439 }
1440
1441 static void
1442 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1443 {
1444   vat_main_t *vam = &vat_main;
1445   i32 retval = ntohl (mp->retval);
1446   if (vam->async_mode)
1447     {
1448       vam->async_errors += (retval < 0);
1449     }
1450   else
1451     {
1452       vam->retval = retval;
1453       vam->result_ready = 1;
1454     }
1455 }
1456
1457 static void vl_api_tap_delete_reply_t_handler_json
1458   (vl_api_tap_delete_reply_t * mp)
1459 {
1460   vat_main_t *vam = &vat_main;
1461   vat_json_node_t node;
1462
1463   vat_json_init_object (&node);
1464   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1465
1466   vat_json_print (vam->ofp, &node);
1467   vat_json_free (&node);
1468
1469   vam->retval = ntohl (mp->retval);
1470   vam->result_ready = 1;
1471 }
1472
1473 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1474   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1475 {
1476   vat_main_t *vam = &vat_main;
1477   i32 retval = ntohl (mp->retval);
1478   if (vam->async_mode)
1479     {
1480       vam->async_errors += (retval < 0);
1481     }
1482   else
1483     {
1484       vam->retval = retval;
1485       vam->result_ready = 1;
1486     }
1487 }
1488
1489 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1490   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1491 {
1492   vat_main_t *vam = &vat_main;
1493   vat_json_node_t node;
1494
1495   vat_json_init_object (&node);
1496   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1497   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1498                             ntohl (mp->tunnel_sw_if_index));
1499
1500   vat_json_print (vam->ofp, &node);
1501   vat_json_free (&node);
1502
1503   vam->retval = ntohl (mp->retval);
1504   vam->result_ready = 1;
1505 }
1506
1507 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1508   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1509 {
1510   vat_main_t *vam = &vat_main;
1511   i32 retval = ntohl (mp->retval);
1512   if (vam->async_mode)
1513     {
1514       vam->async_errors += (retval < 0);
1515     }
1516   else
1517     {
1518       vam->retval = retval;
1519       vam->sw_if_index = ntohl (mp->sw_if_index);
1520       vam->result_ready = 1;
1521     }
1522 }
1523
1524 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1525   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1526 {
1527   vat_main_t *vam = &vat_main;
1528   vat_json_node_t node;
1529
1530   vat_json_init_object (&node);
1531   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1532   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1533
1534   vat_json_print (vam->ofp, &node);
1535   vat_json_free (&node);
1536
1537   vam->retval = ntohl (mp->retval);
1538   vam->result_ready = 1;
1539 }
1540
1541
1542 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1543   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1544 {
1545   vat_main_t *vam = &vat_main;
1546   i32 retval = ntohl (mp->retval);
1547   if (vam->async_mode)
1548     {
1549       vam->async_errors += (retval < 0);
1550     }
1551   else
1552     {
1553       vam->retval = retval;
1554       vam->result_ready = 1;
1555     }
1556 }
1557
1558 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1559   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1560 {
1561   vat_main_t *vam = &vat_main;
1562   vat_json_node_t node;
1563
1564   vat_json_init_object (&node);
1565   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1566   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1567
1568   vat_json_print (vam->ofp, &node);
1569   vat_json_free (&node);
1570
1571   vam->retval = ntohl (mp->retval);
1572   vam->result_ready = 1;
1573 }
1574
1575 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1576   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1577 {
1578   vat_main_t *vam = &vat_main;
1579   i32 retval = ntohl (mp->retval);
1580   if (vam->async_mode)
1581     {
1582       vam->async_errors += (retval < 0);
1583     }
1584   else
1585     {
1586       vam->retval = retval;
1587       vam->sw_if_index = ntohl (mp->sw_if_index);
1588       vam->result_ready = 1;
1589     }
1590 }
1591
1592 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1593   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1594 {
1595   vat_main_t *vam = &vat_main;
1596   vat_json_node_t node;
1597
1598   vat_json_init_object (&node);
1599   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1600   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1601
1602   vat_json_print (vam->ofp, &node);
1603   vat_json_free (&node);
1604
1605   vam->retval = ntohl (mp->retval);
1606   vam->result_ready = 1;
1607 }
1608
1609 static void vl_api_gre_add_del_tunnel_reply_t_handler
1610   (vl_api_gre_add_del_tunnel_reply_t * mp)
1611 {
1612   vat_main_t *vam = &vat_main;
1613   i32 retval = ntohl (mp->retval);
1614   if (vam->async_mode)
1615     {
1616       vam->async_errors += (retval < 0);
1617     }
1618   else
1619     {
1620       vam->retval = retval;
1621       vam->sw_if_index = ntohl (mp->sw_if_index);
1622       vam->result_ready = 1;
1623     }
1624 }
1625
1626 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1627   (vl_api_gre_add_del_tunnel_reply_t * mp)
1628 {
1629   vat_main_t *vam = &vat_main;
1630   vat_json_node_t node;
1631
1632   vat_json_init_object (&node);
1633   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1634   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1635
1636   vat_json_print (vam->ofp, &node);
1637   vat_json_free (&node);
1638
1639   vam->retval = ntohl (mp->retval);
1640   vam->result_ready = 1;
1641 }
1642
1643 static void vl_api_create_vhost_user_if_reply_t_handler
1644   (vl_api_create_vhost_user_if_reply_t * mp)
1645 {
1646   vat_main_t *vam = &vat_main;
1647   i32 retval = ntohl (mp->retval);
1648   if (vam->async_mode)
1649     {
1650       vam->async_errors += (retval < 0);
1651     }
1652   else
1653     {
1654       vam->retval = retval;
1655       vam->sw_if_index = ntohl (mp->sw_if_index);
1656       vam->result_ready = 1;
1657     }
1658 }
1659
1660 static void vl_api_create_vhost_user_if_reply_t_handler_json
1661   (vl_api_create_vhost_user_if_reply_t * mp)
1662 {
1663   vat_main_t *vam = &vat_main;
1664   vat_json_node_t node;
1665
1666   vat_json_init_object (&node);
1667   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1668   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1669
1670   vat_json_print (vam->ofp, &node);
1671   vat_json_free (&node);
1672
1673   vam->retval = ntohl (mp->retval);
1674   vam->result_ready = 1;
1675 }
1676
1677 static void vl_api_ip_address_details_t_handler
1678   (vl_api_ip_address_details_t * mp)
1679 {
1680   vat_main_t *vam = &vat_main;
1681   static ip_address_details_t empty_ip_address_details = { {0} };
1682   ip_address_details_t *address = NULL;
1683   ip_details_t *current_ip_details = NULL;
1684   ip_details_t *details = NULL;
1685
1686   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1687
1688   if (!details || vam->current_sw_if_index >= vec_len (details)
1689       || !details[vam->current_sw_if_index].present)
1690     {
1691       errmsg ("ip address details arrived but not stored\n");
1692       errmsg ("ip_dump should be called first\n");
1693       return;
1694     }
1695
1696   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1697
1698 #define addresses (current_ip_details->addr)
1699
1700   vec_validate_init_empty (addresses, vec_len (addresses),
1701                            empty_ip_address_details);
1702
1703   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1704
1705   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1706   address->prefix_length = mp->prefix_length;
1707 #undef addresses
1708 }
1709
1710 static void vl_api_ip_address_details_t_handler_json
1711   (vl_api_ip_address_details_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   vat_json_node_t *node = NULL;
1715   struct in6_addr ip6;
1716   struct in_addr ip4;
1717
1718   if (VAT_JSON_ARRAY != vam->json_tree.type)
1719     {
1720       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1721       vat_json_init_array (&vam->json_tree);
1722     }
1723   node = vat_json_array_add (&vam->json_tree);
1724
1725   vat_json_init_object (node);
1726   if (vam->is_ipv6)
1727     {
1728       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1729       vat_json_object_add_ip6 (node, "ip", ip6);
1730     }
1731   else
1732     {
1733       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1734       vat_json_object_add_ip4 (node, "ip", ip4);
1735     }
1736   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1737 }
1738
1739 static void
1740 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1741 {
1742   vat_main_t *vam = &vat_main;
1743   static ip_details_t empty_ip_details = { 0 };
1744   ip_details_t *ip = NULL;
1745   u32 sw_if_index = ~0;
1746
1747   sw_if_index = ntohl (mp->sw_if_index);
1748
1749   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1750                            sw_if_index, empty_ip_details);
1751
1752   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1753                          sw_if_index);
1754
1755   ip->present = 1;
1756 }
1757
1758 static void
1759 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1760 {
1761   vat_main_t *vam = &vat_main;
1762
1763   if (VAT_JSON_ARRAY != vam->json_tree.type)
1764     {
1765       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1766       vat_json_init_array (&vam->json_tree);
1767     }
1768   vat_json_array_add_uint (&vam->json_tree,
1769                            clib_net_to_host_u32 (mp->sw_if_index));
1770 }
1771
1772 static void vl_api_map_domain_details_t_handler_json
1773   (vl_api_map_domain_details_t * mp)
1774 {
1775   vat_json_node_t *node = NULL;
1776   vat_main_t *vam = &vat_main;
1777   struct in6_addr ip6;
1778   struct in_addr ip4;
1779
1780   if (VAT_JSON_ARRAY != vam->json_tree.type)
1781     {
1782       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1783       vat_json_init_array (&vam->json_tree);
1784     }
1785
1786   node = vat_json_array_add (&vam->json_tree);
1787   vat_json_init_object (node);
1788
1789   vat_json_object_add_uint (node, "domain_index",
1790                             clib_net_to_host_u32 (mp->domain_index));
1791   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1792   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1793   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1794   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1795   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1796   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1797   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1798   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1799   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1800   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1801   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1802   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1803   vat_json_object_add_uint (node, "flags", mp->flags);
1804   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1805   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1806 }
1807
1808 static void vl_api_map_domain_details_t_handler
1809   (vl_api_map_domain_details_t * mp)
1810 {
1811   vat_main_t *vam = &vat_main;
1812
1813   if (mp->is_translation)
1814     {
1815       fformat (vam->ofp,
1816                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1817                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1818                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1819                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1820                clib_net_to_host_u32 (mp->domain_index));
1821     }
1822   else
1823     {
1824       fformat (vam->ofp,
1825                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1826                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1827                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1828                format_ip6_address, mp->ip6_src,
1829                clib_net_to_host_u32 (mp->domain_index));
1830     }
1831   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1832            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1833            mp->is_translation ? "map-t" : "");
1834 }
1835
1836 static void vl_api_map_rule_details_t_handler_json
1837   (vl_api_map_rule_details_t * mp)
1838 {
1839   struct in6_addr ip6;
1840   vat_json_node_t *node = NULL;
1841   vat_main_t *vam = &vat_main;
1842
1843   if (VAT_JSON_ARRAY != vam->json_tree.type)
1844     {
1845       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1846       vat_json_init_array (&vam->json_tree);
1847     }
1848
1849   node = vat_json_array_add (&vam->json_tree);
1850   vat_json_init_object (node);
1851
1852   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1853   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1854   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1855 }
1856
1857 static void
1858 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1859 {
1860   vat_main_t *vam = &vat_main;
1861   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1862            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1863 }
1864
1865 static void
1866 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1867 {
1868   vat_main_t *vam = &vat_main;
1869   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1870           "router_addr %U host_mac %U\n",
1871           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1872           format_ip4_address, &mp->host_address,
1873           format_ip4_address, &mp->router_address,
1874           format_ethernet_address, mp->host_mac);
1875 }
1876
1877 static void vl_api_dhcp_compl_event_t_handler_json
1878   (vl_api_dhcp_compl_event_t * mp)
1879 {
1880   /* JSON output not supported */
1881 }
1882
1883 static void
1884 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1885                               u32 counter)
1886 {
1887   vat_main_t *vam = &vat_main;
1888   static u64 default_counter = 0;
1889
1890   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1891                            NULL);
1892   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1893                            sw_if_index, default_counter);
1894   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1895 }
1896
1897 static void
1898 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1899                                 interface_counter_t counter)
1900 {
1901   vat_main_t *vam = &vat_main;
1902   static interface_counter_t default_counter = { 0, };
1903
1904   vec_validate_init_empty (vam->combined_interface_counters,
1905                            vnet_counter_type, NULL);
1906   vec_validate_init_empty (vam->combined_interface_counters
1907                            [vnet_counter_type], sw_if_index, default_counter);
1908   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1909 }
1910
1911 static void vl_api_vnet_interface_counters_t_handler
1912   (vl_api_vnet_interface_counters_t * mp)
1913 {
1914   /* not supported */
1915 }
1916
1917 static void vl_api_vnet_interface_counters_t_handler_json
1918   (vl_api_vnet_interface_counters_t * mp)
1919 {
1920   interface_counter_t counter;
1921   vlib_counter_t *v;
1922   u64 *v_packets;
1923   u64 packets;
1924   u32 count;
1925   u32 first_sw_if_index;
1926   int i;
1927
1928   count = ntohl (mp->count);
1929   first_sw_if_index = ntohl (mp->first_sw_if_index);
1930
1931   if (!mp->is_combined)
1932     {
1933       v_packets = (u64 *) & mp->data;
1934       for (i = 0; i < count; i++)
1935         {
1936           packets =
1937             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1938           set_simple_interface_counter (mp->vnet_counter_type,
1939                                         first_sw_if_index + i, packets);
1940           v_packets++;
1941         }
1942     }
1943   else
1944     {
1945       v = (vlib_counter_t *) & mp->data;
1946       for (i = 0; i < count; i++)
1947         {
1948           counter.packets =
1949             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1950           counter.bytes =
1951             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1952           set_combined_interface_counter (mp->vnet_counter_type,
1953                                           first_sw_if_index + i, counter);
1954           v++;
1955         }
1956     }
1957 }
1958
1959 static u32
1960 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1961 {
1962   vat_main_t *vam = &vat_main;
1963   u32 i;
1964
1965   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1966     {
1967       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1968         {
1969           return i;
1970         }
1971     }
1972   return ~0;
1973 }
1974
1975 static u32
1976 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1977 {
1978   vat_main_t *vam = &vat_main;
1979   u32 i;
1980
1981   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1982     {
1983       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1984         {
1985           return i;
1986         }
1987     }
1988   return ~0;
1989 }
1990
1991 static void vl_api_vnet_ip4_fib_counters_t_handler
1992   (vl_api_vnet_ip4_fib_counters_t * mp)
1993 {
1994   /* not supported */
1995 }
1996
1997 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1998   (vl_api_vnet_ip4_fib_counters_t * mp)
1999 {
2000   vat_main_t *vam = &vat_main;
2001   vl_api_ip4_fib_counter_t *v;
2002   ip4_fib_counter_t *counter;
2003   struct in_addr ip4;
2004   u32 vrf_id;
2005   u32 vrf_index;
2006   u32 count;
2007   int i;
2008
2009   vrf_id = ntohl (mp->vrf_id);
2010   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2011   if (~0 == vrf_index)
2012     {
2013       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2014       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2015       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2016       vec_validate (vam->ip4_fib_counters, vrf_index);
2017       vam->ip4_fib_counters[vrf_index] = NULL;
2018     }
2019
2020   vec_free (vam->ip4_fib_counters[vrf_index]);
2021   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2022   count = ntohl (mp->count);
2023   for (i = 0; i < count; i++)
2024     {
2025       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2026       counter = &vam->ip4_fib_counters[vrf_index][i];
2027       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2028       counter->address = ip4;
2029       counter->address_length = v->address_length;
2030       counter->packets = clib_net_to_host_u64 (v->packets);
2031       counter->bytes = clib_net_to_host_u64 (v->bytes);
2032       v++;
2033     }
2034 }
2035
2036 static void vl_api_vnet_ip6_fib_counters_t_handler
2037   (vl_api_vnet_ip6_fib_counters_t * mp)
2038 {
2039   /* not supported */
2040 }
2041
2042 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2043   (vl_api_vnet_ip6_fib_counters_t * mp)
2044 {
2045   vat_main_t *vam = &vat_main;
2046   vl_api_ip6_fib_counter_t *v;
2047   ip6_fib_counter_t *counter;
2048   struct in6_addr ip6;
2049   u32 vrf_id;
2050   u32 vrf_index;
2051   u32 count;
2052   int i;
2053
2054   vrf_id = ntohl (mp->vrf_id);
2055   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2056   if (~0 == vrf_index)
2057     {
2058       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2059       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2060       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2061       vec_validate (vam->ip6_fib_counters, vrf_index);
2062       vam->ip6_fib_counters[vrf_index] = NULL;
2063     }
2064
2065   vec_free (vam->ip6_fib_counters[vrf_index]);
2066   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2067   count = ntohl (mp->count);
2068   for (i = 0; i < count; i++)
2069     {
2070       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2071       counter = &vam->ip6_fib_counters[vrf_index][i];
2072       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2073       counter->address = ip6;
2074       counter->address_length = v->address_length;
2075       counter->packets = clib_net_to_host_u64 (v->packets);
2076       counter->bytes = clib_net_to_host_u64 (v->bytes);
2077       v++;
2078     }
2079 }
2080
2081 static void vl_api_get_first_msg_id_reply_t_handler
2082   (vl_api_get_first_msg_id_reply_t * mp)
2083 {
2084   vat_main_t *vam = &vat_main;
2085   i32 retval = ntohl (mp->retval);
2086
2087   if (vam->async_mode)
2088     {
2089       vam->async_errors += (retval < 0);
2090     }
2091   else
2092     {
2093       vam->retval = retval;
2094       vam->result_ready = 1;
2095     }
2096   if (retval >= 0)
2097     {
2098       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2099     }
2100 }
2101
2102 static void vl_api_get_first_msg_id_reply_t_handler_json
2103   (vl_api_get_first_msg_id_reply_t * mp)
2104 {
2105   vat_main_t *vam = &vat_main;
2106   vat_json_node_t node;
2107
2108   vat_json_init_object (&node);
2109   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2110   vat_json_object_add_uint (&node, "first_msg_id",
2111                             (uint) ntohs (mp->first_msg_id));
2112
2113   vat_json_print (vam->ofp, &node);
2114   vat_json_free (&node);
2115
2116   vam->retval = ntohl (mp->retval);
2117   vam->result_ready = 1;
2118 }
2119
2120 static void vl_api_get_node_graph_reply_t_handler
2121   (vl_api_get_node_graph_reply_t * mp)
2122 {
2123   vat_main_t *vam = &vat_main;
2124   api_main_t *am = &api_main;
2125   i32 retval = ntohl (mp->retval);
2126   u8 *pvt_copy, *reply;
2127   void *oldheap;
2128   vlib_node_t *node;
2129   int i;
2130
2131   if (vam->async_mode)
2132     {
2133       vam->async_errors += (retval < 0);
2134     }
2135   else
2136     {
2137       vam->retval = retval;
2138       vam->result_ready = 1;
2139     }
2140
2141   /* "Should never happen..." */
2142   if (retval != 0)
2143     return;
2144
2145   reply = (u8 *) (mp->reply_in_shmem);
2146   pvt_copy = vec_dup (reply);
2147
2148   /* Toss the shared-memory original... */
2149   pthread_mutex_lock (&am->vlib_rp->mutex);
2150   oldheap = svm_push_data_heap (am->vlib_rp);
2151
2152   vec_free (reply);
2153
2154   svm_pop_heap (oldheap);
2155   pthread_mutex_unlock (&am->vlib_rp->mutex);
2156
2157   if (vam->graph_nodes)
2158     {
2159       hash_free (vam->graph_node_index_by_name);
2160
2161       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2162         {
2163           node = vam->graph_nodes[i];
2164           vec_free (node->name);
2165           vec_free (node->next_nodes);
2166           vec_free (node);
2167         }
2168       vec_free (vam->graph_nodes);
2169     }
2170
2171   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2172   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2173   vec_free (pvt_copy);
2174
2175   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2176     {
2177       node = vam->graph_nodes[i];
2178       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2179     }
2180 }
2181
2182 static void vl_api_get_node_graph_reply_t_handler_json
2183   (vl_api_get_node_graph_reply_t * mp)
2184 {
2185   vat_main_t *vam = &vat_main;
2186   api_main_t *am = &api_main;
2187   void *oldheap;
2188   vat_json_node_t node;
2189   u8 *reply;
2190
2191   /* $$$$ make this real? */
2192   vat_json_init_object (&node);
2193   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2194   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2195
2196   reply = (u8 *) (mp->reply_in_shmem);
2197
2198   /* Toss the shared-memory original... */
2199   pthread_mutex_lock (&am->vlib_rp->mutex);
2200   oldheap = svm_push_data_heap (am->vlib_rp);
2201
2202   vec_free (reply);
2203
2204   svm_pop_heap (oldheap);
2205   pthread_mutex_unlock (&am->vlib_rp->mutex);
2206
2207   vat_json_print (vam->ofp, &node);
2208   vat_json_free (&node);
2209
2210   vam->retval = ntohl (mp->retval);
2211   vam->result_ready = 1;
2212 }
2213
2214 static void
2215 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2216 {
2217   vat_main_t *vam = &vat_main;
2218   u8 *s = 0;
2219
2220   if (mp->local)
2221     {
2222       s = format (s, "%=16d%=16d%=16d\n",
2223                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2224     }
2225   else
2226     {
2227       s = format (s, "%=16U%=16d%=16d\n",
2228                   mp->is_ipv6 ? format_ip6_address :
2229                   format_ip4_address,
2230                   mp->ip_address, mp->priority, mp->weight);
2231     }
2232
2233   fformat (vam->ofp, "%v", s);
2234   vec_free (s);
2235 }
2236
2237 static void
2238 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2239                                             mp)
2240 {
2241   vat_main_t *vam = &vat_main;
2242   vat_json_node_t *node = NULL;
2243   struct in6_addr ip6;
2244   struct in_addr ip4;
2245
2246   if (VAT_JSON_ARRAY != vam->json_tree.type)
2247     {
2248       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2249       vat_json_init_array (&vam->json_tree);
2250     }
2251   node = vat_json_array_add (&vam->json_tree);
2252   vat_json_init_object (node);
2253
2254   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2255   vat_json_object_add_uint (node, "priority", mp->priority);
2256   vat_json_object_add_uint (node, "weight", mp->weight);
2257
2258   if (mp->local)
2259     vat_json_object_add_uint (node, "sw_if_index",
2260                               clib_net_to_host_u32 (mp->sw_if_index));
2261   else
2262     {
2263       if (mp->is_ipv6)
2264         {
2265           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2266           vat_json_object_add_ip6 (node, "address", ip6);
2267         }
2268       else
2269         {
2270           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2271           vat_json_object_add_ip4 (node, "address", ip4);
2272         }
2273     }
2274 }
2275
2276 static void
2277 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2278                                            mp)
2279 {
2280   vat_main_t *vam = &vat_main;
2281   u8 *ls_name = 0;
2282
2283   ls_name = format (0, "%s", mp->ls_name);
2284
2285   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2286            ls_name);
2287   vec_free (ls_name);
2288 }
2289
2290 static void
2291   vl_api_lisp_locator_set_details_t_handler_json
2292   (vl_api_lisp_locator_set_details_t * mp)
2293 {
2294   vat_main_t *vam = &vat_main;
2295   vat_json_node_t *node = 0;
2296   u8 *ls_name = 0;
2297
2298   ls_name = format (0, "%s", mp->ls_name);
2299   vec_add1 (ls_name, 0);
2300
2301   if (VAT_JSON_ARRAY != vam->json_tree.type)
2302     {
2303       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2304       vat_json_init_array (&vam->json_tree);
2305     }
2306   node = vat_json_array_add (&vam->json_tree);
2307
2308   vat_json_init_object (node);
2309   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2310   vat_json_object_add_uint (node, "ls_index",
2311                             clib_net_to_host_u32 (mp->ls_index));
2312   vec_free (ls_name);
2313 }
2314
2315 static u8 *
2316 format_lisp_flat_eid (u8 * s, va_list * args)
2317 {
2318   u32 type = va_arg (*args, u32);
2319   u8 *eid = va_arg (*args, u8 *);
2320   u32 eid_len = va_arg (*args, u32);
2321
2322   switch (type)
2323     {
2324     case 0:
2325       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2326     case 1:
2327       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2328     case 2:
2329       return format (s, "%U", format_ethernet_address, eid);
2330     }
2331   return 0;
2332 }
2333
2334 static u8 *
2335 format_lisp_eid_vat (u8 * s, va_list * args)
2336 {
2337   u32 type = va_arg (*args, u32);
2338   u8 *eid = va_arg (*args, u8 *);
2339   u32 eid_len = va_arg (*args, u32);
2340   u8 *seid = va_arg (*args, u8 *);
2341   u32 seid_len = va_arg (*args, u32);
2342   u32 is_src_dst = va_arg (*args, u32);
2343
2344   if (is_src_dst)
2345     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2346
2347   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2348
2349   return s;
2350 }
2351
2352 static void
2353 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2354 {
2355   vat_main_t *vam = &vat_main;
2356   u8 *s = 0, *eid = 0;
2357
2358   if (~0 == mp->locator_set_index)
2359     s = format (0, "action: %d", mp->action);
2360   else
2361     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2362
2363   eid = format (0, "%U", format_lisp_eid_vat,
2364                 mp->eid_type,
2365                 mp->eid,
2366                 mp->eid_prefix_len,
2367                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2368   vec_add1 (eid, 0);
2369
2370   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2371            clib_net_to_host_u32 (mp->vni),
2372            eid,
2373            mp->is_local ? "local" : "remote",
2374            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2375   vec_free (s);
2376   vec_free (eid);
2377 }
2378
2379 static void
2380 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2381                                               * mp)
2382 {
2383   vat_main_t *vam = &vat_main;
2384   vat_json_node_t *node = 0;
2385   u8 *eid = 0;
2386
2387   if (VAT_JSON_ARRAY != vam->json_tree.type)
2388     {
2389       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2390       vat_json_init_array (&vam->json_tree);
2391     }
2392   node = vat_json_array_add (&vam->json_tree);
2393
2394   vat_json_init_object (node);
2395   if (~0 == mp->locator_set_index)
2396     vat_json_object_add_uint (node, "action", mp->action);
2397   else
2398     vat_json_object_add_uint (node, "locator_set_index",
2399                               clib_net_to_host_u32 (mp->locator_set_index));
2400
2401   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2402   eid = format (0, "%U", format_lisp_eid_vat,
2403                 mp->eid_type,
2404                 mp->eid,
2405                 mp->eid_prefix_len,
2406                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2407   vec_add1 (eid, 0);
2408   vat_json_object_add_string_copy (node, "eid", eid);
2409   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2410   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2411   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2412   vec_free (eid);
2413 }
2414
2415 static void
2416   vl_api_lisp_eid_table_map_details_t_handler
2417   (vl_api_lisp_eid_table_map_details_t * mp)
2418 {
2419   vat_main_t *vam = &vat_main;
2420
2421   u8 *line = format (0, "%=10d%=10d",
2422                      clib_net_to_host_u32 (mp->vni),
2423                      clib_net_to_host_u32 (mp->dp_table));
2424   fformat (vam->ofp, "%v\n", line);
2425   vec_free (line);
2426 }
2427
2428 static void
2429   vl_api_lisp_eid_table_map_details_t_handler_json
2430   (vl_api_lisp_eid_table_map_details_t * mp)
2431 {
2432   vat_main_t *vam = &vat_main;
2433   vat_json_node_t *node = NULL;
2434
2435   if (VAT_JSON_ARRAY != vam->json_tree.type)
2436     {
2437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2438       vat_json_init_array (&vam->json_tree);
2439     }
2440   node = vat_json_array_add (&vam->json_tree);
2441   vat_json_init_object (node);
2442   vat_json_object_add_uint (node, "dp_table",
2443                             clib_net_to_host_u32 (mp->dp_table));
2444   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2445 }
2446
2447 static void
2448   vl_api_lisp_eid_table_vni_details_t_handler
2449   (vl_api_lisp_eid_table_vni_details_t * mp)
2450 {
2451   vat_main_t *vam = &vat_main;
2452
2453   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2454   fformat (vam->ofp, "%v\n", line);
2455   vec_free (line);
2456 }
2457
2458 static void
2459   vl_api_lisp_eid_table_vni_details_t_handler_json
2460   (vl_api_lisp_eid_table_vni_details_t * mp)
2461 {
2462   vat_main_t *vam = &vat_main;
2463   vat_json_node_t *node = NULL;
2464
2465   if (VAT_JSON_ARRAY != vam->json_tree.type)
2466     {
2467       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2468       vat_json_init_array (&vam->json_tree);
2469     }
2470   node = vat_json_array_add (&vam->json_tree);
2471   vat_json_init_object (node);
2472   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2473 }
2474
2475 static u8 *
2476 format_decap_next (u8 * s, va_list * args)
2477 {
2478   u32 next_index = va_arg (*args, u32);
2479
2480   switch (next_index)
2481     {
2482     case LISP_GPE_INPUT_NEXT_DROP:
2483       return format (s, "drop");
2484     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2485       return format (s, "ip4");
2486     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2487       return format (s, "ip6");
2488     default:
2489       return format (s, "unknown %d", next_index);
2490     }
2491   return s;
2492 }
2493
2494 static void
2495 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2496                                           mp)
2497 {
2498   vat_main_t *vam = &vat_main;
2499   u8 *iid_str;
2500   u8 *flag_str = NULL;
2501
2502   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2503
2504 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2505   foreach_lisp_gpe_flag_bit;
2506 #undef _
2507
2508   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2509            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2510            mp->tunnels,
2511            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2512            mp->source_ip,
2513            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2514            mp->destination_ip,
2515            ntohl (mp->encap_fib_id),
2516            ntohl (mp->decap_fib_id),
2517            format_decap_next, ntohl (mp->dcap_next),
2518            mp->ver_res >> 6,
2519            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2520
2521   vec_free (iid_str);
2522 }
2523
2524 static void
2525   vl_api_lisp_gpe_tunnel_details_t_handler_json
2526   (vl_api_lisp_gpe_tunnel_details_t * mp)
2527 {
2528   vat_main_t *vam = &vat_main;
2529   vat_json_node_t *node = NULL;
2530   struct in6_addr ip6;
2531   struct in_addr ip4;
2532   u8 *next_decap_str;
2533
2534   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2535
2536   if (VAT_JSON_ARRAY != vam->json_tree.type)
2537     {
2538       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2539       vat_json_init_array (&vam->json_tree);
2540     }
2541   node = vat_json_array_add (&vam->json_tree);
2542
2543   vat_json_init_object (node);
2544   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2545   if (mp->is_ipv6)
2546     {
2547       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2548       vat_json_object_add_ip6 (node, "source address", ip6);
2549       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2550       vat_json_object_add_ip6 (node, "destination address", ip6);
2551     }
2552   else
2553     {
2554       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2555       vat_json_object_add_ip4 (node, "source address", ip4);
2556       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2557       vat_json_object_add_ip4 (node, "destination address", ip4);
2558     }
2559   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2560   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2561   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2562   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2563   vat_json_object_add_uint (node, "flags", mp->flags);
2564   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2565   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2566   vat_json_object_add_uint (node, "res", mp->res);
2567   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2568
2569   vec_free (next_decap_str);
2570 }
2571
2572 static void
2573   vl_api_lisp_adjacencies_get_reply_t_handler
2574   (vl_api_lisp_adjacencies_get_reply_t * mp)
2575 {
2576   vat_main_t *vam = &vat_main;
2577   u32 i, n;
2578   int retval = clib_net_to_host_u32 (mp->retval);
2579   vl_api_lisp_adjacency_t *a;
2580
2581   if (retval)
2582     goto end;
2583
2584   n = clib_net_to_host_u32 (mp->count);
2585
2586   for (i = 0; i < n; i++)
2587     {
2588       a = &mp->adjacencies[i];
2589       fformat (vam->ofp, "%U %40U\n",
2590                format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2591                format_lisp_flat_eid, a->eid_type, a->reid,
2592                a->reid_prefix_len);
2593     }
2594
2595 end:
2596   vam->retval = retval;
2597   vam->result_ready = 1;
2598 }
2599
2600 static void
2601   vl_api_lisp_adjacencies_get_reply_t_handler_json
2602   (vl_api_lisp_adjacencies_get_reply_t * mp)
2603 {
2604   u8 *s = 0;
2605   vat_main_t *vam = &vat_main;
2606   vat_json_node_t *e = 0, root;
2607   u32 i, n;
2608   int retval = clib_net_to_host_u32 (mp->retval);
2609   vl_api_lisp_adjacency_t *a;
2610
2611   if (retval)
2612     goto end;
2613
2614   n = clib_net_to_host_u32 (mp->count);
2615   vat_json_init_array (&root);
2616
2617   for (i = 0; i < n; i++)
2618     {
2619       e = vat_json_array_add (&root);
2620       a = &mp->adjacencies[i];
2621
2622       vat_json_init_object (e);
2623       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2624                   a->leid_prefix_len);
2625       vec_add1 (s, 0);
2626       vat_json_object_add_string_copy (e, "leid", s);
2627       vec_free (s);
2628
2629       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2630                   a->reid_prefix_len);
2631       vec_add1 (s, 0);
2632       vat_json_object_add_string_copy (e, "reid", s);
2633       vec_free (s);
2634     }
2635
2636   vat_json_print (vam->ofp, &root);
2637   vat_json_free (&root);
2638
2639 end:
2640   vam->retval = retval;
2641   vam->result_ready = 1;
2642 }
2643
2644 static void
2645 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2646                                             * mp)
2647 {
2648   vat_main_t *vam = &vat_main;
2649
2650   fformat (vam->ofp, "%=20U\n",
2651            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2652            mp->ip_address);
2653 }
2654
2655 static void
2656   vl_api_lisp_map_resolver_details_t_handler_json
2657   (vl_api_lisp_map_resolver_details_t * mp)
2658 {
2659   vat_main_t *vam = &vat_main;
2660   vat_json_node_t *node = NULL;
2661   struct in6_addr ip6;
2662   struct in_addr ip4;
2663
2664   if (VAT_JSON_ARRAY != vam->json_tree.type)
2665     {
2666       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2667       vat_json_init_array (&vam->json_tree);
2668     }
2669   node = vat_json_array_add (&vam->json_tree);
2670
2671   vat_json_init_object (node);
2672   if (mp->is_ipv6)
2673     {
2674       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2675       vat_json_object_add_ip6 (node, "map resolver", ip6);
2676     }
2677   else
2678     {
2679       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2680       vat_json_object_add_ip4 (node, "map resolver", ip4);
2681     }
2682 }
2683
2684 static void
2685   vl_api_show_lisp_status_reply_t_handler
2686   (vl_api_show_lisp_status_reply_t * mp)
2687 {
2688   vat_main_t *vam = &vat_main;
2689   i32 retval = ntohl (mp->retval);
2690
2691   if (0 <= retval)
2692     {
2693       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2694                mp->feature_status ? "enabled" : "disabled",
2695                mp->gpe_status ? "enabled" : "disabled");
2696     }
2697
2698   vam->retval = retval;
2699   vam->result_ready = 1;
2700 }
2701
2702 static void
2703   vl_api_show_lisp_status_reply_t_handler_json
2704   (vl_api_show_lisp_status_reply_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   vat_json_node_t node;
2708   u8 *gpe_status = NULL;
2709   u8 *feature_status = NULL;
2710
2711   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2712   feature_status = format (0, "%s",
2713                            mp->feature_status ? "enabled" : "disabled");
2714   vec_add1 (gpe_status, 0);
2715   vec_add1 (feature_status, 0);
2716
2717   vat_json_init_object (&node);
2718   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2719   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2720
2721   vec_free (gpe_status);
2722   vec_free (feature_status);
2723
2724   vat_json_print (vam->ofp, &node);
2725   vat_json_free (&node);
2726
2727   vam->retval = ntohl (mp->retval);
2728   vam->result_ready = 1;
2729 }
2730
2731 static void
2732   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2733   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2734 {
2735   vat_main_t *vam = &vat_main;
2736   i32 retval = ntohl (mp->retval);
2737
2738   if (retval >= 0)
2739     {
2740       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2741     }
2742
2743   vam->retval = retval;
2744   vam->result_ready = 1;
2745 }
2746
2747 static void
2748   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2749   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2750 {
2751   vat_main_t *vam = &vat_main;
2752   vat_json_node_t *node = NULL;
2753
2754   if (VAT_JSON_ARRAY != vam->json_tree.type)
2755     {
2756       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2757       vat_json_init_array (&vam->json_tree);
2758     }
2759   node = vat_json_array_add (&vam->json_tree);
2760
2761   vat_json_init_object (node);
2762   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2763
2764   vat_json_print (vam->ofp, node);
2765   vat_json_free (node);
2766
2767   vam->retval = ntohl (mp->retval);
2768   vam->result_ready = 1;
2769 }
2770
2771 static u8 *
2772 format_lisp_map_request_mode (u8 * s, va_list * args)
2773 {
2774   u32 mode = va_arg (*args, u32);
2775
2776   switch (mode)
2777     {
2778     case 0:
2779       return format (0, "dst-only");
2780     case 1:
2781       return format (0, "src-dst");
2782     }
2783   return 0;
2784 }
2785
2786 static void
2787   vl_api_show_lisp_map_request_mode_reply_t_handler
2788   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2789 {
2790   vat_main_t *vam = &vat_main;
2791   i32 retval = ntohl (mp->retval);
2792
2793   if (0 <= retval)
2794     {
2795       u32 mode = mp->mode;
2796       fformat (vam->ofp, "map_request_mode: %U\n",
2797                format_lisp_map_request_mode, mode);
2798     }
2799
2800   vam->retval = retval;
2801   vam->result_ready = 1;
2802 }
2803
2804 static void
2805   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2806   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2807 {
2808   vat_main_t *vam = &vat_main;
2809   vat_json_node_t node;
2810   u8 *s = 0;
2811   u32 mode;
2812
2813   mode = mp->mode;
2814   s = format (0, "%U", format_lisp_map_request_mode, mode);
2815   vec_add1 (s, 0);
2816
2817   vat_json_init_object (&node);
2818   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2819   vat_json_print (vam->ofp, &node);
2820   vat_json_free (&node);
2821
2822   vec_free (s);
2823   vam->retval = ntohl (mp->retval);
2824   vam->result_ready = 1;
2825 }
2826
2827 static void
2828 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2829 {
2830   vat_main_t *vam = &vat_main;
2831   i32 retval = ntohl (mp->retval);
2832
2833   if (0 <= retval)
2834     {
2835       fformat (vam->ofp, "%-20s%-16s\n",
2836                mp->status ? "enabled" : "disabled",
2837                mp->status ? (char *) mp->locator_set_name : "");
2838     }
2839
2840   vam->retval = retval;
2841   vam->result_ready = 1;
2842 }
2843
2844 static void
2845 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2846                                             mp)
2847 {
2848   vat_main_t *vam = &vat_main;
2849   vat_json_node_t node;
2850   u8 *status = 0;
2851
2852   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2853   vec_add1 (status, 0);
2854
2855   vat_json_init_object (&node);
2856   vat_json_object_add_string_copy (&node, "status", status);
2857   if (mp->status)
2858     {
2859       vat_json_object_add_string_copy (&node, "locator_set",
2860                                        mp->locator_set_name);
2861     }
2862
2863   vec_free (status);
2864
2865   vat_json_print (vam->ofp, &node);
2866   vat_json_free (&node);
2867
2868   vam->retval = ntohl (mp->retval);
2869   vam->result_ready = 1;
2870 }
2871
2872 static u8 *
2873 format_policer_type (u8 * s, va_list * va)
2874 {
2875   u32 i = va_arg (*va, u32);
2876
2877   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2878     s = format (s, "1r2c");
2879   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2880     s = format (s, "1r3c");
2881   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2882     s = format (s, "2r3c-2698");
2883   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2884     s = format (s, "2r3c-4115");
2885   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2886     s = format (s, "2r3c-mef5cf1");
2887   else
2888     s = format (s, "ILLEGAL");
2889   return s;
2890 }
2891
2892 static u8 *
2893 format_policer_rate_type (u8 * s, va_list * va)
2894 {
2895   u32 i = va_arg (*va, u32);
2896
2897   if (i == SSE2_QOS_RATE_KBPS)
2898     s = format (s, "kbps");
2899   else if (i == SSE2_QOS_RATE_PPS)
2900     s = format (s, "pps");
2901   else
2902     s = format (s, "ILLEGAL");
2903   return s;
2904 }
2905
2906 static u8 *
2907 format_policer_round_type (u8 * s, va_list * va)
2908 {
2909   u32 i = va_arg (*va, u32);
2910
2911   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2912     s = format (s, "closest");
2913   else if (i == SSE2_QOS_ROUND_TO_UP)
2914     s = format (s, "up");
2915   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2916     s = format (s, "down");
2917   else
2918     s = format (s, "ILLEGAL");
2919   return s;
2920 }
2921
2922 static u8 *
2923 format_policer_action_type (u8 * s, va_list * va)
2924 {
2925   u32 i = va_arg (*va, u32);
2926
2927   if (i == SSE2_QOS_ACTION_DROP)
2928     s = format (s, "drop");
2929   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2930     s = format (s, "transmit");
2931   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2932     s = format (s, "mark-and-transmit");
2933   else
2934     s = format (s, "ILLEGAL");
2935   return s;
2936 }
2937
2938 static u8 *
2939 format_dscp (u8 * s, va_list * va)
2940 {
2941   u32 i = va_arg (*va, u32);
2942   char *t = 0;
2943
2944   switch (i)
2945     {
2946 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2947       foreach_vnet_dscp
2948 #undef _
2949     default:
2950       return format (s, "ILLEGAL");
2951     }
2952   s = format (s, "%s", t);
2953   return s;
2954 }
2955
2956 static void
2957 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2958 {
2959   vat_main_t *vam = &vat_main;
2960   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2961
2962   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2963     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2964   else
2965     conform_dscp_str = format (0, "");
2966
2967   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2968     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2969   else
2970     exceed_dscp_str = format (0, "");
2971
2972   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2973     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2974   else
2975     violate_dscp_str = format (0, "");
2976
2977   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2978            "rate type %U, round type %U, %s rate, %s color-aware, "
2979            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2980            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2981            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2982            mp->name,
2983            format_policer_type, mp->type,
2984            ntohl (mp->cir),
2985            ntohl (mp->eir),
2986            clib_net_to_host_u64 (mp->cb),
2987            clib_net_to_host_u64 (mp->eb),
2988            format_policer_rate_type, mp->rate_type,
2989            format_policer_round_type, mp->round_type,
2990            mp->single_rate ? "single" : "dual",
2991            mp->color_aware ? "is" : "not",
2992            ntohl (mp->cir_tokens_per_period),
2993            ntohl (mp->pir_tokens_per_period),
2994            ntohl (mp->scale),
2995            ntohl (mp->current_limit),
2996            ntohl (mp->current_bucket),
2997            ntohl (mp->extended_limit),
2998            ntohl (mp->extended_bucket),
2999            clib_net_to_host_u64 (mp->last_update_time),
3000            format_policer_action_type, mp->conform_action_type,
3001            conform_dscp_str,
3002            format_policer_action_type, mp->exceed_action_type,
3003            exceed_dscp_str,
3004            format_policer_action_type, mp->violate_action_type,
3005            violate_dscp_str);
3006
3007   vec_free (conform_dscp_str);
3008   vec_free (exceed_dscp_str);
3009   vec_free (violate_dscp_str);
3010 }
3011
3012 static void vl_api_policer_details_t_handler_json
3013   (vl_api_policer_details_t * mp)
3014 {
3015   vat_main_t *vam = &vat_main;
3016   vat_json_node_t *node;
3017   u8 *rate_type_str, *round_type_str, *type_str;
3018   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3019
3020   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3021   round_type_str =
3022     format (0, "%U", format_policer_round_type, mp->round_type);
3023   type_str = format (0, "%U", format_policer_type, mp->type);
3024   conform_action_str = format (0, "%U", format_policer_action_type,
3025                                mp->conform_action_type);
3026   exceed_action_str = format (0, "%U", format_policer_action_type,
3027                               mp->exceed_action_type);
3028   violate_action_str = format (0, "%U", format_policer_action_type,
3029                                mp->violate_action_type);
3030
3031   if (VAT_JSON_ARRAY != vam->json_tree.type)
3032     {
3033       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3034       vat_json_init_array (&vam->json_tree);
3035     }
3036   node = vat_json_array_add (&vam->json_tree);
3037
3038   vat_json_init_object (node);
3039   vat_json_object_add_string_copy (node, "name", mp->name);
3040   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3041   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3042   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3043   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3044   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3045   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3046   vat_json_object_add_string_copy (node, "type", type_str);
3047   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3048   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3049   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3050   vat_json_object_add_uint (node, "cir_tokens_per_period",
3051                             ntohl (mp->cir_tokens_per_period));
3052   vat_json_object_add_uint (node, "eir_tokens_per_period",
3053                             ntohl (mp->pir_tokens_per_period));
3054   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3055   vat_json_object_add_uint (node, "current_bucket",
3056                             ntohl (mp->current_bucket));
3057   vat_json_object_add_uint (node, "extended_limit",
3058                             ntohl (mp->extended_limit));
3059   vat_json_object_add_uint (node, "extended_bucket",
3060                             ntohl (mp->extended_bucket));
3061   vat_json_object_add_uint (node, "last_update_time",
3062                             ntohl (mp->last_update_time));
3063   vat_json_object_add_string_copy (node, "conform_action",
3064                                    conform_action_str);
3065   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3066     {
3067       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3068       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3069       vec_free (dscp_str);
3070     }
3071   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3072   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3073     {
3074       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3075       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3076       vec_free (dscp_str);
3077     }
3078   vat_json_object_add_string_copy (node, "violate_action",
3079                                    violate_action_str);
3080   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3081     {
3082       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3083       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3084       vec_free (dscp_str);
3085     }
3086
3087   vec_free (rate_type_str);
3088   vec_free (round_type_str);
3089   vec_free (type_str);
3090   vec_free (conform_action_str);
3091   vec_free (exceed_action_str);
3092   vec_free (violate_action_str);
3093 }
3094
3095 static void
3096 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3097                                            mp)
3098 {
3099   vat_main_t *vam = &vat_main;
3100   int i, count = ntohl (mp->count);
3101
3102   if (count > 0)
3103     fformat (vam->ofp, "classify table ids (%d) : ", count);
3104   for (i = 0; i < count; i++)
3105     {
3106       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3107       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3108     }
3109   vam->retval = ntohl (mp->retval);
3110   vam->result_ready = 1;
3111 }
3112
3113 static void
3114   vl_api_classify_table_ids_reply_t_handler_json
3115   (vl_api_classify_table_ids_reply_t * mp)
3116 {
3117   vat_main_t *vam = &vat_main;
3118   int i, count = ntohl (mp->count);
3119
3120   if (count > 0)
3121     {
3122       vat_json_node_t node;
3123
3124       vat_json_init_object (&node);
3125       for (i = 0; i < count; i++)
3126         {
3127           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3128         }
3129       vat_json_print (vam->ofp, &node);
3130       vat_json_free (&node);
3131     }
3132   vam->retval = ntohl (mp->retval);
3133   vam->result_ready = 1;
3134 }
3135
3136 static void
3137   vl_api_classify_table_by_interface_reply_t_handler
3138   (vl_api_classify_table_by_interface_reply_t * mp)
3139 {
3140   vat_main_t *vam = &vat_main;
3141   u32 table_id;
3142
3143   table_id = ntohl (mp->l2_table_id);
3144   if (table_id != ~0)
3145     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3146   else
3147     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3148   table_id = ntohl (mp->ip4_table_id);
3149   if (table_id != ~0)
3150     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3151   else
3152     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3153   table_id = ntohl (mp->ip6_table_id);
3154   if (table_id != ~0)
3155     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3156   else
3157     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3158   vam->retval = ntohl (mp->retval);
3159   vam->result_ready = 1;
3160 }
3161
3162 static void
3163   vl_api_classify_table_by_interface_reply_t_handler_json
3164   (vl_api_classify_table_by_interface_reply_t * mp)
3165 {
3166   vat_main_t *vam = &vat_main;
3167   vat_json_node_t node;
3168
3169   vat_json_init_object (&node);
3170
3171   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3172   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3173   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3174
3175   vat_json_print (vam->ofp, &node);
3176   vat_json_free (&node);
3177
3178   vam->retval = ntohl (mp->retval);
3179   vam->result_ready = 1;
3180 }
3181
3182 static void vl_api_policer_add_del_reply_t_handler
3183   (vl_api_policer_add_del_reply_t * mp)
3184 {
3185   vat_main_t *vam = &vat_main;
3186   i32 retval = ntohl (mp->retval);
3187   if (vam->async_mode)
3188     {
3189       vam->async_errors += (retval < 0);
3190     }
3191   else
3192     {
3193       vam->retval = retval;
3194       vam->result_ready = 1;
3195       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3196         /*
3197          * Note: this is just barely thread-safe, depends on
3198          * the main thread spinning waiting for an answer...
3199          */
3200         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3201     }
3202 }
3203
3204 static void vl_api_policer_add_del_reply_t_handler_json
3205   (vl_api_policer_add_del_reply_t * mp)
3206 {
3207   vat_main_t *vam = &vat_main;
3208   vat_json_node_t node;
3209
3210   vat_json_init_object (&node);
3211   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3212   vat_json_object_add_uint (&node, "policer_index",
3213                             ntohl (mp->policer_index));
3214
3215   vat_json_print (vam->ofp, &node);
3216   vat_json_free (&node);
3217
3218   vam->retval = ntohl (mp->retval);
3219   vam->result_ready = 1;
3220 }
3221
3222 /* Format hex dump. */
3223 u8 *
3224 format_hex_bytes (u8 * s, va_list * va)
3225 {
3226   u8 *bytes = va_arg (*va, u8 *);
3227   int n_bytes = va_arg (*va, int);
3228   uword i;
3229
3230   /* Print short or long form depending on byte count. */
3231   uword short_form = n_bytes <= 32;
3232   uword indent = format_get_indent (s);
3233
3234   if (n_bytes == 0)
3235     return s;
3236
3237   for (i = 0; i < n_bytes; i++)
3238     {
3239       if (!short_form && (i % 32) == 0)
3240         s = format (s, "%08x: ", i);
3241       s = format (s, "%02x", bytes[i]);
3242       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3243         s = format (s, "\n%U", format_white_space, indent);
3244     }
3245
3246   return s;
3247 }
3248
3249 static void
3250 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3251                                             * mp)
3252 {
3253   vat_main_t *vam = &vat_main;
3254   i32 retval = ntohl (mp->retval);
3255   if (retval == 0)
3256     {
3257       fformat (vam->ofp, "classify table info :\n");
3258       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3259                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3260                ntohl (mp->miss_next_index));
3261       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3262                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3263                ntohl (mp->match_n_vectors));
3264       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3265                ntohl (mp->mask_length));
3266     }
3267   vam->retval = retval;
3268   vam->result_ready = 1;
3269 }
3270
3271 static void
3272   vl_api_classify_table_info_reply_t_handler_json
3273   (vl_api_classify_table_info_reply_t * mp)
3274 {
3275   vat_main_t *vam = &vat_main;
3276   vat_json_node_t node;
3277
3278   i32 retval = ntohl (mp->retval);
3279   if (retval == 0)
3280     {
3281       vat_json_init_object (&node);
3282
3283       vat_json_object_add_int (&node, "sessions",
3284                                ntohl (mp->active_sessions));
3285       vat_json_object_add_int (&node, "nexttbl",
3286                                ntohl (mp->next_table_index));
3287       vat_json_object_add_int (&node, "nextnode",
3288                                ntohl (mp->miss_next_index));
3289       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3290       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3291       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3292       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3293                       ntohl (mp->mask_length), 0);
3294       vat_json_object_add_string_copy (&node, "mask", s);
3295
3296       vat_json_print (vam->ofp, &node);
3297       vat_json_free (&node);
3298     }
3299   vam->retval = ntohl (mp->retval);
3300   vam->result_ready = 1;
3301 }
3302
3303 static void
3304 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3305                                            mp)
3306 {
3307   vat_main_t *vam = &vat_main;
3308
3309   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3310            ntohl (mp->hit_next_index), ntohl (mp->advance),
3311            ntohl (mp->opaque_index));
3312   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3313            ntohl (mp->match_length));
3314 }
3315
3316 static void
3317   vl_api_classify_session_details_t_handler_json
3318   (vl_api_classify_session_details_t * mp)
3319 {
3320   vat_main_t *vam = &vat_main;
3321   vat_json_node_t *node = NULL;
3322
3323   if (VAT_JSON_ARRAY != vam->json_tree.type)
3324     {
3325       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3326       vat_json_init_array (&vam->json_tree);
3327     }
3328   node = vat_json_array_add (&vam->json_tree);
3329
3330   vat_json_init_object (node);
3331   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3332   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3333   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3334   u8 *s =
3335     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3336             0);
3337   vat_json_object_add_string_copy (node, "match", s);
3338 }
3339
3340 static void vl_api_pg_create_interface_reply_t_handler
3341   (vl_api_pg_create_interface_reply_t * mp)
3342 {
3343   vat_main_t *vam = &vat_main;
3344
3345   vam->retval = ntohl (mp->retval);
3346   vam->result_ready = 1;
3347 }
3348
3349 static void vl_api_pg_create_interface_reply_t_handler_json
3350   (vl_api_pg_create_interface_reply_t * mp)
3351 {
3352   vat_main_t *vam = &vat_main;
3353   vat_json_node_t node;
3354
3355   i32 retval = ntohl (mp->retval);
3356   if (retval == 0)
3357     {
3358       vat_json_init_object (&node);
3359
3360       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3361
3362       vat_json_print (vam->ofp, &node);
3363       vat_json_free (&node);
3364     }
3365   vam->retval = ntohl (mp->retval);
3366   vam->result_ready = 1;
3367 }
3368
3369 static void vl_api_policer_classify_details_t_handler
3370   (vl_api_policer_classify_details_t * mp)
3371 {
3372   vat_main_t *vam = &vat_main;
3373
3374   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3375            ntohl (mp->table_index));
3376 }
3377
3378 static void vl_api_policer_classify_details_t_handler_json
3379   (vl_api_policer_classify_details_t * mp)
3380 {
3381   vat_main_t *vam = &vat_main;
3382   vat_json_node_t *node;
3383
3384   if (VAT_JSON_ARRAY != vam->json_tree.type)
3385     {
3386       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3387       vat_json_init_array (&vam->json_tree);
3388     }
3389   node = vat_json_array_add (&vam->json_tree);
3390
3391   vat_json_init_object (node);
3392   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3393   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3394 }
3395
3396 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3397   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3398 {
3399   vat_main_t *vam = &vat_main;
3400   i32 retval = ntohl (mp->retval);
3401   if (vam->async_mode)
3402     {
3403       vam->async_errors += (retval < 0);
3404     }
3405   else
3406     {
3407       vam->retval = retval;
3408       vam->sw_if_index = ntohl (mp->sw_if_index);
3409       vam->result_ready = 1;
3410     }
3411 }
3412
3413 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3414   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3415 {
3416   vat_main_t *vam = &vat_main;
3417   vat_json_node_t node;
3418
3419   vat_json_init_object (&node);
3420   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3421   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3422
3423   vat_json_print (vam->ofp, &node);
3424   vat_json_free (&node);
3425
3426   vam->retval = ntohl (mp->retval);
3427   vam->result_ready = 1;
3428 }
3429
3430 static void vl_api_flow_classify_details_t_handler
3431   (vl_api_flow_classify_details_t * mp)
3432 {
3433   vat_main_t *vam = &vat_main;
3434
3435   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3436            ntohl (mp->table_index));
3437 }
3438
3439 static void vl_api_flow_classify_details_t_handler_json
3440   (vl_api_flow_classify_details_t * mp)
3441 {
3442   vat_main_t *vam = &vat_main;
3443   vat_json_node_t *node;
3444
3445   if (VAT_JSON_ARRAY != vam->json_tree.type)
3446     {
3447       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3448       vat_json_init_array (&vam->json_tree);
3449     }
3450   node = vat_json_array_add (&vam->json_tree);
3451
3452   vat_json_init_object (node);
3453   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3454   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3455 }
3456
3457
3458
3459 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3460 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3461 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3462 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3463 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3464 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3465
3466 /*
3467  * Generate boilerplate reply handlers, which
3468  * dig the return value out of the xxx_reply_t API message,
3469  * stick it into vam->retval, and set vam->result_ready
3470  *
3471  * Could also do this by pointing N message decode slots at
3472  * a single function, but that could break in subtle ways.
3473  */
3474
3475 #define foreach_standard_reply_retval_handler           \
3476 _(sw_interface_set_flags_reply)                         \
3477 _(sw_interface_add_del_address_reply)                   \
3478 _(sw_interface_set_table_reply)                         \
3479 _(sw_interface_set_mpls_enable_reply)                   \
3480 _(sw_interface_set_vpath_reply)                         \
3481 _(sw_interface_set_l2_bridge_reply)                     \
3482 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3483 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3484 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3485 _(bridge_domain_add_del_reply)                          \
3486 _(sw_interface_set_l2_xconnect_reply)                   \
3487 _(l2fib_add_del_reply)                                  \
3488 _(ip_add_del_route_reply)                               \
3489 _(mpls_route_add_del_reply)                             \
3490 _(mpls_ip_bind_unbind_reply)                            \
3491 _(proxy_arp_add_del_reply)                              \
3492 _(proxy_arp_intfc_enable_disable_reply)                 \
3493 _(mpls_add_del_encap_reply)                             \
3494 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3495 _(sw_interface_set_unnumbered_reply)                    \
3496 _(ip_neighbor_add_del_reply)                            \
3497 _(reset_vrf_reply)                                      \
3498 _(oam_add_del_reply)                                    \
3499 _(reset_fib_reply)                                      \
3500 _(dhcp_proxy_config_reply)                              \
3501 _(dhcp_proxy_config_2_reply)                            \
3502 _(dhcp_proxy_set_vss_reply)                             \
3503 _(dhcp_client_config_reply)                             \
3504 _(set_ip_flow_hash_reply)                               \
3505 _(sw_interface_ip6_enable_disable_reply)                \
3506 _(sw_interface_ip6_set_link_local_address_reply)        \
3507 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3508 _(sw_interface_ip6nd_ra_config_reply)                   \
3509 _(set_arp_neighbor_limit_reply)                         \
3510 _(l2_patch_add_del_reply)                               \
3511 _(sr_tunnel_add_del_reply)                              \
3512 _(sr_policy_add_del_reply)                              \
3513 _(sr_multicast_map_add_del_reply)                       \
3514 _(classify_add_del_session_reply)                       \
3515 _(classify_set_interface_ip_table_reply)                \
3516 _(classify_set_interface_l2_tables_reply)               \
3517 _(l2tpv3_set_tunnel_cookies_reply)                      \
3518 _(l2tpv3_interface_enable_disable_reply)                \
3519 _(l2tpv3_set_lookup_key_reply)                          \
3520 _(l2_fib_clear_table_reply)                             \
3521 _(l2_interface_efp_filter_reply)                        \
3522 _(l2_interface_vlan_tag_rewrite_reply)                  \
3523 _(modify_vhost_user_if_reply)                           \
3524 _(delete_vhost_user_if_reply)                           \
3525 _(want_ip4_arp_events_reply)                            \
3526 _(want_ip6_nd_events_reply)                             \
3527 _(input_acl_set_interface_reply)                        \
3528 _(ipsec_spd_add_del_reply)                              \
3529 _(ipsec_interface_add_del_spd_reply)                    \
3530 _(ipsec_spd_add_del_entry_reply)                        \
3531 _(ipsec_sad_add_del_entry_reply)                        \
3532 _(ipsec_sa_set_key_reply)                               \
3533 _(ikev2_profile_add_del_reply)                          \
3534 _(ikev2_profile_set_auth_reply)                         \
3535 _(ikev2_profile_set_id_reply)                           \
3536 _(ikev2_profile_set_ts_reply)                           \
3537 _(ikev2_set_local_key_reply)                            \
3538 _(delete_loopback_reply)                                \
3539 _(bd_ip_mac_add_del_reply)                              \
3540 _(map_del_domain_reply)                                 \
3541 _(map_add_del_rule_reply)                               \
3542 _(want_interface_events_reply)                          \
3543 _(want_stats_reply)                                     \
3544 _(cop_interface_enable_disable_reply)                   \
3545 _(cop_whitelist_enable_disable_reply)                   \
3546 _(sw_interface_clear_stats_reply)                       \
3547 _(ioam_enable_reply)                              \
3548 _(ioam_disable_reply)                              \
3549 _(lisp_add_del_locator_reply)                           \
3550 _(lisp_add_del_local_eid_reply)                         \
3551 _(lisp_add_del_remote_mapping_reply)                    \
3552 _(lisp_add_del_adjacency_reply)                         \
3553 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3554 _(lisp_add_del_map_resolver_reply)                      \
3555 _(lisp_gpe_enable_disable_reply)                        \
3556 _(lisp_gpe_add_del_iface_reply)                         \
3557 _(lisp_enable_disable_reply)                            \
3558 _(lisp_pitr_set_locator_set_reply)                      \
3559 _(lisp_map_request_mode_reply)                          \
3560 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3561 _(lisp_eid_table_add_del_map_reply)                     \
3562 _(vxlan_gpe_add_del_tunnel_reply)                       \
3563 _(af_packet_delete_reply)                               \
3564 _(policer_classify_set_interface_reply)                 \
3565 _(netmap_create_reply)                                  \
3566 _(netmap_delete_reply)                                  \
3567 _(set_ipfix_exporter_reply)                             \
3568 _(set_ipfix_classify_stream_reply)                      \
3569 _(ipfix_classify_table_add_del_reply)                   \
3570 _(flow_classify_set_interface_reply)                    \
3571 _(sw_interface_span_enable_disable_reply)               \
3572 _(pg_capture_reply)                                     \
3573 _(pg_enable_disable_reply)                              \
3574 _(ip_source_and_port_range_check_add_del_reply)         \
3575 _(ip_source_and_port_range_check_interface_add_del_reply)\
3576 _(delete_subif_reply)                                   \
3577 _(l2_interface_pbb_tag_rewrite_reply)                   \
3578 _(punt_reply)
3579
3580 #define _(n)                                    \
3581     static void vl_api_##n##_t_handler          \
3582     (vl_api_##n##_t * mp)                       \
3583     {                                           \
3584         vat_main_t * vam = &vat_main;           \
3585         i32 retval = ntohl(mp->retval);         \
3586         if (vam->async_mode) {                  \
3587             vam->async_errors += (retval < 0);  \
3588         } else {                                \
3589             vam->retval = retval;               \
3590             vam->result_ready = 1;              \
3591         }                                       \
3592     }
3593 foreach_standard_reply_retval_handler;
3594 #undef _
3595
3596 #define _(n)                                    \
3597     static void vl_api_##n##_t_handler_json     \
3598     (vl_api_##n##_t * mp)                       \
3599     {                                           \
3600         vat_main_t * vam = &vat_main;           \
3601         vat_json_node_t node;                   \
3602         vat_json_init_object(&node);            \
3603         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3604         vat_json_print(vam->ofp, &node);        \
3605         vam->retval = ntohl(mp->retval);        \
3606         vam->result_ready = 1;                  \
3607     }
3608 foreach_standard_reply_retval_handler;
3609 #undef _
3610
3611 /*
3612  * Table of message reply handlers, must include boilerplate handlers
3613  * we just generated
3614  */
3615
3616 #define foreach_vpe_api_reply_msg                                       \
3617 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3618 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3619 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3620 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3621 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3622 _(CLI_REPLY, cli_reply)                                                 \
3623 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3624 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3625   sw_interface_add_del_address_reply)                                   \
3626 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3627 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3628 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3629 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3630   sw_interface_set_l2_xconnect_reply)                                   \
3631 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3632   sw_interface_set_l2_bridge_reply)                                     \
3633 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3634   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3635 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3636   sw_interface_set_dpdk_hqos_subport_reply)                             \
3637 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3638   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3639 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3640 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3641 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3642 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3643 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3644 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3645 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3646 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3647 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3648 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3649 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3650 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3651 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3652 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3653 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3654   proxy_arp_intfc_enable_disable_reply)                                 \
3655 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3656 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3657   mpls_ethernet_add_del_tunnel_reply)                                   \
3658 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3659   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3660 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3661   sw_interface_set_unnumbered_reply)                                    \
3662 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3663 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3664 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3665 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3666 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3667 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3668 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3669 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3670 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3671 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3672 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3673 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3674   sw_interface_ip6_enable_disable_reply)                                \
3675 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3676   sw_interface_ip6_set_link_local_address_reply)                        \
3677 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3678   sw_interface_ip6nd_ra_prefix_reply)                                   \
3679 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3680   sw_interface_ip6nd_ra_config_reply)                                   \
3681 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3682 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3683 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3684 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3685 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3686 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3687 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3688 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3689 classify_set_interface_ip_table_reply)                                  \
3690 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3691   classify_set_interface_l2_tables_reply)                               \
3692 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3693 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3694 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3695 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3696 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3697   l2tpv3_interface_enable_disable_reply)                                \
3698 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3699 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3700 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3701 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3702 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3703 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3704 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3705 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3706 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3707 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3708 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3709 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3710 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3711 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3712 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3713 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3714 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3715 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3716 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3717 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3718 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3719 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3720 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3721 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3722 _(IP_DETAILS, ip_details)                                               \
3723 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3724 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3725 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3726 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3727 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3728 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3729 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3730 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3731 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3732 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3733 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3734 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3735 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3736 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3737 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3738 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3739 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3740 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3741 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3742 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3743 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3744 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3745 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3746 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3747 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3748 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3749 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3750 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3751 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3752 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3753 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3754 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3755 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3756 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3757 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3758 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3759 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3760 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3761 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3762 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3763 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3764 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3765 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3766 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3767 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3768 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3769 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3770 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3771 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3772 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3773 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3774 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3775 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3776   lisp_add_del_map_request_itr_rlocs_reply)                             \
3777 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3778   lisp_get_map_request_itr_rlocs_reply)                                 \
3779 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3780 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3781 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3782 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3783 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3784 _(POLICER_DETAILS, policer_details)                                     \
3785 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3786 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3787 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3788 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3789 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3790 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3791 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3792 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3793 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3794 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3795 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3796 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3797 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3798 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3799 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3800 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3801 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3802 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3803 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3804 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3805 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3806 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3807 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3808 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3809 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3810 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3811  ip_source_and_port_range_check_add_del_reply)                          \
3812 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3813  ip_source_and_port_range_check_interface_add_del_reply)                \
3814 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3815 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3816 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3817 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3818 _(PUNT_REPLY, punt_reply)                                               \
3819 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3820 _(IP6_FIB_DETAILS, ip6_fib_details)
3821
3822 /* M: construct, but don't yet send a message */
3823
3824 #define M(T,t)                                  \
3825 do {                                            \
3826     vam->result_ready = 0;                      \
3827     mp = vl_msg_api_alloc(sizeof(*mp));         \
3828     memset (mp, 0, sizeof (*mp));               \
3829     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3830     mp->client_index = vam->my_client_index;    \
3831 } while(0);
3832
3833 #define M2(T,t,n)                               \
3834 do {                                            \
3835     vam->result_ready = 0;                      \
3836     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3837     memset (mp, 0, sizeof (*mp));               \
3838     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3839     mp->client_index = vam->my_client_index;    \
3840 } while(0);
3841
3842
3843 /* S: send a message */
3844 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3845
3846 /* W: wait for results, with timeout */
3847 #define W                                       \
3848 do {                                            \
3849     timeout = vat_time_now (vam) + 1.0;         \
3850                                                 \
3851     while (vat_time_now (vam) < timeout) {      \
3852         if (vam->result_ready == 1) {           \
3853             return (vam->retval);               \
3854         }                                       \
3855     }                                           \
3856     return -99;                                 \
3857 } while(0);
3858
3859 /* W2: wait for results, with timeout */
3860 #define W2(body)                                \
3861 do {                                            \
3862     timeout = vat_time_now (vam) + 1.0;         \
3863                                                 \
3864     while (vat_time_now (vam) < timeout) {      \
3865         if (vam->result_ready == 1) {           \
3866           (body);                               \
3867           return (vam->retval);                 \
3868         }                                       \
3869     }                                           \
3870     return -99;                                 \
3871 } while(0);
3872
3873 typedef struct
3874 {
3875   u8 *name;
3876   u32 value;
3877 } name_sort_t;
3878
3879
3880 #define STR_VTR_OP_CASE(op)     \
3881     case L2_VTR_ ## op:         \
3882         return "" # op;
3883
3884 static const char *
3885 str_vtr_op (u32 vtr_op)
3886 {
3887   switch (vtr_op)
3888     {
3889       STR_VTR_OP_CASE (DISABLED);
3890       STR_VTR_OP_CASE (PUSH_1);
3891       STR_VTR_OP_CASE (PUSH_2);
3892       STR_VTR_OP_CASE (POP_1);
3893       STR_VTR_OP_CASE (POP_2);
3894       STR_VTR_OP_CASE (TRANSLATE_1_1);
3895       STR_VTR_OP_CASE (TRANSLATE_1_2);
3896       STR_VTR_OP_CASE (TRANSLATE_2_1);
3897       STR_VTR_OP_CASE (TRANSLATE_2_2);
3898     }
3899
3900   return "UNKNOWN";
3901 }
3902
3903 static int
3904 dump_sub_interface_table (vat_main_t * vam)
3905 {
3906   const sw_interface_subif_t *sub = NULL;
3907
3908   if (vam->json_output)
3909     {
3910       clib_warning
3911         ("JSON output supported only for VPE API calls and dump_stats_table");
3912       return -99;
3913     }
3914
3915   fformat (vam->ofp,
3916            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3917            "Interface", "sw_if_index",
3918            "sub id", "dot1ad", "tags", "outer id",
3919            "inner id", "exact", "default", "outer any", "inner any");
3920
3921   vec_foreach (sub, vam->sw_if_subif_table)
3922   {
3923     fformat (vam->ofp,
3924              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3925              sub->interface_name,
3926              sub->sw_if_index,
3927              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3928              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3929              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3930              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3931     if (sub->vtr_op != L2_VTR_DISABLED)
3932       {
3933         fformat (vam->ofp,
3934                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3935                  "tag1: %d tag2: %d ]\n",
3936                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3937                  sub->vtr_tag1, sub->vtr_tag2);
3938       }
3939   }
3940
3941   return 0;
3942 }
3943
3944 static int
3945 name_sort_cmp (void *a1, void *a2)
3946 {
3947   name_sort_t *n1 = a1;
3948   name_sort_t *n2 = a2;
3949
3950   return strcmp ((char *) n1->name, (char *) n2->name);
3951 }
3952
3953 static int
3954 dump_interface_table (vat_main_t * vam)
3955 {
3956   hash_pair_t *p;
3957   name_sort_t *nses = 0, *ns;
3958
3959   if (vam->json_output)
3960     {
3961       clib_warning
3962         ("JSON output supported only for VPE API calls and dump_stats_table");
3963       return -99;
3964     }
3965
3966   /* *INDENT-OFF* */
3967   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3968   ({
3969     vec_add2 (nses, ns, 1);
3970     ns->name = (u8 *)(p->key);
3971     ns->value = (u32) p->value[0];
3972   }));
3973   /* *INDENT-ON* */
3974
3975   vec_sort_with_function (nses, name_sort_cmp);
3976
3977   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3978   vec_foreach (ns, nses)
3979   {
3980     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3981   }
3982   vec_free (nses);
3983   return 0;
3984 }
3985
3986 static int
3987 dump_ip_table (vat_main_t * vam, int is_ipv6)
3988 {
3989   const ip_details_t *det = NULL;
3990   const ip_address_details_t *address = NULL;
3991   u32 i = ~0;
3992
3993   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3994
3995   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3996   {
3997     i++;
3998     if (!det->present)
3999       {
4000         continue;
4001       }
4002     fformat (vam->ofp, "%-12d\n", i);
4003     fformat (vam->ofp,
4004              "            %-30s%-13s\n", "Address", "Prefix length");
4005     if (!det->addr)
4006       {
4007         continue;
4008       }
4009     vec_foreach (address, det->addr)
4010     {
4011       fformat (vam->ofp,
4012                "            %-30U%-13d\n",
4013                is_ipv6 ? format_ip6_address : format_ip4_address,
4014                address->ip, address->prefix_length);
4015     }
4016   }
4017
4018   return 0;
4019 }
4020
4021 static int
4022 dump_ipv4_table (vat_main_t * vam)
4023 {
4024   if (vam->json_output)
4025     {
4026       clib_warning
4027         ("JSON output supported only for VPE API calls and dump_stats_table");
4028       return -99;
4029     }
4030
4031   return dump_ip_table (vam, 0);
4032 }
4033
4034 static int
4035 dump_ipv6_table (vat_main_t * vam)
4036 {
4037   if (vam->json_output)
4038     {
4039       clib_warning
4040         ("JSON output supported only for VPE API calls and dump_stats_table");
4041       return -99;
4042     }
4043
4044   return dump_ip_table (vam, 1);
4045 }
4046
4047 static char *
4048 counter_type_to_str (u8 counter_type, u8 is_combined)
4049 {
4050   if (!is_combined)
4051     {
4052       switch (counter_type)
4053         {
4054         case VNET_INTERFACE_COUNTER_DROP:
4055           return "drop";
4056         case VNET_INTERFACE_COUNTER_PUNT:
4057           return "punt";
4058         case VNET_INTERFACE_COUNTER_IP4:
4059           return "ip4";
4060         case VNET_INTERFACE_COUNTER_IP6:
4061           return "ip6";
4062         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4063           return "rx-no-buf";
4064         case VNET_INTERFACE_COUNTER_RX_MISS:
4065           return "rx-miss";
4066         case VNET_INTERFACE_COUNTER_RX_ERROR:
4067           return "rx-error";
4068         case VNET_INTERFACE_COUNTER_TX_ERROR:
4069           return "tx-error";
4070         default:
4071           return "INVALID-COUNTER-TYPE";
4072         }
4073     }
4074   else
4075     {
4076       switch (counter_type)
4077         {
4078         case VNET_INTERFACE_COUNTER_RX:
4079           return "rx";
4080         case VNET_INTERFACE_COUNTER_TX:
4081           return "tx";
4082         default:
4083           return "INVALID-COUNTER-TYPE";
4084         }
4085     }
4086 }
4087
4088 static int
4089 dump_stats_table (vat_main_t * vam)
4090 {
4091   vat_json_node_t node;
4092   vat_json_node_t *msg_array;
4093   vat_json_node_t *msg;
4094   vat_json_node_t *counter_array;
4095   vat_json_node_t *counter;
4096   interface_counter_t c;
4097   u64 packets;
4098   ip4_fib_counter_t *c4;
4099   ip6_fib_counter_t *c6;
4100   int i, j;
4101
4102   if (!vam->json_output)
4103     {
4104       clib_warning ("dump_stats_table supported only in JSON format");
4105       return -99;
4106     }
4107
4108   vat_json_init_object (&node);
4109
4110   /* interface counters */
4111   msg_array = vat_json_object_add (&node, "interface_counters");
4112   vat_json_init_array (msg_array);
4113   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4114     {
4115       msg = vat_json_array_add (msg_array);
4116       vat_json_init_object (msg);
4117       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4118                                        (u8 *) counter_type_to_str (i, 0));
4119       vat_json_object_add_int (msg, "is_combined", 0);
4120       counter_array = vat_json_object_add (msg, "data");
4121       vat_json_init_array (counter_array);
4122       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4123         {
4124           packets = vam->simple_interface_counters[i][j];
4125           vat_json_array_add_uint (counter_array, packets);
4126         }
4127     }
4128   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4129     {
4130       msg = vat_json_array_add (msg_array);
4131       vat_json_init_object (msg);
4132       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4133                                        (u8 *) counter_type_to_str (i, 1));
4134       vat_json_object_add_int (msg, "is_combined", 1);
4135       counter_array = vat_json_object_add (msg, "data");
4136       vat_json_init_array (counter_array);
4137       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4138         {
4139           c = vam->combined_interface_counters[i][j];
4140           counter = vat_json_array_add (counter_array);
4141           vat_json_init_object (counter);
4142           vat_json_object_add_uint (counter, "packets", c.packets);
4143           vat_json_object_add_uint (counter, "bytes", c.bytes);
4144         }
4145     }
4146
4147   /* ip4 fib counters */
4148   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4149   vat_json_init_array (msg_array);
4150   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4151     {
4152       msg = vat_json_array_add (msg_array);
4153       vat_json_init_object (msg);
4154       vat_json_object_add_uint (msg, "vrf_id",
4155                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4156       counter_array = vat_json_object_add (msg, "c");
4157       vat_json_init_array (counter_array);
4158       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4159         {
4160           counter = vat_json_array_add (counter_array);
4161           vat_json_init_object (counter);
4162           c4 = &vam->ip4_fib_counters[i][j];
4163           vat_json_object_add_ip4 (counter, "address", c4->address);
4164           vat_json_object_add_uint (counter, "address_length",
4165                                     c4->address_length);
4166           vat_json_object_add_uint (counter, "packets", c4->packets);
4167           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4168         }
4169     }
4170
4171   /* ip6 fib counters */
4172   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4173   vat_json_init_array (msg_array);
4174   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4175     {
4176       msg = vat_json_array_add (msg_array);
4177       vat_json_init_object (msg);
4178       vat_json_object_add_uint (msg, "vrf_id",
4179                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4180       counter_array = vat_json_object_add (msg, "c");
4181       vat_json_init_array (counter_array);
4182       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4183         {
4184           counter = vat_json_array_add (counter_array);
4185           vat_json_init_object (counter);
4186           c6 = &vam->ip6_fib_counters[i][j];
4187           vat_json_object_add_ip6 (counter, "address", c6->address);
4188           vat_json_object_add_uint (counter, "address_length",
4189                                     c6->address_length);
4190           vat_json_object_add_uint (counter, "packets", c6->packets);
4191           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4192         }
4193     }
4194
4195   vat_json_print (vam->ofp, &node);
4196   vat_json_free (&node);
4197
4198   return 0;
4199 }
4200
4201 int
4202 exec (vat_main_t * vam)
4203 {
4204   api_main_t *am = &api_main;
4205   vl_api_cli_request_t *mp;
4206   f64 timeout;
4207   void *oldheap;
4208   u8 *cmd = 0;
4209   unformat_input_t *i = vam->input;
4210
4211   if (vec_len (i->buffer) == 0)
4212     return -1;
4213
4214   if (vam->exec_mode == 0 && unformat (i, "mode"))
4215     {
4216       vam->exec_mode = 1;
4217       return 0;
4218     }
4219   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4220     {
4221       vam->exec_mode = 0;
4222       return 0;
4223     }
4224
4225
4226   M (CLI_REQUEST, cli_request);
4227
4228   /*
4229    * Copy cmd into shared memory.
4230    * In order for the CLI command to work, it
4231    * must be a vector ending in \n, not a C-string ending
4232    * in \n\0.
4233    */
4234   pthread_mutex_lock (&am->vlib_rp->mutex);
4235   oldheap = svm_push_data_heap (am->vlib_rp);
4236
4237   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4238   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4239
4240   svm_pop_heap (oldheap);
4241   pthread_mutex_unlock (&am->vlib_rp->mutex);
4242
4243   mp->cmd_in_shmem = (u64) cmd;
4244   S;
4245   timeout = vat_time_now (vam) + 10.0;
4246
4247   while (vat_time_now (vam) < timeout)
4248     {
4249       if (vam->result_ready == 1)
4250         {
4251           u8 *free_me;
4252           if (vam->shmem_result != NULL)
4253             fformat (vam->ofp, "%s", vam->shmem_result);
4254           pthread_mutex_lock (&am->vlib_rp->mutex);
4255           oldheap = svm_push_data_heap (am->vlib_rp);
4256
4257           free_me = (u8 *) vam->shmem_result;
4258           vec_free (free_me);
4259
4260           svm_pop_heap (oldheap);
4261           pthread_mutex_unlock (&am->vlib_rp->mutex);
4262           return 0;
4263         }
4264     }
4265   return -99;
4266 }
4267
4268 /*
4269  * Future replacement of exec() that passes CLI buffers directly in
4270  * the API messages instead of an additional shared memory area.
4271  */
4272 static int
4273 exec_inband (vat_main_t * vam)
4274 {
4275   vl_api_cli_inband_t *mp;
4276   f64 timeout;
4277   unformat_input_t *i = vam->input;
4278
4279   if (vec_len (i->buffer) == 0)
4280     return -1;
4281
4282   if (vam->exec_mode == 0 && unformat (i, "mode"))
4283     {
4284       vam->exec_mode = 1;
4285       return 0;
4286     }
4287   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4288     {
4289       vam->exec_mode = 0;
4290       return 0;
4291     }
4292
4293   /*
4294    * In order for the CLI command to work, it
4295    * must be a vector ending in \n, not a C-string ending
4296    * in \n\0.
4297    */
4298   u32 len = vec_len (vam->input->buffer);
4299   M2 (CLI_INBAND, cli_inband, len);
4300   clib_memcpy (mp->cmd, vam->input->buffer, len);
4301   mp->length = htonl (len);
4302
4303   S;
4304   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4305 }
4306
4307 static int
4308 api_create_loopback (vat_main_t * vam)
4309 {
4310   unformat_input_t *i = vam->input;
4311   vl_api_create_loopback_t *mp;
4312   f64 timeout;
4313   u8 mac_address[6];
4314   u8 mac_set = 0;
4315
4316   memset (mac_address, 0, sizeof (mac_address));
4317
4318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4319     {
4320       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4321         mac_set = 1;
4322       else
4323         break;
4324     }
4325
4326   /* Construct the API message */
4327   M (CREATE_LOOPBACK, create_loopback);
4328   if (mac_set)
4329     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4330
4331   S;
4332   W;
4333 }
4334
4335 static int
4336 api_delete_loopback (vat_main_t * vam)
4337 {
4338   unformat_input_t *i = vam->input;
4339   vl_api_delete_loopback_t *mp;
4340   f64 timeout;
4341   u32 sw_if_index = ~0;
4342
4343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4344     {
4345       if (unformat (i, "sw_if_index %d", &sw_if_index))
4346         ;
4347       else
4348         break;
4349     }
4350
4351   if (sw_if_index == ~0)
4352     {
4353       errmsg ("missing sw_if_index\n");
4354       return -99;
4355     }
4356
4357   /* Construct the API message */
4358   M (DELETE_LOOPBACK, delete_loopback);
4359   mp->sw_if_index = ntohl (sw_if_index);
4360
4361   S;
4362   W;
4363 }
4364
4365 static int
4366 api_want_stats (vat_main_t * vam)
4367 {
4368   unformat_input_t *i = vam->input;
4369   vl_api_want_stats_t *mp;
4370   f64 timeout;
4371   int enable = -1;
4372
4373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4374     {
4375       if (unformat (i, "enable"))
4376         enable = 1;
4377       else if (unformat (i, "disable"))
4378         enable = 0;
4379       else
4380         break;
4381     }
4382
4383   if (enable == -1)
4384     {
4385       errmsg ("missing enable|disable\n");
4386       return -99;
4387     }
4388
4389   M (WANT_STATS, want_stats);
4390   mp->enable_disable = enable;
4391
4392   S;
4393   W;
4394 }
4395
4396 static int
4397 api_want_interface_events (vat_main_t * vam)
4398 {
4399   unformat_input_t *i = vam->input;
4400   vl_api_want_interface_events_t *mp;
4401   f64 timeout;
4402   int enable = -1;
4403
4404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4405     {
4406       if (unformat (i, "enable"))
4407         enable = 1;
4408       else if (unformat (i, "disable"))
4409         enable = 0;
4410       else
4411         break;
4412     }
4413
4414   if (enable == -1)
4415     {
4416       errmsg ("missing enable|disable\n");
4417       return -99;
4418     }
4419
4420   M (WANT_INTERFACE_EVENTS, want_interface_events);
4421   mp->enable_disable = enable;
4422
4423   vam->interface_event_display = enable;
4424
4425   S;
4426   W;
4427 }
4428
4429
4430 /* Note: non-static, called once to set up the initial intfc table */
4431 int
4432 api_sw_interface_dump (vat_main_t * vam)
4433 {
4434   vl_api_sw_interface_dump_t *mp;
4435   f64 timeout;
4436   hash_pair_t *p;
4437   name_sort_t *nses = 0, *ns;
4438   sw_interface_subif_t *sub = NULL;
4439
4440   /* Toss the old name table */
4441   /* *INDENT-OFF* */
4442   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4443   ({
4444     vec_add2 (nses, ns, 1);
4445     ns->name = (u8 *)(p->key);
4446     ns->value = (u32) p->value[0];
4447   }));
4448   /* *INDENT-ON* */
4449
4450   hash_free (vam->sw_if_index_by_interface_name);
4451
4452   vec_foreach (ns, nses) vec_free (ns->name);
4453
4454   vec_free (nses);
4455
4456   vec_foreach (sub, vam->sw_if_subif_table)
4457   {
4458     vec_free (sub->interface_name);
4459   }
4460   vec_free (vam->sw_if_subif_table);
4461
4462   /* recreate the interface name hash table */
4463   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4464
4465   /* Get list of ethernets */
4466   M (SW_INTERFACE_DUMP, sw_interface_dump);
4467   mp->name_filter_valid = 1;
4468   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4469   S;
4470
4471   /* and local / loopback interfaces */
4472   M (SW_INTERFACE_DUMP, sw_interface_dump);
4473   mp->name_filter_valid = 1;
4474   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4475   S;
4476
4477   /* and packet-generator interfaces */
4478   M (SW_INTERFACE_DUMP, sw_interface_dump);
4479   mp->name_filter_valid = 1;
4480   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4481   S;
4482
4483   /* and vxlan-gpe tunnel interfaces */
4484   M (SW_INTERFACE_DUMP, sw_interface_dump);
4485   mp->name_filter_valid = 1;
4486   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4487            sizeof (mp->name_filter) - 1);
4488   S;
4489
4490   /* and vxlan tunnel interfaces */
4491   M (SW_INTERFACE_DUMP, sw_interface_dump);
4492   mp->name_filter_valid = 1;
4493   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4494   S;
4495
4496   /* and host (af_packet) interfaces */
4497   M (SW_INTERFACE_DUMP, sw_interface_dump);
4498   mp->name_filter_valid = 1;
4499   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4500   S;
4501
4502   /* and l2tpv3 tunnel interfaces */
4503   M (SW_INTERFACE_DUMP, sw_interface_dump);
4504   mp->name_filter_valid = 1;
4505   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4506            sizeof (mp->name_filter) - 1);
4507   S;
4508
4509   /* and GRE tunnel interfaces */
4510   M (SW_INTERFACE_DUMP, sw_interface_dump);
4511   mp->name_filter_valid = 1;
4512   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4513   S;
4514
4515   /* and LISP-GPE interfaces */
4516   M (SW_INTERFACE_DUMP, sw_interface_dump);
4517   mp->name_filter_valid = 1;
4518   strncpy ((char *) mp->name_filter, "lisp_gpe",
4519            sizeof (mp->name_filter) - 1);
4520   S;
4521
4522   /* and IPSEC tunnel interfaces */
4523   M (SW_INTERFACE_DUMP, sw_interface_dump);
4524   mp->name_filter_valid = 1;
4525   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4526   S;
4527
4528   /* Use a control ping for synchronization */
4529   {
4530     vl_api_control_ping_t *mp;
4531     M (CONTROL_PING, control_ping);
4532     S;
4533   }
4534   W;
4535 }
4536
4537 static int
4538 api_sw_interface_set_flags (vat_main_t * vam)
4539 {
4540   unformat_input_t *i = vam->input;
4541   vl_api_sw_interface_set_flags_t *mp;
4542   f64 timeout;
4543   u32 sw_if_index;
4544   u8 sw_if_index_set = 0;
4545   u8 admin_up = 0, link_up = 0;
4546
4547   /* Parse args required to build the message */
4548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4549     {
4550       if (unformat (i, "admin-up"))
4551         admin_up = 1;
4552       else if (unformat (i, "admin-down"))
4553         admin_up = 0;
4554       else if (unformat (i, "link-up"))
4555         link_up = 1;
4556       else if (unformat (i, "link-down"))
4557         link_up = 0;
4558       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4559         sw_if_index_set = 1;
4560       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4561         sw_if_index_set = 1;
4562       else
4563         break;
4564     }
4565
4566   if (sw_if_index_set == 0)
4567     {
4568       errmsg ("missing interface name or sw_if_index\n");
4569       return -99;
4570     }
4571
4572   /* Construct the API message */
4573   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4574   mp->sw_if_index = ntohl (sw_if_index);
4575   mp->admin_up_down = admin_up;
4576   mp->link_up_down = link_up;
4577
4578   /* send it... */
4579   S;
4580
4581   /* Wait for a reply, return the good/bad news... */
4582   W;
4583 }
4584
4585 static int
4586 api_sw_interface_clear_stats (vat_main_t * vam)
4587 {
4588   unformat_input_t *i = vam->input;
4589   vl_api_sw_interface_clear_stats_t *mp;
4590   f64 timeout;
4591   u32 sw_if_index;
4592   u8 sw_if_index_set = 0;
4593
4594   /* Parse args required to build the message */
4595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4596     {
4597       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4598         sw_if_index_set = 1;
4599       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4600         sw_if_index_set = 1;
4601       else
4602         break;
4603     }
4604
4605   /* Construct the API message */
4606   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4607
4608   if (sw_if_index_set == 1)
4609     mp->sw_if_index = ntohl (sw_if_index);
4610   else
4611     mp->sw_if_index = ~0;
4612
4613   /* send it... */
4614   S;
4615
4616   /* Wait for a reply, return the good/bad news... */
4617   W;
4618 }
4619
4620 static int
4621 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4622 {
4623   unformat_input_t *i = vam->input;
4624   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4625   f64 timeout;
4626   u32 sw_if_index;
4627   u8 sw_if_index_set = 0;
4628   u32 subport;
4629   u8 subport_set = 0;
4630   u32 pipe;
4631   u8 pipe_set = 0;
4632   u32 profile;
4633   u8 profile_set = 0;
4634
4635   /* Parse args required to build the message */
4636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4637     {
4638       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4639         sw_if_index_set = 1;
4640       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4641         sw_if_index_set = 1;
4642       else if (unformat (i, "subport %u", &subport))
4643         subport_set = 1;
4644       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4645         sw_if_index_set = 1;
4646       else if (unformat (i, "pipe %u", &pipe))
4647         pipe_set = 1;
4648       else if (unformat (i, "profile %u", &profile))
4649         profile_set = 1;
4650       else
4651         break;
4652     }
4653
4654   if (sw_if_index_set == 0)
4655     {
4656       errmsg ("missing interface name or sw_if_index\n");
4657       return -99;
4658     }
4659
4660   if (subport_set == 0)
4661     {
4662       errmsg ("missing subport \n");
4663       return -99;
4664     }
4665
4666   if (pipe_set == 0)
4667     {
4668       errmsg ("missing pipe\n");
4669       return -99;
4670     }
4671
4672   if (profile_set == 0)
4673     {
4674       errmsg ("missing profile\n");
4675       return -99;
4676     }
4677
4678   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4679
4680   mp->sw_if_index = ntohl (sw_if_index);
4681   mp->subport = ntohl (subport);
4682   mp->pipe = ntohl (pipe);
4683   mp->profile = ntohl (profile);
4684
4685
4686   S;
4687   W;
4688   /* NOTREACHED */
4689   return 0;
4690 }
4691
4692 static int
4693 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4694 {
4695   unformat_input_t *i = vam->input;
4696   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4697   f64 timeout;
4698   u32 sw_if_index;
4699   u8 sw_if_index_set = 0;
4700   u32 subport;
4701   u8 subport_set = 0;
4702   u32 tb_rate = 1250000000;     /* 10GbE */
4703   u32 tb_size = 1000000;
4704   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4705   u32 tc_period = 10;
4706
4707   /* Parse args required to build the message */
4708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4709     {
4710       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4711         sw_if_index_set = 1;
4712       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4713         sw_if_index_set = 1;
4714       else if (unformat (i, "subport %u", &subport))
4715         subport_set = 1;
4716       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4717         sw_if_index_set = 1;
4718       else if (unformat (i, "rate %u", &tb_rate))
4719         {
4720           u32 tc_id;
4721
4722           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4723                tc_id++)
4724             tc_rate[tc_id] = tb_rate;
4725         }
4726       else if (unformat (i, "bktsize %u", &tb_size))
4727         ;
4728       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4729         ;
4730       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4731         ;
4732       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4733         ;
4734       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4735         ;
4736       else if (unformat (i, "period %u", &tc_period))
4737         ;
4738       else
4739         break;
4740     }
4741
4742   if (sw_if_index_set == 0)
4743     {
4744       errmsg ("missing interface name or sw_if_index\n");
4745       return -99;
4746     }
4747
4748   if (subport_set == 0)
4749     {
4750       errmsg ("missing subport \n");
4751       return -99;
4752     }
4753
4754   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4755
4756   mp->sw_if_index = ntohl (sw_if_index);
4757   mp->subport = ntohl (subport);
4758   mp->tb_rate = ntohl (tb_rate);
4759   mp->tb_size = ntohl (tb_size);
4760   mp->tc_rate[0] = ntohl (tc_rate[0]);
4761   mp->tc_rate[1] = ntohl (tc_rate[1]);
4762   mp->tc_rate[2] = ntohl (tc_rate[2]);
4763   mp->tc_rate[3] = ntohl (tc_rate[3]);
4764   mp->tc_period = ntohl (tc_period);
4765
4766   S;
4767   W;
4768   /* NOTREACHED */
4769   return 0;
4770 }
4771
4772 static int
4773 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4774 {
4775   unformat_input_t *i = vam->input;
4776   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4777   f64 timeout;
4778   u32 sw_if_index;
4779   u8 sw_if_index_set = 0;
4780   u8 entry_set = 0;
4781   u8 tc_set = 0;
4782   u8 queue_set = 0;
4783   u32 entry, tc, queue;
4784
4785   /* Parse args required to build the message */
4786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4787     {
4788       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4789         sw_if_index_set = 1;
4790       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4791         sw_if_index_set = 1;
4792       else if (unformat (i, "entry %d", &entry))
4793         entry_set = 1;
4794       else if (unformat (i, "tc %d", &tc))
4795         tc_set = 1;
4796       else if (unformat (i, "queue %d", &queue))
4797         queue_set = 1;
4798       else
4799         break;
4800     }
4801
4802   if (sw_if_index_set == 0)
4803     {
4804       errmsg ("missing interface name or sw_if_index\n");
4805       return -99;
4806     }
4807
4808   if (entry_set == 0)
4809     {
4810       errmsg ("missing entry \n");
4811       return -99;
4812     }
4813
4814   if (tc_set == 0)
4815     {
4816       errmsg ("missing traffic class \n");
4817       return -99;
4818     }
4819
4820   if (queue_set == 0)
4821     {
4822       errmsg ("missing queue \n");
4823       return -99;
4824     }
4825
4826   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4827
4828   mp->sw_if_index = ntohl (sw_if_index);
4829   mp->entry = ntohl (entry);
4830   mp->tc = ntohl (tc);
4831   mp->queue = ntohl (queue);
4832
4833   S;
4834   W;
4835   /* NOTREACHED */
4836   return 0;
4837 }
4838
4839 static int
4840 api_sw_interface_add_del_address (vat_main_t * vam)
4841 {
4842   unformat_input_t *i = vam->input;
4843   vl_api_sw_interface_add_del_address_t *mp;
4844   f64 timeout;
4845   u32 sw_if_index;
4846   u8 sw_if_index_set = 0;
4847   u8 is_add = 1, del_all = 0;
4848   u32 address_length = 0;
4849   u8 v4_address_set = 0;
4850   u8 v6_address_set = 0;
4851   ip4_address_t v4address;
4852   ip6_address_t v6address;
4853
4854   /* Parse args required to build the message */
4855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4856     {
4857       if (unformat (i, "del-all"))
4858         del_all = 1;
4859       else if (unformat (i, "del"))
4860         is_add = 0;
4861       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4862         sw_if_index_set = 1;
4863       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4864         sw_if_index_set = 1;
4865       else if (unformat (i, "%U/%d",
4866                          unformat_ip4_address, &v4address, &address_length))
4867         v4_address_set = 1;
4868       else if (unformat (i, "%U/%d",
4869                          unformat_ip6_address, &v6address, &address_length))
4870         v6_address_set = 1;
4871       else
4872         break;
4873     }
4874
4875   if (sw_if_index_set == 0)
4876     {
4877       errmsg ("missing interface name or sw_if_index\n");
4878       return -99;
4879     }
4880   if (v4_address_set && v6_address_set)
4881     {
4882       errmsg ("both v4 and v6 addresses set\n");
4883       return -99;
4884     }
4885   if (!v4_address_set && !v6_address_set && !del_all)
4886     {
4887       errmsg ("no addresses set\n");
4888       return -99;
4889     }
4890
4891   /* Construct the API message */
4892   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4893
4894   mp->sw_if_index = ntohl (sw_if_index);
4895   mp->is_add = is_add;
4896   mp->del_all = del_all;
4897   if (v6_address_set)
4898     {
4899       mp->is_ipv6 = 1;
4900       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4901     }
4902   else
4903     {
4904       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4905     }
4906   mp->address_length = address_length;
4907
4908   /* send it... */
4909   S;
4910
4911   /* Wait for a reply, return good/bad news  */
4912   W;
4913 }
4914
4915 static int
4916 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4917 {
4918   unformat_input_t *i = vam->input;
4919   vl_api_sw_interface_set_mpls_enable_t *mp;
4920   f64 timeout;
4921   u32 sw_if_index;
4922   u8 sw_if_index_set = 0;
4923   u8 enable = 1;
4924
4925   /* Parse args required to build the message */
4926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4927     {
4928       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4929         sw_if_index_set = 1;
4930       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4931         sw_if_index_set = 1;
4932       else if (unformat (i, "disable"))
4933         enable = 0;
4934       else if (unformat (i, "dis"))
4935         enable = 0;
4936       else
4937         break;
4938     }
4939
4940   if (sw_if_index_set == 0)
4941     {
4942       errmsg ("missing interface name or sw_if_index\n");
4943       return -99;
4944     }
4945
4946   /* Construct the API message */
4947   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
4948
4949   mp->sw_if_index = ntohl (sw_if_index);
4950   mp->enable = enable;
4951
4952   /* send it... */
4953   S;
4954
4955   /* Wait for a reply... */
4956   W;
4957 }
4958
4959 static int
4960 api_sw_interface_set_table (vat_main_t * vam)
4961 {
4962   unformat_input_t *i = vam->input;
4963   vl_api_sw_interface_set_table_t *mp;
4964   f64 timeout;
4965   u32 sw_if_index, vrf_id = 0;
4966   u8 sw_if_index_set = 0;
4967   u8 is_ipv6 = 0;
4968
4969   /* Parse args required to build the message */
4970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4971     {
4972       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4973         sw_if_index_set = 1;
4974       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4975         sw_if_index_set = 1;
4976       else if (unformat (i, "vrf %d", &vrf_id))
4977         ;
4978       else if (unformat (i, "ipv6"))
4979         is_ipv6 = 1;
4980       else
4981         break;
4982     }
4983
4984   if (sw_if_index_set == 0)
4985     {
4986       errmsg ("missing interface name or sw_if_index\n");
4987       return -99;
4988     }
4989
4990   /* Construct the API message */
4991   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4992
4993   mp->sw_if_index = ntohl (sw_if_index);
4994   mp->is_ipv6 = is_ipv6;
4995   mp->vrf_id = ntohl (vrf_id);
4996
4997   /* send it... */
4998   S;
4999
5000   /* Wait for a reply... */
5001   W;
5002 }
5003
5004 static int
5005 api_sw_interface_set_vpath (vat_main_t * vam)
5006 {
5007   unformat_input_t *i = vam->input;
5008   vl_api_sw_interface_set_vpath_t *mp;
5009   f64 timeout;
5010   u32 sw_if_index = 0;
5011   u8 sw_if_index_set = 0;
5012   u8 is_enable = 0;
5013
5014   /* Parse args required to build the message */
5015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5016     {
5017       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5018         sw_if_index_set = 1;
5019       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5020         sw_if_index_set = 1;
5021       else if (unformat (i, "enable"))
5022         is_enable = 1;
5023       else if (unformat (i, "disable"))
5024         is_enable = 0;
5025       else
5026         break;
5027     }
5028
5029   if (sw_if_index_set == 0)
5030     {
5031       errmsg ("missing interface name or sw_if_index\n");
5032       return -99;
5033     }
5034
5035   /* Construct the API message */
5036   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5037
5038   mp->sw_if_index = ntohl (sw_if_index);
5039   mp->enable = is_enable;
5040
5041   /* send it... */
5042   S;
5043
5044   /* Wait for a reply... */
5045   W;
5046 }
5047
5048 static int
5049 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5050 {
5051   unformat_input_t *i = vam->input;
5052   vl_api_sw_interface_set_l2_xconnect_t *mp;
5053   f64 timeout;
5054   u32 rx_sw_if_index;
5055   u8 rx_sw_if_index_set = 0;
5056   u32 tx_sw_if_index;
5057   u8 tx_sw_if_index_set = 0;
5058   u8 enable = 1;
5059
5060   /* Parse args required to build the message */
5061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5062     {
5063       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5064         rx_sw_if_index_set = 1;
5065       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5066         tx_sw_if_index_set = 1;
5067       else if (unformat (i, "rx"))
5068         {
5069           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5070             {
5071               if (unformat (i, "%U", unformat_sw_if_index, vam,
5072                             &rx_sw_if_index))
5073                 rx_sw_if_index_set = 1;
5074             }
5075           else
5076             break;
5077         }
5078       else if (unformat (i, "tx"))
5079         {
5080           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5081             {
5082               if (unformat (i, "%U", unformat_sw_if_index, vam,
5083                             &tx_sw_if_index))
5084                 tx_sw_if_index_set = 1;
5085             }
5086           else
5087             break;
5088         }
5089       else if (unformat (i, "enable"))
5090         enable = 1;
5091       else if (unformat (i, "disable"))
5092         enable = 0;
5093       else
5094         break;
5095     }
5096
5097   if (rx_sw_if_index_set == 0)
5098     {
5099       errmsg ("missing rx interface name or rx_sw_if_index\n");
5100       return -99;
5101     }
5102
5103   if (enable && (tx_sw_if_index_set == 0))
5104     {
5105       errmsg ("missing tx interface name or tx_sw_if_index\n");
5106       return -99;
5107     }
5108
5109   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5110
5111   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5112   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5113   mp->enable = enable;
5114
5115   S;
5116   W;
5117   /* NOTREACHED */
5118   return 0;
5119 }
5120
5121 static int
5122 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5123 {
5124   unformat_input_t *i = vam->input;
5125   vl_api_sw_interface_set_l2_bridge_t *mp;
5126   f64 timeout;
5127   u32 rx_sw_if_index;
5128   u8 rx_sw_if_index_set = 0;
5129   u32 bd_id;
5130   u8 bd_id_set = 0;
5131   u8 bvi = 0;
5132   u32 shg = 0;
5133   u8 enable = 1;
5134
5135   /* Parse args required to build the message */
5136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5137     {
5138       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5139         rx_sw_if_index_set = 1;
5140       else if (unformat (i, "bd_id %d", &bd_id))
5141         bd_id_set = 1;
5142       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5143         rx_sw_if_index_set = 1;
5144       else if (unformat (i, "shg %d", &shg))
5145         ;
5146       else if (unformat (i, "bvi"))
5147         bvi = 1;
5148       else if (unformat (i, "enable"))
5149         enable = 1;
5150       else if (unformat (i, "disable"))
5151         enable = 0;
5152       else
5153         break;
5154     }
5155
5156   if (rx_sw_if_index_set == 0)
5157     {
5158       errmsg ("missing rx interface name or sw_if_index\n");
5159       return -99;
5160     }
5161
5162   if (enable && (bd_id_set == 0))
5163     {
5164       errmsg ("missing bridge domain\n");
5165       return -99;
5166     }
5167
5168   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5169
5170   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5171   mp->bd_id = ntohl (bd_id);
5172   mp->shg = (u8) shg;
5173   mp->bvi = bvi;
5174   mp->enable = enable;
5175
5176   S;
5177   W;
5178   /* NOTREACHED */
5179   return 0;
5180 }
5181
5182 static int
5183 api_bridge_domain_dump (vat_main_t * vam)
5184 {
5185   unformat_input_t *i = vam->input;
5186   vl_api_bridge_domain_dump_t *mp;
5187   f64 timeout;
5188   u32 bd_id = ~0;
5189
5190   /* Parse args required to build the message */
5191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5192     {
5193       if (unformat (i, "bd_id %d", &bd_id))
5194         ;
5195       else
5196         break;
5197     }
5198
5199   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5200   mp->bd_id = ntohl (bd_id);
5201   S;
5202
5203   /* Use a control ping for synchronization */
5204   {
5205     vl_api_control_ping_t *mp;
5206     M (CONTROL_PING, control_ping);
5207     S;
5208   }
5209
5210   W;
5211   /* NOTREACHED */
5212   return 0;
5213 }
5214
5215 static int
5216 api_bridge_domain_add_del (vat_main_t * vam)
5217 {
5218   unformat_input_t *i = vam->input;
5219   vl_api_bridge_domain_add_del_t *mp;
5220   f64 timeout;
5221   u32 bd_id = ~0;
5222   u8 is_add = 1;
5223   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5224
5225   /* Parse args required to build the message */
5226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5227     {
5228       if (unformat (i, "bd_id %d", &bd_id))
5229         ;
5230       else if (unformat (i, "flood %d", &flood))
5231         ;
5232       else if (unformat (i, "uu-flood %d", &uu_flood))
5233         ;
5234       else if (unformat (i, "forward %d", &forward))
5235         ;
5236       else if (unformat (i, "learn %d", &learn))
5237         ;
5238       else if (unformat (i, "arp-term %d", &arp_term))
5239         ;
5240       else if (unformat (i, "del"))
5241         {
5242           is_add = 0;
5243           flood = uu_flood = forward = learn = 0;
5244         }
5245       else
5246         break;
5247     }
5248
5249   if (bd_id == ~0)
5250     {
5251       errmsg ("missing bridge domain\n");
5252       return -99;
5253     }
5254
5255   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5256
5257   mp->bd_id = ntohl (bd_id);
5258   mp->flood = flood;
5259   mp->uu_flood = uu_flood;
5260   mp->forward = forward;
5261   mp->learn = learn;
5262   mp->arp_term = arp_term;
5263   mp->is_add = is_add;
5264
5265   S;
5266   W;
5267   /* NOTREACHED */
5268   return 0;
5269 }
5270
5271 static int
5272 api_l2fib_add_del (vat_main_t * vam)
5273 {
5274   unformat_input_t *i = vam->input;
5275   vl_api_l2fib_add_del_t *mp;
5276   f64 timeout;
5277   u64 mac = 0;
5278   u8 mac_set = 0;
5279   u32 bd_id;
5280   u8 bd_id_set = 0;
5281   u32 sw_if_index;
5282   u8 sw_if_index_set = 0;
5283   u8 is_add = 1;
5284   u8 static_mac = 0;
5285   u8 filter_mac = 0;
5286   u8 bvi_mac = 0;
5287   int count = 1;
5288   f64 before = 0;
5289   int j;
5290
5291   /* Parse args required to build the message */
5292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5293     {
5294       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5295         mac_set = 1;
5296       else if (unformat (i, "bd_id %d", &bd_id))
5297         bd_id_set = 1;
5298       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5299         sw_if_index_set = 1;
5300       else if (unformat (i, "sw_if"))
5301         {
5302           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5303             {
5304               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5305                 sw_if_index_set = 1;
5306             }
5307           else
5308             break;
5309         }
5310       else if (unformat (i, "static"))
5311         static_mac = 1;
5312       else if (unformat (i, "filter"))
5313         {
5314           filter_mac = 1;
5315           static_mac = 1;
5316         }
5317       else if (unformat (i, "bvi"))
5318         {
5319           bvi_mac = 1;
5320           static_mac = 1;
5321         }
5322       else if (unformat (i, "del"))
5323         is_add = 0;
5324       else if (unformat (i, "count %d", &count))
5325         ;
5326       else
5327         break;
5328     }
5329
5330   if (mac_set == 0)
5331     {
5332       errmsg ("missing mac address\n");
5333       return -99;
5334     }
5335
5336   if (bd_id_set == 0)
5337     {
5338       errmsg ("missing bridge domain\n");
5339       return -99;
5340     }
5341
5342   if (is_add && (sw_if_index_set == 0))
5343     {
5344       errmsg ("missing interface name or sw_if_index\n");
5345       return -99;
5346     }
5347
5348   if (count > 1)
5349     {
5350       /* Turn on async mode */
5351       vam->async_mode = 1;
5352       vam->async_errors = 0;
5353       before = vat_time_now (vam);
5354     }
5355
5356   for (j = 0; j < count; j++)
5357     {
5358       M (L2FIB_ADD_DEL, l2fib_add_del);
5359
5360       mp->mac = mac;
5361       mp->bd_id = ntohl (bd_id);
5362       mp->is_add = is_add;
5363
5364       if (is_add)
5365         {
5366           mp->sw_if_index = ntohl (sw_if_index);
5367           mp->static_mac = static_mac;
5368           mp->filter_mac = filter_mac;
5369           mp->bvi_mac = bvi_mac;
5370         }
5371       increment_mac_address (&mac);
5372       /* send it... */
5373       S;
5374     }
5375
5376   if (count > 1)
5377     {
5378       vl_api_control_ping_t *mp;
5379       f64 after;
5380
5381       /* Shut off async mode */
5382       vam->async_mode = 0;
5383
5384       M (CONTROL_PING, control_ping);
5385       S;
5386
5387       timeout = vat_time_now (vam) + 1.0;
5388       while (vat_time_now (vam) < timeout)
5389         if (vam->result_ready == 1)
5390           goto out;
5391       vam->retval = -99;
5392
5393     out:
5394       if (vam->retval == -99)
5395         errmsg ("timeout\n");
5396
5397       if (vam->async_errors > 0)
5398         {
5399           errmsg ("%d asynchronous errors\n", vam->async_errors);
5400           vam->retval = -98;
5401         }
5402       vam->async_errors = 0;
5403       after = vat_time_now (vam);
5404
5405       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5406                count, after - before, count / (after - before));
5407     }
5408   else
5409     {
5410       /* Wait for a reply... */
5411       W;
5412     }
5413   /* Return the good/bad news */
5414   return (vam->retval);
5415 }
5416
5417 static int
5418 api_l2_flags (vat_main_t * vam)
5419 {
5420   unformat_input_t *i = vam->input;
5421   vl_api_l2_flags_t *mp;
5422   f64 timeout;
5423   u32 sw_if_index;
5424   u32 feature_bitmap = 0;
5425   u8 sw_if_index_set = 0;
5426
5427   /* Parse args required to build the message */
5428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5429     {
5430       if (unformat (i, "sw_if_index %d", &sw_if_index))
5431         sw_if_index_set = 1;
5432       else if (unformat (i, "sw_if"))
5433         {
5434           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5435             {
5436               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5437                 sw_if_index_set = 1;
5438             }
5439           else
5440             break;
5441         }
5442       else if (unformat (i, "learn"))
5443         feature_bitmap |= L2INPUT_FEAT_LEARN;
5444       else if (unformat (i, "forward"))
5445         feature_bitmap |= L2INPUT_FEAT_FWD;
5446       else if (unformat (i, "flood"))
5447         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5448       else if (unformat (i, "uu-flood"))
5449         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5450       else
5451         break;
5452     }
5453
5454   if (sw_if_index_set == 0)
5455     {
5456       errmsg ("missing interface name or sw_if_index\n");
5457       return -99;
5458     }
5459
5460   M (L2_FLAGS, l2_flags);
5461
5462   mp->sw_if_index = ntohl (sw_if_index);
5463   mp->feature_bitmap = ntohl (feature_bitmap);
5464
5465   S;
5466   W;
5467   /* NOTREACHED */
5468   return 0;
5469 }
5470
5471 static int
5472 api_bridge_flags (vat_main_t * vam)
5473 {
5474   unformat_input_t *i = vam->input;
5475   vl_api_bridge_flags_t *mp;
5476   f64 timeout;
5477   u32 bd_id;
5478   u8 bd_id_set = 0;
5479   u8 is_set = 1;
5480   u32 flags = 0;
5481
5482   /* Parse args required to build the message */
5483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5484     {
5485       if (unformat (i, "bd_id %d", &bd_id))
5486         bd_id_set = 1;
5487       else if (unformat (i, "learn"))
5488         flags |= L2_LEARN;
5489       else if (unformat (i, "forward"))
5490         flags |= L2_FWD;
5491       else if (unformat (i, "flood"))
5492         flags |= L2_FLOOD;
5493       else if (unformat (i, "uu-flood"))
5494         flags |= L2_UU_FLOOD;
5495       else if (unformat (i, "arp-term"))
5496         flags |= L2_ARP_TERM;
5497       else if (unformat (i, "off"))
5498         is_set = 0;
5499       else if (unformat (i, "disable"))
5500         is_set = 0;
5501       else
5502         break;
5503     }
5504
5505   if (bd_id_set == 0)
5506     {
5507       errmsg ("missing bridge domain\n");
5508       return -99;
5509     }
5510
5511   M (BRIDGE_FLAGS, bridge_flags);
5512
5513   mp->bd_id = ntohl (bd_id);
5514   mp->feature_bitmap = ntohl (flags);
5515   mp->is_set = is_set;
5516
5517   S;
5518   W;
5519   /* NOTREACHED */
5520   return 0;
5521 }
5522
5523 static int
5524 api_bd_ip_mac_add_del (vat_main_t * vam)
5525 {
5526   unformat_input_t *i = vam->input;
5527   vl_api_bd_ip_mac_add_del_t *mp;
5528   f64 timeout;
5529   u32 bd_id;
5530   u8 is_ipv6 = 0;
5531   u8 is_add = 1;
5532   u8 bd_id_set = 0;
5533   u8 ip_set = 0;
5534   u8 mac_set = 0;
5535   ip4_address_t v4addr;
5536   ip6_address_t v6addr;
5537   u8 macaddr[6];
5538
5539
5540   /* Parse args required to build the message */
5541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5542     {
5543       if (unformat (i, "bd_id %d", &bd_id))
5544         {
5545           bd_id_set++;
5546         }
5547       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5548         {
5549           ip_set++;
5550         }
5551       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5552         {
5553           ip_set++;
5554           is_ipv6++;
5555         }
5556       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5557         {
5558           mac_set++;
5559         }
5560       else if (unformat (i, "del"))
5561         is_add = 0;
5562       else
5563         break;
5564     }
5565
5566   if (bd_id_set == 0)
5567     {
5568       errmsg ("missing bridge domain\n");
5569       return -99;
5570     }
5571   else if (ip_set == 0)
5572     {
5573       errmsg ("missing IP address\n");
5574       return -99;
5575     }
5576   else if (mac_set == 0)
5577     {
5578       errmsg ("missing MAC address\n");
5579       return -99;
5580     }
5581
5582   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5583
5584   mp->bd_id = ntohl (bd_id);
5585   mp->is_ipv6 = is_ipv6;
5586   mp->is_add = is_add;
5587   if (is_ipv6)
5588     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5589   else
5590     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5591   clib_memcpy (mp->mac_address, macaddr, 6);
5592   S;
5593   W;
5594   /* NOTREACHED */
5595   return 0;
5596 }
5597
5598 static int
5599 api_tap_connect (vat_main_t * vam)
5600 {
5601   unformat_input_t *i = vam->input;
5602   vl_api_tap_connect_t *mp;
5603   f64 timeout;
5604   u8 mac_address[6];
5605   u8 random_mac = 1;
5606   u8 name_set = 0;
5607   u8 *tap_name;
5608
5609   memset (mac_address, 0, sizeof (mac_address));
5610
5611   /* Parse args required to build the message */
5612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5613     {
5614       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5615         {
5616           random_mac = 0;
5617         }
5618       else if (unformat (i, "random-mac"))
5619         random_mac = 1;
5620       else if (unformat (i, "tapname %s", &tap_name))
5621         name_set = 1;
5622       else
5623         break;
5624     }
5625
5626   if (name_set == 0)
5627     {
5628       errmsg ("missing tap name\n");
5629       return -99;
5630     }
5631   if (vec_len (tap_name) > 63)
5632     {
5633       errmsg ("tap name too long\n");
5634     }
5635   vec_add1 (tap_name, 0);
5636
5637   /* Construct the API message */
5638   M (TAP_CONNECT, tap_connect);
5639
5640   mp->use_random_mac = random_mac;
5641   clib_memcpy (mp->mac_address, mac_address, 6);
5642   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5643   vec_free (tap_name);
5644
5645   /* send it... */
5646   S;
5647
5648   /* Wait for a reply... */
5649   W;
5650 }
5651
5652 static int
5653 api_tap_modify (vat_main_t * vam)
5654 {
5655   unformat_input_t *i = vam->input;
5656   vl_api_tap_modify_t *mp;
5657   f64 timeout;
5658   u8 mac_address[6];
5659   u8 random_mac = 1;
5660   u8 name_set = 0;
5661   u8 *tap_name;
5662   u32 sw_if_index = ~0;
5663   u8 sw_if_index_set = 0;
5664
5665   memset (mac_address, 0, sizeof (mac_address));
5666
5667   /* Parse args required to build the message */
5668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5669     {
5670       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5671         sw_if_index_set = 1;
5672       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5673         sw_if_index_set = 1;
5674       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5675         {
5676           random_mac = 0;
5677         }
5678       else if (unformat (i, "random-mac"))
5679         random_mac = 1;
5680       else if (unformat (i, "tapname %s", &tap_name))
5681         name_set = 1;
5682       else
5683         break;
5684     }
5685
5686   if (sw_if_index_set == 0)
5687     {
5688       errmsg ("missing vpp interface name");
5689       return -99;
5690     }
5691   if (name_set == 0)
5692     {
5693       errmsg ("missing tap name\n");
5694       return -99;
5695     }
5696   if (vec_len (tap_name) > 63)
5697     {
5698       errmsg ("tap name too long\n");
5699     }
5700   vec_add1 (tap_name, 0);
5701
5702   /* Construct the API message */
5703   M (TAP_MODIFY, tap_modify);
5704
5705   mp->use_random_mac = random_mac;
5706   mp->sw_if_index = ntohl (sw_if_index);
5707   clib_memcpy (mp->mac_address, mac_address, 6);
5708   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5709   vec_free (tap_name);
5710
5711   /* send it... */
5712   S;
5713
5714   /* Wait for a reply... */
5715   W;
5716 }
5717
5718 static int
5719 api_tap_delete (vat_main_t * vam)
5720 {
5721   unformat_input_t *i = vam->input;
5722   vl_api_tap_delete_t *mp;
5723   f64 timeout;
5724   u32 sw_if_index = ~0;
5725   u8 sw_if_index_set = 0;
5726
5727   /* Parse args required to build the message */
5728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5729     {
5730       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5731         sw_if_index_set = 1;
5732       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5733         sw_if_index_set = 1;
5734       else
5735         break;
5736     }
5737
5738   if (sw_if_index_set == 0)
5739     {
5740       errmsg ("missing vpp interface name");
5741       return -99;
5742     }
5743
5744   /* Construct the API message */
5745   M (TAP_DELETE, tap_delete);
5746
5747   mp->sw_if_index = ntohl (sw_if_index);
5748
5749   /* send it... */
5750   S;
5751
5752   /* Wait for a reply... */
5753   W;
5754 }
5755
5756 static int
5757 api_ip_add_del_route (vat_main_t * vam)
5758 {
5759   unformat_input_t *i = vam->input;
5760   vl_api_ip_add_del_route_t *mp;
5761   f64 timeout;
5762   u32 sw_if_index = ~0, vrf_id = 0;
5763   u8 sw_if_index_set = 0;
5764   u8 is_ipv6 = 0;
5765   u8 is_local = 0, is_drop = 0;
5766   u8 is_unreach = 0, is_prohibit = 0;
5767   u8 create_vrf_if_needed = 0;
5768   u8 is_add = 1;
5769   u8 next_hop_weight = 1;
5770   u8 not_last = 0;
5771   u8 is_multipath = 0;
5772   u8 address_set = 0;
5773   u8 address_length_set = 0;
5774   u32 next_hop_table_id = 0;
5775   u32 resolve_attempts = 0;
5776   u32 dst_address_length = 0;
5777   u8 next_hop_set = 0;
5778   ip4_address_t v4_dst_address, v4_next_hop_address;
5779   ip6_address_t v6_dst_address, v6_next_hop_address;
5780   int count = 1;
5781   int j;
5782   f64 before = 0;
5783   u32 random_add_del = 0;
5784   u32 *random_vector = 0;
5785   uword *random_hash;
5786   u32 random_seed = 0xdeaddabe;
5787   u32 classify_table_index = ~0;
5788   u8 is_classify = 0;
5789   u8 resolve_host = 0, resolve_attached = 0;
5790   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5791
5792   /* Parse args required to build the message */
5793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5794     {
5795       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5796         sw_if_index_set = 1;
5797       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5798         sw_if_index_set = 1;
5799       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5800         {
5801           address_set = 1;
5802           is_ipv6 = 0;
5803         }
5804       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5805         {
5806           address_set = 1;
5807           is_ipv6 = 1;
5808         }
5809       else if (unformat (i, "/%d", &dst_address_length))
5810         {
5811           address_length_set = 1;
5812         }
5813
5814       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5815                                          &v4_next_hop_address))
5816         {
5817           next_hop_set = 1;
5818         }
5819       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5820                                          &v6_next_hop_address))
5821         {
5822           next_hop_set = 1;
5823         }
5824       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5825         ;
5826       else if (unformat (i, "weight %d", &next_hop_weight))
5827         ;
5828       else if (unformat (i, "drop"))
5829         {
5830           is_drop = 1;
5831         }
5832       else if (unformat (i, "null-send-unreach"))
5833         {
5834           is_unreach = 1;
5835         }
5836       else if (unformat (i, "null-send-prohibit"))
5837         {
5838           is_prohibit = 1;
5839         }
5840       else if (unformat (i, "local"))
5841         {
5842           is_local = 1;
5843         }
5844       else if (unformat (i, "classify %d", &classify_table_index))
5845         {
5846           is_classify = 1;
5847         }
5848       else if (unformat (i, "del"))
5849         is_add = 0;
5850       else if (unformat (i, "add"))
5851         is_add = 1;
5852       else if (unformat (i, "not-last"))
5853         not_last = 1;
5854       else if (unformat (i, "resolve-via-host"))
5855         resolve_host = 1;
5856       else if (unformat (i, "resolve-via-attached"))
5857         resolve_attached = 1;
5858       else if (unformat (i, "multipath"))
5859         is_multipath = 1;
5860       else if (unformat (i, "vrf %d", &vrf_id))
5861         ;
5862       else if (unformat (i, "create-vrf"))
5863         create_vrf_if_needed = 1;
5864       else if (unformat (i, "count %d", &count))
5865         ;
5866       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
5867         ;
5868       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
5869         ;
5870       else if (unformat (i, "out-label %d", &next_hop_out_label))
5871         ;
5872       else if (unformat (i, "random"))
5873         random_add_del = 1;
5874       else if (unformat (i, "seed %d", &random_seed))
5875         ;
5876       else
5877         {
5878           clib_warning ("parse error '%U'", format_unformat_error, i);
5879           return -99;
5880         }
5881     }
5882
5883   if (resolve_attempts > 0 && sw_if_index_set == 0)
5884     {
5885       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5886       return -99;
5887     }
5888
5889   if (!next_hop_set && !is_drop && !is_local &&
5890       !is_classify && !is_unreach && !is_prohibit)
5891     {
5892       errmsg
5893         ("next hop / local / drop / unreach / prohibit / classify not set\n");
5894       return -99;
5895     }
5896
5897   if (address_set == 0)
5898     {
5899       errmsg ("missing addresses\n");
5900       return -99;
5901     }
5902
5903   if (address_length_set == 0)
5904     {
5905       errmsg ("missing address length\n");
5906       return -99;
5907     }
5908
5909   /* Generate a pile of unique, random routes */
5910   if (random_add_del)
5911     {
5912       u32 this_random_address;
5913       random_hash = hash_create (count, sizeof (uword));
5914
5915       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5916       for (j = 0; j <= count; j++)
5917         {
5918           do
5919             {
5920               this_random_address = random_u32 (&random_seed);
5921               this_random_address =
5922                 clib_host_to_net_u32 (this_random_address);
5923             }
5924           while (hash_get (random_hash, this_random_address));
5925           vec_add1 (random_vector, this_random_address);
5926           hash_set (random_hash, this_random_address, 1);
5927         }
5928       hash_free (random_hash);
5929       v4_dst_address.as_u32 = random_vector[0];
5930     }
5931
5932   if (count > 1)
5933     {
5934       /* Turn on async mode */
5935       vam->async_mode = 1;
5936       vam->async_errors = 0;
5937       before = vat_time_now (vam);
5938     }
5939
5940   for (j = 0; j < count; j++)
5941     {
5942       /* Construct the API message */
5943       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5944
5945       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5946       mp->table_id = ntohl (vrf_id);
5947       if (resolve_attempts > 0)
5948         {
5949           mp->resolve_attempts = ntohl (resolve_attempts);
5950           mp->resolve_if_needed = 1;
5951         }
5952       mp->create_vrf_if_needed = create_vrf_if_needed;
5953
5954       mp->is_add = is_add;
5955       mp->is_drop = is_drop;
5956       mp->is_unreach = is_unreach;
5957       mp->is_prohibit = is_prohibit;
5958       mp->is_ipv6 = is_ipv6;
5959       mp->is_local = is_local;
5960       mp->is_classify = is_classify;
5961       mp->is_multipath = is_multipath;
5962       mp->is_resolve_host = resolve_host;
5963       mp->is_resolve_attached = resolve_attached;
5964       mp->not_last = not_last;
5965       mp->next_hop_weight = next_hop_weight;
5966       mp->dst_address_length = dst_address_length;
5967       mp->next_hop_table_id = ntohl (next_hop_table_id);
5968       mp->classify_table_index = ntohl (classify_table_index);
5969       mp->next_hop_out_label = ntohl (next_hop_out_label);
5970
5971       if (is_ipv6)
5972         {
5973           clib_memcpy (mp->dst_address, &v6_dst_address,
5974                        sizeof (v6_dst_address));
5975           if (next_hop_set)
5976             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5977                          sizeof (v6_next_hop_address));
5978           increment_v6_address (&v6_dst_address);
5979         }
5980       else
5981         {
5982           clib_memcpy (mp->dst_address, &v4_dst_address,
5983                        sizeof (v4_dst_address));
5984           if (next_hop_set)
5985             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5986                          sizeof (v4_next_hop_address));
5987           if (random_add_del)
5988             v4_dst_address.as_u32 = random_vector[j + 1];
5989           else
5990             increment_v4_address (&v4_dst_address);
5991         }
5992       /* send it... */
5993       S;
5994       /* If we receive SIGTERM, stop now... */
5995       if (vam->do_exit)
5996         break;
5997     }
5998
5999   /* When testing multiple add/del ops, use a control-ping to sync */
6000   if (count > 1)
6001     {
6002       vl_api_control_ping_t *mp;
6003       f64 after;
6004
6005       /* Shut off async mode */
6006       vam->async_mode = 0;
6007
6008       M (CONTROL_PING, control_ping);
6009       S;
6010
6011       timeout = vat_time_now (vam) + 1.0;
6012       while (vat_time_now (vam) < timeout)
6013         if (vam->result_ready == 1)
6014           goto out;
6015       vam->retval = -99;
6016
6017     out:
6018       if (vam->retval == -99)
6019         errmsg ("timeout\n");
6020
6021       if (vam->async_errors > 0)
6022         {
6023           errmsg ("%d asynchronous errors\n", vam->async_errors);
6024           vam->retval = -98;
6025         }
6026       vam->async_errors = 0;
6027       after = vat_time_now (vam);
6028
6029       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6030       if (j > 0)
6031         count = j;
6032
6033       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6034                count, after - before, count / (after - before));
6035     }
6036   else
6037     {
6038       /* Wait for a reply... */
6039       W;
6040     }
6041
6042   /* Return the good/bad news */
6043   return (vam->retval);
6044 }
6045
6046 static int
6047 api_mpls_route_add_del (vat_main_t * vam)
6048 {
6049   unformat_input_t *i = vam->input;
6050   vl_api_mpls_route_add_del_t *mp;
6051   f64 timeout;
6052   u32 sw_if_index = ~0, table_id = 0;
6053   u8 create_table_if_needed = 0;
6054   u8 is_add = 1;
6055   u8 next_hop_weight = 1;
6056   u8 is_multipath = 0;
6057   u32 next_hop_table_id = 0;
6058   u8 next_hop_set = 0;
6059   ip4_address_t v4_next_hop_address = {
6060     .as_u32 = 0,
6061   };
6062   ip6_address_t v6_next_hop_address = { {0} };
6063   int count = 1;
6064   int j;
6065   f64 before = 0;
6066   u32 classify_table_index = ~0;
6067   u8 is_classify = 0;
6068   u8 resolve_host = 0, resolve_attached = 0;
6069   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6070   mpls_label_t local_label = MPLS_LABEL_INVALID;
6071   u8 is_eos = 1;
6072   u8 next_hop_proto_is_ip4 = 1;
6073
6074   /* Parse args required to build the message */
6075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6076     {
6077       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6078         ;
6079       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6080         ;
6081       else if (unformat (i, "%d", &local_label))
6082         ;
6083       else if (unformat (i, "eos"))
6084         is_eos = 1;
6085       else if (unformat (i, "non-eos"))
6086         is_eos = 0;
6087       else if (unformat (i, "via %U", unformat_ip4_address,
6088                          &v4_next_hop_address))
6089         {
6090           next_hop_set = 1;
6091           next_hop_proto_is_ip4 = 1;
6092         }
6093       else if (unformat (i, "via %U", unformat_ip6_address,
6094                          &v6_next_hop_address))
6095         {
6096           next_hop_set = 1;
6097           next_hop_proto_is_ip4 = 0;
6098         }
6099       else if (unformat (i, "weight %d", &next_hop_weight))
6100         ;
6101       else if (unformat (i, "create-table"))
6102         create_table_if_needed = 1;
6103       else if (unformat (i, "classify %d", &classify_table_index))
6104         {
6105           is_classify = 1;
6106         }
6107       else if (unformat (i, "del"))
6108         is_add = 0;
6109       else if (unformat (i, "add"))
6110         is_add = 1;
6111       else if (unformat (i, "resolve-via-host"))
6112         resolve_host = 1;
6113       else if (unformat (i, "resolve-via-attached"))
6114         resolve_attached = 1;
6115       else if (unformat (i, "multipath"))
6116         is_multipath = 1;
6117       else if (unformat (i, "count %d", &count))
6118         ;
6119       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6120         {
6121           next_hop_set = 1;
6122           next_hop_proto_is_ip4 = 1;
6123         }
6124       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6125         {
6126           next_hop_set = 1;
6127           next_hop_proto_is_ip4 = 0;
6128         }
6129       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6130         ;
6131       else if (unformat (i, "out-label %d", &next_hop_out_label))
6132         ;
6133       else
6134         {
6135           clib_warning ("parse error '%U'", format_unformat_error, i);
6136           return -99;
6137         }
6138     }
6139
6140   if (!next_hop_set && !is_classify)
6141     {
6142       errmsg ("next hop / classify not set\n");
6143       return -99;
6144     }
6145
6146   if (MPLS_LABEL_INVALID == local_label)
6147     {
6148       errmsg ("missing label\n");
6149       return -99;
6150     }
6151
6152   if (count > 1)
6153     {
6154       /* Turn on async mode */
6155       vam->async_mode = 1;
6156       vam->async_errors = 0;
6157       before = vat_time_now (vam);
6158     }
6159
6160   for (j = 0; j < count; j++)
6161     {
6162       /* Construct the API message */
6163       M (MPLS_ROUTE_ADD_DEL, mpls_route_add_del);
6164
6165       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6166       mp->mr_table_id = ntohl (table_id);
6167       mp->mr_create_table_if_needed = create_table_if_needed;
6168
6169       mp->mr_is_add = is_add;
6170       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6171       mp->mr_is_classify = is_classify;
6172       mp->mr_is_multipath = is_multipath;
6173       mp->mr_is_resolve_host = resolve_host;
6174       mp->mr_is_resolve_attached = resolve_attached;
6175       mp->mr_next_hop_weight = next_hop_weight;
6176       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6177       mp->mr_classify_table_index = ntohl (classify_table_index);
6178       mp->mr_next_hop_out_label = ntohl (next_hop_out_label);
6179       mp->mr_label = ntohl (local_label);
6180       mp->mr_eos = is_eos;
6181
6182       if (next_hop_set)
6183         {
6184           if (next_hop_proto_is_ip4)
6185             {
6186               clib_memcpy (mp->mr_next_hop,
6187                            &v4_next_hop_address,
6188                            sizeof (v4_next_hop_address));
6189             }
6190           else
6191             {
6192               clib_memcpy (mp->mr_next_hop,
6193                            &v6_next_hop_address,
6194                            sizeof (v6_next_hop_address));
6195             }
6196         }
6197       local_label++;
6198
6199       /* send it... */
6200       S;
6201       /* If we receive SIGTERM, stop now... */
6202       if (vam->do_exit)
6203         break;
6204     }
6205
6206   /* When testing multiple add/del ops, use a control-ping to sync */
6207   if (count > 1)
6208     {
6209       vl_api_control_ping_t *mp;
6210       f64 after;
6211
6212       /* Shut off async mode */
6213       vam->async_mode = 0;
6214
6215       M (CONTROL_PING, control_ping);
6216       S;
6217
6218       timeout = vat_time_now (vam) + 1.0;
6219       while (vat_time_now (vam) < timeout)
6220         if (vam->result_ready == 1)
6221           goto out;
6222       vam->retval = -99;
6223
6224     out:
6225       if (vam->retval == -99)
6226         errmsg ("timeout\n");
6227
6228       if (vam->async_errors > 0)
6229         {
6230           errmsg ("%d asynchronous errors\n", vam->async_errors);
6231           vam->retval = -98;
6232         }
6233       vam->async_errors = 0;
6234       after = vat_time_now (vam);
6235
6236       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6237       if (j > 0)
6238         count = j;
6239
6240       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6241                count, after - before, count / (after - before));
6242     }
6243   else
6244     {
6245       /* Wait for a reply... */
6246       W;
6247     }
6248
6249   /* Return the good/bad news */
6250   return (vam->retval);
6251 }
6252
6253 static int
6254 api_mpls_ip_bind_unbind (vat_main_t * vam)
6255 {
6256   unformat_input_t *i = vam->input;
6257   vl_api_mpls_ip_bind_unbind_t *mp;
6258   f64 timeout;
6259   u32 ip_table_id = 0;
6260   u8 create_table_if_needed = 0;
6261   u8 is_bind = 1;
6262   u8 is_ip4 = 1;
6263   ip4_address_t v4_address;
6264   ip6_address_t v6_address;
6265   u32 address_length;
6266   u8 address_set = 0;
6267   mpls_label_t local_label = MPLS_LABEL_INVALID;
6268
6269   /* Parse args required to build the message */
6270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6271     {
6272       if (unformat (i, "%U/%d", unformat_ip4_address,
6273                     &v4_address, &address_length))
6274         {
6275           is_ip4 = 1;
6276           address_set = 1;
6277         }
6278       else if (unformat (i, "%U/%d", unformat_ip6_address,
6279                          &v6_address, &address_length))
6280         {
6281           is_ip4 = 0;
6282           address_set = 1;
6283         }
6284       else if (unformat (i, "%d", &local_label))
6285         ;
6286       else if (unformat (i, "create-table"))
6287         create_table_if_needed = 1;
6288       else if (unformat (i, "table-id %d", &ip_table_id))
6289         ;
6290       else if (unformat (i, "unbind"))
6291         is_bind = 0;
6292       else if (unformat (i, "bind"))
6293         is_bind = 1;
6294       else
6295         {
6296           clib_warning ("parse error '%U'", format_unformat_error, i);
6297           return -99;
6298         }
6299     }
6300
6301   if (!address_set)
6302     {
6303       errmsg ("IP addres not set\n");
6304       return -99;
6305     }
6306
6307   if (MPLS_LABEL_INVALID == local_label)
6308     {
6309       errmsg ("missing label\n");
6310       return -99;
6311     }
6312
6313   /* Construct the API message */
6314   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6315
6316   mp->mb_create_table_if_needed = create_table_if_needed;
6317   mp->mb_is_bind = is_bind;
6318   mp->mb_is_ip4 = is_ip4;
6319   mp->mb_ip_table_id = ntohl (ip_table_id);
6320   mp->mb_mpls_table_id = 0;
6321   mp->mb_label = ntohl (local_label);
6322   mp->mb_address_length = address_length;
6323
6324   if (is_ip4)
6325     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6326   else
6327     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6328
6329   /* send it... */
6330   S;
6331
6332   /* Wait for a reply... */
6333   W;
6334 }
6335
6336 static int
6337 api_proxy_arp_add_del (vat_main_t * vam)
6338 {
6339   unformat_input_t *i = vam->input;
6340   vl_api_proxy_arp_add_del_t *mp;
6341   f64 timeout;
6342   u32 vrf_id = 0;
6343   u8 is_add = 1;
6344   ip4_address_t lo, hi;
6345   u8 range_set = 0;
6346
6347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6348     {
6349       if (unformat (i, "vrf %d", &vrf_id))
6350         ;
6351       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6352                          unformat_ip4_address, &hi))
6353         range_set = 1;
6354       else if (unformat (i, "del"))
6355         is_add = 0;
6356       else
6357         {
6358           clib_warning ("parse error '%U'", format_unformat_error, i);
6359           return -99;
6360         }
6361     }
6362
6363   if (range_set == 0)
6364     {
6365       errmsg ("address range not set\n");
6366       return -99;
6367     }
6368
6369   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6370
6371   mp->vrf_id = ntohl (vrf_id);
6372   mp->is_add = is_add;
6373   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6374   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6375
6376   S;
6377   W;
6378   /* NOTREACHED */
6379   return 0;
6380 }
6381
6382 static int
6383 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6384 {
6385   unformat_input_t *i = vam->input;
6386   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6387   f64 timeout;
6388   u32 sw_if_index;
6389   u8 enable = 1;
6390   u8 sw_if_index_set = 0;
6391
6392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6393     {
6394       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6395         sw_if_index_set = 1;
6396       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6397         sw_if_index_set = 1;
6398       else if (unformat (i, "enable"))
6399         enable = 1;
6400       else if (unformat (i, "disable"))
6401         enable = 0;
6402       else
6403         {
6404           clib_warning ("parse error '%U'", format_unformat_error, i);
6405           return -99;
6406         }
6407     }
6408
6409   if (sw_if_index_set == 0)
6410     {
6411       errmsg ("missing interface name or sw_if_index\n");
6412       return -99;
6413     }
6414
6415   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6416
6417   mp->sw_if_index = ntohl (sw_if_index);
6418   mp->enable_disable = enable;
6419
6420   S;
6421   W;
6422   /* NOTREACHED */
6423   return 0;
6424 }
6425
6426 static int
6427 api_mpls_add_del_encap (vat_main_t * vam)
6428 {
6429   unformat_input_t *i = vam->input;
6430   vl_api_mpls_add_del_encap_t *mp;
6431   f64 timeout;
6432   u32 vrf_id = 0;
6433   u32 *labels = 0;
6434   u32 label;
6435   ip4_address_t dst_address;
6436   u8 is_add = 1;
6437
6438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6439     {
6440       if (unformat (i, "vrf %d", &vrf_id))
6441         ;
6442       else if (unformat (i, "label %d", &label))
6443         vec_add1 (labels, ntohl (label));
6444       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6445         ;
6446       else if (unformat (i, "del"))
6447         is_add = 0;
6448       else
6449         {
6450           clib_warning ("parse error '%U'", format_unformat_error, i);
6451           return -99;
6452         }
6453     }
6454
6455   if (vec_len (labels) == 0)
6456     {
6457       errmsg ("missing encap label stack\n");
6458       return -99;
6459     }
6460
6461   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6462       sizeof (u32) * vec_len (labels));
6463
6464   mp->vrf_id = ntohl (vrf_id);
6465   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6466   mp->is_add = is_add;
6467   mp->nlabels = vec_len (labels);
6468   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6469
6470   vec_free (labels);
6471
6472   S;
6473   W;
6474   /* NOTREACHED */
6475   return 0;
6476 }
6477
6478 static int
6479 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6480 {
6481   unformat_input_t *i = vam->input;
6482   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6483   f64 timeout;
6484   u32 inner_vrf_id = 0;
6485   ip4_address_t intfc_address;
6486   u8 dst_mac_address[6];
6487   int dst_set = 1;
6488   u32 tmp;
6489   u8 intfc_address_length = 0;
6490   u8 is_add = 1;
6491   u8 l2_only = 0;
6492   u32 tx_sw_if_index;
6493   int tx_sw_if_index_set = 0;
6494
6495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6496     {
6497       if (unformat (i, "vrf %d", &inner_vrf_id))
6498         ;
6499       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6500                          &intfc_address, &tmp))
6501         intfc_address_length = tmp;
6502       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6503         tx_sw_if_index_set = 1;
6504       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6505         tx_sw_if_index_set = 1;
6506       else if (unformat (i, "dst %U", unformat_ethernet_address,
6507                          dst_mac_address))
6508         dst_set = 1;
6509       else if (unformat (i, "l2-only"))
6510         l2_only = 1;
6511       else if (unformat (i, "del"))
6512         is_add = 0;
6513       else
6514         {
6515           clib_warning ("parse error '%U'", format_unformat_error, i);
6516           return -99;
6517         }
6518     }
6519
6520   if (!dst_set)
6521     {
6522       errmsg ("dst (mac address) not set\n");
6523       return -99;
6524     }
6525   if (!tx_sw_if_index_set)
6526     {
6527       errmsg ("tx-intfc not set\n");
6528       return -99;
6529     }
6530
6531   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6532
6533   mp->vrf_id = ntohl (inner_vrf_id);
6534   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6535   mp->adj_address_length = intfc_address_length;
6536   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6537                sizeof (dst_mac_address));
6538   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6539   mp->l2_only = l2_only;
6540   mp->is_add = is_add;
6541
6542   S;
6543   W;
6544   /* NOTREACHED */
6545   return 0;
6546 }
6547
6548 static int
6549 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6550 {
6551   unformat_input_t *i = vam->input;
6552   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6553   f64 timeout;
6554   u32 inner_vrf_id = 0;
6555   u32 outer_vrf_id = 0;
6556   ip4_address_t adj_address;
6557   int adj_address_set = 0;
6558   ip4_address_t next_hop_address;
6559   int next_hop_address_set = 0;
6560   u32 tmp;
6561   u8 adj_address_length = 0;
6562   u8 l2_only = 0;
6563   u8 is_add = 1;
6564   u32 resolve_attempts = 5;
6565   u8 resolve_if_needed = 1;
6566
6567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6568     {
6569       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6570         ;
6571       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6572         ;
6573       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6574                          &adj_address, &tmp))
6575         {
6576           adj_address_length = tmp;
6577           adj_address_set = 1;
6578         }
6579       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6580                          &next_hop_address))
6581         next_hop_address_set = 1;
6582       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6583         ;
6584       else if (unformat (i, "resolve-if-needed %d", &tmp))
6585         resolve_if_needed = tmp;
6586       else if (unformat (i, "l2-only"))
6587         l2_only = 1;
6588       else if (unformat (i, "del"))
6589         is_add = 0;
6590       else
6591         {
6592           clib_warning ("parse error '%U'", format_unformat_error, i);
6593           return -99;
6594         }
6595     }
6596
6597   if (!adj_address_set)
6598     {
6599       errmsg ("adjacency address/mask not set\n");
6600       return -99;
6601     }
6602   if (!next_hop_address_set)
6603     {
6604       errmsg ("ip4 next hop address (in outer fib) not set\n");
6605       return -99;
6606     }
6607
6608   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6609
6610   mp->inner_vrf_id = ntohl (inner_vrf_id);
6611   mp->outer_vrf_id = ntohl (outer_vrf_id);
6612   mp->resolve_attempts = ntohl (resolve_attempts);
6613   mp->resolve_if_needed = resolve_if_needed;
6614   mp->is_add = is_add;
6615   mp->l2_only = l2_only;
6616   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6617   mp->adj_address_length = adj_address_length;
6618   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6619                sizeof (next_hop_address));
6620
6621   S;
6622   W;
6623   /* NOTREACHED */
6624   return 0;
6625 }
6626
6627 static int
6628 api_sw_interface_set_unnumbered (vat_main_t * vam)
6629 {
6630   unformat_input_t *i = vam->input;
6631   vl_api_sw_interface_set_unnumbered_t *mp;
6632   f64 timeout;
6633   u32 sw_if_index;
6634   u32 unnum_sw_index = ~0;
6635   u8 is_add = 1;
6636   u8 sw_if_index_set = 0;
6637
6638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6639     {
6640       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6641         sw_if_index_set = 1;
6642       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6643         sw_if_index_set = 1;
6644       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6645         ;
6646       else if (unformat (i, "del"))
6647         is_add = 0;
6648       else
6649         {
6650           clib_warning ("parse error '%U'", format_unformat_error, i);
6651           return -99;
6652         }
6653     }
6654
6655   if (sw_if_index_set == 0)
6656     {
6657       errmsg ("missing interface name or sw_if_index\n");
6658       return -99;
6659     }
6660
6661   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6662
6663   mp->sw_if_index = ntohl (sw_if_index);
6664   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6665   mp->is_add = is_add;
6666
6667   S;
6668   W;
6669   /* NOTREACHED */
6670   return 0;
6671 }
6672
6673 static int
6674 api_ip_neighbor_add_del (vat_main_t * vam)
6675 {
6676   unformat_input_t *i = vam->input;
6677   vl_api_ip_neighbor_add_del_t *mp;
6678   f64 timeout;
6679   u32 sw_if_index;
6680   u8 sw_if_index_set = 0;
6681   u32 vrf_id = 0;
6682   u8 is_add = 1;
6683   u8 is_static = 0;
6684   u8 mac_address[6];
6685   u8 mac_set = 0;
6686   u8 v4_address_set = 0;
6687   u8 v6_address_set = 0;
6688   ip4_address_t v4address;
6689   ip6_address_t v6address;
6690
6691   memset (mac_address, 0, sizeof (mac_address));
6692
6693   /* Parse args required to build the message */
6694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6695     {
6696       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6697         {
6698           mac_set = 1;
6699         }
6700       else if (unformat (i, "del"))
6701         is_add = 0;
6702       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6703         sw_if_index_set = 1;
6704       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6705         sw_if_index_set = 1;
6706       else if (unformat (i, "is_static"))
6707         is_static = 1;
6708       else if (unformat (i, "vrf %d", &vrf_id))
6709         ;
6710       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6711         v4_address_set = 1;
6712       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6713         v6_address_set = 1;
6714       else
6715         {
6716           clib_warning ("parse error '%U'", format_unformat_error, i);
6717           return -99;
6718         }
6719     }
6720
6721   if (sw_if_index_set == 0)
6722     {
6723       errmsg ("missing interface name or sw_if_index\n");
6724       return -99;
6725     }
6726   if (v4_address_set && v6_address_set)
6727     {
6728       errmsg ("both v4 and v6 addresses set\n");
6729       return -99;
6730     }
6731   if (!v4_address_set && !v6_address_set)
6732     {
6733       errmsg ("no address set\n");
6734       return -99;
6735     }
6736
6737   /* Construct the API message */
6738   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6739
6740   mp->sw_if_index = ntohl (sw_if_index);
6741   mp->is_add = is_add;
6742   mp->vrf_id = ntohl (vrf_id);
6743   mp->is_static = is_static;
6744   if (mac_set)
6745     clib_memcpy (mp->mac_address, mac_address, 6);
6746   if (v6_address_set)
6747     {
6748       mp->is_ipv6 = 1;
6749       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6750     }
6751   else
6752     {
6753       /* mp->is_ipv6 = 0; via memset in M macro above */
6754       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6755     }
6756
6757   /* send it... */
6758   S;
6759
6760   /* Wait for a reply, return good/bad news  */
6761   W;
6762
6763   /* NOTREACHED */
6764   return 0;
6765 }
6766
6767 static int
6768 api_reset_vrf (vat_main_t * vam)
6769 {
6770   unformat_input_t *i = vam->input;
6771   vl_api_reset_vrf_t *mp;
6772   f64 timeout;
6773   u32 vrf_id = 0;
6774   u8 is_ipv6 = 0;
6775   u8 vrf_id_set = 0;
6776
6777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6778     {
6779       if (unformat (i, "vrf %d", &vrf_id))
6780         vrf_id_set = 1;
6781       else if (unformat (i, "ipv6"))
6782         is_ipv6 = 1;
6783       else
6784         {
6785           clib_warning ("parse error '%U'", format_unformat_error, i);
6786           return -99;
6787         }
6788     }
6789
6790   if (vrf_id_set == 0)
6791     {
6792       errmsg ("missing vrf id\n");
6793       return -99;
6794     }
6795
6796   M (RESET_VRF, reset_vrf);
6797
6798   mp->vrf_id = ntohl (vrf_id);
6799   mp->is_ipv6 = is_ipv6;
6800
6801   S;
6802   W;
6803   /* NOTREACHED */
6804   return 0;
6805 }
6806
6807 static int
6808 api_create_vlan_subif (vat_main_t * vam)
6809 {
6810   unformat_input_t *i = vam->input;
6811   vl_api_create_vlan_subif_t *mp;
6812   f64 timeout;
6813   u32 sw_if_index;
6814   u8 sw_if_index_set = 0;
6815   u32 vlan_id;
6816   u8 vlan_id_set = 0;
6817
6818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6819     {
6820       if (unformat (i, "sw_if_index %d", &sw_if_index))
6821         sw_if_index_set = 1;
6822       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6823         sw_if_index_set = 1;
6824       else if (unformat (i, "vlan %d", &vlan_id))
6825         vlan_id_set = 1;
6826       else
6827         {
6828           clib_warning ("parse error '%U'", format_unformat_error, i);
6829           return -99;
6830         }
6831     }
6832
6833   if (sw_if_index_set == 0)
6834     {
6835       errmsg ("missing interface name or sw_if_index\n");
6836       return -99;
6837     }
6838
6839   if (vlan_id_set == 0)
6840     {
6841       errmsg ("missing vlan_id\n");
6842       return -99;
6843     }
6844   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6845
6846   mp->sw_if_index = ntohl (sw_if_index);
6847   mp->vlan_id = ntohl (vlan_id);
6848
6849   S;
6850   W;
6851   /* NOTREACHED */
6852   return 0;
6853 }
6854
6855 #define foreach_create_subif_bit                \
6856 _(no_tags)                                      \
6857 _(one_tag)                                      \
6858 _(two_tags)                                     \
6859 _(dot1ad)                                       \
6860 _(exact_match)                                  \
6861 _(default_sub)                                  \
6862 _(outer_vlan_id_any)                            \
6863 _(inner_vlan_id_any)
6864
6865 static int
6866 api_create_subif (vat_main_t * vam)
6867 {
6868   unformat_input_t *i = vam->input;
6869   vl_api_create_subif_t *mp;
6870   f64 timeout;
6871   u32 sw_if_index;
6872   u8 sw_if_index_set = 0;
6873   u32 sub_id;
6874   u8 sub_id_set = 0;
6875   u32 no_tags = 0;
6876   u32 one_tag = 0;
6877   u32 two_tags = 0;
6878   u32 dot1ad = 0;
6879   u32 exact_match = 0;
6880   u32 default_sub = 0;
6881   u32 outer_vlan_id_any = 0;
6882   u32 inner_vlan_id_any = 0;
6883   u32 tmp;
6884   u16 outer_vlan_id = 0;
6885   u16 inner_vlan_id = 0;
6886
6887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6888     {
6889       if (unformat (i, "sw_if_index %d", &sw_if_index))
6890         sw_if_index_set = 1;
6891       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6892         sw_if_index_set = 1;
6893       else if (unformat (i, "sub_id %d", &sub_id))
6894         sub_id_set = 1;
6895       else if (unformat (i, "outer_vlan_id %d", &tmp))
6896         outer_vlan_id = tmp;
6897       else if (unformat (i, "inner_vlan_id %d", &tmp))
6898         inner_vlan_id = tmp;
6899
6900 #define _(a) else if (unformat (i, #a)) a = 1 ;
6901       foreach_create_subif_bit
6902 #undef _
6903         else
6904         {
6905           clib_warning ("parse error '%U'", format_unformat_error, i);
6906           return -99;
6907         }
6908     }
6909
6910   if (sw_if_index_set == 0)
6911     {
6912       errmsg ("missing interface name or sw_if_index\n");
6913       return -99;
6914     }
6915
6916   if (sub_id_set == 0)
6917     {
6918       errmsg ("missing sub_id\n");
6919       return -99;
6920     }
6921   M (CREATE_SUBIF, create_subif);
6922
6923   mp->sw_if_index = ntohl (sw_if_index);
6924   mp->sub_id = ntohl (sub_id);
6925
6926 #define _(a) mp->a = a;
6927   foreach_create_subif_bit;
6928 #undef _
6929
6930   mp->outer_vlan_id = ntohs (outer_vlan_id);
6931   mp->inner_vlan_id = ntohs (inner_vlan_id);
6932
6933   S;
6934   W;
6935   /* NOTREACHED */
6936   return 0;
6937 }
6938
6939 static int
6940 api_oam_add_del (vat_main_t * vam)
6941 {
6942   unformat_input_t *i = vam->input;
6943   vl_api_oam_add_del_t *mp;
6944   f64 timeout;
6945   u32 vrf_id = 0;
6946   u8 is_add = 1;
6947   ip4_address_t src, dst;
6948   u8 src_set = 0;
6949   u8 dst_set = 0;
6950
6951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6952     {
6953       if (unformat (i, "vrf %d", &vrf_id))
6954         ;
6955       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6956         src_set = 1;
6957       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6958         dst_set = 1;
6959       else if (unformat (i, "del"))
6960         is_add = 0;
6961       else
6962         {
6963           clib_warning ("parse error '%U'", format_unformat_error, i);
6964           return -99;
6965         }
6966     }
6967
6968   if (src_set == 0)
6969     {
6970       errmsg ("missing src addr\n");
6971       return -99;
6972     }
6973
6974   if (dst_set == 0)
6975     {
6976       errmsg ("missing dst addr\n");
6977       return -99;
6978     }
6979
6980   M (OAM_ADD_DEL, oam_add_del);
6981
6982   mp->vrf_id = ntohl (vrf_id);
6983   mp->is_add = is_add;
6984   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6985   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6986
6987   S;
6988   W;
6989   /* NOTREACHED */
6990   return 0;
6991 }
6992
6993 static int
6994 api_reset_fib (vat_main_t * vam)
6995 {
6996   unformat_input_t *i = vam->input;
6997   vl_api_reset_fib_t *mp;
6998   f64 timeout;
6999   u32 vrf_id = 0;
7000   u8 is_ipv6 = 0;
7001   u8 vrf_id_set = 0;
7002
7003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7004     {
7005       if (unformat (i, "vrf %d", &vrf_id))
7006         vrf_id_set = 1;
7007       else if (unformat (i, "ipv6"))
7008         is_ipv6 = 1;
7009       else
7010         {
7011           clib_warning ("parse error '%U'", format_unformat_error, i);
7012           return -99;
7013         }
7014     }
7015
7016   if (vrf_id_set == 0)
7017     {
7018       errmsg ("missing vrf id\n");
7019       return -99;
7020     }
7021
7022   M (RESET_FIB, reset_fib);
7023
7024   mp->vrf_id = ntohl (vrf_id);
7025   mp->is_ipv6 = is_ipv6;
7026
7027   S;
7028   W;
7029   /* NOTREACHED */
7030   return 0;
7031 }
7032
7033 static int
7034 api_dhcp_proxy_config (vat_main_t * vam)
7035 {
7036   unformat_input_t *i = vam->input;
7037   vl_api_dhcp_proxy_config_t *mp;
7038   f64 timeout;
7039   u32 vrf_id = 0;
7040   u8 is_add = 1;
7041   u8 insert_cid = 1;
7042   u8 v4_address_set = 0;
7043   u8 v6_address_set = 0;
7044   ip4_address_t v4address;
7045   ip6_address_t v6address;
7046   u8 v4_src_address_set = 0;
7047   u8 v6_src_address_set = 0;
7048   ip4_address_t v4srcaddress;
7049   ip6_address_t v6srcaddress;
7050
7051   /* Parse args required to build the message */
7052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7053     {
7054       if (unformat (i, "del"))
7055         is_add = 0;
7056       else if (unformat (i, "vrf %d", &vrf_id))
7057         ;
7058       else if (unformat (i, "insert-cid %d", &insert_cid))
7059         ;
7060       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7061         v4_address_set = 1;
7062       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7063         v6_address_set = 1;
7064       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7065         v4_src_address_set = 1;
7066       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7067         v6_src_address_set = 1;
7068       else
7069         break;
7070     }
7071
7072   if (v4_address_set && v6_address_set)
7073     {
7074       errmsg ("both v4 and v6 server addresses set\n");
7075       return -99;
7076     }
7077   if (!v4_address_set && !v6_address_set)
7078     {
7079       errmsg ("no server addresses set\n");
7080       return -99;
7081     }
7082
7083   if (v4_src_address_set && v6_src_address_set)
7084     {
7085       errmsg ("both v4 and v6  src addresses set\n");
7086       return -99;
7087     }
7088   if (!v4_src_address_set && !v6_src_address_set)
7089     {
7090       errmsg ("no src addresses set\n");
7091       return -99;
7092     }
7093
7094   if (!(v4_src_address_set && v4_address_set) &&
7095       !(v6_src_address_set && v6_address_set))
7096     {
7097       errmsg ("no matching server and src addresses set\n");
7098       return -99;
7099     }
7100
7101   /* Construct the API message */
7102   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7103
7104   mp->insert_circuit_id = insert_cid;
7105   mp->is_add = is_add;
7106   mp->vrf_id = ntohl (vrf_id);
7107   if (v6_address_set)
7108     {
7109       mp->is_ipv6 = 1;
7110       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7111       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7112     }
7113   else
7114     {
7115       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7116       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7117     }
7118
7119   /* send it... */
7120   S;
7121
7122   /* Wait for a reply, return good/bad news  */
7123   W;
7124   /* NOTREACHED */
7125   return 0;
7126 }
7127
7128 static int
7129 api_dhcp_proxy_config_2 (vat_main_t * vam)
7130 {
7131   unformat_input_t *i = vam->input;
7132   vl_api_dhcp_proxy_config_2_t *mp;
7133   f64 timeout;
7134   u32 rx_vrf_id = 0;
7135   u32 server_vrf_id = 0;
7136   u8 is_add = 1;
7137   u8 insert_cid = 1;
7138   u8 v4_address_set = 0;
7139   u8 v6_address_set = 0;
7140   ip4_address_t v4address;
7141   ip6_address_t v6address;
7142   u8 v4_src_address_set = 0;
7143   u8 v6_src_address_set = 0;
7144   ip4_address_t v4srcaddress;
7145   ip6_address_t v6srcaddress;
7146
7147   /* Parse args required to build the message */
7148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7149     {
7150       if (unformat (i, "del"))
7151         is_add = 0;
7152       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7153         ;
7154       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7155         ;
7156       else if (unformat (i, "insert-cid %d", &insert_cid))
7157         ;
7158       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7159         v4_address_set = 1;
7160       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7161         v6_address_set = 1;
7162       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7163         v4_src_address_set = 1;
7164       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7165         v6_src_address_set = 1;
7166       else
7167         break;
7168     }
7169
7170   if (v4_address_set && v6_address_set)
7171     {
7172       errmsg ("both v4 and v6 server addresses set\n");
7173       return -99;
7174     }
7175   if (!v4_address_set && !v6_address_set)
7176     {
7177       errmsg ("no server addresses set\n");
7178       return -99;
7179     }
7180
7181   if (v4_src_address_set && v6_src_address_set)
7182     {
7183       errmsg ("both v4 and v6  src addresses set\n");
7184       return -99;
7185     }
7186   if (!v4_src_address_set && !v6_src_address_set)
7187     {
7188       errmsg ("no src addresses set\n");
7189       return -99;
7190     }
7191
7192   if (!(v4_src_address_set && v4_address_set) &&
7193       !(v6_src_address_set && v6_address_set))
7194     {
7195       errmsg ("no matching server and src addresses set\n");
7196       return -99;
7197     }
7198
7199   /* Construct the API message */
7200   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7201
7202   mp->insert_circuit_id = insert_cid;
7203   mp->is_add = is_add;
7204   mp->rx_vrf_id = ntohl (rx_vrf_id);
7205   mp->server_vrf_id = ntohl (server_vrf_id);
7206   if (v6_address_set)
7207     {
7208       mp->is_ipv6 = 1;
7209       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7210       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7211     }
7212   else
7213     {
7214       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7215       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7216     }
7217
7218   /* send it... */
7219   S;
7220
7221   /* Wait for a reply, return good/bad news  */
7222   W;
7223   /* NOTREACHED */
7224   return 0;
7225 }
7226
7227 static int
7228 api_dhcp_proxy_set_vss (vat_main_t * vam)
7229 {
7230   unformat_input_t *i = vam->input;
7231   vl_api_dhcp_proxy_set_vss_t *mp;
7232   f64 timeout;
7233   u8 is_ipv6 = 0;
7234   u8 is_add = 1;
7235   u32 tbl_id;
7236   u8 tbl_id_set = 0;
7237   u32 oui;
7238   u8 oui_set = 0;
7239   u32 fib_id;
7240   u8 fib_id_set = 0;
7241
7242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7243     {
7244       if (unformat (i, "tbl_id %d", &tbl_id))
7245         tbl_id_set = 1;
7246       if (unformat (i, "fib_id %d", &fib_id))
7247         fib_id_set = 1;
7248       if (unformat (i, "oui %d", &oui))
7249         oui_set = 1;
7250       else if (unformat (i, "ipv6"))
7251         is_ipv6 = 1;
7252       else if (unformat (i, "del"))
7253         is_add = 0;
7254       else
7255         {
7256           clib_warning ("parse error '%U'", format_unformat_error, i);
7257           return -99;
7258         }
7259     }
7260
7261   if (tbl_id_set == 0)
7262     {
7263       errmsg ("missing tbl id\n");
7264       return -99;
7265     }
7266
7267   if (fib_id_set == 0)
7268     {
7269       errmsg ("missing fib id\n");
7270       return -99;
7271     }
7272   if (oui_set == 0)
7273     {
7274       errmsg ("missing oui\n");
7275       return -99;
7276     }
7277
7278   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7279   mp->tbl_id = ntohl (tbl_id);
7280   mp->fib_id = ntohl (fib_id);
7281   mp->oui = ntohl (oui);
7282   mp->is_ipv6 = is_ipv6;
7283   mp->is_add = is_add;
7284
7285   S;
7286   W;
7287   /* NOTREACHED */
7288   return 0;
7289 }
7290
7291 static int
7292 api_dhcp_client_config (vat_main_t * vam)
7293 {
7294   unformat_input_t *i = vam->input;
7295   vl_api_dhcp_client_config_t *mp;
7296   f64 timeout;
7297   u32 sw_if_index;
7298   u8 sw_if_index_set = 0;
7299   u8 is_add = 1;
7300   u8 *hostname = 0;
7301   u8 disable_event = 0;
7302
7303   /* Parse args required to build the message */
7304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7305     {
7306       if (unformat (i, "del"))
7307         is_add = 0;
7308       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7309         sw_if_index_set = 1;
7310       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7311         sw_if_index_set = 1;
7312       else if (unformat (i, "hostname %s", &hostname))
7313         ;
7314       else if (unformat (i, "disable_event"))
7315         disable_event = 1;
7316       else
7317         break;
7318     }
7319
7320   if (sw_if_index_set == 0)
7321     {
7322       errmsg ("missing interface name or sw_if_index\n");
7323       return -99;
7324     }
7325
7326   if (vec_len (hostname) > 63)
7327     {
7328       errmsg ("hostname too long\n");
7329     }
7330   vec_add1 (hostname, 0);
7331
7332   /* Construct the API message */
7333   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7334
7335   mp->sw_if_index = ntohl (sw_if_index);
7336   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7337   vec_free (hostname);
7338   mp->is_add = is_add;
7339   mp->want_dhcp_event = disable_event ? 0 : 1;
7340   mp->pid = getpid ();
7341
7342   /* send it... */
7343   S;
7344
7345   /* Wait for a reply, return good/bad news  */
7346   W;
7347   /* NOTREACHED */
7348   return 0;
7349 }
7350
7351 static int
7352 api_set_ip_flow_hash (vat_main_t * vam)
7353 {
7354   unformat_input_t *i = vam->input;
7355   vl_api_set_ip_flow_hash_t *mp;
7356   f64 timeout;
7357   u32 vrf_id = 0;
7358   u8 is_ipv6 = 0;
7359   u8 vrf_id_set = 0;
7360   u8 src = 0;
7361   u8 dst = 0;
7362   u8 sport = 0;
7363   u8 dport = 0;
7364   u8 proto = 0;
7365   u8 reverse = 0;
7366
7367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7368     {
7369       if (unformat (i, "vrf %d", &vrf_id))
7370         vrf_id_set = 1;
7371       else if (unformat (i, "ipv6"))
7372         is_ipv6 = 1;
7373       else if (unformat (i, "src"))
7374         src = 1;
7375       else if (unformat (i, "dst"))
7376         dst = 1;
7377       else if (unformat (i, "sport"))
7378         sport = 1;
7379       else if (unformat (i, "dport"))
7380         dport = 1;
7381       else if (unformat (i, "proto"))
7382         proto = 1;
7383       else if (unformat (i, "reverse"))
7384         reverse = 1;
7385
7386       else
7387         {
7388           clib_warning ("parse error '%U'", format_unformat_error, i);
7389           return -99;
7390         }
7391     }
7392
7393   if (vrf_id_set == 0)
7394     {
7395       errmsg ("missing vrf id\n");
7396       return -99;
7397     }
7398
7399   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7400   mp->src = src;
7401   mp->dst = dst;
7402   mp->sport = sport;
7403   mp->dport = dport;
7404   mp->proto = proto;
7405   mp->reverse = reverse;
7406   mp->vrf_id = ntohl (vrf_id);
7407   mp->is_ipv6 = is_ipv6;
7408
7409   S;
7410   W;
7411   /* NOTREACHED */
7412   return 0;
7413 }
7414
7415 static int
7416 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7417 {
7418   unformat_input_t *i = vam->input;
7419   vl_api_sw_interface_ip6_enable_disable_t *mp;
7420   f64 timeout;
7421   u32 sw_if_index;
7422   u8 sw_if_index_set = 0;
7423   u8 enable = 0;
7424
7425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7426     {
7427       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7428         sw_if_index_set = 1;
7429       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7430         sw_if_index_set = 1;
7431       else if (unformat (i, "enable"))
7432         enable = 1;
7433       else if (unformat (i, "disable"))
7434         enable = 0;
7435       else
7436         {
7437           clib_warning ("parse error '%U'", format_unformat_error, i);
7438           return -99;
7439         }
7440     }
7441
7442   if (sw_if_index_set == 0)
7443     {
7444       errmsg ("missing interface name or sw_if_index\n");
7445       return -99;
7446     }
7447
7448   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7449
7450   mp->sw_if_index = ntohl (sw_if_index);
7451   mp->enable = enable;
7452
7453   S;
7454   W;
7455   /* NOTREACHED */
7456   return 0;
7457 }
7458
7459 static int
7460 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7461 {
7462   unformat_input_t *i = vam->input;
7463   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7464   f64 timeout;
7465   u32 sw_if_index;
7466   u8 sw_if_index_set = 0;
7467   u32 address_length = 0;
7468   u8 v6_address_set = 0;
7469   ip6_address_t v6address;
7470
7471   /* Parse args required to build the message */
7472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7473     {
7474       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7475         sw_if_index_set = 1;
7476       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7477         sw_if_index_set = 1;
7478       else if (unformat (i, "%U/%d",
7479                          unformat_ip6_address, &v6address, &address_length))
7480         v6_address_set = 1;
7481       else
7482         break;
7483     }
7484
7485   if (sw_if_index_set == 0)
7486     {
7487       errmsg ("missing interface name or sw_if_index\n");
7488       return -99;
7489     }
7490   if (!v6_address_set)
7491     {
7492       errmsg ("no address set\n");
7493       return -99;
7494     }
7495
7496   /* Construct the API message */
7497   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7498      sw_interface_ip6_set_link_local_address);
7499
7500   mp->sw_if_index = ntohl (sw_if_index);
7501   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7502   mp->address_length = address_length;
7503
7504   /* send it... */
7505   S;
7506
7507   /* Wait for a reply, return good/bad news  */
7508   W;
7509
7510   /* NOTREACHED */
7511   return 0;
7512 }
7513
7514
7515 static int
7516 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7517 {
7518   unformat_input_t *i = vam->input;
7519   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7520   f64 timeout;
7521   u32 sw_if_index;
7522   u8 sw_if_index_set = 0;
7523   u32 address_length = 0;
7524   u8 v6_address_set = 0;
7525   ip6_address_t v6address;
7526   u8 use_default = 0;
7527   u8 no_advertise = 0;
7528   u8 off_link = 0;
7529   u8 no_autoconfig = 0;
7530   u8 no_onlink = 0;
7531   u8 is_no = 0;
7532   u32 val_lifetime = 0;
7533   u32 pref_lifetime = 0;
7534
7535   /* Parse args required to build the message */
7536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7537     {
7538       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7539         sw_if_index_set = 1;
7540       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7541         sw_if_index_set = 1;
7542       else if (unformat (i, "%U/%d",
7543                          unformat_ip6_address, &v6address, &address_length))
7544         v6_address_set = 1;
7545       else if (unformat (i, "val_life %d", &val_lifetime))
7546         ;
7547       else if (unformat (i, "pref_life %d", &pref_lifetime))
7548         ;
7549       else if (unformat (i, "def"))
7550         use_default = 1;
7551       else if (unformat (i, "noadv"))
7552         no_advertise = 1;
7553       else if (unformat (i, "offl"))
7554         off_link = 1;
7555       else if (unformat (i, "noauto"))
7556         no_autoconfig = 1;
7557       else if (unformat (i, "nolink"))
7558         no_onlink = 1;
7559       else if (unformat (i, "isno"))
7560         is_no = 1;
7561       else
7562         {
7563           clib_warning ("parse error '%U'", format_unformat_error, i);
7564           return -99;
7565         }
7566     }
7567
7568   if (sw_if_index_set == 0)
7569     {
7570       errmsg ("missing interface name or sw_if_index\n");
7571       return -99;
7572     }
7573   if (!v6_address_set)
7574     {
7575       errmsg ("no address set\n");
7576       return -99;
7577     }
7578
7579   /* Construct the API message */
7580   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7581
7582   mp->sw_if_index = ntohl (sw_if_index);
7583   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7584   mp->address_length = address_length;
7585   mp->use_default = use_default;
7586   mp->no_advertise = no_advertise;
7587   mp->off_link = off_link;
7588   mp->no_autoconfig = no_autoconfig;
7589   mp->no_onlink = no_onlink;
7590   mp->is_no = is_no;
7591   mp->val_lifetime = ntohl (val_lifetime);
7592   mp->pref_lifetime = ntohl (pref_lifetime);
7593
7594   /* send it... */
7595   S;
7596
7597   /* Wait for a reply, return good/bad news  */
7598   W;
7599
7600   /* NOTREACHED */
7601   return 0;
7602 }
7603
7604 static int
7605 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7606 {
7607   unformat_input_t *i = vam->input;
7608   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7609   f64 timeout;
7610   u32 sw_if_index;
7611   u8 sw_if_index_set = 0;
7612   u8 suppress = 0;
7613   u8 managed = 0;
7614   u8 other = 0;
7615   u8 ll_option = 0;
7616   u8 send_unicast = 0;
7617   u8 cease = 0;
7618   u8 is_no = 0;
7619   u8 default_router = 0;
7620   u32 max_interval = 0;
7621   u32 min_interval = 0;
7622   u32 lifetime = 0;
7623   u32 initial_count = 0;
7624   u32 initial_interval = 0;
7625
7626
7627   /* Parse args required to build the message */
7628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7629     {
7630       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7631         sw_if_index_set = 1;
7632       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7633         sw_if_index_set = 1;
7634       else if (unformat (i, "maxint %d", &max_interval))
7635         ;
7636       else if (unformat (i, "minint %d", &min_interval))
7637         ;
7638       else if (unformat (i, "life %d", &lifetime))
7639         ;
7640       else if (unformat (i, "count %d", &initial_count))
7641         ;
7642       else if (unformat (i, "interval %d", &initial_interval))
7643         ;
7644       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7645         suppress = 1;
7646       else if (unformat (i, "managed"))
7647         managed = 1;
7648       else if (unformat (i, "other"))
7649         other = 1;
7650       else if (unformat (i, "ll"))
7651         ll_option = 1;
7652       else if (unformat (i, "send"))
7653         send_unicast = 1;
7654       else if (unformat (i, "cease"))
7655         cease = 1;
7656       else if (unformat (i, "isno"))
7657         is_no = 1;
7658       else if (unformat (i, "def"))
7659         default_router = 1;
7660       else
7661         {
7662           clib_warning ("parse error '%U'", format_unformat_error, i);
7663           return -99;
7664         }
7665     }
7666
7667   if (sw_if_index_set == 0)
7668     {
7669       errmsg ("missing interface name or sw_if_index\n");
7670       return -99;
7671     }
7672
7673   /* Construct the API message */
7674   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7675
7676   mp->sw_if_index = ntohl (sw_if_index);
7677   mp->max_interval = ntohl (max_interval);
7678   mp->min_interval = ntohl (min_interval);
7679   mp->lifetime = ntohl (lifetime);
7680   mp->initial_count = ntohl (initial_count);
7681   mp->initial_interval = ntohl (initial_interval);
7682   mp->suppress = suppress;
7683   mp->managed = managed;
7684   mp->other = other;
7685   mp->ll_option = ll_option;
7686   mp->send_unicast = send_unicast;
7687   mp->cease = cease;
7688   mp->is_no = is_no;
7689   mp->default_router = default_router;
7690
7691   /* send it... */
7692   S;
7693
7694   /* Wait for a reply, return good/bad news  */
7695   W;
7696
7697   /* NOTREACHED */
7698   return 0;
7699 }
7700
7701 static int
7702 api_set_arp_neighbor_limit (vat_main_t * vam)
7703 {
7704   unformat_input_t *i = vam->input;
7705   vl_api_set_arp_neighbor_limit_t *mp;
7706   f64 timeout;
7707   u32 arp_nbr_limit;
7708   u8 limit_set = 0;
7709   u8 is_ipv6 = 0;
7710
7711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7712     {
7713       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7714         limit_set = 1;
7715       else if (unformat (i, "ipv6"))
7716         is_ipv6 = 1;
7717       else
7718         {
7719           clib_warning ("parse error '%U'", format_unformat_error, i);
7720           return -99;
7721         }
7722     }
7723
7724   if (limit_set == 0)
7725     {
7726       errmsg ("missing limit value\n");
7727       return -99;
7728     }
7729
7730   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7731
7732   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7733   mp->is_ipv6 = is_ipv6;
7734
7735   S;
7736   W;
7737   /* NOTREACHED */
7738   return 0;
7739 }
7740
7741 static int
7742 api_l2_patch_add_del (vat_main_t * vam)
7743 {
7744   unformat_input_t *i = vam->input;
7745   vl_api_l2_patch_add_del_t *mp;
7746   f64 timeout;
7747   u32 rx_sw_if_index;
7748   u8 rx_sw_if_index_set = 0;
7749   u32 tx_sw_if_index;
7750   u8 tx_sw_if_index_set = 0;
7751   u8 is_add = 1;
7752
7753   /* Parse args required to build the message */
7754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7755     {
7756       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7757         rx_sw_if_index_set = 1;
7758       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7759         tx_sw_if_index_set = 1;
7760       else if (unformat (i, "rx"))
7761         {
7762           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7763             {
7764               if (unformat (i, "%U", unformat_sw_if_index, vam,
7765                             &rx_sw_if_index))
7766                 rx_sw_if_index_set = 1;
7767             }
7768           else
7769             break;
7770         }
7771       else if (unformat (i, "tx"))
7772         {
7773           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7774             {
7775               if (unformat (i, "%U", unformat_sw_if_index, vam,
7776                             &tx_sw_if_index))
7777                 tx_sw_if_index_set = 1;
7778             }
7779           else
7780             break;
7781         }
7782       else if (unformat (i, "del"))
7783         is_add = 0;
7784       else
7785         break;
7786     }
7787
7788   if (rx_sw_if_index_set == 0)
7789     {
7790       errmsg ("missing rx interface name or rx_sw_if_index\n");
7791       return -99;
7792     }
7793
7794   if (tx_sw_if_index_set == 0)
7795     {
7796       errmsg ("missing tx interface name or tx_sw_if_index\n");
7797       return -99;
7798     }
7799
7800   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7801
7802   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7803   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7804   mp->is_add = is_add;
7805
7806   S;
7807   W;
7808   /* NOTREACHED */
7809   return 0;
7810 }
7811
7812 static int
7813 api_ioam_enable (vat_main_t * vam)
7814 {
7815   unformat_input_t *input = vam->input;
7816   vl_api_ioam_enable_t *mp;
7817   f64 timeout;
7818   u32 id = 0;
7819   int has_trace_option = 0;
7820   int has_pot_option = 0;
7821   int has_seqno_option = 0;
7822   int has_analyse_option = 0;
7823
7824   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7825     {
7826       if (unformat (input, "trace"))
7827         has_trace_option = 1;
7828       else if (unformat (input, "pot"))
7829         has_pot_option = 1;
7830       else if (unformat (input, "seqno"))
7831         has_seqno_option = 1;
7832       else if (unformat (input, "analyse"))
7833         has_analyse_option = 1;
7834       else
7835         break;
7836     }
7837   M (IOAM_ENABLE, ioam_enable);
7838   mp->id = htons (id);
7839   mp->seqno = has_seqno_option;
7840   mp->analyse = has_analyse_option;
7841   mp->pot_enable = has_pot_option;
7842   mp->trace_enable = has_trace_option;
7843
7844   S;
7845   W;
7846
7847   return (0);
7848
7849 }
7850
7851
7852 static int
7853 api_ioam_disable (vat_main_t * vam)
7854 {
7855   vl_api_ioam_disable_t *mp;
7856   f64 timeout;
7857
7858   M (IOAM_DISABLE, ioam_disable);
7859   S;
7860   W;
7861   return 0;
7862 }
7863
7864 static int
7865 api_sr_tunnel_add_del (vat_main_t * vam)
7866 {
7867   unformat_input_t *i = vam->input;
7868   vl_api_sr_tunnel_add_del_t *mp;
7869   f64 timeout;
7870   int is_del = 0;
7871   int pl_index;
7872   ip6_address_t src_address;
7873   int src_address_set = 0;
7874   ip6_address_t dst_address;
7875   u32 dst_mask_width;
7876   int dst_address_set = 0;
7877   u16 flags = 0;
7878   u32 rx_table_id = 0;
7879   u32 tx_table_id = 0;
7880   ip6_address_t *segments = 0;
7881   ip6_address_t *this_seg;
7882   ip6_address_t *tags = 0;
7883   ip6_address_t *this_tag;
7884   ip6_address_t next_address, tag;
7885   u8 *name = 0;
7886   u8 *policy_name = 0;
7887
7888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7889     {
7890       if (unformat (i, "del"))
7891         is_del = 1;
7892       else if (unformat (i, "name %s", &name))
7893         ;
7894       else if (unformat (i, "policy %s", &policy_name))
7895         ;
7896       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7897         ;
7898       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7899         ;
7900       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7901         src_address_set = 1;
7902       else if (unformat (i, "dst %U/%d",
7903                          unformat_ip6_address, &dst_address, &dst_mask_width))
7904         dst_address_set = 1;
7905       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7906         {
7907           vec_add2 (segments, this_seg, 1);
7908           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7909                        sizeof (*this_seg));
7910         }
7911       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7912         {
7913           vec_add2 (tags, this_tag, 1);
7914           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7915         }
7916       else if (unformat (i, "clean"))
7917         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7918       else if (unformat (i, "protected"))
7919         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7920       else if (unformat (i, "InPE %d", &pl_index))
7921         {
7922           if (pl_index <= 0 || pl_index > 4)
7923             {
7924             pl_index_range_error:
7925               errmsg ("pl index %d out of range\n", pl_index);
7926               return -99;
7927             }
7928           flags |=
7929             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7930         }
7931       else if (unformat (i, "EgPE %d", &pl_index))
7932         {
7933           if (pl_index <= 0 || pl_index > 4)
7934             goto pl_index_range_error;
7935           flags |=
7936             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7937         }
7938       else if (unformat (i, "OrgSrc %d", &pl_index))
7939         {
7940           if (pl_index <= 0 || pl_index > 4)
7941             goto pl_index_range_error;
7942           flags |=
7943             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7944         }
7945       else
7946         break;
7947     }
7948
7949   if (!src_address_set)
7950     {
7951       errmsg ("src address required\n");
7952       return -99;
7953     }
7954
7955   if (!dst_address_set)
7956     {
7957       errmsg ("dst address required\n");
7958       return -99;
7959     }
7960
7961   if (!segments)
7962     {
7963       errmsg ("at least one sr segment required\n");
7964       return -99;
7965     }
7966
7967   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7968       vec_len (segments) * sizeof (ip6_address_t)
7969       + vec_len (tags) * sizeof (ip6_address_t));
7970
7971   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7972   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7973   mp->dst_mask_width = dst_mask_width;
7974   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7975   mp->n_segments = vec_len (segments);
7976   mp->n_tags = vec_len (tags);
7977   mp->is_add = is_del == 0;
7978   clib_memcpy (mp->segs_and_tags, segments,
7979                vec_len (segments) * sizeof (ip6_address_t));
7980   clib_memcpy (mp->segs_and_tags +
7981                vec_len (segments) * sizeof (ip6_address_t), tags,
7982                vec_len (tags) * sizeof (ip6_address_t));
7983
7984   mp->outer_vrf_id = ntohl (rx_table_id);
7985   mp->inner_vrf_id = ntohl (tx_table_id);
7986   memcpy (mp->name, name, vec_len (name));
7987   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7988
7989   vec_free (segments);
7990   vec_free (tags);
7991
7992   S;
7993   W;
7994   /* NOTREACHED */
7995 }
7996
7997 static int
7998 api_sr_policy_add_del (vat_main_t * vam)
7999 {
8000   unformat_input_t *input = vam->input;
8001   vl_api_sr_policy_add_del_t *mp;
8002   f64 timeout;
8003   int is_del = 0;
8004   u8 *name = 0;
8005   u8 *tunnel_name = 0;
8006   u8 **tunnel_names = 0;
8007
8008   int name_set = 0;
8009   int tunnel_set = 0;
8010   int j = 0;
8011   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8012   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8013
8014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8015     {
8016       if (unformat (input, "del"))
8017         is_del = 1;
8018       else if (unformat (input, "name %s", &name))
8019         name_set = 1;
8020       else if (unformat (input, "tunnel %s", &tunnel_name))
8021         {
8022           if (tunnel_name)
8023             {
8024               vec_add1 (tunnel_names, tunnel_name);
8025               /* For serializer:
8026                  - length = #bytes to store in serial vector
8027                  - +1 = byte to store that length
8028                */
8029               tunnel_names_length += (vec_len (tunnel_name) + 1);
8030               tunnel_set = 1;
8031               tunnel_name = 0;
8032             }
8033         }
8034       else
8035         break;
8036     }
8037
8038   if (!name_set)
8039     {
8040       errmsg ("policy name required\n");
8041       return -99;
8042     }
8043
8044   if ((!tunnel_set) && (!is_del))
8045     {
8046       errmsg ("tunnel name required\n");
8047       return -99;
8048     }
8049
8050   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8051
8052
8053
8054   mp->is_add = !is_del;
8055
8056   memcpy (mp->name, name, vec_len (name));
8057   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8058   u8 *serial_orig = 0;
8059   vec_validate (serial_orig, tunnel_names_length);
8060   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8061   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8062
8063   for (j = 0; j < vec_len (tunnel_names); j++)
8064     {
8065       tun_name_len = vec_len (tunnel_names[j]);
8066       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8067       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8068       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8069       serial_orig += tun_name_len;      // Advance past the copy
8070     }
8071   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8072
8073   vec_free (tunnel_names);
8074   vec_free (tunnel_name);
8075
8076   S;
8077   W;
8078   /* NOTREACHED */
8079 }
8080
8081 static int
8082 api_sr_multicast_map_add_del (vat_main_t * vam)
8083 {
8084   unformat_input_t *input = vam->input;
8085   vl_api_sr_multicast_map_add_del_t *mp;
8086   f64 timeout;
8087   int is_del = 0;
8088   ip6_address_t multicast_address;
8089   u8 *policy_name = 0;
8090   int multicast_address_set = 0;
8091
8092   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8093     {
8094       if (unformat (input, "del"))
8095         is_del = 1;
8096       else
8097         if (unformat
8098             (input, "address %U", unformat_ip6_address, &multicast_address))
8099         multicast_address_set = 1;
8100       else if (unformat (input, "sr-policy %s", &policy_name))
8101         ;
8102       else
8103         break;
8104     }
8105
8106   if (!is_del && !policy_name)
8107     {
8108       errmsg ("sr-policy name required\n");
8109       return -99;
8110     }
8111
8112
8113   if (!multicast_address_set)
8114     {
8115       errmsg ("address required\n");
8116       return -99;
8117     }
8118
8119   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8120
8121   mp->is_add = !is_del;
8122   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8123   clib_memcpy (mp->multicast_address, &multicast_address,
8124                sizeof (mp->multicast_address));
8125
8126
8127   vec_free (policy_name);
8128
8129   S;
8130   W;
8131   /* NOTREACHED */
8132 }
8133
8134
8135 #define foreach_tcp_proto_field                 \
8136 _(src_port)                                     \
8137 _(dst_port)
8138
8139 #define foreach_udp_proto_field                 \
8140 _(src_port)                                     \
8141 _(dst_port)
8142
8143 #define foreach_ip4_proto_field                 \
8144 _(src_address)                                  \
8145 _(dst_address)                                  \
8146 _(tos)                                          \
8147 _(length)                                       \
8148 _(fragment_id)                                  \
8149 _(ttl)                                          \
8150 _(protocol)                                     \
8151 _(checksum)
8152
8153 uword
8154 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8155 {
8156   u8 **maskp = va_arg (*args, u8 **);
8157   u8 *mask = 0;
8158   u8 found_something = 0;
8159   tcp_header_t *tcp;
8160
8161 #define _(a) u8 a=0;
8162   foreach_tcp_proto_field;
8163 #undef _
8164
8165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8166     {
8167       if (0);
8168 #define _(a) else if (unformat (input, #a)) a=1;
8169       foreach_tcp_proto_field
8170 #undef _
8171         else
8172         break;
8173     }
8174
8175 #define _(a) found_something += a;
8176   foreach_tcp_proto_field;
8177 #undef _
8178
8179   if (found_something == 0)
8180     return 0;
8181
8182   vec_validate (mask, sizeof (*tcp) - 1);
8183
8184   tcp = (tcp_header_t *) mask;
8185
8186 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8187   foreach_tcp_proto_field;
8188 #undef _
8189
8190   *maskp = mask;
8191   return 1;
8192 }
8193
8194 uword
8195 unformat_udp_mask (unformat_input_t * input, va_list * args)
8196 {
8197   u8 **maskp = va_arg (*args, u8 **);
8198   u8 *mask = 0;
8199   u8 found_something = 0;
8200   udp_header_t *udp;
8201
8202 #define _(a) u8 a=0;
8203   foreach_udp_proto_field;
8204 #undef _
8205
8206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8207     {
8208       if (0);
8209 #define _(a) else if (unformat (input, #a)) a=1;
8210       foreach_udp_proto_field
8211 #undef _
8212         else
8213         break;
8214     }
8215
8216 #define _(a) found_something += a;
8217   foreach_udp_proto_field;
8218 #undef _
8219
8220   if (found_something == 0)
8221     return 0;
8222
8223   vec_validate (mask, sizeof (*udp) - 1);
8224
8225   udp = (udp_header_t *) mask;
8226
8227 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8228   foreach_udp_proto_field;
8229 #undef _
8230
8231   *maskp = mask;
8232   return 1;
8233 }
8234
8235 typedef struct
8236 {
8237   u16 src_port, dst_port;
8238 } tcpudp_header_t;
8239
8240 uword
8241 unformat_l4_mask (unformat_input_t * input, va_list * args)
8242 {
8243   u8 **maskp = va_arg (*args, u8 **);
8244   u16 src_port = 0, dst_port = 0;
8245   tcpudp_header_t *tcpudp;
8246
8247   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8248     {
8249       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8250         return 1;
8251       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8252         return 1;
8253       else if (unformat (input, "src_port"))
8254         src_port = 0xFFFF;
8255       else if (unformat (input, "dst_port"))
8256         dst_port = 0xFFFF;
8257       else
8258         return 0;
8259     }
8260
8261   if (!src_port && !dst_port)
8262     return 0;
8263
8264   u8 *mask = 0;
8265   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8266
8267   tcpudp = (tcpudp_header_t *) mask;
8268   tcpudp->src_port = src_port;
8269   tcpudp->dst_port = dst_port;
8270
8271   *maskp = mask;
8272
8273   return 1;
8274 }
8275
8276 uword
8277 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8278 {
8279   u8 **maskp = va_arg (*args, u8 **);
8280   u8 *mask = 0;
8281   u8 found_something = 0;
8282   ip4_header_t *ip;
8283
8284 #define _(a) u8 a=0;
8285   foreach_ip4_proto_field;
8286 #undef _
8287   u8 version = 0;
8288   u8 hdr_length = 0;
8289
8290
8291   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8292     {
8293       if (unformat (input, "version"))
8294         version = 1;
8295       else if (unformat (input, "hdr_length"))
8296         hdr_length = 1;
8297       else if (unformat (input, "src"))
8298         src_address = 1;
8299       else if (unformat (input, "dst"))
8300         dst_address = 1;
8301       else if (unformat (input, "proto"))
8302         protocol = 1;
8303
8304 #define _(a) else if (unformat (input, #a)) a=1;
8305       foreach_ip4_proto_field
8306 #undef _
8307         else
8308         break;
8309     }
8310
8311 #define _(a) found_something += a;
8312   foreach_ip4_proto_field;
8313 #undef _
8314
8315   if (found_something == 0)
8316     return 0;
8317
8318   vec_validate (mask, sizeof (*ip) - 1);
8319
8320   ip = (ip4_header_t *) mask;
8321
8322 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8323   foreach_ip4_proto_field;
8324 #undef _
8325
8326   ip->ip_version_and_header_length = 0;
8327
8328   if (version)
8329     ip->ip_version_and_header_length |= 0xF0;
8330
8331   if (hdr_length)
8332     ip->ip_version_and_header_length |= 0x0F;
8333
8334   *maskp = mask;
8335   return 1;
8336 }
8337
8338 #define foreach_ip6_proto_field                 \
8339 _(src_address)                                  \
8340 _(dst_address)                                  \
8341 _(payload_length)                               \
8342 _(hop_limit)                                    \
8343 _(protocol)
8344
8345 uword
8346 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8347 {
8348   u8 **maskp = va_arg (*args, u8 **);
8349   u8 *mask = 0;
8350   u8 found_something = 0;
8351   ip6_header_t *ip;
8352   u32 ip_version_traffic_class_and_flow_label;
8353
8354 #define _(a) u8 a=0;
8355   foreach_ip6_proto_field;
8356 #undef _
8357   u8 version = 0;
8358   u8 traffic_class = 0;
8359   u8 flow_label = 0;
8360
8361   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8362     {
8363       if (unformat (input, "version"))
8364         version = 1;
8365       else if (unformat (input, "traffic-class"))
8366         traffic_class = 1;
8367       else if (unformat (input, "flow-label"))
8368         flow_label = 1;
8369       else if (unformat (input, "src"))
8370         src_address = 1;
8371       else if (unformat (input, "dst"))
8372         dst_address = 1;
8373       else if (unformat (input, "proto"))
8374         protocol = 1;
8375
8376 #define _(a) else if (unformat (input, #a)) a=1;
8377       foreach_ip6_proto_field
8378 #undef _
8379         else
8380         break;
8381     }
8382
8383 #define _(a) found_something += a;
8384   foreach_ip6_proto_field;
8385 #undef _
8386
8387   if (found_something == 0)
8388     return 0;
8389
8390   vec_validate (mask, sizeof (*ip) - 1);
8391
8392   ip = (ip6_header_t *) mask;
8393
8394 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8395   foreach_ip6_proto_field;
8396 #undef _
8397
8398   ip_version_traffic_class_and_flow_label = 0;
8399
8400   if (version)
8401     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8402
8403   if (traffic_class)
8404     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8405
8406   if (flow_label)
8407     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8408
8409   ip->ip_version_traffic_class_and_flow_label =
8410     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8411
8412   *maskp = mask;
8413   return 1;
8414 }
8415
8416 uword
8417 unformat_l3_mask (unformat_input_t * input, va_list * args)
8418 {
8419   u8 **maskp = va_arg (*args, u8 **);
8420
8421   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8422     {
8423       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8424         return 1;
8425       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8426         return 1;
8427       else
8428         break;
8429     }
8430   return 0;
8431 }
8432
8433 uword
8434 unformat_l2_mask (unformat_input_t * input, va_list * args)
8435 {
8436   u8 **maskp = va_arg (*args, u8 **);
8437   u8 *mask = 0;
8438   u8 src = 0;
8439   u8 dst = 0;
8440   u8 proto = 0;
8441   u8 tag1 = 0;
8442   u8 tag2 = 0;
8443   u8 ignore_tag1 = 0;
8444   u8 ignore_tag2 = 0;
8445   u8 cos1 = 0;
8446   u8 cos2 = 0;
8447   u8 dot1q = 0;
8448   u8 dot1ad = 0;
8449   int len = 14;
8450
8451   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8452     {
8453       if (unformat (input, "src"))
8454         src = 1;
8455       else if (unformat (input, "dst"))
8456         dst = 1;
8457       else if (unformat (input, "proto"))
8458         proto = 1;
8459       else if (unformat (input, "tag1"))
8460         tag1 = 1;
8461       else if (unformat (input, "tag2"))
8462         tag2 = 1;
8463       else if (unformat (input, "ignore-tag1"))
8464         ignore_tag1 = 1;
8465       else if (unformat (input, "ignore-tag2"))
8466         ignore_tag2 = 1;
8467       else if (unformat (input, "cos1"))
8468         cos1 = 1;
8469       else if (unformat (input, "cos2"))
8470         cos2 = 1;
8471       else if (unformat (input, "dot1q"))
8472         dot1q = 1;
8473       else if (unformat (input, "dot1ad"))
8474         dot1ad = 1;
8475       else
8476         break;
8477     }
8478   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8479        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8480     return 0;
8481
8482   if (tag1 || ignore_tag1 || cos1 || dot1q)
8483     len = 18;
8484   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8485     len = 22;
8486
8487   vec_validate (mask, len - 1);
8488
8489   if (dst)
8490     memset (mask, 0xff, 6);
8491
8492   if (src)
8493     memset (mask + 6, 0xff, 6);
8494
8495   if (tag2 || dot1ad)
8496     {
8497       /* inner vlan tag */
8498       if (tag2)
8499         {
8500           mask[19] = 0xff;
8501           mask[18] = 0x0f;
8502         }
8503       if (cos2)
8504         mask[18] |= 0xe0;
8505       if (proto)
8506         mask[21] = mask[20] = 0xff;
8507       if (tag1)
8508         {
8509           mask[15] = 0xff;
8510           mask[14] = 0x0f;
8511         }
8512       if (cos1)
8513         mask[14] |= 0xe0;
8514       *maskp = mask;
8515       return 1;
8516     }
8517   if (tag1 | dot1q)
8518     {
8519       if (tag1)
8520         {
8521           mask[15] = 0xff;
8522           mask[14] = 0x0f;
8523         }
8524       if (cos1)
8525         mask[14] |= 0xe0;
8526       if (proto)
8527         mask[16] = mask[17] = 0xff;
8528
8529       *maskp = mask;
8530       return 1;
8531     }
8532   if (cos2)
8533     mask[18] |= 0xe0;
8534   if (cos1)
8535     mask[14] |= 0xe0;
8536   if (proto)
8537     mask[12] = mask[13] = 0xff;
8538
8539   *maskp = mask;
8540   return 1;
8541 }
8542
8543 uword
8544 unformat_classify_mask (unformat_input_t * input, va_list * args)
8545 {
8546   u8 **maskp = va_arg (*args, u8 **);
8547   u32 *skipp = va_arg (*args, u32 *);
8548   u32 *matchp = va_arg (*args, u32 *);
8549   u32 match;
8550   u8 *mask = 0;
8551   u8 *l2 = 0;
8552   u8 *l3 = 0;
8553   u8 *l4 = 0;
8554   int i;
8555
8556   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8557     {
8558       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8559         ;
8560       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8561         ;
8562       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8563         ;
8564       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8565         ;
8566       else
8567         break;
8568     }
8569
8570   if (l4 && !l3)
8571     {
8572       vec_free (mask);
8573       vec_free (l2);
8574       vec_free (l4);
8575       return 0;
8576     }
8577
8578   if (mask || l2 || l3 || l4)
8579     {
8580       if (l2 || l3 || l4)
8581         {
8582           /* "With a free Ethernet header in every package" */
8583           if (l2 == 0)
8584             vec_validate (l2, 13);
8585           mask = l2;
8586           if (vec_len (l3))
8587             {
8588               vec_append (mask, l3);
8589               vec_free (l3);
8590             }
8591           if (vec_len (l4))
8592             {
8593               vec_append (mask, l4);
8594               vec_free (l4);
8595             }
8596         }
8597
8598       /* Scan forward looking for the first significant mask octet */
8599       for (i = 0; i < vec_len (mask); i++)
8600         if (mask[i])
8601           break;
8602
8603       /* compute (skip, match) params */
8604       *skipp = i / sizeof (u32x4);
8605       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8606
8607       /* Pad mask to an even multiple of the vector size */
8608       while (vec_len (mask) % sizeof (u32x4))
8609         vec_add1 (mask, 0);
8610
8611       match = vec_len (mask) / sizeof (u32x4);
8612
8613       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8614         {
8615           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8616           if (*tmp || *(tmp + 1))
8617             break;
8618           match--;
8619         }
8620       if (match == 0)
8621         clib_warning ("BUG: match 0");
8622
8623       _vec_len (mask) = match * sizeof (u32x4);
8624
8625       *matchp = match;
8626       *maskp = mask;
8627
8628       return 1;
8629     }
8630
8631   return 0;
8632 }
8633
8634 #define foreach_l2_next                         \
8635 _(drop, DROP)                                   \
8636 _(ethernet, ETHERNET_INPUT)                     \
8637 _(ip4, IP4_INPUT)                               \
8638 _(ip6, IP6_INPUT)
8639
8640 uword
8641 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8642 {
8643   u32 *miss_next_indexp = va_arg (*args, u32 *);
8644   u32 next_index = 0;
8645   u32 tmp;
8646
8647 #define _(n,N) \
8648   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8649   foreach_l2_next;
8650 #undef _
8651
8652   if (unformat (input, "%d", &tmp))
8653     {
8654       next_index = tmp;
8655       goto out;
8656     }
8657
8658   return 0;
8659
8660 out:
8661   *miss_next_indexp = next_index;
8662   return 1;
8663 }
8664
8665 #define foreach_ip_next                         \
8666 _(drop, DROP)                                   \
8667 _(local, LOCAL)                                 \
8668 _(rewrite, REWRITE)
8669
8670 uword
8671 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8672 {
8673   u32 *miss_next_indexp = va_arg (*args, u32 *);
8674   u32 next_index = 0;
8675   u32 tmp;
8676
8677 #define _(n,N) \
8678   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8679   foreach_ip_next;
8680 #undef _
8681
8682   if (unformat (input, "%d", &tmp))
8683     {
8684       next_index = tmp;
8685       goto out;
8686     }
8687
8688   return 0;
8689
8690 out:
8691   *miss_next_indexp = next_index;
8692   return 1;
8693 }
8694
8695 #define foreach_acl_next                        \
8696 _(deny, DENY)
8697
8698 uword
8699 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8700 {
8701   u32 *miss_next_indexp = va_arg (*args, u32 *);
8702   u32 next_index = 0;
8703   u32 tmp;
8704
8705 #define _(n,N) \
8706   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8707   foreach_acl_next;
8708 #undef _
8709
8710   if (unformat (input, "permit"))
8711     {
8712       next_index = ~0;
8713       goto out;
8714     }
8715   else if (unformat (input, "%d", &tmp))
8716     {
8717       next_index = tmp;
8718       goto out;
8719     }
8720
8721   return 0;
8722
8723 out:
8724   *miss_next_indexp = next_index;
8725   return 1;
8726 }
8727
8728 uword
8729 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8730 {
8731   u32 *r = va_arg (*args, u32 *);
8732
8733   if (unformat (input, "conform-color"))
8734     *r = POLICE_CONFORM;
8735   else if (unformat (input, "exceed-color"))
8736     *r = POLICE_EXCEED;
8737   else
8738     return 0;
8739
8740   return 1;
8741 }
8742
8743 static int
8744 api_classify_add_del_table (vat_main_t * vam)
8745 {
8746   unformat_input_t *i = vam->input;
8747   vl_api_classify_add_del_table_t *mp;
8748
8749   u32 nbuckets = 2;
8750   u32 skip = ~0;
8751   u32 match = ~0;
8752   int is_add = 1;
8753   u32 table_index = ~0;
8754   u32 next_table_index = ~0;
8755   u32 miss_next_index = ~0;
8756   u32 memory_size = 32 << 20;
8757   u8 *mask = 0;
8758   f64 timeout;
8759   u32 current_data_flag = 0;
8760   int current_data_offset = 0;
8761
8762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8763     {
8764       if (unformat (i, "del"))
8765         is_add = 0;
8766       else if (unformat (i, "buckets %d", &nbuckets))
8767         ;
8768       else if (unformat (i, "memory_size %d", &memory_size))
8769         ;
8770       else if (unformat (i, "skip %d", &skip))
8771         ;
8772       else if (unformat (i, "match %d", &match))
8773         ;
8774       else if (unformat (i, "table %d", &table_index))
8775         ;
8776       else if (unformat (i, "mask %U", unformat_classify_mask,
8777                          &mask, &skip, &match))
8778         ;
8779       else if (unformat (i, "next-table %d", &next_table_index))
8780         ;
8781       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8782                          &miss_next_index))
8783         ;
8784       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8785                          &miss_next_index))
8786         ;
8787       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8788                          &miss_next_index))
8789         ;
8790       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8791         ;
8792       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8793         ;
8794       else
8795         break;
8796     }
8797
8798   if (is_add && mask == 0)
8799     {
8800       errmsg ("Mask required\n");
8801       return -99;
8802     }
8803
8804   if (is_add && skip == ~0)
8805     {
8806       errmsg ("skip count required\n");
8807       return -99;
8808     }
8809
8810   if (is_add && match == ~0)
8811     {
8812       errmsg ("match count required\n");
8813       return -99;
8814     }
8815
8816   if (!is_add && table_index == ~0)
8817     {
8818       errmsg ("table index required for delete\n");
8819       return -99;
8820     }
8821
8822   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8823
8824   mp->is_add = is_add;
8825   mp->table_index = ntohl (table_index);
8826   mp->nbuckets = ntohl (nbuckets);
8827   mp->memory_size = ntohl (memory_size);
8828   mp->skip_n_vectors = ntohl (skip);
8829   mp->match_n_vectors = ntohl (match);
8830   mp->next_table_index = ntohl (next_table_index);
8831   mp->miss_next_index = ntohl (miss_next_index);
8832   mp->current_data_flag = ntohl (current_data_flag);
8833   mp->current_data_offset = ntohl (current_data_offset);
8834   clib_memcpy (mp->mask, mask, vec_len (mask));
8835
8836   vec_free (mask);
8837
8838   S;
8839   W;
8840   /* NOTREACHED */
8841 }
8842
8843 uword
8844 unformat_l4_match (unformat_input_t * input, va_list * args)
8845 {
8846   u8 **matchp = va_arg (*args, u8 **);
8847
8848   u8 *proto_header = 0;
8849   int src_port = 0;
8850   int dst_port = 0;
8851
8852   tcpudp_header_t h;
8853
8854   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8855     {
8856       if (unformat (input, "src_port %d", &src_port))
8857         ;
8858       else if (unformat (input, "dst_port %d", &dst_port))
8859         ;
8860       else
8861         return 0;
8862     }
8863
8864   h.src_port = clib_host_to_net_u16 (src_port);
8865   h.dst_port = clib_host_to_net_u16 (dst_port);
8866   vec_validate (proto_header, sizeof (h) - 1);
8867   memcpy (proto_header, &h, sizeof (h));
8868
8869   *matchp = proto_header;
8870
8871   return 1;
8872 }
8873
8874 uword
8875 unformat_ip4_match (unformat_input_t * input, va_list * args)
8876 {
8877   u8 **matchp = va_arg (*args, u8 **);
8878   u8 *match = 0;
8879   ip4_header_t *ip;
8880   int version = 0;
8881   u32 version_val;
8882   int hdr_length = 0;
8883   u32 hdr_length_val;
8884   int src = 0, dst = 0;
8885   ip4_address_t src_val, dst_val;
8886   int proto = 0;
8887   u32 proto_val;
8888   int tos = 0;
8889   u32 tos_val;
8890   int length = 0;
8891   u32 length_val;
8892   int fragment_id = 0;
8893   u32 fragment_id_val;
8894   int ttl = 0;
8895   int ttl_val;
8896   int checksum = 0;
8897   u32 checksum_val;
8898
8899   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8900     {
8901       if (unformat (input, "version %d", &version_val))
8902         version = 1;
8903       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8904         hdr_length = 1;
8905       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8906         src = 1;
8907       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8908         dst = 1;
8909       else if (unformat (input, "proto %d", &proto_val))
8910         proto = 1;
8911       else if (unformat (input, "tos %d", &tos_val))
8912         tos = 1;
8913       else if (unformat (input, "length %d", &length_val))
8914         length = 1;
8915       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8916         fragment_id = 1;
8917       else if (unformat (input, "ttl %d", &ttl_val))
8918         ttl = 1;
8919       else if (unformat (input, "checksum %d", &checksum_val))
8920         checksum = 1;
8921       else
8922         break;
8923     }
8924
8925   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8926       + ttl + checksum == 0)
8927     return 0;
8928
8929   /*
8930    * Aligned because we use the real comparison functions
8931    */
8932   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8933
8934   ip = (ip4_header_t *) match;
8935
8936   /* These are realistically matched in practice */
8937   if (src)
8938     ip->src_address.as_u32 = src_val.as_u32;
8939
8940   if (dst)
8941     ip->dst_address.as_u32 = dst_val.as_u32;
8942
8943   if (proto)
8944     ip->protocol = proto_val;
8945
8946
8947   /* These are not, but they're included for completeness */
8948   if (version)
8949     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8950
8951   if (hdr_length)
8952     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8953
8954   if (tos)
8955     ip->tos = tos_val;
8956
8957   if (length)
8958     ip->length = clib_host_to_net_u16 (length_val);
8959
8960   if (ttl)
8961     ip->ttl = ttl_val;
8962
8963   if (checksum)
8964     ip->checksum = clib_host_to_net_u16 (checksum_val);
8965
8966   *matchp = match;
8967   return 1;
8968 }
8969
8970 uword
8971 unformat_ip6_match (unformat_input_t * input, va_list * args)
8972 {
8973   u8 **matchp = va_arg (*args, u8 **);
8974   u8 *match = 0;
8975   ip6_header_t *ip;
8976   int version = 0;
8977   u32 version_val;
8978   u8 traffic_class = 0;
8979   u32 traffic_class_val = 0;
8980   u8 flow_label = 0;
8981   u8 flow_label_val;
8982   int src = 0, dst = 0;
8983   ip6_address_t src_val, dst_val;
8984   int proto = 0;
8985   u32 proto_val;
8986   int payload_length = 0;
8987   u32 payload_length_val;
8988   int hop_limit = 0;
8989   int hop_limit_val;
8990   u32 ip_version_traffic_class_and_flow_label;
8991
8992   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8993     {
8994       if (unformat (input, "version %d", &version_val))
8995         version = 1;
8996       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8997         traffic_class = 1;
8998       else if (unformat (input, "flow_label %d", &flow_label_val))
8999         flow_label = 1;
9000       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9001         src = 1;
9002       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9003         dst = 1;
9004       else if (unformat (input, "proto %d", &proto_val))
9005         proto = 1;
9006       else if (unformat (input, "payload_length %d", &payload_length_val))
9007         payload_length = 1;
9008       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9009         hop_limit = 1;
9010       else
9011         break;
9012     }
9013
9014   if (version + traffic_class + flow_label + src + dst + proto +
9015       payload_length + hop_limit == 0)
9016     return 0;
9017
9018   /*
9019    * Aligned because we use the real comparison functions
9020    */
9021   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9022
9023   ip = (ip6_header_t *) match;
9024
9025   if (src)
9026     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9027
9028   if (dst)
9029     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9030
9031   if (proto)
9032     ip->protocol = proto_val;
9033
9034   ip_version_traffic_class_and_flow_label = 0;
9035
9036   if (version)
9037     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9038
9039   if (traffic_class)
9040     ip_version_traffic_class_and_flow_label |=
9041       (traffic_class_val & 0xFF) << 20;
9042
9043   if (flow_label)
9044     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9045
9046   ip->ip_version_traffic_class_and_flow_label =
9047     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9048
9049   if (payload_length)
9050     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9051
9052   if (hop_limit)
9053     ip->hop_limit = hop_limit_val;
9054
9055   *matchp = match;
9056   return 1;
9057 }
9058
9059 uword
9060 unformat_l3_match (unformat_input_t * input, va_list * args)
9061 {
9062   u8 **matchp = va_arg (*args, u8 **);
9063
9064   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9065     {
9066       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9067         return 1;
9068       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9069         return 1;
9070       else
9071         break;
9072     }
9073   return 0;
9074 }
9075
9076 uword
9077 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9078 {
9079   u8 *tagp = va_arg (*args, u8 *);
9080   u32 tag;
9081
9082   if (unformat (input, "%d", &tag))
9083     {
9084       tagp[0] = (tag >> 8) & 0x0F;
9085       tagp[1] = tag & 0xFF;
9086       return 1;
9087     }
9088
9089   return 0;
9090 }
9091
9092 uword
9093 unformat_l2_match (unformat_input_t * input, va_list * args)
9094 {
9095   u8 **matchp = va_arg (*args, u8 **);
9096   u8 *match = 0;
9097   u8 src = 0;
9098   u8 src_val[6];
9099   u8 dst = 0;
9100   u8 dst_val[6];
9101   u8 proto = 0;
9102   u16 proto_val;
9103   u8 tag1 = 0;
9104   u8 tag1_val[2];
9105   u8 tag2 = 0;
9106   u8 tag2_val[2];
9107   int len = 14;
9108   u8 ignore_tag1 = 0;
9109   u8 ignore_tag2 = 0;
9110   u8 cos1 = 0;
9111   u8 cos2 = 0;
9112   u32 cos1_val = 0;
9113   u32 cos2_val = 0;
9114
9115   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9116     {
9117       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9118         src = 1;
9119       else
9120         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9121         dst = 1;
9122       else if (unformat (input, "proto %U",
9123                          unformat_ethernet_type_host_byte_order, &proto_val))
9124         proto = 1;
9125       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9126         tag1 = 1;
9127       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9128         tag2 = 1;
9129       else if (unformat (input, "ignore-tag1"))
9130         ignore_tag1 = 1;
9131       else if (unformat (input, "ignore-tag2"))
9132         ignore_tag2 = 1;
9133       else if (unformat (input, "cos1 %d", &cos1_val))
9134         cos1 = 1;
9135       else if (unformat (input, "cos2 %d", &cos2_val))
9136         cos2 = 1;
9137       else
9138         break;
9139     }
9140   if ((src + dst + proto + tag1 + tag2 +
9141        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9142     return 0;
9143
9144   if (tag1 || ignore_tag1 || cos1)
9145     len = 18;
9146   if (tag2 || ignore_tag2 || cos2)
9147     len = 22;
9148
9149   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9150
9151   if (dst)
9152     clib_memcpy (match, dst_val, 6);
9153
9154   if (src)
9155     clib_memcpy (match + 6, src_val, 6);
9156
9157   if (tag2)
9158     {
9159       /* inner vlan tag */
9160       match[19] = tag2_val[1];
9161       match[18] = tag2_val[0];
9162       if (cos2)
9163         match[18] |= (cos2_val & 0x7) << 5;
9164       if (proto)
9165         {
9166           match[21] = proto_val & 0xff;
9167           match[20] = proto_val >> 8;
9168         }
9169       if (tag1)
9170         {
9171           match[15] = tag1_val[1];
9172           match[14] = tag1_val[0];
9173         }
9174       if (cos1)
9175         match[14] |= (cos1_val & 0x7) << 5;
9176       *matchp = match;
9177       return 1;
9178     }
9179   if (tag1)
9180     {
9181       match[15] = tag1_val[1];
9182       match[14] = tag1_val[0];
9183       if (proto)
9184         {
9185           match[17] = proto_val & 0xff;
9186           match[16] = proto_val >> 8;
9187         }
9188       if (cos1)
9189         match[14] |= (cos1_val & 0x7) << 5;
9190
9191       *matchp = match;
9192       return 1;
9193     }
9194   if (cos2)
9195     match[18] |= (cos2_val & 0x7) << 5;
9196   if (cos1)
9197     match[14] |= (cos1_val & 0x7) << 5;
9198   if (proto)
9199     {
9200       match[13] = proto_val & 0xff;
9201       match[12] = proto_val >> 8;
9202     }
9203
9204   *matchp = match;
9205   return 1;
9206 }
9207
9208
9209 uword
9210 unformat_classify_match (unformat_input_t * input, va_list * args)
9211 {
9212   u8 **matchp = va_arg (*args, u8 **);
9213   u32 skip_n_vectors = va_arg (*args, u32);
9214   u32 match_n_vectors = va_arg (*args, u32);
9215
9216   u8 *match = 0;
9217   u8 *l2 = 0;
9218   u8 *l3 = 0;
9219   u8 *l4 = 0;
9220
9221   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9222     {
9223       if (unformat (input, "hex %U", unformat_hex_string, &match))
9224         ;
9225       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9226         ;
9227       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9228         ;
9229       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9230         ;
9231       else
9232         break;
9233     }
9234
9235   if (l4 && !l3)
9236     {
9237       vec_free (match);
9238       vec_free (l2);
9239       vec_free (l4);
9240       return 0;
9241     }
9242
9243   if (match || l2 || l3 || l4)
9244     {
9245       if (l2 || l3 || l4)
9246         {
9247           /* "Win a free Ethernet header in every packet" */
9248           if (l2 == 0)
9249             vec_validate_aligned (l2, 13, sizeof (u32x4));
9250           match = l2;
9251           if (vec_len (l3))
9252             {
9253               vec_append_aligned (match, l3, sizeof (u32x4));
9254               vec_free (l3);
9255             }
9256           if (vec_len (l4))
9257             {
9258               vec_append_aligned (match, l4, sizeof (u32x4));
9259               vec_free (l4);
9260             }
9261         }
9262
9263       /* Make sure the vector is big enough even if key is all 0's */
9264       vec_validate_aligned
9265         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9266          sizeof (u32x4));
9267
9268       /* Set size, include skipped vectors */
9269       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9270
9271       *matchp = match;
9272
9273       return 1;
9274     }
9275
9276   return 0;
9277 }
9278
9279 static int
9280 api_classify_add_del_session (vat_main_t * vam)
9281 {
9282   unformat_input_t *i = vam->input;
9283   vl_api_classify_add_del_session_t *mp;
9284   int is_add = 1;
9285   u32 table_index = ~0;
9286   u32 hit_next_index = ~0;
9287   u32 opaque_index = ~0;
9288   u8 *match = 0;
9289   i32 advance = 0;
9290   f64 timeout;
9291   u32 skip_n_vectors = 0;
9292   u32 match_n_vectors = 0;
9293   u32 action = 0;
9294   u32 metadata = 0;
9295
9296   /*
9297    * Warning: you have to supply skip_n and match_n
9298    * because the API client cant simply look at the classify
9299    * table object.
9300    */
9301
9302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9303     {
9304       if (unformat (i, "del"))
9305         is_add = 0;
9306       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9307                          &hit_next_index))
9308         ;
9309       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9310                          &hit_next_index))
9311         ;
9312       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9313                          &hit_next_index))
9314         ;
9315       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9316         ;
9317       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9318         ;
9319       else if (unformat (i, "opaque-index %d", &opaque_index))
9320         ;
9321       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9322         ;
9323       else if (unformat (i, "match_n %d", &match_n_vectors))
9324         ;
9325       else if (unformat (i, "match %U", unformat_classify_match,
9326                          &match, skip_n_vectors, match_n_vectors))
9327         ;
9328       else if (unformat (i, "advance %d", &advance))
9329         ;
9330       else if (unformat (i, "table-index %d", &table_index))
9331         ;
9332       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9333         action = 1;
9334       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9335         action = 2;
9336       else if (unformat (i, "action %d", &action))
9337         ;
9338       else if (unformat (i, "metadata %d", &metadata))
9339         ;
9340       else
9341         break;
9342     }
9343
9344   if (table_index == ~0)
9345     {
9346       errmsg ("Table index required\n");
9347       return -99;
9348     }
9349
9350   if (is_add && match == 0)
9351     {
9352       errmsg ("Match value required\n");
9353       return -99;
9354     }
9355
9356   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9357
9358   mp->is_add = is_add;
9359   mp->table_index = ntohl (table_index);
9360   mp->hit_next_index = ntohl (hit_next_index);
9361   mp->opaque_index = ntohl (opaque_index);
9362   mp->advance = ntohl (advance);
9363   mp->action = action;
9364   mp->metadata = ntohl (metadata);
9365   clib_memcpy (mp->match, match, vec_len (match));
9366   vec_free (match);
9367
9368   S;
9369   W;
9370   /* NOTREACHED */
9371 }
9372
9373 static int
9374 api_classify_set_interface_ip_table (vat_main_t * vam)
9375 {
9376   unformat_input_t *i = vam->input;
9377   vl_api_classify_set_interface_ip_table_t *mp;
9378   f64 timeout;
9379   u32 sw_if_index;
9380   int sw_if_index_set;
9381   u32 table_index = ~0;
9382   u8 is_ipv6 = 0;
9383
9384   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9385     {
9386       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9387         sw_if_index_set = 1;
9388       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9389         sw_if_index_set = 1;
9390       else if (unformat (i, "table %d", &table_index))
9391         ;
9392       else
9393         {
9394           clib_warning ("parse error '%U'", format_unformat_error, i);
9395           return -99;
9396         }
9397     }
9398
9399   if (sw_if_index_set == 0)
9400     {
9401       errmsg ("missing interface name or sw_if_index\n");
9402       return -99;
9403     }
9404
9405
9406   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9407
9408   mp->sw_if_index = ntohl (sw_if_index);
9409   mp->table_index = ntohl (table_index);
9410   mp->is_ipv6 = is_ipv6;
9411
9412   S;
9413   W;
9414   /* NOTREACHED */
9415   return 0;
9416 }
9417
9418 static int
9419 api_classify_set_interface_l2_tables (vat_main_t * vam)
9420 {
9421   unformat_input_t *i = vam->input;
9422   vl_api_classify_set_interface_l2_tables_t *mp;
9423   f64 timeout;
9424   u32 sw_if_index;
9425   int sw_if_index_set;
9426   u32 ip4_table_index = ~0;
9427   u32 ip6_table_index = ~0;
9428   u32 other_table_index = ~0;
9429   u32 is_input = 1;
9430
9431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9432     {
9433       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9434         sw_if_index_set = 1;
9435       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9436         sw_if_index_set = 1;
9437       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9438         ;
9439       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9440         ;
9441       else if (unformat (i, "other-table %d", &other_table_index))
9442         ;
9443       else if (unformat (i, "is-input %d", &is_input))
9444         ;
9445       else
9446         {
9447           clib_warning ("parse error '%U'", format_unformat_error, i);
9448           return -99;
9449         }
9450     }
9451
9452   if (sw_if_index_set == 0)
9453     {
9454       errmsg ("missing interface name or sw_if_index\n");
9455       return -99;
9456     }
9457
9458
9459   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9460
9461   mp->sw_if_index = ntohl (sw_if_index);
9462   mp->ip4_table_index = ntohl (ip4_table_index);
9463   mp->ip6_table_index = ntohl (ip6_table_index);
9464   mp->other_table_index = ntohl (other_table_index);
9465   mp->is_input = (u8) is_input;
9466
9467   S;
9468   W;
9469   /* NOTREACHED */
9470   return 0;
9471 }
9472
9473 static int
9474 api_set_ipfix_exporter (vat_main_t * vam)
9475 {
9476   unformat_input_t *i = vam->input;
9477   vl_api_set_ipfix_exporter_t *mp;
9478   ip4_address_t collector_address;
9479   u8 collector_address_set = 0;
9480   u32 collector_port = ~0;
9481   ip4_address_t src_address;
9482   u8 src_address_set = 0;
9483   u32 vrf_id = ~0;
9484   u32 path_mtu = ~0;
9485   u32 template_interval = ~0;
9486   u8 udp_checksum = 0;
9487   f64 timeout;
9488
9489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9490     {
9491       if (unformat (i, "collector_address %U", unformat_ip4_address,
9492                     &collector_address))
9493         collector_address_set = 1;
9494       else if (unformat (i, "collector_port %d", &collector_port))
9495         ;
9496       else if (unformat (i, "src_address %U", unformat_ip4_address,
9497                          &src_address))
9498         src_address_set = 1;
9499       else if (unformat (i, "vrf_id %d", &vrf_id))
9500         ;
9501       else if (unformat (i, "path_mtu %d", &path_mtu))
9502         ;
9503       else if (unformat (i, "template_interval %d", &template_interval))
9504         ;
9505       else if (unformat (i, "udp_checksum"))
9506         udp_checksum = 1;
9507       else
9508         break;
9509     }
9510
9511   if (collector_address_set == 0)
9512     {
9513       errmsg ("collector_address required\n");
9514       return -99;
9515     }
9516
9517   if (src_address_set == 0)
9518     {
9519       errmsg ("src_address required\n");
9520       return -99;
9521     }
9522
9523   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9524
9525   memcpy (mp->collector_address, collector_address.data,
9526           sizeof (collector_address.data));
9527   mp->collector_port = htons ((u16) collector_port);
9528   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9529   mp->vrf_id = htonl (vrf_id);
9530   mp->path_mtu = htonl (path_mtu);
9531   mp->template_interval = htonl (template_interval);
9532   mp->udp_checksum = udp_checksum;
9533
9534   S;
9535   W;
9536   /* NOTREACHED */
9537 }
9538
9539 static int
9540 api_set_ipfix_classify_stream (vat_main_t * vam)
9541 {
9542   unformat_input_t *i = vam->input;
9543   vl_api_set_ipfix_classify_stream_t *mp;
9544   u32 domain_id = 0;
9545   u32 src_port = UDP_DST_PORT_ipfix;
9546   f64 timeout;
9547
9548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9549     {
9550       if (unformat (i, "domain %d", &domain_id))
9551         ;
9552       else if (unformat (i, "src_port %d", &src_port))
9553         ;
9554       else
9555         {
9556           errmsg ("unknown input `%U'", format_unformat_error, i);
9557           return -99;
9558         }
9559     }
9560
9561   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9562
9563   mp->domain_id = htonl (domain_id);
9564   mp->src_port = htons ((u16) src_port);
9565
9566   S;
9567   W;
9568   /* NOTREACHED */
9569 }
9570
9571 static int
9572 api_ipfix_classify_table_add_del (vat_main_t * vam)
9573 {
9574   unformat_input_t *i = vam->input;
9575   vl_api_ipfix_classify_table_add_del_t *mp;
9576   int is_add = -1;
9577   u32 classify_table_index = ~0;
9578   u8 ip_version = 0;
9579   u8 transport_protocol = 255;
9580   f64 timeout;
9581
9582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9583     {
9584       if (unformat (i, "add"))
9585         is_add = 1;
9586       else if (unformat (i, "del"))
9587         is_add = 0;
9588       else if (unformat (i, "table %d", &classify_table_index))
9589         ;
9590       else if (unformat (i, "ip4"))
9591         ip_version = 4;
9592       else if (unformat (i, "ip6"))
9593         ip_version = 6;
9594       else if (unformat (i, "tcp"))
9595         transport_protocol = 6;
9596       else if (unformat (i, "udp"))
9597         transport_protocol = 17;
9598       else
9599         {
9600           errmsg ("unknown input `%U'", format_unformat_error, i);
9601           return -99;
9602         }
9603     }
9604
9605   if (is_add == -1)
9606     {
9607       errmsg ("expecting: add|del");
9608       return -99;
9609     }
9610   if (classify_table_index == ~0)
9611     {
9612       errmsg ("classifier table not specified");
9613       return -99;
9614     }
9615   if (ip_version == 0)
9616     {
9617       errmsg ("IP version not specified");
9618       return -99;
9619     }
9620
9621   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9622
9623   mp->is_add = is_add;
9624   mp->table_id = htonl (classify_table_index);
9625   mp->ip_version = ip_version;
9626   mp->transport_protocol = transport_protocol;
9627
9628   S;
9629   W;
9630   /* NOTREACHED */
9631 }
9632
9633 static int
9634 api_get_node_index (vat_main_t * vam)
9635 {
9636   unformat_input_t *i = vam->input;
9637   vl_api_get_node_index_t *mp;
9638   f64 timeout;
9639   u8 *name = 0;
9640
9641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9642     {
9643       if (unformat (i, "node %s", &name))
9644         ;
9645       else
9646         break;
9647     }
9648   if (name == 0)
9649     {
9650       errmsg ("node name required\n");
9651       return -99;
9652     }
9653   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9654     {
9655       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9656       return -99;
9657     }
9658
9659   M (GET_NODE_INDEX, get_node_index);
9660   clib_memcpy (mp->node_name, name, vec_len (name));
9661   vec_free (name);
9662
9663   S;
9664   W;
9665   /* NOTREACHED */
9666   return 0;
9667 }
9668
9669 static int
9670 api_get_next_index (vat_main_t * vam)
9671 {
9672   unformat_input_t *i = vam->input;
9673   vl_api_get_next_index_t *mp;
9674   f64 timeout;
9675   u8 *node_name = 0, *next_node_name = 0;
9676
9677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9678     {
9679       if (unformat (i, "node-name %s", &node_name))
9680         ;
9681       else if (unformat (i, "next-node-name %s", &next_node_name))
9682         break;
9683     }
9684
9685   if (node_name == 0)
9686     {
9687       errmsg ("node name required\n");
9688       return -99;
9689     }
9690   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9691     {
9692       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9693       return -99;
9694     }
9695
9696   if (next_node_name == 0)
9697     {
9698       errmsg ("next node name required\n");
9699       return -99;
9700     }
9701   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9702     {
9703       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9704       return -99;
9705     }
9706
9707   M (GET_NEXT_INDEX, get_next_index);
9708   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9709   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9710   vec_free (node_name);
9711   vec_free (next_node_name);
9712
9713   S;
9714   W;
9715   /* NOTREACHED */
9716   return 0;
9717 }
9718
9719 static int
9720 api_add_node_next (vat_main_t * vam)
9721 {
9722   unformat_input_t *i = vam->input;
9723   vl_api_add_node_next_t *mp;
9724   f64 timeout;
9725   u8 *name = 0;
9726   u8 *next = 0;
9727
9728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9729     {
9730       if (unformat (i, "node %s", &name))
9731         ;
9732       else if (unformat (i, "next %s", &next))
9733         ;
9734       else
9735         break;
9736     }
9737   if (name == 0)
9738     {
9739       errmsg ("node name required\n");
9740       return -99;
9741     }
9742   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9743     {
9744       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9745       return -99;
9746     }
9747   if (next == 0)
9748     {
9749       errmsg ("next node required\n");
9750       return -99;
9751     }
9752   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9753     {
9754       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9755       return -99;
9756     }
9757
9758   M (ADD_NODE_NEXT, add_node_next);
9759   clib_memcpy (mp->node_name, name, vec_len (name));
9760   clib_memcpy (mp->next_name, next, vec_len (next));
9761   vec_free (name);
9762   vec_free (next);
9763
9764   S;
9765   W;
9766   /* NOTREACHED */
9767   return 0;
9768 }
9769
9770 static int
9771 api_l2tpv3_create_tunnel (vat_main_t * vam)
9772 {
9773   unformat_input_t *i = vam->input;
9774   ip6_address_t client_address, our_address;
9775   int client_address_set = 0;
9776   int our_address_set = 0;
9777   u32 local_session_id = 0;
9778   u32 remote_session_id = 0;
9779   u64 local_cookie = 0;
9780   u64 remote_cookie = 0;
9781   u8 l2_sublayer_present = 0;
9782   vl_api_l2tpv3_create_tunnel_t *mp;
9783   f64 timeout;
9784
9785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9786     {
9787       if (unformat (i, "client_address %U", unformat_ip6_address,
9788                     &client_address))
9789         client_address_set = 1;
9790       else if (unformat (i, "our_address %U", unformat_ip6_address,
9791                          &our_address))
9792         our_address_set = 1;
9793       else if (unformat (i, "local_session_id %d", &local_session_id))
9794         ;
9795       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9796         ;
9797       else if (unformat (i, "local_cookie %lld", &local_cookie))
9798         ;
9799       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9800         ;
9801       else if (unformat (i, "l2-sublayer-present"))
9802         l2_sublayer_present = 1;
9803       else
9804         break;
9805     }
9806
9807   if (client_address_set == 0)
9808     {
9809       errmsg ("client_address required\n");
9810       return -99;
9811     }
9812
9813   if (our_address_set == 0)
9814     {
9815       errmsg ("our_address required\n");
9816       return -99;
9817     }
9818
9819   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9820
9821   clib_memcpy (mp->client_address, client_address.as_u8,
9822                sizeof (mp->client_address));
9823
9824   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9825
9826   mp->local_session_id = ntohl (local_session_id);
9827   mp->remote_session_id = ntohl (remote_session_id);
9828   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9829   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9830   mp->l2_sublayer_present = l2_sublayer_present;
9831   mp->is_ipv6 = 1;
9832
9833   S;
9834   W;
9835   /* NOTREACHED */
9836   return 0;
9837 }
9838
9839 static int
9840 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9841 {
9842   unformat_input_t *i = vam->input;
9843   u32 sw_if_index;
9844   u8 sw_if_index_set = 0;
9845   u64 new_local_cookie = 0;
9846   u64 new_remote_cookie = 0;
9847   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9848   f64 timeout;
9849
9850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9851     {
9852       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9853         sw_if_index_set = 1;
9854       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9855         sw_if_index_set = 1;
9856       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9857         ;
9858       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9859         ;
9860       else
9861         break;
9862     }
9863
9864   if (sw_if_index_set == 0)
9865     {
9866       errmsg ("missing interface name or sw_if_index\n");
9867       return -99;
9868     }
9869
9870   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9871
9872   mp->sw_if_index = ntohl (sw_if_index);
9873   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9874   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9875
9876   S;
9877   W;
9878   /* NOTREACHED */
9879   return 0;
9880 }
9881
9882 static int
9883 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9884 {
9885   unformat_input_t *i = vam->input;
9886   vl_api_l2tpv3_interface_enable_disable_t *mp;
9887   f64 timeout;
9888   u32 sw_if_index;
9889   u8 sw_if_index_set = 0;
9890   u8 enable_disable = 1;
9891
9892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9893     {
9894       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9895         sw_if_index_set = 1;
9896       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9897         sw_if_index_set = 1;
9898       else if (unformat (i, "enable"))
9899         enable_disable = 1;
9900       else if (unformat (i, "disable"))
9901         enable_disable = 0;
9902       else
9903         break;
9904     }
9905
9906   if (sw_if_index_set == 0)
9907     {
9908       errmsg ("missing interface name or sw_if_index\n");
9909       return -99;
9910     }
9911
9912   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9913
9914   mp->sw_if_index = ntohl (sw_if_index);
9915   mp->enable_disable = enable_disable;
9916
9917   S;
9918   W;
9919   /* NOTREACHED */
9920   return 0;
9921 }
9922
9923 static int
9924 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9925 {
9926   unformat_input_t *i = vam->input;
9927   vl_api_l2tpv3_set_lookup_key_t *mp;
9928   f64 timeout;
9929   u8 key = ~0;
9930
9931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9932     {
9933       if (unformat (i, "lookup_v6_src"))
9934         key = L2T_LOOKUP_SRC_ADDRESS;
9935       else if (unformat (i, "lookup_v6_dst"))
9936         key = L2T_LOOKUP_DST_ADDRESS;
9937       else if (unformat (i, "lookup_session_id"))
9938         key = L2T_LOOKUP_SESSION_ID;
9939       else
9940         break;
9941     }
9942
9943   if (key == (u8) ~ 0)
9944     {
9945       errmsg ("l2tp session lookup key unset\n");
9946       return -99;
9947     }
9948
9949   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9950
9951   mp->key = key;
9952
9953   S;
9954   W;
9955   /* NOTREACHED */
9956   return 0;
9957 }
9958
9959 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9960   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9961 {
9962   vat_main_t *vam = &vat_main;
9963
9964   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9965            format_ip6_address, mp->our_address,
9966            format_ip6_address, mp->client_address,
9967            clib_net_to_host_u32 (mp->sw_if_index));
9968
9969   fformat (vam->ofp,
9970            "   local cookies %016llx %016llx remote cookie %016llx\n",
9971            clib_net_to_host_u64 (mp->local_cookie[0]),
9972            clib_net_to_host_u64 (mp->local_cookie[1]),
9973            clib_net_to_host_u64 (mp->remote_cookie));
9974
9975   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9976            clib_net_to_host_u32 (mp->local_session_id),
9977            clib_net_to_host_u32 (mp->remote_session_id));
9978
9979   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9980            mp->l2_sublayer_present ? "preset" : "absent");
9981
9982 }
9983
9984 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9985   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9986 {
9987   vat_main_t *vam = &vat_main;
9988   vat_json_node_t *node = NULL;
9989   struct in6_addr addr;
9990
9991   if (VAT_JSON_ARRAY != vam->json_tree.type)
9992     {
9993       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9994       vat_json_init_array (&vam->json_tree);
9995     }
9996   node = vat_json_array_add (&vam->json_tree);
9997
9998   vat_json_init_object (node);
9999
10000   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10001   vat_json_object_add_ip6 (node, "our_address", addr);
10002   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10003   vat_json_object_add_ip6 (node, "client_address", addr);
10004
10005   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10006   vat_json_init_array (lc);
10007   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10008   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10009   vat_json_object_add_uint (node, "remote_cookie",
10010                             clib_net_to_host_u64 (mp->remote_cookie));
10011
10012   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10013   vat_json_object_add_uint (node, "local_session_id",
10014                             clib_net_to_host_u32 (mp->local_session_id));
10015   vat_json_object_add_uint (node, "remote_session_id",
10016                             clib_net_to_host_u32 (mp->remote_session_id));
10017   vat_json_object_add_string_copy (node, "l2_sublayer",
10018                                    mp->l2_sublayer_present ? (u8 *) "present"
10019                                    : (u8 *) "absent");
10020 }
10021
10022 static int
10023 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10024 {
10025   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10026   f64 timeout;
10027
10028   /* Get list of l2tpv3-tunnel interfaces */
10029   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10030   S;
10031
10032   /* Use a control ping for synchronization */
10033   {
10034     vl_api_control_ping_t *mp;
10035     M (CONTROL_PING, control_ping);
10036     S;
10037   }
10038   W;
10039 }
10040
10041
10042 static void vl_api_sw_interface_tap_details_t_handler
10043   (vl_api_sw_interface_tap_details_t * mp)
10044 {
10045   vat_main_t *vam = &vat_main;
10046
10047   fformat (vam->ofp, "%-16s %d\n",
10048            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10049 }
10050
10051 static void vl_api_sw_interface_tap_details_t_handler_json
10052   (vl_api_sw_interface_tap_details_t * mp)
10053 {
10054   vat_main_t *vam = &vat_main;
10055   vat_json_node_t *node = NULL;
10056
10057   if (VAT_JSON_ARRAY != vam->json_tree.type)
10058     {
10059       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10060       vat_json_init_array (&vam->json_tree);
10061     }
10062   node = vat_json_array_add (&vam->json_tree);
10063
10064   vat_json_init_object (node);
10065   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10066   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10067 }
10068
10069 static int
10070 api_sw_interface_tap_dump (vat_main_t * vam)
10071 {
10072   vl_api_sw_interface_tap_dump_t *mp;
10073   f64 timeout;
10074
10075   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10076   /* Get list of tap interfaces */
10077   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10078   S;
10079
10080   /* Use a control ping for synchronization */
10081   {
10082     vl_api_control_ping_t *mp;
10083     M (CONTROL_PING, control_ping);
10084     S;
10085   }
10086   W;
10087 }
10088
10089 static uword unformat_vxlan_decap_next
10090   (unformat_input_t * input, va_list * args)
10091 {
10092   u32 *result = va_arg (*args, u32 *);
10093   u32 tmp;
10094
10095   if (unformat (input, "l2"))
10096     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10097   else if (unformat (input, "%d", &tmp))
10098     *result = tmp;
10099   else
10100     return 0;
10101   return 1;
10102 }
10103
10104 static int
10105 api_vxlan_add_del_tunnel (vat_main_t * vam)
10106 {
10107   unformat_input_t *line_input = vam->input;
10108   vl_api_vxlan_add_del_tunnel_t *mp;
10109   f64 timeout;
10110   ip4_address_t src4, dst4;
10111   ip6_address_t src6, dst6;
10112   u8 is_add = 1;
10113   u8 ipv4_set = 0, ipv6_set = 0;
10114   u8 src_set = 0;
10115   u8 dst_set = 0;
10116   u32 encap_vrf_id = 0;
10117   u32 decap_next_index = ~0;
10118   u32 vni = 0;
10119
10120   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10121     {
10122       if (unformat (line_input, "del"))
10123         is_add = 0;
10124       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10125         {
10126           ipv4_set = 1;
10127           src_set = 1;
10128         }
10129       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10130         {
10131           ipv4_set = 1;
10132           dst_set = 1;
10133         }
10134       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
10135         {
10136           ipv6_set = 1;
10137           src_set = 1;
10138         }
10139       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
10140         {
10141           ipv6_set = 1;
10142           dst_set = 1;
10143         }
10144       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10145         ;
10146       else if (unformat (line_input, "decap-next %U",
10147                          unformat_vxlan_decap_next, &decap_next_index))
10148         ;
10149       else if (unformat (line_input, "vni %d", &vni))
10150         ;
10151       else
10152         {
10153           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10154           return -99;
10155         }
10156     }
10157
10158   if (src_set == 0)
10159     {
10160       errmsg ("tunnel src address not specified\n");
10161       return -99;
10162     }
10163   if (dst_set == 0)
10164     {
10165       errmsg ("tunnel dst address not specified\n");
10166       return -99;
10167     }
10168
10169   if (ipv4_set && ipv6_set)
10170     {
10171       errmsg ("both IPv4 and IPv6 addresses specified");
10172       return -99;
10173     }
10174
10175   if ((vni == 0) || (vni >> 24))
10176     {
10177       errmsg ("vni not specified or out of range\n");
10178       return -99;
10179     }
10180
10181   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10182
10183   if (ipv6_set)
10184     {
10185       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
10186       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
10187     }
10188   else
10189     {
10190       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10191       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10192     }
10193   mp->encap_vrf_id = ntohl (encap_vrf_id);
10194   mp->decap_next_index = ntohl (decap_next_index);
10195   mp->vni = ntohl (vni);
10196   mp->is_add = is_add;
10197   mp->is_ipv6 = ipv6_set;
10198
10199   S;
10200   W;
10201   /* NOTREACHED */
10202   return 0;
10203 }
10204
10205 static void vl_api_vxlan_tunnel_details_t_handler
10206   (vl_api_vxlan_tunnel_details_t * mp)
10207 {
10208   vat_main_t *vam = &vat_main;
10209
10210   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
10211            ntohl (mp->sw_if_index),
10212            format_ip46_address, &(mp->src_address[0]),
10213            IP46_TYPE_ANY,
10214            format_ip46_address, &(mp->dst_address[0]),
10215            IP46_TYPE_ANY,
10216            ntohl (mp->encap_vrf_id),
10217            ntohl (mp->decap_next_index), ntohl (mp->vni));
10218 }
10219
10220 static void vl_api_vxlan_tunnel_details_t_handler_json
10221   (vl_api_vxlan_tunnel_details_t * mp)
10222 {
10223   vat_main_t *vam = &vat_main;
10224   vat_json_node_t *node = NULL;
10225   struct in_addr ip4;
10226   struct in6_addr ip6;
10227
10228   if (VAT_JSON_ARRAY != vam->json_tree.type)
10229     {
10230       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10231       vat_json_init_array (&vam->json_tree);
10232     }
10233   node = vat_json_array_add (&vam->json_tree);
10234
10235   vat_json_init_object (node);
10236   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10237   if (mp->is_ipv6)
10238     {
10239       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
10240       vat_json_object_add_ip6 (node, "src_address", ip6);
10241       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
10242       vat_json_object_add_ip6 (node, "dst_address", ip6);
10243     }
10244   else
10245     {
10246       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
10247       vat_json_object_add_ip4 (node, "src_address", ip4);
10248       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
10249       vat_json_object_add_ip4 (node, "dst_address", ip4);
10250     }
10251   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10252   vat_json_object_add_uint (node, "decap_next_index",
10253                             ntohl (mp->decap_next_index));
10254   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10255   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10256 }
10257
10258 static int
10259 api_vxlan_tunnel_dump (vat_main_t * vam)
10260 {
10261   unformat_input_t *i = vam->input;
10262   vl_api_vxlan_tunnel_dump_t *mp;
10263   f64 timeout;
10264   u32 sw_if_index;
10265   u8 sw_if_index_set = 0;
10266
10267   /* Parse args required to build the message */
10268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10269     {
10270       if (unformat (i, "sw_if_index %d", &sw_if_index))
10271         sw_if_index_set = 1;
10272       else
10273         break;
10274     }
10275
10276   if (sw_if_index_set == 0)
10277     {
10278       sw_if_index = ~0;
10279     }
10280
10281   if (!vam->json_output)
10282     {
10283       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
10284                "sw_if_index", "src_address", "dst_address",
10285                "encap_vrf_id", "decap_next_index", "vni");
10286     }
10287
10288   /* Get list of vxlan-tunnel interfaces */
10289   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10290
10291   mp->sw_if_index = htonl (sw_if_index);
10292
10293   S;
10294
10295   /* Use a control ping for synchronization */
10296   {
10297     vl_api_control_ping_t *mp;
10298     M (CONTROL_PING, control_ping);
10299     S;
10300   }
10301   W;
10302 }
10303
10304 static int
10305 api_gre_add_del_tunnel (vat_main_t * vam)
10306 {
10307   unformat_input_t *line_input = vam->input;
10308   vl_api_gre_add_del_tunnel_t *mp;
10309   f64 timeout;
10310   ip4_address_t src4, dst4;
10311   u8 is_add = 1;
10312   u8 teb = 0;
10313   u8 src_set = 0;
10314   u8 dst_set = 0;
10315   u32 outer_fib_id = 0;
10316
10317   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10318     {
10319       if (unformat (line_input, "del"))
10320         is_add = 0;
10321       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10322         src_set = 1;
10323       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10324         dst_set = 1;
10325       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10326         ;
10327       else if (unformat (line_input, "teb"))
10328         teb = 1;
10329       else
10330         {
10331           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10332           return -99;
10333         }
10334     }
10335
10336   if (src_set == 0)
10337     {
10338       errmsg ("tunnel src address not specified\n");
10339       return -99;
10340     }
10341   if (dst_set == 0)
10342     {
10343       errmsg ("tunnel dst address not specified\n");
10344       return -99;
10345     }
10346
10347
10348   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10349
10350   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10351   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10352   mp->outer_fib_id = ntohl (outer_fib_id);
10353   mp->is_add = is_add;
10354   mp->teb = teb;
10355
10356   S;
10357   W;
10358   /* NOTREACHED */
10359   return 0;
10360 }
10361
10362 static void vl_api_gre_tunnel_details_t_handler
10363   (vl_api_gre_tunnel_details_t * mp)
10364 {
10365   vat_main_t *vam = &vat_main;
10366
10367   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10368            ntohl (mp->sw_if_index),
10369            format_ip4_address, &mp->src_address,
10370            format_ip4_address, &mp->dst_address,
10371            mp->teb, ntohl (mp->outer_fib_id));
10372 }
10373
10374 static void vl_api_gre_tunnel_details_t_handler_json
10375   (vl_api_gre_tunnel_details_t * mp)
10376 {
10377   vat_main_t *vam = &vat_main;
10378   vat_json_node_t *node = NULL;
10379   struct in_addr ip4;
10380
10381   if (VAT_JSON_ARRAY != vam->json_tree.type)
10382     {
10383       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10384       vat_json_init_array (&vam->json_tree);
10385     }
10386   node = vat_json_array_add (&vam->json_tree);
10387
10388   vat_json_init_object (node);
10389   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10390   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10391   vat_json_object_add_ip4 (node, "src_address", ip4);
10392   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10393   vat_json_object_add_ip4 (node, "dst_address", ip4);
10394   vat_json_object_add_uint (node, "teb", mp->teb);
10395   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10396 }
10397
10398 static int
10399 api_gre_tunnel_dump (vat_main_t * vam)
10400 {
10401   unformat_input_t *i = vam->input;
10402   vl_api_gre_tunnel_dump_t *mp;
10403   f64 timeout;
10404   u32 sw_if_index;
10405   u8 sw_if_index_set = 0;
10406
10407   /* Parse args required to build the message */
10408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10409     {
10410       if (unformat (i, "sw_if_index %d", &sw_if_index))
10411         sw_if_index_set = 1;
10412       else
10413         break;
10414     }
10415
10416   if (sw_if_index_set == 0)
10417     {
10418       sw_if_index = ~0;
10419     }
10420
10421   if (!vam->json_output)
10422     {
10423       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10424                "sw_if_index", "src_address", "dst_address", "teb",
10425                "outer_fib_id");
10426     }
10427
10428   /* Get list of gre-tunnel interfaces */
10429   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10430
10431   mp->sw_if_index = htonl (sw_if_index);
10432
10433   S;
10434
10435   /* Use a control ping for synchronization */
10436   {
10437     vl_api_control_ping_t *mp;
10438     M (CONTROL_PING, control_ping);
10439     S;
10440   }
10441   W;
10442 }
10443
10444 static int
10445 api_l2_fib_clear_table (vat_main_t * vam)
10446 {
10447 //  unformat_input_t * i = vam->input;
10448   vl_api_l2_fib_clear_table_t *mp;
10449   f64 timeout;
10450
10451   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10452
10453   S;
10454   W;
10455   /* NOTREACHED */
10456   return 0;
10457 }
10458
10459 static int
10460 api_l2_interface_efp_filter (vat_main_t * vam)
10461 {
10462   unformat_input_t *i = vam->input;
10463   vl_api_l2_interface_efp_filter_t *mp;
10464   f64 timeout;
10465   u32 sw_if_index;
10466   u8 enable = 1;
10467   u8 sw_if_index_set = 0;
10468
10469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10470     {
10471       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10472         sw_if_index_set = 1;
10473       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10474         sw_if_index_set = 1;
10475       else if (unformat (i, "enable"))
10476         enable = 1;
10477       else if (unformat (i, "disable"))
10478         enable = 0;
10479       else
10480         {
10481           clib_warning ("parse error '%U'", format_unformat_error, i);
10482           return -99;
10483         }
10484     }
10485
10486   if (sw_if_index_set == 0)
10487     {
10488       errmsg ("missing sw_if_index\n");
10489       return -99;
10490     }
10491
10492   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10493
10494   mp->sw_if_index = ntohl (sw_if_index);
10495   mp->enable_disable = enable;
10496
10497   S;
10498   W;
10499   /* NOTREACHED */
10500   return 0;
10501 }
10502
10503 #define foreach_vtr_op                          \
10504 _("disable",  L2_VTR_DISABLED)                  \
10505 _("push-1",  L2_VTR_PUSH_1)                     \
10506 _("push-2",  L2_VTR_PUSH_2)                     \
10507 _("pop-1",  L2_VTR_POP_1)                       \
10508 _("pop-2",  L2_VTR_POP_2)                       \
10509 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10510 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10511 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10512 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10513
10514 static int
10515 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10516 {
10517   unformat_input_t *i = vam->input;
10518   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10519   f64 timeout;
10520   u32 sw_if_index;
10521   u8 sw_if_index_set = 0;
10522   u8 vtr_op_set = 0;
10523   u32 vtr_op = 0;
10524   u32 push_dot1q = 1;
10525   u32 tag1 = ~0;
10526   u32 tag2 = ~0;
10527
10528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10529     {
10530       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10531         sw_if_index_set = 1;
10532       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10533         sw_if_index_set = 1;
10534       else if (unformat (i, "vtr_op %d", &vtr_op))
10535         vtr_op_set = 1;
10536 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10537       foreach_vtr_op
10538 #undef _
10539         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10540         ;
10541       else if (unformat (i, "tag1 %d", &tag1))
10542         ;
10543       else if (unformat (i, "tag2 %d", &tag2))
10544         ;
10545       else
10546         {
10547           clib_warning ("parse error '%U'", format_unformat_error, i);
10548           return -99;
10549         }
10550     }
10551
10552   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10553     {
10554       errmsg ("missing vtr operation or sw_if_index\n");
10555       return -99;
10556     }
10557
10558   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10559     mp->sw_if_index = ntohl (sw_if_index);
10560   mp->vtr_op = ntohl (vtr_op);
10561   mp->push_dot1q = ntohl (push_dot1q);
10562   mp->tag1 = ntohl (tag1);
10563   mp->tag2 = ntohl (tag2);
10564
10565   S;
10566   W;
10567   /* NOTREACHED */
10568   return 0;
10569 }
10570
10571 static int
10572 api_create_vhost_user_if (vat_main_t * vam)
10573 {
10574   unformat_input_t *i = vam->input;
10575   vl_api_create_vhost_user_if_t *mp;
10576   f64 timeout;
10577   u8 *file_name;
10578   u8 is_server = 0;
10579   u8 file_name_set = 0;
10580   u32 custom_dev_instance = ~0;
10581   u8 hwaddr[6];
10582   u8 use_custom_mac = 0;
10583
10584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10585     {
10586       if (unformat (i, "socket %s", &file_name))
10587         {
10588           file_name_set = 1;
10589         }
10590       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10591         ;
10592       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10593         use_custom_mac = 1;
10594       else if (unformat (i, "server"))
10595         is_server = 1;
10596       else
10597         break;
10598     }
10599
10600   if (file_name_set == 0)
10601     {
10602       errmsg ("missing socket file name\n");
10603       return -99;
10604     }
10605
10606   if (vec_len (file_name) > 255)
10607     {
10608       errmsg ("socket file name too long\n");
10609       return -99;
10610     }
10611   vec_add1 (file_name, 0);
10612
10613   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10614
10615   mp->is_server = is_server;
10616   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10617   vec_free (file_name);
10618   if (custom_dev_instance != ~0)
10619     {
10620       mp->renumber = 1;
10621       mp->custom_dev_instance = ntohl (custom_dev_instance);
10622     }
10623   mp->use_custom_mac = use_custom_mac;
10624   clib_memcpy (mp->mac_address, hwaddr, 6);
10625
10626   S;
10627   W;
10628   /* NOTREACHED */
10629   return 0;
10630 }
10631
10632 static int
10633 api_modify_vhost_user_if (vat_main_t * vam)
10634 {
10635   unformat_input_t *i = vam->input;
10636   vl_api_modify_vhost_user_if_t *mp;
10637   f64 timeout;
10638   u8 *file_name;
10639   u8 is_server = 0;
10640   u8 file_name_set = 0;
10641   u32 custom_dev_instance = ~0;
10642   u8 sw_if_index_set = 0;
10643   u32 sw_if_index = (u32) ~ 0;
10644
10645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10646     {
10647       if (unformat (i, "%U", 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, "socket %s", &file_name))
10652         {
10653           file_name_set = 1;
10654         }
10655       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10656         ;
10657       else if (unformat (i, "server"))
10658         is_server = 1;
10659       else
10660         break;
10661     }
10662
10663   if (sw_if_index_set == 0)
10664     {
10665       errmsg ("missing sw_if_index or interface name\n");
10666       return -99;
10667     }
10668
10669   if (file_name_set == 0)
10670     {
10671       errmsg ("missing socket file name\n");
10672       return -99;
10673     }
10674
10675   if (vec_len (file_name) > 255)
10676     {
10677       errmsg ("socket file name too long\n");
10678       return -99;
10679     }
10680   vec_add1 (file_name, 0);
10681
10682   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10683
10684   mp->sw_if_index = ntohl (sw_if_index);
10685   mp->is_server = is_server;
10686   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10687   vec_free (file_name);
10688   if (custom_dev_instance != ~0)
10689     {
10690       mp->renumber = 1;
10691       mp->custom_dev_instance = ntohl (custom_dev_instance);
10692     }
10693
10694   S;
10695   W;
10696   /* NOTREACHED */
10697   return 0;
10698 }
10699
10700 static int
10701 api_delete_vhost_user_if (vat_main_t * vam)
10702 {
10703   unformat_input_t *i = vam->input;
10704   vl_api_delete_vhost_user_if_t *mp;
10705   f64 timeout;
10706   u32 sw_if_index = ~0;
10707   u8 sw_if_index_set = 0;
10708
10709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10710     {
10711       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10712         sw_if_index_set = 1;
10713       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10714         sw_if_index_set = 1;
10715       else
10716         break;
10717     }
10718
10719   if (sw_if_index_set == 0)
10720     {
10721       errmsg ("missing sw_if_index or interface name\n");
10722       return -99;
10723     }
10724
10725
10726   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10727
10728   mp->sw_if_index = ntohl (sw_if_index);
10729
10730   S;
10731   W;
10732   /* NOTREACHED */
10733   return 0;
10734 }
10735
10736 static void vl_api_sw_interface_vhost_user_details_t_handler
10737   (vl_api_sw_interface_vhost_user_details_t * mp)
10738 {
10739   vat_main_t *vam = &vat_main;
10740
10741   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10742            (char *) mp->interface_name,
10743            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10744            clib_net_to_host_u64 (mp->features), mp->is_server,
10745            ntohl (mp->num_regions), (char *) mp->sock_filename);
10746   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10747 }
10748
10749 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10750   (vl_api_sw_interface_vhost_user_details_t * mp)
10751 {
10752   vat_main_t *vam = &vat_main;
10753   vat_json_node_t *node = NULL;
10754
10755   if (VAT_JSON_ARRAY != vam->json_tree.type)
10756     {
10757       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10758       vat_json_init_array (&vam->json_tree);
10759     }
10760   node = vat_json_array_add (&vam->json_tree);
10761
10762   vat_json_init_object (node);
10763   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10764   vat_json_object_add_string_copy (node, "interface_name",
10765                                    mp->interface_name);
10766   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10767                             ntohl (mp->virtio_net_hdr_sz));
10768   vat_json_object_add_uint (node, "features",
10769                             clib_net_to_host_u64 (mp->features));
10770   vat_json_object_add_uint (node, "is_server", mp->is_server);
10771   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10772   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10773   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10774 }
10775
10776 static int
10777 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10778 {
10779   vl_api_sw_interface_vhost_user_dump_t *mp;
10780   f64 timeout;
10781   fformat (vam->ofp,
10782            "Interface name           idx hdr_sz features server regions filename\n");
10783
10784   /* Get list of vhost-user interfaces */
10785   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10786   S;
10787
10788   /* Use a control ping for synchronization */
10789   {
10790     vl_api_control_ping_t *mp;
10791     M (CONTROL_PING, control_ping);
10792     S;
10793   }
10794   W;
10795 }
10796
10797 static int
10798 api_show_version (vat_main_t * vam)
10799 {
10800   vl_api_show_version_t *mp;
10801   f64 timeout;
10802
10803   M (SHOW_VERSION, show_version);
10804
10805   S;
10806   W;
10807   /* NOTREACHED */
10808   return 0;
10809 }
10810
10811
10812 static int
10813 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10814 {
10815   unformat_input_t *line_input = vam->input;
10816   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10817   f64 timeout;
10818   ip4_address_t local4, remote4;
10819   ip6_address_t local6, remote6;
10820   u8 is_add = 1;
10821   u8 ipv4_set = 0, ipv6_set = 0;
10822   u8 local_set = 0;
10823   u8 remote_set = 0;
10824   u32 encap_vrf_id = 0;
10825   u32 decap_vrf_id = 0;
10826   u8 protocol = ~0;
10827   u32 vni;
10828   u8 vni_set = 0;
10829
10830   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10831     {
10832       if (unformat (line_input, "del"))
10833         is_add = 0;
10834       else if (unformat (line_input, "local %U",
10835                          unformat_ip4_address, &local4))
10836         {
10837           local_set = 1;
10838           ipv4_set = 1;
10839         }
10840       else if (unformat (line_input, "remote %U",
10841                          unformat_ip4_address, &remote4))
10842         {
10843           remote_set = 1;
10844           ipv4_set = 1;
10845         }
10846       else if (unformat (line_input, "local %U",
10847                          unformat_ip6_address, &local6))
10848         {
10849           local_set = 1;
10850           ipv6_set = 1;
10851         }
10852       else if (unformat (line_input, "remote %U",
10853                          unformat_ip6_address, &remote6))
10854         {
10855           remote_set = 1;
10856           ipv6_set = 1;
10857         }
10858       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10859         ;
10860       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10861         ;
10862       else if (unformat (line_input, "vni %d", &vni))
10863         vni_set = 1;
10864       else if (unformat (line_input, "next-ip4"))
10865         protocol = 1;
10866       else if (unformat (line_input, "next-ip6"))
10867         protocol = 2;
10868       else if (unformat (line_input, "next-ethernet"))
10869         protocol = 3;
10870       else if (unformat (line_input, "next-nsh"))
10871         protocol = 4;
10872       else
10873         {
10874           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10875           return -99;
10876         }
10877     }
10878
10879   if (local_set == 0)
10880     {
10881       errmsg ("tunnel local address not specified\n");
10882       return -99;
10883     }
10884   if (remote_set == 0)
10885     {
10886       errmsg ("tunnel remote address not specified\n");
10887       return -99;
10888     }
10889   if (ipv4_set && ipv6_set)
10890     {
10891       errmsg ("both IPv4 and IPv6 addresses specified");
10892       return -99;
10893     }
10894
10895   if (vni_set == 0)
10896     {
10897       errmsg ("vni not specified\n");
10898       return -99;
10899     }
10900
10901   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10902
10903
10904   if (ipv6_set)
10905     {
10906       clib_memcpy (&mp->local, &local6, sizeof (local6));
10907       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10908     }
10909   else
10910     {
10911       clib_memcpy (&mp->local, &local4, sizeof (local4));
10912       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10913     }
10914
10915   mp->encap_vrf_id = ntohl (encap_vrf_id);
10916   mp->decap_vrf_id = ntohl (decap_vrf_id);
10917   mp->protocol = ntohl (protocol);
10918   mp->vni = ntohl (vni);
10919   mp->is_add = is_add;
10920   mp->is_ipv6 = ipv6_set;
10921
10922   S;
10923   W;
10924   /* NOTREACHED */
10925   return 0;
10926 }
10927
10928 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10929   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10930 {
10931   vat_main_t *vam = &vat_main;
10932
10933   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10934            ntohl (mp->sw_if_index),
10935            format_ip46_address, &(mp->local[0]),
10936            format_ip46_address, &(mp->remote[0]),
10937            ntohl (mp->vni),
10938            ntohl (mp->protocol),
10939            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10940 }
10941
10942 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10943   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10944 {
10945   vat_main_t *vam = &vat_main;
10946   vat_json_node_t *node = NULL;
10947   struct in_addr ip4;
10948   struct in6_addr ip6;
10949
10950   if (VAT_JSON_ARRAY != vam->json_tree.type)
10951     {
10952       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10953       vat_json_init_array (&vam->json_tree);
10954     }
10955   node = vat_json_array_add (&vam->json_tree);
10956
10957   vat_json_init_object (node);
10958   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10959   if (mp->is_ipv6)
10960     {
10961       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10962       vat_json_object_add_ip6 (node, "local", ip6);
10963       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10964       vat_json_object_add_ip6 (node, "remote", ip6);
10965     }
10966   else
10967     {
10968       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10969       vat_json_object_add_ip4 (node, "local", ip4);
10970       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10971       vat_json_object_add_ip4 (node, "remote", ip4);
10972     }
10973   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10974   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10975   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10976   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10977   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10978 }
10979
10980 static int
10981 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10982 {
10983   unformat_input_t *i = vam->input;
10984   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10985   f64 timeout;
10986   u32 sw_if_index;
10987   u8 sw_if_index_set = 0;
10988
10989   /* Parse args required to build the message */
10990   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10991     {
10992       if (unformat (i, "sw_if_index %d", &sw_if_index))
10993         sw_if_index_set = 1;
10994       else
10995         break;
10996     }
10997
10998   if (sw_if_index_set == 0)
10999     {
11000       sw_if_index = ~0;
11001     }
11002
11003   if (!vam->json_output)
11004     {
11005       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
11006                "sw_if_index", "local", "remote", "vni",
11007                "protocol", "encap_vrf_id", "decap_vrf_id");
11008     }
11009
11010   /* Get list of vxlan-tunnel interfaces */
11011   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11012
11013   mp->sw_if_index = htonl (sw_if_index);
11014
11015   S;
11016
11017   /* Use a control ping for synchronization */
11018   {
11019     vl_api_control_ping_t *mp;
11020     M (CONTROL_PING, control_ping);
11021     S;
11022   }
11023   W;
11024 }
11025
11026 u8 *
11027 format_l2_fib_mac_address (u8 * s, va_list * args)
11028 {
11029   u8 *a = va_arg (*args, u8 *);
11030
11031   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11032                  a[2], a[3], a[4], a[5], a[6], a[7]);
11033 }
11034
11035 static void vl_api_l2_fib_table_entry_t_handler
11036   (vl_api_l2_fib_table_entry_t * mp)
11037 {
11038   vat_main_t *vam = &vat_main;
11039
11040   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11041            "       %d       %d     %d\n",
11042            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11043            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11044            mp->bvi_mac);
11045 }
11046
11047 static void vl_api_l2_fib_table_entry_t_handler_json
11048   (vl_api_l2_fib_table_entry_t * mp)
11049 {
11050   vat_main_t *vam = &vat_main;
11051   vat_json_node_t *node = NULL;
11052
11053   if (VAT_JSON_ARRAY != vam->json_tree.type)
11054     {
11055       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11056       vat_json_init_array (&vam->json_tree);
11057     }
11058   node = vat_json_array_add (&vam->json_tree);
11059
11060   vat_json_init_object (node);
11061   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11062   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11063   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11064   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11065   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11066   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11067 }
11068
11069 static int
11070 api_l2_fib_table_dump (vat_main_t * vam)
11071 {
11072   unformat_input_t *i = vam->input;
11073   vl_api_l2_fib_table_dump_t *mp;
11074   f64 timeout;
11075   u32 bd_id;
11076   u8 bd_id_set = 0;
11077
11078   /* Parse args required to build the message */
11079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11080     {
11081       if (unformat (i, "bd_id %d", &bd_id))
11082         bd_id_set = 1;
11083       else
11084         break;
11085     }
11086
11087   if (bd_id_set == 0)
11088     {
11089       errmsg ("missing bridge domain\n");
11090       return -99;
11091     }
11092
11093   fformat (vam->ofp,
11094            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11095
11096   /* Get list of l2 fib entries */
11097   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11098
11099   mp->bd_id = ntohl (bd_id);
11100   S;
11101
11102   /* Use a control ping for synchronization */
11103   {
11104     vl_api_control_ping_t *mp;
11105     M (CONTROL_PING, control_ping);
11106     S;
11107   }
11108   W;
11109 }
11110
11111
11112 static int
11113 api_interface_name_renumber (vat_main_t * vam)
11114 {
11115   unformat_input_t *line_input = vam->input;
11116   vl_api_interface_name_renumber_t *mp;
11117   u32 sw_if_index = ~0;
11118   f64 timeout;
11119   u32 new_show_dev_instance = ~0;
11120
11121   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11122     {
11123       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11124                     &sw_if_index))
11125         ;
11126       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11127         ;
11128       else if (unformat (line_input, "new_show_dev_instance %d",
11129                          &new_show_dev_instance))
11130         ;
11131       else
11132         break;
11133     }
11134
11135   if (sw_if_index == ~0)
11136     {
11137       errmsg ("missing interface name or sw_if_index\n");
11138       return -99;
11139     }
11140
11141   if (new_show_dev_instance == ~0)
11142     {
11143       errmsg ("missing new_show_dev_instance\n");
11144       return -99;
11145     }
11146
11147   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11148
11149   mp->sw_if_index = ntohl (sw_if_index);
11150   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11151
11152   S;
11153   W;
11154 }
11155
11156 static int
11157 api_want_ip4_arp_events (vat_main_t * vam)
11158 {
11159   unformat_input_t *line_input = vam->input;
11160   vl_api_want_ip4_arp_events_t *mp;
11161   f64 timeout;
11162   ip4_address_t address;
11163   int address_set = 0;
11164   u32 enable_disable = 1;
11165
11166   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11167     {
11168       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11169         address_set = 1;
11170       else if (unformat (line_input, "del"))
11171         enable_disable = 0;
11172       else
11173         break;
11174     }
11175
11176   if (address_set == 0)
11177     {
11178       errmsg ("missing addresses\n");
11179       return -99;
11180     }
11181
11182   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11183   mp->enable_disable = enable_disable;
11184   mp->pid = getpid ();
11185   mp->address = address.as_u32;
11186
11187   S;
11188   W;
11189 }
11190
11191 static int
11192 api_want_ip6_nd_events (vat_main_t * vam)
11193 {
11194   unformat_input_t *line_input = vam->input;
11195   vl_api_want_ip6_nd_events_t *mp;
11196   f64 timeout;
11197   ip6_address_t address;
11198   int address_set = 0;
11199   u32 enable_disable = 1;
11200
11201   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11202     {
11203       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11204         address_set = 1;
11205       else if (unformat (line_input, "del"))
11206         enable_disable = 0;
11207       else
11208         break;
11209     }
11210
11211   if (address_set == 0)
11212     {
11213       errmsg ("missing addresses\n");
11214       return -99;
11215     }
11216
11217   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11218   mp->enable_disable = enable_disable;
11219   mp->pid = getpid ();
11220   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11221
11222   S;
11223   W;
11224 }
11225
11226 static int
11227 api_input_acl_set_interface (vat_main_t * vam)
11228 {
11229   unformat_input_t *i = vam->input;
11230   vl_api_input_acl_set_interface_t *mp;
11231   f64 timeout;
11232   u32 sw_if_index;
11233   int sw_if_index_set;
11234   u32 ip4_table_index = ~0;
11235   u32 ip6_table_index = ~0;
11236   u32 l2_table_index = ~0;
11237   u8 is_add = 1;
11238
11239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11240     {
11241       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11242         sw_if_index_set = 1;
11243       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11244         sw_if_index_set = 1;
11245       else if (unformat (i, "del"))
11246         is_add = 0;
11247       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11248         ;
11249       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11250         ;
11251       else if (unformat (i, "l2-table %d", &l2_table_index))
11252         ;
11253       else
11254         {
11255           clib_warning ("parse error '%U'", format_unformat_error, i);
11256           return -99;
11257         }
11258     }
11259
11260   if (sw_if_index_set == 0)
11261     {
11262       errmsg ("missing interface name or sw_if_index\n");
11263       return -99;
11264     }
11265
11266   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11267
11268   mp->sw_if_index = ntohl (sw_if_index);
11269   mp->ip4_table_index = ntohl (ip4_table_index);
11270   mp->ip6_table_index = ntohl (ip6_table_index);
11271   mp->l2_table_index = ntohl (l2_table_index);
11272   mp->is_add = is_add;
11273
11274   S;
11275   W;
11276   /* NOTREACHED */
11277   return 0;
11278 }
11279
11280 static int
11281 api_ip_address_dump (vat_main_t * vam)
11282 {
11283   unformat_input_t *i = vam->input;
11284   vl_api_ip_address_dump_t *mp;
11285   u32 sw_if_index = ~0;
11286   u8 sw_if_index_set = 0;
11287   u8 ipv4_set = 0;
11288   u8 ipv6_set = 0;
11289   f64 timeout;
11290
11291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11292     {
11293       if (unformat (i, "sw_if_index %d", &sw_if_index))
11294         sw_if_index_set = 1;
11295       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11296         sw_if_index_set = 1;
11297       else if (unformat (i, "ipv4"))
11298         ipv4_set = 1;
11299       else if (unformat (i, "ipv6"))
11300         ipv6_set = 1;
11301       else
11302         break;
11303     }
11304
11305   if (ipv4_set && ipv6_set)
11306     {
11307       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11308       return -99;
11309     }
11310
11311   if ((!ipv4_set) && (!ipv6_set))
11312     {
11313       errmsg ("no ipv4 nor ipv6 flag set\n");
11314       return -99;
11315     }
11316
11317   if (sw_if_index_set == 0)
11318     {
11319       errmsg ("missing interface name or sw_if_index\n");
11320       return -99;
11321     }
11322
11323   vam->current_sw_if_index = sw_if_index;
11324   vam->is_ipv6 = ipv6_set;
11325
11326   M (IP_ADDRESS_DUMP, ip_address_dump);
11327   mp->sw_if_index = ntohl (sw_if_index);
11328   mp->is_ipv6 = ipv6_set;
11329   S;
11330
11331   /* Use a control ping for synchronization */
11332   {
11333     vl_api_control_ping_t *mp;
11334     M (CONTROL_PING, control_ping);
11335     S;
11336   }
11337   W;
11338 }
11339
11340 static int
11341 api_ip_dump (vat_main_t * vam)
11342 {
11343   vl_api_ip_dump_t *mp;
11344   unformat_input_t *in = vam->input;
11345   int ipv4_set = 0;
11346   int ipv6_set = 0;
11347   int is_ipv6;
11348   f64 timeout;
11349   int i;
11350
11351   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11352     {
11353       if (unformat (in, "ipv4"))
11354         ipv4_set = 1;
11355       else if (unformat (in, "ipv6"))
11356         ipv6_set = 1;
11357       else
11358         break;
11359     }
11360
11361   if (ipv4_set && ipv6_set)
11362     {
11363       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11364       return -99;
11365     }
11366
11367   if ((!ipv4_set) && (!ipv6_set))
11368     {
11369       errmsg ("no ipv4 nor ipv6 flag set\n");
11370       return -99;
11371     }
11372
11373   is_ipv6 = ipv6_set;
11374   vam->is_ipv6 = is_ipv6;
11375
11376   /* free old data */
11377   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11378     {
11379       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11380     }
11381   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11382
11383   M (IP_DUMP, ip_dump);
11384   mp->is_ipv6 = ipv6_set;
11385   S;
11386
11387   /* Use a control ping for synchronization */
11388   {
11389     vl_api_control_ping_t *mp;
11390     M (CONTROL_PING, control_ping);
11391     S;
11392   }
11393   W;
11394 }
11395
11396 static int
11397 api_ipsec_spd_add_del (vat_main_t * vam)
11398 {
11399 #if DPDK > 0
11400   unformat_input_t *i = vam->input;
11401   vl_api_ipsec_spd_add_del_t *mp;
11402   f64 timeout;
11403   u32 spd_id = ~0;
11404   u8 is_add = 1;
11405
11406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11407     {
11408       if (unformat (i, "spd_id %d", &spd_id))
11409         ;
11410       else if (unformat (i, "del"))
11411         is_add = 0;
11412       else
11413         {
11414           clib_warning ("parse error '%U'", format_unformat_error, i);
11415           return -99;
11416         }
11417     }
11418   if (spd_id == ~0)
11419     {
11420       errmsg ("spd_id must be set\n");
11421       return -99;
11422     }
11423
11424   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11425
11426   mp->spd_id = ntohl (spd_id);
11427   mp->is_add = is_add;
11428
11429   S;
11430   W;
11431   /* NOTREACHED */
11432   return 0;
11433 #else
11434   clib_warning ("unsupported (no dpdk)");
11435   return -99;
11436 #endif
11437 }
11438
11439 static int
11440 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11441 {
11442 #if DPDK > 0
11443   unformat_input_t *i = vam->input;
11444   vl_api_ipsec_interface_add_del_spd_t *mp;
11445   f64 timeout;
11446   u32 sw_if_index;
11447   u8 sw_if_index_set = 0;
11448   u32 spd_id = (u32) ~ 0;
11449   u8 is_add = 1;
11450
11451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11452     {
11453       if (unformat (i, "del"))
11454         is_add = 0;
11455       else if (unformat (i, "spd_id %d", &spd_id))
11456         ;
11457       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11458         sw_if_index_set = 1;
11459       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11460         sw_if_index_set = 1;
11461       else
11462         {
11463           clib_warning ("parse error '%U'", format_unformat_error, i);
11464           return -99;
11465         }
11466
11467     }
11468
11469   if (spd_id == (u32) ~ 0)
11470     {
11471       errmsg ("spd_id must be set\n");
11472       return -99;
11473     }
11474
11475   if (sw_if_index_set == 0)
11476     {
11477       errmsg ("missing interface name or sw_if_index\n");
11478       return -99;
11479     }
11480
11481   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11482
11483   mp->spd_id = ntohl (spd_id);
11484   mp->sw_if_index = ntohl (sw_if_index);
11485   mp->is_add = is_add;
11486
11487   S;
11488   W;
11489   /* NOTREACHED */
11490   return 0;
11491 #else
11492   clib_warning ("unsupported (no dpdk)");
11493   return -99;
11494 #endif
11495 }
11496
11497 static int
11498 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11499 {
11500 #if DPDK > 0
11501   unformat_input_t *i = vam->input;
11502   vl_api_ipsec_spd_add_del_entry_t *mp;
11503   f64 timeout;
11504   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11505   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11506   i32 priority = 0;
11507   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11508   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11509   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11510   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11511
11512   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11513   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11514   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11515   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11516   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11517   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11518
11519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11520     {
11521       if (unformat (i, "del"))
11522         is_add = 0;
11523       if (unformat (i, "outbound"))
11524         is_outbound = 1;
11525       if (unformat (i, "inbound"))
11526         is_outbound = 0;
11527       else if (unformat (i, "spd_id %d", &spd_id))
11528         ;
11529       else if (unformat (i, "sa_id %d", &sa_id))
11530         ;
11531       else if (unformat (i, "priority %d", &priority))
11532         ;
11533       else if (unformat (i, "protocol %d", &protocol))
11534         ;
11535       else if (unformat (i, "lport_start %d", &lport_start))
11536         ;
11537       else if (unformat (i, "lport_stop %d", &lport_stop))
11538         ;
11539       else if (unformat (i, "rport_start %d", &rport_start))
11540         ;
11541       else if (unformat (i, "rport_stop %d", &rport_stop))
11542         ;
11543       else
11544         if (unformat
11545             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11546         {
11547           is_ipv6 = 0;
11548           is_ip_any = 0;
11549         }
11550       else
11551         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11552         {
11553           is_ipv6 = 0;
11554           is_ip_any = 0;
11555         }
11556       else
11557         if (unformat
11558             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11559         {
11560           is_ipv6 = 0;
11561           is_ip_any = 0;
11562         }
11563       else
11564         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11565         {
11566           is_ipv6 = 0;
11567           is_ip_any = 0;
11568         }
11569       else
11570         if (unformat
11571             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11572         {
11573           is_ipv6 = 1;
11574           is_ip_any = 0;
11575         }
11576       else
11577         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11578         {
11579           is_ipv6 = 1;
11580           is_ip_any = 0;
11581         }
11582       else
11583         if (unformat
11584             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11585         {
11586           is_ipv6 = 1;
11587           is_ip_any = 0;
11588         }
11589       else
11590         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11591         {
11592           is_ipv6 = 1;
11593           is_ip_any = 0;
11594         }
11595       else
11596         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11597         {
11598           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11599             {
11600               clib_warning ("unsupported action: 'resolve'");
11601               return -99;
11602             }
11603         }
11604       else
11605         {
11606           clib_warning ("parse error '%U'", format_unformat_error, i);
11607           return -99;
11608         }
11609
11610     }
11611
11612   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11613
11614   mp->spd_id = ntohl (spd_id);
11615   mp->priority = ntohl (priority);
11616   mp->is_outbound = is_outbound;
11617
11618   mp->is_ipv6 = is_ipv6;
11619   if (is_ipv6 || is_ip_any)
11620     {
11621       clib_memcpy (mp->remote_address_start, &raddr6_start,
11622                    sizeof (ip6_address_t));
11623       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11624                    sizeof (ip6_address_t));
11625       clib_memcpy (mp->local_address_start, &laddr6_start,
11626                    sizeof (ip6_address_t));
11627       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11628                    sizeof (ip6_address_t));
11629     }
11630   else
11631     {
11632       clib_memcpy (mp->remote_address_start, &raddr4_start,
11633                    sizeof (ip4_address_t));
11634       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11635                    sizeof (ip4_address_t));
11636       clib_memcpy (mp->local_address_start, &laddr4_start,
11637                    sizeof (ip4_address_t));
11638       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11639                    sizeof (ip4_address_t));
11640     }
11641   mp->protocol = (u8) protocol;
11642   mp->local_port_start = ntohs ((u16) lport_start);
11643   mp->local_port_stop = ntohs ((u16) lport_stop);
11644   mp->remote_port_start = ntohs ((u16) rport_start);
11645   mp->remote_port_stop = ntohs ((u16) rport_stop);
11646   mp->policy = (u8) policy;
11647   mp->sa_id = ntohl (sa_id);
11648   mp->is_add = is_add;
11649   mp->is_ip_any = is_ip_any;
11650   S;
11651   W;
11652   /* NOTREACHED */
11653   return 0;
11654 #else
11655   clib_warning ("unsupported (no dpdk)");
11656   return -99;
11657 #endif
11658 }
11659
11660 static int
11661 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11662 {
11663 #if DPDK > 0
11664   unformat_input_t *i = vam->input;
11665   vl_api_ipsec_sad_add_del_entry_t *mp;
11666   f64 timeout;
11667   u32 sad_id = 0, spi = 0;
11668   u8 *ck = 0, *ik = 0;
11669   u8 is_add = 1;
11670
11671   u8 protocol = IPSEC_PROTOCOL_AH;
11672   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11673   u32 crypto_alg = 0, integ_alg = 0;
11674   ip4_address_t tun_src4;
11675   ip4_address_t tun_dst4;
11676   ip6_address_t tun_src6;
11677   ip6_address_t tun_dst6;
11678
11679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11680     {
11681       if (unformat (i, "del"))
11682         is_add = 0;
11683       else if (unformat (i, "sad_id %d", &sad_id))
11684         ;
11685       else if (unformat (i, "spi %d", &spi))
11686         ;
11687       else if (unformat (i, "esp"))
11688         protocol = IPSEC_PROTOCOL_ESP;
11689       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11690         {
11691           is_tunnel = 1;
11692           is_tunnel_ipv6 = 0;
11693         }
11694       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11695         {
11696           is_tunnel = 1;
11697           is_tunnel_ipv6 = 0;
11698         }
11699       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11700         {
11701           is_tunnel = 1;
11702           is_tunnel_ipv6 = 1;
11703         }
11704       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11705         {
11706           is_tunnel = 1;
11707           is_tunnel_ipv6 = 1;
11708         }
11709       else
11710         if (unformat
11711             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11712         {
11713           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11714               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11715             {
11716               clib_warning ("unsupported crypto-alg: '%U'",
11717                             format_ipsec_crypto_alg, crypto_alg);
11718               return -99;
11719             }
11720         }
11721       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11722         ;
11723       else
11724         if (unformat
11725             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11726         {
11727           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11728               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11729             {
11730               clib_warning ("unsupported integ-alg: '%U'",
11731                             format_ipsec_integ_alg, integ_alg);
11732               return -99;
11733             }
11734         }
11735       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11736         ;
11737       else
11738         {
11739           clib_warning ("parse error '%U'", format_unformat_error, i);
11740           return -99;
11741         }
11742
11743     }
11744
11745   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11746
11747   mp->sad_id = ntohl (sad_id);
11748   mp->is_add = is_add;
11749   mp->protocol = protocol;
11750   mp->spi = ntohl (spi);
11751   mp->is_tunnel = is_tunnel;
11752   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11753   mp->crypto_algorithm = crypto_alg;
11754   mp->integrity_algorithm = integ_alg;
11755   mp->crypto_key_length = vec_len (ck);
11756   mp->integrity_key_length = vec_len (ik);
11757
11758   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11759     mp->crypto_key_length = sizeof (mp->crypto_key);
11760
11761   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11762     mp->integrity_key_length = sizeof (mp->integrity_key);
11763
11764   if (ck)
11765     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11766   if (ik)
11767     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11768
11769   if (is_tunnel)
11770     {
11771       if (is_tunnel_ipv6)
11772         {
11773           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11774                        sizeof (ip6_address_t));
11775           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11776                        sizeof (ip6_address_t));
11777         }
11778       else
11779         {
11780           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11781                        sizeof (ip4_address_t));
11782           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11783                        sizeof (ip4_address_t));
11784         }
11785     }
11786
11787   S;
11788   W;
11789   /* NOTREACHED */
11790   return 0;
11791 #else
11792   clib_warning ("unsupported (no dpdk)");
11793   return -99;
11794 #endif
11795 }
11796
11797 static int
11798 api_ipsec_sa_set_key (vat_main_t * vam)
11799 {
11800 #if DPDK > 0
11801   unformat_input_t *i = vam->input;
11802   vl_api_ipsec_sa_set_key_t *mp;
11803   f64 timeout;
11804   u32 sa_id;
11805   u8 *ck = 0, *ik = 0;
11806
11807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11808     {
11809       if (unformat (i, "sa_id %d", &sa_id))
11810         ;
11811       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11812         ;
11813       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11814         ;
11815       else
11816         {
11817           clib_warning ("parse error '%U'", format_unformat_error, i);
11818           return -99;
11819         }
11820     }
11821
11822   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11823
11824   mp->sa_id = ntohl (sa_id);
11825   mp->crypto_key_length = vec_len (ck);
11826   mp->integrity_key_length = vec_len (ik);
11827
11828   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11829     mp->crypto_key_length = sizeof (mp->crypto_key);
11830
11831   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11832     mp->integrity_key_length = sizeof (mp->integrity_key);
11833
11834   if (ck)
11835     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11836   if (ik)
11837     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11838
11839   S;
11840   W;
11841   /* NOTREACHED */
11842   return 0;
11843 #else
11844   clib_warning ("unsupported (no dpdk)");
11845   return -99;
11846 #endif
11847 }
11848
11849 static int
11850 api_ikev2_profile_add_del (vat_main_t * vam)
11851 {
11852 #if DPDK > 0
11853   unformat_input_t *i = vam->input;
11854   vl_api_ikev2_profile_add_del_t *mp;
11855   f64 timeout;
11856   u8 is_add = 1;
11857   u8 *name = 0;
11858
11859   const char *valid_chars = "a-zA-Z0-9_";
11860
11861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11862     {
11863       if (unformat (i, "del"))
11864         is_add = 0;
11865       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11866         vec_add1 (name, 0);
11867       else
11868         {
11869           errmsg ("parse error '%U'", format_unformat_error, i);
11870           return -99;
11871         }
11872     }
11873
11874   if (!vec_len (name))
11875     {
11876       errmsg ("profile name must be specified");
11877       return -99;
11878     }
11879
11880   if (vec_len (name) > 64)
11881     {
11882       errmsg ("profile name too long");
11883       return -99;
11884     }
11885
11886   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11887
11888   clib_memcpy (mp->name, name, vec_len (name));
11889   mp->is_add = is_add;
11890   vec_free (name);
11891
11892   S;
11893   W;
11894   /* NOTREACHED */
11895   return 0;
11896 #else
11897   clib_warning ("unsupported (no dpdk)");
11898   return -99;
11899 #endif
11900 }
11901
11902 static int
11903 api_ikev2_profile_set_auth (vat_main_t * vam)
11904 {
11905 #if DPDK > 0
11906   unformat_input_t *i = vam->input;
11907   vl_api_ikev2_profile_set_auth_t *mp;
11908   f64 timeout;
11909   u8 *name = 0;
11910   u8 *data = 0;
11911   u32 auth_method = 0;
11912   u8 is_hex = 0;
11913
11914   const char *valid_chars = "a-zA-Z0-9_";
11915
11916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11917     {
11918       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11919         vec_add1 (name, 0);
11920       else if (unformat (i, "auth_method %U",
11921                          unformat_ikev2_auth_method, &auth_method))
11922         ;
11923       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11924         is_hex = 1;
11925       else if (unformat (i, "auth_data %v", &data))
11926         ;
11927       else
11928         {
11929           errmsg ("parse error '%U'", format_unformat_error, i);
11930           return -99;
11931         }
11932     }
11933
11934   if (!vec_len (name))
11935     {
11936       errmsg ("profile name must be specified");
11937       return -99;
11938     }
11939
11940   if (vec_len (name) > 64)
11941     {
11942       errmsg ("profile name too long");
11943       return -99;
11944     }
11945
11946   if (!vec_len (data))
11947     {
11948       errmsg ("auth_data must be specified");
11949       return -99;
11950     }
11951
11952   if (!auth_method)
11953     {
11954       errmsg ("auth_method must be specified");
11955       return -99;
11956     }
11957
11958   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11959
11960   mp->is_hex = is_hex;
11961   mp->auth_method = (u8) auth_method;
11962   mp->data_len = vec_len (data);
11963   clib_memcpy (mp->name, name, vec_len (name));
11964   clib_memcpy (mp->data, data, vec_len (data));
11965   vec_free (name);
11966   vec_free (data);
11967
11968   S;
11969   W;
11970   /* NOTREACHED */
11971   return 0;
11972 #else
11973   clib_warning ("unsupported (no dpdk)");
11974   return -99;
11975 #endif
11976 }
11977
11978 static int
11979 api_ikev2_profile_set_id (vat_main_t * vam)
11980 {
11981 #if DPDK > 0
11982   unformat_input_t *i = vam->input;
11983   vl_api_ikev2_profile_set_id_t *mp;
11984   f64 timeout;
11985   u8 *name = 0;
11986   u8 *data = 0;
11987   u8 is_local = 0;
11988   u32 id_type = 0;
11989   ip4_address_t ip4;
11990
11991   const char *valid_chars = "a-zA-Z0-9_";
11992
11993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11994     {
11995       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11996         vec_add1 (name, 0);
11997       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11998         ;
11999       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12000         {
12001           data = vec_new (u8, 4);
12002           clib_memcpy (data, ip4.as_u8, 4);
12003         }
12004       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12005         ;
12006       else if (unformat (i, "id_data %v", &data))
12007         ;
12008       else if (unformat (i, "local"))
12009         is_local = 1;
12010       else if (unformat (i, "remote"))
12011         is_local = 0;
12012       else
12013         {
12014           errmsg ("parse error '%U'", format_unformat_error, i);
12015           return -99;
12016         }
12017     }
12018
12019   if (!vec_len (name))
12020     {
12021       errmsg ("profile name must be specified");
12022       return -99;
12023     }
12024
12025   if (vec_len (name) > 64)
12026     {
12027       errmsg ("profile name too long");
12028       return -99;
12029     }
12030
12031   if (!vec_len (data))
12032     {
12033       errmsg ("id_data must be specified");
12034       return -99;
12035     }
12036
12037   if (!id_type)
12038     {
12039       errmsg ("id_type must be specified");
12040       return -99;
12041     }
12042
12043   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12044
12045   mp->is_local = is_local;
12046   mp->id_type = (u8) id_type;
12047   mp->data_len = vec_len (data);
12048   clib_memcpy (mp->name, name, vec_len (name));
12049   clib_memcpy (mp->data, data, vec_len (data));
12050   vec_free (name);
12051   vec_free (data);
12052
12053   S;
12054   W;
12055   /* NOTREACHED */
12056   return 0;
12057 #else
12058   clib_warning ("unsupported (no dpdk)");
12059   return -99;
12060 #endif
12061 }
12062
12063 static int
12064 api_ikev2_profile_set_ts (vat_main_t * vam)
12065 {
12066 #if DPDK > 0
12067   unformat_input_t *i = vam->input;
12068   vl_api_ikev2_profile_set_ts_t *mp;
12069   f64 timeout;
12070   u8 *name = 0;
12071   u8 is_local = 0;
12072   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12073   ip4_address_t start_addr, end_addr;
12074
12075   const char *valid_chars = "a-zA-Z0-9_";
12076
12077   start_addr.as_u32 = 0;
12078   end_addr.as_u32 = (u32) ~ 0;
12079
12080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12081     {
12082       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12083         vec_add1 (name, 0);
12084       else if (unformat (i, "protocol %d", &proto))
12085         ;
12086       else if (unformat (i, "start_port %d", &start_port))
12087         ;
12088       else if (unformat (i, "end_port %d", &end_port))
12089         ;
12090       else
12091         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12092         ;
12093       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12094         ;
12095       else if (unformat (i, "local"))
12096         is_local = 1;
12097       else if (unformat (i, "remote"))
12098         is_local = 0;
12099       else
12100         {
12101           errmsg ("parse error '%U'", format_unformat_error, i);
12102           return -99;
12103         }
12104     }
12105
12106   if (!vec_len (name))
12107     {
12108       errmsg ("profile name must be specified");
12109       return -99;
12110     }
12111
12112   if (vec_len (name) > 64)
12113     {
12114       errmsg ("profile name too long");
12115       return -99;
12116     }
12117
12118   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12119
12120   mp->is_local = is_local;
12121   mp->proto = (u8) proto;
12122   mp->start_port = (u16) start_port;
12123   mp->end_port = (u16) end_port;
12124   mp->start_addr = start_addr.as_u32;
12125   mp->end_addr = end_addr.as_u32;
12126   clib_memcpy (mp->name, name, vec_len (name));
12127   vec_free (name);
12128
12129   S;
12130   W;
12131   /* NOTREACHED */
12132   return 0;
12133 #else
12134   clib_warning ("unsupported (no dpdk)");
12135   return -99;
12136 #endif
12137 }
12138
12139 static int
12140 api_ikev2_set_local_key (vat_main_t * vam)
12141 {
12142 #if DPDK > 0
12143   unformat_input_t *i = vam->input;
12144   vl_api_ikev2_set_local_key_t *mp;
12145   f64 timeout;
12146   u8 *file = 0;
12147
12148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12149     {
12150       if (unformat (i, "file %v", &file))
12151         vec_add1 (file, 0);
12152       else
12153         {
12154           errmsg ("parse error '%U'", format_unformat_error, i);
12155           return -99;
12156         }
12157     }
12158
12159   if (!vec_len (file))
12160     {
12161       errmsg ("RSA key file must be specified");
12162       return -99;
12163     }
12164
12165   if (vec_len (file) > 256)
12166     {
12167       errmsg ("file name too long");
12168       return -99;
12169     }
12170
12171   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12172
12173   clib_memcpy (mp->key_file, file, vec_len (file));
12174   vec_free (file);
12175
12176   S;
12177   W;
12178   /* NOTREACHED */
12179   return 0;
12180 #else
12181   clib_warning ("unsupported (no dpdk)");
12182   return -99;
12183 #endif
12184 }
12185
12186 /*
12187  * MAP
12188  */
12189 static int
12190 api_map_add_domain (vat_main_t * vam)
12191 {
12192   unformat_input_t *i = vam->input;
12193   vl_api_map_add_domain_t *mp;
12194   f64 timeout;
12195
12196   ip4_address_t ip4_prefix;
12197   ip6_address_t ip6_prefix;
12198   ip6_address_t ip6_src;
12199   u32 num_m_args = 0;
12200   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12201     0, psid_length = 0;
12202   u8 is_translation = 0;
12203   u32 mtu = 0;
12204   u32 ip6_src_len = 128;
12205
12206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12207     {
12208       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12209                     &ip4_prefix, &ip4_prefix_len))
12210         num_m_args++;
12211       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12212                          &ip6_prefix, &ip6_prefix_len))
12213         num_m_args++;
12214       else
12215         if (unformat
12216             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12217              &ip6_src_len))
12218         num_m_args++;
12219       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12220         num_m_args++;
12221       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12222         num_m_args++;
12223       else if (unformat (i, "psid-offset %d", &psid_offset))
12224         num_m_args++;
12225       else if (unformat (i, "psid-len %d", &psid_length))
12226         num_m_args++;
12227       else if (unformat (i, "mtu %d", &mtu))
12228         num_m_args++;
12229       else if (unformat (i, "map-t"))
12230         is_translation = 1;
12231       else
12232         {
12233           clib_warning ("parse error '%U'", format_unformat_error, i);
12234           return -99;
12235         }
12236     }
12237
12238   if (num_m_args < 3)
12239     {
12240       errmsg ("mandatory argument(s) missing\n");
12241       return -99;
12242     }
12243
12244   /* Construct the API message */
12245   M (MAP_ADD_DOMAIN, map_add_domain);
12246
12247   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12248   mp->ip4_prefix_len = ip4_prefix_len;
12249
12250   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12251   mp->ip6_prefix_len = ip6_prefix_len;
12252
12253   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12254   mp->ip6_src_prefix_len = ip6_src_len;
12255
12256   mp->ea_bits_len = ea_bits_len;
12257   mp->psid_offset = psid_offset;
12258   mp->psid_length = psid_length;
12259   mp->is_translation = is_translation;
12260   mp->mtu = htons (mtu);
12261
12262   /* send it... */
12263   S;
12264
12265   /* Wait for a reply, return good/bad news  */
12266   W;
12267 }
12268
12269 static int
12270 api_map_del_domain (vat_main_t * vam)
12271 {
12272   unformat_input_t *i = vam->input;
12273   vl_api_map_del_domain_t *mp;
12274   f64 timeout;
12275
12276   u32 num_m_args = 0;
12277   u32 index;
12278
12279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12280     {
12281       if (unformat (i, "index %d", &index))
12282         num_m_args++;
12283       else
12284         {
12285           clib_warning ("parse error '%U'", format_unformat_error, i);
12286           return -99;
12287         }
12288     }
12289
12290   if (num_m_args != 1)
12291     {
12292       errmsg ("mandatory argument(s) missing\n");
12293       return -99;
12294     }
12295
12296   /* Construct the API message */
12297   M (MAP_DEL_DOMAIN, map_del_domain);
12298
12299   mp->index = ntohl (index);
12300
12301   /* send it... */
12302   S;
12303
12304   /* Wait for a reply, return good/bad news  */
12305   W;
12306 }
12307
12308 static int
12309 api_map_add_del_rule (vat_main_t * vam)
12310 {
12311   unformat_input_t *i = vam->input;
12312   vl_api_map_add_del_rule_t *mp;
12313   f64 timeout;
12314   u8 is_add = 1;
12315   ip6_address_t ip6_dst;
12316   u32 num_m_args = 0, index, psid = 0;
12317
12318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12319     {
12320       if (unformat (i, "index %d", &index))
12321         num_m_args++;
12322       else if (unformat (i, "psid %d", &psid))
12323         num_m_args++;
12324       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12325         num_m_args++;
12326       else if (unformat (i, "del"))
12327         {
12328           is_add = 0;
12329         }
12330       else
12331         {
12332           clib_warning ("parse error '%U'", format_unformat_error, i);
12333           return -99;
12334         }
12335     }
12336
12337   /* Construct the API message */
12338   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12339
12340   mp->index = ntohl (index);
12341   mp->is_add = is_add;
12342   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12343   mp->psid = ntohs (psid);
12344
12345   /* send it... */
12346   S;
12347
12348   /* Wait for a reply, return good/bad news  */
12349   W;
12350 }
12351
12352 static int
12353 api_map_domain_dump (vat_main_t * vam)
12354 {
12355   vl_api_map_domain_dump_t *mp;
12356   f64 timeout;
12357
12358   /* Construct the API message */
12359   M (MAP_DOMAIN_DUMP, map_domain_dump);
12360
12361   /* send it... */
12362   S;
12363
12364   /* Use a control ping for synchronization */
12365   {
12366     vl_api_control_ping_t *mp;
12367     M (CONTROL_PING, control_ping);
12368     S;
12369   }
12370   W;
12371 }
12372
12373 static int
12374 api_map_rule_dump (vat_main_t * vam)
12375 {
12376   unformat_input_t *i = vam->input;
12377   vl_api_map_rule_dump_t *mp;
12378   f64 timeout;
12379   u32 domain_index = ~0;
12380
12381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12382     {
12383       if (unformat (i, "index %u", &domain_index))
12384         ;
12385       else
12386         break;
12387     }
12388
12389   if (domain_index == ~0)
12390     {
12391       clib_warning ("parse error: domain index expected");
12392       return -99;
12393     }
12394
12395   /* Construct the API message */
12396   M (MAP_RULE_DUMP, map_rule_dump);
12397
12398   mp->domain_index = htonl (domain_index);
12399
12400   /* send it... */
12401   S;
12402
12403   /* Use a control ping for synchronization */
12404   {
12405     vl_api_control_ping_t *mp;
12406     M (CONTROL_PING, control_ping);
12407     S;
12408   }
12409   W;
12410 }
12411
12412 static void vl_api_map_add_domain_reply_t_handler
12413   (vl_api_map_add_domain_reply_t * mp)
12414 {
12415   vat_main_t *vam = &vat_main;
12416   i32 retval = ntohl (mp->retval);
12417
12418   if (vam->async_mode)
12419     {
12420       vam->async_errors += (retval < 0);
12421     }
12422   else
12423     {
12424       vam->retval = retval;
12425       vam->result_ready = 1;
12426     }
12427 }
12428
12429 static void vl_api_map_add_domain_reply_t_handler_json
12430   (vl_api_map_add_domain_reply_t * mp)
12431 {
12432   vat_main_t *vam = &vat_main;
12433   vat_json_node_t node;
12434
12435   vat_json_init_object (&node);
12436   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12437   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12438
12439   vat_json_print (vam->ofp, &node);
12440   vat_json_free (&node);
12441
12442   vam->retval = ntohl (mp->retval);
12443   vam->result_ready = 1;
12444 }
12445
12446 static int
12447 api_get_first_msg_id (vat_main_t * vam)
12448 {
12449   vl_api_get_first_msg_id_t *mp;
12450   f64 timeout;
12451   unformat_input_t *i = vam->input;
12452   u8 *name;
12453   u8 name_set = 0;
12454
12455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12456     {
12457       if (unformat (i, "client %s", &name))
12458         name_set = 1;
12459       else
12460         break;
12461     }
12462
12463   if (name_set == 0)
12464     {
12465       errmsg ("missing client name\n");
12466       return -99;
12467     }
12468   vec_add1 (name, 0);
12469
12470   if (vec_len (name) > 63)
12471     {
12472       errmsg ("client name too long\n");
12473       return -99;
12474     }
12475
12476   M (GET_FIRST_MSG_ID, get_first_msg_id);
12477   clib_memcpy (mp->name, name, vec_len (name));
12478   S;
12479   W;
12480   /* NOTREACHED */
12481   return 0;
12482 }
12483
12484 static int
12485 api_cop_interface_enable_disable (vat_main_t * vam)
12486 {
12487   unformat_input_t *line_input = vam->input;
12488   vl_api_cop_interface_enable_disable_t *mp;
12489   f64 timeout;
12490   u32 sw_if_index = ~0;
12491   u8 enable_disable = 1;
12492
12493   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12494     {
12495       if (unformat (line_input, "disable"))
12496         enable_disable = 0;
12497       if (unformat (line_input, "enable"))
12498         enable_disable = 1;
12499       else if (unformat (line_input, "%U", unformat_sw_if_index,
12500                          vam, &sw_if_index))
12501         ;
12502       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12503         ;
12504       else
12505         break;
12506     }
12507
12508   if (sw_if_index == ~0)
12509     {
12510       errmsg ("missing interface name or sw_if_index\n");
12511       return -99;
12512     }
12513
12514   /* Construct the API message */
12515   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12516   mp->sw_if_index = ntohl (sw_if_index);
12517   mp->enable_disable = enable_disable;
12518
12519   /* send it... */
12520   S;
12521   /* Wait for the reply */
12522   W;
12523 }
12524
12525 static int
12526 api_cop_whitelist_enable_disable (vat_main_t * vam)
12527 {
12528   unformat_input_t *line_input = vam->input;
12529   vl_api_cop_whitelist_enable_disable_t *mp;
12530   f64 timeout;
12531   u32 sw_if_index = ~0;
12532   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12533   u32 fib_id = 0;
12534
12535   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12536     {
12537       if (unformat (line_input, "ip4"))
12538         ip4 = 1;
12539       else if (unformat (line_input, "ip6"))
12540         ip6 = 1;
12541       else if (unformat (line_input, "default"))
12542         default_cop = 1;
12543       else if (unformat (line_input, "%U", unformat_sw_if_index,
12544                          vam, &sw_if_index))
12545         ;
12546       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12547         ;
12548       else if (unformat (line_input, "fib-id %d", &fib_id))
12549         ;
12550       else
12551         break;
12552     }
12553
12554   if (sw_if_index == ~0)
12555     {
12556       errmsg ("missing interface name or sw_if_index\n");
12557       return -99;
12558     }
12559
12560   /* Construct the API message */
12561   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12562   mp->sw_if_index = ntohl (sw_if_index);
12563   mp->fib_id = ntohl (fib_id);
12564   mp->ip4 = ip4;
12565   mp->ip6 = ip6;
12566   mp->default_cop = default_cop;
12567
12568   /* send it... */
12569   S;
12570   /* Wait for the reply */
12571   W;
12572 }
12573
12574 static int
12575 api_get_node_graph (vat_main_t * vam)
12576 {
12577   vl_api_get_node_graph_t *mp;
12578   f64 timeout;
12579
12580   M (GET_NODE_GRAPH, get_node_graph);
12581
12582   /* send it... */
12583   S;
12584   /* Wait for the reply */
12585   W;
12586 }
12587
12588 /* *INDENT-OFF* */
12589 /** Used for parsing LISP eids */
12590 typedef CLIB_PACKED(struct{
12591   u8 addr[16];   /**< eid address */
12592   u32 len;       /**< prefix length if IP */
12593   u8 type;      /**< type of eid */
12594 }) lisp_eid_vat_t;
12595 /* *INDENT-ON* */
12596
12597 static uword
12598 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12599 {
12600   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12601
12602   memset (a, 0, sizeof (a[0]));
12603
12604   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12605     {
12606       a->type = 0;              /* ipv4 type */
12607     }
12608   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12609     {
12610       a->type = 1;              /* ipv6 type */
12611     }
12612   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12613     {
12614       a->type = 2;              /* mac type */
12615     }
12616   else
12617     {
12618       return 0;
12619     }
12620
12621   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12622     {
12623       return 0;
12624     }
12625
12626   return 1;
12627 }
12628
12629 static int
12630 lisp_eid_size_vat (u8 type)
12631 {
12632   switch (type)
12633     {
12634     case 0:
12635       return 4;
12636     case 1:
12637       return 16;
12638     case 2:
12639       return 6;
12640     }
12641   return 0;
12642 }
12643
12644 static void
12645 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12646 {
12647   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12648 }
12649
12650 /* *INDENT-OFF* */
12651 /** Used for transferring locators via VPP API */
12652 typedef CLIB_PACKED(struct
12653 {
12654   u32 sw_if_index; /**< locator sw_if_index */
12655   u8 priority; /**< locator priority */
12656   u8 weight;   /**< locator weight */
12657 }) ls_locator_t;
12658 /* *INDENT-ON* */
12659
12660 static int
12661 api_lisp_add_del_locator_set (vat_main_t * vam)
12662 {
12663   unformat_input_t *input = vam->input;
12664   vl_api_lisp_add_del_locator_set_t *mp;
12665   f64 timeout = ~0;
12666   u8 is_add = 1;
12667   u8 *locator_set_name = NULL;
12668   u8 locator_set_name_set = 0;
12669   ls_locator_t locator, *locators = 0;
12670   u32 sw_if_index, priority, weight;
12671   u32 data_len = 0;
12672
12673   /* Parse args required to build the message */
12674   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12675     {
12676       if (unformat (input, "del"))
12677         {
12678           is_add = 0;
12679         }
12680       else if (unformat (input, "locator-set %s", &locator_set_name))
12681         {
12682           locator_set_name_set = 1;
12683         }
12684       else if (unformat (input, "sw_if_index %u p %u w %u",
12685                          &sw_if_index, &priority, &weight))
12686         {
12687           locator.sw_if_index = htonl (sw_if_index);
12688           locator.priority = priority;
12689           locator.weight = weight;
12690           vec_add1 (locators, locator);
12691         }
12692       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12693                          vam, &sw_if_index, &priority, &weight))
12694         {
12695           locator.sw_if_index = htonl (sw_if_index);
12696           locator.priority = priority;
12697           locator.weight = weight;
12698           vec_add1 (locators, locator);
12699         }
12700       else
12701         break;
12702     }
12703
12704   if (locator_set_name_set == 0)
12705     {
12706       errmsg ("missing locator-set name");
12707       vec_free (locators);
12708       return -99;
12709     }
12710
12711   if (vec_len (locator_set_name) > 64)
12712     {
12713       errmsg ("locator-set name too long\n");
12714       vec_free (locator_set_name);
12715       vec_free (locators);
12716       return -99;
12717     }
12718   vec_add1 (locator_set_name, 0);
12719
12720   data_len = sizeof (ls_locator_t) * vec_len (locators);
12721
12722   /* Construct the API message */
12723   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12724
12725   mp->is_add = is_add;
12726   clib_memcpy (mp->locator_set_name, locator_set_name,
12727                vec_len (locator_set_name));
12728   vec_free (locator_set_name);
12729
12730   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12731   if (locators)
12732     clib_memcpy (mp->locators, locators, data_len);
12733   vec_free (locators);
12734
12735   /* send it... */
12736   S;
12737
12738   /* Wait for a reply... */
12739   W;
12740
12741   /* NOTREACHED */
12742   return 0;
12743 }
12744
12745 static int
12746 api_lisp_add_del_locator (vat_main_t * vam)
12747 {
12748   unformat_input_t *input = vam->input;
12749   vl_api_lisp_add_del_locator_t *mp;
12750   f64 timeout = ~0;
12751   u32 tmp_if_index = ~0;
12752   u32 sw_if_index = ~0;
12753   u8 sw_if_index_set = 0;
12754   u8 sw_if_index_if_name_set = 0;
12755   u32 priority = ~0;
12756   u8 priority_set = 0;
12757   u32 weight = ~0;
12758   u8 weight_set = 0;
12759   u8 is_add = 1;
12760   u8 *locator_set_name = NULL;
12761   u8 locator_set_name_set = 0;
12762
12763   /* Parse args required to build the message */
12764   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12765     {
12766       if (unformat (input, "del"))
12767         {
12768           is_add = 0;
12769         }
12770       else if (unformat (input, "locator-set %s", &locator_set_name))
12771         {
12772           locator_set_name_set = 1;
12773         }
12774       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12775                          &tmp_if_index))
12776         {
12777           sw_if_index_if_name_set = 1;
12778           sw_if_index = tmp_if_index;
12779         }
12780       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12781         {
12782           sw_if_index_set = 1;
12783           sw_if_index = tmp_if_index;
12784         }
12785       else if (unformat (input, "p %d", &priority))
12786         {
12787           priority_set = 1;
12788         }
12789       else if (unformat (input, "w %d", &weight))
12790         {
12791           weight_set = 1;
12792         }
12793       else
12794         break;
12795     }
12796
12797   if (locator_set_name_set == 0)
12798     {
12799       errmsg ("missing locator-set name");
12800       return -99;
12801     }
12802
12803   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12804     {
12805       errmsg ("missing sw_if_index");
12806       vec_free (locator_set_name);
12807       return -99;
12808     }
12809
12810   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12811     {
12812       errmsg ("cannot use both params interface name and sw_if_index");
12813       vec_free (locator_set_name);
12814       return -99;
12815     }
12816
12817   if (priority_set == 0)
12818     {
12819       errmsg ("missing locator-set priority\n");
12820       vec_free (locator_set_name);
12821       return -99;
12822     }
12823
12824   if (weight_set == 0)
12825     {
12826       errmsg ("missing locator-set weight\n");
12827       vec_free (locator_set_name);
12828       return -99;
12829     }
12830
12831   if (vec_len (locator_set_name) > 64)
12832     {
12833       errmsg ("locator-set name too long\n");
12834       vec_free (locator_set_name);
12835       return -99;
12836     }
12837   vec_add1 (locator_set_name, 0);
12838
12839   /* Construct the API message */
12840   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12841
12842   mp->is_add = is_add;
12843   mp->sw_if_index = ntohl (sw_if_index);
12844   mp->priority = priority;
12845   mp->weight = weight;
12846   clib_memcpy (mp->locator_set_name, locator_set_name,
12847                vec_len (locator_set_name));
12848   vec_free (locator_set_name);
12849
12850   /* send it... */
12851   S;
12852
12853   /* Wait for a reply... */
12854   W;
12855
12856   /* NOTREACHED */
12857   return 0;
12858 }
12859
12860 static int
12861 api_lisp_add_del_local_eid (vat_main_t * vam)
12862 {
12863   unformat_input_t *input = vam->input;
12864   vl_api_lisp_add_del_local_eid_t *mp;
12865   f64 timeout = ~0;
12866   u8 is_add = 1;
12867   u8 eid_set = 0;
12868   lisp_eid_vat_t _eid, *eid = &_eid;
12869   u8 *locator_set_name = 0;
12870   u8 locator_set_name_set = 0;
12871   u32 vni = 0;
12872
12873   /* Parse args required to build the message */
12874   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12875     {
12876       if (unformat (input, "del"))
12877         {
12878           is_add = 0;
12879         }
12880       else if (unformat (input, "vni %d", &vni))
12881         {
12882           ;
12883         }
12884       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12885         {
12886           eid_set = 1;
12887         }
12888       else if (unformat (input, "locator-set %s", &locator_set_name))
12889         {
12890           locator_set_name_set = 1;
12891         }
12892       else
12893         break;
12894     }
12895
12896   if (locator_set_name_set == 0)
12897     {
12898       errmsg ("missing locator-set name\n");
12899       return -99;
12900     }
12901
12902   if (0 == eid_set)
12903     {
12904       errmsg ("EID address not set!");
12905       vec_free (locator_set_name);
12906       return -99;
12907     }
12908
12909   if (vec_len (locator_set_name) > 64)
12910     {
12911       errmsg ("locator-set name too long\n");
12912       vec_free (locator_set_name);
12913       return -99;
12914     }
12915   vec_add1 (locator_set_name, 0);
12916
12917   /* Construct the API message */
12918   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12919
12920   mp->is_add = is_add;
12921   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12922   mp->eid_type = eid->type;
12923   mp->prefix_len = eid->len;
12924   mp->vni = clib_host_to_net_u32 (vni);
12925   clib_memcpy (mp->locator_set_name, locator_set_name,
12926                vec_len (locator_set_name));
12927
12928   vec_free (locator_set_name);
12929
12930   /* send it... */
12931   S;
12932
12933   /* Wait for a reply... */
12934   W;
12935
12936   /* NOTREACHED */
12937   return 0;
12938 }
12939
12940 /* *INDENT-OFF* */
12941 /** Used for transferring locators via VPP API */
12942 typedef CLIB_PACKED(struct
12943 {
12944   u8 is_ip4; /**< is locator an IPv4 address? */
12945   u8 priority; /**< locator priority */
12946   u8 weight;   /**< locator weight */
12947   u8 addr[16]; /**< IPv4/IPv6 address */
12948 }) rloc_t;
12949 /* *INDENT-ON* */
12950
12951 static int
12952 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12953 {
12954   unformat_input_t *input = vam->input;
12955   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12956   f64 timeout = ~0;
12957   u8 is_add = 1;
12958   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12959   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12960   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12961   u32 action = ~0, p, w;
12962   ip4_address_t rmt_rloc4, lcl_rloc4;
12963   ip6_address_t rmt_rloc6, lcl_rloc6;
12964   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12965
12966   memset (&rloc, 0, sizeof (rloc));
12967
12968   /* Parse args required to build the message */
12969   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12970     {
12971       if (unformat (input, "del"))
12972         {
12973           is_add = 0;
12974         }
12975       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12976         {
12977           rmt_eid_set = 1;
12978         }
12979       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12980         {
12981           lcl_eid_set = 1;
12982         }
12983       else if (unformat (input, "p %d w %d", &p, &w))
12984         {
12985           if (!curr_rloc)
12986             {
12987               errmsg ("No RLOC configured for setting priority/weight!");
12988               return -99;
12989             }
12990           curr_rloc->priority = p;
12991           curr_rloc->weight = w;
12992         }
12993       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12994                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12995         {
12996           rloc.is_ip4 = 1;
12997
12998           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12999           rloc.priority = rloc.weight = 0;
13000           vec_add1 (lcl_locs, rloc);
13001
13002           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13003           vec_add1 (rmt_locs, rloc);
13004           /* priority and weight saved in rmt loc */
13005           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13006         }
13007       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13008                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13009         {
13010           rloc.is_ip4 = 0;
13011           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13012           rloc.priority = rloc.weight = 0;
13013           vec_add1 (lcl_locs, rloc);
13014
13015           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13016           vec_add1 (rmt_locs, rloc);
13017           /* priority and weight saved in rmt loc */
13018           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13019         }
13020       else if (unformat (input, "action %d", &action))
13021         {
13022           ;
13023         }
13024       else
13025         {
13026           clib_warning ("parse error '%U'", format_unformat_error, input);
13027           return -99;
13028         }
13029     }
13030
13031   if (!rmt_eid_set)
13032     {
13033       errmsg ("remote eid addresses not set\n");
13034       return -99;
13035     }
13036
13037   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13038     {
13039       errmsg ("eid types don't match\n");
13040       return -99;
13041     }
13042
13043   if (0 == rmt_locs && (u32) ~ 0 == action)
13044     {
13045       errmsg ("action not set for negative mapping\n");
13046       return -99;
13047     }
13048
13049   /* Construct the API message */
13050   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13051
13052   mp->is_add = is_add;
13053   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13054   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13055   mp->eid_type = rmt_eid->type;
13056   mp->rmt_len = rmt_eid->len;
13057   mp->lcl_len = lcl_eid->len;
13058   mp->action = action;
13059
13060   if (0 != rmt_locs && 0 != lcl_locs)
13061     {
13062       mp->loc_num = vec_len (rmt_locs);
13063       clib_memcpy (mp->lcl_locs, lcl_locs,
13064                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13065       clib_memcpy (mp->rmt_locs, rmt_locs,
13066                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13067     }
13068   vec_free (lcl_locs);
13069   vec_free (rmt_locs);
13070
13071   /* send it... */
13072   S;
13073
13074   /* Wait for a reply... */
13075   W;
13076
13077   /* NOTREACHED */
13078   return 0;
13079 }
13080
13081 static int
13082 api_lisp_add_del_map_resolver (vat_main_t * vam)
13083 {
13084   unformat_input_t *input = vam->input;
13085   vl_api_lisp_add_del_map_resolver_t *mp;
13086   f64 timeout = ~0;
13087   u8 is_add = 1;
13088   u8 ipv4_set = 0;
13089   u8 ipv6_set = 0;
13090   ip4_address_t ipv4;
13091   ip6_address_t ipv6;
13092
13093   /* Parse args required to build the message */
13094   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13095     {
13096       if (unformat (input, "del"))
13097         {
13098           is_add = 0;
13099         }
13100       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13101         {
13102           ipv4_set = 1;
13103         }
13104       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13105         {
13106           ipv6_set = 1;
13107         }
13108       else
13109         break;
13110     }
13111
13112   if (ipv4_set && ipv6_set)
13113     {
13114       errmsg ("both eid v4 and v6 addresses set\n");
13115       return -99;
13116     }
13117
13118   if (!ipv4_set && !ipv6_set)
13119     {
13120       errmsg ("eid addresses not set\n");
13121       return -99;
13122     }
13123
13124   /* Construct the API message */
13125   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13126
13127   mp->is_add = is_add;
13128   if (ipv6_set)
13129     {
13130       mp->is_ipv6 = 1;
13131       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13132     }
13133   else
13134     {
13135       mp->is_ipv6 = 0;
13136       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13137     }
13138
13139   /* send it... */
13140   S;
13141
13142   /* Wait for a reply... */
13143   W;
13144
13145   /* NOTREACHED */
13146   return 0;
13147 }
13148
13149 static int
13150 api_lisp_gpe_enable_disable (vat_main_t * vam)
13151 {
13152   unformat_input_t *input = vam->input;
13153   vl_api_lisp_gpe_enable_disable_t *mp;
13154   f64 timeout = ~0;
13155   u8 is_set = 0;
13156   u8 is_en = 1;
13157
13158   /* Parse args required to build the message */
13159   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13160     {
13161       if (unformat (input, "enable"))
13162         {
13163           is_set = 1;
13164           is_en = 1;
13165         }
13166       else if (unformat (input, "disable"))
13167         {
13168           is_set = 1;
13169           is_en = 0;
13170         }
13171       else
13172         break;
13173     }
13174
13175   if (is_set == 0)
13176     {
13177       errmsg ("Value not set\n");
13178       return -99;
13179     }
13180
13181   /* Construct the API message */
13182   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13183
13184   mp->is_en = is_en;
13185
13186   /* send it... */
13187   S;
13188
13189   /* Wait for a reply... */
13190   W;
13191
13192   /* NOTREACHED */
13193   return 0;
13194 }
13195
13196 static int
13197 api_lisp_enable_disable (vat_main_t * vam)
13198 {
13199   unformat_input_t *input = vam->input;
13200   vl_api_lisp_enable_disable_t *mp;
13201   f64 timeout = ~0;
13202   u8 is_set = 0;
13203   u8 is_en = 0;
13204
13205   /* Parse args required to build the message */
13206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13207     {
13208       if (unformat (input, "enable"))
13209         {
13210           is_set = 1;
13211           is_en = 1;
13212         }
13213       else if (unformat (input, "disable"))
13214         {
13215           is_set = 1;
13216         }
13217       else
13218         break;
13219     }
13220
13221   if (!is_set)
13222     {
13223       errmsg ("Value not set\n");
13224       return -99;
13225     }
13226
13227   /* Construct the API message */
13228   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13229
13230   mp->is_en = is_en;
13231
13232   /* send it... */
13233   S;
13234
13235   /* Wait for a reply... */
13236   W;
13237
13238   /* NOTREACHED */
13239   return 0;
13240 }
13241
13242 static int
13243 api_show_lisp_map_request_mode (vat_main_t * vam)
13244 {
13245   f64 timeout = ~0;
13246   vl_api_show_lisp_map_request_mode_t *mp;
13247
13248   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13249
13250   /* send */
13251   S;
13252
13253   /* wait for reply */
13254   W;
13255
13256   return 0;
13257 }
13258
13259 static int
13260 api_lisp_map_request_mode (vat_main_t * vam)
13261 {
13262   f64 timeout = ~0;
13263   unformat_input_t *input = vam->input;
13264   vl_api_lisp_map_request_mode_t *mp;
13265   u8 mode = 0;
13266
13267   /* Parse args required to build the message */
13268   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13269     {
13270       if (unformat (input, "dst-only"))
13271         mode = 0;
13272       else if (unformat (input, "src-dst"))
13273         mode = 1;
13274       else
13275         {
13276           errmsg ("parse error '%U'", format_unformat_error, input);
13277           return -99;
13278         }
13279     }
13280
13281   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13282
13283   mp->mode = mode;
13284
13285   /* send */
13286   S;
13287
13288   /* wait for reply */
13289   W;
13290
13291   /* notreached */
13292   return 0;
13293 }
13294
13295 /**
13296  * Enable/disable LISP proxy ITR.
13297  *
13298  * @param vam vpp API test context
13299  * @return return code
13300  */
13301 static int
13302 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13303 {
13304   f64 timeout = ~0;
13305   u8 ls_name_set = 0;
13306   unformat_input_t *input = vam->input;
13307   vl_api_lisp_pitr_set_locator_set_t *mp;
13308   u8 is_add = 1;
13309   u8 *ls_name = 0;
13310
13311   /* Parse args required to build the message */
13312   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13313     {
13314       if (unformat (input, "del"))
13315         is_add = 0;
13316       else if (unformat (input, "locator-set %s", &ls_name))
13317         ls_name_set = 1;
13318       else
13319         {
13320           errmsg ("parse error '%U'", format_unformat_error, input);
13321           return -99;
13322         }
13323     }
13324
13325   if (!ls_name_set)
13326     {
13327       errmsg ("locator-set name not set!");
13328       return -99;
13329     }
13330
13331   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13332
13333   mp->is_add = is_add;
13334   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13335   vec_free (ls_name);
13336
13337   /* send */
13338   S;
13339
13340   /* wait for reply */
13341   W;
13342
13343   /* notreached */
13344   return 0;
13345 }
13346
13347 static int
13348 api_show_lisp_pitr (vat_main_t * vam)
13349 {
13350   vl_api_show_lisp_pitr_t *mp;
13351   f64 timeout = ~0;
13352
13353   if (!vam->json_output)
13354     {
13355       fformat (vam->ofp, "%=20s\n", "lisp status:");
13356     }
13357
13358   M (SHOW_LISP_PITR, show_lisp_pitr);
13359   /* send it... */
13360   S;
13361
13362   /* Wait for a reply... */
13363   W;
13364
13365   /* NOTREACHED */
13366   return 0;
13367 }
13368
13369 /**
13370  * Add/delete mapping between vni and vrf
13371  */
13372 static int
13373 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13374 {
13375   f64 timeout = ~0;
13376   unformat_input_t *input = vam->input;
13377   vl_api_lisp_eid_table_add_del_map_t *mp;
13378   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13379   u32 vni, vrf, bd_index;
13380
13381   /* Parse args required to build the message */
13382   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13383     {
13384       if (unformat (input, "del"))
13385         is_add = 0;
13386       else if (unformat (input, "vrf %d", &vrf))
13387         vrf_set = 1;
13388       else if (unformat (input, "bd_index %d", &bd_index))
13389         bd_index_set = 1;
13390       else if (unformat (input, "vni %d", &vni))
13391         vni_set = 1;
13392       else
13393         break;
13394     }
13395
13396   if (!vni_set || (!vrf_set && !bd_index_set))
13397     {
13398       errmsg ("missing arguments!");
13399       return -99;
13400     }
13401
13402   if (vrf_set && bd_index_set)
13403     {
13404       errmsg ("error: both vrf and bd entered!");
13405       return -99;
13406     }
13407
13408   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13409
13410   mp->is_add = is_add;
13411   mp->vni = htonl (vni);
13412   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13413   mp->is_l2 = bd_index_set;
13414
13415   /* send */
13416   S;
13417
13418   /* wait for reply */
13419   W;
13420
13421   /* notreached */
13422   return 0;
13423 }
13424
13425 uword
13426 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13427 {
13428   u32 *action = va_arg (*args, u32 *);
13429   u8 *s = 0;
13430
13431   if (unformat (input, "%s", &s))
13432     {
13433       if (!strcmp ((char *) s, "no-action"))
13434         action[0] = 0;
13435       else if (!strcmp ((char *) s, "natively-forward"))
13436         action[0] = 1;
13437       else if (!strcmp ((char *) s, "send-map-request"))
13438         action[0] = 2;
13439       else if (!strcmp ((char *) s, "drop"))
13440         action[0] = 3;
13441       else
13442         {
13443           clib_warning ("invalid action: '%s'", s);
13444           action[0] = 3;
13445         }
13446     }
13447   else
13448     return 0;
13449
13450   vec_free (s);
13451   return 1;
13452 }
13453
13454 /**
13455  * Add/del remote mapping to/from LISP control plane
13456  *
13457  * @param vam vpp API test context
13458  * @return return code
13459  */
13460 static int
13461 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13462 {
13463   unformat_input_t *input = vam->input;
13464   vl_api_lisp_add_del_remote_mapping_t *mp;
13465   f64 timeout = ~0;
13466   u32 vni = 0;
13467   lisp_eid_vat_t _eid, *eid = &_eid;
13468   lisp_eid_vat_t _seid, *seid = &_seid;
13469   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13470   u32 action = ~0, p, w, data_len;
13471   ip4_address_t rloc4;
13472   ip6_address_t rloc6;
13473   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13474
13475   memset (&rloc, 0, sizeof (rloc));
13476
13477   /* Parse args required to build the message */
13478   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13479     {
13480       if (unformat (input, "del-all"))
13481         {
13482           del_all = 1;
13483         }
13484       else if (unformat (input, "del"))
13485         {
13486           is_add = 0;
13487         }
13488       else if (unformat (input, "add"))
13489         {
13490           is_add = 1;
13491         }
13492       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13493         {
13494           eid_set = 1;
13495         }
13496       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13497         {
13498           seid_set = 1;
13499         }
13500       else if (unformat (input, "vni %d", &vni))
13501         {
13502           ;
13503         }
13504       else if (unformat (input, "p %d w %d", &p, &w))
13505         {
13506           if (!curr_rloc)
13507             {
13508               errmsg ("No RLOC configured for setting priority/weight!");
13509               return -99;
13510             }
13511           curr_rloc->priority = p;
13512           curr_rloc->weight = w;
13513         }
13514       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13515         {
13516           rloc.is_ip4 = 1;
13517           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13518           vec_add1 (rlocs, rloc);
13519           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13520         }
13521       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13522         {
13523           rloc.is_ip4 = 0;
13524           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13525           vec_add1 (rlocs, rloc);
13526           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13527         }
13528       else if (unformat (input, "action %U",
13529                          unformat_negative_mapping_action, &action))
13530         {
13531           ;
13532         }
13533       else
13534         {
13535           clib_warning ("parse error '%U'", format_unformat_error, input);
13536           return -99;
13537         }
13538     }
13539
13540   if (0 == eid_set)
13541     {
13542       errmsg ("missing params!");
13543       return -99;
13544     }
13545
13546   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13547     {
13548       errmsg ("no action set for negative map-reply!");
13549       return -99;
13550     }
13551
13552   data_len = vec_len (rlocs) * sizeof (rloc_t);
13553
13554   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13555   mp->is_add = is_add;
13556   mp->vni = htonl (vni);
13557   mp->action = (u8) action;
13558   mp->is_src_dst = seid_set;
13559   mp->eid_len = eid->len;
13560   mp->seid_len = seid->len;
13561   mp->del_all = del_all;
13562   mp->eid_type = eid->type;
13563   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13564   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13565
13566   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13567   clib_memcpy (mp->rlocs, rlocs, data_len);
13568   vec_free (rlocs);
13569
13570   /* send it... */
13571   S;
13572
13573   /* Wait for a reply... */
13574   W;
13575
13576   /* NOTREACHED */
13577   return 0;
13578 }
13579
13580 /**
13581  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13582  * forwarding entries in data-plane accordingly.
13583  *
13584  * @param vam vpp API test context
13585  * @return return code
13586  */
13587 static int
13588 api_lisp_add_del_adjacency (vat_main_t * vam)
13589 {
13590   unformat_input_t *input = vam->input;
13591   vl_api_lisp_add_del_adjacency_t *mp;
13592   f64 timeout = ~0;
13593   u32 vni = 0;
13594   ip4_address_t leid4, reid4;
13595   ip6_address_t leid6, reid6;
13596   u8 reid_mac[6] = { 0 };
13597   u8 leid_mac[6] = { 0 };
13598   u8 reid_type, leid_type;
13599   u32 leid_len = 0, reid_len = 0, len;
13600   u8 is_add = 1;
13601
13602   leid_type = reid_type = (u8) ~ 0;
13603
13604   /* Parse args required to build the message */
13605   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13606     {
13607       if (unformat (input, "del"))
13608         {
13609           is_add = 0;
13610         }
13611       else if (unformat (input, "add"))
13612         {
13613           is_add = 1;
13614         }
13615       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13616                          &reid4, &len))
13617         {
13618           reid_type = 0;        /* ipv4 */
13619           reid_len = len;
13620         }
13621       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13622                          &reid6, &len))
13623         {
13624           reid_type = 1;        /* ipv6 */
13625           reid_len = len;
13626         }
13627       else if (unformat (input, "reid %U", unformat_ethernet_address,
13628                          reid_mac))
13629         {
13630           reid_type = 2;        /* mac */
13631         }
13632       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13633                          &leid4, &len))
13634         {
13635           leid_type = 0;        /* ipv4 */
13636           leid_len = len;
13637         }
13638       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13639                          &leid6, &len))
13640         {
13641           leid_type = 1;        /* ipv6 */
13642           leid_len = len;
13643         }
13644       else if (unformat (input, "leid %U", unformat_ethernet_address,
13645                          leid_mac))
13646         {
13647           leid_type = 2;        /* mac */
13648         }
13649       else if (unformat (input, "vni %d", &vni))
13650         {
13651           ;
13652         }
13653       else
13654         {
13655           errmsg ("parse error '%U'", format_unformat_error, input);
13656           return -99;
13657         }
13658     }
13659
13660   if ((u8) ~ 0 == reid_type)
13661     {
13662       errmsg ("missing params!");
13663       return -99;
13664     }
13665
13666   if (leid_type != reid_type)
13667     {
13668       errmsg ("remote and local EIDs are of different types!");
13669       return -99;
13670     }
13671
13672   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13673   mp->is_add = is_add;
13674   mp->vni = htonl (vni);
13675   mp->leid_len = leid_len;
13676   mp->reid_len = reid_len;
13677   mp->eid_type = reid_type;
13678
13679   switch (mp->eid_type)
13680     {
13681     case 0:
13682       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13683       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13684       break;
13685     case 1:
13686       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13687       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13688       break;
13689     case 2:
13690       clib_memcpy (mp->leid, leid_mac, 6);
13691       clib_memcpy (mp->reid, reid_mac, 6);
13692       break;
13693     default:
13694       errmsg ("unknown EID type %d!", mp->eid_type);
13695       return 0;
13696     }
13697
13698   /* send it... */
13699   S;
13700
13701   /* Wait for a reply... */
13702   W;
13703
13704   /* NOTREACHED */
13705   return 0;
13706 }
13707
13708 static int
13709 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13710 {
13711   unformat_input_t *input = vam->input;
13712   vl_api_lisp_gpe_add_del_iface_t *mp;
13713   f64 timeout = ~0;
13714   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13715   u32 dp_table = 0, vni = 0;
13716
13717   /* Parse args required to build the message */
13718   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13719     {
13720       if (unformat (input, "up"))
13721         {
13722           action_set = 1;
13723           is_add = 1;
13724         }
13725       else if (unformat (input, "down"))
13726         {
13727           action_set = 1;
13728           is_add = 0;
13729         }
13730       else if (unformat (input, "table_id %d", &dp_table))
13731         {
13732           dp_table_set = 1;
13733         }
13734       else if (unformat (input, "bd_id %d", &dp_table))
13735         {
13736           dp_table_set = 1;
13737           is_l2 = 1;
13738         }
13739       else if (unformat (input, "vni %d", &vni))
13740         {
13741           vni_set = 1;
13742         }
13743       else
13744         break;
13745     }
13746
13747   if (action_set == 0)
13748     {
13749       errmsg ("Action not set\n");
13750       return -99;
13751     }
13752   if (dp_table_set == 0 || vni_set == 0)
13753     {
13754       errmsg ("vni and dp_table must be set\n");
13755       return -99;
13756     }
13757
13758   /* Construct the API message */
13759   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13760
13761   mp->is_add = is_add;
13762   mp->dp_table = dp_table;
13763   mp->is_l2 = is_l2;
13764   mp->vni = vni;
13765
13766   /* send it... */
13767   S;
13768
13769   /* Wait for a reply... */
13770   W;
13771
13772   /* NOTREACHED */
13773   return 0;
13774 }
13775
13776 /**
13777  * Add/del map request itr rlocs from LISP control plane and updates
13778  *
13779  * @param vam vpp API test context
13780  * @return return code
13781  */
13782 static int
13783 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13784 {
13785   unformat_input_t *input = vam->input;
13786   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13787   f64 timeout = ~0;
13788   u8 *locator_set_name = 0;
13789   u8 locator_set_name_set = 0;
13790   u8 is_add = 1;
13791
13792   /* Parse args required to build the message */
13793   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13794     {
13795       if (unformat (input, "del"))
13796         {
13797           is_add = 0;
13798         }
13799       else if (unformat (input, "%_%v%_", &locator_set_name))
13800         {
13801           locator_set_name_set = 1;
13802         }
13803       else
13804         {
13805           clib_warning ("parse error '%U'", format_unformat_error, input);
13806           return -99;
13807         }
13808     }
13809
13810   if (is_add && !locator_set_name_set)
13811     {
13812       errmsg ("itr-rloc is not set!");
13813       return -99;
13814     }
13815
13816   if (is_add && vec_len (locator_set_name) > 64)
13817     {
13818       errmsg ("itr-rloc locator-set name too long\n");
13819       vec_free (locator_set_name);
13820       return -99;
13821     }
13822
13823   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13824   mp->is_add = is_add;
13825   if (is_add)
13826     {
13827       clib_memcpy (mp->locator_set_name, locator_set_name,
13828                    vec_len (locator_set_name));
13829     }
13830   else
13831     {
13832       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13833     }
13834   vec_free (locator_set_name);
13835
13836   /* send it... */
13837   S;
13838
13839   /* Wait for a reply... */
13840   W;
13841
13842   /* NOTREACHED */
13843   return 0;
13844 }
13845
13846 static int
13847 api_lisp_locator_dump (vat_main_t * vam)
13848 {
13849   unformat_input_t *input = vam->input;
13850   vl_api_lisp_locator_dump_t *mp;
13851   f64 timeout = ~0;
13852   u8 is_index_set = 0, is_name_set = 0;
13853   u8 *ls_name = 0;
13854   u32 ls_index = ~0;
13855
13856   /* Parse args required to build the message */
13857   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13858     {
13859       if (unformat (input, "ls_name %_%v%_", &ls_name))
13860         {
13861           is_name_set = 1;
13862         }
13863       else if (unformat (input, "ls_index %d", &ls_index))
13864         {
13865           is_index_set = 1;
13866         }
13867       else
13868         {
13869           errmsg ("parse error '%U'", format_unformat_error, input);
13870           return -99;
13871         }
13872     }
13873
13874   if (!is_index_set && !is_name_set)
13875     {
13876       errmsg ("error: expected one of index or name!\n");
13877       return -99;
13878     }
13879
13880   if (is_index_set && is_name_set)
13881     {
13882       errmsg ("error: only one param expected!\n");
13883       return -99;
13884     }
13885
13886   if (vec_len (ls_name) > 62)
13887     {
13888       errmsg ("error: locator set name too long!");
13889       return -99;
13890     }
13891
13892   if (!vam->json_output)
13893     {
13894       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13895                "weight");
13896     }
13897
13898   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13899   mp->is_index_set = is_index_set;
13900
13901   if (is_index_set)
13902     mp->ls_index = clib_host_to_net_u32 (ls_index);
13903   else
13904     {
13905       vec_add1 (ls_name, 0);
13906       strncpy ((char *) mp->ls_name, (char *) ls_name,
13907                sizeof (mp->ls_name) - 1);
13908     }
13909
13910   /* send it... */
13911   S;
13912
13913   /* Use a control ping for synchronization */
13914   {
13915     vl_api_control_ping_t *mp;
13916     M (CONTROL_PING, control_ping);
13917     S;
13918   }
13919   /* Wait for a reply... */
13920   W;
13921
13922   /* NOTREACHED */
13923   return 0;
13924 }
13925
13926 static int
13927 api_lisp_locator_set_dump (vat_main_t * vam)
13928 {
13929   vl_api_lisp_locator_set_dump_t *mp;
13930   unformat_input_t *input = vam->input;
13931   f64 timeout = ~0;
13932   u8 filter = 0;
13933
13934   /* Parse args required to build the message */
13935   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13936     {
13937       if (unformat (input, "local"))
13938         {
13939           filter = 1;
13940         }
13941       else if (unformat (input, "remote"))
13942         {
13943           filter = 2;
13944         }
13945       else
13946         {
13947           errmsg ("parse error '%U'", format_unformat_error, input);
13948           return -99;
13949         }
13950     }
13951
13952   if (!vam->json_output)
13953     {
13954       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13955     }
13956
13957   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13958
13959   mp->filter = filter;
13960
13961   /* send it... */
13962   S;
13963
13964   /* Use a control ping for synchronization */
13965   {
13966     vl_api_control_ping_t *mp;
13967     M (CONTROL_PING, control_ping);
13968     S;
13969   }
13970   /* Wait for a reply... */
13971   W;
13972
13973   /* NOTREACHED */
13974   return 0;
13975 }
13976
13977 static int
13978 api_lisp_eid_table_map_dump (vat_main_t * vam)
13979 {
13980   u8 is_l2 = 0;
13981   u8 mode_set = 0;
13982   unformat_input_t *input = vam->input;
13983   vl_api_lisp_eid_table_map_dump_t *mp;
13984   f64 timeout = ~0;
13985
13986   /* Parse args required to build the message */
13987   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13988     {
13989       if (unformat (input, "l2"))
13990         {
13991           is_l2 = 1;
13992           mode_set = 1;
13993         }
13994       else if (unformat (input, "l3"))
13995         {
13996           is_l2 = 0;
13997           mode_set = 1;
13998         }
13999       else
14000         {
14001           errmsg ("parse error '%U'", format_unformat_error, input);
14002           return -99;
14003         }
14004     }
14005
14006   if (!mode_set)
14007     {
14008       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
14009       return -99;
14010     }
14011
14012   if (!vam->json_output)
14013     {
14014       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
14015     }
14016
14017   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14018   mp->is_l2 = is_l2;
14019
14020   /* send it... */
14021   S;
14022
14023   /* Use a control ping for synchronization */
14024   {
14025     vl_api_control_ping_t *mp;
14026     M (CONTROL_PING, control_ping);
14027     S;
14028   }
14029   /* Wait for a reply... */
14030   W;
14031
14032   /* NOTREACHED */
14033   return 0;
14034 }
14035
14036 static int
14037 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14038 {
14039   vl_api_lisp_eid_table_vni_dump_t *mp;
14040   f64 timeout = ~0;
14041
14042   if (!vam->json_output)
14043     {
14044       fformat (vam->ofp, "VNI\n");
14045     }
14046
14047   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14048
14049   /* send it... */
14050   S;
14051
14052   /* Use a control ping for synchronization */
14053   {
14054     vl_api_control_ping_t *mp;
14055     M (CONTROL_PING, control_ping);
14056     S;
14057   }
14058   /* Wait for a reply... */
14059   W;
14060
14061   /* NOTREACHED */
14062   return 0;
14063 }
14064
14065 static int
14066 api_lisp_eid_table_dump (vat_main_t * vam)
14067 {
14068   unformat_input_t *i = vam->input;
14069   vl_api_lisp_eid_table_dump_t *mp;
14070   f64 timeout = ~0;
14071   struct in_addr ip4;
14072   struct in6_addr ip6;
14073   u8 mac[6];
14074   u8 eid_type = ~0, eid_set = 0;
14075   u32 prefix_length = ~0, t, vni = 0;
14076   u8 filter = 0;
14077
14078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14079     {
14080       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14081         {
14082           eid_set = 1;
14083           eid_type = 0;
14084           prefix_length = t;
14085         }
14086       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14087         {
14088           eid_set = 1;
14089           eid_type = 1;
14090           prefix_length = t;
14091         }
14092       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14093         {
14094           eid_set = 1;
14095           eid_type = 2;
14096         }
14097       else if (unformat (i, "vni %d", &t))
14098         {
14099           vni = t;
14100         }
14101       else if (unformat (i, "local"))
14102         {
14103           filter = 1;
14104         }
14105       else if (unformat (i, "remote"))
14106         {
14107           filter = 2;
14108         }
14109       else
14110         {
14111           errmsg ("parse error '%U'", format_unformat_error, i);
14112           return -99;
14113         }
14114     }
14115
14116   if (!vam->json_output)
14117     {
14118       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
14119                "ls_index", "ttl", "authoritative");
14120     }
14121
14122   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14123
14124   mp->filter = filter;
14125   if (eid_set)
14126     {
14127       mp->eid_set = 1;
14128       mp->vni = htonl (vni);
14129       mp->eid_type = eid_type;
14130       switch (eid_type)
14131         {
14132         case 0:
14133           mp->prefix_length = prefix_length;
14134           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14135           break;
14136         case 1:
14137           mp->prefix_length = prefix_length;
14138           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14139           break;
14140         case 2:
14141           clib_memcpy (mp->eid, mac, sizeof (mac));
14142           break;
14143         default:
14144           errmsg ("unknown EID type %d!", eid_type);
14145           return -99;
14146         }
14147     }
14148
14149   /* send it... */
14150   S;
14151
14152   /* Use a control ping for synchronization */
14153   {
14154     vl_api_control_ping_t *mp;
14155     M (CONTROL_PING, control_ping);
14156     S;
14157   }
14158
14159   /* Wait for a reply... */
14160   W;
14161
14162   /* NOTREACHED */
14163   return 0;
14164 }
14165
14166 static int
14167 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14168 {
14169   vl_api_lisp_gpe_tunnel_dump_t *mp;
14170   f64 timeout = ~0;
14171
14172   if (!vam->json_output)
14173     {
14174       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14175                "%=16s%=16s%=16s%=16s%=16s\n",
14176                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14177                "Decap next", "Lisp version", "Flags", "Next protocol",
14178                "ver_res", "res", "iid");
14179     }
14180
14181   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14182   /* send it... */
14183   S;
14184
14185   /* Use a control ping for synchronization */
14186   {
14187     vl_api_control_ping_t *mp;
14188     M (CONTROL_PING, control_ping);
14189     S;
14190   }
14191   /* Wait for a reply... */
14192   W;
14193
14194   /* NOTREACHED */
14195   return 0;
14196 }
14197
14198 static int
14199 api_lisp_adjacencies_get (vat_main_t * vam)
14200 {
14201   unformat_input_t *i = vam->input;
14202   vl_api_lisp_adjacencies_get_t *mp;
14203   f64 timeout = ~0;
14204   u8 vni_set = 0;
14205   u32 vni = ~0;
14206
14207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14208     {
14209       if (unformat (i, "vni %d", &vni))
14210         {
14211           vni_set = 1;
14212         }
14213       else
14214         {
14215           errmsg ("parse error '%U'\n", format_unformat_error, i);
14216           return -99;
14217         }
14218     }
14219
14220   if (!vni_set)
14221     {
14222       errmsg ("vni not set!\n");
14223       return -99;
14224     }
14225
14226   if (!vam->json_output)
14227     {
14228       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14229     }
14230
14231   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14232   mp->vni = clib_host_to_net_u32 (vni);
14233
14234   /* send it... */
14235   S;
14236
14237   /* Wait for a reply... */
14238   W;
14239
14240   /* NOTREACHED */
14241   return 0;
14242 }
14243
14244 static int
14245 api_lisp_map_resolver_dump (vat_main_t * vam)
14246 {
14247   vl_api_lisp_map_resolver_dump_t *mp;
14248   f64 timeout = ~0;
14249
14250   if (!vam->json_output)
14251     {
14252       fformat (vam->ofp, "%=20s\n", "Map resolver");
14253     }
14254
14255   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14256   /* send it... */
14257   S;
14258
14259   /* Use a control ping for synchronization */
14260   {
14261     vl_api_control_ping_t *mp;
14262     M (CONTROL_PING, control_ping);
14263     S;
14264   }
14265   /* Wait for a reply... */
14266   W;
14267
14268   /* NOTREACHED */
14269   return 0;
14270 }
14271
14272 static int
14273 api_show_lisp_status (vat_main_t * vam)
14274 {
14275   vl_api_show_lisp_status_t *mp;
14276   f64 timeout = ~0;
14277
14278   if (!vam->json_output)
14279     {
14280       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14281     }
14282
14283   M (SHOW_LISP_STATUS, show_lisp_status);
14284   /* send it... */
14285   S;
14286   /* Wait for a reply... */
14287   W;
14288
14289   /* NOTREACHED */
14290   return 0;
14291 }
14292
14293 static int
14294 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14295 {
14296   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14297   f64 timeout = ~0;
14298
14299   if (!vam->json_output)
14300     {
14301       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14302     }
14303
14304   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14305   /* send it... */
14306   S;
14307   /* Wait for a reply... */
14308   W;
14309
14310   /* NOTREACHED */
14311   return 0;
14312 }
14313
14314 static int
14315 api_af_packet_create (vat_main_t * vam)
14316 {
14317   unformat_input_t *i = vam->input;
14318   vl_api_af_packet_create_t *mp;
14319   f64 timeout;
14320   u8 *host_if_name = 0;
14321   u8 hw_addr[6];
14322   u8 random_hw_addr = 1;
14323
14324   memset (hw_addr, 0, sizeof (hw_addr));
14325
14326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14327     {
14328       if (unformat (i, "name %s", &host_if_name))
14329         vec_add1 (host_if_name, 0);
14330       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14331         random_hw_addr = 0;
14332       else
14333         break;
14334     }
14335
14336   if (!vec_len (host_if_name))
14337     {
14338       errmsg ("host-interface name must be specified");
14339       return -99;
14340     }
14341
14342   if (vec_len (host_if_name) > 64)
14343     {
14344       errmsg ("host-interface name too long");
14345       return -99;
14346     }
14347
14348   M (AF_PACKET_CREATE, af_packet_create);
14349
14350   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14351   clib_memcpy (mp->hw_addr, hw_addr, 6);
14352   mp->use_random_hw_addr = random_hw_addr;
14353   vec_free (host_if_name);
14354
14355   S;
14356   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14357   /* NOTREACHED */
14358   return 0;
14359 }
14360
14361 static int
14362 api_af_packet_delete (vat_main_t * vam)
14363 {
14364   unformat_input_t *i = vam->input;
14365   vl_api_af_packet_delete_t *mp;
14366   f64 timeout;
14367   u8 *host_if_name = 0;
14368
14369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14370     {
14371       if (unformat (i, "name %s", &host_if_name))
14372         vec_add1 (host_if_name, 0);
14373       else
14374         break;
14375     }
14376
14377   if (!vec_len (host_if_name))
14378     {
14379       errmsg ("host-interface name must be specified");
14380       return -99;
14381     }
14382
14383   if (vec_len (host_if_name) > 64)
14384     {
14385       errmsg ("host-interface name too long");
14386       return -99;
14387     }
14388
14389   M (AF_PACKET_DELETE, af_packet_delete);
14390
14391   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14392   vec_free (host_if_name);
14393
14394   S;
14395   W;
14396   /* NOTREACHED */
14397   return 0;
14398 }
14399
14400 static int
14401 api_policer_add_del (vat_main_t * vam)
14402 {
14403   unformat_input_t *i = vam->input;
14404   vl_api_policer_add_del_t *mp;
14405   f64 timeout;
14406   u8 is_add = 1;
14407   u8 *name = 0;
14408   u32 cir = 0;
14409   u32 eir = 0;
14410   u64 cb = 0;
14411   u64 eb = 0;
14412   u8 rate_type = 0;
14413   u8 round_type = 0;
14414   u8 type = 0;
14415   u8 color_aware = 0;
14416   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14417
14418   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14419   conform_action.dscp = 0;
14420   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14421   exceed_action.dscp = 0;
14422   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14423   violate_action.dscp = 0;
14424
14425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14426     {
14427       if (unformat (i, "del"))
14428         is_add = 0;
14429       else if (unformat (i, "name %s", &name))
14430         vec_add1 (name, 0);
14431       else if (unformat (i, "cir %u", &cir))
14432         ;
14433       else if (unformat (i, "eir %u", &eir))
14434         ;
14435       else if (unformat (i, "cb %u", &cb))
14436         ;
14437       else if (unformat (i, "eb %u", &eb))
14438         ;
14439       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14440                          &rate_type))
14441         ;
14442       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14443                          &round_type))
14444         ;
14445       else if (unformat (i, "type %U", unformat_policer_type, &type))
14446         ;
14447       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14448                          &conform_action))
14449         ;
14450       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14451                          &exceed_action))
14452         ;
14453       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14454                          &violate_action))
14455         ;
14456       else if (unformat (i, "color-aware"))
14457         color_aware = 1;
14458       else
14459         break;
14460     }
14461
14462   if (!vec_len (name))
14463     {
14464       errmsg ("policer name must be specified");
14465       return -99;
14466     }
14467
14468   if (vec_len (name) > 64)
14469     {
14470       errmsg ("policer name too long");
14471       return -99;
14472     }
14473
14474   M (POLICER_ADD_DEL, policer_add_del);
14475
14476   clib_memcpy (mp->name, name, vec_len (name));
14477   vec_free (name);
14478   mp->is_add = is_add;
14479   mp->cir = cir;
14480   mp->eir = eir;
14481   mp->cb = cb;
14482   mp->eb = eb;
14483   mp->rate_type = rate_type;
14484   mp->round_type = round_type;
14485   mp->type = type;
14486   mp->conform_action_type = conform_action.action_type;
14487   mp->conform_dscp = conform_action.dscp;
14488   mp->exceed_action_type = exceed_action.action_type;
14489   mp->exceed_dscp = exceed_action.dscp;
14490   mp->violate_action_type = violate_action.action_type;
14491   mp->violate_dscp = violate_action.dscp;
14492   mp->color_aware = color_aware;
14493
14494   S;
14495   W;
14496   /* NOTREACHED */
14497   return 0;
14498 }
14499
14500 static int
14501 api_policer_dump (vat_main_t * vam)
14502 {
14503   unformat_input_t *i = vam->input;
14504   vl_api_policer_dump_t *mp;
14505   f64 timeout = ~0;
14506   u8 *match_name = 0;
14507   u8 match_name_valid = 0;
14508
14509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14510     {
14511       if (unformat (i, "name %s", &match_name))
14512         {
14513           vec_add1 (match_name, 0);
14514           match_name_valid = 1;
14515         }
14516       else
14517         break;
14518     }
14519
14520   M (POLICER_DUMP, policer_dump);
14521   mp->match_name_valid = match_name_valid;
14522   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14523   vec_free (match_name);
14524   /* send it... */
14525   S;
14526
14527   /* Use a control ping for synchronization */
14528   {
14529     vl_api_control_ping_t *mp;
14530     M (CONTROL_PING, control_ping);
14531     S;
14532   }
14533   /* Wait for a reply... */
14534   W;
14535
14536   /* NOTREACHED */
14537   return 0;
14538 }
14539
14540 static int
14541 api_policer_classify_set_interface (vat_main_t * vam)
14542 {
14543   unformat_input_t *i = vam->input;
14544   vl_api_policer_classify_set_interface_t *mp;
14545   f64 timeout;
14546   u32 sw_if_index;
14547   int sw_if_index_set;
14548   u32 ip4_table_index = ~0;
14549   u32 ip6_table_index = ~0;
14550   u32 l2_table_index = ~0;
14551   u8 is_add = 1;
14552
14553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14554     {
14555       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14556         sw_if_index_set = 1;
14557       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14558         sw_if_index_set = 1;
14559       else if (unformat (i, "del"))
14560         is_add = 0;
14561       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14562         ;
14563       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14564         ;
14565       else if (unformat (i, "l2-table %d", &l2_table_index))
14566         ;
14567       else
14568         {
14569           clib_warning ("parse error '%U'", format_unformat_error, i);
14570           return -99;
14571         }
14572     }
14573
14574   if (sw_if_index_set == 0)
14575     {
14576       errmsg ("missing interface name or sw_if_index\n");
14577       return -99;
14578     }
14579
14580   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14581
14582   mp->sw_if_index = ntohl (sw_if_index);
14583   mp->ip4_table_index = ntohl (ip4_table_index);
14584   mp->ip6_table_index = ntohl (ip6_table_index);
14585   mp->l2_table_index = ntohl (l2_table_index);
14586   mp->is_add = is_add;
14587
14588   S;
14589   W;
14590   /* NOTREACHED */
14591   return 0;
14592 }
14593
14594 static int
14595 api_policer_classify_dump (vat_main_t * vam)
14596 {
14597   unformat_input_t *i = vam->input;
14598   vl_api_policer_classify_dump_t *mp;
14599   f64 timeout = ~0;
14600   u8 type = POLICER_CLASSIFY_N_TABLES;
14601
14602   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14603     ;
14604   else
14605     {
14606       errmsg ("classify table type must be specified\n");
14607       return -99;
14608     }
14609
14610   if (!vam->json_output)
14611     {
14612       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14613     }
14614
14615   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14616   mp->type = type;
14617   /* send it... */
14618   S;
14619
14620   /* Use a control ping for synchronization */
14621   {
14622     vl_api_control_ping_t *mp;
14623     M (CONTROL_PING, control_ping);
14624     S;
14625   }
14626   /* Wait for a reply... */
14627   W;
14628
14629   /* NOTREACHED */
14630   return 0;
14631 }
14632
14633 static int
14634 api_netmap_create (vat_main_t * vam)
14635 {
14636   unformat_input_t *i = vam->input;
14637   vl_api_netmap_create_t *mp;
14638   f64 timeout;
14639   u8 *if_name = 0;
14640   u8 hw_addr[6];
14641   u8 random_hw_addr = 1;
14642   u8 is_pipe = 0;
14643   u8 is_master = 0;
14644
14645   memset (hw_addr, 0, sizeof (hw_addr));
14646
14647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14648     {
14649       if (unformat (i, "name %s", &if_name))
14650         vec_add1 (if_name, 0);
14651       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14652         random_hw_addr = 0;
14653       else if (unformat (i, "pipe"))
14654         is_pipe = 1;
14655       else if (unformat (i, "master"))
14656         is_master = 1;
14657       else if (unformat (i, "slave"))
14658         is_master = 0;
14659       else
14660         break;
14661     }
14662
14663   if (!vec_len (if_name))
14664     {
14665       errmsg ("interface name must be specified");
14666       return -99;
14667     }
14668
14669   if (vec_len (if_name) > 64)
14670     {
14671       errmsg ("interface name too long");
14672       return -99;
14673     }
14674
14675   M (NETMAP_CREATE, netmap_create);
14676
14677   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14678   clib_memcpy (mp->hw_addr, hw_addr, 6);
14679   mp->use_random_hw_addr = random_hw_addr;
14680   mp->is_pipe = is_pipe;
14681   mp->is_master = is_master;
14682   vec_free (if_name);
14683
14684   S;
14685   W;
14686   /* NOTREACHED */
14687   return 0;
14688 }
14689
14690 static int
14691 api_netmap_delete (vat_main_t * vam)
14692 {
14693   unformat_input_t *i = vam->input;
14694   vl_api_netmap_delete_t *mp;
14695   f64 timeout;
14696   u8 *if_name = 0;
14697
14698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14699     {
14700       if (unformat (i, "name %s", &if_name))
14701         vec_add1 (if_name, 0);
14702       else
14703         break;
14704     }
14705
14706   if (!vec_len (if_name))
14707     {
14708       errmsg ("interface name must be specified");
14709       return -99;
14710     }
14711
14712   if (vec_len (if_name) > 64)
14713     {
14714       errmsg ("interface name too long");
14715       return -99;
14716     }
14717
14718   M (NETMAP_DELETE, netmap_delete);
14719
14720   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14721   vec_free (if_name);
14722
14723   S;
14724   W;
14725   /* NOTREACHED */
14726   return 0;
14727 }
14728
14729 static void vl_api_mpls_eth_tunnel_details_t_handler
14730   (vl_api_mpls_eth_tunnel_details_t * mp)
14731 {
14732   vat_main_t *vam = &vat_main;
14733   i32 i;
14734   i32 len = ntohl (mp->nlabels);
14735
14736   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14737            ntohl (mp->tunnel_index),
14738            format_ethernet_address, &mp->tunnel_dst_mac,
14739            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14740   for (i = 0; i < len; i++)
14741     {
14742       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14743     }
14744   fformat (vam->ofp, "\n");
14745   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14746            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14747 }
14748
14749 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14750   (vl_api_mpls_eth_tunnel_details_t * mp)
14751 {
14752   vat_main_t *vam = &vat_main;
14753   vat_json_node_t *node = NULL;
14754   struct in_addr ip4;
14755   i32 i;
14756   i32 len = ntohl (mp->nlabels);
14757
14758   if (VAT_JSON_ARRAY != vam->json_tree.type)
14759     {
14760       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14761       vat_json_init_array (&vam->json_tree);
14762     }
14763   node = vat_json_array_add (&vam->json_tree);
14764
14765   vat_json_init_object (node);
14766   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14767   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14768   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14769   vat_json_object_add_uint (node, "inner_fib_index",
14770                             ntohl (mp->inner_fib_index));
14771   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14772   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14773   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14774   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14775   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14776                                    format (0, "%U", format_ethernet_address,
14777                                            &mp->tunnel_dst_mac));
14778   vat_json_object_add_uint (node, "tx_sw_if_index",
14779                             ntohl (mp->tx_sw_if_index));
14780   vat_json_object_add_uint (node, "label_count", len);
14781   for (i = 0; i < len; i++)
14782     {
14783       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14784     }
14785 }
14786
14787 static int
14788 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14789 {
14790   vl_api_mpls_eth_tunnel_dump_t *mp;
14791   f64 timeout;
14792   i32 index = -1;
14793
14794   /* Parse args required to build the message */
14795   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14796     {
14797       if (!unformat (vam->input, "tunnel_index %d", &index))
14798         {
14799           index = -1;
14800           break;
14801         }
14802     }
14803
14804   fformat (vam->ofp, "  tunnel_index %d\n", index);
14805
14806   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14807   mp->tunnel_index = htonl (index);
14808   S;
14809
14810   /* Use a control ping for synchronization */
14811   {
14812     vl_api_control_ping_t *mp;
14813     M (CONTROL_PING, control_ping);
14814     S;
14815   }
14816   W;
14817 }
14818
14819 static void vl_api_mpls_fib_encap_details_t_handler
14820   (vl_api_mpls_fib_encap_details_t * mp)
14821 {
14822   vat_main_t *vam = &vat_main;
14823   i32 i;
14824   i32 len = ntohl (mp->nlabels);
14825
14826   fformat (vam->ofp, "table %d, dest %U, label ",
14827            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14828   for (i = 0; i < len; i++)
14829     {
14830       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14831     }
14832   fformat (vam->ofp, "\n");
14833 }
14834
14835 static void vl_api_mpls_fib_encap_details_t_handler_json
14836   (vl_api_mpls_fib_encap_details_t * mp)
14837 {
14838   vat_main_t *vam = &vat_main;
14839   vat_json_node_t *node = NULL;
14840   i32 i;
14841   i32 len = ntohl (mp->nlabels);
14842   struct in_addr ip4;
14843
14844   if (VAT_JSON_ARRAY != vam->json_tree.type)
14845     {
14846       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14847       vat_json_init_array (&vam->json_tree);
14848     }
14849   node = vat_json_array_add (&vam->json_tree);
14850
14851   vat_json_init_object (node);
14852   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14853   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14854   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14855   vat_json_object_add_ip4 (node, "dest", ip4);
14856   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14857   vat_json_object_add_uint (node, "label_count", len);
14858   for (i = 0; i < len; i++)
14859     {
14860       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14861     }
14862 }
14863
14864 static int
14865 api_mpls_fib_encap_dump (vat_main_t * vam)
14866 {
14867   vl_api_mpls_fib_encap_dump_t *mp;
14868   f64 timeout;
14869
14870   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14871   S;
14872
14873   /* Use a control ping for synchronization */
14874   {
14875     vl_api_control_ping_t *mp;
14876     M (CONTROL_PING, control_ping);
14877     S;
14878   }
14879   W;
14880 }
14881
14882 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
14883 #define vl_api_mpls_fib_details_t_print vl_noop_handler
14884
14885 static void
14886 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
14887 {
14888   vat_main_t *vam = &vat_main;
14889   int count = ntohl (mp->count);
14890   vl_api_fib_path_t *fp;
14891   int i;
14892
14893   fformat (vam->ofp,
14894            "table-id %d, label %u, ess_bit %u\n",
14895            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
14896   fp = mp->path;
14897   for (i = 0; i < count; i++)
14898     {
14899       fformat (vam->ofp,
14900                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, is_unreach %d, "
14901                "is_prohitbit %d, afi %d, next_hop %U\n", ntohl (fp->weight),
14902                ntohl (fp->sw_if_index), fp->is_local, fp->is_drop,
14903                fp->is_unreach, fp->is_prohibit, fp->afi, format_ip46_address,
14904                fp->next_hop, fp->afi);
14905       fp++;
14906     }
14907 }
14908
14909 static void vl_api_mpls_fib_details_t_handler_json
14910   (vl_api_mpls_fib_details_t * mp)
14911 {
14912   vat_main_t *vam = &vat_main;
14913   int count = ntohl (mp->count);
14914   vat_json_node_t *node = NULL;
14915   struct in_addr ip4;
14916   struct in6_addr ip6;
14917   vl_api_fib_path_t *fp;
14918   int i;
14919
14920   if (VAT_JSON_ARRAY != vam->json_tree.type)
14921     {
14922       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14923       vat_json_init_array (&vam->json_tree);
14924     }
14925   node = vat_json_array_add (&vam->json_tree);
14926
14927   vat_json_init_object (node);
14928   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14929   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
14930   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14931   vat_json_object_add_uint (node, "path_count", count);
14932   fp = mp->path;
14933   for (i = 0; i < count; i++)
14934     {
14935       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
14936       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
14937       vat_json_object_add_uint (node, "is_local", fp->is_local);
14938       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
14939       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
14940       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
14941       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
14942       if (fp->afi == IP46_TYPE_IP4)
14943         {
14944           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
14945           vat_json_object_add_ip4 (node, "next_hop", ip4);
14946         }
14947       else if (fp->afi == IP46_TYPE_IP6)
14948         {
14949           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
14950           vat_json_object_add_ip6 (node, "next_hop", ip6);
14951         }
14952     }
14953 }
14954
14955 static int
14956 api_mpls_fib_dump (vat_main_t * vam)
14957 {
14958   vl_api_mpls_fib_dump_t *mp;
14959   f64 timeout;
14960
14961   M (MPLS_FIB_DUMP, mpls_fib_dump);
14962   S;
14963
14964   /* Use a control ping for synchronization */
14965   {
14966     vl_api_control_ping_t *mp;
14967     M (CONTROL_PING, control_ping);
14968     S;
14969   }
14970   W;
14971 }
14972
14973 #define vl_api_ip_fib_details_t_endian vl_noop_handler
14974 #define vl_api_ip_fib_details_t_print vl_noop_handler
14975
14976 static void
14977 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
14978 {
14979   vat_main_t *vam = &vat_main;
14980   int count = ntohl (mp->count);
14981   vl_api_fib_path_t *fp;
14982   int i;
14983
14984   fformat (vam->ofp,
14985            "table-id %d, prefix %U/%d\n",
14986            ntohl (mp->table_id), format_ip4_address, mp->address,
14987            mp->address_length);
14988   fp = mp->path;
14989   for (i = 0; i < count; i++)
14990     {
14991       fformat (vam->ofp,
14992                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, is_unreach %d, "
14993                "is_prohitbit %d, afi %d, next_hop %U\n", ntohl (fp->weight),
14994                ntohl (fp->sw_if_index), fp->is_local, fp->is_drop,
14995                fp->is_unreach, fp->is_prohibit, fp->afi, format_ip46_address,
14996                fp->next_hop, fp->afi);
14997       fp++;
14998     }
14999 }
15000
15001 static void vl_api_ip_fib_details_t_handler_json
15002   (vl_api_ip_fib_details_t * mp)
15003 {
15004   vat_main_t *vam = &vat_main;
15005   int count = ntohl (mp->count);
15006   vat_json_node_t *node = NULL;
15007   struct in_addr ip4;
15008   struct in6_addr ip6;
15009   vl_api_fib_path_t *fp;
15010   int i;
15011
15012   if (VAT_JSON_ARRAY != vam->json_tree.type)
15013     {
15014       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15015       vat_json_init_array (&vam->json_tree);
15016     }
15017   node = vat_json_array_add (&vam->json_tree);
15018
15019   vat_json_init_object (node);
15020   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15021   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15022   vat_json_object_add_ip4 (node, "prefix", ip4);
15023   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15024   vat_json_object_add_uint (node, "path_count", count);
15025   fp = mp->path;
15026   for (i = 0; i < count; i++)
15027     {
15028       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15029       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15030       vat_json_object_add_uint (node, "is_local", fp->is_local);
15031       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15032       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15033       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15034       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15035       if (fp->afi == IP46_TYPE_IP4)
15036         {
15037           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15038           vat_json_object_add_ip4 (node, "next_hop", ip4);
15039         }
15040       else if (fp->afi == IP46_TYPE_IP6)
15041         {
15042           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15043           vat_json_object_add_ip6 (node, "next_hop", ip6);
15044         }
15045     }
15046 }
15047
15048 static int
15049 api_ip_fib_dump (vat_main_t * vam)
15050 {
15051   vl_api_ip_fib_dump_t *mp;
15052   f64 timeout;
15053
15054   M (IP_FIB_DUMP, ip_fib_dump);
15055   S;
15056
15057   /* Use a control ping for synchronization */
15058   {
15059     vl_api_control_ping_t *mp;
15060     M (CONTROL_PING, control_ping);
15061     S;
15062   }
15063   W;
15064 }
15065
15066 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15067 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15068
15069 static void
15070 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15071 {
15072   vat_main_t *vam = &vat_main;
15073   int count = ntohl (mp->count);
15074   vl_api_fib_path_t *fp;
15075   int i;
15076
15077   fformat (vam->ofp,
15078            "table-id %d, prefix %U/%d\n",
15079            ntohl (mp->table_id), format_ip6_address, mp->address,
15080            mp->address_length);
15081   fp = mp->path;
15082   for (i = 0; i < count; i++)
15083     {
15084       fformat (vam->ofp,
15085                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, is_unreach %d, "
15086                "is_prohitbit %d, afi %d, next_hop %U\n", ntohl (fp->weight),
15087                ntohl (fp->sw_if_index), fp->is_local, fp->is_drop,
15088                fp->is_unreach, fp->is_prohibit, fp->afi, format_ip46_address,
15089                fp->next_hop, fp->afi);
15090       fp++;
15091     }
15092 }
15093
15094 static void vl_api_ip6_fib_details_t_handler_json
15095   (vl_api_ip6_fib_details_t * mp)
15096 {
15097   vat_main_t *vam = &vat_main;
15098   int count = ntohl (mp->count);
15099   vat_json_node_t *node = NULL;
15100   struct in_addr ip4;
15101   struct in6_addr ip6;
15102   vl_api_fib_path_t *fp;
15103   int i;
15104
15105   if (VAT_JSON_ARRAY != vam->json_tree.type)
15106     {
15107       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15108       vat_json_init_array (&vam->json_tree);
15109     }
15110   node = vat_json_array_add (&vam->json_tree);
15111
15112   vat_json_init_object (node);
15113   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15114   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15115   vat_json_object_add_ip6 (node, "prefix", ip6);
15116   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15117   vat_json_object_add_uint (node, "path_count", count);
15118   fp = mp->path;
15119   for (i = 0; i < count; i++)
15120     {
15121       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15122       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15123       vat_json_object_add_uint (node, "is_local", fp->is_local);
15124       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15125       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15126       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15127       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15128       if (fp->afi == IP46_TYPE_IP4)
15129         {
15130           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15131           vat_json_object_add_ip4 (node, "next_hop", ip4);
15132         }
15133       else if (fp->afi == IP46_TYPE_IP6)
15134         {
15135           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15136           vat_json_object_add_ip6 (node, "next_hop", ip6);
15137         }
15138     }
15139 }
15140
15141 static int
15142 api_ip6_fib_dump (vat_main_t * vam)
15143 {
15144   vl_api_ip6_fib_dump_t *mp;
15145   f64 timeout;
15146
15147   M (IP6_FIB_DUMP, ip6_fib_dump);
15148   S;
15149
15150   /* Use a control ping for synchronization */
15151   {
15152     vl_api_control_ping_t *mp;
15153     M (CONTROL_PING, control_ping);
15154     S;
15155   }
15156   W;
15157 }
15158
15159 int
15160 api_classify_table_ids (vat_main_t * vam)
15161 {
15162   vl_api_classify_table_ids_t *mp;
15163   f64 timeout;
15164
15165   /* Construct the API message */
15166   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15167   mp->context = 0;
15168
15169   S;
15170   W;
15171   /* NOTREACHED */
15172   return 0;
15173 }
15174
15175 int
15176 api_classify_table_by_interface (vat_main_t * vam)
15177 {
15178   unformat_input_t *input = vam->input;
15179   vl_api_classify_table_by_interface_t *mp;
15180   f64 timeout;
15181
15182   u32 sw_if_index = ~0;
15183   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15184     {
15185       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15186         ;
15187       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15188         ;
15189       else
15190         break;
15191     }
15192   if (sw_if_index == ~0)
15193     {
15194       errmsg ("missing interface name or sw_if_index\n");
15195       return -99;
15196     }
15197
15198   /* Construct the API message */
15199   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15200   mp->context = 0;
15201   mp->sw_if_index = ntohl (sw_if_index);
15202
15203   S;
15204   W;
15205   /* NOTREACHED */
15206   return 0;
15207 }
15208
15209 int
15210 api_classify_table_info (vat_main_t * vam)
15211 {
15212   unformat_input_t *input = vam->input;
15213   vl_api_classify_table_info_t *mp;
15214   f64 timeout;
15215
15216   u32 table_id = ~0;
15217   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15218     {
15219       if (unformat (input, "table_id %d", &table_id))
15220         ;
15221       else
15222         break;
15223     }
15224   if (table_id == ~0)
15225     {
15226       errmsg ("missing table id\n");
15227       return -99;
15228     }
15229
15230   /* Construct the API message */
15231   M (CLASSIFY_TABLE_INFO, classify_table_info);
15232   mp->context = 0;
15233   mp->table_id = ntohl (table_id);
15234
15235   S;
15236   W;
15237   /* NOTREACHED */
15238   return 0;
15239 }
15240
15241 int
15242 api_classify_session_dump (vat_main_t * vam)
15243 {
15244   unformat_input_t *input = vam->input;
15245   vl_api_classify_session_dump_t *mp;
15246   f64 timeout;
15247
15248   u32 table_id = ~0;
15249   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15250     {
15251       if (unformat (input, "table_id %d", &table_id))
15252         ;
15253       else
15254         break;
15255     }
15256   if (table_id == ~0)
15257     {
15258       errmsg ("missing table id\n");
15259       return -99;
15260     }
15261
15262   /* Construct the API message */
15263   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15264   mp->context = 0;
15265   mp->table_id = ntohl (table_id);
15266   S;
15267
15268   /* Use a control ping for synchronization */
15269   {
15270     vl_api_control_ping_t *mp;
15271     M (CONTROL_PING, control_ping);
15272     S;
15273   }
15274   W;
15275   /* NOTREACHED */
15276   return 0;
15277 }
15278
15279 static void
15280 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15281 {
15282   vat_main_t *vam = &vat_main;
15283
15284   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15285            "src_address %U, vrf_id %d, path_mtu %u, "
15286            "template_interval %u, udp_checksum %d\n",
15287            format_ip4_address, mp->collector_address,
15288            ntohs (mp->collector_port),
15289            format_ip4_address, mp->src_address,
15290            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15291            ntohl (mp->template_interval), mp->udp_checksum);
15292
15293   vam->retval = 0;
15294   vam->result_ready = 1;
15295 }
15296
15297 static void
15298   vl_api_ipfix_exporter_details_t_handler_json
15299   (vl_api_ipfix_exporter_details_t * mp)
15300 {
15301   vat_main_t *vam = &vat_main;
15302   vat_json_node_t node;
15303   struct in_addr collector_address;
15304   struct in_addr src_address;
15305
15306   vat_json_init_object (&node);
15307   clib_memcpy (&collector_address, &mp->collector_address,
15308                sizeof (collector_address));
15309   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15310   vat_json_object_add_uint (&node, "collector_port",
15311                             ntohs (mp->collector_port));
15312   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15313   vat_json_object_add_ip4 (&node, "src_address", src_address);
15314   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15315   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15316   vat_json_object_add_uint (&node, "template_interval",
15317                             ntohl (mp->template_interval));
15318   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15319
15320   vat_json_print (vam->ofp, &node);
15321   vat_json_free (&node);
15322   vam->retval = 0;
15323   vam->result_ready = 1;
15324 }
15325
15326 int
15327 api_ipfix_exporter_dump (vat_main_t * vam)
15328 {
15329   vl_api_ipfix_exporter_dump_t *mp;
15330   f64 timeout;
15331
15332   /* Construct the API message */
15333   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15334   mp->context = 0;
15335
15336   S;
15337   W;
15338   /* NOTREACHED */
15339   return 0;
15340 }
15341
15342 static int
15343 api_ipfix_classify_stream_dump (vat_main_t * vam)
15344 {
15345   vl_api_ipfix_classify_stream_dump_t *mp;
15346   f64 timeout;
15347
15348   /* Construct the API message */
15349   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15350   mp->context = 0;
15351
15352   S;
15353   W;
15354   /* NOTREACHED */
15355   return 0;
15356 }
15357
15358 static void
15359   vl_api_ipfix_classify_stream_details_t_handler
15360   (vl_api_ipfix_classify_stream_details_t * mp)
15361 {
15362   vat_main_t *vam = &vat_main;
15363   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15364            ntohl (mp->domain_id), ntohs (mp->src_port));
15365   vam->retval = 0;
15366   vam->result_ready = 1;
15367 }
15368
15369 static void
15370   vl_api_ipfix_classify_stream_details_t_handler_json
15371   (vl_api_ipfix_classify_stream_details_t * mp)
15372 {
15373   vat_main_t *vam = &vat_main;
15374   vat_json_node_t node;
15375
15376   vat_json_init_object (&node);
15377   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15378   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15379
15380   vat_json_print (vam->ofp, &node);
15381   vat_json_free (&node);
15382   vam->retval = 0;
15383   vam->result_ready = 1;
15384 }
15385
15386 static int
15387 api_ipfix_classify_table_dump (vat_main_t * vam)
15388 {
15389   vl_api_ipfix_classify_table_dump_t *mp;
15390   f64 timeout;
15391
15392   if (!vam->json_output)
15393     {
15394       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15395                "transport_protocol");
15396     }
15397
15398   /* Construct the API message */
15399   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15400
15401   /* send it... */
15402   S;
15403
15404   /* Use a control ping for synchronization */
15405   {
15406     vl_api_control_ping_t *mp;
15407     M (CONTROL_PING, control_ping);
15408     S;
15409   }
15410   W;
15411 }
15412
15413 static void
15414   vl_api_ipfix_classify_table_details_t_handler
15415   (vl_api_ipfix_classify_table_details_t * mp)
15416 {
15417   vat_main_t *vam = &vat_main;
15418   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15419            mp->transport_protocol);
15420 }
15421
15422 static void
15423   vl_api_ipfix_classify_table_details_t_handler_json
15424   (vl_api_ipfix_classify_table_details_t * mp)
15425 {
15426   vat_json_node_t *node = NULL;
15427   vat_main_t *vam = &vat_main;
15428
15429   if (VAT_JSON_ARRAY != vam->json_tree.type)
15430     {
15431       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15432       vat_json_init_array (&vam->json_tree);
15433     }
15434
15435   node = vat_json_array_add (&vam->json_tree);
15436   vat_json_init_object (node);
15437
15438   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15439   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15440   vat_json_object_add_uint (node, "transport_protocol",
15441                             mp->transport_protocol);
15442 }
15443
15444 static int
15445 api_sw_interface_span_enable_disable (vat_main_t * vam)
15446 {
15447   unformat_input_t *i = vam->input;
15448   vl_api_sw_interface_span_enable_disable_t *mp;
15449   f64 timeout;
15450   u32 src_sw_if_index = ~0;
15451   u32 dst_sw_if_index = ~0;
15452   u8 enable = 1;
15453
15454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15455     {
15456       if (unformat (i, "src %U", unformat_sw_if_index, vam, &src_sw_if_index))
15457         ;
15458       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15459         ;
15460       else
15461         if (unformat
15462             (i, "dst %U", unformat_sw_if_index, vam, &dst_sw_if_index))
15463         ;
15464       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15465         ;
15466       else if (unformat (i, "disable"))
15467         enable = 0;
15468       else
15469         break;
15470     }
15471
15472   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15473
15474   mp->sw_if_index_from = htonl (src_sw_if_index);
15475   mp->sw_if_index_to = htonl (dst_sw_if_index);
15476   mp->enable = enable;
15477
15478   S;
15479   W;
15480   /* NOTREACHED */
15481   return 0;
15482 }
15483
15484 static void
15485 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
15486                                             * mp)
15487 {
15488   vat_main_t *vam = &vat_main;
15489
15490   fformat (vam->ofp, "%u => %u\n",
15491            ntohl (mp->sw_if_index_from), ntohl (mp->sw_if_index_to));
15492 }
15493
15494 static void
15495   vl_api_sw_interface_span_details_t_handler_json
15496   (vl_api_sw_interface_span_details_t * mp)
15497 {
15498   vat_main_t *vam = &vat_main;
15499   vat_json_node_t *node = NULL;
15500
15501   if (VAT_JSON_ARRAY != vam->json_tree.type)
15502     {
15503       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15504       vat_json_init_array (&vam->json_tree);
15505     }
15506   node = vat_json_array_add (&vam->json_tree);
15507
15508   vat_json_init_object (node);
15509   vat_json_object_add_uint (node, "src-if-index",
15510                             ntohl (mp->sw_if_index_from));
15511   vat_json_object_add_uint (node, "dst-if-index", ntohl (mp->sw_if_index_to));
15512 }
15513
15514 static int
15515 api_sw_interface_span_dump (vat_main_t * vam)
15516 {
15517   vl_api_sw_interface_span_dump_t *mp;
15518   f64 timeout;
15519
15520   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
15521   S;
15522
15523   /* Use a control ping for synchronization */
15524   {
15525     vl_api_control_ping_t *mp;
15526     M (CONTROL_PING, control_ping);
15527     S;
15528   }
15529   W;
15530 }
15531
15532 int
15533 api_pg_create_interface (vat_main_t * vam)
15534 {
15535   unformat_input_t *input = vam->input;
15536   vl_api_pg_create_interface_t *mp;
15537   f64 timeout;
15538
15539   u32 if_id = ~0;
15540   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15541     {
15542       if (unformat (input, "if_id %d", &if_id))
15543         ;
15544       else
15545         break;
15546     }
15547   if (if_id == ~0)
15548     {
15549       errmsg ("missing pg interface index\n");
15550       return -99;
15551     }
15552
15553   /* Construct the API message */
15554   M (PG_CREATE_INTERFACE, pg_create_interface);
15555   mp->context = 0;
15556   mp->interface_id = ntohl (if_id);
15557
15558   S;
15559   W;
15560   /* NOTREACHED */
15561   return 0;
15562 }
15563
15564 int
15565 api_pg_capture (vat_main_t * vam)
15566 {
15567   unformat_input_t *input = vam->input;
15568   vl_api_pg_capture_t *mp;
15569   f64 timeout;
15570
15571   u32 if_id = ~0;
15572   u8 enable = 1;
15573   u32 count = 1;
15574   u8 pcap_file_set = 0;
15575   u8 *pcap_file = 0;
15576   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15577     {
15578       if (unformat (input, "if_id %d", &if_id))
15579         ;
15580       else if (unformat (input, "pcap %s", &pcap_file))
15581         pcap_file_set = 1;
15582       else if (unformat (input, "count %d", &count))
15583         ;
15584       else if (unformat (input, "disable"))
15585         enable = 0;
15586       else
15587         break;
15588     }
15589   if (if_id == ~0)
15590     {
15591       errmsg ("missing pg interface index\n");
15592       return -99;
15593     }
15594   if (pcap_file_set > 0)
15595     {
15596       if (vec_len (pcap_file) > 255)
15597         {
15598           errmsg ("pcap file name is too long\n");
15599           return -99;
15600         }
15601     }
15602
15603   u32 name_len = vec_len (pcap_file);
15604   /* Construct the API message */
15605   M (PG_CAPTURE, pg_capture);
15606   mp->context = 0;
15607   mp->interface_id = ntohl (if_id);
15608   mp->is_enabled = enable;
15609   mp->count = ntohl (count);
15610   mp->pcap_name_length = ntohl (name_len);
15611   if (pcap_file_set != 0)
15612     {
15613       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15614     }
15615   vec_free (pcap_file);
15616
15617   S;
15618   W;
15619   /* NOTREACHED */
15620   return 0;
15621 }
15622
15623 int
15624 api_pg_enable_disable (vat_main_t * vam)
15625 {
15626   unformat_input_t *input = vam->input;
15627   vl_api_pg_enable_disable_t *mp;
15628   f64 timeout;
15629
15630   u8 enable = 1;
15631   u8 stream_name_set = 0;
15632   u8 *stream_name = 0;
15633   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15634     {
15635       if (unformat (input, "stream %s", &stream_name))
15636         stream_name_set = 1;
15637       else if (unformat (input, "disable"))
15638         enable = 0;
15639       else
15640         break;
15641     }
15642
15643   if (stream_name_set > 0)
15644     {
15645       if (vec_len (stream_name) > 255)
15646         {
15647           errmsg ("stream name too long\n");
15648           return -99;
15649         }
15650     }
15651
15652   u32 name_len = vec_len (stream_name);
15653   /* Construct the API message */
15654   M (PG_ENABLE_DISABLE, pg_enable_disable);
15655   mp->context = 0;
15656   mp->is_enabled = enable;
15657   if (stream_name_set != 0)
15658     {
15659       mp->stream_name_length = ntohl (name_len);
15660       clib_memcpy (mp->stream_name, stream_name, name_len);
15661     }
15662   vec_free (stream_name);
15663
15664   S;
15665   W;
15666   /* NOTREACHED */
15667   return 0;
15668 }
15669
15670 int
15671 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15672 {
15673   unformat_input_t *input = vam->input;
15674   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15675   f64 timeout;
15676
15677   u16 *low_ports = 0;
15678   u16 *high_ports = 0;
15679   u16 this_low;
15680   u16 this_hi;
15681   ip4_address_t ip4_addr;
15682   ip6_address_t ip6_addr;
15683   u32 length;
15684   u32 tmp, tmp2;
15685   u8 prefix_set = 0;
15686   u32 vrf_id = ~0;
15687   u8 is_add = 1;
15688   u8 is_ipv6 = 0;
15689
15690   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15691     {
15692       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15693         {
15694           prefix_set = 1;
15695         }
15696       else
15697         if (unformat
15698             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15699         {
15700           prefix_set = 1;
15701           is_ipv6 = 1;
15702         }
15703       else if (unformat (input, "vrf %d", &vrf_id))
15704         ;
15705       else if (unformat (input, "del"))
15706         is_add = 0;
15707       else if (unformat (input, "port %d", &tmp))
15708         {
15709           if (tmp == 0 || tmp > 65535)
15710             {
15711               errmsg ("port %d out of range", tmp);
15712               return -99;
15713             }
15714           this_low = tmp;
15715           this_hi = this_low + 1;
15716           vec_add1 (low_ports, this_low);
15717           vec_add1 (high_ports, this_hi);
15718         }
15719       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15720         {
15721           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15722             {
15723               errmsg ("incorrect range parameters\n");
15724               return -99;
15725             }
15726           this_low = tmp;
15727           /* Note: in debug CLI +1 is added to high before
15728              passing to real fn that does "the work"
15729              (ip_source_and_port_range_check_add_del).
15730              This fn is a wrapper around the binary API fn a
15731              control plane will call, which expects this increment
15732              to have occurred. Hence letting the binary API control
15733              plane fn do the increment for consistency between VAT
15734              and other control planes.
15735            */
15736           this_hi = tmp2;
15737           vec_add1 (low_ports, this_low);
15738           vec_add1 (high_ports, this_hi);
15739         }
15740       else
15741         break;
15742     }
15743
15744   if (prefix_set == 0)
15745     {
15746       errmsg ("<address>/<mask> not specified\n");
15747       return -99;
15748     }
15749
15750   if (vrf_id == ~0)
15751     {
15752       errmsg ("VRF ID required, not specified\n");
15753       return -99;
15754     }
15755
15756   if (vrf_id == 0)
15757     {
15758       errmsg
15759         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15760       return -99;
15761     }
15762
15763   if (vec_len (low_ports) == 0)
15764     {
15765       errmsg ("At least one port or port range required\n");
15766       return -99;
15767     }
15768
15769   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15770      ip_source_and_port_range_check_add_del);
15771
15772   mp->is_add = is_add;
15773
15774   if (is_ipv6)
15775     {
15776       mp->is_ipv6 = 1;
15777       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15778     }
15779   else
15780     {
15781       mp->is_ipv6 = 0;
15782       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15783     }
15784
15785   mp->mask_length = length;
15786   mp->number_of_ranges = vec_len (low_ports);
15787
15788   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15789   vec_free (low_ports);
15790
15791   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15792   vec_free (high_ports);
15793
15794   mp->vrf_id = ntohl (vrf_id);
15795
15796   S;
15797   W;
15798   /* NOTREACHED */
15799   return 0;
15800 }
15801
15802 int
15803 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15804 {
15805   unformat_input_t *input = vam->input;
15806   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15807   f64 timeout;
15808   u32 sw_if_index = ~0;
15809   int vrf_set = 0;
15810   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15811   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15812   u8 is_add = 1;
15813
15814   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15815     {
15816       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15817         ;
15818       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15819         ;
15820       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15821         vrf_set = 1;
15822       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15823         vrf_set = 1;
15824       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15825         vrf_set = 1;
15826       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15827         vrf_set = 1;
15828       else if (unformat (input, "del"))
15829         is_add = 0;
15830       else
15831         break;
15832     }
15833
15834   if (sw_if_index == ~0)
15835     {
15836       errmsg ("Interface required but not specified\n");
15837       return -99;
15838     }
15839
15840   if (vrf_set == 0)
15841     {
15842       errmsg ("VRF ID required but not specified\n");
15843       return -99;
15844     }
15845
15846   if (tcp_out_vrf_id == 0
15847       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15848     {
15849       errmsg
15850         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15851       return -99;
15852     }
15853
15854   /* Construct the API message */
15855   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15856      ip_source_and_port_range_check_interface_add_del);
15857
15858   mp->sw_if_index = ntohl (sw_if_index);
15859   mp->is_add = is_add;
15860   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15861   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15862   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15863   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15864
15865   /* send it... */
15866   S;
15867
15868   /* Wait for a reply... */
15869   W;
15870 }
15871
15872 static int
15873 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15874 {
15875   unformat_input_t *i = vam->input;
15876   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15877   f64 timeout;
15878   u32 local_sa_id = 0;
15879   u32 remote_sa_id = 0;
15880   ip4_address_t src_address;
15881   ip4_address_t dst_address;
15882   u8 is_add = 1;
15883
15884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15885     {
15886       if (unformat (i, "local_sa %d", &local_sa_id))
15887         ;
15888       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15889         ;
15890       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15891         ;
15892       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15893         ;
15894       else if (unformat (i, "del"))
15895         is_add = 0;
15896       else
15897         {
15898           clib_warning ("parse error '%U'", format_unformat_error, i);
15899           return -99;
15900         }
15901     }
15902
15903   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15904
15905   mp->local_sa_id = ntohl (local_sa_id);
15906   mp->remote_sa_id = ntohl (remote_sa_id);
15907   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15908   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15909   mp->is_add = is_add;
15910
15911   S;
15912   W;
15913   /* NOTREACHED */
15914   return 0;
15915 }
15916
15917 static int
15918 api_punt (vat_main_t * vam)
15919 {
15920   unformat_input_t *i = vam->input;
15921   vl_api_punt_t *mp;
15922   f64 timeout;
15923   u32 ipv = ~0;
15924   u32 protocol = ~0;
15925   u32 port = ~0;
15926   int is_add = 1;
15927
15928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15929     {
15930       if (unformat (i, "ip %d", &ipv))
15931         ;
15932       else if (unformat (i, "protocol %d", &protocol))
15933         ;
15934       else if (unformat (i, "port %d", &port))
15935         ;
15936       else if (unformat (i, "del"))
15937         is_add = 0;
15938       else
15939         {
15940           clib_warning ("parse error '%U'", format_unformat_error, i);
15941           return -99;
15942         }
15943     }
15944
15945   M (PUNT, punt);
15946
15947   mp->is_add = (u8) is_add;
15948   mp->ipv = (u8) ipv;
15949   mp->l4_protocol = (u8) protocol;
15950   mp->l4_port = htons ((u16) port);
15951
15952   S;
15953   W;
15954   /* NOTREACHED */
15955   return 0;
15956 }
15957
15958 static void vl_api_ipsec_gre_tunnel_details_t_handler
15959   (vl_api_ipsec_gre_tunnel_details_t * mp)
15960 {
15961   vat_main_t *vam = &vat_main;
15962
15963   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15964            ntohl (mp->sw_if_index),
15965            format_ip4_address, &mp->src_address,
15966            format_ip4_address, &mp->dst_address,
15967            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15968 }
15969
15970 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15971   (vl_api_ipsec_gre_tunnel_details_t * mp)
15972 {
15973   vat_main_t *vam = &vat_main;
15974   vat_json_node_t *node = NULL;
15975   struct in_addr ip4;
15976
15977   if (VAT_JSON_ARRAY != vam->json_tree.type)
15978     {
15979       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15980       vat_json_init_array (&vam->json_tree);
15981     }
15982   node = vat_json_array_add (&vam->json_tree);
15983
15984   vat_json_init_object (node);
15985   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15986   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15987   vat_json_object_add_ip4 (node, "src_address", ip4);
15988   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15989   vat_json_object_add_ip4 (node, "dst_address", ip4);
15990   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15991   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15992 }
15993
15994 static int
15995 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15996 {
15997   unformat_input_t *i = vam->input;
15998   vl_api_ipsec_gre_tunnel_dump_t *mp;
15999   f64 timeout;
16000   u32 sw_if_index;
16001   u8 sw_if_index_set = 0;
16002
16003   /* Parse args required to build the message */
16004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16005     {
16006       if (unformat (i, "sw_if_index %d", &sw_if_index))
16007         sw_if_index_set = 1;
16008       else
16009         break;
16010     }
16011
16012   if (sw_if_index_set == 0)
16013     {
16014       sw_if_index = ~0;
16015     }
16016
16017   if (!vam->json_output)
16018     {
16019       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
16020                "sw_if_index", "src_address", "dst_address",
16021                "local_sa_id", "remote_sa_id");
16022     }
16023
16024   /* Get list of gre-tunnel interfaces */
16025   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16026
16027   mp->sw_if_index = htonl (sw_if_index);
16028
16029   S;
16030
16031   /* Use a control ping for synchronization */
16032   {
16033     vl_api_control_ping_t *mp;
16034     M (CONTROL_PING, control_ping);
16035     S;
16036   }
16037   W;
16038 }
16039
16040 static int
16041 api_delete_subif (vat_main_t * vam)
16042 {
16043   unformat_input_t *i = vam->input;
16044   vl_api_delete_subif_t *mp;
16045   f64 timeout;
16046   u32 sw_if_index = ~0;
16047
16048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16049     {
16050       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16051         ;
16052       if (unformat (i, "sw_if_index %d", &sw_if_index))
16053         ;
16054       else
16055         break;
16056     }
16057
16058   if (sw_if_index == ~0)
16059     {
16060       errmsg ("missing sw_if_index\n");
16061       return -99;
16062     }
16063
16064   /* Construct the API message */
16065   M (DELETE_SUBIF, delete_subif);
16066   mp->sw_if_index = ntohl (sw_if_index);
16067
16068   S;
16069   W;
16070 }
16071
16072 #define foreach_pbb_vtr_op      \
16073 _("disable",  L2_VTR_DISABLED)  \
16074 _("pop",  L2_VTR_POP_2)         \
16075 _("push",  L2_VTR_PUSH_2)
16076
16077 static int
16078 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16079 {
16080   unformat_input_t *i = vam->input;
16081   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16082   f64 timeout;
16083   u32 sw_if_index = ~0, vtr_op = ~0;
16084   u16 outer_tag = ~0;
16085   u8 dmac[6], smac[6];
16086   u8 dmac_set = 0, smac_set = 0;
16087   u16 vlanid = 0;
16088   u32 sid = ~0;
16089   u32 tmp;
16090
16091   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16092     {
16093       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16094         ;
16095       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16096         ;
16097       else if (unformat (i, "vtr_op %d", &vtr_op))
16098         ;
16099 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16100       foreach_pbb_vtr_op
16101 #undef _
16102         else if (unformat (i, "translate_pbb_stag"))
16103         {
16104           if (unformat (i, "%d", &tmp))
16105             {
16106               vtr_op = L2_VTR_TRANSLATE_2_1;
16107               outer_tag = tmp;
16108             }
16109           else
16110             {
16111               errmsg
16112                 ("translate_pbb_stag operation requires outer tag definition\n");
16113               return -99;
16114             }
16115         }
16116       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16117         dmac_set++;
16118       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16119         smac_set++;
16120       else if (unformat (i, "sid %d", &sid))
16121         ;
16122       else if (unformat (i, "vlanid %d", &tmp))
16123         vlanid = tmp;
16124       else
16125         {
16126           clib_warning ("parse error '%U'", format_unformat_error, i);
16127           return -99;
16128         }
16129     }
16130
16131   if ((sw_if_index == ~0) || (vtr_op == ~0))
16132     {
16133       errmsg ("missing sw_if_index or vtr operation\n");
16134       return -99;
16135     }
16136   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16137       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16138     {
16139       errmsg
16140         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
16141       return -99;
16142     }
16143
16144   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16145   mp->sw_if_index = ntohl (sw_if_index);
16146   mp->vtr_op = ntohl (vtr_op);
16147   mp->outer_tag = ntohs (outer_tag);
16148   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16149   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16150   mp->b_vlanid = ntohs (vlanid);
16151   mp->i_sid = ntohl (sid);
16152
16153   S;
16154   W;
16155   /* NOTREACHED */
16156   return 0;
16157 }
16158
16159 static int
16160 api_flow_classify_set_interface (vat_main_t * vam)
16161 {
16162   unformat_input_t *i = vam->input;
16163   vl_api_flow_classify_set_interface_t *mp;
16164   f64 timeout;
16165   u32 sw_if_index;
16166   int sw_if_index_set;
16167   u32 ip4_table_index = ~0;
16168   u32 ip6_table_index = ~0;
16169   u8 is_add = 1;
16170
16171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16172     {
16173       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16174         sw_if_index_set = 1;
16175       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16176         sw_if_index_set = 1;
16177       else if (unformat (i, "del"))
16178         is_add = 0;
16179       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16180         ;
16181       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16182         ;
16183       else
16184         {
16185           clib_warning ("parse error '%U'", format_unformat_error, i);
16186           return -99;
16187         }
16188     }
16189
16190   if (sw_if_index_set == 0)
16191     {
16192       errmsg ("missing interface name or sw_if_index\n");
16193       return -99;
16194     }
16195
16196   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16197
16198   mp->sw_if_index = ntohl (sw_if_index);
16199   mp->ip4_table_index = ntohl (ip4_table_index);
16200   mp->ip6_table_index = ntohl (ip6_table_index);
16201   mp->is_add = is_add;
16202
16203   S;
16204   W;
16205   /* NOTREACHED */
16206   return 0;
16207 }
16208
16209 static int
16210 api_flow_classify_dump (vat_main_t * vam)
16211 {
16212   unformat_input_t *i = vam->input;
16213   vl_api_flow_classify_dump_t *mp;
16214   f64 timeout = ~0;
16215   u8 type = FLOW_CLASSIFY_N_TABLES;
16216
16217   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16218     ;
16219   else
16220     {
16221       errmsg ("classify table type must be specified\n");
16222       return -99;
16223     }
16224
16225   if (!vam->json_output)
16226     {
16227       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
16228     }
16229
16230   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16231   mp->type = type;
16232   /* send it... */
16233   S;
16234
16235   /* Use a control ping for synchronization */
16236   {
16237     vl_api_control_ping_t *mp;
16238     M (CONTROL_PING, control_ping);
16239     S;
16240   }
16241   /* Wait for a reply... */
16242   W;
16243
16244   /* NOTREACHED */
16245   return 0;
16246 }
16247
16248 static int
16249 q_or_quit (vat_main_t * vam)
16250 {
16251   longjmp (vam->jump_buf, 1);
16252   return 0;                     /* not so much */
16253 }
16254
16255 static int
16256 q (vat_main_t * vam)
16257 {
16258   return q_or_quit (vam);
16259 }
16260
16261 static int
16262 quit (vat_main_t * vam)
16263 {
16264   return q_or_quit (vam);
16265 }
16266
16267 static int
16268 comment (vat_main_t * vam)
16269 {
16270   return 0;
16271 }
16272
16273 static int
16274 cmd_cmp (void *a1, void *a2)
16275 {
16276   u8 **c1 = a1;
16277   u8 **c2 = a2;
16278
16279   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
16280 }
16281
16282 static int
16283 help (vat_main_t * vam)
16284 {
16285   u8 **cmds = 0;
16286   u8 *name = 0;
16287   hash_pair_t *p;
16288   unformat_input_t *i = vam->input;
16289   int j;
16290
16291   if (unformat (i, "%s", &name))
16292     {
16293       uword *hs;
16294
16295       vec_add1 (name, 0);
16296
16297       hs = hash_get_mem (vam->help_by_name, name);
16298       if (hs)
16299         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
16300       else
16301         fformat (vam->ofp, "No such msg / command '%s'\n", name);
16302       vec_free (name);
16303       return 0;
16304     }
16305
16306   fformat (vam->ofp, "Help is available for the following:\n");
16307
16308     /* *INDENT-OFF* */
16309     hash_foreach_pair (p, vam->function_by_name,
16310     ({
16311       vec_add1 (cmds, (u8 *)(p->key));
16312     }));
16313     /* *INDENT-ON* */
16314
16315   vec_sort_with_function (cmds, cmd_cmp);
16316
16317   for (j = 0; j < vec_len (cmds); j++)
16318     fformat (vam->ofp, "%s\n", cmds[j]);
16319
16320   vec_free (cmds);
16321   return 0;
16322 }
16323
16324 static int
16325 set (vat_main_t * vam)
16326 {
16327   u8 *name = 0, *value = 0;
16328   unformat_input_t *i = vam->input;
16329
16330   if (unformat (i, "%s", &name))
16331     {
16332       /* The input buffer is a vector, not a string. */
16333       value = vec_dup (i->buffer);
16334       vec_delete (value, i->index, 0);
16335       /* Almost certainly has a trailing newline */
16336       if (value[vec_len (value) - 1] == '\n')
16337         value[vec_len (value) - 1] = 0;
16338       /* Make sure it's a proper string, one way or the other */
16339       vec_add1 (value, 0);
16340       (void) clib_macro_set_value (&vam->macro_main,
16341                                    (char *) name, (char *) value);
16342     }
16343   else
16344     errmsg ("usage: set <name> <value>\n");
16345
16346   vec_free (name);
16347   vec_free (value);
16348   return 0;
16349 }
16350
16351 static int
16352 unset (vat_main_t * vam)
16353 {
16354   u8 *name = 0;
16355
16356   if (unformat (vam->input, "%s", &name))
16357     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
16358       errmsg ("unset: %s wasn't set\n", name);
16359   vec_free (name);
16360   return 0;
16361 }
16362
16363 typedef struct
16364 {
16365   u8 *name;
16366   u8 *value;
16367 } macro_sort_t;
16368
16369
16370 static int
16371 macro_sort_cmp (void *a1, void *a2)
16372 {
16373   macro_sort_t *s1 = a1;
16374   macro_sort_t *s2 = a2;
16375
16376   return strcmp ((char *) (s1->name), (char *) (s2->name));
16377 }
16378
16379 static int
16380 dump_macro_table (vat_main_t * vam)
16381 {
16382   macro_sort_t *sort_me = 0, *sm;
16383   int i;
16384   hash_pair_t *p;
16385
16386     /* *INDENT-OFF* */
16387     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
16388     ({
16389       vec_add2 (sort_me, sm, 1);
16390       sm->name = (u8 *)(p->key);
16391       sm->value = (u8 *) (p->value[0]);
16392     }));
16393     /* *INDENT-ON* */
16394
16395   vec_sort_with_function (sort_me, macro_sort_cmp);
16396
16397   if (vec_len (sort_me))
16398     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
16399   else
16400     fformat (vam->ofp, "The macro table is empty...\n");
16401
16402   for (i = 0; i < vec_len (sort_me); i++)
16403     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
16404   return 0;
16405 }
16406
16407 static int
16408 dump_node_table (vat_main_t * vam)
16409 {
16410   int i, j;
16411   vlib_node_t *node, *next_node;
16412
16413   if (vec_len (vam->graph_nodes) == 0)
16414     {
16415       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16416       return 0;
16417     }
16418
16419   for (i = 0; i < vec_len (vam->graph_nodes); i++)
16420     {
16421       node = vam->graph_nodes[i];
16422       fformat (vam->ofp, "[%d] %s\n", i, node->name);
16423       for (j = 0; j < vec_len (node->next_nodes); j++)
16424         {
16425           if (node->next_nodes[j] != ~0)
16426             {
16427               next_node = vam->graph_nodes[node->next_nodes[j]];
16428               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16429             }
16430         }
16431     }
16432   return 0;
16433 }
16434
16435 static int
16436 search_node_table (vat_main_t * vam)
16437 {
16438   unformat_input_t *line_input = vam->input;
16439   u8 *node_to_find;
16440   int j;
16441   vlib_node_t *node, *next_node;
16442   uword *p;
16443
16444   if (vam->graph_node_index_by_name == 0)
16445     {
16446       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16447       return 0;
16448     }
16449
16450   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16451     {
16452       if (unformat (line_input, "%s", &node_to_find))
16453         {
16454           vec_add1 (node_to_find, 0);
16455           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
16456           if (p == 0)
16457             {
16458               fformat (vam->ofp, "%s not found...\n", node_to_find);
16459               goto out;
16460             }
16461           node = vam->graph_nodes[p[0]];
16462           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
16463           for (j = 0; j < vec_len (node->next_nodes); j++)
16464             {
16465               if (node->next_nodes[j] != ~0)
16466                 {
16467                   next_node = vam->graph_nodes[node->next_nodes[j]];
16468                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16469                 }
16470             }
16471         }
16472
16473       else
16474         {
16475           clib_warning ("parse error '%U'", format_unformat_error,
16476                         line_input);
16477           return -99;
16478         }
16479
16480     out:
16481       vec_free (node_to_find);
16482
16483     }
16484
16485   return 0;
16486 }
16487
16488
16489 static int
16490 script (vat_main_t * vam)
16491 {
16492   u8 *s = 0;
16493   char *save_current_file;
16494   unformat_input_t save_input;
16495   jmp_buf save_jump_buf;
16496   u32 save_line_number;
16497
16498   FILE *new_fp, *save_ifp;
16499
16500   if (unformat (vam->input, "%s", &s))
16501     {
16502       new_fp = fopen ((char *) s, "r");
16503       if (new_fp == 0)
16504         {
16505           errmsg ("Couldn't open script file %s\n", s);
16506           vec_free (s);
16507           return -99;
16508         }
16509     }
16510   else
16511     {
16512       errmsg ("Missing script name\n");
16513       return -99;
16514     }
16515
16516   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
16517   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
16518   save_ifp = vam->ifp;
16519   save_line_number = vam->input_line_number;
16520   save_current_file = (char *) vam->current_file;
16521
16522   vam->input_line_number = 0;
16523   vam->ifp = new_fp;
16524   vam->current_file = s;
16525   do_one_file (vam);
16526
16527   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
16528   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
16529   vam->ifp = save_ifp;
16530   vam->input_line_number = save_line_number;
16531   vam->current_file = (u8 *) save_current_file;
16532   vec_free (s);
16533
16534   return 0;
16535 }
16536
16537 static int
16538 echo (vat_main_t * vam)
16539 {
16540   fformat (vam->ofp, "%v", vam->input->buffer);
16541   return 0;
16542 }
16543
16544 /* List of API message constructors, CLI names map to api_xxx */
16545 #define foreach_vpe_api_msg                                             \
16546 _(create_loopback,"[mac <mac-addr>]")                                   \
16547 _(sw_interface_dump,"")                                                 \
16548 _(sw_interface_set_flags,                                               \
16549   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
16550 _(sw_interface_add_del_address,                                         \
16551   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
16552 _(sw_interface_set_table,                                               \
16553   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
16554 _(sw_interface_set_mpls_enable,                                                \
16555   "<intfc> | sw_if_index [disable | dis]")                                \
16556 _(sw_interface_set_vpath,                                               \
16557   "<intfc> | sw_if_index <id> enable | disable")                        \
16558 _(sw_interface_set_l2_xconnect,                                         \
16559   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16560   "enable | disable")                                                   \
16561 _(sw_interface_set_l2_bridge,                                           \
16562   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16563   "[shg <split-horizon-group>] [bvi]\n"                                 \
16564   "enable | disable")                                                   \
16565 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16566   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16567   "profile <profile-id>\n")                                             \
16568 _(sw_interface_set_dpdk_hqos_subport,                                   \
16569   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16570   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16571 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16572   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16573 _(bridge_domain_add_del,                                                \
16574   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16575 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16576 _(l2fib_add_del,                                                        \
16577   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16578 _(l2_flags,                                                             \
16579   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16580 _(bridge_flags,                                                         \
16581   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16582 _(tap_connect,                                                          \
16583   "tapname <name> mac <mac-addr> | random-mac")                         \
16584 _(tap_modify,                                                           \
16585   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16586 _(tap_delete,                                                           \
16587   "<vpp-if-name> | sw_if_index <id>")                                   \
16588 _(sw_interface_tap_dump, "")                                            \
16589 _(ip_add_del_route,                                                     \
16590   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
16591   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16592   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16593   "[multipath] [count <n>]")                                            \
16594 _(mpls_route_add_del,                                                   \
16595   "<label> <eos> via <addr> [table-id <n>]\n"                           \
16596   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16597   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16598   "[multipath] [count <n>]")                                            \
16599 _(mpls_ip_bind_unbind,                                                  \
16600   "<label> <addr/len>")                                                 \
16601 _(proxy_arp_add_del,                                                    \
16602   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16603 _(proxy_arp_intfc_enable_disable,                                       \
16604   "<intfc> | sw_if_index <id> enable | disable")                        \
16605 _(mpls_add_del_encap,                                                   \
16606   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
16607 _(sw_interface_set_unnumbered,                                          \
16608   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16609 _(ip_neighbor_add_del,                                                  \
16610   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16611   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16612 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16613 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16614 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16615   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16616   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16617   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16618 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16619 _(reset_fib, "vrf <n> [ipv6]")                                          \
16620 _(dhcp_proxy_config,                                                    \
16621   "svr <v46-address> src <v46-address>\n"                               \
16622    "insert-cid <n> [del]")                                              \
16623 _(dhcp_proxy_config_2,                                                  \
16624   "svr <v46-address> src <v46-address>\n"                               \
16625    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16626 _(dhcp_proxy_set_vss,                                                   \
16627   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16628 _(dhcp_client_config,                                                   \
16629   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16630 _(set_ip_flow_hash,                                                     \
16631   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16632 _(sw_interface_ip6_enable_disable,                                      \
16633   "<intfc> | sw_if_index <id> enable | disable")                        \
16634 _(sw_interface_ip6_set_link_local_address,                              \
16635   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16636 _(sw_interface_ip6nd_ra_prefix,                                         \
16637   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16638   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16639   "[nolink] [isno]")                                                    \
16640 _(sw_interface_ip6nd_ra_config,                                         \
16641   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16642   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16643   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16644 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16645 _(l2_patch_add_del,                                                     \
16646   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16647   "enable | disable")                                                   \
16648 _(mpls_ethernet_add_del_tunnel,                                         \
16649   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
16650   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
16651 _(mpls_ethernet_add_del_tunnel_2,                                       \
16652   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
16653   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
16654 _(sr_tunnel_add_del,                                                    \
16655   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16656   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16657   "[policy <policy_name>]")                                             \
16658 _(sr_policy_add_del,                                                    \
16659   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16660 _(sr_multicast_map_add_del,                                             \
16661   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16662 _(classify_add_del_table,                                               \
16663   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16664   " [del] mask <mask-value>\n"                                          \
16665   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
16666   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
16667 _(classify_add_del_session,                                             \
16668   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16669   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16670   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
16671   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
16672 _(classify_set_interface_ip_table,                                      \
16673   "<intfc> | sw_if_index <nn> table <nn>")                              \
16674 _(classify_set_interface_l2_tables,                                     \
16675   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16676   "  [other-table <nn>]")                                               \
16677 _(get_node_index, "node <node-name")                                    \
16678 _(add_node_next, "node <node-name> next <next-node-name>")              \
16679 _(l2tpv3_create_tunnel,                                                 \
16680   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16681   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16682   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16683 _(l2tpv3_set_tunnel_cookies,                                            \
16684   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16685   "[new_remote_cookie <nn>]\n")                                         \
16686 _(l2tpv3_interface_enable_disable,                                      \
16687   "<intfc> | sw_if_index <nn> enable | disable")                        \
16688 _(l2tpv3_set_lookup_key,                                                \
16689   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16690 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16691 _(vxlan_add_del_tunnel,                                                 \
16692   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
16693   " [decap-next l2|ip4|ip6] [del]")                                     \
16694 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16695 _(gre_add_del_tunnel,                                                   \
16696   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16697 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16698 _(l2_fib_clear_table, "")                                               \
16699 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16700 _(l2_interface_vlan_tag_rewrite,                                        \
16701   "<intfc> | sw_if_index <nn> \n"                                       \
16702   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
16703   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
16704 _(create_vhost_user_if,                                                 \
16705         "socket <filename> [server] [renumber <dev_instance>] "         \
16706         "[mac <mac_address>]")                                          \
16707 _(modify_vhost_user_if,                                                 \
16708         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
16709         "[server] [renumber <dev_instance>]")                           \
16710 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
16711 _(sw_interface_vhost_user_dump, "")                                     \
16712 _(show_version, "")                                                     \
16713 _(vxlan_gpe_add_del_tunnel,                                             \
16714   "local <addr> remote <addr> vni <nn>\n"                               \
16715     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
16716   "[next-ethernet] [next-nsh]\n")                                       \
16717 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
16718 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
16719 _(interface_name_renumber,                                              \
16720   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
16721 _(input_acl_set_interface,                                              \
16722   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16723   "  [l2-table <nn>] [del]")                                            \
16724 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
16725 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
16726 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
16727 _(ip_dump, "ipv4 | ipv6")                                               \
16728 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
16729 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
16730   "  spid_id <n> ")                                                     \
16731 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
16732   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
16733   "  integ_alg <alg> integ_key <hex>")                                  \
16734 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
16735   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
16736   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
16737   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
16738 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
16739 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
16740 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
16741   "(auth_data 0x<data> | auth_data <data>)")                            \
16742 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
16743   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
16744 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16745   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16746   "(local|remote)")                                                     \
16747 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16748 _(delete_loopback,"sw_if_index <nn>")                                   \
16749 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16750 _(map_add_domain,                                                       \
16751   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16752   "ip6-src <ip6addr> "                                                  \
16753   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16754 _(map_del_domain, "index <n>")                                          \
16755 _(map_add_del_rule,                                                     \
16756   "index <n> psid <n> dst <ip6addr> [del]")                             \
16757 _(map_domain_dump, "")                                                  \
16758 _(map_rule_dump, "index <map-domain>")                                  \
16759 _(want_interface_events,  "enable|disable")                             \
16760 _(want_stats,"enable|disable")                                          \
16761 _(get_first_msg_id, "client <name>")                                    \
16762 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16763 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16764   "fib-id <nn> [ip4][ip6][default]")                                    \
16765 _(get_node_graph, " ")                                                  \
16766 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16767 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16768 _(ioam_disable, "")                                                \
16769 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16770                             " sw_if_index <sw_if_index> p <priority> "  \
16771                             "w <weight>] [del]")                        \
16772 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16773                         "iface <intf> | sw_if_index <sw_if_index> "     \
16774                         "p <priority> w <weight> [del]")                \
16775 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16776                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16777                           "locator-set <locator_name> [del]")           \
16778 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16779   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16780 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16781 _(lisp_gpe_enable_disable, "enable|disable")                            \
16782 _(lisp_enable_disable, "enable|disable")                                \
16783 _(lisp_gpe_add_del_iface, "up|down")                                    \
16784 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
16785                                "[seid <seid>] "                         \
16786                                "rloc <locator> p <prio> "               \
16787                                "w <weight> [rloc <loc> ... ] "          \
16788                                "action <action> [del-all]")             \
16789 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
16790                           "<local-eid>")                                \
16791 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16792 _(lisp_map_request_mode, "src-dst|dst-only")                            \
16793 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16794 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16795 _(lisp_locator_set_dump, "[local | remote]")                            \
16796 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
16797 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16798                        "[local] | [remote]")                            \
16799 _(lisp_eid_table_vni_dump, "")                                          \
16800 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16801 _(lisp_gpe_tunnel_dump, "")                                             \
16802 _(lisp_map_resolver_dump, "")                                           \
16803 _(lisp_adjacencies_get, "vni <vni>")                                    \
16804 _(show_lisp_status, "")                                                 \
16805 _(lisp_get_map_request_itr_rlocs, "")                                   \
16806 _(show_lisp_pitr, "")                                                   \
16807 _(show_lisp_map_request_mode, "")                                       \
16808 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16809 _(af_packet_delete, "name <host interface name>")                       \
16810 _(policer_add_del, "name <policer name> <params> [del]")                \
16811 _(policer_dump, "[name <policer name>]")                                \
16812 _(policer_classify_set_interface,                                       \
16813   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16814   "  [l2-table <nn>] [del]")                                            \
16815 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16816 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16817     "[master|slave]")                                                   \
16818 _(netmap_delete, "name <interface name>")                               \
16819 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16820 _(mpls_fib_encap_dump, "")                                              \
16821 _(mpls_fib_dump, "")                                                    \
16822 _(classify_table_ids, "")                                               \
16823 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16824 _(classify_table_info, "table_id <nn>")                                 \
16825 _(classify_session_dump, "table_id <nn>")                               \
16826 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
16827     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
16828     "[template_interval <nn>] [udp_checksum]")                          \
16829 _(ipfix_exporter_dump, "")                                              \
16830 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
16831 _(ipfix_classify_stream_dump, "")                                       \
16832 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
16833 _(ipfix_classify_table_dump, "")                                        \
16834 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [[dst <intfc> | dst_sw_if_index <id>] | disable]") \
16835 _(sw_interface_span_dump, "")                                           \
16836 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
16837 _(pg_create_interface, "if_id <nn>")                                    \
16838 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
16839 _(pg_enable_disable, "[stream <id>] disable")                           \
16840 _(ip_source_and_port_range_check_add_del,                               \
16841   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
16842 _(ip_source_and_port_range_check_interface_add_del,                     \
16843   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
16844   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
16845 _(ipsec_gre_add_del_tunnel,                                             \
16846   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
16847 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
16848 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
16849 _(l2_interface_pbb_tag_rewrite,                                         \
16850   "<intfc> | sw_if_index <nn> \n"                                       \
16851   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
16852   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
16853 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
16854 _(flow_classify_set_interface,                                          \
16855   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
16856 _(flow_classify_dump, "type [ip4|ip6]")                                 \
16857 _(ip_fib_dump, "")                                                      \
16858 _(ip6_fib_dump, "")
16859
16860 /* List of command functions, CLI names map directly to functions */
16861 #define foreach_cli_function                                    \
16862 _(comment, "usage: comment <ignore-rest-of-line>")              \
16863 _(dump_interface_table, "usage: dump_interface_table")          \
16864 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
16865 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
16866 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
16867 _(dump_stats_table, "usage: dump_stats_table")                  \
16868 _(dump_macro_table, "usage: dump_macro_table ")                 \
16869 _(dump_node_table, "usage: dump_node_table")                    \
16870 _(echo, "usage: echo <message>")                                \
16871 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
16872 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
16873 _(help, "usage: help")                                          \
16874 _(q, "usage: quit")                                             \
16875 _(quit, "usage: quit")                                          \
16876 _(search_node_table, "usage: search_node_table <name>...")      \
16877 _(set, "usage: set <variable-name> <value>")                    \
16878 _(script, "usage: script <file-name>")                          \
16879 _(unset, "usage: unset <variable-name>")
16880
16881 #define _(N,n)                                  \
16882     static void vl_api_##n##_t_handler_uni      \
16883     (vl_api_##n##_t * mp)                       \
16884     {                                           \
16885         vat_main_t * vam = &vat_main;           \
16886         if (vam->json_output) {                 \
16887             vl_api_##n##_t_handler_json(mp);    \
16888         } else {                                \
16889             vl_api_##n##_t_handler(mp);         \
16890         }                                       \
16891     }
16892 foreach_vpe_api_reply_msg;
16893 #undef _
16894
16895 void
16896 vat_api_hookup (vat_main_t * vam)
16897 {
16898 #define _(N,n)                                                  \
16899     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
16900                            vl_api_##n##_t_handler_uni,          \
16901                            vl_noop_handler,                     \
16902                            vl_api_##n##_t_endian,               \
16903                            vl_api_##n##_t_print,                \
16904                            sizeof(vl_api_##n##_t), 1);
16905   foreach_vpe_api_reply_msg;
16906 #undef _
16907
16908   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
16909
16910   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
16911
16912   vam->function_by_name = hash_create_string (0, sizeof (uword));
16913
16914   vam->help_by_name = hash_create_string (0, sizeof (uword));
16915
16916   /* API messages we can send */
16917 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
16918   foreach_vpe_api_msg;
16919 #undef _
16920
16921   /* Help strings */
16922 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16923   foreach_vpe_api_msg;
16924 #undef _
16925
16926   /* CLI functions */
16927 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
16928   foreach_cli_function;
16929 #undef _
16930
16931   /* Help strings */
16932 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16933   foreach_cli_function;
16934 #undef _
16935 }
16936
16937 #undef vl_api_version
16938 #define vl_api_version(n,v) static u32 vpe_api_version = v;
16939 #include <vpp-api/vpe.api.h>
16940 #undef vl_api_version
16941
16942 void
16943 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
16944 {
16945   /*
16946    * Send the main API signature in slot 0. This bit of code must
16947    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
16948    */
16949   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
16950 }
16951
16952 /*
16953  * fd.io coding-style-patch-verification: ON
16954  *
16955  * Local Variables:
16956  * eval: (c-set-style "gnu")
16957  * End:
16958  */