aa8752566792fd65e03fd007a40d1726e4e7880d
[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   /* Shut up coverity */
6496   memset (dst_mac_address, 0, sizeof (dst_mac_address));
6497
6498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6499     {
6500       if (unformat (i, "vrf %d", &inner_vrf_id))
6501         ;
6502       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6503                          &intfc_address, &tmp))
6504         intfc_address_length = tmp;
6505       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6506         tx_sw_if_index_set = 1;
6507       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6508         tx_sw_if_index_set = 1;
6509       else if (unformat (i, "dst %U", unformat_ethernet_address,
6510                          dst_mac_address))
6511         dst_set = 1;
6512       else if (unformat (i, "l2-only"))
6513         l2_only = 1;
6514       else if (unformat (i, "del"))
6515         is_add = 0;
6516       else
6517         {
6518           clib_warning ("parse error '%U'", format_unformat_error, i);
6519           return -99;
6520         }
6521     }
6522
6523   if (!dst_set)
6524     {
6525       errmsg ("dst (mac address) not set\n");
6526       return -99;
6527     }
6528   if (!tx_sw_if_index_set)
6529     {
6530       errmsg ("tx-intfc not set\n");
6531       return -99;
6532     }
6533
6534   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6535
6536   mp->vrf_id = ntohl (inner_vrf_id);
6537   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6538   mp->adj_address_length = intfc_address_length;
6539   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6540                sizeof (dst_mac_address));
6541   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6542   mp->l2_only = l2_only;
6543   mp->is_add = is_add;
6544
6545   S;
6546   W;
6547   /* NOTREACHED */
6548   return 0;
6549 }
6550
6551 static int
6552 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6553 {
6554   unformat_input_t *i = vam->input;
6555   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6556   f64 timeout;
6557   u32 inner_vrf_id = 0;
6558   u32 outer_vrf_id = 0;
6559   ip4_address_t adj_address;
6560   int adj_address_set = 0;
6561   ip4_address_t next_hop_address;
6562   int next_hop_address_set = 0;
6563   u32 tmp;
6564   u8 adj_address_length = 0;
6565   u8 l2_only = 0;
6566   u8 is_add = 1;
6567   u32 resolve_attempts = 5;
6568   u8 resolve_if_needed = 1;
6569
6570   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6571     {
6572       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6573         ;
6574       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6575         ;
6576       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6577                          &adj_address, &tmp))
6578         {
6579           adj_address_length = tmp;
6580           adj_address_set = 1;
6581         }
6582       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6583                          &next_hop_address))
6584         next_hop_address_set = 1;
6585       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6586         ;
6587       else if (unformat (i, "resolve-if-needed %d", &tmp))
6588         resolve_if_needed = tmp;
6589       else if (unformat (i, "l2-only"))
6590         l2_only = 1;
6591       else if (unformat (i, "del"))
6592         is_add = 0;
6593       else
6594         {
6595           clib_warning ("parse error '%U'", format_unformat_error, i);
6596           return -99;
6597         }
6598     }
6599
6600   if (!adj_address_set)
6601     {
6602       errmsg ("adjacency address/mask not set\n");
6603       return -99;
6604     }
6605   if (!next_hop_address_set)
6606     {
6607       errmsg ("ip4 next hop address (in outer fib) not set\n");
6608       return -99;
6609     }
6610
6611   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6612
6613   mp->inner_vrf_id = ntohl (inner_vrf_id);
6614   mp->outer_vrf_id = ntohl (outer_vrf_id);
6615   mp->resolve_attempts = ntohl (resolve_attempts);
6616   mp->resolve_if_needed = resolve_if_needed;
6617   mp->is_add = is_add;
6618   mp->l2_only = l2_only;
6619   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6620   mp->adj_address_length = adj_address_length;
6621   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6622                sizeof (next_hop_address));
6623
6624   S;
6625   W;
6626   /* NOTREACHED */
6627   return 0;
6628 }
6629
6630 static int
6631 api_sw_interface_set_unnumbered (vat_main_t * vam)
6632 {
6633   unformat_input_t *i = vam->input;
6634   vl_api_sw_interface_set_unnumbered_t *mp;
6635   f64 timeout;
6636   u32 sw_if_index;
6637   u32 unnum_sw_index = ~0;
6638   u8 is_add = 1;
6639   u8 sw_if_index_set = 0;
6640
6641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6642     {
6643       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6644         sw_if_index_set = 1;
6645       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6646         sw_if_index_set = 1;
6647       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6648         ;
6649       else if (unformat (i, "del"))
6650         is_add = 0;
6651       else
6652         {
6653           clib_warning ("parse error '%U'", format_unformat_error, i);
6654           return -99;
6655         }
6656     }
6657
6658   if (sw_if_index_set == 0)
6659     {
6660       errmsg ("missing interface name or sw_if_index\n");
6661       return -99;
6662     }
6663
6664   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6665
6666   mp->sw_if_index = ntohl (sw_if_index);
6667   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6668   mp->is_add = is_add;
6669
6670   S;
6671   W;
6672   /* NOTREACHED */
6673   return 0;
6674 }
6675
6676 static int
6677 api_ip_neighbor_add_del (vat_main_t * vam)
6678 {
6679   unformat_input_t *i = vam->input;
6680   vl_api_ip_neighbor_add_del_t *mp;
6681   f64 timeout;
6682   u32 sw_if_index;
6683   u8 sw_if_index_set = 0;
6684   u32 vrf_id = 0;
6685   u8 is_add = 1;
6686   u8 is_static = 0;
6687   u8 mac_address[6];
6688   u8 mac_set = 0;
6689   u8 v4_address_set = 0;
6690   u8 v6_address_set = 0;
6691   ip4_address_t v4address;
6692   ip6_address_t v6address;
6693
6694   memset (mac_address, 0, sizeof (mac_address));
6695
6696   /* Parse args required to build the message */
6697   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6698     {
6699       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6700         {
6701           mac_set = 1;
6702         }
6703       else if (unformat (i, "del"))
6704         is_add = 0;
6705       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6706         sw_if_index_set = 1;
6707       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6708         sw_if_index_set = 1;
6709       else if (unformat (i, "is_static"))
6710         is_static = 1;
6711       else if (unformat (i, "vrf %d", &vrf_id))
6712         ;
6713       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6714         v4_address_set = 1;
6715       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6716         v6_address_set = 1;
6717       else
6718         {
6719           clib_warning ("parse error '%U'", format_unformat_error, i);
6720           return -99;
6721         }
6722     }
6723
6724   if (sw_if_index_set == 0)
6725     {
6726       errmsg ("missing interface name or sw_if_index\n");
6727       return -99;
6728     }
6729   if (v4_address_set && v6_address_set)
6730     {
6731       errmsg ("both v4 and v6 addresses set\n");
6732       return -99;
6733     }
6734   if (!v4_address_set && !v6_address_set)
6735     {
6736       errmsg ("no address set\n");
6737       return -99;
6738     }
6739
6740   /* Construct the API message */
6741   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6742
6743   mp->sw_if_index = ntohl (sw_if_index);
6744   mp->is_add = is_add;
6745   mp->vrf_id = ntohl (vrf_id);
6746   mp->is_static = is_static;
6747   if (mac_set)
6748     clib_memcpy (mp->mac_address, mac_address, 6);
6749   if (v6_address_set)
6750     {
6751       mp->is_ipv6 = 1;
6752       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6753     }
6754   else
6755     {
6756       /* mp->is_ipv6 = 0; via memset in M macro above */
6757       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6758     }
6759
6760   /* send it... */
6761   S;
6762
6763   /* Wait for a reply, return good/bad news  */
6764   W;
6765
6766   /* NOTREACHED */
6767   return 0;
6768 }
6769
6770 static int
6771 api_reset_vrf (vat_main_t * vam)
6772 {
6773   unformat_input_t *i = vam->input;
6774   vl_api_reset_vrf_t *mp;
6775   f64 timeout;
6776   u32 vrf_id = 0;
6777   u8 is_ipv6 = 0;
6778   u8 vrf_id_set = 0;
6779
6780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6781     {
6782       if (unformat (i, "vrf %d", &vrf_id))
6783         vrf_id_set = 1;
6784       else if (unformat (i, "ipv6"))
6785         is_ipv6 = 1;
6786       else
6787         {
6788           clib_warning ("parse error '%U'", format_unformat_error, i);
6789           return -99;
6790         }
6791     }
6792
6793   if (vrf_id_set == 0)
6794     {
6795       errmsg ("missing vrf id\n");
6796       return -99;
6797     }
6798
6799   M (RESET_VRF, reset_vrf);
6800
6801   mp->vrf_id = ntohl (vrf_id);
6802   mp->is_ipv6 = is_ipv6;
6803
6804   S;
6805   W;
6806   /* NOTREACHED */
6807   return 0;
6808 }
6809
6810 static int
6811 api_create_vlan_subif (vat_main_t * vam)
6812 {
6813   unformat_input_t *i = vam->input;
6814   vl_api_create_vlan_subif_t *mp;
6815   f64 timeout;
6816   u32 sw_if_index;
6817   u8 sw_if_index_set = 0;
6818   u32 vlan_id;
6819   u8 vlan_id_set = 0;
6820
6821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6822     {
6823       if (unformat (i, "sw_if_index %d", &sw_if_index))
6824         sw_if_index_set = 1;
6825       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6826         sw_if_index_set = 1;
6827       else if (unformat (i, "vlan %d", &vlan_id))
6828         vlan_id_set = 1;
6829       else
6830         {
6831           clib_warning ("parse error '%U'", format_unformat_error, i);
6832           return -99;
6833         }
6834     }
6835
6836   if (sw_if_index_set == 0)
6837     {
6838       errmsg ("missing interface name or sw_if_index\n");
6839       return -99;
6840     }
6841
6842   if (vlan_id_set == 0)
6843     {
6844       errmsg ("missing vlan_id\n");
6845       return -99;
6846     }
6847   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6848
6849   mp->sw_if_index = ntohl (sw_if_index);
6850   mp->vlan_id = ntohl (vlan_id);
6851
6852   S;
6853   W;
6854   /* NOTREACHED */
6855   return 0;
6856 }
6857
6858 #define foreach_create_subif_bit                \
6859 _(no_tags)                                      \
6860 _(one_tag)                                      \
6861 _(two_tags)                                     \
6862 _(dot1ad)                                       \
6863 _(exact_match)                                  \
6864 _(default_sub)                                  \
6865 _(outer_vlan_id_any)                            \
6866 _(inner_vlan_id_any)
6867
6868 static int
6869 api_create_subif (vat_main_t * vam)
6870 {
6871   unformat_input_t *i = vam->input;
6872   vl_api_create_subif_t *mp;
6873   f64 timeout;
6874   u32 sw_if_index;
6875   u8 sw_if_index_set = 0;
6876   u32 sub_id;
6877   u8 sub_id_set = 0;
6878   u32 no_tags = 0;
6879   u32 one_tag = 0;
6880   u32 two_tags = 0;
6881   u32 dot1ad = 0;
6882   u32 exact_match = 0;
6883   u32 default_sub = 0;
6884   u32 outer_vlan_id_any = 0;
6885   u32 inner_vlan_id_any = 0;
6886   u32 tmp;
6887   u16 outer_vlan_id = 0;
6888   u16 inner_vlan_id = 0;
6889
6890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6891     {
6892       if (unformat (i, "sw_if_index %d", &sw_if_index))
6893         sw_if_index_set = 1;
6894       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6895         sw_if_index_set = 1;
6896       else if (unformat (i, "sub_id %d", &sub_id))
6897         sub_id_set = 1;
6898       else if (unformat (i, "outer_vlan_id %d", &tmp))
6899         outer_vlan_id = tmp;
6900       else if (unformat (i, "inner_vlan_id %d", &tmp))
6901         inner_vlan_id = tmp;
6902
6903 #define _(a) else if (unformat (i, #a)) a = 1 ;
6904       foreach_create_subif_bit
6905 #undef _
6906         else
6907         {
6908           clib_warning ("parse error '%U'", format_unformat_error, i);
6909           return -99;
6910         }
6911     }
6912
6913   if (sw_if_index_set == 0)
6914     {
6915       errmsg ("missing interface name or sw_if_index\n");
6916       return -99;
6917     }
6918
6919   if (sub_id_set == 0)
6920     {
6921       errmsg ("missing sub_id\n");
6922       return -99;
6923     }
6924   M (CREATE_SUBIF, create_subif);
6925
6926   mp->sw_if_index = ntohl (sw_if_index);
6927   mp->sub_id = ntohl (sub_id);
6928
6929 #define _(a) mp->a = a;
6930   foreach_create_subif_bit;
6931 #undef _
6932
6933   mp->outer_vlan_id = ntohs (outer_vlan_id);
6934   mp->inner_vlan_id = ntohs (inner_vlan_id);
6935
6936   S;
6937   W;
6938   /* NOTREACHED */
6939   return 0;
6940 }
6941
6942 static int
6943 api_oam_add_del (vat_main_t * vam)
6944 {
6945   unformat_input_t *i = vam->input;
6946   vl_api_oam_add_del_t *mp;
6947   f64 timeout;
6948   u32 vrf_id = 0;
6949   u8 is_add = 1;
6950   ip4_address_t src, dst;
6951   u8 src_set = 0;
6952   u8 dst_set = 0;
6953
6954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6955     {
6956       if (unformat (i, "vrf %d", &vrf_id))
6957         ;
6958       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6959         src_set = 1;
6960       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6961         dst_set = 1;
6962       else if (unformat (i, "del"))
6963         is_add = 0;
6964       else
6965         {
6966           clib_warning ("parse error '%U'", format_unformat_error, i);
6967           return -99;
6968         }
6969     }
6970
6971   if (src_set == 0)
6972     {
6973       errmsg ("missing src addr\n");
6974       return -99;
6975     }
6976
6977   if (dst_set == 0)
6978     {
6979       errmsg ("missing dst addr\n");
6980       return -99;
6981     }
6982
6983   M (OAM_ADD_DEL, oam_add_del);
6984
6985   mp->vrf_id = ntohl (vrf_id);
6986   mp->is_add = is_add;
6987   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6988   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6989
6990   S;
6991   W;
6992   /* NOTREACHED */
6993   return 0;
6994 }
6995
6996 static int
6997 api_reset_fib (vat_main_t * vam)
6998 {
6999   unformat_input_t *i = vam->input;
7000   vl_api_reset_fib_t *mp;
7001   f64 timeout;
7002   u32 vrf_id = 0;
7003   u8 is_ipv6 = 0;
7004   u8 vrf_id_set = 0;
7005
7006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7007     {
7008       if (unformat (i, "vrf %d", &vrf_id))
7009         vrf_id_set = 1;
7010       else if (unformat (i, "ipv6"))
7011         is_ipv6 = 1;
7012       else
7013         {
7014           clib_warning ("parse error '%U'", format_unformat_error, i);
7015           return -99;
7016         }
7017     }
7018
7019   if (vrf_id_set == 0)
7020     {
7021       errmsg ("missing vrf id\n");
7022       return -99;
7023     }
7024
7025   M (RESET_FIB, reset_fib);
7026
7027   mp->vrf_id = ntohl (vrf_id);
7028   mp->is_ipv6 = is_ipv6;
7029
7030   S;
7031   W;
7032   /* NOTREACHED */
7033   return 0;
7034 }
7035
7036 static int
7037 api_dhcp_proxy_config (vat_main_t * vam)
7038 {
7039   unformat_input_t *i = vam->input;
7040   vl_api_dhcp_proxy_config_t *mp;
7041   f64 timeout;
7042   u32 vrf_id = 0;
7043   u8 is_add = 1;
7044   u8 insert_cid = 1;
7045   u8 v4_address_set = 0;
7046   u8 v6_address_set = 0;
7047   ip4_address_t v4address;
7048   ip6_address_t v6address;
7049   u8 v4_src_address_set = 0;
7050   u8 v6_src_address_set = 0;
7051   ip4_address_t v4srcaddress;
7052   ip6_address_t v6srcaddress;
7053
7054   /* Parse args required to build the message */
7055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7056     {
7057       if (unformat (i, "del"))
7058         is_add = 0;
7059       else if (unformat (i, "vrf %d", &vrf_id))
7060         ;
7061       else if (unformat (i, "insert-cid %d", &insert_cid))
7062         ;
7063       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7064         v4_address_set = 1;
7065       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7066         v6_address_set = 1;
7067       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7068         v4_src_address_set = 1;
7069       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7070         v6_src_address_set = 1;
7071       else
7072         break;
7073     }
7074
7075   if (v4_address_set && v6_address_set)
7076     {
7077       errmsg ("both v4 and v6 server addresses set\n");
7078       return -99;
7079     }
7080   if (!v4_address_set && !v6_address_set)
7081     {
7082       errmsg ("no server addresses set\n");
7083       return -99;
7084     }
7085
7086   if (v4_src_address_set && v6_src_address_set)
7087     {
7088       errmsg ("both v4 and v6  src addresses set\n");
7089       return -99;
7090     }
7091   if (!v4_src_address_set && !v6_src_address_set)
7092     {
7093       errmsg ("no src addresses set\n");
7094       return -99;
7095     }
7096
7097   if (!(v4_src_address_set && v4_address_set) &&
7098       !(v6_src_address_set && v6_address_set))
7099     {
7100       errmsg ("no matching server and src addresses set\n");
7101       return -99;
7102     }
7103
7104   /* Construct the API message */
7105   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7106
7107   mp->insert_circuit_id = insert_cid;
7108   mp->is_add = is_add;
7109   mp->vrf_id = ntohl (vrf_id);
7110   if (v6_address_set)
7111     {
7112       mp->is_ipv6 = 1;
7113       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7114       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7115     }
7116   else
7117     {
7118       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7119       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7120     }
7121
7122   /* send it... */
7123   S;
7124
7125   /* Wait for a reply, return good/bad news  */
7126   W;
7127   /* NOTREACHED */
7128   return 0;
7129 }
7130
7131 static int
7132 api_dhcp_proxy_config_2 (vat_main_t * vam)
7133 {
7134   unformat_input_t *i = vam->input;
7135   vl_api_dhcp_proxy_config_2_t *mp;
7136   f64 timeout;
7137   u32 rx_vrf_id = 0;
7138   u32 server_vrf_id = 0;
7139   u8 is_add = 1;
7140   u8 insert_cid = 1;
7141   u8 v4_address_set = 0;
7142   u8 v6_address_set = 0;
7143   ip4_address_t v4address;
7144   ip6_address_t v6address;
7145   u8 v4_src_address_set = 0;
7146   u8 v6_src_address_set = 0;
7147   ip4_address_t v4srcaddress;
7148   ip6_address_t v6srcaddress;
7149
7150   /* Parse args required to build the message */
7151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7152     {
7153       if (unformat (i, "del"))
7154         is_add = 0;
7155       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7156         ;
7157       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7158         ;
7159       else if (unformat (i, "insert-cid %d", &insert_cid))
7160         ;
7161       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7162         v4_address_set = 1;
7163       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7164         v6_address_set = 1;
7165       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7166         v4_src_address_set = 1;
7167       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7168         v6_src_address_set = 1;
7169       else
7170         break;
7171     }
7172
7173   if (v4_address_set && v6_address_set)
7174     {
7175       errmsg ("both v4 and v6 server addresses set\n");
7176       return -99;
7177     }
7178   if (!v4_address_set && !v6_address_set)
7179     {
7180       errmsg ("no server addresses set\n");
7181       return -99;
7182     }
7183
7184   if (v4_src_address_set && v6_src_address_set)
7185     {
7186       errmsg ("both v4 and v6  src addresses set\n");
7187       return -99;
7188     }
7189   if (!v4_src_address_set && !v6_src_address_set)
7190     {
7191       errmsg ("no src addresses set\n");
7192       return -99;
7193     }
7194
7195   if (!(v4_src_address_set && v4_address_set) &&
7196       !(v6_src_address_set && v6_address_set))
7197     {
7198       errmsg ("no matching server and src addresses set\n");
7199       return -99;
7200     }
7201
7202   /* Construct the API message */
7203   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7204
7205   mp->insert_circuit_id = insert_cid;
7206   mp->is_add = is_add;
7207   mp->rx_vrf_id = ntohl (rx_vrf_id);
7208   mp->server_vrf_id = ntohl (server_vrf_id);
7209   if (v6_address_set)
7210     {
7211       mp->is_ipv6 = 1;
7212       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7213       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7214     }
7215   else
7216     {
7217       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7218       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7219     }
7220
7221   /* send it... */
7222   S;
7223
7224   /* Wait for a reply, return good/bad news  */
7225   W;
7226   /* NOTREACHED */
7227   return 0;
7228 }
7229
7230 static int
7231 api_dhcp_proxy_set_vss (vat_main_t * vam)
7232 {
7233   unformat_input_t *i = vam->input;
7234   vl_api_dhcp_proxy_set_vss_t *mp;
7235   f64 timeout;
7236   u8 is_ipv6 = 0;
7237   u8 is_add = 1;
7238   u32 tbl_id;
7239   u8 tbl_id_set = 0;
7240   u32 oui;
7241   u8 oui_set = 0;
7242   u32 fib_id;
7243   u8 fib_id_set = 0;
7244
7245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7246     {
7247       if (unformat (i, "tbl_id %d", &tbl_id))
7248         tbl_id_set = 1;
7249       if (unformat (i, "fib_id %d", &fib_id))
7250         fib_id_set = 1;
7251       if (unformat (i, "oui %d", &oui))
7252         oui_set = 1;
7253       else if (unformat (i, "ipv6"))
7254         is_ipv6 = 1;
7255       else if (unformat (i, "del"))
7256         is_add = 0;
7257       else
7258         {
7259           clib_warning ("parse error '%U'", format_unformat_error, i);
7260           return -99;
7261         }
7262     }
7263
7264   if (tbl_id_set == 0)
7265     {
7266       errmsg ("missing tbl id\n");
7267       return -99;
7268     }
7269
7270   if (fib_id_set == 0)
7271     {
7272       errmsg ("missing fib id\n");
7273       return -99;
7274     }
7275   if (oui_set == 0)
7276     {
7277       errmsg ("missing oui\n");
7278       return -99;
7279     }
7280
7281   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7282   mp->tbl_id = ntohl (tbl_id);
7283   mp->fib_id = ntohl (fib_id);
7284   mp->oui = ntohl (oui);
7285   mp->is_ipv6 = is_ipv6;
7286   mp->is_add = is_add;
7287
7288   S;
7289   W;
7290   /* NOTREACHED */
7291   return 0;
7292 }
7293
7294 static int
7295 api_dhcp_client_config (vat_main_t * vam)
7296 {
7297   unformat_input_t *i = vam->input;
7298   vl_api_dhcp_client_config_t *mp;
7299   f64 timeout;
7300   u32 sw_if_index;
7301   u8 sw_if_index_set = 0;
7302   u8 is_add = 1;
7303   u8 *hostname = 0;
7304   u8 disable_event = 0;
7305
7306   /* Parse args required to build the message */
7307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7308     {
7309       if (unformat (i, "del"))
7310         is_add = 0;
7311       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7312         sw_if_index_set = 1;
7313       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7314         sw_if_index_set = 1;
7315       else if (unformat (i, "hostname %s", &hostname))
7316         ;
7317       else if (unformat (i, "disable_event"))
7318         disable_event = 1;
7319       else
7320         break;
7321     }
7322
7323   if (sw_if_index_set == 0)
7324     {
7325       errmsg ("missing interface name or sw_if_index\n");
7326       return -99;
7327     }
7328
7329   if (vec_len (hostname) > 63)
7330     {
7331       errmsg ("hostname too long\n");
7332     }
7333   vec_add1 (hostname, 0);
7334
7335   /* Construct the API message */
7336   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7337
7338   mp->sw_if_index = ntohl (sw_if_index);
7339   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7340   vec_free (hostname);
7341   mp->is_add = is_add;
7342   mp->want_dhcp_event = disable_event ? 0 : 1;
7343   mp->pid = getpid ();
7344
7345   /* send it... */
7346   S;
7347
7348   /* Wait for a reply, return good/bad news  */
7349   W;
7350   /* NOTREACHED */
7351   return 0;
7352 }
7353
7354 static int
7355 api_set_ip_flow_hash (vat_main_t * vam)
7356 {
7357   unformat_input_t *i = vam->input;
7358   vl_api_set_ip_flow_hash_t *mp;
7359   f64 timeout;
7360   u32 vrf_id = 0;
7361   u8 is_ipv6 = 0;
7362   u8 vrf_id_set = 0;
7363   u8 src = 0;
7364   u8 dst = 0;
7365   u8 sport = 0;
7366   u8 dport = 0;
7367   u8 proto = 0;
7368   u8 reverse = 0;
7369
7370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7371     {
7372       if (unformat (i, "vrf %d", &vrf_id))
7373         vrf_id_set = 1;
7374       else if (unformat (i, "ipv6"))
7375         is_ipv6 = 1;
7376       else if (unformat (i, "src"))
7377         src = 1;
7378       else if (unformat (i, "dst"))
7379         dst = 1;
7380       else if (unformat (i, "sport"))
7381         sport = 1;
7382       else if (unformat (i, "dport"))
7383         dport = 1;
7384       else if (unformat (i, "proto"))
7385         proto = 1;
7386       else if (unformat (i, "reverse"))
7387         reverse = 1;
7388
7389       else
7390         {
7391           clib_warning ("parse error '%U'", format_unformat_error, i);
7392           return -99;
7393         }
7394     }
7395
7396   if (vrf_id_set == 0)
7397     {
7398       errmsg ("missing vrf id\n");
7399       return -99;
7400     }
7401
7402   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7403   mp->src = src;
7404   mp->dst = dst;
7405   mp->sport = sport;
7406   mp->dport = dport;
7407   mp->proto = proto;
7408   mp->reverse = reverse;
7409   mp->vrf_id = ntohl (vrf_id);
7410   mp->is_ipv6 = is_ipv6;
7411
7412   S;
7413   W;
7414   /* NOTREACHED */
7415   return 0;
7416 }
7417
7418 static int
7419 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7420 {
7421   unformat_input_t *i = vam->input;
7422   vl_api_sw_interface_ip6_enable_disable_t *mp;
7423   f64 timeout;
7424   u32 sw_if_index;
7425   u8 sw_if_index_set = 0;
7426   u8 enable = 0;
7427
7428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7429     {
7430       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7431         sw_if_index_set = 1;
7432       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7433         sw_if_index_set = 1;
7434       else if (unformat (i, "enable"))
7435         enable = 1;
7436       else if (unformat (i, "disable"))
7437         enable = 0;
7438       else
7439         {
7440           clib_warning ("parse error '%U'", format_unformat_error, i);
7441           return -99;
7442         }
7443     }
7444
7445   if (sw_if_index_set == 0)
7446     {
7447       errmsg ("missing interface name or sw_if_index\n");
7448       return -99;
7449     }
7450
7451   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7452
7453   mp->sw_if_index = ntohl (sw_if_index);
7454   mp->enable = enable;
7455
7456   S;
7457   W;
7458   /* NOTREACHED */
7459   return 0;
7460 }
7461
7462 static int
7463 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7464 {
7465   unformat_input_t *i = vam->input;
7466   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7467   f64 timeout;
7468   u32 sw_if_index;
7469   u8 sw_if_index_set = 0;
7470   u32 address_length = 0;
7471   u8 v6_address_set = 0;
7472   ip6_address_t v6address;
7473
7474   /* Parse args required to build the message */
7475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7476     {
7477       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7478         sw_if_index_set = 1;
7479       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7480         sw_if_index_set = 1;
7481       else if (unformat (i, "%U/%d",
7482                          unformat_ip6_address, &v6address, &address_length))
7483         v6_address_set = 1;
7484       else
7485         break;
7486     }
7487
7488   if (sw_if_index_set == 0)
7489     {
7490       errmsg ("missing interface name or sw_if_index\n");
7491       return -99;
7492     }
7493   if (!v6_address_set)
7494     {
7495       errmsg ("no address set\n");
7496       return -99;
7497     }
7498
7499   /* Construct the API message */
7500   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7501      sw_interface_ip6_set_link_local_address);
7502
7503   mp->sw_if_index = ntohl (sw_if_index);
7504   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7505   mp->address_length = address_length;
7506
7507   /* send it... */
7508   S;
7509
7510   /* Wait for a reply, return good/bad news  */
7511   W;
7512
7513   /* NOTREACHED */
7514   return 0;
7515 }
7516
7517
7518 static int
7519 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7520 {
7521   unformat_input_t *i = vam->input;
7522   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7523   f64 timeout;
7524   u32 sw_if_index;
7525   u8 sw_if_index_set = 0;
7526   u32 address_length = 0;
7527   u8 v6_address_set = 0;
7528   ip6_address_t v6address;
7529   u8 use_default = 0;
7530   u8 no_advertise = 0;
7531   u8 off_link = 0;
7532   u8 no_autoconfig = 0;
7533   u8 no_onlink = 0;
7534   u8 is_no = 0;
7535   u32 val_lifetime = 0;
7536   u32 pref_lifetime = 0;
7537
7538   /* Parse args required to build the message */
7539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7540     {
7541       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7542         sw_if_index_set = 1;
7543       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7544         sw_if_index_set = 1;
7545       else if (unformat (i, "%U/%d",
7546                          unformat_ip6_address, &v6address, &address_length))
7547         v6_address_set = 1;
7548       else if (unformat (i, "val_life %d", &val_lifetime))
7549         ;
7550       else if (unformat (i, "pref_life %d", &pref_lifetime))
7551         ;
7552       else if (unformat (i, "def"))
7553         use_default = 1;
7554       else if (unformat (i, "noadv"))
7555         no_advertise = 1;
7556       else if (unformat (i, "offl"))
7557         off_link = 1;
7558       else if (unformat (i, "noauto"))
7559         no_autoconfig = 1;
7560       else if (unformat (i, "nolink"))
7561         no_onlink = 1;
7562       else if (unformat (i, "isno"))
7563         is_no = 1;
7564       else
7565         {
7566           clib_warning ("parse error '%U'", format_unformat_error, i);
7567           return -99;
7568         }
7569     }
7570
7571   if (sw_if_index_set == 0)
7572     {
7573       errmsg ("missing interface name or sw_if_index\n");
7574       return -99;
7575     }
7576   if (!v6_address_set)
7577     {
7578       errmsg ("no address set\n");
7579       return -99;
7580     }
7581
7582   /* Construct the API message */
7583   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7584
7585   mp->sw_if_index = ntohl (sw_if_index);
7586   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7587   mp->address_length = address_length;
7588   mp->use_default = use_default;
7589   mp->no_advertise = no_advertise;
7590   mp->off_link = off_link;
7591   mp->no_autoconfig = no_autoconfig;
7592   mp->no_onlink = no_onlink;
7593   mp->is_no = is_no;
7594   mp->val_lifetime = ntohl (val_lifetime);
7595   mp->pref_lifetime = ntohl (pref_lifetime);
7596
7597   /* send it... */
7598   S;
7599
7600   /* Wait for a reply, return good/bad news  */
7601   W;
7602
7603   /* NOTREACHED */
7604   return 0;
7605 }
7606
7607 static int
7608 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7609 {
7610   unformat_input_t *i = vam->input;
7611   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7612   f64 timeout;
7613   u32 sw_if_index;
7614   u8 sw_if_index_set = 0;
7615   u8 suppress = 0;
7616   u8 managed = 0;
7617   u8 other = 0;
7618   u8 ll_option = 0;
7619   u8 send_unicast = 0;
7620   u8 cease = 0;
7621   u8 is_no = 0;
7622   u8 default_router = 0;
7623   u32 max_interval = 0;
7624   u32 min_interval = 0;
7625   u32 lifetime = 0;
7626   u32 initial_count = 0;
7627   u32 initial_interval = 0;
7628
7629
7630   /* Parse args required to build the message */
7631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7632     {
7633       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7634         sw_if_index_set = 1;
7635       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7636         sw_if_index_set = 1;
7637       else if (unformat (i, "maxint %d", &max_interval))
7638         ;
7639       else if (unformat (i, "minint %d", &min_interval))
7640         ;
7641       else if (unformat (i, "life %d", &lifetime))
7642         ;
7643       else if (unformat (i, "count %d", &initial_count))
7644         ;
7645       else if (unformat (i, "interval %d", &initial_interval))
7646         ;
7647       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7648         suppress = 1;
7649       else if (unformat (i, "managed"))
7650         managed = 1;
7651       else if (unformat (i, "other"))
7652         other = 1;
7653       else if (unformat (i, "ll"))
7654         ll_option = 1;
7655       else if (unformat (i, "send"))
7656         send_unicast = 1;
7657       else if (unformat (i, "cease"))
7658         cease = 1;
7659       else if (unformat (i, "isno"))
7660         is_no = 1;
7661       else if (unformat (i, "def"))
7662         default_router = 1;
7663       else
7664         {
7665           clib_warning ("parse error '%U'", format_unformat_error, i);
7666           return -99;
7667         }
7668     }
7669
7670   if (sw_if_index_set == 0)
7671     {
7672       errmsg ("missing interface name or sw_if_index\n");
7673       return -99;
7674     }
7675
7676   /* Construct the API message */
7677   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7678
7679   mp->sw_if_index = ntohl (sw_if_index);
7680   mp->max_interval = ntohl (max_interval);
7681   mp->min_interval = ntohl (min_interval);
7682   mp->lifetime = ntohl (lifetime);
7683   mp->initial_count = ntohl (initial_count);
7684   mp->initial_interval = ntohl (initial_interval);
7685   mp->suppress = suppress;
7686   mp->managed = managed;
7687   mp->other = other;
7688   mp->ll_option = ll_option;
7689   mp->send_unicast = send_unicast;
7690   mp->cease = cease;
7691   mp->is_no = is_no;
7692   mp->default_router = default_router;
7693
7694   /* send it... */
7695   S;
7696
7697   /* Wait for a reply, return good/bad news  */
7698   W;
7699
7700   /* NOTREACHED */
7701   return 0;
7702 }
7703
7704 static int
7705 api_set_arp_neighbor_limit (vat_main_t * vam)
7706 {
7707   unformat_input_t *i = vam->input;
7708   vl_api_set_arp_neighbor_limit_t *mp;
7709   f64 timeout;
7710   u32 arp_nbr_limit;
7711   u8 limit_set = 0;
7712   u8 is_ipv6 = 0;
7713
7714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7715     {
7716       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7717         limit_set = 1;
7718       else if (unformat (i, "ipv6"))
7719         is_ipv6 = 1;
7720       else
7721         {
7722           clib_warning ("parse error '%U'", format_unformat_error, i);
7723           return -99;
7724         }
7725     }
7726
7727   if (limit_set == 0)
7728     {
7729       errmsg ("missing limit value\n");
7730       return -99;
7731     }
7732
7733   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7734
7735   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7736   mp->is_ipv6 = is_ipv6;
7737
7738   S;
7739   W;
7740   /* NOTREACHED */
7741   return 0;
7742 }
7743
7744 static int
7745 api_l2_patch_add_del (vat_main_t * vam)
7746 {
7747   unformat_input_t *i = vam->input;
7748   vl_api_l2_patch_add_del_t *mp;
7749   f64 timeout;
7750   u32 rx_sw_if_index;
7751   u8 rx_sw_if_index_set = 0;
7752   u32 tx_sw_if_index;
7753   u8 tx_sw_if_index_set = 0;
7754   u8 is_add = 1;
7755
7756   /* Parse args required to build the message */
7757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7758     {
7759       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7760         rx_sw_if_index_set = 1;
7761       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7762         tx_sw_if_index_set = 1;
7763       else if (unformat (i, "rx"))
7764         {
7765           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7766             {
7767               if (unformat (i, "%U", unformat_sw_if_index, vam,
7768                             &rx_sw_if_index))
7769                 rx_sw_if_index_set = 1;
7770             }
7771           else
7772             break;
7773         }
7774       else if (unformat (i, "tx"))
7775         {
7776           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7777             {
7778               if (unformat (i, "%U", unformat_sw_if_index, vam,
7779                             &tx_sw_if_index))
7780                 tx_sw_if_index_set = 1;
7781             }
7782           else
7783             break;
7784         }
7785       else if (unformat (i, "del"))
7786         is_add = 0;
7787       else
7788         break;
7789     }
7790
7791   if (rx_sw_if_index_set == 0)
7792     {
7793       errmsg ("missing rx interface name or rx_sw_if_index\n");
7794       return -99;
7795     }
7796
7797   if (tx_sw_if_index_set == 0)
7798     {
7799       errmsg ("missing tx interface name or tx_sw_if_index\n");
7800       return -99;
7801     }
7802
7803   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7804
7805   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7806   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7807   mp->is_add = is_add;
7808
7809   S;
7810   W;
7811   /* NOTREACHED */
7812   return 0;
7813 }
7814
7815 static int
7816 api_ioam_enable (vat_main_t * vam)
7817 {
7818   unformat_input_t *input = vam->input;
7819   vl_api_ioam_enable_t *mp;
7820   f64 timeout;
7821   u32 id = 0;
7822   int has_trace_option = 0;
7823   int has_pot_option = 0;
7824   int has_seqno_option = 0;
7825   int has_analyse_option = 0;
7826
7827   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7828     {
7829       if (unformat (input, "trace"))
7830         has_trace_option = 1;
7831       else if (unformat (input, "pot"))
7832         has_pot_option = 1;
7833       else if (unformat (input, "seqno"))
7834         has_seqno_option = 1;
7835       else if (unformat (input, "analyse"))
7836         has_analyse_option = 1;
7837       else
7838         break;
7839     }
7840   M (IOAM_ENABLE, ioam_enable);
7841   mp->id = htons (id);
7842   mp->seqno = has_seqno_option;
7843   mp->analyse = has_analyse_option;
7844   mp->pot_enable = has_pot_option;
7845   mp->trace_enable = has_trace_option;
7846
7847   S;
7848   W;
7849
7850   return (0);
7851
7852 }
7853
7854
7855 static int
7856 api_ioam_disable (vat_main_t * vam)
7857 {
7858   vl_api_ioam_disable_t *mp;
7859   f64 timeout;
7860
7861   M (IOAM_DISABLE, ioam_disable);
7862   S;
7863   W;
7864   return 0;
7865 }
7866
7867 static int
7868 api_sr_tunnel_add_del (vat_main_t * vam)
7869 {
7870   unformat_input_t *i = vam->input;
7871   vl_api_sr_tunnel_add_del_t *mp;
7872   f64 timeout;
7873   int is_del = 0;
7874   int pl_index;
7875   ip6_address_t src_address;
7876   int src_address_set = 0;
7877   ip6_address_t dst_address;
7878   u32 dst_mask_width;
7879   int dst_address_set = 0;
7880   u16 flags = 0;
7881   u32 rx_table_id = 0;
7882   u32 tx_table_id = 0;
7883   ip6_address_t *segments = 0;
7884   ip6_address_t *this_seg;
7885   ip6_address_t *tags = 0;
7886   ip6_address_t *this_tag;
7887   ip6_address_t next_address, tag;
7888   u8 *name = 0;
7889   u8 *policy_name = 0;
7890
7891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7892     {
7893       if (unformat (i, "del"))
7894         is_del = 1;
7895       else if (unformat (i, "name %s", &name))
7896         ;
7897       else if (unformat (i, "policy %s", &policy_name))
7898         ;
7899       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7900         ;
7901       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7902         ;
7903       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7904         src_address_set = 1;
7905       else if (unformat (i, "dst %U/%d",
7906                          unformat_ip6_address, &dst_address, &dst_mask_width))
7907         dst_address_set = 1;
7908       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7909         {
7910           vec_add2 (segments, this_seg, 1);
7911           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7912                        sizeof (*this_seg));
7913         }
7914       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7915         {
7916           vec_add2 (tags, this_tag, 1);
7917           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7918         }
7919       else if (unformat (i, "clean"))
7920         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7921       else if (unformat (i, "protected"))
7922         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7923       else if (unformat (i, "InPE %d", &pl_index))
7924         {
7925           if (pl_index <= 0 || pl_index > 4)
7926             {
7927             pl_index_range_error:
7928               errmsg ("pl index %d out of range\n", pl_index);
7929               return -99;
7930             }
7931           flags |=
7932             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7933         }
7934       else if (unformat (i, "EgPE %d", &pl_index))
7935         {
7936           if (pl_index <= 0 || pl_index > 4)
7937             goto pl_index_range_error;
7938           flags |=
7939             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7940         }
7941       else if (unformat (i, "OrgSrc %d", &pl_index))
7942         {
7943           if (pl_index <= 0 || pl_index > 4)
7944             goto pl_index_range_error;
7945           flags |=
7946             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7947         }
7948       else
7949         break;
7950     }
7951
7952   if (!src_address_set)
7953     {
7954       errmsg ("src address required\n");
7955       return -99;
7956     }
7957
7958   if (!dst_address_set)
7959     {
7960       errmsg ("dst address required\n");
7961       return -99;
7962     }
7963
7964   if (!segments)
7965     {
7966       errmsg ("at least one sr segment required\n");
7967       return -99;
7968     }
7969
7970   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7971       vec_len (segments) * sizeof (ip6_address_t)
7972       + vec_len (tags) * sizeof (ip6_address_t));
7973
7974   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7975   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7976   mp->dst_mask_width = dst_mask_width;
7977   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7978   mp->n_segments = vec_len (segments);
7979   mp->n_tags = vec_len (tags);
7980   mp->is_add = is_del == 0;
7981   clib_memcpy (mp->segs_and_tags, segments,
7982                vec_len (segments) * sizeof (ip6_address_t));
7983   clib_memcpy (mp->segs_and_tags +
7984                vec_len (segments) * sizeof (ip6_address_t), tags,
7985                vec_len (tags) * sizeof (ip6_address_t));
7986
7987   mp->outer_vrf_id = ntohl (rx_table_id);
7988   mp->inner_vrf_id = ntohl (tx_table_id);
7989   memcpy (mp->name, name, vec_len (name));
7990   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7991
7992   vec_free (segments);
7993   vec_free (tags);
7994
7995   S;
7996   W;
7997   /* NOTREACHED */
7998 }
7999
8000 static int
8001 api_sr_policy_add_del (vat_main_t * vam)
8002 {
8003   unformat_input_t *input = vam->input;
8004   vl_api_sr_policy_add_del_t *mp;
8005   f64 timeout;
8006   int is_del = 0;
8007   u8 *name = 0;
8008   u8 *tunnel_name = 0;
8009   u8 **tunnel_names = 0;
8010
8011   int name_set = 0;
8012   int tunnel_set = 0;
8013   int j = 0;
8014   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8015   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8016
8017   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8018     {
8019       if (unformat (input, "del"))
8020         is_del = 1;
8021       else if (unformat (input, "name %s", &name))
8022         name_set = 1;
8023       else if (unformat (input, "tunnel %s", &tunnel_name))
8024         {
8025           if (tunnel_name)
8026             {
8027               vec_add1 (tunnel_names, tunnel_name);
8028               /* For serializer:
8029                  - length = #bytes to store in serial vector
8030                  - +1 = byte to store that length
8031                */
8032               tunnel_names_length += (vec_len (tunnel_name) + 1);
8033               tunnel_set = 1;
8034               tunnel_name = 0;
8035             }
8036         }
8037       else
8038         break;
8039     }
8040
8041   if (!name_set)
8042     {
8043       errmsg ("policy name required\n");
8044       return -99;
8045     }
8046
8047   if ((!tunnel_set) && (!is_del))
8048     {
8049       errmsg ("tunnel name required\n");
8050       return -99;
8051     }
8052
8053   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8054
8055
8056
8057   mp->is_add = !is_del;
8058
8059   memcpy (mp->name, name, vec_len (name));
8060   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8061   u8 *serial_orig = 0;
8062   vec_validate (serial_orig, tunnel_names_length);
8063   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8064   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8065
8066   for (j = 0; j < vec_len (tunnel_names); j++)
8067     {
8068       tun_name_len = vec_len (tunnel_names[j]);
8069       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8070       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8071       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8072       serial_orig += tun_name_len;      // Advance past the copy
8073     }
8074   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8075
8076   vec_free (tunnel_names);
8077   vec_free (tunnel_name);
8078
8079   S;
8080   W;
8081   /* NOTREACHED */
8082 }
8083
8084 static int
8085 api_sr_multicast_map_add_del (vat_main_t * vam)
8086 {
8087   unformat_input_t *input = vam->input;
8088   vl_api_sr_multicast_map_add_del_t *mp;
8089   f64 timeout;
8090   int is_del = 0;
8091   ip6_address_t multicast_address;
8092   u8 *policy_name = 0;
8093   int multicast_address_set = 0;
8094
8095   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8096     {
8097       if (unformat (input, "del"))
8098         is_del = 1;
8099       else
8100         if (unformat
8101             (input, "address %U", unformat_ip6_address, &multicast_address))
8102         multicast_address_set = 1;
8103       else if (unformat (input, "sr-policy %s", &policy_name))
8104         ;
8105       else
8106         break;
8107     }
8108
8109   if (!is_del && !policy_name)
8110     {
8111       errmsg ("sr-policy name required\n");
8112       return -99;
8113     }
8114
8115
8116   if (!multicast_address_set)
8117     {
8118       errmsg ("address required\n");
8119       return -99;
8120     }
8121
8122   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8123
8124   mp->is_add = !is_del;
8125   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8126   clib_memcpy (mp->multicast_address, &multicast_address,
8127                sizeof (mp->multicast_address));
8128
8129
8130   vec_free (policy_name);
8131
8132   S;
8133   W;
8134   /* NOTREACHED */
8135 }
8136
8137
8138 #define foreach_tcp_proto_field                 \
8139 _(src_port)                                     \
8140 _(dst_port)
8141
8142 #define foreach_udp_proto_field                 \
8143 _(src_port)                                     \
8144 _(dst_port)
8145
8146 #define foreach_ip4_proto_field                 \
8147 _(src_address)                                  \
8148 _(dst_address)                                  \
8149 _(tos)                                          \
8150 _(length)                                       \
8151 _(fragment_id)                                  \
8152 _(ttl)                                          \
8153 _(protocol)                                     \
8154 _(checksum)
8155
8156 uword
8157 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8158 {
8159   u8 **maskp = va_arg (*args, u8 **);
8160   u8 *mask = 0;
8161   u8 found_something = 0;
8162   tcp_header_t *tcp;
8163
8164 #define _(a) u8 a=0;
8165   foreach_tcp_proto_field;
8166 #undef _
8167
8168   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8169     {
8170       if (0);
8171 #define _(a) else if (unformat (input, #a)) a=1;
8172       foreach_tcp_proto_field
8173 #undef _
8174         else
8175         break;
8176     }
8177
8178 #define _(a) found_something += a;
8179   foreach_tcp_proto_field;
8180 #undef _
8181
8182   if (found_something == 0)
8183     return 0;
8184
8185   vec_validate (mask, sizeof (*tcp) - 1);
8186
8187   tcp = (tcp_header_t *) mask;
8188
8189 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8190   foreach_tcp_proto_field;
8191 #undef _
8192
8193   *maskp = mask;
8194   return 1;
8195 }
8196
8197 uword
8198 unformat_udp_mask (unformat_input_t * input, va_list * args)
8199 {
8200   u8 **maskp = va_arg (*args, u8 **);
8201   u8 *mask = 0;
8202   u8 found_something = 0;
8203   udp_header_t *udp;
8204
8205 #define _(a) u8 a=0;
8206   foreach_udp_proto_field;
8207 #undef _
8208
8209   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8210     {
8211       if (0);
8212 #define _(a) else if (unformat (input, #a)) a=1;
8213       foreach_udp_proto_field
8214 #undef _
8215         else
8216         break;
8217     }
8218
8219 #define _(a) found_something += a;
8220   foreach_udp_proto_field;
8221 #undef _
8222
8223   if (found_something == 0)
8224     return 0;
8225
8226   vec_validate (mask, sizeof (*udp) - 1);
8227
8228   udp = (udp_header_t *) mask;
8229
8230 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8231   foreach_udp_proto_field;
8232 #undef _
8233
8234   *maskp = mask;
8235   return 1;
8236 }
8237
8238 typedef struct
8239 {
8240   u16 src_port, dst_port;
8241 } tcpudp_header_t;
8242
8243 uword
8244 unformat_l4_mask (unformat_input_t * input, va_list * args)
8245 {
8246   u8 **maskp = va_arg (*args, u8 **);
8247   u16 src_port = 0, dst_port = 0;
8248   tcpudp_header_t *tcpudp;
8249
8250   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8251     {
8252       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8253         return 1;
8254       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8255         return 1;
8256       else if (unformat (input, "src_port"))
8257         src_port = 0xFFFF;
8258       else if (unformat (input, "dst_port"))
8259         dst_port = 0xFFFF;
8260       else
8261         return 0;
8262     }
8263
8264   if (!src_port && !dst_port)
8265     return 0;
8266
8267   u8 *mask = 0;
8268   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8269
8270   tcpudp = (tcpudp_header_t *) mask;
8271   tcpudp->src_port = src_port;
8272   tcpudp->dst_port = dst_port;
8273
8274   *maskp = mask;
8275
8276   return 1;
8277 }
8278
8279 uword
8280 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8281 {
8282   u8 **maskp = va_arg (*args, u8 **);
8283   u8 *mask = 0;
8284   u8 found_something = 0;
8285   ip4_header_t *ip;
8286
8287 #define _(a) u8 a=0;
8288   foreach_ip4_proto_field;
8289 #undef _
8290   u8 version = 0;
8291   u8 hdr_length = 0;
8292
8293
8294   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8295     {
8296       if (unformat (input, "version"))
8297         version = 1;
8298       else if (unformat (input, "hdr_length"))
8299         hdr_length = 1;
8300       else if (unformat (input, "src"))
8301         src_address = 1;
8302       else if (unformat (input, "dst"))
8303         dst_address = 1;
8304       else if (unformat (input, "proto"))
8305         protocol = 1;
8306
8307 #define _(a) else if (unformat (input, #a)) a=1;
8308       foreach_ip4_proto_field
8309 #undef _
8310         else
8311         break;
8312     }
8313
8314 #define _(a) found_something += a;
8315   foreach_ip4_proto_field;
8316 #undef _
8317
8318   if (found_something == 0)
8319     return 0;
8320
8321   vec_validate (mask, sizeof (*ip) - 1);
8322
8323   ip = (ip4_header_t *) mask;
8324
8325 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8326   foreach_ip4_proto_field;
8327 #undef _
8328
8329   ip->ip_version_and_header_length = 0;
8330
8331   if (version)
8332     ip->ip_version_and_header_length |= 0xF0;
8333
8334   if (hdr_length)
8335     ip->ip_version_and_header_length |= 0x0F;
8336
8337   *maskp = mask;
8338   return 1;
8339 }
8340
8341 #define foreach_ip6_proto_field                 \
8342 _(src_address)                                  \
8343 _(dst_address)                                  \
8344 _(payload_length)                               \
8345 _(hop_limit)                                    \
8346 _(protocol)
8347
8348 uword
8349 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8350 {
8351   u8 **maskp = va_arg (*args, u8 **);
8352   u8 *mask = 0;
8353   u8 found_something = 0;
8354   ip6_header_t *ip;
8355   u32 ip_version_traffic_class_and_flow_label;
8356
8357 #define _(a) u8 a=0;
8358   foreach_ip6_proto_field;
8359 #undef _
8360   u8 version = 0;
8361   u8 traffic_class = 0;
8362   u8 flow_label = 0;
8363
8364   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8365     {
8366       if (unformat (input, "version"))
8367         version = 1;
8368       else if (unformat (input, "traffic-class"))
8369         traffic_class = 1;
8370       else if (unformat (input, "flow-label"))
8371         flow_label = 1;
8372       else if (unformat (input, "src"))
8373         src_address = 1;
8374       else if (unformat (input, "dst"))
8375         dst_address = 1;
8376       else if (unformat (input, "proto"))
8377         protocol = 1;
8378
8379 #define _(a) else if (unformat (input, #a)) a=1;
8380       foreach_ip6_proto_field
8381 #undef _
8382         else
8383         break;
8384     }
8385
8386 #define _(a) found_something += a;
8387   foreach_ip6_proto_field;
8388 #undef _
8389
8390   if (found_something == 0)
8391     return 0;
8392
8393   vec_validate (mask, sizeof (*ip) - 1);
8394
8395   ip = (ip6_header_t *) mask;
8396
8397 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8398   foreach_ip6_proto_field;
8399 #undef _
8400
8401   ip_version_traffic_class_and_flow_label = 0;
8402
8403   if (version)
8404     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8405
8406   if (traffic_class)
8407     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8408
8409   if (flow_label)
8410     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8411
8412   ip->ip_version_traffic_class_and_flow_label =
8413     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8414
8415   *maskp = mask;
8416   return 1;
8417 }
8418
8419 uword
8420 unformat_l3_mask (unformat_input_t * input, va_list * args)
8421 {
8422   u8 **maskp = va_arg (*args, u8 **);
8423
8424   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8425     {
8426       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8427         return 1;
8428       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8429         return 1;
8430       else
8431         break;
8432     }
8433   return 0;
8434 }
8435
8436 uword
8437 unformat_l2_mask (unformat_input_t * input, va_list * args)
8438 {
8439   u8 **maskp = va_arg (*args, u8 **);
8440   u8 *mask = 0;
8441   u8 src = 0;
8442   u8 dst = 0;
8443   u8 proto = 0;
8444   u8 tag1 = 0;
8445   u8 tag2 = 0;
8446   u8 ignore_tag1 = 0;
8447   u8 ignore_tag2 = 0;
8448   u8 cos1 = 0;
8449   u8 cos2 = 0;
8450   u8 dot1q = 0;
8451   u8 dot1ad = 0;
8452   int len = 14;
8453
8454   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8455     {
8456       if (unformat (input, "src"))
8457         src = 1;
8458       else if (unformat (input, "dst"))
8459         dst = 1;
8460       else if (unformat (input, "proto"))
8461         proto = 1;
8462       else if (unformat (input, "tag1"))
8463         tag1 = 1;
8464       else if (unformat (input, "tag2"))
8465         tag2 = 1;
8466       else if (unformat (input, "ignore-tag1"))
8467         ignore_tag1 = 1;
8468       else if (unformat (input, "ignore-tag2"))
8469         ignore_tag2 = 1;
8470       else if (unformat (input, "cos1"))
8471         cos1 = 1;
8472       else if (unformat (input, "cos2"))
8473         cos2 = 1;
8474       else if (unformat (input, "dot1q"))
8475         dot1q = 1;
8476       else if (unformat (input, "dot1ad"))
8477         dot1ad = 1;
8478       else
8479         break;
8480     }
8481   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8482        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8483     return 0;
8484
8485   if (tag1 || ignore_tag1 || cos1 || dot1q)
8486     len = 18;
8487   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8488     len = 22;
8489
8490   vec_validate (mask, len - 1);
8491
8492   if (dst)
8493     memset (mask, 0xff, 6);
8494
8495   if (src)
8496     memset (mask + 6, 0xff, 6);
8497
8498   if (tag2 || dot1ad)
8499     {
8500       /* inner vlan tag */
8501       if (tag2)
8502         {
8503           mask[19] = 0xff;
8504           mask[18] = 0x0f;
8505         }
8506       if (cos2)
8507         mask[18] |= 0xe0;
8508       if (proto)
8509         mask[21] = mask[20] = 0xff;
8510       if (tag1)
8511         {
8512           mask[15] = 0xff;
8513           mask[14] = 0x0f;
8514         }
8515       if (cos1)
8516         mask[14] |= 0xe0;
8517       *maskp = mask;
8518       return 1;
8519     }
8520   if (tag1 | dot1q)
8521     {
8522       if (tag1)
8523         {
8524           mask[15] = 0xff;
8525           mask[14] = 0x0f;
8526         }
8527       if (cos1)
8528         mask[14] |= 0xe0;
8529       if (proto)
8530         mask[16] = mask[17] = 0xff;
8531
8532       *maskp = mask;
8533       return 1;
8534     }
8535   if (cos2)
8536     mask[18] |= 0xe0;
8537   if (cos1)
8538     mask[14] |= 0xe0;
8539   if (proto)
8540     mask[12] = mask[13] = 0xff;
8541
8542   *maskp = mask;
8543   return 1;
8544 }
8545
8546 uword
8547 unformat_classify_mask (unformat_input_t * input, va_list * args)
8548 {
8549   u8 **maskp = va_arg (*args, u8 **);
8550   u32 *skipp = va_arg (*args, u32 *);
8551   u32 *matchp = va_arg (*args, u32 *);
8552   u32 match;
8553   u8 *mask = 0;
8554   u8 *l2 = 0;
8555   u8 *l3 = 0;
8556   u8 *l4 = 0;
8557   int i;
8558
8559   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8560     {
8561       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8562         ;
8563       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8564         ;
8565       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8566         ;
8567       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8568         ;
8569       else
8570         break;
8571     }
8572
8573   if (l4 && !l3)
8574     {
8575       vec_free (mask);
8576       vec_free (l2);
8577       vec_free (l4);
8578       return 0;
8579     }
8580
8581   if (mask || l2 || l3 || l4)
8582     {
8583       if (l2 || l3 || l4)
8584         {
8585           /* "With a free Ethernet header in every package" */
8586           if (l2 == 0)
8587             vec_validate (l2, 13);
8588           mask = l2;
8589           if (vec_len (l3))
8590             {
8591               vec_append (mask, l3);
8592               vec_free (l3);
8593             }
8594           if (vec_len (l4))
8595             {
8596               vec_append (mask, l4);
8597               vec_free (l4);
8598             }
8599         }
8600
8601       /* Scan forward looking for the first significant mask octet */
8602       for (i = 0; i < vec_len (mask); i++)
8603         if (mask[i])
8604           break;
8605
8606       /* compute (skip, match) params */
8607       *skipp = i / sizeof (u32x4);
8608       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8609
8610       /* Pad mask to an even multiple of the vector size */
8611       while (vec_len (mask) % sizeof (u32x4))
8612         vec_add1 (mask, 0);
8613
8614       match = vec_len (mask) / sizeof (u32x4);
8615
8616       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8617         {
8618           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8619           if (*tmp || *(tmp + 1))
8620             break;
8621           match--;
8622         }
8623       if (match == 0)
8624         clib_warning ("BUG: match 0");
8625
8626       _vec_len (mask) = match * sizeof (u32x4);
8627
8628       *matchp = match;
8629       *maskp = mask;
8630
8631       return 1;
8632     }
8633
8634   return 0;
8635 }
8636
8637 #define foreach_l2_next                         \
8638 _(drop, DROP)                                   \
8639 _(ethernet, ETHERNET_INPUT)                     \
8640 _(ip4, IP4_INPUT)                               \
8641 _(ip6, IP6_INPUT)
8642
8643 uword
8644 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8645 {
8646   u32 *miss_next_indexp = va_arg (*args, u32 *);
8647   u32 next_index = 0;
8648   u32 tmp;
8649
8650 #define _(n,N) \
8651   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8652   foreach_l2_next;
8653 #undef _
8654
8655   if (unformat (input, "%d", &tmp))
8656     {
8657       next_index = tmp;
8658       goto out;
8659     }
8660
8661   return 0;
8662
8663 out:
8664   *miss_next_indexp = next_index;
8665   return 1;
8666 }
8667
8668 #define foreach_ip_next                         \
8669 _(drop, DROP)                                   \
8670 _(local, LOCAL)                                 \
8671 _(rewrite, REWRITE)
8672
8673 uword
8674 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8675 {
8676   u32 *miss_next_indexp = va_arg (*args, u32 *);
8677   u32 next_index = 0;
8678   u32 tmp;
8679
8680 #define _(n,N) \
8681   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8682   foreach_ip_next;
8683 #undef _
8684
8685   if (unformat (input, "%d", &tmp))
8686     {
8687       next_index = tmp;
8688       goto out;
8689     }
8690
8691   return 0;
8692
8693 out:
8694   *miss_next_indexp = next_index;
8695   return 1;
8696 }
8697
8698 #define foreach_acl_next                        \
8699 _(deny, DENY)
8700
8701 uword
8702 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8703 {
8704   u32 *miss_next_indexp = va_arg (*args, u32 *);
8705   u32 next_index = 0;
8706   u32 tmp;
8707
8708 #define _(n,N) \
8709   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8710   foreach_acl_next;
8711 #undef _
8712
8713   if (unformat (input, "permit"))
8714     {
8715       next_index = ~0;
8716       goto out;
8717     }
8718   else if (unformat (input, "%d", &tmp))
8719     {
8720       next_index = tmp;
8721       goto out;
8722     }
8723
8724   return 0;
8725
8726 out:
8727   *miss_next_indexp = next_index;
8728   return 1;
8729 }
8730
8731 uword
8732 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8733 {
8734   u32 *r = va_arg (*args, u32 *);
8735
8736   if (unformat (input, "conform-color"))
8737     *r = POLICE_CONFORM;
8738   else if (unformat (input, "exceed-color"))
8739     *r = POLICE_EXCEED;
8740   else
8741     return 0;
8742
8743   return 1;
8744 }
8745
8746 static int
8747 api_classify_add_del_table (vat_main_t * vam)
8748 {
8749   unformat_input_t *i = vam->input;
8750   vl_api_classify_add_del_table_t *mp;
8751
8752   u32 nbuckets = 2;
8753   u32 skip = ~0;
8754   u32 match = ~0;
8755   int is_add = 1;
8756   u32 table_index = ~0;
8757   u32 next_table_index = ~0;
8758   u32 miss_next_index = ~0;
8759   u32 memory_size = 32 << 20;
8760   u8 *mask = 0;
8761   f64 timeout;
8762   u32 current_data_flag = 0;
8763   int current_data_offset = 0;
8764
8765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8766     {
8767       if (unformat (i, "del"))
8768         is_add = 0;
8769       else if (unformat (i, "buckets %d", &nbuckets))
8770         ;
8771       else if (unformat (i, "memory_size %d", &memory_size))
8772         ;
8773       else if (unformat (i, "skip %d", &skip))
8774         ;
8775       else if (unformat (i, "match %d", &match))
8776         ;
8777       else if (unformat (i, "table %d", &table_index))
8778         ;
8779       else if (unformat (i, "mask %U", unformat_classify_mask,
8780                          &mask, &skip, &match))
8781         ;
8782       else if (unformat (i, "next-table %d", &next_table_index))
8783         ;
8784       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8785                          &miss_next_index))
8786         ;
8787       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8788                          &miss_next_index))
8789         ;
8790       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8791                          &miss_next_index))
8792         ;
8793       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8794         ;
8795       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8796         ;
8797       else
8798         break;
8799     }
8800
8801   if (is_add && mask == 0)
8802     {
8803       errmsg ("Mask required\n");
8804       return -99;
8805     }
8806
8807   if (is_add && skip == ~0)
8808     {
8809       errmsg ("skip count required\n");
8810       return -99;
8811     }
8812
8813   if (is_add && match == ~0)
8814     {
8815       errmsg ("match count required\n");
8816       return -99;
8817     }
8818
8819   if (!is_add && table_index == ~0)
8820     {
8821       errmsg ("table index required for delete\n");
8822       return -99;
8823     }
8824
8825   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8826
8827   mp->is_add = is_add;
8828   mp->table_index = ntohl (table_index);
8829   mp->nbuckets = ntohl (nbuckets);
8830   mp->memory_size = ntohl (memory_size);
8831   mp->skip_n_vectors = ntohl (skip);
8832   mp->match_n_vectors = ntohl (match);
8833   mp->next_table_index = ntohl (next_table_index);
8834   mp->miss_next_index = ntohl (miss_next_index);
8835   mp->current_data_flag = ntohl (current_data_flag);
8836   mp->current_data_offset = ntohl (current_data_offset);
8837   clib_memcpy (mp->mask, mask, vec_len (mask));
8838
8839   vec_free (mask);
8840
8841   S;
8842   W;
8843   /* NOTREACHED */
8844 }
8845
8846 uword
8847 unformat_l4_match (unformat_input_t * input, va_list * args)
8848 {
8849   u8 **matchp = va_arg (*args, u8 **);
8850
8851   u8 *proto_header = 0;
8852   int src_port = 0;
8853   int dst_port = 0;
8854
8855   tcpudp_header_t h;
8856
8857   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8858     {
8859       if (unformat (input, "src_port %d", &src_port))
8860         ;
8861       else if (unformat (input, "dst_port %d", &dst_port))
8862         ;
8863       else
8864         return 0;
8865     }
8866
8867   h.src_port = clib_host_to_net_u16 (src_port);
8868   h.dst_port = clib_host_to_net_u16 (dst_port);
8869   vec_validate (proto_header, sizeof (h) - 1);
8870   memcpy (proto_header, &h, sizeof (h));
8871
8872   *matchp = proto_header;
8873
8874   return 1;
8875 }
8876
8877 uword
8878 unformat_ip4_match (unformat_input_t * input, va_list * args)
8879 {
8880   u8 **matchp = va_arg (*args, u8 **);
8881   u8 *match = 0;
8882   ip4_header_t *ip;
8883   int version = 0;
8884   u32 version_val;
8885   int hdr_length = 0;
8886   u32 hdr_length_val;
8887   int src = 0, dst = 0;
8888   ip4_address_t src_val, dst_val;
8889   int proto = 0;
8890   u32 proto_val;
8891   int tos = 0;
8892   u32 tos_val;
8893   int length = 0;
8894   u32 length_val;
8895   int fragment_id = 0;
8896   u32 fragment_id_val;
8897   int ttl = 0;
8898   int ttl_val;
8899   int checksum = 0;
8900   u32 checksum_val;
8901
8902   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8903     {
8904       if (unformat (input, "version %d", &version_val))
8905         version = 1;
8906       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8907         hdr_length = 1;
8908       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8909         src = 1;
8910       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8911         dst = 1;
8912       else if (unformat (input, "proto %d", &proto_val))
8913         proto = 1;
8914       else if (unformat (input, "tos %d", &tos_val))
8915         tos = 1;
8916       else if (unformat (input, "length %d", &length_val))
8917         length = 1;
8918       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8919         fragment_id = 1;
8920       else if (unformat (input, "ttl %d", &ttl_val))
8921         ttl = 1;
8922       else if (unformat (input, "checksum %d", &checksum_val))
8923         checksum = 1;
8924       else
8925         break;
8926     }
8927
8928   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8929       + ttl + checksum == 0)
8930     return 0;
8931
8932   /*
8933    * Aligned because we use the real comparison functions
8934    */
8935   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8936
8937   ip = (ip4_header_t *) match;
8938
8939   /* These are realistically matched in practice */
8940   if (src)
8941     ip->src_address.as_u32 = src_val.as_u32;
8942
8943   if (dst)
8944     ip->dst_address.as_u32 = dst_val.as_u32;
8945
8946   if (proto)
8947     ip->protocol = proto_val;
8948
8949
8950   /* These are not, but they're included for completeness */
8951   if (version)
8952     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8953
8954   if (hdr_length)
8955     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8956
8957   if (tos)
8958     ip->tos = tos_val;
8959
8960   if (length)
8961     ip->length = clib_host_to_net_u16 (length_val);
8962
8963   if (ttl)
8964     ip->ttl = ttl_val;
8965
8966   if (checksum)
8967     ip->checksum = clib_host_to_net_u16 (checksum_val);
8968
8969   *matchp = match;
8970   return 1;
8971 }
8972
8973 uword
8974 unformat_ip6_match (unformat_input_t * input, va_list * args)
8975 {
8976   u8 **matchp = va_arg (*args, u8 **);
8977   u8 *match = 0;
8978   ip6_header_t *ip;
8979   int version = 0;
8980   u32 version_val;
8981   u8 traffic_class = 0;
8982   u32 traffic_class_val = 0;
8983   u8 flow_label = 0;
8984   u8 flow_label_val;
8985   int src = 0, dst = 0;
8986   ip6_address_t src_val, dst_val;
8987   int proto = 0;
8988   u32 proto_val;
8989   int payload_length = 0;
8990   u32 payload_length_val;
8991   int hop_limit = 0;
8992   int hop_limit_val;
8993   u32 ip_version_traffic_class_and_flow_label;
8994
8995   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8996     {
8997       if (unformat (input, "version %d", &version_val))
8998         version = 1;
8999       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9000         traffic_class = 1;
9001       else if (unformat (input, "flow_label %d", &flow_label_val))
9002         flow_label = 1;
9003       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9004         src = 1;
9005       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9006         dst = 1;
9007       else if (unformat (input, "proto %d", &proto_val))
9008         proto = 1;
9009       else if (unformat (input, "payload_length %d", &payload_length_val))
9010         payload_length = 1;
9011       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9012         hop_limit = 1;
9013       else
9014         break;
9015     }
9016
9017   if (version + traffic_class + flow_label + src + dst + proto +
9018       payload_length + hop_limit == 0)
9019     return 0;
9020
9021   /*
9022    * Aligned because we use the real comparison functions
9023    */
9024   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9025
9026   ip = (ip6_header_t *) match;
9027
9028   if (src)
9029     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9030
9031   if (dst)
9032     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9033
9034   if (proto)
9035     ip->protocol = proto_val;
9036
9037   ip_version_traffic_class_and_flow_label = 0;
9038
9039   if (version)
9040     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9041
9042   if (traffic_class)
9043     ip_version_traffic_class_and_flow_label |=
9044       (traffic_class_val & 0xFF) << 20;
9045
9046   if (flow_label)
9047     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9048
9049   ip->ip_version_traffic_class_and_flow_label =
9050     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9051
9052   if (payload_length)
9053     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9054
9055   if (hop_limit)
9056     ip->hop_limit = hop_limit_val;
9057
9058   *matchp = match;
9059   return 1;
9060 }
9061
9062 uword
9063 unformat_l3_match (unformat_input_t * input, va_list * args)
9064 {
9065   u8 **matchp = va_arg (*args, u8 **);
9066
9067   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9068     {
9069       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9070         return 1;
9071       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9072         return 1;
9073       else
9074         break;
9075     }
9076   return 0;
9077 }
9078
9079 uword
9080 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9081 {
9082   u8 *tagp = va_arg (*args, u8 *);
9083   u32 tag;
9084
9085   if (unformat (input, "%d", &tag))
9086     {
9087       tagp[0] = (tag >> 8) & 0x0F;
9088       tagp[1] = tag & 0xFF;
9089       return 1;
9090     }
9091
9092   return 0;
9093 }
9094
9095 uword
9096 unformat_l2_match (unformat_input_t * input, va_list * args)
9097 {
9098   u8 **matchp = va_arg (*args, u8 **);
9099   u8 *match = 0;
9100   u8 src = 0;
9101   u8 src_val[6];
9102   u8 dst = 0;
9103   u8 dst_val[6];
9104   u8 proto = 0;
9105   u16 proto_val;
9106   u8 tag1 = 0;
9107   u8 tag1_val[2];
9108   u8 tag2 = 0;
9109   u8 tag2_val[2];
9110   int len = 14;
9111   u8 ignore_tag1 = 0;
9112   u8 ignore_tag2 = 0;
9113   u8 cos1 = 0;
9114   u8 cos2 = 0;
9115   u32 cos1_val = 0;
9116   u32 cos2_val = 0;
9117
9118   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9119     {
9120       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9121         src = 1;
9122       else
9123         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9124         dst = 1;
9125       else if (unformat (input, "proto %U",
9126                          unformat_ethernet_type_host_byte_order, &proto_val))
9127         proto = 1;
9128       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9129         tag1 = 1;
9130       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9131         tag2 = 1;
9132       else if (unformat (input, "ignore-tag1"))
9133         ignore_tag1 = 1;
9134       else if (unformat (input, "ignore-tag2"))
9135         ignore_tag2 = 1;
9136       else if (unformat (input, "cos1 %d", &cos1_val))
9137         cos1 = 1;
9138       else if (unformat (input, "cos2 %d", &cos2_val))
9139         cos2 = 1;
9140       else
9141         break;
9142     }
9143   if ((src + dst + proto + tag1 + tag2 +
9144        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9145     return 0;
9146
9147   if (tag1 || ignore_tag1 || cos1)
9148     len = 18;
9149   if (tag2 || ignore_tag2 || cos2)
9150     len = 22;
9151
9152   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9153
9154   if (dst)
9155     clib_memcpy (match, dst_val, 6);
9156
9157   if (src)
9158     clib_memcpy (match + 6, src_val, 6);
9159
9160   if (tag2)
9161     {
9162       /* inner vlan tag */
9163       match[19] = tag2_val[1];
9164       match[18] = tag2_val[0];
9165       if (cos2)
9166         match[18] |= (cos2_val & 0x7) << 5;
9167       if (proto)
9168         {
9169           match[21] = proto_val & 0xff;
9170           match[20] = proto_val >> 8;
9171         }
9172       if (tag1)
9173         {
9174           match[15] = tag1_val[1];
9175           match[14] = tag1_val[0];
9176         }
9177       if (cos1)
9178         match[14] |= (cos1_val & 0x7) << 5;
9179       *matchp = match;
9180       return 1;
9181     }
9182   if (tag1)
9183     {
9184       match[15] = tag1_val[1];
9185       match[14] = tag1_val[0];
9186       if (proto)
9187         {
9188           match[17] = proto_val & 0xff;
9189           match[16] = proto_val >> 8;
9190         }
9191       if (cos1)
9192         match[14] |= (cos1_val & 0x7) << 5;
9193
9194       *matchp = match;
9195       return 1;
9196     }
9197   if (cos2)
9198     match[18] |= (cos2_val & 0x7) << 5;
9199   if (cos1)
9200     match[14] |= (cos1_val & 0x7) << 5;
9201   if (proto)
9202     {
9203       match[13] = proto_val & 0xff;
9204       match[12] = proto_val >> 8;
9205     }
9206
9207   *matchp = match;
9208   return 1;
9209 }
9210
9211
9212 uword
9213 unformat_classify_match (unformat_input_t * input, va_list * args)
9214 {
9215   u8 **matchp = va_arg (*args, u8 **);
9216   u32 skip_n_vectors = va_arg (*args, u32);
9217   u32 match_n_vectors = va_arg (*args, u32);
9218
9219   u8 *match = 0;
9220   u8 *l2 = 0;
9221   u8 *l3 = 0;
9222   u8 *l4 = 0;
9223
9224   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9225     {
9226       if (unformat (input, "hex %U", unformat_hex_string, &match))
9227         ;
9228       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9229         ;
9230       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9231         ;
9232       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9233         ;
9234       else
9235         break;
9236     }
9237
9238   if (l4 && !l3)
9239     {
9240       vec_free (match);
9241       vec_free (l2);
9242       vec_free (l4);
9243       return 0;
9244     }
9245
9246   if (match || l2 || l3 || l4)
9247     {
9248       if (l2 || l3 || l4)
9249         {
9250           /* "Win a free Ethernet header in every packet" */
9251           if (l2 == 0)
9252             vec_validate_aligned (l2, 13, sizeof (u32x4));
9253           match = l2;
9254           if (vec_len (l3))
9255             {
9256               vec_append_aligned (match, l3, sizeof (u32x4));
9257               vec_free (l3);
9258             }
9259           if (vec_len (l4))
9260             {
9261               vec_append_aligned (match, l4, sizeof (u32x4));
9262               vec_free (l4);
9263             }
9264         }
9265
9266       /* Make sure the vector is big enough even if key is all 0's */
9267       vec_validate_aligned
9268         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9269          sizeof (u32x4));
9270
9271       /* Set size, include skipped vectors */
9272       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9273
9274       *matchp = match;
9275
9276       return 1;
9277     }
9278
9279   return 0;
9280 }
9281
9282 static int
9283 api_classify_add_del_session (vat_main_t * vam)
9284 {
9285   unformat_input_t *i = vam->input;
9286   vl_api_classify_add_del_session_t *mp;
9287   int is_add = 1;
9288   u32 table_index = ~0;
9289   u32 hit_next_index = ~0;
9290   u32 opaque_index = ~0;
9291   u8 *match = 0;
9292   i32 advance = 0;
9293   f64 timeout;
9294   u32 skip_n_vectors = 0;
9295   u32 match_n_vectors = 0;
9296   u32 action = 0;
9297   u32 metadata = 0;
9298
9299   /*
9300    * Warning: you have to supply skip_n and match_n
9301    * because the API client cant simply look at the classify
9302    * table object.
9303    */
9304
9305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9306     {
9307       if (unformat (i, "del"))
9308         is_add = 0;
9309       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9310                          &hit_next_index))
9311         ;
9312       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9313                          &hit_next_index))
9314         ;
9315       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9316                          &hit_next_index))
9317         ;
9318       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9319         ;
9320       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9321         ;
9322       else if (unformat (i, "opaque-index %d", &opaque_index))
9323         ;
9324       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9325         ;
9326       else if (unformat (i, "match_n %d", &match_n_vectors))
9327         ;
9328       else if (unformat (i, "match %U", unformat_classify_match,
9329                          &match, skip_n_vectors, match_n_vectors))
9330         ;
9331       else if (unformat (i, "advance %d", &advance))
9332         ;
9333       else if (unformat (i, "table-index %d", &table_index))
9334         ;
9335       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9336         action = 1;
9337       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9338         action = 2;
9339       else if (unformat (i, "action %d", &action))
9340         ;
9341       else if (unformat (i, "metadata %d", &metadata))
9342         ;
9343       else
9344         break;
9345     }
9346
9347   if (table_index == ~0)
9348     {
9349       errmsg ("Table index required\n");
9350       return -99;
9351     }
9352
9353   if (is_add && match == 0)
9354     {
9355       errmsg ("Match value required\n");
9356       return -99;
9357     }
9358
9359   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9360
9361   mp->is_add = is_add;
9362   mp->table_index = ntohl (table_index);
9363   mp->hit_next_index = ntohl (hit_next_index);
9364   mp->opaque_index = ntohl (opaque_index);
9365   mp->advance = ntohl (advance);
9366   mp->action = action;
9367   mp->metadata = ntohl (metadata);
9368   clib_memcpy (mp->match, match, vec_len (match));
9369   vec_free (match);
9370
9371   S;
9372   W;
9373   /* NOTREACHED */
9374 }
9375
9376 static int
9377 api_classify_set_interface_ip_table (vat_main_t * vam)
9378 {
9379   unformat_input_t *i = vam->input;
9380   vl_api_classify_set_interface_ip_table_t *mp;
9381   f64 timeout;
9382   u32 sw_if_index;
9383   int sw_if_index_set;
9384   u32 table_index = ~0;
9385   u8 is_ipv6 = 0;
9386
9387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9388     {
9389       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9390         sw_if_index_set = 1;
9391       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9392         sw_if_index_set = 1;
9393       else if (unformat (i, "table %d", &table_index))
9394         ;
9395       else
9396         {
9397           clib_warning ("parse error '%U'", format_unformat_error, i);
9398           return -99;
9399         }
9400     }
9401
9402   if (sw_if_index_set == 0)
9403     {
9404       errmsg ("missing interface name or sw_if_index\n");
9405       return -99;
9406     }
9407
9408
9409   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9410
9411   mp->sw_if_index = ntohl (sw_if_index);
9412   mp->table_index = ntohl (table_index);
9413   mp->is_ipv6 = is_ipv6;
9414
9415   S;
9416   W;
9417   /* NOTREACHED */
9418   return 0;
9419 }
9420
9421 static int
9422 api_classify_set_interface_l2_tables (vat_main_t * vam)
9423 {
9424   unformat_input_t *i = vam->input;
9425   vl_api_classify_set_interface_l2_tables_t *mp;
9426   f64 timeout;
9427   u32 sw_if_index;
9428   int sw_if_index_set;
9429   u32 ip4_table_index = ~0;
9430   u32 ip6_table_index = ~0;
9431   u32 other_table_index = ~0;
9432   u32 is_input = 1;
9433
9434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9435     {
9436       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9437         sw_if_index_set = 1;
9438       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9439         sw_if_index_set = 1;
9440       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9441         ;
9442       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9443         ;
9444       else if (unformat (i, "other-table %d", &other_table_index))
9445         ;
9446       else if (unformat (i, "is-input %d", &is_input))
9447         ;
9448       else
9449         {
9450           clib_warning ("parse error '%U'", format_unformat_error, i);
9451           return -99;
9452         }
9453     }
9454
9455   if (sw_if_index_set == 0)
9456     {
9457       errmsg ("missing interface name or sw_if_index\n");
9458       return -99;
9459     }
9460
9461
9462   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9463
9464   mp->sw_if_index = ntohl (sw_if_index);
9465   mp->ip4_table_index = ntohl (ip4_table_index);
9466   mp->ip6_table_index = ntohl (ip6_table_index);
9467   mp->other_table_index = ntohl (other_table_index);
9468   mp->is_input = (u8) is_input;
9469
9470   S;
9471   W;
9472   /* NOTREACHED */
9473   return 0;
9474 }
9475
9476 static int
9477 api_set_ipfix_exporter (vat_main_t * vam)
9478 {
9479   unformat_input_t *i = vam->input;
9480   vl_api_set_ipfix_exporter_t *mp;
9481   ip4_address_t collector_address;
9482   u8 collector_address_set = 0;
9483   u32 collector_port = ~0;
9484   ip4_address_t src_address;
9485   u8 src_address_set = 0;
9486   u32 vrf_id = ~0;
9487   u32 path_mtu = ~0;
9488   u32 template_interval = ~0;
9489   u8 udp_checksum = 0;
9490   f64 timeout;
9491
9492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9493     {
9494       if (unformat (i, "collector_address %U", unformat_ip4_address,
9495                     &collector_address))
9496         collector_address_set = 1;
9497       else if (unformat (i, "collector_port %d", &collector_port))
9498         ;
9499       else if (unformat (i, "src_address %U", unformat_ip4_address,
9500                          &src_address))
9501         src_address_set = 1;
9502       else if (unformat (i, "vrf_id %d", &vrf_id))
9503         ;
9504       else if (unformat (i, "path_mtu %d", &path_mtu))
9505         ;
9506       else if (unformat (i, "template_interval %d", &template_interval))
9507         ;
9508       else if (unformat (i, "udp_checksum"))
9509         udp_checksum = 1;
9510       else
9511         break;
9512     }
9513
9514   if (collector_address_set == 0)
9515     {
9516       errmsg ("collector_address required\n");
9517       return -99;
9518     }
9519
9520   if (src_address_set == 0)
9521     {
9522       errmsg ("src_address required\n");
9523       return -99;
9524     }
9525
9526   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9527
9528   memcpy (mp->collector_address, collector_address.data,
9529           sizeof (collector_address.data));
9530   mp->collector_port = htons ((u16) collector_port);
9531   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9532   mp->vrf_id = htonl (vrf_id);
9533   mp->path_mtu = htonl (path_mtu);
9534   mp->template_interval = htonl (template_interval);
9535   mp->udp_checksum = udp_checksum;
9536
9537   S;
9538   W;
9539   /* NOTREACHED */
9540 }
9541
9542 static int
9543 api_set_ipfix_classify_stream (vat_main_t * vam)
9544 {
9545   unformat_input_t *i = vam->input;
9546   vl_api_set_ipfix_classify_stream_t *mp;
9547   u32 domain_id = 0;
9548   u32 src_port = UDP_DST_PORT_ipfix;
9549   f64 timeout;
9550
9551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9552     {
9553       if (unformat (i, "domain %d", &domain_id))
9554         ;
9555       else if (unformat (i, "src_port %d", &src_port))
9556         ;
9557       else
9558         {
9559           errmsg ("unknown input `%U'", format_unformat_error, i);
9560           return -99;
9561         }
9562     }
9563
9564   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9565
9566   mp->domain_id = htonl (domain_id);
9567   mp->src_port = htons ((u16) src_port);
9568
9569   S;
9570   W;
9571   /* NOTREACHED */
9572 }
9573
9574 static int
9575 api_ipfix_classify_table_add_del (vat_main_t * vam)
9576 {
9577   unformat_input_t *i = vam->input;
9578   vl_api_ipfix_classify_table_add_del_t *mp;
9579   int is_add = -1;
9580   u32 classify_table_index = ~0;
9581   u8 ip_version = 0;
9582   u8 transport_protocol = 255;
9583   f64 timeout;
9584
9585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9586     {
9587       if (unformat (i, "add"))
9588         is_add = 1;
9589       else if (unformat (i, "del"))
9590         is_add = 0;
9591       else if (unformat (i, "table %d", &classify_table_index))
9592         ;
9593       else if (unformat (i, "ip4"))
9594         ip_version = 4;
9595       else if (unformat (i, "ip6"))
9596         ip_version = 6;
9597       else if (unformat (i, "tcp"))
9598         transport_protocol = 6;
9599       else if (unformat (i, "udp"))
9600         transport_protocol = 17;
9601       else
9602         {
9603           errmsg ("unknown input `%U'", format_unformat_error, i);
9604           return -99;
9605         }
9606     }
9607
9608   if (is_add == -1)
9609     {
9610       errmsg ("expecting: add|del");
9611       return -99;
9612     }
9613   if (classify_table_index == ~0)
9614     {
9615       errmsg ("classifier table not specified");
9616       return -99;
9617     }
9618   if (ip_version == 0)
9619     {
9620       errmsg ("IP version not specified");
9621       return -99;
9622     }
9623
9624   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9625
9626   mp->is_add = is_add;
9627   mp->table_id = htonl (classify_table_index);
9628   mp->ip_version = ip_version;
9629   mp->transport_protocol = transport_protocol;
9630
9631   S;
9632   W;
9633   /* NOTREACHED */
9634 }
9635
9636 static int
9637 api_get_node_index (vat_main_t * vam)
9638 {
9639   unformat_input_t *i = vam->input;
9640   vl_api_get_node_index_t *mp;
9641   f64 timeout;
9642   u8 *name = 0;
9643
9644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9645     {
9646       if (unformat (i, "node %s", &name))
9647         ;
9648       else
9649         break;
9650     }
9651   if (name == 0)
9652     {
9653       errmsg ("node name required\n");
9654       return -99;
9655     }
9656   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9657     {
9658       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9659       return -99;
9660     }
9661
9662   M (GET_NODE_INDEX, get_node_index);
9663   clib_memcpy (mp->node_name, name, vec_len (name));
9664   vec_free (name);
9665
9666   S;
9667   W;
9668   /* NOTREACHED */
9669   return 0;
9670 }
9671
9672 static int
9673 api_get_next_index (vat_main_t * vam)
9674 {
9675   unformat_input_t *i = vam->input;
9676   vl_api_get_next_index_t *mp;
9677   f64 timeout;
9678   u8 *node_name = 0, *next_node_name = 0;
9679
9680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9681     {
9682       if (unformat (i, "node-name %s", &node_name))
9683         ;
9684       else if (unformat (i, "next-node-name %s", &next_node_name))
9685         break;
9686     }
9687
9688   if (node_name == 0)
9689     {
9690       errmsg ("node name required\n");
9691       return -99;
9692     }
9693   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9694     {
9695       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9696       return -99;
9697     }
9698
9699   if (next_node_name == 0)
9700     {
9701       errmsg ("next node name required\n");
9702       return -99;
9703     }
9704   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9705     {
9706       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9707       return -99;
9708     }
9709
9710   M (GET_NEXT_INDEX, get_next_index);
9711   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9712   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9713   vec_free (node_name);
9714   vec_free (next_node_name);
9715
9716   S;
9717   W;
9718   /* NOTREACHED */
9719   return 0;
9720 }
9721
9722 static int
9723 api_add_node_next (vat_main_t * vam)
9724 {
9725   unformat_input_t *i = vam->input;
9726   vl_api_add_node_next_t *mp;
9727   f64 timeout;
9728   u8 *name = 0;
9729   u8 *next = 0;
9730
9731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9732     {
9733       if (unformat (i, "node %s", &name))
9734         ;
9735       else if (unformat (i, "next %s", &next))
9736         ;
9737       else
9738         break;
9739     }
9740   if (name == 0)
9741     {
9742       errmsg ("node name required\n");
9743       return -99;
9744     }
9745   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9746     {
9747       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9748       return -99;
9749     }
9750   if (next == 0)
9751     {
9752       errmsg ("next node required\n");
9753       return -99;
9754     }
9755   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9756     {
9757       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9758       return -99;
9759     }
9760
9761   M (ADD_NODE_NEXT, add_node_next);
9762   clib_memcpy (mp->node_name, name, vec_len (name));
9763   clib_memcpy (mp->next_name, next, vec_len (next));
9764   vec_free (name);
9765   vec_free (next);
9766
9767   S;
9768   W;
9769   /* NOTREACHED */
9770   return 0;
9771 }
9772
9773 static int
9774 api_l2tpv3_create_tunnel (vat_main_t * vam)
9775 {
9776   unformat_input_t *i = vam->input;
9777   ip6_address_t client_address, our_address;
9778   int client_address_set = 0;
9779   int our_address_set = 0;
9780   u32 local_session_id = 0;
9781   u32 remote_session_id = 0;
9782   u64 local_cookie = 0;
9783   u64 remote_cookie = 0;
9784   u8 l2_sublayer_present = 0;
9785   vl_api_l2tpv3_create_tunnel_t *mp;
9786   f64 timeout;
9787
9788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9789     {
9790       if (unformat (i, "client_address %U", unformat_ip6_address,
9791                     &client_address))
9792         client_address_set = 1;
9793       else if (unformat (i, "our_address %U", unformat_ip6_address,
9794                          &our_address))
9795         our_address_set = 1;
9796       else if (unformat (i, "local_session_id %d", &local_session_id))
9797         ;
9798       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9799         ;
9800       else if (unformat (i, "local_cookie %lld", &local_cookie))
9801         ;
9802       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9803         ;
9804       else if (unformat (i, "l2-sublayer-present"))
9805         l2_sublayer_present = 1;
9806       else
9807         break;
9808     }
9809
9810   if (client_address_set == 0)
9811     {
9812       errmsg ("client_address required\n");
9813       return -99;
9814     }
9815
9816   if (our_address_set == 0)
9817     {
9818       errmsg ("our_address required\n");
9819       return -99;
9820     }
9821
9822   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9823
9824   clib_memcpy (mp->client_address, client_address.as_u8,
9825                sizeof (mp->client_address));
9826
9827   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9828
9829   mp->local_session_id = ntohl (local_session_id);
9830   mp->remote_session_id = ntohl (remote_session_id);
9831   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9832   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9833   mp->l2_sublayer_present = l2_sublayer_present;
9834   mp->is_ipv6 = 1;
9835
9836   S;
9837   W;
9838   /* NOTREACHED */
9839   return 0;
9840 }
9841
9842 static int
9843 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9844 {
9845   unformat_input_t *i = vam->input;
9846   u32 sw_if_index;
9847   u8 sw_if_index_set = 0;
9848   u64 new_local_cookie = 0;
9849   u64 new_remote_cookie = 0;
9850   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9851   f64 timeout;
9852
9853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9854     {
9855       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9856         sw_if_index_set = 1;
9857       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9858         sw_if_index_set = 1;
9859       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9860         ;
9861       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9862         ;
9863       else
9864         break;
9865     }
9866
9867   if (sw_if_index_set == 0)
9868     {
9869       errmsg ("missing interface name or sw_if_index\n");
9870       return -99;
9871     }
9872
9873   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9874
9875   mp->sw_if_index = ntohl (sw_if_index);
9876   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9877   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9878
9879   S;
9880   W;
9881   /* NOTREACHED */
9882   return 0;
9883 }
9884
9885 static int
9886 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9887 {
9888   unformat_input_t *i = vam->input;
9889   vl_api_l2tpv3_interface_enable_disable_t *mp;
9890   f64 timeout;
9891   u32 sw_if_index;
9892   u8 sw_if_index_set = 0;
9893   u8 enable_disable = 1;
9894
9895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9896     {
9897       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9898         sw_if_index_set = 1;
9899       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9900         sw_if_index_set = 1;
9901       else if (unformat (i, "enable"))
9902         enable_disable = 1;
9903       else if (unformat (i, "disable"))
9904         enable_disable = 0;
9905       else
9906         break;
9907     }
9908
9909   if (sw_if_index_set == 0)
9910     {
9911       errmsg ("missing interface name or sw_if_index\n");
9912       return -99;
9913     }
9914
9915   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9916
9917   mp->sw_if_index = ntohl (sw_if_index);
9918   mp->enable_disable = enable_disable;
9919
9920   S;
9921   W;
9922   /* NOTREACHED */
9923   return 0;
9924 }
9925
9926 static int
9927 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9928 {
9929   unformat_input_t *i = vam->input;
9930   vl_api_l2tpv3_set_lookup_key_t *mp;
9931   f64 timeout;
9932   u8 key = ~0;
9933
9934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9935     {
9936       if (unformat (i, "lookup_v6_src"))
9937         key = L2T_LOOKUP_SRC_ADDRESS;
9938       else if (unformat (i, "lookup_v6_dst"))
9939         key = L2T_LOOKUP_DST_ADDRESS;
9940       else if (unformat (i, "lookup_session_id"))
9941         key = L2T_LOOKUP_SESSION_ID;
9942       else
9943         break;
9944     }
9945
9946   if (key == (u8) ~ 0)
9947     {
9948       errmsg ("l2tp session lookup key unset\n");
9949       return -99;
9950     }
9951
9952   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9953
9954   mp->key = key;
9955
9956   S;
9957   W;
9958   /* NOTREACHED */
9959   return 0;
9960 }
9961
9962 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9963   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9964 {
9965   vat_main_t *vam = &vat_main;
9966
9967   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9968            format_ip6_address, mp->our_address,
9969            format_ip6_address, mp->client_address,
9970            clib_net_to_host_u32 (mp->sw_if_index));
9971
9972   fformat (vam->ofp,
9973            "   local cookies %016llx %016llx remote cookie %016llx\n",
9974            clib_net_to_host_u64 (mp->local_cookie[0]),
9975            clib_net_to_host_u64 (mp->local_cookie[1]),
9976            clib_net_to_host_u64 (mp->remote_cookie));
9977
9978   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9979            clib_net_to_host_u32 (mp->local_session_id),
9980            clib_net_to_host_u32 (mp->remote_session_id));
9981
9982   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9983            mp->l2_sublayer_present ? "preset" : "absent");
9984
9985 }
9986
9987 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9988   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9989 {
9990   vat_main_t *vam = &vat_main;
9991   vat_json_node_t *node = NULL;
9992   struct in6_addr addr;
9993
9994   if (VAT_JSON_ARRAY != vam->json_tree.type)
9995     {
9996       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9997       vat_json_init_array (&vam->json_tree);
9998     }
9999   node = vat_json_array_add (&vam->json_tree);
10000
10001   vat_json_init_object (node);
10002
10003   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10004   vat_json_object_add_ip6 (node, "our_address", addr);
10005   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10006   vat_json_object_add_ip6 (node, "client_address", addr);
10007
10008   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10009   vat_json_init_array (lc);
10010   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10011   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10012   vat_json_object_add_uint (node, "remote_cookie",
10013                             clib_net_to_host_u64 (mp->remote_cookie));
10014
10015   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10016   vat_json_object_add_uint (node, "local_session_id",
10017                             clib_net_to_host_u32 (mp->local_session_id));
10018   vat_json_object_add_uint (node, "remote_session_id",
10019                             clib_net_to_host_u32 (mp->remote_session_id));
10020   vat_json_object_add_string_copy (node, "l2_sublayer",
10021                                    mp->l2_sublayer_present ? (u8 *) "present"
10022                                    : (u8 *) "absent");
10023 }
10024
10025 static int
10026 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10027 {
10028   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10029   f64 timeout;
10030
10031   /* Get list of l2tpv3-tunnel interfaces */
10032   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10033   S;
10034
10035   /* Use a control ping for synchronization */
10036   {
10037     vl_api_control_ping_t *mp;
10038     M (CONTROL_PING, control_ping);
10039     S;
10040   }
10041   W;
10042 }
10043
10044
10045 static void vl_api_sw_interface_tap_details_t_handler
10046   (vl_api_sw_interface_tap_details_t * mp)
10047 {
10048   vat_main_t *vam = &vat_main;
10049
10050   fformat (vam->ofp, "%-16s %d\n",
10051            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10052 }
10053
10054 static void vl_api_sw_interface_tap_details_t_handler_json
10055   (vl_api_sw_interface_tap_details_t * mp)
10056 {
10057   vat_main_t *vam = &vat_main;
10058   vat_json_node_t *node = NULL;
10059
10060   if (VAT_JSON_ARRAY != vam->json_tree.type)
10061     {
10062       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10063       vat_json_init_array (&vam->json_tree);
10064     }
10065   node = vat_json_array_add (&vam->json_tree);
10066
10067   vat_json_init_object (node);
10068   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10069   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10070 }
10071
10072 static int
10073 api_sw_interface_tap_dump (vat_main_t * vam)
10074 {
10075   vl_api_sw_interface_tap_dump_t *mp;
10076   f64 timeout;
10077
10078   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10079   /* Get list of tap interfaces */
10080   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10081   S;
10082
10083   /* Use a control ping for synchronization */
10084   {
10085     vl_api_control_ping_t *mp;
10086     M (CONTROL_PING, control_ping);
10087     S;
10088   }
10089   W;
10090 }
10091
10092 static uword unformat_vxlan_decap_next
10093   (unformat_input_t * input, va_list * args)
10094 {
10095   u32 *result = va_arg (*args, u32 *);
10096   u32 tmp;
10097
10098   if (unformat (input, "l2"))
10099     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10100   else if (unformat (input, "%d", &tmp))
10101     *result = tmp;
10102   else
10103     return 0;
10104   return 1;
10105 }
10106
10107 static int
10108 api_vxlan_add_del_tunnel (vat_main_t * vam)
10109 {
10110   unformat_input_t *line_input = vam->input;
10111   vl_api_vxlan_add_del_tunnel_t *mp;
10112   f64 timeout;
10113   ip4_address_t src4, dst4;
10114   ip6_address_t src6, dst6;
10115   u8 is_add = 1;
10116   u8 ipv4_set = 0, ipv6_set = 0;
10117   u8 src_set = 0;
10118   u8 dst_set = 0;
10119   u32 encap_vrf_id = 0;
10120   u32 decap_next_index = ~0;
10121   u32 vni = 0;
10122
10123   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10124     {
10125       if (unformat (line_input, "del"))
10126         is_add = 0;
10127       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10128         {
10129           ipv4_set = 1;
10130           src_set = 1;
10131         }
10132       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10133         {
10134           ipv4_set = 1;
10135           dst_set = 1;
10136         }
10137       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
10138         {
10139           ipv6_set = 1;
10140           src_set = 1;
10141         }
10142       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
10143         {
10144           ipv6_set = 1;
10145           dst_set = 1;
10146         }
10147       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10148         ;
10149       else if (unformat (line_input, "decap-next %U",
10150                          unformat_vxlan_decap_next, &decap_next_index))
10151         ;
10152       else if (unformat (line_input, "vni %d", &vni))
10153         ;
10154       else
10155         {
10156           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10157           return -99;
10158         }
10159     }
10160
10161   if (src_set == 0)
10162     {
10163       errmsg ("tunnel src address not specified\n");
10164       return -99;
10165     }
10166   if (dst_set == 0)
10167     {
10168       errmsg ("tunnel dst address not specified\n");
10169       return -99;
10170     }
10171
10172   if (ipv4_set && ipv6_set)
10173     {
10174       errmsg ("both IPv4 and IPv6 addresses specified");
10175       return -99;
10176     }
10177
10178   if ((vni == 0) || (vni >> 24))
10179     {
10180       errmsg ("vni not specified or out of range\n");
10181       return -99;
10182     }
10183
10184   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10185
10186   if (ipv6_set)
10187     {
10188       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
10189       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
10190     }
10191   else
10192     {
10193       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10194       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10195     }
10196   mp->encap_vrf_id = ntohl (encap_vrf_id);
10197   mp->decap_next_index = ntohl (decap_next_index);
10198   mp->vni = ntohl (vni);
10199   mp->is_add = is_add;
10200   mp->is_ipv6 = ipv6_set;
10201
10202   S;
10203   W;
10204   /* NOTREACHED */
10205   return 0;
10206 }
10207
10208 static void vl_api_vxlan_tunnel_details_t_handler
10209   (vl_api_vxlan_tunnel_details_t * mp)
10210 {
10211   vat_main_t *vam = &vat_main;
10212
10213   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
10214            ntohl (mp->sw_if_index),
10215            format_ip46_address, &(mp->src_address[0]),
10216            IP46_TYPE_ANY,
10217            format_ip46_address, &(mp->dst_address[0]),
10218            IP46_TYPE_ANY,
10219            ntohl (mp->encap_vrf_id),
10220            ntohl (mp->decap_next_index), ntohl (mp->vni));
10221 }
10222
10223 static void vl_api_vxlan_tunnel_details_t_handler_json
10224   (vl_api_vxlan_tunnel_details_t * mp)
10225 {
10226   vat_main_t *vam = &vat_main;
10227   vat_json_node_t *node = NULL;
10228   struct in_addr ip4;
10229   struct in6_addr ip6;
10230
10231   if (VAT_JSON_ARRAY != vam->json_tree.type)
10232     {
10233       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10234       vat_json_init_array (&vam->json_tree);
10235     }
10236   node = vat_json_array_add (&vam->json_tree);
10237
10238   vat_json_init_object (node);
10239   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10240   if (mp->is_ipv6)
10241     {
10242       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
10243       vat_json_object_add_ip6 (node, "src_address", ip6);
10244       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
10245       vat_json_object_add_ip6 (node, "dst_address", ip6);
10246     }
10247   else
10248     {
10249       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
10250       vat_json_object_add_ip4 (node, "src_address", ip4);
10251       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
10252       vat_json_object_add_ip4 (node, "dst_address", ip4);
10253     }
10254   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10255   vat_json_object_add_uint (node, "decap_next_index",
10256                             ntohl (mp->decap_next_index));
10257   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10258   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10259 }
10260
10261 static int
10262 api_vxlan_tunnel_dump (vat_main_t * vam)
10263 {
10264   unformat_input_t *i = vam->input;
10265   vl_api_vxlan_tunnel_dump_t *mp;
10266   f64 timeout;
10267   u32 sw_if_index;
10268   u8 sw_if_index_set = 0;
10269
10270   /* Parse args required to build the message */
10271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10272     {
10273       if (unformat (i, "sw_if_index %d", &sw_if_index))
10274         sw_if_index_set = 1;
10275       else
10276         break;
10277     }
10278
10279   if (sw_if_index_set == 0)
10280     {
10281       sw_if_index = ~0;
10282     }
10283
10284   if (!vam->json_output)
10285     {
10286       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
10287                "sw_if_index", "src_address", "dst_address",
10288                "encap_vrf_id", "decap_next_index", "vni");
10289     }
10290
10291   /* Get list of vxlan-tunnel interfaces */
10292   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10293
10294   mp->sw_if_index = htonl (sw_if_index);
10295
10296   S;
10297
10298   /* Use a control ping for synchronization */
10299   {
10300     vl_api_control_ping_t *mp;
10301     M (CONTROL_PING, control_ping);
10302     S;
10303   }
10304   W;
10305 }
10306
10307 static int
10308 api_gre_add_del_tunnel (vat_main_t * vam)
10309 {
10310   unformat_input_t *line_input = vam->input;
10311   vl_api_gre_add_del_tunnel_t *mp;
10312   f64 timeout;
10313   ip4_address_t src4, dst4;
10314   u8 is_add = 1;
10315   u8 teb = 0;
10316   u8 src_set = 0;
10317   u8 dst_set = 0;
10318   u32 outer_fib_id = 0;
10319
10320   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10321     {
10322       if (unformat (line_input, "del"))
10323         is_add = 0;
10324       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10325         src_set = 1;
10326       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10327         dst_set = 1;
10328       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10329         ;
10330       else if (unformat (line_input, "teb"))
10331         teb = 1;
10332       else
10333         {
10334           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10335           return -99;
10336         }
10337     }
10338
10339   if (src_set == 0)
10340     {
10341       errmsg ("tunnel src address not specified\n");
10342       return -99;
10343     }
10344   if (dst_set == 0)
10345     {
10346       errmsg ("tunnel dst address not specified\n");
10347       return -99;
10348     }
10349
10350
10351   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10352
10353   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10354   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10355   mp->outer_fib_id = ntohl (outer_fib_id);
10356   mp->is_add = is_add;
10357   mp->teb = teb;
10358
10359   S;
10360   W;
10361   /* NOTREACHED */
10362   return 0;
10363 }
10364
10365 static void vl_api_gre_tunnel_details_t_handler
10366   (vl_api_gre_tunnel_details_t * mp)
10367 {
10368   vat_main_t *vam = &vat_main;
10369
10370   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10371            ntohl (mp->sw_if_index),
10372            format_ip4_address, &mp->src_address,
10373            format_ip4_address, &mp->dst_address,
10374            mp->teb, ntohl (mp->outer_fib_id));
10375 }
10376
10377 static void vl_api_gre_tunnel_details_t_handler_json
10378   (vl_api_gre_tunnel_details_t * mp)
10379 {
10380   vat_main_t *vam = &vat_main;
10381   vat_json_node_t *node = NULL;
10382   struct in_addr ip4;
10383
10384   if (VAT_JSON_ARRAY != vam->json_tree.type)
10385     {
10386       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10387       vat_json_init_array (&vam->json_tree);
10388     }
10389   node = vat_json_array_add (&vam->json_tree);
10390
10391   vat_json_init_object (node);
10392   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10393   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10394   vat_json_object_add_ip4 (node, "src_address", ip4);
10395   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10396   vat_json_object_add_ip4 (node, "dst_address", ip4);
10397   vat_json_object_add_uint (node, "teb", mp->teb);
10398   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10399 }
10400
10401 static int
10402 api_gre_tunnel_dump (vat_main_t * vam)
10403 {
10404   unformat_input_t *i = vam->input;
10405   vl_api_gre_tunnel_dump_t *mp;
10406   f64 timeout;
10407   u32 sw_if_index;
10408   u8 sw_if_index_set = 0;
10409
10410   /* Parse args required to build the message */
10411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10412     {
10413       if (unformat (i, "sw_if_index %d", &sw_if_index))
10414         sw_if_index_set = 1;
10415       else
10416         break;
10417     }
10418
10419   if (sw_if_index_set == 0)
10420     {
10421       sw_if_index = ~0;
10422     }
10423
10424   if (!vam->json_output)
10425     {
10426       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10427                "sw_if_index", "src_address", "dst_address", "teb",
10428                "outer_fib_id");
10429     }
10430
10431   /* Get list of gre-tunnel interfaces */
10432   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10433
10434   mp->sw_if_index = htonl (sw_if_index);
10435
10436   S;
10437
10438   /* Use a control ping for synchronization */
10439   {
10440     vl_api_control_ping_t *mp;
10441     M (CONTROL_PING, control_ping);
10442     S;
10443   }
10444   W;
10445 }
10446
10447 static int
10448 api_l2_fib_clear_table (vat_main_t * vam)
10449 {
10450 //  unformat_input_t * i = vam->input;
10451   vl_api_l2_fib_clear_table_t *mp;
10452   f64 timeout;
10453
10454   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10455
10456   S;
10457   W;
10458   /* NOTREACHED */
10459   return 0;
10460 }
10461
10462 static int
10463 api_l2_interface_efp_filter (vat_main_t * vam)
10464 {
10465   unformat_input_t *i = vam->input;
10466   vl_api_l2_interface_efp_filter_t *mp;
10467   f64 timeout;
10468   u32 sw_if_index;
10469   u8 enable = 1;
10470   u8 sw_if_index_set = 0;
10471
10472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10473     {
10474       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10475         sw_if_index_set = 1;
10476       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10477         sw_if_index_set = 1;
10478       else if (unformat (i, "enable"))
10479         enable = 1;
10480       else if (unformat (i, "disable"))
10481         enable = 0;
10482       else
10483         {
10484           clib_warning ("parse error '%U'", format_unformat_error, i);
10485           return -99;
10486         }
10487     }
10488
10489   if (sw_if_index_set == 0)
10490     {
10491       errmsg ("missing sw_if_index\n");
10492       return -99;
10493     }
10494
10495   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10496
10497   mp->sw_if_index = ntohl (sw_if_index);
10498   mp->enable_disable = enable;
10499
10500   S;
10501   W;
10502   /* NOTREACHED */
10503   return 0;
10504 }
10505
10506 #define foreach_vtr_op                          \
10507 _("disable",  L2_VTR_DISABLED)                  \
10508 _("push-1",  L2_VTR_PUSH_1)                     \
10509 _("push-2",  L2_VTR_PUSH_2)                     \
10510 _("pop-1",  L2_VTR_POP_1)                       \
10511 _("pop-2",  L2_VTR_POP_2)                       \
10512 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10513 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10514 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10515 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10516
10517 static int
10518 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10519 {
10520   unformat_input_t *i = vam->input;
10521   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10522   f64 timeout;
10523   u32 sw_if_index;
10524   u8 sw_if_index_set = 0;
10525   u8 vtr_op_set = 0;
10526   u32 vtr_op = 0;
10527   u32 push_dot1q = 1;
10528   u32 tag1 = ~0;
10529   u32 tag2 = ~0;
10530
10531   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10532     {
10533       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10534         sw_if_index_set = 1;
10535       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10536         sw_if_index_set = 1;
10537       else if (unformat (i, "vtr_op %d", &vtr_op))
10538         vtr_op_set = 1;
10539 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10540       foreach_vtr_op
10541 #undef _
10542         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10543         ;
10544       else if (unformat (i, "tag1 %d", &tag1))
10545         ;
10546       else if (unformat (i, "tag2 %d", &tag2))
10547         ;
10548       else
10549         {
10550           clib_warning ("parse error '%U'", format_unformat_error, i);
10551           return -99;
10552         }
10553     }
10554
10555   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10556     {
10557       errmsg ("missing vtr operation or sw_if_index\n");
10558       return -99;
10559     }
10560
10561   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10562     mp->sw_if_index = ntohl (sw_if_index);
10563   mp->vtr_op = ntohl (vtr_op);
10564   mp->push_dot1q = ntohl (push_dot1q);
10565   mp->tag1 = ntohl (tag1);
10566   mp->tag2 = ntohl (tag2);
10567
10568   S;
10569   W;
10570   /* NOTREACHED */
10571   return 0;
10572 }
10573
10574 static int
10575 api_create_vhost_user_if (vat_main_t * vam)
10576 {
10577   unformat_input_t *i = vam->input;
10578   vl_api_create_vhost_user_if_t *mp;
10579   f64 timeout;
10580   u8 *file_name;
10581   u8 is_server = 0;
10582   u8 file_name_set = 0;
10583   u32 custom_dev_instance = ~0;
10584   u8 hwaddr[6];
10585   u8 use_custom_mac = 0;
10586
10587   /* Shut up coverity */
10588   memset (hwaddr, 0, sizeof (hwaddr));
10589
10590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10591     {
10592       if (unformat (i, "socket %s", &file_name))
10593         {
10594           file_name_set = 1;
10595         }
10596       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10597         ;
10598       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10599         use_custom_mac = 1;
10600       else if (unformat (i, "server"))
10601         is_server = 1;
10602       else
10603         break;
10604     }
10605
10606   if (file_name_set == 0)
10607     {
10608       errmsg ("missing socket file name\n");
10609       return -99;
10610     }
10611
10612   if (vec_len (file_name) > 255)
10613     {
10614       errmsg ("socket file name too long\n");
10615       return -99;
10616     }
10617   vec_add1 (file_name, 0);
10618
10619   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10620
10621   mp->is_server = is_server;
10622   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10623   vec_free (file_name);
10624   if (custom_dev_instance != ~0)
10625     {
10626       mp->renumber = 1;
10627       mp->custom_dev_instance = ntohl (custom_dev_instance);
10628     }
10629   mp->use_custom_mac = use_custom_mac;
10630   clib_memcpy (mp->mac_address, hwaddr, 6);
10631
10632   S;
10633   W;
10634   /* NOTREACHED */
10635   return 0;
10636 }
10637
10638 static int
10639 api_modify_vhost_user_if (vat_main_t * vam)
10640 {
10641   unformat_input_t *i = vam->input;
10642   vl_api_modify_vhost_user_if_t *mp;
10643   f64 timeout;
10644   u8 *file_name;
10645   u8 is_server = 0;
10646   u8 file_name_set = 0;
10647   u32 custom_dev_instance = ~0;
10648   u8 sw_if_index_set = 0;
10649   u32 sw_if_index = (u32) ~ 0;
10650
10651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10652     {
10653       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10654         sw_if_index_set = 1;
10655       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10656         sw_if_index_set = 1;
10657       else if (unformat (i, "socket %s", &file_name))
10658         {
10659           file_name_set = 1;
10660         }
10661       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10662         ;
10663       else if (unformat (i, "server"))
10664         is_server = 1;
10665       else
10666         break;
10667     }
10668
10669   if (sw_if_index_set == 0)
10670     {
10671       errmsg ("missing sw_if_index or interface name\n");
10672       return -99;
10673     }
10674
10675   if (file_name_set == 0)
10676     {
10677       errmsg ("missing socket file name\n");
10678       return -99;
10679     }
10680
10681   if (vec_len (file_name) > 255)
10682     {
10683       errmsg ("socket file name too long\n");
10684       return -99;
10685     }
10686   vec_add1 (file_name, 0);
10687
10688   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10689
10690   mp->sw_if_index = ntohl (sw_if_index);
10691   mp->is_server = is_server;
10692   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10693   vec_free (file_name);
10694   if (custom_dev_instance != ~0)
10695     {
10696       mp->renumber = 1;
10697       mp->custom_dev_instance = ntohl (custom_dev_instance);
10698     }
10699
10700   S;
10701   W;
10702   /* NOTREACHED */
10703   return 0;
10704 }
10705
10706 static int
10707 api_delete_vhost_user_if (vat_main_t * vam)
10708 {
10709   unformat_input_t *i = vam->input;
10710   vl_api_delete_vhost_user_if_t *mp;
10711   f64 timeout;
10712   u32 sw_if_index = ~0;
10713   u8 sw_if_index_set = 0;
10714
10715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10716     {
10717       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10718         sw_if_index_set = 1;
10719       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10720         sw_if_index_set = 1;
10721       else
10722         break;
10723     }
10724
10725   if (sw_if_index_set == 0)
10726     {
10727       errmsg ("missing sw_if_index or interface name\n");
10728       return -99;
10729     }
10730
10731
10732   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10733
10734   mp->sw_if_index = ntohl (sw_if_index);
10735
10736   S;
10737   W;
10738   /* NOTREACHED */
10739   return 0;
10740 }
10741
10742 static void vl_api_sw_interface_vhost_user_details_t_handler
10743   (vl_api_sw_interface_vhost_user_details_t * mp)
10744 {
10745   vat_main_t *vam = &vat_main;
10746
10747   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10748            (char *) mp->interface_name,
10749            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10750            clib_net_to_host_u64 (mp->features), mp->is_server,
10751            ntohl (mp->num_regions), (char *) mp->sock_filename);
10752   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10753 }
10754
10755 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10756   (vl_api_sw_interface_vhost_user_details_t * mp)
10757 {
10758   vat_main_t *vam = &vat_main;
10759   vat_json_node_t *node = NULL;
10760
10761   if (VAT_JSON_ARRAY != vam->json_tree.type)
10762     {
10763       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10764       vat_json_init_array (&vam->json_tree);
10765     }
10766   node = vat_json_array_add (&vam->json_tree);
10767
10768   vat_json_init_object (node);
10769   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10770   vat_json_object_add_string_copy (node, "interface_name",
10771                                    mp->interface_name);
10772   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10773                             ntohl (mp->virtio_net_hdr_sz));
10774   vat_json_object_add_uint (node, "features",
10775                             clib_net_to_host_u64 (mp->features));
10776   vat_json_object_add_uint (node, "is_server", mp->is_server);
10777   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10778   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10779   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10780 }
10781
10782 static int
10783 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10784 {
10785   vl_api_sw_interface_vhost_user_dump_t *mp;
10786   f64 timeout;
10787   fformat (vam->ofp,
10788            "Interface name           idx hdr_sz features server regions filename\n");
10789
10790   /* Get list of vhost-user interfaces */
10791   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10792   S;
10793
10794   /* Use a control ping for synchronization */
10795   {
10796     vl_api_control_ping_t *mp;
10797     M (CONTROL_PING, control_ping);
10798     S;
10799   }
10800   W;
10801 }
10802
10803 static int
10804 api_show_version (vat_main_t * vam)
10805 {
10806   vl_api_show_version_t *mp;
10807   f64 timeout;
10808
10809   M (SHOW_VERSION, show_version);
10810
10811   S;
10812   W;
10813   /* NOTREACHED */
10814   return 0;
10815 }
10816
10817
10818 static int
10819 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10820 {
10821   unformat_input_t *line_input = vam->input;
10822   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10823   f64 timeout;
10824   ip4_address_t local4, remote4;
10825   ip6_address_t local6, remote6;
10826   u8 is_add = 1;
10827   u8 ipv4_set = 0, ipv6_set = 0;
10828   u8 local_set = 0;
10829   u8 remote_set = 0;
10830   u32 encap_vrf_id = 0;
10831   u32 decap_vrf_id = 0;
10832   u8 protocol = ~0;
10833   u32 vni;
10834   u8 vni_set = 0;
10835
10836   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10837     {
10838       if (unformat (line_input, "del"))
10839         is_add = 0;
10840       else if (unformat (line_input, "local %U",
10841                          unformat_ip4_address, &local4))
10842         {
10843           local_set = 1;
10844           ipv4_set = 1;
10845         }
10846       else if (unformat (line_input, "remote %U",
10847                          unformat_ip4_address, &remote4))
10848         {
10849           remote_set = 1;
10850           ipv4_set = 1;
10851         }
10852       else if (unformat (line_input, "local %U",
10853                          unformat_ip6_address, &local6))
10854         {
10855           local_set = 1;
10856           ipv6_set = 1;
10857         }
10858       else if (unformat (line_input, "remote %U",
10859                          unformat_ip6_address, &remote6))
10860         {
10861           remote_set = 1;
10862           ipv6_set = 1;
10863         }
10864       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10865         ;
10866       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10867         ;
10868       else if (unformat (line_input, "vni %d", &vni))
10869         vni_set = 1;
10870       else if (unformat (line_input, "next-ip4"))
10871         protocol = 1;
10872       else if (unformat (line_input, "next-ip6"))
10873         protocol = 2;
10874       else if (unformat (line_input, "next-ethernet"))
10875         protocol = 3;
10876       else if (unformat (line_input, "next-nsh"))
10877         protocol = 4;
10878       else
10879         {
10880           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10881           return -99;
10882         }
10883     }
10884
10885   if (local_set == 0)
10886     {
10887       errmsg ("tunnel local address not specified\n");
10888       return -99;
10889     }
10890   if (remote_set == 0)
10891     {
10892       errmsg ("tunnel remote address not specified\n");
10893       return -99;
10894     }
10895   if (ipv4_set && ipv6_set)
10896     {
10897       errmsg ("both IPv4 and IPv6 addresses specified");
10898       return -99;
10899     }
10900
10901   if (vni_set == 0)
10902     {
10903       errmsg ("vni not specified\n");
10904       return -99;
10905     }
10906
10907   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10908
10909
10910   if (ipv6_set)
10911     {
10912       clib_memcpy (&mp->local, &local6, sizeof (local6));
10913       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10914     }
10915   else
10916     {
10917       clib_memcpy (&mp->local, &local4, sizeof (local4));
10918       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10919     }
10920
10921   mp->encap_vrf_id = ntohl (encap_vrf_id);
10922   mp->decap_vrf_id = ntohl (decap_vrf_id);
10923   mp->protocol = ntohl (protocol);
10924   mp->vni = ntohl (vni);
10925   mp->is_add = is_add;
10926   mp->is_ipv6 = ipv6_set;
10927
10928   S;
10929   W;
10930   /* NOTREACHED */
10931   return 0;
10932 }
10933
10934 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10935   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10936 {
10937   vat_main_t *vam = &vat_main;
10938
10939   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10940            ntohl (mp->sw_if_index),
10941            format_ip46_address, &(mp->local[0]),
10942            format_ip46_address, &(mp->remote[0]),
10943            ntohl (mp->vni),
10944            ntohl (mp->protocol),
10945            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10946 }
10947
10948 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10949   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10950 {
10951   vat_main_t *vam = &vat_main;
10952   vat_json_node_t *node = NULL;
10953   struct in_addr ip4;
10954   struct in6_addr ip6;
10955
10956   if (VAT_JSON_ARRAY != vam->json_tree.type)
10957     {
10958       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10959       vat_json_init_array (&vam->json_tree);
10960     }
10961   node = vat_json_array_add (&vam->json_tree);
10962
10963   vat_json_init_object (node);
10964   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10965   if (mp->is_ipv6)
10966     {
10967       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10968       vat_json_object_add_ip6 (node, "local", ip6);
10969       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10970       vat_json_object_add_ip6 (node, "remote", ip6);
10971     }
10972   else
10973     {
10974       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10975       vat_json_object_add_ip4 (node, "local", ip4);
10976       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10977       vat_json_object_add_ip4 (node, "remote", ip4);
10978     }
10979   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10980   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10981   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10982   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10983   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10984 }
10985
10986 static int
10987 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10988 {
10989   unformat_input_t *i = vam->input;
10990   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10991   f64 timeout;
10992   u32 sw_if_index;
10993   u8 sw_if_index_set = 0;
10994
10995   /* Parse args required to build the message */
10996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10997     {
10998       if (unformat (i, "sw_if_index %d", &sw_if_index))
10999         sw_if_index_set = 1;
11000       else
11001         break;
11002     }
11003
11004   if (sw_if_index_set == 0)
11005     {
11006       sw_if_index = ~0;
11007     }
11008
11009   if (!vam->json_output)
11010     {
11011       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
11012                "sw_if_index", "local", "remote", "vni",
11013                "protocol", "encap_vrf_id", "decap_vrf_id");
11014     }
11015
11016   /* Get list of vxlan-tunnel interfaces */
11017   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11018
11019   mp->sw_if_index = htonl (sw_if_index);
11020
11021   S;
11022
11023   /* Use a control ping for synchronization */
11024   {
11025     vl_api_control_ping_t *mp;
11026     M (CONTROL_PING, control_ping);
11027     S;
11028   }
11029   W;
11030 }
11031
11032 u8 *
11033 format_l2_fib_mac_address (u8 * s, va_list * args)
11034 {
11035   u8 *a = va_arg (*args, u8 *);
11036
11037   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11038                  a[2], a[3], a[4], a[5], a[6], a[7]);
11039 }
11040
11041 static void vl_api_l2_fib_table_entry_t_handler
11042   (vl_api_l2_fib_table_entry_t * mp)
11043 {
11044   vat_main_t *vam = &vat_main;
11045
11046   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11047            "       %d       %d     %d\n",
11048            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11049            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11050            mp->bvi_mac);
11051 }
11052
11053 static void vl_api_l2_fib_table_entry_t_handler_json
11054   (vl_api_l2_fib_table_entry_t * mp)
11055 {
11056   vat_main_t *vam = &vat_main;
11057   vat_json_node_t *node = NULL;
11058
11059   if (VAT_JSON_ARRAY != vam->json_tree.type)
11060     {
11061       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11062       vat_json_init_array (&vam->json_tree);
11063     }
11064   node = vat_json_array_add (&vam->json_tree);
11065
11066   vat_json_init_object (node);
11067   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11068   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11069   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11070   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11071   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11072   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11073 }
11074
11075 static int
11076 api_l2_fib_table_dump (vat_main_t * vam)
11077 {
11078   unformat_input_t *i = vam->input;
11079   vl_api_l2_fib_table_dump_t *mp;
11080   f64 timeout;
11081   u32 bd_id;
11082   u8 bd_id_set = 0;
11083
11084   /* Parse args required to build the message */
11085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11086     {
11087       if (unformat (i, "bd_id %d", &bd_id))
11088         bd_id_set = 1;
11089       else
11090         break;
11091     }
11092
11093   if (bd_id_set == 0)
11094     {
11095       errmsg ("missing bridge domain\n");
11096       return -99;
11097     }
11098
11099   fformat (vam->ofp,
11100            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11101
11102   /* Get list of l2 fib entries */
11103   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11104
11105   mp->bd_id = ntohl (bd_id);
11106   S;
11107
11108   /* Use a control ping for synchronization */
11109   {
11110     vl_api_control_ping_t *mp;
11111     M (CONTROL_PING, control_ping);
11112     S;
11113   }
11114   W;
11115 }
11116
11117
11118 static int
11119 api_interface_name_renumber (vat_main_t * vam)
11120 {
11121   unformat_input_t *line_input = vam->input;
11122   vl_api_interface_name_renumber_t *mp;
11123   u32 sw_if_index = ~0;
11124   f64 timeout;
11125   u32 new_show_dev_instance = ~0;
11126
11127   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11128     {
11129       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11130                     &sw_if_index))
11131         ;
11132       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11133         ;
11134       else if (unformat (line_input, "new_show_dev_instance %d",
11135                          &new_show_dev_instance))
11136         ;
11137       else
11138         break;
11139     }
11140
11141   if (sw_if_index == ~0)
11142     {
11143       errmsg ("missing interface name or sw_if_index\n");
11144       return -99;
11145     }
11146
11147   if (new_show_dev_instance == ~0)
11148     {
11149       errmsg ("missing new_show_dev_instance\n");
11150       return -99;
11151     }
11152
11153   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11154
11155   mp->sw_if_index = ntohl (sw_if_index);
11156   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11157
11158   S;
11159   W;
11160 }
11161
11162 static int
11163 api_want_ip4_arp_events (vat_main_t * vam)
11164 {
11165   unformat_input_t *line_input = vam->input;
11166   vl_api_want_ip4_arp_events_t *mp;
11167   f64 timeout;
11168   ip4_address_t address;
11169   int address_set = 0;
11170   u32 enable_disable = 1;
11171
11172   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11173     {
11174       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11175         address_set = 1;
11176       else if (unformat (line_input, "del"))
11177         enable_disable = 0;
11178       else
11179         break;
11180     }
11181
11182   if (address_set == 0)
11183     {
11184       errmsg ("missing addresses\n");
11185       return -99;
11186     }
11187
11188   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11189   mp->enable_disable = enable_disable;
11190   mp->pid = getpid ();
11191   mp->address = address.as_u32;
11192
11193   S;
11194   W;
11195 }
11196
11197 static int
11198 api_want_ip6_nd_events (vat_main_t * vam)
11199 {
11200   unformat_input_t *line_input = vam->input;
11201   vl_api_want_ip6_nd_events_t *mp;
11202   f64 timeout;
11203   ip6_address_t address;
11204   int address_set = 0;
11205   u32 enable_disable = 1;
11206
11207   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11208     {
11209       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11210         address_set = 1;
11211       else if (unformat (line_input, "del"))
11212         enable_disable = 0;
11213       else
11214         break;
11215     }
11216
11217   if (address_set == 0)
11218     {
11219       errmsg ("missing addresses\n");
11220       return -99;
11221     }
11222
11223   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11224   mp->enable_disable = enable_disable;
11225   mp->pid = getpid ();
11226   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11227
11228   S;
11229   W;
11230 }
11231
11232 static int
11233 api_input_acl_set_interface (vat_main_t * vam)
11234 {
11235   unformat_input_t *i = vam->input;
11236   vl_api_input_acl_set_interface_t *mp;
11237   f64 timeout;
11238   u32 sw_if_index;
11239   int sw_if_index_set;
11240   u32 ip4_table_index = ~0;
11241   u32 ip6_table_index = ~0;
11242   u32 l2_table_index = ~0;
11243   u8 is_add = 1;
11244
11245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11246     {
11247       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11248         sw_if_index_set = 1;
11249       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11250         sw_if_index_set = 1;
11251       else if (unformat (i, "del"))
11252         is_add = 0;
11253       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11254         ;
11255       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11256         ;
11257       else if (unformat (i, "l2-table %d", &l2_table_index))
11258         ;
11259       else
11260         {
11261           clib_warning ("parse error '%U'", format_unformat_error, i);
11262           return -99;
11263         }
11264     }
11265
11266   if (sw_if_index_set == 0)
11267     {
11268       errmsg ("missing interface name or sw_if_index\n");
11269       return -99;
11270     }
11271
11272   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11273
11274   mp->sw_if_index = ntohl (sw_if_index);
11275   mp->ip4_table_index = ntohl (ip4_table_index);
11276   mp->ip6_table_index = ntohl (ip6_table_index);
11277   mp->l2_table_index = ntohl (l2_table_index);
11278   mp->is_add = is_add;
11279
11280   S;
11281   W;
11282   /* NOTREACHED */
11283   return 0;
11284 }
11285
11286 static int
11287 api_ip_address_dump (vat_main_t * vam)
11288 {
11289   unformat_input_t *i = vam->input;
11290   vl_api_ip_address_dump_t *mp;
11291   u32 sw_if_index = ~0;
11292   u8 sw_if_index_set = 0;
11293   u8 ipv4_set = 0;
11294   u8 ipv6_set = 0;
11295   f64 timeout;
11296
11297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11298     {
11299       if (unformat (i, "sw_if_index %d", &sw_if_index))
11300         sw_if_index_set = 1;
11301       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11302         sw_if_index_set = 1;
11303       else if (unformat (i, "ipv4"))
11304         ipv4_set = 1;
11305       else if (unformat (i, "ipv6"))
11306         ipv6_set = 1;
11307       else
11308         break;
11309     }
11310
11311   if (ipv4_set && ipv6_set)
11312     {
11313       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11314       return -99;
11315     }
11316
11317   if ((!ipv4_set) && (!ipv6_set))
11318     {
11319       errmsg ("no ipv4 nor ipv6 flag set\n");
11320       return -99;
11321     }
11322
11323   if (sw_if_index_set == 0)
11324     {
11325       errmsg ("missing interface name or sw_if_index\n");
11326       return -99;
11327     }
11328
11329   vam->current_sw_if_index = sw_if_index;
11330   vam->is_ipv6 = ipv6_set;
11331
11332   M (IP_ADDRESS_DUMP, ip_address_dump);
11333   mp->sw_if_index = ntohl (sw_if_index);
11334   mp->is_ipv6 = ipv6_set;
11335   S;
11336
11337   /* Use a control ping for synchronization */
11338   {
11339     vl_api_control_ping_t *mp;
11340     M (CONTROL_PING, control_ping);
11341     S;
11342   }
11343   W;
11344 }
11345
11346 static int
11347 api_ip_dump (vat_main_t * vam)
11348 {
11349   vl_api_ip_dump_t *mp;
11350   unformat_input_t *in = vam->input;
11351   int ipv4_set = 0;
11352   int ipv6_set = 0;
11353   int is_ipv6;
11354   f64 timeout;
11355   int i;
11356
11357   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11358     {
11359       if (unformat (in, "ipv4"))
11360         ipv4_set = 1;
11361       else if (unformat (in, "ipv6"))
11362         ipv6_set = 1;
11363       else
11364         break;
11365     }
11366
11367   if (ipv4_set && ipv6_set)
11368     {
11369       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11370       return -99;
11371     }
11372
11373   if ((!ipv4_set) && (!ipv6_set))
11374     {
11375       errmsg ("no ipv4 nor ipv6 flag set\n");
11376       return -99;
11377     }
11378
11379   is_ipv6 = ipv6_set;
11380   vam->is_ipv6 = is_ipv6;
11381
11382   /* free old data */
11383   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11384     {
11385       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11386     }
11387   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11388
11389   M (IP_DUMP, ip_dump);
11390   mp->is_ipv6 = ipv6_set;
11391   S;
11392
11393   /* Use a control ping for synchronization */
11394   {
11395     vl_api_control_ping_t *mp;
11396     M (CONTROL_PING, control_ping);
11397     S;
11398   }
11399   W;
11400 }
11401
11402 static int
11403 api_ipsec_spd_add_del (vat_main_t * vam)
11404 {
11405 #if DPDK > 0
11406   unformat_input_t *i = vam->input;
11407   vl_api_ipsec_spd_add_del_t *mp;
11408   f64 timeout;
11409   u32 spd_id = ~0;
11410   u8 is_add = 1;
11411
11412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11413     {
11414       if (unformat (i, "spd_id %d", &spd_id))
11415         ;
11416       else if (unformat (i, "del"))
11417         is_add = 0;
11418       else
11419         {
11420           clib_warning ("parse error '%U'", format_unformat_error, i);
11421           return -99;
11422         }
11423     }
11424   if (spd_id == ~0)
11425     {
11426       errmsg ("spd_id must be set\n");
11427       return -99;
11428     }
11429
11430   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11431
11432   mp->spd_id = ntohl (spd_id);
11433   mp->is_add = is_add;
11434
11435   S;
11436   W;
11437   /* NOTREACHED */
11438   return 0;
11439 #else
11440   clib_warning ("unsupported (no dpdk)");
11441   return -99;
11442 #endif
11443 }
11444
11445 static int
11446 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11447 {
11448 #if DPDK > 0
11449   unformat_input_t *i = vam->input;
11450   vl_api_ipsec_interface_add_del_spd_t *mp;
11451   f64 timeout;
11452   u32 sw_if_index;
11453   u8 sw_if_index_set = 0;
11454   u32 spd_id = (u32) ~ 0;
11455   u8 is_add = 1;
11456
11457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11458     {
11459       if (unformat (i, "del"))
11460         is_add = 0;
11461       else if (unformat (i, "spd_id %d", &spd_id))
11462         ;
11463       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11464         sw_if_index_set = 1;
11465       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11466         sw_if_index_set = 1;
11467       else
11468         {
11469           clib_warning ("parse error '%U'", format_unformat_error, i);
11470           return -99;
11471         }
11472
11473     }
11474
11475   if (spd_id == (u32) ~ 0)
11476     {
11477       errmsg ("spd_id must be set\n");
11478       return -99;
11479     }
11480
11481   if (sw_if_index_set == 0)
11482     {
11483       errmsg ("missing interface name or sw_if_index\n");
11484       return -99;
11485     }
11486
11487   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11488
11489   mp->spd_id = ntohl (spd_id);
11490   mp->sw_if_index = ntohl (sw_if_index);
11491   mp->is_add = is_add;
11492
11493   S;
11494   W;
11495   /* NOTREACHED */
11496   return 0;
11497 #else
11498   clib_warning ("unsupported (no dpdk)");
11499   return -99;
11500 #endif
11501 }
11502
11503 static int
11504 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11505 {
11506 #if DPDK > 0
11507   unformat_input_t *i = vam->input;
11508   vl_api_ipsec_spd_add_del_entry_t *mp;
11509   f64 timeout;
11510   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11511   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11512   i32 priority = 0;
11513   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11514   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11515   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11516   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11517
11518   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11519   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11520   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11521   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11522   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11523   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11524
11525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11526     {
11527       if (unformat (i, "del"))
11528         is_add = 0;
11529       if (unformat (i, "outbound"))
11530         is_outbound = 1;
11531       if (unformat (i, "inbound"))
11532         is_outbound = 0;
11533       else if (unformat (i, "spd_id %d", &spd_id))
11534         ;
11535       else if (unformat (i, "sa_id %d", &sa_id))
11536         ;
11537       else if (unformat (i, "priority %d", &priority))
11538         ;
11539       else if (unformat (i, "protocol %d", &protocol))
11540         ;
11541       else if (unformat (i, "lport_start %d", &lport_start))
11542         ;
11543       else if (unformat (i, "lport_stop %d", &lport_stop))
11544         ;
11545       else if (unformat (i, "rport_start %d", &rport_start))
11546         ;
11547       else if (unformat (i, "rport_stop %d", &rport_stop))
11548         ;
11549       else
11550         if (unformat
11551             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11552         {
11553           is_ipv6 = 0;
11554           is_ip_any = 0;
11555         }
11556       else
11557         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11558         {
11559           is_ipv6 = 0;
11560           is_ip_any = 0;
11561         }
11562       else
11563         if (unformat
11564             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11565         {
11566           is_ipv6 = 0;
11567           is_ip_any = 0;
11568         }
11569       else
11570         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11571         {
11572           is_ipv6 = 0;
11573           is_ip_any = 0;
11574         }
11575       else
11576         if (unformat
11577             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11578         {
11579           is_ipv6 = 1;
11580           is_ip_any = 0;
11581         }
11582       else
11583         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11584         {
11585           is_ipv6 = 1;
11586           is_ip_any = 0;
11587         }
11588       else
11589         if (unformat
11590             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11591         {
11592           is_ipv6 = 1;
11593           is_ip_any = 0;
11594         }
11595       else
11596         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11597         {
11598           is_ipv6 = 1;
11599           is_ip_any = 0;
11600         }
11601       else
11602         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11603         {
11604           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11605             {
11606               clib_warning ("unsupported action: 'resolve'");
11607               return -99;
11608             }
11609         }
11610       else
11611         {
11612           clib_warning ("parse error '%U'", format_unformat_error, i);
11613           return -99;
11614         }
11615
11616     }
11617
11618   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11619
11620   mp->spd_id = ntohl (spd_id);
11621   mp->priority = ntohl (priority);
11622   mp->is_outbound = is_outbound;
11623
11624   mp->is_ipv6 = is_ipv6;
11625   if (is_ipv6 || is_ip_any)
11626     {
11627       clib_memcpy (mp->remote_address_start, &raddr6_start,
11628                    sizeof (ip6_address_t));
11629       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11630                    sizeof (ip6_address_t));
11631       clib_memcpy (mp->local_address_start, &laddr6_start,
11632                    sizeof (ip6_address_t));
11633       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11634                    sizeof (ip6_address_t));
11635     }
11636   else
11637     {
11638       clib_memcpy (mp->remote_address_start, &raddr4_start,
11639                    sizeof (ip4_address_t));
11640       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11641                    sizeof (ip4_address_t));
11642       clib_memcpy (mp->local_address_start, &laddr4_start,
11643                    sizeof (ip4_address_t));
11644       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11645                    sizeof (ip4_address_t));
11646     }
11647   mp->protocol = (u8) protocol;
11648   mp->local_port_start = ntohs ((u16) lport_start);
11649   mp->local_port_stop = ntohs ((u16) lport_stop);
11650   mp->remote_port_start = ntohs ((u16) rport_start);
11651   mp->remote_port_stop = ntohs ((u16) rport_stop);
11652   mp->policy = (u8) policy;
11653   mp->sa_id = ntohl (sa_id);
11654   mp->is_add = is_add;
11655   mp->is_ip_any = is_ip_any;
11656   S;
11657   W;
11658   /* NOTREACHED */
11659   return 0;
11660 #else
11661   clib_warning ("unsupported (no dpdk)");
11662   return -99;
11663 #endif
11664 }
11665
11666 static int
11667 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11668 {
11669 #if DPDK > 0
11670   unformat_input_t *i = vam->input;
11671   vl_api_ipsec_sad_add_del_entry_t *mp;
11672   f64 timeout;
11673   u32 sad_id = 0, spi = 0;
11674   u8 *ck = 0, *ik = 0;
11675   u8 is_add = 1;
11676
11677   u8 protocol = IPSEC_PROTOCOL_AH;
11678   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11679   u32 crypto_alg = 0, integ_alg = 0;
11680   ip4_address_t tun_src4;
11681   ip4_address_t tun_dst4;
11682   ip6_address_t tun_src6;
11683   ip6_address_t tun_dst6;
11684
11685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11686     {
11687       if (unformat (i, "del"))
11688         is_add = 0;
11689       else if (unformat (i, "sad_id %d", &sad_id))
11690         ;
11691       else if (unformat (i, "spi %d", &spi))
11692         ;
11693       else if (unformat (i, "esp"))
11694         protocol = IPSEC_PROTOCOL_ESP;
11695       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11696         {
11697           is_tunnel = 1;
11698           is_tunnel_ipv6 = 0;
11699         }
11700       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11701         {
11702           is_tunnel = 1;
11703           is_tunnel_ipv6 = 0;
11704         }
11705       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11706         {
11707           is_tunnel = 1;
11708           is_tunnel_ipv6 = 1;
11709         }
11710       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11711         {
11712           is_tunnel = 1;
11713           is_tunnel_ipv6 = 1;
11714         }
11715       else
11716         if (unformat
11717             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11718         {
11719           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11720               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11721             {
11722               clib_warning ("unsupported crypto-alg: '%U'",
11723                             format_ipsec_crypto_alg, crypto_alg);
11724               return -99;
11725             }
11726         }
11727       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11728         ;
11729       else
11730         if (unformat
11731             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11732         {
11733           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11734               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11735             {
11736               clib_warning ("unsupported integ-alg: '%U'",
11737                             format_ipsec_integ_alg, integ_alg);
11738               return -99;
11739             }
11740         }
11741       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11742         ;
11743       else
11744         {
11745           clib_warning ("parse error '%U'", format_unformat_error, i);
11746           return -99;
11747         }
11748
11749     }
11750
11751   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11752
11753   mp->sad_id = ntohl (sad_id);
11754   mp->is_add = is_add;
11755   mp->protocol = protocol;
11756   mp->spi = ntohl (spi);
11757   mp->is_tunnel = is_tunnel;
11758   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11759   mp->crypto_algorithm = crypto_alg;
11760   mp->integrity_algorithm = integ_alg;
11761   mp->crypto_key_length = vec_len (ck);
11762   mp->integrity_key_length = vec_len (ik);
11763
11764   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11765     mp->crypto_key_length = sizeof (mp->crypto_key);
11766
11767   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11768     mp->integrity_key_length = sizeof (mp->integrity_key);
11769
11770   if (ck)
11771     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11772   if (ik)
11773     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11774
11775   if (is_tunnel)
11776     {
11777       if (is_tunnel_ipv6)
11778         {
11779           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11780                        sizeof (ip6_address_t));
11781           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11782                        sizeof (ip6_address_t));
11783         }
11784       else
11785         {
11786           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11787                        sizeof (ip4_address_t));
11788           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11789                        sizeof (ip4_address_t));
11790         }
11791     }
11792
11793   S;
11794   W;
11795   /* NOTREACHED */
11796   return 0;
11797 #else
11798   clib_warning ("unsupported (no dpdk)");
11799   return -99;
11800 #endif
11801 }
11802
11803 static int
11804 api_ipsec_sa_set_key (vat_main_t * vam)
11805 {
11806 #if DPDK > 0
11807   unformat_input_t *i = vam->input;
11808   vl_api_ipsec_sa_set_key_t *mp;
11809   f64 timeout;
11810   u32 sa_id;
11811   u8 *ck = 0, *ik = 0;
11812
11813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11814     {
11815       if (unformat (i, "sa_id %d", &sa_id))
11816         ;
11817       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11818         ;
11819       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11820         ;
11821       else
11822         {
11823           clib_warning ("parse error '%U'", format_unformat_error, i);
11824           return -99;
11825         }
11826     }
11827
11828   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11829
11830   mp->sa_id = ntohl (sa_id);
11831   mp->crypto_key_length = vec_len (ck);
11832   mp->integrity_key_length = vec_len (ik);
11833
11834   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11835     mp->crypto_key_length = sizeof (mp->crypto_key);
11836
11837   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11838     mp->integrity_key_length = sizeof (mp->integrity_key);
11839
11840   if (ck)
11841     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11842   if (ik)
11843     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11844
11845   S;
11846   W;
11847   /* NOTREACHED */
11848   return 0;
11849 #else
11850   clib_warning ("unsupported (no dpdk)");
11851   return -99;
11852 #endif
11853 }
11854
11855 static int
11856 api_ikev2_profile_add_del (vat_main_t * vam)
11857 {
11858 #if DPDK > 0
11859   unformat_input_t *i = vam->input;
11860   vl_api_ikev2_profile_add_del_t *mp;
11861   f64 timeout;
11862   u8 is_add = 1;
11863   u8 *name = 0;
11864
11865   const char *valid_chars = "a-zA-Z0-9_";
11866
11867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11868     {
11869       if (unformat (i, "del"))
11870         is_add = 0;
11871       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11872         vec_add1 (name, 0);
11873       else
11874         {
11875           errmsg ("parse error '%U'", format_unformat_error, i);
11876           return -99;
11877         }
11878     }
11879
11880   if (!vec_len (name))
11881     {
11882       errmsg ("profile name must be specified");
11883       return -99;
11884     }
11885
11886   if (vec_len (name) > 64)
11887     {
11888       errmsg ("profile name too long");
11889       return -99;
11890     }
11891
11892   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11893
11894   clib_memcpy (mp->name, name, vec_len (name));
11895   mp->is_add = is_add;
11896   vec_free (name);
11897
11898   S;
11899   W;
11900   /* NOTREACHED */
11901   return 0;
11902 #else
11903   clib_warning ("unsupported (no dpdk)");
11904   return -99;
11905 #endif
11906 }
11907
11908 static int
11909 api_ikev2_profile_set_auth (vat_main_t * vam)
11910 {
11911 #if DPDK > 0
11912   unformat_input_t *i = vam->input;
11913   vl_api_ikev2_profile_set_auth_t *mp;
11914   f64 timeout;
11915   u8 *name = 0;
11916   u8 *data = 0;
11917   u32 auth_method = 0;
11918   u8 is_hex = 0;
11919
11920   const char *valid_chars = "a-zA-Z0-9_";
11921
11922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11923     {
11924       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11925         vec_add1 (name, 0);
11926       else if (unformat (i, "auth_method %U",
11927                          unformat_ikev2_auth_method, &auth_method))
11928         ;
11929       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11930         is_hex = 1;
11931       else if (unformat (i, "auth_data %v", &data))
11932         ;
11933       else
11934         {
11935           errmsg ("parse error '%U'", format_unformat_error, i);
11936           return -99;
11937         }
11938     }
11939
11940   if (!vec_len (name))
11941     {
11942       errmsg ("profile name must be specified");
11943       return -99;
11944     }
11945
11946   if (vec_len (name) > 64)
11947     {
11948       errmsg ("profile name too long");
11949       return -99;
11950     }
11951
11952   if (!vec_len (data))
11953     {
11954       errmsg ("auth_data must be specified");
11955       return -99;
11956     }
11957
11958   if (!auth_method)
11959     {
11960       errmsg ("auth_method must be specified");
11961       return -99;
11962     }
11963
11964   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11965
11966   mp->is_hex = is_hex;
11967   mp->auth_method = (u8) auth_method;
11968   mp->data_len = vec_len (data);
11969   clib_memcpy (mp->name, name, vec_len (name));
11970   clib_memcpy (mp->data, data, vec_len (data));
11971   vec_free (name);
11972   vec_free (data);
11973
11974   S;
11975   W;
11976   /* NOTREACHED */
11977   return 0;
11978 #else
11979   clib_warning ("unsupported (no dpdk)");
11980   return -99;
11981 #endif
11982 }
11983
11984 static int
11985 api_ikev2_profile_set_id (vat_main_t * vam)
11986 {
11987 #if DPDK > 0
11988   unformat_input_t *i = vam->input;
11989   vl_api_ikev2_profile_set_id_t *mp;
11990   f64 timeout;
11991   u8 *name = 0;
11992   u8 *data = 0;
11993   u8 is_local = 0;
11994   u32 id_type = 0;
11995   ip4_address_t ip4;
11996
11997   const char *valid_chars = "a-zA-Z0-9_";
11998
11999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12000     {
12001       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12002         vec_add1 (name, 0);
12003       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12004         ;
12005       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12006         {
12007           data = vec_new (u8, 4);
12008           clib_memcpy (data, ip4.as_u8, 4);
12009         }
12010       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12011         ;
12012       else if (unformat (i, "id_data %v", &data))
12013         ;
12014       else if (unformat (i, "local"))
12015         is_local = 1;
12016       else if (unformat (i, "remote"))
12017         is_local = 0;
12018       else
12019         {
12020           errmsg ("parse error '%U'", format_unformat_error, i);
12021           return -99;
12022         }
12023     }
12024
12025   if (!vec_len (name))
12026     {
12027       errmsg ("profile name must be specified");
12028       return -99;
12029     }
12030
12031   if (vec_len (name) > 64)
12032     {
12033       errmsg ("profile name too long");
12034       return -99;
12035     }
12036
12037   if (!vec_len (data))
12038     {
12039       errmsg ("id_data must be specified");
12040       return -99;
12041     }
12042
12043   if (!id_type)
12044     {
12045       errmsg ("id_type must be specified");
12046       return -99;
12047     }
12048
12049   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12050
12051   mp->is_local = is_local;
12052   mp->id_type = (u8) id_type;
12053   mp->data_len = vec_len (data);
12054   clib_memcpy (mp->name, name, vec_len (name));
12055   clib_memcpy (mp->data, data, vec_len (data));
12056   vec_free (name);
12057   vec_free (data);
12058
12059   S;
12060   W;
12061   /* NOTREACHED */
12062   return 0;
12063 #else
12064   clib_warning ("unsupported (no dpdk)");
12065   return -99;
12066 #endif
12067 }
12068
12069 static int
12070 api_ikev2_profile_set_ts (vat_main_t * vam)
12071 {
12072 #if DPDK > 0
12073   unformat_input_t *i = vam->input;
12074   vl_api_ikev2_profile_set_ts_t *mp;
12075   f64 timeout;
12076   u8 *name = 0;
12077   u8 is_local = 0;
12078   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12079   ip4_address_t start_addr, end_addr;
12080
12081   const char *valid_chars = "a-zA-Z0-9_";
12082
12083   start_addr.as_u32 = 0;
12084   end_addr.as_u32 = (u32) ~ 0;
12085
12086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12087     {
12088       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12089         vec_add1 (name, 0);
12090       else if (unformat (i, "protocol %d", &proto))
12091         ;
12092       else if (unformat (i, "start_port %d", &start_port))
12093         ;
12094       else if (unformat (i, "end_port %d", &end_port))
12095         ;
12096       else
12097         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12098         ;
12099       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12100         ;
12101       else if (unformat (i, "local"))
12102         is_local = 1;
12103       else if (unformat (i, "remote"))
12104         is_local = 0;
12105       else
12106         {
12107           errmsg ("parse error '%U'", format_unformat_error, i);
12108           return -99;
12109         }
12110     }
12111
12112   if (!vec_len (name))
12113     {
12114       errmsg ("profile name must be specified");
12115       return -99;
12116     }
12117
12118   if (vec_len (name) > 64)
12119     {
12120       errmsg ("profile name too long");
12121       return -99;
12122     }
12123
12124   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12125
12126   mp->is_local = is_local;
12127   mp->proto = (u8) proto;
12128   mp->start_port = (u16) start_port;
12129   mp->end_port = (u16) end_port;
12130   mp->start_addr = start_addr.as_u32;
12131   mp->end_addr = end_addr.as_u32;
12132   clib_memcpy (mp->name, name, vec_len (name));
12133   vec_free (name);
12134
12135   S;
12136   W;
12137   /* NOTREACHED */
12138   return 0;
12139 #else
12140   clib_warning ("unsupported (no dpdk)");
12141   return -99;
12142 #endif
12143 }
12144
12145 static int
12146 api_ikev2_set_local_key (vat_main_t * vam)
12147 {
12148 #if DPDK > 0
12149   unformat_input_t *i = vam->input;
12150   vl_api_ikev2_set_local_key_t *mp;
12151   f64 timeout;
12152   u8 *file = 0;
12153
12154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12155     {
12156       if (unformat (i, "file %v", &file))
12157         vec_add1 (file, 0);
12158       else
12159         {
12160           errmsg ("parse error '%U'", format_unformat_error, i);
12161           return -99;
12162         }
12163     }
12164
12165   if (!vec_len (file))
12166     {
12167       errmsg ("RSA key file must be specified");
12168       return -99;
12169     }
12170
12171   if (vec_len (file) > 256)
12172     {
12173       errmsg ("file name too long");
12174       return -99;
12175     }
12176
12177   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12178
12179   clib_memcpy (mp->key_file, file, vec_len (file));
12180   vec_free (file);
12181
12182   S;
12183   W;
12184   /* NOTREACHED */
12185   return 0;
12186 #else
12187   clib_warning ("unsupported (no dpdk)");
12188   return -99;
12189 #endif
12190 }
12191
12192 /*
12193  * MAP
12194  */
12195 static int
12196 api_map_add_domain (vat_main_t * vam)
12197 {
12198   unformat_input_t *i = vam->input;
12199   vl_api_map_add_domain_t *mp;
12200   f64 timeout;
12201
12202   ip4_address_t ip4_prefix;
12203   ip6_address_t ip6_prefix;
12204   ip6_address_t ip6_src;
12205   u32 num_m_args = 0;
12206   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12207     0, psid_length = 0;
12208   u8 is_translation = 0;
12209   u32 mtu = 0;
12210   u32 ip6_src_len = 128;
12211
12212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12213     {
12214       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12215                     &ip4_prefix, &ip4_prefix_len))
12216         num_m_args++;
12217       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12218                          &ip6_prefix, &ip6_prefix_len))
12219         num_m_args++;
12220       else
12221         if (unformat
12222             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12223              &ip6_src_len))
12224         num_m_args++;
12225       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12226         num_m_args++;
12227       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12228         num_m_args++;
12229       else if (unformat (i, "psid-offset %d", &psid_offset))
12230         num_m_args++;
12231       else if (unformat (i, "psid-len %d", &psid_length))
12232         num_m_args++;
12233       else if (unformat (i, "mtu %d", &mtu))
12234         num_m_args++;
12235       else if (unformat (i, "map-t"))
12236         is_translation = 1;
12237       else
12238         {
12239           clib_warning ("parse error '%U'", format_unformat_error, i);
12240           return -99;
12241         }
12242     }
12243
12244   if (num_m_args < 3)
12245     {
12246       errmsg ("mandatory argument(s) missing\n");
12247       return -99;
12248     }
12249
12250   /* Construct the API message */
12251   M (MAP_ADD_DOMAIN, map_add_domain);
12252
12253   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12254   mp->ip4_prefix_len = ip4_prefix_len;
12255
12256   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12257   mp->ip6_prefix_len = ip6_prefix_len;
12258
12259   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12260   mp->ip6_src_prefix_len = ip6_src_len;
12261
12262   mp->ea_bits_len = ea_bits_len;
12263   mp->psid_offset = psid_offset;
12264   mp->psid_length = psid_length;
12265   mp->is_translation = is_translation;
12266   mp->mtu = htons (mtu);
12267
12268   /* send it... */
12269   S;
12270
12271   /* Wait for a reply, return good/bad news  */
12272   W;
12273 }
12274
12275 static int
12276 api_map_del_domain (vat_main_t * vam)
12277 {
12278   unformat_input_t *i = vam->input;
12279   vl_api_map_del_domain_t *mp;
12280   f64 timeout;
12281
12282   u32 num_m_args = 0;
12283   u32 index;
12284
12285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12286     {
12287       if (unformat (i, "index %d", &index))
12288         num_m_args++;
12289       else
12290         {
12291           clib_warning ("parse error '%U'", format_unformat_error, i);
12292           return -99;
12293         }
12294     }
12295
12296   if (num_m_args != 1)
12297     {
12298       errmsg ("mandatory argument(s) missing\n");
12299       return -99;
12300     }
12301
12302   /* Construct the API message */
12303   M (MAP_DEL_DOMAIN, map_del_domain);
12304
12305   mp->index = ntohl (index);
12306
12307   /* send it... */
12308   S;
12309
12310   /* Wait for a reply, return good/bad news  */
12311   W;
12312 }
12313
12314 static int
12315 api_map_add_del_rule (vat_main_t * vam)
12316 {
12317   unformat_input_t *i = vam->input;
12318   vl_api_map_add_del_rule_t *mp;
12319   f64 timeout;
12320   u8 is_add = 1;
12321   ip6_address_t ip6_dst;
12322   u32 num_m_args = 0, index, psid = 0;
12323
12324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12325     {
12326       if (unformat (i, "index %d", &index))
12327         num_m_args++;
12328       else if (unformat (i, "psid %d", &psid))
12329         num_m_args++;
12330       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12331         num_m_args++;
12332       else if (unformat (i, "del"))
12333         {
12334           is_add = 0;
12335         }
12336       else
12337         {
12338           clib_warning ("parse error '%U'", format_unformat_error, i);
12339           return -99;
12340         }
12341     }
12342
12343   /* Construct the API message */
12344   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12345
12346   mp->index = ntohl (index);
12347   mp->is_add = is_add;
12348   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12349   mp->psid = ntohs (psid);
12350
12351   /* send it... */
12352   S;
12353
12354   /* Wait for a reply, return good/bad news  */
12355   W;
12356 }
12357
12358 static int
12359 api_map_domain_dump (vat_main_t * vam)
12360 {
12361   vl_api_map_domain_dump_t *mp;
12362   f64 timeout;
12363
12364   /* Construct the API message */
12365   M (MAP_DOMAIN_DUMP, map_domain_dump);
12366
12367   /* send it... */
12368   S;
12369
12370   /* Use a control ping for synchronization */
12371   {
12372     vl_api_control_ping_t *mp;
12373     M (CONTROL_PING, control_ping);
12374     S;
12375   }
12376   W;
12377 }
12378
12379 static int
12380 api_map_rule_dump (vat_main_t * vam)
12381 {
12382   unformat_input_t *i = vam->input;
12383   vl_api_map_rule_dump_t *mp;
12384   f64 timeout;
12385   u32 domain_index = ~0;
12386
12387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12388     {
12389       if (unformat (i, "index %u", &domain_index))
12390         ;
12391       else
12392         break;
12393     }
12394
12395   if (domain_index == ~0)
12396     {
12397       clib_warning ("parse error: domain index expected");
12398       return -99;
12399     }
12400
12401   /* Construct the API message */
12402   M (MAP_RULE_DUMP, map_rule_dump);
12403
12404   mp->domain_index = htonl (domain_index);
12405
12406   /* send it... */
12407   S;
12408
12409   /* Use a control ping for synchronization */
12410   {
12411     vl_api_control_ping_t *mp;
12412     M (CONTROL_PING, control_ping);
12413     S;
12414   }
12415   W;
12416 }
12417
12418 static void vl_api_map_add_domain_reply_t_handler
12419   (vl_api_map_add_domain_reply_t * mp)
12420 {
12421   vat_main_t *vam = &vat_main;
12422   i32 retval = ntohl (mp->retval);
12423
12424   if (vam->async_mode)
12425     {
12426       vam->async_errors += (retval < 0);
12427     }
12428   else
12429     {
12430       vam->retval = retval;
12431       vam->result_ready = 1;
12432     }
12433 }
12434
12435 static void vl_api_map_add_domain_reply_t_handler_json
12436   (vl_api_map_add_domain_reply_t * mp)
12437 {
12438   vat_main_t *vam = &vat_main;
12439   vat_json_node_t node;
12440
12441   vat_json_init_object (&node);
12442   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12443   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12444
12445   vat_json_print (vam->ofp, &node);
12446   vat_json_free (&node);
12447
12448   vam->retval = ntohl (mp->retval);
12449   vam->result_ready = 1;
12450 }
12451
12452 static int
12453 api_get_first_msg_id (vat_main_t * vam)
12454 {
12455   vl_api_get_first_msg_id_t *mp;
12456   f64 timeout;
12457   unformat_input_t *i = vam->input;
12458   u8 *name;
12459   u8 name_set = 0;
12460
12461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12462     {
12463       if (unformat (i, "client %s", &name))
12464         name_set = 1;
12465       else
12466         break;
12467     }
12468
12469   if (name_set == 0)
12470     {
12471       errmsg ("missing client name\n");
12472       return -99;
12473     }
12474   vec_add1 (name, 0);
12475
12476   if (vec_len (name) > 63)
12477     {
12478       errmsg ("client name too long\n");
12479       return -99;
12480     }
12481
12482   M (GET_FIRST_MSG_ID, get_first_msg_id);
12483   clib_memcpy (mp->name, name, vec_len (name));
12484   S;
12485   W;
12486   /* NOTREACHED */
12487   return 0;
12488 }
12489
12490 static int
12491 api_cop_interface_enable_disable (vat_main_t * vam)
12492 {
12493   unformat_input_t *line_input = vam->input;
12494   vl_api_cop_interface_enable_disable_t *mp;
12495   f64 timeout;
12496   u32 sw_if_index = ~0;
12497   u8 enable_disable = 1;
12498
12499   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12500     {
12501       if (unformat (line_input, "disable"))
12502         enable_disable = 0;
12503       if (unformat (line_input, "enable"))
12504         enable_disable = 1;
12505       else if (unformat (line_input, "%U", unformat_sw_if_index,
12506                          vam, &sw_if_index))
12507         ;
12508       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12509         ;
12510       else
12511         break;
12512     }
12513
12514   if (sw_if_index == ~0)
12515     {
12516       errmsg ("missing interface name or sw_if_index\n");
12517       return -99;
12518     }
12519
12520   /* Construct the API message */
12521   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12522   mp->sw_if_index = ntohl (sw_if_index);
12523   mp->enable_disable = enable_disable;
12524
12525   /* send it... */
12526   S;
12527   /* Wait for the reply */
12528   W;
12529 }
12530
12531 static int
12532 api_cop_whitelist_enable_disable (vat_main_t * vam)
12533 {
12534   unformat_input_t *line_input = vam->input;
12535   vl_api_cop_whitelist_enable_disable_t *mp;
12536   f64 timeout;
12537   u32 sw_if_index = ~0;
12538   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12539   u32 fib_id = 0;
12540
12541   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12542     {
12543       if (unformat (line_input, "ip4"))
12544         ip4 = 1;
12545       else if (unformat (line_input, "ip6"))
12546         ip6 = 1;
12547       else if (unformat (line_input, "default"))
12548         default_cop = 1;
12549       else if (unformat (line_input, "%U", unformat_sw_if_index,
12550                          vam, &sw_if_index))
12551         ;
12552       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12553         ;
12554       else if (unformat (line_input, "fib-id %d", &fib_id))
12555         ;
12556       else
12557         break;
12558     }
12559
12560   if (sw_if_index == ~0)
12561     {
12562       errmsg ("missing interface name or sw_if_index\n");
12563       return -99;
12564     }
12565
12566   /* Construct the API message */
12567   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12568   mp->sw_if_index = ntohl (sw_if_index);
12569   mp->fib_id = ntohl (fib_id);
12570   mp->ip4 = ip4;
12571   mp->ip6 = ip6;
12572   mp->default_cop = default_cop;
12573
12574   /* send it... */
12575   S;
12576   /* Wait for the reply */
12577   W;
12578 }
12579
12580 static int
12581 api_get_node_graph (vat_main_t * vam)
12582 {
12583   vl_api_get_node_graph_t *mp;
12584   f64 timeout;
12585
12586   M (GET_NODE_GRAPH, get_node_graph);
12587
12588   /* send it... */
12589   S;
12590   /* Wait for the reply */
12591   W;
12592 }
12593
12594 /* *INDENT-OFF* */
12595 /** Used for parsing LISP eids */
12596 typedef CLIB_PACKED(struct{
12597   u8 addr[16];   /**< eid address */
12598   u32 len;       /**< prefix length if IP */
12599   u8 type;      /**< type of eid */
12600 }) lisp_eid_vat_t;
12601 /* *INDENT-ON* */
12602
12603 static uword
12604 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12605 {
12606   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12607
12608   memset (a, 0, sizeof (a[0]));
12609
12610   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12611     {
12612       a->type = 0;              /* ipv4 type */
12613     }
12614   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12615     {
12616       a->type = 1;              /* ipv6 type */
12617     }
12618   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12619     {
12620       a->type = 2;              /* mac type */
12621     }
12622   else
12623     {
12624       return 0;
12625     }
12626
12627   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12628     {
12629       return 0;
12630     }
12631
12632   return 1;
12633 }
12634
12635 static int
12636 lisp_eid_size_vat (u8 type)
12637 {
12638   switch (type)
12639     {
12640     case 0:
12641       return 4;
12642     case 1:
12643       return 16;
12644     case 2:
12645       return 6;
12646     }
12647   return 0;
12648 }
12649
12650 static void
12651 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12652 {
12653   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12654 }
12655
12656 /* *INDENT-OFF* */
12657 /** Used for transferring locators via VPP API */
12658 typedef CLIB_PACKED(struct
12659 {
12660   u32 sw_if_index; /**< locator sw_if_index */
12661   u8 priority; /**< locator priority */
12662   u8 weight;   /**< locator weight */
12663 }) ls_locator_t;
12664 /* *INDENT-ON* */
12665
12666 static int
12667 api_lisp_add_del_locator_set (vat_main_t * vam)
12668 {
12669   unformat_input_t *input = vam->input;
12670   vl_api_lisp_add_del_locator_set_t *mp;
12671   f64 timeout = ~0;
12672   u8 is_add = 1;
12673   u8 *locator_set_name = NULL;
12674   u8 locator_set_name_set = 0;
12675   ls_locator_t locator, *locators = 0;
12676   u32 sw_if_index, priority, weight;
12677   u32 data_len = 0;
12678
12679   /* Parse args required to build the message */
12680   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12681     {
12682       if (unformat (input, "del"))
12683         {
12684           is_add = 0;
12685         }
12686       else if (unformat (input, "locator-set %s", &locator_set_name))
12687         {
12688           locator_set_name_set = 1;
12689         }
12690       else if (unformat (input, "sw_if_index %u p %u w %u",
12691                          &sw_if_index, &priority, &weight))
12692         {
12693           locator.sw_if_index = htonl (sw_if_index);
12694           locator.priority = priority;
12695           locator.weight = weight;
12696           vec_add1 (locators, locator);
12697         }
12698       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12699                          vam, &sw_if_index, &priority, &weight))
12700         {
12701           locator.sw_if_index = htonl (sw_if_index);
12702           locator.priority = priority;
12703           locator.weight = weight;
12704           vec_add1 (locators, locator);
12705         }
12706       else
12707         break;
12708     }
12709
12710   if (locator_set_name_set == 0)
12711     {
12712       errmsg ("missing locator-set name");
12713       vec_free (locators);
12714       return -99;
12715     }
12716
12717   if (vec_len (locator_set_name) > 64)
12718     {
12719       errmsg ("locator-set name too long\n");
12720       vec_free (locator_set_name);
12721       vec_free (locators);
12722       return -99;
12723     }
12724   vec_add1 (locator_set_name, 0);
12725
12726   data_len = sizeof (ls_locator_t) * vec_len (locators);
12727
12728   /* Construct the API message */
12729   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12730
12731   mp->is_add = is_add;
12732   clib_memcpy (mp->locator_set_name, locator_set_name,
12733                vec_len (locator_set_name));
12734   vec_free (locator_set_name);
12735
12736   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12737   if (locators)
12738     clib_memcpy (mp->locators, locators, data_len);
12739   vec_free (locators);
12740
12741   /* send it... */
12742   S;
12743
12744   /* Wait for a reply... */
12745   W;
12746
12747   /* NOTREACHED */
12748   return 0;
12749 }
12750
12751 static int
12752 api_lisp_add_del_locator (vat_main_t * vam)
12753 {
12754   unformat_input_t *input = vam->input;
12755   vl_api_lisp_add_del_locator_t *mp;
12756   f64 timeout = ~0;
12757   u32 tmp_if_index = ~0;
12758   u32 sw_if_index = ~0;
12759   u8 sw_if_index_set = 0;
12760   u8 sw_if_index_if_name_set = 0;
12761   u32 priority = ~0;
12762   u8 priority_set = 0;
12763   u32 weight = ~0;
12764   u8 weight_set = 0;
12765   u8 is_add = 1;
12766   u8 *locator_set_name = NULL;
12767   u8 locator_set_name_set = 0;
12768
12769   /* Parse args required to build the message */
12770   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12771     {
12772       if (unformat (input, "del"))
12773         {
12774           is_add = 0;
12775         }
12776       else if (unformat (input, "locator-set %s", &locator_set_name))
12777         {
12778           locator_set_name_set = 1;
12779         }
12780       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12781                          &tmp_if_index))
12782         {
12783           sw_if_index_if_name_set = 1;
12784           sw_if_index = tmp_if_index;
12785         }
12786       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12787         {
12788           sw_if_index_set = 1;
12789           sw_if_index = tmp_if_index;
12790         }
12791       else if (unformat (input, "p %d", &priority))
12792         {
12793           priority_set = 1;
12794         }
12795       else if (unformat (input, "w %d", &weight))
12796         {
12797           weight_set = 1;
12798         }
12799       else
12800         break;
12801     }
12802
12803   if (locator_set_name_set == 0)
12804     {
12805       errmsg ("missing locator-set name");
12806       return -99;
12807     }
12808
12809   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12810     {
12811       errmsg ("missing sw_if_index");
12812       vec_free (locator_set_name);
12813       return -99;
12814     }
12815
12816   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12817     {
12818       errmsg ("cannot use both params interface name and sw_if_index");
12819       vec_free (locator_set_name);
12820       return -99;
12821     }
12822
12823   if (priority_set == 0)
12824     {
12825       errmsg ("missing locator-set priority\n");
12826       vec_free (locator_set_name);
12827       return -99;
12828     }
12829
12830   if (weight_set == 0)
12831     {
12832       errmsg ("missing locator-set weight\n");
12833       vec_free (locator_set_name);
12834       return -99;
12835     }
12836
12837   if (vec_len (locator_set_name) > 64)
12838     {
12839       errmsg ("locator-set name too long\n");
12840       vec_free (locator_set_name);
12841       return -99;
12842     }
12843   vec_add1 (locator_set_name, 0);
12844
12845   /* Construct the API message */
12846   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12847
12848   mp->is_add = is_add;
12849   mp->sw_if_index = ntohl (sw_if_index);
12850   mp->priority = priority;
12851   mp->weight = weight;
12852   clib_memcpy (mp->locator_set_name, locator_set_name,
12853                vec_len (locator_set_name));
12854   vec_free (locator_set_name);
12855
12856   /* send it... */
12857   S;
12858
12859   /* Wait for a reply... */
12860   W;
12861
12862   /* NOTREACHED */
12863   return 0;
12864 }
12865
12866 static int
12867 api_lisp_add_del_local_eid (vat_main_t * vam)
12868 {
12869   unformat_input_t *input = vam->input;
12870   vl_api_lisp_add_del_local_eid_t *mp;
12871   f64 timeout = ~0;
12872   u8 is_add = 1;
12873   u8 eid_set = 0;
12874   lisp_eid_vat_t _eid, *eid = &_eid;
12875   u8 *locator_set_name = 0;
12876   u8 locator_set_name_set = 0;
12877   u32 vni = 0;
12878
12879   /* Parse args required to build the message */
12880   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12881     {
12882       if (unformat (input, "del"))
12883         {
12884           is_add = 0;
12885         }
12886       else if (unformat (input, "vni %d", &vni))
12887         {
12888           ;
12889         }
12890       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12891         {
12892           eid_set = 1;
12893         }
12894       else if (unformat (input, "locator-set %s", &locator_set_name))
12895         {
12896           locator_set_name_set = 1;
12897         }
12898       else
12899         break;
12900     }
12901
12902   if (locator_set_name_set == 0)
12903     {
12904       errmsg ("missing locator-set name\n");
12905       return -99;
12906     }
12907
12908   if (0 == eid_set)
12909     {
12910       errmsg ("EID address not set!");
12911       vec_free (locator_set_name);
12912       return -99;
12913     }
12914
12915   if (vec_len (locator_set_name) > 64)
12916     {
12917       errmsg ("locator-set name too long\n");
12918       vec_free (locator_set_name);
12919       return -99;
12920     }
12921   vec_add1 (locator_set_name, 0);
12922
12923   /* Construct the API message */
12924   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12925
12926   mp->is_add = is_add;
12927   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12928   mp->eid_type = eid->type;
12929   mp->prefix_len = eid->len;
12930   mp->vni = clib_host_to_net_u32 (vni);
12931   clib_memcpy (mp->locator_set_name, locator_set_name,
12932                vec_len (locator_set_name));
12933
12934   vec_free (locator_set_name);
12935
12936   /* send it... */
12937   S;
12938
12939   /* Wait for a reply... */
12940   W;
12941
12942   /* NOTREACHED */
12943   return 0;
12944 }
12945
12946 /* *INDENT-OFF* */
12947 /** Used for transferring locators via VPP API */
12948 typedef CLIB_PACKED(struct
12949 {
12950   u8 is_ip4; /**< is locator an IPv4 address? */
12951   u8 priority; /**< locator priority */
12952   u8 weight;   /**< locator weight */
12953   u8 addr[16]; /**< IPv4/IPv6 address */
12954 }) rloc_t;
12955 /* *INDENT-ON* */
12956
12957 static int
12958 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12959 {
12960   unformat_input_t *input = vam->input;
12961   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12962   f64 timeout = ~0;
12963   u8 is_add = 1;
12964   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12965   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12966   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12967   u32 action = ~0, p, w;
12968   ip4_address_t rmt_rloc4, lcl_rloc4;
12969   ip6_address_t rmt_rloc6, lcl_rloc6;
12970   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12971
12972   memset (&rloc, 0, sizeof (rloc));
12973
12974   /* Parse args required to build the message */
12975   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12976     {
12977       if (unformat (input, "del"))
12978         {
12979           is_add = 0;
12980         }
12981       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12982         {
12983           rmt_eid_set = 1;
12984         }
12985       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12986         {
12987           lcl_eid_set = 1;
12988         }
12989       else if (unformat (input, "p %d w %d", &p, &w))
12990         {
12991           if (!curr_rloc)
12992             {
12993               errmsg ("No RLOC configured for setting priority/weight!");
12994               return -99;
12995             }
12996           curr_rloc->priority = p;
12997           curr_rloc->weight = w;
12998         }
12999       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13000                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13001         {
13002           rloc.is_ip4 = 1;
13003
13004           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13005           rloc.priority = rloc.weight = 0;
13006           vec_add1 (lcl_locs, rloc);
13007
13008           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13009           vec_add1 (rmt_locs, rloc);
13010           /* priority and weight saved in rmt loc */
13011           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13012         }
13013       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13014                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13015         {
13016           rloc.is_ip4 = 0;
13017           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13018           rloc.priority = rloc.weight = 0;
13019           vec_add1 (lcl_locs, rloc);
13020
13021           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13022           vec_add1 (rmt_locs, rloc);
13023           /* priority and weight saved in rmt loc */
13024           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13025         }
13026       else if (unformat (input, "action %d", &action))
13027         {
13028           ;
13029         }
13030       else
13031         {
13032           clib_warning ("parse error '%U'", format_unformat_error, input);
13033           return -99;
13034         }
13035     }
13036
13037   if (!rmt_eid_set)
13038     {
13039       errmsg ("remote eid addresses not set\n");
13040       return -99;
13041     }
13042
13043   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13044     {
13045       errmsg ("eid types don't match\n");
13046       return -99;
13047     }
13048
13049   if (0 == rmt_locs && (u32) ~ 0 == action)
13050     {
13051       errmsg ("action not set for negative mapping\n");
13052       return -99;
13053     }
13054
13055   /* Construct the API message */
13056   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13057
13058   mp->is_add = is_add;
13059   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13060   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13061   mp->eid_type = rmt_eid->type;
13062   mp->rmt_len = rmt_eid->len;
13063   mp->lcl_len = lcl_eid->len;
13064   mp->action = action;
13065
13066   if (0 != rmt_locs && 0 != lcl_locs)
13067     {
13068       mp->loc_num = vec_len (rmt_locs);
13069       clib_memcpy (mp->lcl_locs, lcl_locs,
13070                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13071       clib_memcpy (mp->rmt_locs, rmt_locs,
13072                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13073     }
13074   vec_free (lcl_locs);
13075   vec_free (rmt_locs);
13076
13077   /* send it... */
13078   S;
13079
13080   /* Wait for a reply... */
13081   W;
13082
13083   /* NOTREACHED */
13084   return 0;
13085 }
13086
13087 static int
13088 api_lisp_add_del_map_resolver (vat_main_t * vam)
13089 {
13090   unformat_input_t *input = vam->input;
13091   vl_api_lisp_add_del_map_resolver_t *mp;
13092   f64 timeout = ~0;
13093   u8 is_add = 1;
13094   u8 ipv4_set = 0;
13095   u8 ipv6_set = 0;
13096   ip4_address_t ipv4;
13097   ip6_address_t ipv6;
13098
13099   /* Parse args required to build the message */
13100   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13101     {
13102       if (unformat (input, "del"))
13103         {
13104           is_add = 0;
13105         }
13106       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13107         {
13108           ipv4_set = 1;
13109         }
13110       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13111         {
13112           ipv6_set = 1;
13113         }
13114       else
13115         break;
13116     }
13117
13118   if (ipv4_set && ipv6_set)
13119     {
13120       errmsg ("both eid v4 and v6 addresses set\n");
13121       return -99;
13122     }
13123
13124   if (!ipv4_set && !ipv6_set)
13125     {
13126       errmsg ("eid addresses not set\n");
13127       return -99;
13128     }
13129
13130   /* Construct the API message */
13131   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13132
13133   mp->is_add = is_add;
13134   if (ipv6_set)
13135     {
13136       mp->is_ipv6 = 1;
13137       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13138     }
13139   else
13140     {
13141       mp->is_ipv6 = 0;
13142       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13143     }
13144
13145   /* send it... */
13146   S;
13147
13148   /* Wait for a reply... */
13149   W;
13150
13151   /* NOTREACHED */
13152   return 0;
13153 }
13154
13155 static int
13156 api_lisp_gpe_enable_disable (vat_main_t * vam)
13157 {
13158   unformat_input_t *input = vam->input;
13159   vl_api_lisp_gpe_enable_disable_t *mp;
13160   f64 timeout = ~0;
13161   u8 is_set = 0;
13162   u8 is_en = 1;
13163
13164   /* Parse args required to build the message */
13165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13166     {
13167       if (unformat (input, "enable"))
13168         {
13169           is_set = 1;
13170           is_en = 1;
13171         }
13172       else if (unformat (input, "disable"))
13173         {
13174           is_set = 1;
13175           is_en = 0;
13176         }
13177       else
13178         break;
13179     }
13180
13181   if (is_set == 0)
13182     {
13183       errmsg ("Value not set\n");
13184       return -99;
13185     }
13186
13187   /* Construct the API message */
13188   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13189
13190   mp->is_en = is_en;
13191
13192   /* send it... */
13193   S;
13194
13195   /* Wait for a reply... */
13196   W;
13197
13198   /* NOTREACHED */
13199   return 0;
13200 }
13201
13202 static int
13203 api_lisp_enable_disable (vat_main_t * vam)
13204 {
13205   unformat_input_t *input = vam->input;
13206   vl_api_lisp_enable_disable_t *mp;
13207   f64 timeout = ~0;
13208   u8 is_set = 0;
13209   u8 is_en = 0;
13210
13211   /* Parse args required to build the message */
13212   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13213     {
13214       if (unformat (input, "enable"))
13215         {
13216           is_set = 1;
13217           is_en = 1;
13218         }
13219       else if (unformat (input, "disable"))
13220         {
13221           is_set = 1;
13222         }
13223       else
13224         break;
13225     }
13226
13227   if (!is_set)
13228     {
13229       errmsg ("Value not set\n");
13230       return -99;
13231     }
13232
13233   /* Construct the API message */
13234   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13235
13236   mp->is_en = is_en;
13237
13238   /* send it... */
13239   S;
13240
13241   /* Wait for a reply... */
13242   W;
13243
13244   /* NOTREACHED */
13245   return 0;
13246 }
13247
13248 static int
13249 api_show_lisp_map_request_mode (vat_main_t * vam)
13250 {
13251   f64 timeout = ~0;
13252   vl_api_show_lisp_map_request_mode_t *mp;
13253
13254   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13255
13256   /* send */
13257   S;
13258
13259   /* wait for reply */
13260   W;
13261
13262   return 0;
13263 }
13264
13265 static int
13266 api_lisp_map_request_mode (vat_main_t * vam)
13267 {
13268   f64 timeout = ~0;
13269   unformat_input_t *input = vam->input;
13270   vl_api_lisp_map_request_mode_t *mp;
13271   u8 mode = 0;
13272
13273   /* Parse args required to build the message */
13274   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13275     {
13276       if (unformat (input, "dst-only"))
13277         mode = 0;
13278       else if (unformat (input, "src-dst"))
13279         mode = 1;
13280       else
13281         {
13282           errmsg ("parse error '%U'", format_unformat_error, input);
13283           return -99;
13284         }
13285     }
13286
13287   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13288
13289   mp->mode = mode;
13290
13291   /* send */
13292   S;
13293
13294   /* wait for reply */
13295   W;
13296
13297   /* notreached */
13298   return 0;
13299 }
13300
13301 /**
13302  * Enable/disable LISP proxy ITR.
13303  *
13304  * @param vam vpp API test context
13305  * @return return code
13306  */
13307 static int
13308 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13309 {
13310   f64 timeout = ~0;
13311   u8 ls_name_set = 0;
13312   unformat_input_t *input = vam->input;
13313   vl_api_lisp_pitr_set_locator_set_t *mp;
13314   u8 is_add = 1;
13315   u8 *ls_name = 0;
13316
13317   /* Parse args required to build the message */
13318   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13319     {
13320       if (unformat (input, "del"))
13321         is_add = 0;
13322       else if (unformat (input, "locator-set %s", &ls_name))
13323         ls_name_set = 1;
13324       else
13325         {
13326           errmsg ("parse error '%U'", format_unformat_error, input);
13327           return -99;
13328         }
13329     }
13330
13331   if (!ls_name_set)
13332     {
13333       errmsg ("locator-set name not set!");
13334       return -99;
13335     }
13336
13337   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13338
13339   mp->is_add = is_add;
13340   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13341   vec_free (ls_name);
13342
13343   /* send */
13344   S;
13345
13346   /* wait for reply */
13347   W;
13348
13349   /* notreached */
13350   return 0;
13351 }
13352
13353 static int
13354 api_show_lisp_pitr (vat_main_t * vam)
13355 {
13356   vl_api_show_lisp_pitr_t *mp;
13357   f64 timeout = ~0;
13358
13359   if (!vam->json_output)
13360     {
13361       fformat (vam->ofp, "%=20s\n", "lisp status:");
13362     }
13363
13364   M (SHOW_LISP_PITR, show_lisp_pitr);
13365   /* send it... */
13366   S;
13367
13368   /* Wait for a reply... */
13369   W;
13370
13371   /* NOTREACHED */
13372   return 0;
13373 }
13374
13375 /**
13376  * Add/delete mapping between vni and vrf
13377  */
13378 static int
13379 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13380 {
13381   f64 timeout = ~0;
13382   unformat_input_t *input = vam->input;
13383   vl_api_lisp_eid_table_add_del_map_t *mp;
13384   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13385   u32 vni, vrf, bd_index;
13386
13387   /* Parse args required to build the message */
13388   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13389     {
13390       if (unformat (input, "del"))
13391         is_add = 0;
13392       else if (unformat (input, "vrf %d", &vrf))
13393         vrf_set = 1;
13394       else if (unformat (input, "bd_index %d", &bd_index))
13395         bd_index_set = 1;
13396       else if (unformat (input, "vni %d", &vni))
13397         vni_set = 1;
13398       else
13399         break;
13400     }
13401
13402   if (!vni_set || (!vrf_set && !bd_index_set))
13403     {
13404       errmsg ("missing arguments!");
13405       return -99;
13406     }
13407
13408   if (vrf_set && bd_index_set)
13409     {
13410       errmsg ("error: both vrf and bd entered!");
13411       return -99;
13412     }
13413
13414   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13415
13416   mp->is_add = is_add;
13417   mp->vni = htonl (vni);
13418   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13419   mp->is_l2 = bd_index_set;
13420
13421   /* send */
13422   S;
13423
13424   /* wait for reply */
13425   W;
13426
13427   /* notreached */
13428   return 0;
13429 }
13430
13431 uword
13432 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13433 {
13434   u32 *action = va_arg (*args, u32 *);
13435   u8 *s = 0;
13436
13437   if (unformat (input, "%s", &s))
13438     {
13439       if (!strcmp ((char *) s, "no-action"))
13440         action[0] = 0;
13441       else if (!strcmp ((char *) s, "natively-forward"))
13442         action[0] = 1;
13443       else if (!strcmp ((char *) s, "send-map-request"))
13444         action[0] = 2;
13445       else if (!strcmp ((char *) s, "drop"))
13446         action[0] = 3;
13447       else
13448         {
13449           clib_warning ("invalid action: '%s'", s);
13450           action[0] = 3;
13451         }
13452     }
13453   else
13454     return 0;
13455
13456   vec_free (s);
13457   return 1;
13458 }
13459
13460 /**
13461  * Add/del remote mapping to/from LISP control plane
13462  *
13463  * @param vam vpp API test context
13464  * @return return code
13465  */
13466 static int
13467 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13468 {
13469   unformat_input_t *input = vam->input;
13470   vl_api_lisp_add_del_remote_mapping_t *mp;
13471   f64 timeout = ~0;
13472   u32 vni = 0;
13473   lisp_eid_vat_t _eid, *eid = &_eid;
13474   lisp_eid_vat_t _seid, *seid = &_seid;
13475   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13476   u32 action = ~0, p, w, data_len;
13477   ip4_address_t rloc4;
13478   ip6_address_t rloc6;
13479   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13480
13481   memset (&rloc, 0, sizeof (rloc));
13482
13483   /* Parse args required to build the message */
13484   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13485     {
13486       if (unformat (input, "del-all"))
13487         {
13488           del_all = 1;
13489         }
13490       else if (unformat (input, "del"))
13491         {
13492           is_add = 0;
13493         }
13494       else if (unformat (input, "add"))
13495         {
13496           is_add = 1;
13497         }
13498       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13499         {
13500           eid_set = 1;
13501         }
13502       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13503         {
13504           seid_set = 1;
13505         }
13506       else if (unformat (input, "vni %d", &vni))
13507         {
13508           ;
13509         }
13510       else if (unformat (input, "p %d w %d", &p, &w))
13511         {
13512           if (!curr_rloc)
13513             {
13514               errmsg ("No RLOC configured for setting priority/weight!");
13515               return -99;
13516             }
13517           curr_rloc->priority = p;
13518           curr_rloc->weight = w;
13519         }
13520       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13521         {
13522           rloc.is_ip4 = 1;
13523           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13524           vec_add1 (rlocs, rloc);
13525           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13526         }
13527       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13528         {
13529           rloc.is_ip4 = 0;
13530           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13531           vec_add1 (rlocs, rloc);
13532           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13533         }
13534       else if (unformat (input, "action %U",
13535                          unformat_negative_mapping_action, &action))
13536         {
13537           ;
13538         }
13539       else
13540         {
13541           clib_warning ("parse error '%U'", format_unformat_error, input);
13542           return -99;
13543         }
13544     }
13545
13546   if (0 == eid_set)
13547     {
13548       errmsg ("missing params!");
13549       return -99;
13550     }
13551
13552   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13553     {
13554       errmsg ("no action set for negative map-reply!");
13555       return -99;
13556     }
13557
13558   data_len = vec_len (rlocs) * sizeof (rloc_t);
13559
13560   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13561   mp->is_add = is_add;
13562   mp->vni = htonl (vni);
13563   mp->action = (u8) action;
13564   mp->is_src_dst = seid_set;
13565   mp->eid_len = eid->len;
13566   mp->seid_len = seid->len;
13567   mp->del_all = del_all;
13568   mp->eid_type = eid->type;
13569   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13570   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13571
13572   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13573   clib_memcpy (mp->rlocs, rlocs, data_len);
13574   vec_free (rlocs);
13575
13576   /* send it... */
13577   S;
13578
13579   /* Wait for a reply... */
13580   W;
13581
13582   /* NOTREACHED */
13583   return 0;
13584 }
13585
13586 /**
13587  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13588  * forwarding entries in data-plane accordingly.
13589  *
13590  * @param vam vpp API test context
13591  * @return return code
13592  */
13593 static int
13594 api_lisp_add_del_adjacency (vat_main_t * vam)
13595 {
13596   unformat_input_t *input = vam->input;
13597   vl_api_lisp_add_del_adjacency_t *mp;
13598   f64 timeout = ~0;
13599   u32 vni = 0;
13600   ip4_address_t leid4, reid4;
13601   ip6_address_t leid6, reid6;
13602   u8 reid_mac[6] = { 0 };
13603   u8 leid_mac[6] = { 0 };
13604   u8 reid_type, leid_type;
13605   u32 leid_len = 0, reid_len = 0, len;
13606   u8 is_add = 1;
13607
13608   leid_type = reid_type = (u8) ~ 0;
13609
13610   /* Parse args required to build the message */
13611   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13612     {
13613       if (unformat (input, "del"))
13614         {
13615           is_add = 0;
13616         }
13617       else if (unformat (input, "add"))
13618         {
13619           is_add = 1;
13620         }
13621       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13622                          &reid4, &len))
13623         {
13624           reid_type = 0;        /* ipv4 */
13625           reid_len = len;
13626         }
13627       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13628                          &reid6, &len))
13629         {
13630           reid_type = 1;        /* ipv6 */
13631           reid_len = len;
13632         }
13633       else if (unformat (input, "reid %U", unformat_ethernet_address,
13634                          reid_mac))
13635         {
13636           reid_type = 2;        /* mac */
13637         }
13638       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13639                          &leid4, &len))
13640         {
13641           leid_type = 0;        /* ipv4 */
13642           leid_len = len;
13643         }
13644       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13645                          &leid6, &len))
13646         {
13647           leid_type = 1;        /* ipv6 */
13648           leid_len = len;
13649         }
13650       else if (unformat (input, "leid %U", unformat_ethernet_address,
13651                          leid_mac))
13652         {
13653           leid_type = 2;        /* mac */
13654         }
13655       else if (unformat (input, "vni %d", &vni))
13656         {
13657           ;
13658         }
13659       else
13660         {
13661           errmsg ("parse error '%U'", format_unformat_error, input);
13662           return -99;
13663         }
13664     }
13665
13666   if ((u8) ~ 0 == reid_type)
13667     {
13668       errmsg ("missing params!");
13669       return -99;
13670     }
13671
13672   if (leid_type != reid_type)
13673     {
13674       errmsg ("remote and local EIDs are of different types!");
13675       return -99;
13676     }
13677
13678   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13679   mp->is_add = is_add;
13680   mp->vni = htonl (vni);
13681   mp->leid_len = leid_len;
13682   mp->reid_len = reid_len;
13683   mp->eid_type = reid_type;
13684
13685   switch (mp->eid_type)
13686     {
13687     case 0:
13688       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13689       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13690       break;
13691     case 1:
13692       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13693       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13694       break;
13695     case 2:
13696       clib_memcpy (mp->leid, leid_mac, 6);
13697       clib_memcpy (mp->reid, reid_mac, 6);
13698       break;
13699     default:
13700       errmsg ("unknown EID type %d!", mp->eid_type);
13701       return 0;
13702     }
13703
13704   /* send it... */
13705   S;
13706
13707   /* Wait for a reply... */
13708   W;
13709
13710   /* NOTREACHED */
13711   return 0;
13712 }
13713
13714 static int
13715 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13716 {
13717   unformat_input_t *input = vam->input;
13718   vl_api_lisp_gpe_add_del_iface_t *mp;
13719   f64 timeout = ~0;
13720   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13721   u32 dp_table = 0, vni = 0;
13722
13723   /* Parse args required to build the message */
13724   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13725     {
13726       if (unformat (input, "up"))
13727         {
13728           action_set = 1;
13729           is_add = 1;
13730         }
13731       else if (unformat (input, "down"))
13732         {
13733           action_set = 1;
13734           is_add = 0;
13735         }
13736       else if (unformat (input, "table_id %d", &dp_table))
13737         {
13738           dp_table_set = 1;
13739         }
13740       else if (unformat (input, "bd_id %d", &dp_table))
13741         {
13742           dp_table_set = 1;
13743           is_l2 = 1;
13744         }
13745       else if (unformat (input, "vni %d", &vni))
13746         {
13747           vni_set = 1;
13748         }
13749       else
13750         break;
13751     }
13752
13753   if (action_set == 0)
13754     {
13755       errmsg ("Action not set\n");
13756       return -99;
13757     }
13758   if (dp_table_set == 0 || vni_set == 0)
13759     {
13760       errmsg ("vni and dp_table must be set\n");
13761       return -99;
13762     }
13763
13764   /* Construct the API message */
13765   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13766
13767   mp->is_add = is_add;
13768   mp->dp_table = dp_table;
13769   mp->is_l2 = is_l2;
13770   mp->vni = vni;
13771
13772   /* send it... */
13773   S;
13774
13775   /* Wait for a reply... */
13776   W;
13777
13778   /* NOTREACHED */
13779   return 0;
13780 }
13781
13782 /**
13783  * Add/del map request itr rlocs from LISP control plane and updates
13784  *
13785  * @param vam vpp API test context
13786  * @return return code
13787  */
13788 static int
13789 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13790 {
13791   unformat_input_t *input = vam->input;
13792   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13793   f64 timeout = ~0;
13794   u8 *locator_set_name = 0;
13795   u8 locator_set_name_set = 0;
13796   u8 is_add = 1;
13797
13798   /* Parse args required to build the message */
13799   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13800     {
13801       if (unformat (input, "del"))
13802         {
13803           is_add = 0;
13804         }
13805       else if (unformat (input, "%_%v%_", &locator_set_name))
13806         {
13807           locator_set_name_set = 1;
13808         }
13809       else
13810         {
13811           clib_warning ("parse error '%U'", format_unformat_error, input);
13812           return -99;
13813         }
13814     }
13815
13816   if (is_add && !locator_set_name_set)
13817     {
13818       errmsg ("itr-rloc is not set!");
13819       return -99;
13820     }
13821
13822   if (is_add && vec_len (locator_set_name) > 64)
13823     {
13824       errmsg ("itr-rloc locator-set name too long\n");
13825       vec_free (locator_set_name);
13826       return -99;
13827     }
13828
13829   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13830   mp->is_add = is_add;
13831   if (is_add)
13832     {
13833       clib_memcpy (mp->locator_set_name, locator_set_name,
13834                    vec_len (locator_set_name));
13835     }
13836   else
13837     {
13838       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13839     }
13840   vec_free (locator_set_name);
13841
13842   /* send it... */
13843   S;
13844
13845   /* Wait for a reply... */
13846   W;
13847
13848   /* NOTREACHED */
13849   return 0;
13850 }
13851
13852 static int
13853 api_lisp_locator_dump (vat_main_t * vam)
13854 {
13855   unformat_input_t *input = vam->input;
13856   vl_api_lisp_locator_dump_t *mp;
13857   f64 timeout = ~0;
13858   u8 is_index_set = 0, is_name_set = 0;
13859   u8 *ls_name = 0;
13860   u32 ls_index = ~0;
13861
13862   /* Parse args required to build the message */
13863   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13864     {
13865       if (unformat (input, "ls_name %_%v%_", &ls_name))
13866         {
13867           is_name_set = 1;
13868         }
13869       else if (unformat (input, "ls_index %d", &ls_index))
13870         {
13871           is_index_set = 1;
13872         }
13873       else
13874         {
13875           errmsg ("parse error '%U'", format_unformat_error, input);
13876           return -99;
13877         }
13878     }
13879
13880   if (!is_index_set && !is_name_set)
13881     {
13882       errmsg ("error: expected one of index or name!\n");
13883       return -99;
13884     }
13885
13886   if (is_index_set && is_name_set)
13887     {
13888       errmsg ("error: only one param expected!\n");
13889       return -99;
13890     }
13891
13892   if (vec_len (ls_name) > 62)
13893     {
13894       errmsg ("error: locator set name too long!");
13895       return -99;
13896     }
13897
13898   if (!vam->json_output)
13899     {
13900       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13901                "weight");
13902     }
13903
13904   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13905   mp->is_index_set = is_index_set;
13906
13907   if (is_index_set)
13908     mp->ls_index = clib_host_to_net_u32 (ls_index);
13909   else
13910     {
13911       vec_add1 (ls_name, 0);
13912       strncpy ((char *) mp->ls_name, (char *) ls_name,
13913                sizeof (mp->ls_name) - 1);
13914     }
13915
13916   /* send it... */
13917   S;
13918
13919   /* Use a control ping for synchronization */
13920   {
13921     vl_api_control_ping_t *mp;
13922     M (CONTROL_PING, control_ping);
13923     S;
13924   }
13925   /* Wait for a reply... */
13926   W;
13927
13928   /* NOTREACHED */
13929   return 0;
13930 }
13931
13932 static int
13933 api_lisp_locator_set_dump (vat_main_t * vam)
13934 {
13935   vl_api_lisp_locator_set_dump_t *mp;
13936   unformat_input_t *input = vam->input;
13937   f64 timeout = ~0;
13938   u8 filter = 0;
13939
13940   /* Parse args required to build the message */
13941   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13942     {
13943       if (unformat (input, "local"))
13944         {
13945           filter = 1;
13946         }
13947       else if (unformat (input, "remote"))
13948         {
13949           filter = 2;
13950         }
13951       else
13952         {
13953           errmsg ("parse error '%U'", format_unformat_error, input);
13954           return -99;
13955         }
13956     }
13957
13958   if (!vam->json_output)
13959     {
13960       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13961     }
13962
13963   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13964
13965   mp->filter = filter;
13966
13967   /* send it... */
13968   S;
13969
13970   /* Use a control ping for synchronization */
13971   {
13972     vl_api_control_ping_t *mp;
13973     M (CONTROL_PING, control_ping);
13974     S;
13975   }
13976   /* Wait for a reply... */
13977   W;
13978
13979   /* NOTREACHED */
13980   return 0;
13981 }
13982
13983 static int
13984 api_lisp_eid_table_map_dump (vat_main_t * vam)
13985 {
13986   u8 is_l2 = 0;
13987   u8 mode_set = 0;
13988   unformat_input_t *input = vam->input;
13989   vl_api_lisp_eid_table_map_dump_t *mp;
13990   f64 timeout = ~0;
13991
13992   /* Parse args required to build the message */
13993   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13994     {
13995       if (unformat (input, "l2"))
13996         {
13997           is_l2 = 1;
13998           mode_set = 1;
13999         }
14000       else if (unformat (input, "l3"))
14001         {
14002           is_l2 = 0;
14003           mode_set = 1;
14004         }
14005       else
14006         {
14007           errmsg ("parse error '%U'", format_unformat_error, input);
14008           return -99;
14009         }
14010     }
14011
14012   if (!mode_set)
14013     {
14014       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
14015       return -99;
14016     }
14017
14018   if (!vam->json_output)
14019     {
14020       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
14021     }
14022
14023   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14024   mp->is_l2 = is_l2;
14025
14026   /* send it... */
14027   S;
14028
14029   /* Use a control ping for synchronization */
14030   {
14031     vl_api_control_ping_t *mp;
14032     M (CONTROL_PING, control_ping);
14033     S;
14034   }
14035   /* Wait for a reply... */
14036   W;
14037
14038   /* NOTREACHED */
14039   return 0;
14040 }
14041
14042 static int
14043 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14044 {
14045   vl_api_lisp_eid_table_vni_dump_t *mp;
14046   f64 timeout = ~0;
14047
14048   if (!vam->json_output)
14049     {
14050       fformat (vam->ofp, "VNI\n");
14051     }
14052
14053   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14054
14055   /* send it... */
14056   S;
14057
14058   /* Use a control ping for synchronization */
14059   {
14060     vl_api_control_ping_t *mp;
14061     M (CONTROL_PING, control_ping);
14062     S;
14063   }
14064   /* Wait for a reply... */
14065   W;
14066
14067   /* NOTREACHED */
14068   return 0;
14069 }
14070
14071 static int
14072 api_lisp_eid_table_dump (vat_main_t * vam)
14073 {
14074   unformat_input_t *i = vam->input;
14075   vl_api_lisp_eid_table_dump_t *mp;
14076   f64 timeout = ~0;
14077   struct in_addr ip4;
14078   struct in6_addr ip6;
14079   u8 mac[6];
14080   u8 eid_type = ~0, eid_set = 0;
14081   u32 prefix_length = ~0, t, vni = 0;
14082   u8 filter = 0;
14083
14084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14085     {
14086       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14087         {
14088           eid_set = 1;
14089           eid_type = 0;
14090           prefix_length = t;
14091         }
14092       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14093         {
14094           eid_set = 1;
14095           eid_type = 1;
14096           prefix_length = t;
14097         }
14098       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14099         {
14100           eid_set = 1;
14101           eid_type = 2;
14102         }
14103       else if (unformat (i, "vni %d", &t))
14104         {
14105           vni = t;
14106         }
14107       else if (unformat (i, "local"))
14108         {
14109           filter = 1;
14110         }
14111       else if (unformat (i, "remote"))
14112         {
14113           filter = 2;
14114         }
14115       else
14116         {
14117           errmsg ("parse error '%U'", format_unformat_error, i);
14118           return -99;
14119         }
14120     }
14121
14122   if (!vam->json_output)
14123     {
14124       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
14125                "ls_index", "ttl", "authoritative");
14126     }
14127
14128   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14129
14130   mp->filter = filter;
14131   if (eid_set)
14132     {
14133       mp->eid_set = 1;
14134       mp->vni = htonl (vni);
14135       mp->eid_type = eid_type;
14136       switch (eid_type)
14137         {
14138         case 0:
14139           mp->prefix_length = prefix_length;
14140           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14141           break;
14142         case 1:
14143           mp->prefix_length = prefix_length;
14144           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14145           break;
14146         case 2:
14147           clib_memcpy (mp->eid, mac, sizeof (mac));
14148           break;
14149         default:
14150           errmsg ("unknown EID type %d!", eid_type);
14151           return -99;
14152         }
14153     }
14154
14155   /* send it... */
14156   S;
14157
14158   /* Use a control ping for synchronization */
14159   {
14160     vl_api_control_ping_t *mp;
14161     M (CONTROL_PING, control_ping);
14162     S;
14163   }
14164
14165   /* Wait for a reply... */
14166   W;
14167
14168   /* NOTREACHED */
14169   return 0;
14170 }
14171
14172 static int
14173 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14174 {
14175   vl_api_lisp_gpe_tunnel_dump_t *mp;
14176   f64 timeout = ~0;
14177
14178   if (!vam->json_output)
14179     {
14180       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14181                "%=16s%=16s%=16s%=16s%=16s\n",
14182                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14183                "Decap next", "Lisp version", "Flags", "Next protocol",
14184                "ver_res", "res", "iid");
14185     }
14186
14187   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14188   /* send it... */
14189   S;
14190
14191   /* Use a control ping for synchronization */
14192   {
14193     vl_api_control_ping_t *mp;
14194     M (CONTROL_PING, control_ping);
14195     S;
14196   }
14197   /* Wait for a reply... */
14198   W;
14199
14200   /* NOTREACHED */
14201   return 0;
14202 }
14203
14204 static int
14205 api_lisp_adjacencies_get (vat_main_t * vam)
14206 {
14207   unformat_input_t *i = vam->input;
14208   vl_api_lisp_adjacencies_get_t *mp;
14209   f64 timeout = ~0;
14210   u8 vni_set = 0;
14211   u32 vni = ~0;
14212
14213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14214     {
14215       if (unformat (i, "vni %d", &vni))
14216         {
14217           vni_set = 1;
14218         }
14219       else
14220         {
14221           errmsg ("parse error '%U'\n", format_unformat_error, i);
14222           return -99;
14223         }
14224     }
14225
14226   if (!vni_set)
14227     {
14228       errmsg ("vni not set!\n");
14229       return -99;
14230     }
14231
14232   if (!vam->json_output)
14233     {
14234       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14235     }
14236
14237   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14238   mp->vni = clib_host_to_net_u32 (vni);
14239
14240   /* send it... */
14241   S;
14242
14243   /* Wait for a reply... */
14244   W;
14245
14246   /* NOTREACHED */
14247   return 0;
14248 }
14249
14250 static int
14251 api_lisp_map_resolver_dump (vat_main_t * vam)
14252 {
14253   vl_api_lisp_map_resolver_dump_t *mp;
14254   f64 timeout = ~0;
14255
14256   if (!vam->json_output)
14257     {
14258       fformat (vam->ofp, "%=20s\n", "Map resolver");
14259     }
14260
14261   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14262   /* send it... */
14263   S;
14264
14265   /* Use a control ping for synchronization */
14266   {
14267     vl_api_control_ping_t *mp;
14268     M (CONTROL_PING, control_ping);
14269     S;
14270   }
14271   /* Wait for a reply... */
14272   W;
14273
14274   /* NOTREACHED */
14275   return 0;
14276 }
14277
14278 static int
14279 api_show_lisp_status (vat_main_t * vam)
14280 {
14281   vl_api_show_lisp_status_t *mp;
14282   f64 timeout = ~0;
14283
14284   if (!vam->json_output)
14285     {
14286       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14287     }
14288
14289   M (SHOW_LISP_STATUS, show_lisp_status);
14290   /* send it... */
14291   S;
14292   /* Wait for a reply... */
14293   W;
14294
14295   /* NOTREACHED */
14296   return 0;
14297 }
14298
14299 static int
14300 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14301 {
14302   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14303   f64 timeout = ~0;
14304
14305   if (!vam->json_output)
14306     {
14307       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14308     }
14309
14310   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14311   /* send it... */
14312   S;
14313   /* Wait for a reply... */
14314   W;
14315
14316   /* NOTREACHED */
14317   return 0;
14318 }
14319
14320 static int
14321 api_af_packet_create (vat_main_t * vam)
14322 {
14323   unformat_input_t *i = vam->input;
14324   vl_api_af_packet_create_t *mp;
14325   f64 timeout;
14326   u8 *host_if_name = 0;
14327   u8 hw_addr[6];
14328   u8 random_hw_addr = 1;
14329
14330   memset (hw_addr, 0, sizeof (hw_addr));
14331
14332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14333     {
14334       if (unformat (i, "name %s", &host_if_name))
14335         vec_add1 (host_if_name, 0);
14336       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14337         random_hw_addr = 0;
14338       else
14339         break;
14340     }
14341
14342   if (!vec_len (host_if_name))
14343     {
14344       errmsg ("host-interface name must be specified");
14345       return -99;
14346     }
14347
14348   if (vec_len (host_if_name) > 64)
14349     {
14350       errmsg ("host-interface name too long");
14351       return -99;
14352     }
14353
14354   M (AF_PACKET_CREATE, af_packet_create);
14355
14356   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14357   clib_memcpy (mp->hw_addr, hw_addr, 6);
14358   mp->use_random_hw_addr = random_hw_addr;
14359   vec_free (host_if_name);
14360
14361   S;
14362   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14363   /* NOTREACHED */
14364   return 0;
14365 }
14366
14367 static int
14368 api_af_packet_delete (vat_main_t * vam)
14369 {
14370   unformat_input_t *i = vam->input;
14371   vl_api_af_packet_delete_t *mp;
14372   f64 timeout;
14373   u8 *host_if_name = 0;
14374
14375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14376     {
14377       if (unformat (i, "name %s", &host_if_name))
14378         vec_add1 (host_if_name, 0);
14379       else
14380         break;
14381     }
14382
14383   if (!vec_len (host_if_name))
14384     {
14385       errmsg ("host-interface name must be specified");
14386       return -99;
14387     }
14388
14389   if (vec_len (host_if_name) > 64)
14390     {
14391       errmsg ("host-interface name too long");
14392       return -99;
14393     }
14394
14395   M (AF_PACKET_DELETE, af_packet_delete);
14396
14397   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14398   vec_free (host_if_name);
14399
14400   S;
14401   W;
14402   /* NOTREACHED */
14403   return 0;
14404 }
14405
14406 static int
14407 api_policer_add_del (vat_main_t * vam)
14408 {
14409   unformat_input_t *i = vam->input;
14410   vl_api_policer_add_del_t *mp;
14411   f64 timeout;
14412   u8 is_add = 1;
14413   u8 *name = 0;
14414   u32 cir = 0;
14415   u32 eir = 0;
14416   u64 cb = 0;
14417   u64 eb = 0;
14418   u8 rate_type = 0;
14419   u8 round_type = 0;
14420   u8 type = 0;
14421   u8 color_aware = 0;
14422   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14423
14424   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14425   conform_action.dscp = 0;
14426   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14427   exceed_action.dscp = 0;
14428   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14429   violate_action.dscp = 0;
14430
14431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14432     {
14433       if (unformat (i, "del"))
14434         is_add = 0;
14435       else if (unformat (i, "name %s", &name))
14436         vec_add1 (name, 0);
14437       else if (unformat (i, "cir %u", &cir))
14438         ;
14439       else if (unformat (i, "eir %u", &eir))
14440         ;
14441       else if (unformat (i, "cb %u", &cb))
14442         ;
14443       else if (unformat (i, "eb %u", &eb))
14444         ;
14445       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14446                          &rate_type))
14447         ;
14448       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14449                          &round_type))
14450         ;
14451       else if (unformat (i, "type %U", unformat_policer_type, &type))
14452         ;
14453       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14454                          &conform_action))
14455         ;
14456       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14457                          &exceed_action))
14458         ;
14459       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14460                          &violate_action))
14461         ;
14462       else if (unformat (i, "color-aware"))
14463         color_aware = 1;
14464       else
14465         break;
14466     }
14467
14468   if (!vec_len (name))
14469     {
14470       errmsg ("policer name must be specified");
14471       return -99;
14472     }
14473
14474   if (vec_len (name) > 64)
14475     {
14476       errmsg ("policer name too long");
14477       return -99;
14478     }
14479
14480   M (POLICER_ADD_DEL, policer_add_del);
14481
14482   clib_memcpy (mp->name, name, vec_len (name));
14483   vec_free (name);
14484   mp->is_add = is_add;
14485   mp->cir = cir;
14486   mp->eir = eir;
14487   mp->cb = cb;
14488   mp->eb = eb;
14489   mp->rate_type = rate_type;
14490   mp->round_type = round_type;
14491   mp->type = type;
14492   mp->conform_action_type = conform_action.action_type;
14493   mp->conform_dscp = conform_action.dscp;
14494   mp->exceed_action_type = exceed_action.action_type;
14495   mp->exceed_dscp = exceed_action.dscp;
14496   mp->violate_action_type = violate_action.action_type;
14497   mp->violate_dscp = violate_action.dscp;
14498   mp->color_aware = color_aware;
14499
14500   S;
14501   W;
14502   /* NOTREACHED */
14503   return 0;
14504 }
14505
14506 static int
14507 api_policer_dump (vat_main_t * vam)
14508 {
14509   unformat_input_t *i = vam->input;
14510   vl_api_policer_dump_t *mp;
14511   f64 timeout = ~0;
14512   u8 *match_name = 0;
14513   u8 match_name_valid = 0;
14514
14515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14516     {
14517       if (unformat (i, "name %s", &match_name))
14518         {
14519           vec_add1 (match_name, 0);
14520           match_name_valid = 1;
14521         }
14522       else
14523         break;
14524     }
14525
14526   M (POLICER_DUMP, policer_dump);
14527   mp->match_name_valid = match_name_valid;
14528   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14529   vec_free (match_name);
14530   /* send it... */
14531   S;
14532
14533   /* Use a control ping for synchronization */
14534   {
14535     vl_api_control_ping_t *mp;
14536     M (CONTROL_PING, control_ping);
14537     S;
14538   }
14539   /* Wait for a reply... */
14540   W;
14541
14542   /* NOTREACHED */
14543   return 0;
14544 }
14545
14546 static int
14547 api_policer_classify_set_interface (vat_main_t * vam)
14548 {
14549   unformat_input_t *i = vam->input;
14550   vl_api_policer_classify_set_interface_t *mp;
14551   f64 timeout;
14552   u32 sw_if_index;
14553   int sw_if_index_set;
14554   u32 ip4_table_index = ~0;
14555   u32 ip6_table_index = ~0;
14556   u32 l2_table_index = ~0;
14557   u8 is_add = 1;
14558
14559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14560     {
14561       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14562         sw_if_index_set = 1;
14563       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14564         sw_if_index_set = 1;
14565       else if (unformat (i, "del"))
14566         is_add = 0;
14567       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14568         ;
14569       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14570         ;
14571       else if (unformat (i, "l2-table %d", &l2_table_index))
14572         ;
14573       else
14574         {
14575           clib_warning ("parse error '%U'", format_unformat_error, i);
14576           return -99;
14577         }
14578     }
14579
14580   if (sw_if_index_set == 0)
14581     {
14582       errmsg ("missing interface name or sw_if_index\n");
14583       return -99;
14584     }
14585
14586   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14587
14588   mp->sw_if_index = ntohl (sw_if_index);
14589   mp->ip4_table_index = ntohl (ip4_table_index);
14590   mp->ip6_table_index = ntohl (ip6_table_index);
14591   mp->l2_table_index = ntohl (l2_table_index);
14592   mp->is_add = is_add;
14593
14594   S;
14595   W;
14596   /* NOTREACHED */
14597   return 0;
14598 }
14599
14600 static int
14601 api_policer_classify_dump (vat_main_t * vam)
14602 {
14603   unformat_input_t *i = vam->input;
14604   vl_api_policer_classify_dump_t *mp;
14605   f64 timeout = ~0;
14606   u8 type = POLICER_CLASSIFY_N_TABLES;
14607
14608   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14609     ;
14610   else
14611     {
14612       errmsg ("classify table type must be specified\n");
14613       return -99;
14614     }
14615
14616   if (!vam->json_output)
14617     {
14618       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14619     }
14620
14621   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14622   mp->type = type;
14623   /* send it... */
14624   S;
14625
14626   /* Use a control ping for synchronization */
14627   {
14628     vl_api_control_ping_t *mp;
14629     M (CONTROL_PING, control_ping);
14630     S;
14631   }
14632   /* Wait for a reply... */
14633   W;
14634
14635   /* NOTREACHED */
14636   return 0;
14637 }
14638
14639 static int
14640 api_netmap_create (vat_main_t * vam)
14641 {
14642   unformat_input_t *i = vam->input;
14643   vl_api_netmap_create_t *mp;
14644   f64 timeout;
14645   u8 *if_name = 0;
14646   u8 hw_addr[6];
14647   u8 random_hw_addr = 1;
14648   u8 is_pipe = 0;
14649   u8 is_master = 0;
14650
14651   memset (hw_addr, 0, sizeof (hw_addr));
14652
14653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14654     {
14655       if (unformat (i, "name %s", &if_name))
14656         vec_add1 (if_name, 0);
14657       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14658         random_hw_addr = 0;
14659       else if (unformat (i, "pipe"))
14660         is_pipe = 1;
14661       else if (unformat (i, "master"))
14662         is_master = 1;
14663       else if (unformat (i, "slave"))
14664         is_master = 0;
14665       else
14666         break;
14667     }
14668
14669   if (!vec_len (if_name))
14670     {
14671       errmsg ("interface name must be specified");
14672       return -99;
14673     }
14674
14675   if (vec_len (if_name) > 64)
14676     {
14677       errmsg ("interface name too long");
14678       return -99;
14679     }
14680
14681   M (NETMAP_CREATE, netmap_create);
14682
14683   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14684   clib_memcpy (mp->hw_addr, hw_addr, 6);
14685   mp->use_random_hw_addr = random_hw_addr;
14686   mp->is_pipe = is_pipe;
14687   mp->is_master = is_master;
14688   vec_free (if_name);
14689
14690   S;
14691   W;
14692   /* NOTREACHED */
14693   return 0;
14694 }
14695
14696 static int
14697 api_netmap_delete (vat_main_t * vam)
14698 {
14699   unformat_input_t *i = vam->input;
14700   vl_api_netmap_delete_t *mp;
14701   f64 timeout;
14702   u8 *if_name = 0;
14703
14704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14705     {
14706       if (unformat (i, "name %s", &if_name))
14707         vec_add1 (if_name, 0);
14708       else
14709         break;
14710     }
14711
14712   if (!vec_len (if_name))
14713     {
14714       errmsg ("interface name must be specified");
14715       return -99;
14716     }
14717
14718   if (vec_len (if_name) > 64)
14719     {
14720       errmsg ("interface name too long");
14721       return -99;
14722     }
14723
14724   M (NETMAP_DELETE, netmap_delete);
14725
14726   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14727   vec_free (if_name);
14728
14729   S;
14730   W;
14731   /* NOTREACHED */
14732   return 0;
14733 }
14734
14735 static void vl_api_mpls_eth_tunnel_details_t_handler
14736   (vl_api_mpls_eth_tunnel_details_t * mp)
14737 {
14738   vat_main_t *vam = &vat_main;
14739   i32 i;
14740   i32 len = ntohl (mp->nlabels);
14741
14742   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14743            ntohl (mp->tunnel_index),
14744            format_ethernet_address, &mp->tunnel_dst_mac,
14745            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14746   for (i = 0; i < len; i++)
14747     {
14748       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14749     }
14750   fformat (vam->ofp, "\n");
14751   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14752            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14753 }
14754
14755 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14756   (vl_api_mpls_eth_tunnel_details_t * mp)
14757 {
14758   vat_main_t *vam = &vat_main;
14759   vat_json_node_t *node = NULL;
14760   struct in_addr ip4;
14761   i32 i;
14762   i32 len = ntohl (mp->nlabels);
14763
14764   if (VAT_JSON_ARRAY != vam->json_tree.type)
14765     {
14766       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14767       vat_json_init_array (&vam->json_tree);
14768     }
14769   node = vat_json_array_add (&vam->json_tree);
14770
14771   vat_json_init_object (node);
14772   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14773   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14774   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14775   vat_json_object_add_uint (node, "inner_fib_index",
14776                             ntohl (mp->inner_fib_index));
14777   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14778   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14779   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14780   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14781   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14782                                    format (0, "%U", format_ethernet_address,
14783                                            &mp->tunnel_dst_mac));
14784   vat_json_object_add_uint (node, "tx_sw_if_index",
14785                             ntohl (mp->tx_sw_if_index));
14786   vat_json_object_add_uint (node, "label_count", len);
14787   for (i = 0; i < len; i++)
14788     {
14789       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14790     }
14791 }
14792
14793 static int
14794 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14795 {
14796   vl_api_mpls_eth_tunnel_dump_t *mp;
14797   f64 timeout;
14798   i32 index = -1;
14799
14800   /* Parse args required to build the message */
14801   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14802     {
14803       if (!unformat (vam->input, "tunnel_index %d", &index))
14804         {
14805           index = -1;
14806           break;
14807         }
14808     }
14809
14810   fformat (vam->ofp, "  tunnel_index %d\n", index);
14811
14812   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14813   mp->tunnel_index = htonl (index);
14814   S;
14815
14816   /* Use a control ping for synchronization */
14817   {
14818     vl_api_control_ping_t *mp;
14819     M (CONTROL_PING, control_ping);
14820     S;
14821   }
14822   W;
14823 }
14824
14825 static void vl_api_mpls_fib_encap_details_t_handler
14826   (vl_api_mpls_fib_encap_details_t * mp)
14827 {
14828   vat_main_t *vam = &vat_main;
14829   i32 i;
14830   i32 len = ntohl (mp->nlabels);
14831
14832   fformat (vam->ofp, "table %d, dest %U, label ",
14833            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14834   for (i = 0; i < len; i++)
14835     {
14836       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14837     }
14838   fformat (vam->ofp, "\n");
14839 }
14840
14841 static void vl_api_mpls_fib_encap_details_t_handler_json
14842   (vl_api_mpls_fib_encap_details_t * mp)
14843 {
14844   vat_main_t *vam = &vat_main;
14845   vat_json_node_t *node = NULL;
14846   i32 i;
14847   i32 len = ntohl (mp->nlabels);
14848   struct in_addr ip4;
14849
14850   if (VAT_JSON_ARRAY != vam->json_tree.type)
14851     {
14852       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14853       vat_json_init_array (&vam->json_tree);
14854     }
14855   node = vat_json_array_add (&vam->json_tree);
14856
14857   vat_json_init_object (node);
14858   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14859   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14860   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14861   vat_json_object_add_ip4 (node, "dest", ip4);
14862   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14863   vat_json_object_add_uint (node, "label_count", len);
14864   for (i = 0; i < len; i++)
14865     {
14866       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14867     }
14868 }
14869
14870 static int
14871 api_mpls_fib_encap_dump (vat_main_t * vam)
14872 {
14873   vl_api_mpls_fib_encap_dump_t *mp;
14874   f64 timeout;
14875
14876   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14877   S;
14878
14879   /* Use a control ping for synchronization */
14880   {
14881     vl_api_control_ping_t *mp;
14882     M (CONTROL_PING, control_ping);
14883     S;
14884   }
14885   W;
14886 }
14887
14888 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
14889 #define vl_api_mpls_fib_details_t_print vl_noop_handler
14890
14891 static void
14892 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
14893 {
14894   vat_main_t *vam = &vat_main;
14895   int count = ntohl (mp->count);
14896   vl_api_fib_path_t *fp;
14897   int i;
14898
14899   fformat (vam->ofp,
14900            "table-id %d, label %u, ess_bit %u\n",
14901            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
14902   fp = mp->path;
14903   for (i = 0; i < count; i++)
14904     {
14905       if (fp->afi == IP46_TYPE_IP6)
14906         fformat (vam->ofp,
14907                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14908                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14909                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14910                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14911                  format_ip6_address, fp->next_hop);
14912       else if (fp->afi == IP46_TYPE_IP4)
14913         fformat (vam->ofp,
14914                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14915                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14916                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14917                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14918                  format_ip4_address, fp->next_hop);
14919       fp++;
14920     }
14921 }
14922
14923 static void vl_api_mpls_fib_details_t_handler_json
14924   (vl_api_mpls_fib_details_t * mp)
14925 {
14926   vat_main_t *vam = &vat_main;
14927   int count = ntohl (mp->count);
14928   vat_json_node_t *node = NULL;
14929   struct in_addr ip4;
14930   struct in6_addr ip6;
14931   vl_api_fib_path_t *fp;
14932   int i;
14933
14934   if (VAT_JSON_ARRAY != vam->json_tree.type)
14935     {
14936       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14937       vat_json_init_array (&vam->json_tree);
14938     }
14939   node = vat_json_array_add (&vam->json_tree);
14940
14941   vat_json_init_object (node);
14942   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14943   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
14944   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14945   vat_json_object_add_uint (node, "path_count", count);
14946   fp = mp->path;
14947   for (i = 0; i < count; i++)
14948     {
14949       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
14950       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
14951       vat_json_object_add_uint (node, "is_local", fp->is_local);
14952       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
14953       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
14954       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
14955       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
14956       if (fp->afi == IP46_TYPE_IP4)
14957         {
14958           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
14959           vat_json_object_add_ip4 (node, "next_hop", ip4);
14960         }
14961       else if (fp->afi == IP46_TYPE_IP6)
14962         {
14963           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
14964           vat_json_object_add_ip6 (node, "next_hop", ip6);
14965         }
14966     }
14967 }
14968
14969 static int
14970 api_mpls_fib_dump (vat_main_t * vam)
14971 {
14972   vl_api_mpls_fib_dump_t *mp;
14973   f64 timeout;
14974
14975   M (MPLS_FIB_DUMP, mpls_fib_dump);
14976   S;
14977
14978   /* Use a control ping for synchronization */
14979   {
14980     vl_api_control_ping_t *mp;
14981     M (CONTROL_PING, control_ping);
14982     S;
14983   }
14984   W;
14985 }
14986
14987 #define vl_api_ip_fib_details_t_endian vl_noop_handler
14988 #define vl_api_ip_fib_details_t_print vl_noop_handler
14989
14990 static void
14991 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
14992 {
14993   vat_main_t *vam = &vat_main;
14994   int count = ntohl (mp->count);
14995   vl_api_fib_path_t *fp;
14996   int i;
14997
14998   fformat (vam->ofp,
14999            "table-id %d, prefix %U/%d\n",
15000            ntohl (mp->table_id), format_ip4_address, mp->address,
15001            mp->address_length);
15002   fp = mp->path;
15003   for (i = 0; i < count; i++)
15004     {
15005       if (fp->afi == IP46_TYPE_IP6)
15006         fformat (vam->ofp,
15007                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15008                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15009                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15010                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15011                  format_ip6_address, fp->next_hop);
15012       else if (fp->afi == IP46_TYPE_IP4)
15013         fformat (vam->ofp,
15014                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15015                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15016                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15017                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15018                  format_ip4_address, fp->next_hop);
15019       fp++;
15020     }
15021 }
15022
15023 static void vl_api_ip_fib_details_t_handler_json
15024   (vl_api_ip_fib_details_t * mp)
15025 {
15026   vat_main_t *vam = &vat_main;
15027   int count = ntohl (mp->count);
15028   vat_json_node_t *node = NULL;
15029   struct in_addr ip4;
15030   struct in6_addr ip6;
15031   vl_api_fib_path_t *fp;
15032   int i;
15033
15034   if (VAT_JSON_ARRAY != vam->json_tree.type)
15035     {
15036       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15037       vat_json_init_array (&vam->json_tree);
15038     }
15039   node = vat_json_array_add (&vam->json_tree);
15040
15041   vat_json_init_object (node);
15042   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15043   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15044   vat_json_object_add_ip4 (node, "prefix", ip4);
15045   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15046   vat_json_object_add_uint (node, "path_count", count);
15047   fp = mp->path;
15048   for (i = 0; i < count; i++)
15049     {
15050       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15051       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15052       vat_json_object_add_uint (node, "is_local", fp->is_local);
15053       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15054       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15055       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15056       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15057       if (fp->afi == IP46_TYPE_IP4)
15058         {
15059           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15060           vat_json_object_add_ip4 (node, "next_hop", ip4);
15061         }
15062       else if (fp->afi == IP46_TYPE_IP6)
15063         {
15064           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15065           vat_json_object_add_ip6 (node, "next_hop", ip6);
15066         }
15067     }
15068 }
15069
15070 static int
15071 api_ip_fib_dump (vat_main_t * vam)
15072 {
15073   vl_api_ip_fib_dump_t *mp;
15074   f64 timeout;
15075
15076   M (IP_FIB_DUMP, ip_fib_dump);
15077   S;
15078
15079   /* Use a control ping for synchronization */
15080   {
15081     vl_api_control_ping_t *mp;
15082     M (CONTROL_PING, control_ping);
15083     S;
15084   }
15085   W;
15086 }
15087
15088 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15089 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15090
15091 static void
15092 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15093 {
15094   vat_main_t *vam = &vat_main;
15095   int count = ntohl (mp->count);
15096   vl_api_fib_path_t *fp;
15097   int i;
15098
15099   fformat (vam->ofp,
15100            "table-id %d, prefix %U/%d\n",
15101            ntohl (mp->table_id), format_ip6_address, mp->address,
15102            mp->address_length);
15103   fp = mp->path;
15104   for (i = 0; i < count; i++)
15105     {
15106       if (fp->afi == IP46_TYPE_IP6)
15107         fformat (vam->ofp,
15108                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15109                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15110                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15111                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15112                  format_ip6_address, fp->next_hop);
15113       else if (fp->afi == IP46_TYPE_IP4)
15114         fformat (vam->ofp,
15115                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15116                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15117                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15118                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15119                  format_ip4_address, fp->next_hop);
15120       fp++;
15121     }
15122 }
15123
15124 static void vl_api_ip6_fib_details_t_handler_json
15125   (vl_api_ip6_fib_details_t * mp)
15126 {
15127   vat_main_t *vam = &vat_main;
15128   int count = ntohl (mp->count);
15129   vat_json_node_t *node = NULL;
15130   struct in_addr ip4;
15131   struct in6_addr ip6;
15132   vl_api_fib_path_t *fp;
15133   int i;
15134
15135   if (VAT_JSON_ARRAY != vam->json_tree.type)
15136     {
15137       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15138       vat_json_init_array (&vam->json_tree);
15139     }
15140   node = vat_json_array_add (&vam->json_tree);
15141
15142   vat_json_init_object (node);
15143   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15144   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15145   vat_json_object_add_ip6 (node, "prefix", ip6);
15146   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15147   vat_json_object_add_uint (node, "path_count", count);
15148   fp = mp->path;
15149   for (i = 0; i < count; i++)
15150     {
15151       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15152       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15153       vat_json_object_add_uint (node, "is_local", fp->is_local);
15154       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15155       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15156       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15157       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15158       if (fp->afi == IP46_TYPE_IP4)
15159         {
15160           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15161           vat_json_object_add_ip4 (node, "next_hop", ip4);
15162         }
15163       else if (fp->afi == IP46_TYPE_IP6)
15164         {
15165           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15166           vat_json_object_add_ip6 (node, "next_hop", ip6);
15167         }
15168     }
15169 }
15170
15171 static int
15172 api_ip6_fib_dump (vat_main_t * vam)
15173 {
15174   vl_api_ip6_fib_dump_t *mp;
15175   f64 timeout;
15176
15177   M (IP6_FIB_DUMP, ip6_fib_dump);
15178   S;
15179
15180   /* Use a control ping for synchronization */
15181   {
15182     vl_api_control_ping_t *mp;
15183     M (CONTROL_PING, control_ping);
15184     S;
15185   }
15186   W;
15187 }
15188
15189 int
15190 api_classify_table_ids (vat_main_t * vam)
15191 {
15192   vl_api_classify_table_ids_t *mp;
15193   f64 timeout;
15194
15195   /* Construct the API message */
15196   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15197   mp->context = 0;
15198
15199   S;
15200   W;
15201   /* NOTREACHED */
15202   return 0;
15203 }
15204
15205 int
15206 api_classify_table_by_interface (vat_main_t * vam)
15207 {
15208   unformat_input_t *input = vam->input;
15209   vl_api_classify_table_by_interface_t *mp;
15210   f64 timeout;
15211
15212   u32 sw_if_index = ~0;
15213   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15214     {
15215       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15216         ;
15217       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15218         ;
15219       else
15220         break;
15221     }
15222   if (sw_if_index == ~0)
15223     {
15224       errmsg ("missing interface name or sw_if_index\n");
15225       return -99;
15226     }
15227
15228   /* Construct the API message */
15229   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15230   mp->context = 0;
15231   mp->sw_if_index = ntohl (sw_if_index);
15232
15233   S;
15234   W;
15235   /* NOTREACHED */
15236   return 0;
15237 }
15238
15239 int
15240 api_classify_table_info (vat_main_t * vam)
15241 {
15242   unformat_input_t *input = vam->input;
15243   vl_api_classify_table_info_t *mp;
15244   f64 timeout;
15245
15246   u32 table_id = ~0;
15247   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15248     {
15249       if (unformat (input, "table_id %d", &table_id))
15250         ;
15251       else
15252         break;
15253     }
15254   if (table_id == ~0)
15255     {
15256       errmsg ("missing table id\n");
15257       return -99;
15258     }
15259
15260   /* Construct the API message */
15261   M (CLASSIFY_TABLE_INFO, classify_table_info);
15262   mp->context = 0;
15263   mp->table_id = ntohl (table_id);
15264
15265   S;
15266   W;
15267   /* NOTREACHED */
15268   return 0;
15269 }
15270
15271 int
15272 api_classify_session_dump (vat_main_t * vam)
15273 {
15274   unformat_input_t *input = vam->input;
15275   vl_api_classify_session_dump_t *mp;
15276   f64 timeout;
15277
15278   u32 table_id = ~0;
15279   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15280     {
15281       if (unformat (input, "table_id %d", &table_id))
15282         ;
15283       else
15284         break;
15285     }
15286   if (table_id == ~0)
15287     {
15288       errmsg ("missing table id\n");
15289       return -99;
15290     }
15291
15292   /* Construct the API message */
15293   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15294   mp->context = 0;
15295   mp->table_id = ntohl (table_id);
15296   S;
15297
15298   /* Use a control ping for synchronization */
15299   {
15300     vl_api_control_ping_t *mp;
15301     M (CONTROL_PING, control_ping);
15302     S;
15303   }
15304   W;
15305   /* NOTREACHED */
15306   return 0;
15307 }
15308
15309 static void
15310 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15311 {
15312   vat_main_t *vam = &vat_main;
15313
15314   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15315            "src_address %U, vrf_id %d, path_mtu %u, "
15316            "template_interval %u, udp_checksum %d\n",
15317            format_ip4_address, mp->collector_address,
15318            ntohs (mp->collector_port),
15319            format_ip4_address, mp->src_address,
15320            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15321            ntohl (mp->template_interval), mp->udp_checksum);
15322
15323   vam->retval = 0;
15324   vam->result_ready = 1;
15325 }
15326
15327 static void
15328   vl_api_ipfix_exporter_details_t_handler_json
15329   (vl_api_ipfix_exporter_details_t * mp)
15330 {
15331   vat_main_t *vam = &vat_main;
15332   vat_json_node_t node;
15333   struct in_addr collector_address;
15334   struct in_addr src_address;
15335
15336   vat_json_init_object (&node);
15337   clib_memcpy (&collector_address, &mp->collector_address,
15338                sizeof (collector_address));
15339   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15340   vat_json_object_add_uint (&node, "collector_port",
15341                             ntohs (mp->collector_port));
15342   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15343   vat_json_object_add_ip4 (&node, "src_address", src_address);
15344   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15345   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15346   vat_json_object_add_uint (&node, "template_interval",
15347                             ntohl (mp->template_interval));
15348   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15349
15350   vat_json_print (vam->ofp, &node);
15351   vat_json_free (&node);
15352   vam->retval = 0;
15353   vam->result_ready = 1;
15354 }
15355
15356 int
15357 api_ipfix_exporter_dump (vat_main_t * vam)
15358 {
15359   vl_api_ipfix_exporter_dump_t *mp;
15360   f64 timeout;
15361
15362   /* Construct the API message */
15363   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15364   mp->context = 0;
15365
15366   S;
15367   W;
15368   /* NOTREACHED */
15369   return 0;
15370 }
15371
15372 static int
15373 api_ipfix_classify_stream_dump (vat_main_t * vam)
15374 {
15375   vl_api_ipfix_classify_stream_dump_t *mp;
15376   f64 timeout;
15377
15378   /* Construct the API message */
15379   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15380   mp->context = 0;
15381
15382   S;
15383   W;
15384   /* NOTREACHED */
15385   return 0;
15386 }
15387
15388 static void
15389   vl_api_ipfix_classify_stream_details_t_handler
15390   (vl_api_ipfix_classify_stream_details_t * mp)
15391 {
15392   vat_main_t *vam = &vat_main;
15393   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15394            ntohl (mp->domain_id), ntohs (mp->src_port));
15395   vam->retval = 0;
15396   vam->result_ready = 1;
15397 }
15398
15399 static void
15400   vl_api_ipfix_classify_stream_details_t_handler_json
15401   (vl_api_ipfix_classify_stream_details_t * mp)
15402 {
15403   vat_main_t *vam = &vat_main;
15404   vat_json_node_t node;
15405
15406   vat_json_init_object (&node);
15407   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15408   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15409
15410   vat_json_print (vam->ofp, &node);
15411   vat_json_free (&node);
15412   vam->retval = 0;
15413   vam->result_ready = 1;
15414 }
15415
15416 static int
15417 api_ipfix_classify_table_dump (vat_main_t * vam)
15418 {
15419   vl_api_ipfix_classify_table_dump_t *mp;
15420   f64 timeout;
15421
15422   if (!vam->json_output)
15423     {
15424       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15425                "transport_protocol");
15426     }
15427
15428   /* Construct the API message */
15429   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15430
15431   /* send it... */
15432   S;
15433
15434   /* Use a control ping for synchronization */
15435   {
15436     vl_api_control_ping_t *mp;
15437     M (CONTROL_PING, control_ping);
15438     S;
15439   }
15440   W;
15441 }
15442
15443 static void
15444   vl_api_ipfix_classify_table_details_t_handler
15445   (vl_api_ipfix_classify_table_details_t * mp)
15446 {
15447   vat_main_t *vam = &vat_main;
15448   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15449            mp->transport_protocol);
15450 }
15451
15452 static void
15453   vl_api_ipfix_classify_table_details_t_handler_json
15454   (vl_api_ipfix_classify_table_details_t * mp)
15455 {
15456   vat_json_node_t *node = NULL;
15457   vat_main_t *vam = &vat_main;
15458
15459   if (VAT_JSON_ARRAY != vam->json_tree.type)
15460     {
15461       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15462       vat_json_init_array (&vam->json_tree);
15463     }
15464
15465   node = vat_json_array_add (&vam->json_tree);
15466   vat_json_init_object (node);
15467
15468   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15469   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15470   vat_json_object_add_uint (node, "transport_protocol",
15471                             mp->transport_protocol);
15472 }
15473
15474 static int
15475 api_sw_interface_span_enable_disable (vat_main_t * vam)
15476 {
15477   unformat_input_t *i = vam->input;
15478   vl_api_sw_interface_span_enable_disable_t *mp;
15479   f64 timeout;
15480   u32 src_sw_if_index = ~0;
15481   u32 dst_sw_if_index = ~0;
15482   u8 enable = 1;
15483
15484   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15485     {
15486       if (unformat (i, "src %U", unformat_sw_if_index, vam, &src_sw_if_index))
15487         ;
15488       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15489         ;
15490       else
15491         if (unformat
15492             (i, "dst %U", unformat_sw_if_index, vam, &dst_sw_if_index))
15493         ;
15494       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15495         ;
15496       else if (unformat (i, "disable"))
15497         enable = 0;
15498       else
15499         break;
15500     }
15501
15502   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15503
15504   mp->sw_if_index_from = htonl (src_sw_if_index);
15505   mp->sw_if_index_to = htonl (dst_sw_if_index);
15506   mp->enable = enable;
15507
15508   S;
15509   W;
15510   /* NOTREACHED */
15511   return 0;
15512 }
15513
15514 static void
15515 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
15516                                             * mp)
15517 {
15518   vat_main_t *vam = &vat_main;
15519
15520   fformat (vam->ofp, "%u => %u\n",
15521            ntohl (mp->sw_if_index_from), ntohl (mp->sw_if_index_to));
15522 }
15523
15524 static void
15525   vl_api_sw_interface_span_details_t_handler_json
15526   (vl_api_sw_interface_span_details_t * mp)
15527 {
15528   vat_main_t *vam = &vat_main;
15529   vat_json_node_t *node = NULL;
15530
15531   if (VAT_JSON_ARRAY != vam->json_tree.type)
15532     {
15533       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15534       vat_json_init_array (&vam->json_tree);
15535     }
15536   node = vat_json_array_add (&vam->json_tree);
15537
15538   vat_json_init_object (node);
15539   vat_json_object_add_uint (node, "src-if-index",
15540                             ntohl (mp->sw_if_index_from));
15541   vat_json_object_add_uint (node, "dst-if-index", ntohl (mp->sw_if_index_to));
15542 }
15543
15544 static int
15545 api_sw_interface_span_dump (vat_main_t * vam)
15546 {
15547   vl_api_sw_interface_span_dump_t *mp;
15548   f64 timeout;
15549
15550   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
15551   S;
15552
15553   /* Use a control ping for synchronization */
15554   {
15555     vl_api_control_ping_t *mp;
15556     M (CONTROL_PING, control_ping);
15557     S;
15558   }
15559   W;
15560 }
15561
15562 int
15563 api_pg_create_interface (vat_main_t * vam)
15564 {
15565   unformat_input_t *input = vam->input;
15566   vl_api_pg_create_interface_t *mp;
15567   f64 timeout;
15568
15569   u32 if_id = ~0;
15570   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15571     {
15572       if (unformat (input, "if_id %d", &if_id))
15573         ;
15574       else
15575         break;
15576     }
15577   if (if_id == ~0)
15578     {
15579       errmsg ("missing pg interface index\n");
15580       return -99;
15581     }
15582
15583   /* Construct the API message */
15584   M (PG_CREATE_INTERFACE, pg_create_interface);
15585   mp->context = 0;
15586   mp->interface_id = ntohl (if_id);
15587
15588   S;
15589   W;
15590   /* NOTREACHED */
15591   return 0;
15592 }
15593
15594 int
15595 api_pg_capture (vat_main_t * vam)
15596 {
15597   unformat_input_t *input = vam->input;
15598   vl_api_pg_capture_t *mp;
15599   f64 timeout;
15600
15601   u32 if_id = ~0;
15602   u8 enable = 1;
15603   u32 count = 1;
15604   u8 pcap_file_set = 0;
15605   u8 *pcap_file = 0;
15606   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15607     {
15608       if (unformat (input, "if_id %d", &if_id))
15609         ;
15610       else if (unformat (input, "pcap %s", &pcap_file))
15611         pcap_file_set = 1;
15612       else if (unformat (input, "count %d", &count))
15613         ;
15614       else if (unformat (input, "disable"))
15615         enable = 0;
15616       else
15617         break;
15618     }
15619   if (if_id == ~0)
15620     {
15621       errmsg ("missing pg interface index\n");
15622       return -99;
15623     }
15624   if (pcap_file_set > 0)
15625     {
15626       if (vec_len (pcap_file) > 255)
15627         {
15628           errmsg ("pcap file name is too long\n");
15629           return -99;
15630         }
15631     }
15632
15633   u32 name_len = vec_len (pcap_file);
15634   /* Construct the API message */
15635   M (PG_CAPTURE, pg_capture);
15636   mp->context = 0;
15637   mp->interface_id = ntohl (if_id);
15638   mp->is_enabled = enable;
15639   mp->count = ntohl (count);
15640   mp->pcap_name_length = ntohl (name_len);
15641   if (pcap_file_set != 0)
15642     {
15643       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15644     }
15645   vec_free (pcap_file);
15646
15647   S;
15648   W;
15649   /* NOTREACHED */
15650   return 0;
15651 }
15652
15653 int
15654 api_pg_enable_disable (vat_main_t * vam)
15655 {
15656   unformat_input_t *input = vam->input;
15657   vl_api_pg_enable_disable_t *mp;
15658   f64 timeout;
15659
15660   u8 enable = 1;
15661   u8 stream_name_set = 0;
15662   u8 *stream_name = 0;
15663   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15664     {
15665       if (unformat (input, "stream %s", &stream_name))
15666         stream_name_set = 1;
15667       else if (unformat (input, "disable"))
15668         enable = 0;
15669       else
15670         break;
15671     }
15672
15673   if (stream_name_set > 0)
15674     {
15675       if (vec_len (stream_name) > 255)
15676         {
15677           errmsg ("stream name too long\n");
15678           return -99;
15679         }
15680     }
15681
15682   u32 name_len = vec_len (stream_name);
15683   /* Construct the API message */
15684   M (PG_ENABLE_DISABLE, pg_enable_disable);
15685   mp->context = 0;
15686   mp->is_enabled = enable;
15687   if (stream_name_set != 0)
15688     {
15689       mp->stream_name_length = ntohl (name_len);
15690       clib_memcpy (mp->stream_name, stream_name, name_len);
15691     }
15692   vec_free (stream_name);
15693
15694   S;
15695   W;
15696   /* NOTREACHED */
15697   return 0;
15698 }
15699
15700 int
15701 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15702 {
15703   unformat_input_t *input = vam->input;
15704   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15705   f64 timeout;
15706
15707   u16 *low_ports = 0;
15708   u16 *high_ports = 0;
15709   u16 this_low;
15710   u16 this_hi;
15711   ip4_address_t ip4_addr;
15712   ip6_address_t ip6_addr;
15713   u32 length;
15714   u32 tmp, tmp2;
15715   u8 prefix_set = 0;
15716   u32 vrf_id = ~0;
15717   u8 is_add = 1;
15718   u8 is_ipv6 = 0;
15719
15720   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15721     {
15722       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15723         {
15724           prefix_set = 1;
15725         }
15726       else
15727         if (unformat
15728             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15729         {
15730           prefix_set = 1;
15731           is_ipv6 = 1;
15732         }
15733       else if (unformat (input, "vrf %d", &vrf_id))
15734         ;
15735       else if (unformat (input, "del"))
15736         is_add = 0;
15737       else if (unformat (input, "port %d", &tmp))
15738         {
15739           if (tmp == 0 || tmp > 65535)
15740             {
15741               errmsg ("port %d out of range", tmp);
15742               return -99;
15743             }
15744           this_low = tmp;
15745           this_hi = this_low + 1;
15746           vec_add1 (low_ports, this_low);
15747           vec_add1 (high_ports, this_hi);
15748         }
15749       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15750         {
15751           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15752             {
15753               errmsg ("incorrect range parameters\n");
15754               return -99;
15755             }
15756           this_low = tmp;
15757           /* Note: in debug CLI +1 is added to high before
15758              passing to real fn that does "the work"
15759              (ip_source_and_port_range_check_add_del).
15760              This fn is a wrapper around the binary API fn a
15761              control plane will call, which expects this increment
15762              to have occurred. Hence letting the binary API control
15763              plane fn do the increment for consistency between VAT
15764              and other control planes.
15765            */
15766           this_hi = tmp2;
15767           vec_add1 (low_ports, this_low);
15768           vec_add1 (high_ports, this_hi);
15769         }
15770       else
15771         break;
15772     }
15773
15774   if (prefix_set == 0)
15775     {
15776       errmsg ("<address>/<mask> not specified\n");
15777       return -99;
15778     }
15779
15780   if (vrf_id == ~0)
15781     {
15782       errmsg ("VRF ID required, not specified\n");
15783       return -99;
15784     }
15785
15786   if (vrf_id == 0)
15787     {
15788       errmsg
15789         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15790       return -99;
15791     }
15792
15793   if (vec_len (low_ports) == 0)
15794     {
15795       errmsg ("At least one port or port range required\n");
15796       return -99;
15797     }
15798
15799   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15800      ip_source_and_port_range_check_add_del);
15801
15802   mp->is_add = is_add;
15803
15804   if (is_ipv6)
15805     {
15806       mp->is_ipv6 = 1;
15807       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15808     }
15809   else
15810     {
15811       mp->is_ipv6 = 0;
15812       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15813     }
15814
15815   mp->mask_length = length;
15816   mp->number_of_ranges = vec_len (low_ports);
15817
15818   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15819   vec_free (low_ports);
15820
15821   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15822   vec_free (high_ports);
15823
15824   mp->vrf_id = ntohl (vrf_id);
15825
15826   S;
15827   W;
15828   /* NOTREACHED */
15829   return 0;
15830 }
15831
15832 int
15833 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15834 {
15835   unformat_input_t *input = vam->input;
15836   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15837   f64 timeout;
15838   u32 sw_if_index = ~0;
15839   int vrf_set = 0;
15840   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15841   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15842   u8 is_add = 1;
15843
15844   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15845     {
15846       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15847         ;
15848       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15849         ;
15850       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15851         vrf_set = 1;
15852       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15853         vrf_set = 1;
15854       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15855         vrf_set = 1;
15856       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15857         vrf_set = 1;
15858       else if (unformat (input, "del"))
15859         is_add = 0;
15860       else
15861         break;
15862     }
15863
15864   if (sw_if_index == ~0)
15865     {
15866       errmsg ("Interface required but not specified\n");
15867       return -99;
15868     }
15869
15870   if (vrf_set == 0)
15871     {
15872       errmsg ("VRF ID required but not specified\n");
15873       return -99;
15874     }
15875
15876   if (tcp_out_vrf_id == 0
15877       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15878     {
15879       errmsg
15880         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15881       return -99;
15882     }
15883
15884   /* Construct the API message */
15885   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15886      ip_source_and_port_range_check_interface_add_del);
15887
15888   mp->sw_if_index = ntohl (sw_if_index);
15889   mp->is_add = is_add;
15890   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15891   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15892   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15893   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15894
15895   /* send it... */
15896   S;
15897
15898   /* Wait for a reply... */
15899   W;
15900 }
15901
15902 static int
15903 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15904 {
15905   unformat_input_t *i = vam->input;
15906   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15907   f64 timeout;
15908   u32 local_sa_id = 0;
15909   u32 remote_sa_id = 0;
15910   ip4_address_t src_address;
15911   ip4_address_t dst_address;
15912   u8 is_add = 1;
15913
15914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15915     {
15916       if (unformat (i, "local_sa %d", &local_sa_id))
15917         ;
15918       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15919         ;
15920       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15921         ;
15922       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15923         ;
15924       else if (unformat (i, "del"))
15925         is_add = 0;
15926       else
15927         {
15928           clib_warning ("parse error '%U'", format_unformat_error, i);
15929           return -99;
15930         }
15931     }
15932
15933   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15934
15935   mp->local_sa_id = ntohl (local_sa_id);
15936   mp->remote_sa_id = ntohl (remote_sa_id);
15937   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15938   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15939   mp->is_add = is_add;
15940
15941   S;
15942   W;
15943   /* NOTREACHED */
15944   return 0;
15945 }
15946
15947 static int
15948 api_punt (vat_main_t * vam)
15949 {
15950   unformat_input_t *i = vam->input;
15951   vl_api_punt_t *mp;
15952   f64 timeout;
15953   u32 ipv = ~0;
15954   u32 protocol = ~0;
15955   u32 port = ~0;
15956   int is_add = 1;
15957
15958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15959     {
15960       if (unformat (i, "ip %d", &ipv))
15961         ;
15962       else if (unformat (i, "protocol %d", &protocol))
15963         ;
15964       else if (unformat (i, "port %d", &port))
15965         ;
15966       else if (unformat (i, "del"))
15967         is_add = 0;
15968       else
15969         {
15970           clib_warning ("parse error '%U'", format_unformat_error, i);
15971           return -99;
15972         }
15973     }
15974
15975   M (PUNT, punt);
15976
15977   mp->is_add = (u8) is_add;
15978   mp->ipv = (u8) ipv;
15979   mp->l4_protocol = (u8) protocol;
15980   mp->l4_port = htons ((u16) port);
15981
15982   S;
15983   W;
15984   /* NOTREACHED */
15985   return 0;
15986 }
15987
15988 static void vl_api_ipsec_gre_tunnel_details_t_handler
15989   (vl_api_ipsec_gre_tunnel_details_t * mp)
15990 {
15991   vat_main_t *vam = &vat_main;
15992
15993   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15994            ntohl (mp->sw_if_index),
15995            format_ip4_address, &mp->src_address,
15996            format_ip4_address, &mp->dst_address,
15997            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15998 }
15999
16000 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16001   (vl_api_ipsec_gre_tunnel_details_t * mp)
16002 {
16003   vat_main_t *vam = &vat_main;
16004   vat_json_node_t *node = NULL;
16005   struct in_addr ip4;
16006
16007   if (VAT_JSON_ARRAY != vam->json_tree.type)
16008     {
16009       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16010       vat_json_init_array (&vam->json_tree);
16011     }
16012   node = vat_json_array_add (&vam->json_tree);
16013
16014   vat_json_init_object (node);
16015   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16016   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16017   vat_json_object_add_ip4 (node, "src_address", ip4);
16018   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16019   vat_json_object_add_ip4 (node, "dst_address", ip4);
16020   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16021   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16022 }
16023
16024 static int
16025 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16026 {
16027   unformat_input_t *i = vam->input;
16028   vl_api_ipsec_gre_tunnel_dump_t *mp;
16029   f64 timeout;
16030   u32 sw_if_index;
16031   u8 sw_if_index_set = 0;
16032
16033   /* Parse args required to build the message */
16034   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16035     {
16036       if (unformat (i, "sw_if_index %d", &sw_if_index))
16037         sw_if_index_set = 1;
16038       else
16039         break;
16040     }
16041
16042   if (sw_if_index_set == 0)
16043     {
16044       sw_if_index = ~0;
16045     }
16046
16047   if (!vam->json_output)
16048     {
16049       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
16050                "sw_if_index", "src_address", "dst_address",
16051                "local_sa_id", "remote_sa_id");
16052     }
16053
16054   /* Get list of gre-tunnel interfaces */
16055   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16056
16057   mp->sw_if_index = htonl (sw_if_index);
16058
16059   S;
16060
16061   /* Use a control ping for synchronization */
16062   {
16063     vl_api_control_ping_t *mp;
16064     M (CONTROL_PING, control_ping);
16065     S;
16066   }
16067   W;
16068 }
16069
16070 static int
16071 api_delete_subif (vat_main_t * vam)
16072 {
16073   unformat_input_t *i = vam->input;
16074   vl_api_delete_subif_t *mp;
16075   f64 timeout;
16076   u32 sw_if_index = ~0;
16077
16078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16079     {
16080       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16081         ;
16082       if (unformat (i, "sw_if_index %d", &sw_if_index))
16083         ;
16084       else
16085         break;
16086     }
16087
16088   if (sw_if_index == ~0)
16089     {
16090       errmsg ("missing sw_if_index\n");
16091       return -99;
16092     }
16093
16094   /* Construct the API message */
16095   M (DELETE_SUBIF, delete_subif);
16096   mp->sw_if_index = ntohl (sw_if_index);
16097
16098   S;
16099   W;
16100 }
16101
16102 #define foreach_pbb_vtr_op      \
16103 _("disable",  L2_VTR_DISABLED)  \
16104 _("pop",  L2_VTR_POP_2)         \
16105 _("push",  L2_VTR_PUSH_2)
16106
16107 static int
16108 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16109 {
16110   unformat_input_t *i = vam->input;
16111   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16112   f64 timeout;
16113   u32 sw_if_index = ~0, vtr_op = ~0;
16114   u16 outer_tag = ~0;
16115   u8 dmac[6], smac[6];
16116   u8 dmac_set = 0, smac_set = 0;
16117   u16 vlanid = 0;
16118   u32 sid = ~0;
16119   u32 tmp;
16120
16121   /* Shut up coverity */
16122   memset (dmac, 0, sizeof (dmac));
16123   memset (smac, 0, sizeof (smac));
16124
16125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16126     {
16127       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16128         ;
16129       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16130         ;
16131       else if (unformat (i, "vtr_op %d", &vtr_op))
16132         ;
16133 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16134       foreach_pbb_vtr_op
16135 #undef _
16136         else if (unformat (i, "translate_pbb_stag"))
16137         {
16138           if (unformat (i, "%d", &tmp))
16139             {
16140               vtr_op = L2_VTR_TRANSLATE_2_1;
16141               outer_tag = tmp;
16142             }
16143           else
16144             {
16145               errmsg
16146                 ("translate_pbb_stag operation requires outer tag definition\n");
16147               return -99;
16148             }
16149         }
16150       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16151         dmac_set++;
16152       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16153         smac_set++;
16154       else if (unformat (i, "sid %d", &sid))
16155         ;
16156       else if (unformat (i, "vlanid %d", &tmp))
16157         vlanid = tmp;
16158       else
16159         {
16160           clib_warning ("parse error '%U'", format_unformat_error, i);
16161           return -99;
16162         }
16163     }
16164
16165   if ((sw_if_index == ~0) || (vtr_op == ~0))
16166     {
16167       errmsg ("missing sw_if_index or vtr operation\n");
16168       return -99;
16169     }
16170   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16171       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16172     {
16173       errmsg
16174         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
16175       return -99;
16176     }
16177
16178   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16179   mp->sw_if_index = ntohl (sw_if_index);
16180   mp->vtr_op = ntohl (vtr_op);
16181   mp->outer_tag = ntohs (outer_tag);
16182   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16183   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16184   mp->b_vlanid = ntohs (vlanid);
16185   mp->i_sid = ntohl (sid);
16186
16187   S;
16188   W;
16189   /* NOTREACHED */
16190   return 0;
16191 }
16192
16193 static int
16194 api_flow_classify_set_interface (vat_main_t * vam)
16195 {
16196   unformat_input_t *i = vam->input;
16197   vl_api_flow_classify_set_interface_t *mp;
16198   f64 timeout;
16199   u32 sw_if_index;
16200   int sw_if_index_set;
16201   u32 ip4_table_index = ~0;
16202   u32 ip6_table_index = ~0;
16203   u8 is_add = 1;
16204
16205   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16206     {
16207       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16208         sw_if_index_set = 1;
16209       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16210         sw_if_index_set = 1;
16211       else if (unformat (i, "del"))
16212         is_add = 0;
16213       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16214         ;
16215       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16216         ;
16217       else
16218         {
16219           clib_warning ("parse error '%U'", format_unformat_error, i);
16220           return -99;
16221         }
16222     }
16223
16224   if (sw_if_index_set == 0)
16225     {
16226       errmsg ("missing interface name or sw_if_index\n");
16227       return -99;
16228     }
16229
16230   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16231
16232   mp->sw_if_index = ntohl (sw_if_index);
16233   mp->ip4_table_index = ntohl (ip4_table_index);
16234   mp->ip6_table_index = ntohl (ip6_table_index);
16235   mp->is_add = is_add;
16236
16237   S;
16238   W;
16239   /* NOTREACHED */
16240   return 0;
16241 }
16242
16243 static int
16244 api_flow_classify_dump (vat_main_t * vam)
16245 {
16246   unformat_input_t *i = vam->input;
16247   vl_api_flow_classify_dump_t *mp;
16248   f64 timeout = ~0;
16249   u8 type = FLOW_CLASSIFY_N_TABLES;
16250
16251   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16252     ;
16253   else
16254     {
16255       errmsg ("classify table type must be specified\n");
16256       return -99;
16257     }
16258
16259   if (!vam->json_output)
16260     {
16261       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
16262     }
16263
16264   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16265   mp->type = type;
16266   /* send it... */
16267   S;
16268
16269   /* Use a control ping for synchronization */
16270   {
16271     vl_api_control_ping_t *mp;
16272     M (CONTROL_PING, control_ping);
16273     S;
16274   }
16275   /* Wait for a reply... */
16276   W;
16277
16278   /* NOTREACHED */
16279   return 0;
16280 }
16281
16282 static int
16283 q_or_quit (vat_main_t * vam)
16284 {
16285   longjmp (vam->jump_buf, 1);
16286   return 0;                     /* not so much */
16287 }
16288
16289 static int
16290 q (vat_main_t * vam)
16291 {
16292   return q_or_quit (vam);
16293 }
16294
16295 static int
16296 quit (vat_main_t * vam)
16297 {
16298   return q_or_quit (vam);
16299 }
16300
16301 static int
16302 comment (vat_main_t * vam)
16303 {
16304   return 0;
16305 }
16306
16307 static int
16308 cmd_cmp (void *a1, void *a2)
16309 {
16310   u8 **c1 = a1;
16311   u8 **c2 = a2;
16312
16313   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
16314 }
16315
16316 static int
16317 help (vat_main_t * vam)
16318 {
16319   u8 **cmds = 0;
16320   u8 *name = 0;
16321   hash_pair_t *p;
16322   unformat_input_t *i = vam->input;
16323   int j;
16324
16325   if (unformat (i, "%s", &name))
16326     {
16327       uword *hs;
16328
16329       vec_add1 (name, 0);
16330
16331       hs = hash_get_mem (vam->help_by_name, name);
16332       if (hs)
16333         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
16334       else
16335         fformat (vam->ofp, "No such msg / command '%s'\n", name);
16336       vec_free (name);
16337       return 0;
16338     }
16339
16340   fformat (vam->ofp, "Help is available for the following:\n");
16341
16342     /* *INDENT-OFF* */
16343     hash_foreach_pair (p, vam->function_by_name,
16344     ({
16345       vec_add1 (cmds, (u8 *)(p->key));
16346     }));
16347     /* *INDENT-ON* */
16348
16349   vec_sort_with_function (cmds, cmd_cmp);
16350
16351   for (j = 0; j < vec_len (cmds); j++)
16352     fformat (vam->ofp, "%s\n", cmds[j]);
16353
16354   vec_free (cmds);
16355   return 0;
16356 }
16357
16358 static int
16359 set (vat_main_t * vam)
16360 {
16361   u8 *name = 0, *value = 0;
16362   unformat_input_t *i = vam->input;
16363
16364   if (unformat (i, "%s", &name))
16365     {
16366       /* The input buffer is a vector, not a string. */
16367       value = vec_dup (i->buffer);
16368       vec_delete (value, i->index, 0);
16369       /* Almost certainly has a trailing newline */
16370       if (value[vec_len (value) - 1] == '\n')
16371         value[vec_len (value) - 1] = 0;
16372       /* Make sure it's a proper string, one way or the other */
16373       vec_add1 (value, 0);
16374       (void) clib_macro_set_value (&vam->macro_main,
16375                                    (char *) name, (char *) value);
16376     }
16377   else
16378     errmsg ("usage: set <name> <value>\n");
16379
16380   vec_free (name);
16381   vec_free (value);
16382   return 0;
16383 }
16384
16385 static int
16386 unset (vat_main_t * vam)
16387 {
16388   u8 *name = 0;
16389
16390   if (unformat (vam->input, "%s", &name))
16391     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
16392       errmsg ("unset: %s wasn't set\n", name);
16393   vec_free (name);
16394   return 0;
16395 }
16396
16397 typedef struct
16398 {
16399   u8 *name;
16400   u8 *value;
16401 } macro_sort_t;
16402
16403
16404 static int
16405 macro_sort_cmp (void *a1, void *a2)
16406 {
16407   macro_sort_t *s1 = a1;
16408   macro_sort_t *s2 = a2;
16409
16410   return strcmp ((char *) (s1->name), (char *) (s2->name));
16411 }
16412
16413 static int
16414 dump_macro_table (vat_main_t * vam)
16415 {
16416   macro_sort_t *sort_me = 0, *sm;
16417   int i;
16418   hash_pair_t *p;
16419
16420     /* *INDENT-OFF* */
16421     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
16422     ({
16423       vec_add2 (sort_me, sm, 1);
16424       sm->name = (u8 *)(p->key);
16425       sm->value = (u8 *) (p->value[0]);
16426     }));
16427     /* *INDENT-ON* */
16428
16429   vec_sort_with_function (sort_me, macro_sort_cmp);
16430
16431   if (vec_len (sort_me))
16432     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
16433   else
16434     fformat (vam->ofp, "The macro table is empty...\n");
16435
16436   for (i = 0; i < vec_len (sort_me); i++)
16437     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
16438   return 0;
16439 }
16440
16441 static int
16442 dump_node_table (vat_main_t * vam)
16443 {
16444   int i, j;
16445   vlib_node_t *node, *next_node;
16446
16447   if (vec_len (vam->graph_nodes) == 0)
16448     {
16449       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16450       return 0;
16451     }
16452
16453   for (i = 0; i < vec_len (vam->graph_nodes); i++)
16454     {
16455       node = vam->graph_nodes[i];
16456       fformat (vam->ofp, "[%d] %s\n", i, node->name);
16457       for (j = 0; j < vec_len (node->next_nodes); j++)
16458         {
16459           if (node->next_nodes[j] != ~0)
16460             {
16461               next_node = vam->graph_nodes[node->next_nodes[j]];
16462               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16463             }
16464         }
16465     }
16466   return 0;
16467 }
16468
16469 static int
16470 search_node_table (vat_main_t * vam)
16471 {
16472   unformat_input_t *line_input = vam->input;
16473   u8 *node_to_find;
16474   int j;
16475   vlib_node_t *node, *next_node;
16476   uword *p;
16477
16478   if (vam->graph_node_index_by_name == 0)
16479     {
16480       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16481       return 0;
16482     }
16483
16484   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16485     {
16486       if (unformat (line_input, "%s", &node_to_find))
16487         {
16488           vec_add1 (node_to_find, 0);
16489           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
16490           if (p == 0)
16491             {
16492               fformat (vam->ofp, "%s not found...\n", node_to_find);
16493               goto out;
16494             }
16495           node = vam->graph_nodes[p[0]];
16496           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
16497           for (j = 0; j < vec_len (node->next_nodes); j++)
16498             {
16499               if (node->next_nodes[j] != ~0)
16500                 {
16501                   next_node = vam->graph_nodes[node->next_nodes[j]];
16502                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16503                 }
16504             }
16505         }
16506
16507       else
16508         {
16509           clib_warning ("parse error '%U'", format_unformat_error,
16510                         line_input);
16511           return -99;
16512         }
16513
16514     out:
16515       vec_free (node_to_find);
16516
16517     }
16518
16519   return 0;
16520 }
16521
16522
16523 static int
16524 script (vat_main_t * vam)
16525 {
16526   u8 *s = 0;
16527   char *save_current_file;
16528   unformat_input_t save_input;
16529   jmp_buf save_jump_buf;
16530   u32 save_line_number;
16531
16532   FILE *new_fp, *save_ifp;
16533
16534   if (unformat (vam->input, "%s", &s))
16535     {
16536       new_fp = fopen ((char *) s, "r");
16537       if (new_fp == 0)
16538         {
16539           errmsg ("Couldn't open script file %s\n", s);
16540           vec_free (s);
16541           return -99;
16542         }
16543     }
16544   else
16545     {
16546       errmsg ("Missing script name\n");
16547       return -99;
16548     }
16549
16550   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
16551   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
16552   save_ifp = vam->ifp;
16553   save_line_number = vam->input_line_number;
16554   save_current_file = (char *) vam->current_file;
16555
16556   vam->input_line_number = 0;
16557   vam->ifp = new_fp;
16558   vam->current_file = s;
16559   do_one_file (vam);
16560
16561   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
16562   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
16563   vam->ifp = save_ifp;
16564   vam->input_line_number = save_line_number;
16565   vam->current_file = (u8 *) save_current_file;
16566   vec_free (s);
16567
16568   return 0;
16569 }
16570
16571 static int
16572 echo (vat_main_t * vam)
16573 {
16574   fformat (vam->ofp, "%v", vam->input->buffer);
16575   return 0;
16576 }
16577
16578 /* List of API message constructors, CLI names map to api_xxx */
16579 #define foreach_vpe_api_msg                                             \
16580 _(create_loopback,"[mac <mac-addr>]")                                   \
16581 _(sw_interface_dump,"")                                                 \
16582 _(sw_interface_set_flags,                                               \
16583   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
16584 _(sw_interface_add_del_address,                                         \
16585   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
16586 _(sw_interface_set_table,                                               \
16587   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
16588 _(sw_interface_set_mpls_enable,                                                \
16589   "<intfc> | sw_if_index [disable | dis]")                                \
16590 _(sw_interface_set_vpath,                                               \
16591   "<intfc> | sw_if_index <id> enable | disable")                        \
16592 _(sw_interface_set_l2_xconnect,                                         \
16593   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16594   "enable | disable")                                                   \
16595 _(sw_interface_set_l2_bridge,                                           \
16596   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16597   "[shg <split-horizon-group>] [bvi]\n"                                 \
16598   "enable | disable")                                                   \
16599 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16600   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16601   "profile <profile-id>\n")                                             \
16602 _(sw_interface_set_dpdk_hqos_subport,                                   \
16603   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16604   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16605 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16606   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16607 _(bridge_domain_add_del,                                                \
16608   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16609 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16610 _(l2fib_add_del,                                                        \
16611   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16612 _(l2_flags,                                                             \
16613   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16614 _(bridge_flags,                                                         \
16615   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16616 _(tap_connect,                                                          \
16617   "tapname <name> mac <mac-addr> | random-mac")                         \
16618 _(tap_modify,                                                           \
16619   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16620 _(tap_delete,                                                           \
16621   "<vpp-if-name> | sw_if_index <id>")                                   \
16622 _(sw_interface_tap_dump, "")                                            \
16623 _(ip_add_del_route,                                                     \
16624   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
16625   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16626   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16627   "[multipath] [count <n>]")                                            \
16628 _(mpls_route_add_del,                                                   \
16629   "<label> <eos> via <addr> [table-id <n>]\n"                           \
16630   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16631   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16632   "[multipath] [count <n>]")                                            \
16633 _(mpls_ip_bind_unbind,                                                  \
16634   "<label> <addr/len>")                                                 \
16635 _(proxy_arp_add_del,                                                    \
16636   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16637 _(proxy_arp_intfc_enable_disable,                                       \
16638   "<intfc> | sw_if_index <id> enable | disable")                        \
16639 _(mpls_add_del_encap,                                                   \
16640   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
16641 _(sw_interface_set_unnumbered,                                          \
16642   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16643 _(ip_neighbor_add_del,                                                  \
16644   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16645   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16646 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16647 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16648 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16649   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16650   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16651   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16652 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16653 _(reset_fib, "vrf <n> [ipv6]")                                          \
16654 _(dhcp_proxy_config,                                                    \
16655   "svr <v46-address> src <v46-address>\n"                               \
16656    "insert-cid <n> [del]")                                              \
16657 _(dhcp_proxy_config_2,                                                  \
16658   "svr <v46-address> src <v46-address>\n"                               \
16659    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16660 _(dhcp_proxy_set_vss,                                                   \
16661   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16662 _(dhcp_client_config,                                                   \
16663   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16664 _(set_ip_flow_hash,                                                     \
16665   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16666 _(sw_interface_ip6_enable_disable,                                      \
16667   "<intfc> | sw_if_index <id> enable | disable")                        \
16668 _(sw_interface_ip6_set_link_local_address,                              \
16669   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16670 _(sw_interface_ip6nd_ra_prefix,                                         \
16671   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16672   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16673   "[nolink] [isno]")                                                    \
16674 _(sw_interface_ip6nd_ra_config,                                         \
16675   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16676   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16677   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16678 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16679 _(l2_patch_add_del,                                                     \
16680   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16681   "enable | disable")                                                   \
16682 _(mpls_ethernet_add_del_tunnel,                                         \
16683   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
16684   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
16685 _(mpls_ethernet_add_del_tunnel_2,                                       \
16686   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
16687   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
16688 _(sr_tunnel_add_del,                                                    \
16689   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16690   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16691   "[policy <policy_name>]")                                             \
16692 _(sr_policy_add_del,                                                    \
16693   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16694 _(sr_multicast_map_add_del,                                             \
16695   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16696 _(classify_add_del_table,                                               \
16697   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16698   " [del] mask <mask-value>\n"                                          \
16699   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
16700   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
16701 _(classify_add_del_session,                                             \
16702   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16703   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16704   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
16705   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
16706 _(classify_set_interface_ip_table,                                      \
16707   "<intfc> | sw_if_index <nn> table <nn>")                              \
16708 _(classify_set_interface_l2_tables,                                     \
16709   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16710   "  [other-table <nn>]")                                               \
16711 _(get_node_index, "node <node-name")                                    \
16712 _(add_node_next, "node <node-name> next <next-node-name>")              \
16713 _(l2tpv3_create_tunnel,                                                 \
16714   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16715   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16716   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16717 _(l2tpv3_set_tunnel_cookies,                                            \
16718   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16719   "[new_remote_cookie <nn>]\n")                                         \
16720 _(l2tpv3_interface_enable_disable,                                      \
16721   "<intfc> | sw_if_index <nn> enable | disable")                        \
16722 _(l2tpv3_set_lookup_key,                                                \
16723   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16724 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16725 _(vxlan_add_del_tunnel,                                                 \
16726   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
16727   " [decap-next l2|ip4|ip6] [del]")                                     \
16728 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16729 _(gre_add_del_tunnel,                                                   \
16730   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16731 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16732 _(l2_fib_clear_table, "")                                               \
16733 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16734 _(l2_interface_vlan_tag_rewrite,                                        \
16735   "<intfc> | sw_if_index <nn> \n"                                       \
16736   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
16737   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
16738 _(create_vhost_user_if,                                                 \
16739         "socket <filename> [server] [renumber <dev_instance>] "         \
16740         "[mac <mac_address>]")                                          \
16741 _(modify_vhost_user_if,                                                 \
16742         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
16743         "[server] [renumber <dev_instance>]")                           \
16744 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
16745 _(sw_interface_vhost_user_dump, "")                                     \
16746 _(show_version, "")                                                     \
16747 _(vxlan_gpe_add_del_tunnel,                                             \
16748   "local <addr> remote <addr> vni <nn>\n"                               \
16749     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
16750   "[next-ethernet] [next-nsh]\n")                                       \
16751 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
16752 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
16753 _(interface_name_renumber,                                              \
16754   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
16755 _(input_acl_set_interface,                                              \
16756   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16757   "  [l2-table <nn>] [del]")                                            \
16758 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
16759 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
16760 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
16761 _(ip_dump, "ipv4 | ipv6")                                               \
16762 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
16763 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
16764   "  spid_id <n> ")                                                     \
16765 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
16766   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
16767   "  integ_alg <alg> integ_key <hex>")                                  \
16768 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
16769   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
16770   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
16771   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
16772 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
16773 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
16774 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
16775   "(auth_data 0x<data> | auth_data <data>)")                            \
16776 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
16777   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
16778 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16779   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16780   "(local|remote)")                                                     \
16781 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16782 _(delete_loopback,"sw_if_index <nn>")                                   \
16783 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16784 _(map_add_domain,                                                       \
16785   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16786   "ip6-src <ip6addr> "                                                  \
16787   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16788 _(map_del_domain, "index <n>")                                          \
16789 _(map_add_del_rule,                                                     \
16790   "index <n> psid <n> dst <ip6addr> [del]")                             \
16791 _(map_domain_dump, "")                                                  \
16792 _(map_rule_dump, "index <map-domain>")                                  \
16793 _(want_interface_events,  "enable|disable")                             \
16794 _(want_stats,"enable|disable")                                          \
16795 _(get_first_msg_id, "client <name>")                                    \
16796 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16797 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16798   "fib-id <nn> [ip4][ip6][default]")                                    \
16799 _(get_node_graph, " ")                                                  \
16800 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16801 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16802 _(ioam_disable, "")                                                \
16803 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16804                             " sw_if_index <sw_if_index> p <priority> "  \
16805                             "w <weight>] [del]")                        \
16806 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16807                         "iface <intf> | sw_if_index <sw_if_index> "     \
16808                         "p <priority> w <weight> [del]")                \
16809 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16810                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16811                           "locator-set <locator_name> [del]")           \
16812 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16813   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16814 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16815 _(lisp_gpe_enable_disable, "enable|disable")                            \
16816 _(lisp_enable_disable, "enable|disable")                                \
16817 _(lisp_gpe_add_del_iface, "up|down")                                    \
16818 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
16819                                "[seid <seid>] "                         \
16820                                "rloc <locator> p <prio> "               \
16821                                "w <weight> [rloc <loc> ... ] "          \
16822                                "action <action> [del-all]")             \
16823 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
16824                           "<local-eid>")                                \
16825 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16826 _(lisp_map_request_mode, "src-dst|dst-only")                            \
16827 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16828 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16829 _(lisp_locator_set_dump, "[local | remote]")                            \
16830 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
16831 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16832                        "[local] | [remote]")                            \
16833 _(lisp_eid_table_vni_dump, "")                                          \
16834 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16835 _(lisp_gpe_tunnel_dump, "")                                             \
16836 _(lisp_map_resolver_dump, "")                                           \
16837 _(lisp_adjacencies_get, "vni <vni>")                                    \
16838 _(show_lisp_status, "")                                                 \
16839 _(lisp_get_map_request_itr_rlocs, "")                                   \
16840 _(show_lisp_pitr, "")                                                   \
16841 _(show_lisp_map_request_mode, "")                                       \
16842 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16843 _(af_packet_delete, "name <host interface name>")                       \
16844 _(policer_add_del, "name <policer name> <params> [del]")                \
16845 _(policer_dump, "[name <policer name>]")                                \
16846 _(policer_classify_set_interface,                                       \
16847   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16848   "  [l2-table <nn>] [del]")                                            \
16849 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16850 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16851     "[master|slave]")                                                   \
16852 _(netmap_delete, "name <interface name>")                               \
16853 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16854 _(mpls_fib_encap_dump, "")                                              \
16855 _(mpls_fib_dump, "")                                                    \
16856 _(classify_table_ids, "")                                               \
16857 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16858 _(classify_table_info, "table_id <nn>")                                 \
16859 _(classify_session_dump, "table_id <nn>")                               \
16860 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
16861     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
16862     "[template_interval <nn>] [udp_checksum]")                          \
16863 _(ipfix_exporter_dump, "")                                              \
16864 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
16865 _(ipfix_classify_stream_dump, "")                                       \
16866 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
16867 _(ipfix_classify_table_dump, "")                                        \
16868 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [[dst <intfc> | dst_sw_if_index <id>] | disable]") \
16869 _(sw_interface_span_dump, "")                                           \
16870 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
16871 _(pg_create_interface, "if_id <nn>")                                    \
16872 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
16873 _(pg_enable_disable, "[stream <id>] disable")                           \
16874 _(ip_source_and_port_range_check_add_del,                               \
16875   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
16876 _(ip_source_and_port_range_check_interface_add_del,                     \
16877   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
16878   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
16879 _(ipsec_gre_add_del_tunnel,                                             \
16880   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
16881 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
16882 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
16883 _(l2_interface_pbb_tag_rewrite,                                         \
16884   "<intfc> | sw_if_index <nn> \n"                                       \
16885   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
16886   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
16887 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
16888 _(flow_classify_set_interface,                                          \
16889   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
16890 _(flow_classify_dump, "type [ip4|ip6]")                                 \
16891 _(ip_fib_dump, "")                                                      \
16892 _(ip6_fib_dump, "")
16893
16894 /* List of command functions, CLI names map directly to functions */
16895 #define foreach_cli_function                                    \
16896 _(comment, "usage: comment <ignore-rest-of-line>")              \
16897 _(dump_interface_table, "usage: dump_interface_table")          \
16898 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
16899 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
16900 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
16901 _(dump_stats_table, "usage: dump_stats_table")                  \
16902 _(dump_macro_table, "usage: dump_macro_table ")                 \
16903 _(dump_node_table, "usage: dump_node_table")                    \
16904 _(echo, "usage: echo <message>")                                \
16905 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
16906 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
16907 _(help, "usage: help")                                          \
16908 _(q, "usage: quit")                                             \
16909 _(quit, "usage: quit")                                          \
16910 _(search_node_table, "usage: search_node_table <name>...")      \
16911 _(set, "usage: set <variable-name> <value>")                    \
16912 _(script, "usage: script <file-name>")                          \
16913 _(unset, "usage: unset <variable-name>")
16914
16915 #define _(N,n)                                  \
16916     static void vl_api_##n##_t_handler_uni      \
16917     (vl_api_##n##_t * mp)                       \
16918     {                                           \
16919         vat_main_t * vam = &vat_main;           \
16920         if (vam->json_output) {                 \
16921             vl_api_##n##_t_handler_json(mp);    \
16922         } else {                                \
16923             vl_api_##n##_t_handler(mp);         \
16924         }                                       \
16925     }
16926 foreach_vpe_api_reply_msg;
16927 #undef _
16928
16929 void
16930 vat_api_hookup (vat_main_t * vam)
16931 {
16932 #define _(N,n)                                                  \
16933     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
16934                            vl_api_##n##_t_handler_uni,          \
16935                            vl_noop_handler,                     \
16936                            vl_api_##n##_t_endian,               \
16937                            vl_api_##n##_t_print,                \
16938                            sizeof(vl_api_##n##_t), 1);
16939   foreach_vpe_api_reply_msg;
16940 #undef _
16941
16942   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
16943
16944   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
16945
16946   vam->function_by_name = hash_create_string (0, sizeof (uword));
16947
16948   vam->help_by_name = hash_create_string (0, sizeof (uword));
16949
16950   /* API messages we can send */
16951 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
16952   foreach_vpe_api_msg;
16953 #undef _
16954
16955   /* Help strings */
16956 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16957   foreach_vpe_api_msg;
16958 #undef _
16959
16960   /* CLI functions */
16961 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
16962   foreach_cli_function;
16963 #undef _
16964
16965   /* Help strings */
16966 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16967   foreach_cli_function;
16968 #undef _
16969 }
16970
16971 #undef vl_api_version
16972 #define vl_api_version(n,v) static u32 vpe_api_version = v;
16973 #include <vpp-api/vpe.api.h>
16974 #undef vl_api_version
16975
16976 void
16977 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
16978 {
16979   /*
16980    * Send the main API signature in slot 0. This bit of code must
16981    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
16982    */
16983   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
16984 }
16985
16986 /*
16987  * fd.io coding-style-patch-verification: ON
16988  *
16989  * Local Variables:
16990  * eval: (c-set-style "gnu")
16991  * End:
16992  */