span: add feature (rx only) (VPP-185)
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #if DPDK > 0
41 #include <vnet/ipsec/ipsec.h>
42 #include <vnet/ipsec/ikev2.h>
43 #else
44 #include <inttypes.h>
45 #endif
46 #include <vnet/map/map.h>
47 #include <vnet/cop/cop.h>
48 #include <vnet/ip/ip6_hop_by_hop.h>
49 #include <vnet/ip/ip_source_and_port_range_check.h>
50 #include <vnet/policer/xlate.h>
51 #include <vnet/span/span.h>
52 #include <vnet/policer/policer.h>
53 #include <vnet/policer/police.h>
54
55 #include "vat/json_format.h"
56
57 #include <sys/stat.h>
58
59 #define vl_typedefs             /* define message structures */
60 #include <vpp-api/vpe_all_api_h.h>
61 #undef vl_typedefs
62
63 /* declare message handlers for each api */
64
65 #define vl_endianfun            /* define message structures */
66 #include <vpp-api/vpe_all_api_h.h>
67 #undef vl_endianfun
68
69 /* instantiate all the print functions we know about */
70 #define vl_print(handle, ...)
71 #define vl_printfun
72 #include <vpp-api/vpe_all_api_h.h>
73 #undef vl_printfun
74
75 uword
76 unformat_sw_if_index (unformat_input_t * input, va_list * args)
77 {
78   vat_main_t *vam = va_arg (*args, vat_main_t *);
79   u32 *result = va_arg (*args, u32 *);
80   u8 *if_name;
81   uword *p;
82
83   if (!unformat (input, "%s", &if_name))
84     return 0;
85
86   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
87   if (p == 0)
88     return 0;
89   *result = p[0];
90   return 1;
91 }
92
93 /* Parse an IP4 address %d.%d.%d.%d. */
94 uword
95 unformat_ip4_address (unformat_input_t * input, va_list * args)
96 {
97   u8 *result = va_arg (*args, u8 *);
98   unsigned a[4];
99
100   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
101     return 0;
102
103   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
104     return 0;
105
106   result[0] = a[0];
107   result[1] = a[1];
108   result[2] = a[2];
109   result[3] = a[3];
110
111   return 1;
112 }
113
114
115 uword
116 unformat_ethernet_address (unformat_input_t * input, va_list * args)
117 {
118   u8 *result = va_arg (*args, u8 *);
119   u32 i, a[6];
120
121   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
122                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
123     return 0;
124
125   /* Check range. */
126   for (i = 0; i < 6; i++)
127     if (a[i] >= (1 << 8))
128       return 0;
129
130   for (i = 0; i < 6; i++)
131     result[i] = a[i];
132
133   return 1;
134 }
135
136 /* Returns ethernet type as an int in host byte order. */
137 uword
138 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
139                                         va_list * args)
140 {
141   u16 *result = va_arg (*args, u16 *);
142   int type;
143
144   /* Numeric type. */
145   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
146     {
147       if (type >= (1 << 16))
148         return 0;
149       *result = type;
150       return 1;
151     }
152   return 0;
153 }
154
155 /* Parse an IP6 address. */
156 uword
157 unformat_ip6_address (unformat_input_t * input, va_list * args)
158 {
159   ip6_address_t *result = va_arg (*args, ip6_address_t *);
160   u16 hex_quads[8];
161   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
162   uword c, n_colon, double_colon_index;
163
164   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
165   double_colon_index = ARRAY_LEN (hex_quads);
166   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
167     {
168       hex_digit = 16;
169       if (c >= '0' && c <= '9')
170         hex_digit = c - '0';
171       else if (c >= 'a' && c <= 'f')
172         hex_digit = c + 10 - 'a';
173       else if (c >= 'A' && c <= 'F')
174         hex_digit = c + 10 - 'A';
175       else if (c == ':' && n_colon < 2)
176         n_colon++;
177       else
178         {
179           unformat_put_input (input);
180           break;
181         }
182
183       /* Too many hex quads. */
184       if (n_hex_quads >= ARRAY_LEN (hex_quads))
185         return 0;
186
187       if (hex_digit < 16)
188         {
189           hex_quad = (hex_quad << 4) | hex_digit;
190
191           /* Hex quad must fit in 16 bits. */
192           if (n_hex_digits >= 4)
193             return 0;
194
195           n_colon = 0;
196           n_hex_digits++;
197         }
198
199       /* Save position of :: */
200       if (n_colon == 2)
201         {
202           /* More than one :: ? */
203           if (double_colon_index < ARRAY_LEN (hex_quads))
204             return 0;
205           double_colon_index = n_hex_quads;
206         }
207
208       if (n_colon > 0 && n_hex_digits > 0)
209         {
210           hex_quads[n_hex_quads++] = hex_quad;
211           hex_quad = 0;
212           n_hex_digits = 0;
213         }
214     }
215
216   if (n_hex_digits > 0)
217     hex_quads[n_hex_quads++] = hex_quad;
218
219   {
220     word i;
221
222     /* Expand :: to appropriate number of zero hex quads. */
223     if (double_colon_index < ARRAY_LEN (hex_quads))
224       {
225         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
226
227         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
228           hex_quads[n_zero + i] = hex_quads[i];
229
230         for (i = 0; i < n_zero; i++)
231           hex_quads[double_colon_index + i] = 0;
232
233         n_hex_quads = ARRAY_LEN (hex_quads);
234       }
235
236     /* Too few hex quads given. */
237     if (n_hex_quads < ARRAY_LEN (hex_quads))
238       return 0;
239
240     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
241       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
242
243     return 1;
244   }
245 }
246
247 uword
248 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
249 {
250 #if DPDK > 0
251   u32 *r = va_arg (*args, u32 *);
252
253   if (0);
254 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
255   foreach_ipsec_policy_action
256 #undef _
257     else
258     return 0;
259   return 1;
260 #else
261   return 0;
262 #endif
263 }
264
265 uword
266 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
267 {
268 #if DPDK > 0
269   u32 *r = va_arg (*args, u32 *);
270
271   if (0);
272 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
273   foreach_ipsec_crypto_alg
274 #undef _
275     else
276     return 0;
277   return 1;
278 #else
279   return 0;
280 #endif
281 }
282
283 u8 *
284 format_ipsec_crypto_alg (u8 * s, va_list * args)
285 {
286 #if DPDK > 0
287   u32 i = va_arg (*args, u32);
288   u8 *t = 0;
289
290   switch (i)
291     {
292 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
293       foreach_ipsec_crypto_alg
294 #undef _
295     default:
296       return format (s, "unknown");
297     }
298   return format (s, "%s", t);
299 #else
300   return format (s, "Unimplemented");
301 #endif
302 }
303
304 uword
305 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
306 {
307 #if DPDK > 0
308   u32 *r = va_arg (*args, u32 *);
309
310   if (0);
311 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
312   foreach_ipsec_integ_alg
313 #undef _
314     else
315     return 0;
316   return 1;
317 #else
318   return 0;
319 #endif
320 }
321
322 u8 *
323 format_ipsec_integ_alg (u8 * s, va_list * args)
324 {
325 #if DPDK > 0
326   u32 i = va_arg (*args, u32);
327   u8 *t = 0;
328
329   switch (i)
330     {
331 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
332       foreach_ipsec_integ_alg
333 #undef _
334     default:
335       return format (s, "unknown");
336     }
337   return format (s, "%s", t);
338 #else
339   return format (s, "Unsupported");
340 #endif
341 }
342
343 uword
344 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
345 {
346 #if DPDK > 0
347   u32 *r = va_arg (*args, u32 *);
348
349   if (0);
350 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
351   foreach_ikev2_auth_method
352 #undef _
353     else
354     return 0;
355   return 1;
356 #else
357   return 0;
358 #endif
359 }
360
361 uword
362 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
363 {
364 #if DPDK > 0
365   u32 *r = va_arg (*args, u32 *);
366
367   if (0);
368 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
369   foreach_ikev2_id_type
370 #undef _
371     else
372     return 0;
373   return 1;
374 #else
375   return 0;
376 #endif
377 }
378
379 uword
380 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
381 {
382   u8 *r = va_arg (*args, u8 *);
383
384   if (unformat (input, "kbps"))
385     *r = SSE2_QOS_RATE_KBPS;
386   else if (unformat (input, "pps"))
387     *r = SSE2_QOS_RATE_PPS;
388   else
389     return 0;
390   return 1;
391 }
392
393 uword
394 unformat_policer_round_type (unformat_input_t * input, va_list * args)
395 {
396   u8 *r = va_arg (*args, u8 *);
397
398   if (unformat (input, "closest"))
399     *r = SSE2_QOS_ROUND_TO_CLOSEST;
400   else if (unformat (input, "up"))
401     *r = SSE2_QOS_ROUND_TO_UP;
402   else if (unformat (input, "down"))
403     *r = SSE2_QOS_ROUND_TO_DOWN;
404   else
405     return 0;
406   return 1;
407 }
408
409 uword
410 unformat_policer_type (unformat_input_t * input, va_list * args)
411 {
412   u8 *r = va_arg (*args, u8 *);
413
414   if (unformat (input, "1r2c"))
415     *r = SSE2_QOS_POLICER_TYPE_1R2C;
416   else if (unformat (input, "1r3c"))
417     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
418   else if (unformat (input, "2r3c-2698"))
419     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
420   else if (unformat (input, "2r3c-4115"))
421     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
422   else if (unformat (input, "2r3c-mef5cf1"))
423     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
424   else
425     return 0;
426   return 1;
427 }
428
429 uword
430 unformat_dscp (unformat_input_t * input, va_list * va)
431 {
432   u8 *r = va_arg (*va, u8 *);
433
434   if (0);
435 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
436   foreach_vnet_dscp
437 #undef _
438     else
439     return 0;
440   return 1;
441 }
442
443 uword
444 unformat_policer_action_type (unformat_input_t * input, va_list * va)
445 {
446   sse2_qos_pol_action_params_st *a
447     = va_arg (*va, sse2_qos_pol_action_params_st *);
448
449   if (unformat (input, "drop"))
450     a->action_type = SSE2_QOS_ACTION_DROP;
451   else if (unformat (input, "transmit"))
452     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
453   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
454     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
455   else
456     return 0;
457   return 1;
458 }
459
460 uword
461 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
462 {
463   u32 *r = va_arg (*va, u32 *);
464   u32 tid;
465
466   if (unformat (input, "ip4"))
467     tid = POLICER_CLASSIFY_TABLE_IP4;
468   else if (unformat (input, "ip6"))
469     tid = POLICER_CLASSIFY_TABLE_IP6;
470   else if (unformat (input, "l2"))
471     tid = POLICER_CLASSIFY_TABLE_L2;
472   else
473     return 0;
474
475   *r = tid;
476   return 1;
477 }
478
479 uword
480 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
481 {
482   u32 *r = va_arg (*va, u32 *);
483   u32 tid;
484
485   if (unformat (input, "ip4"))
486     tid = FLOW_CLASSIFY_TABLE_IP4;
487   else if (unformat (input, "ip6"))
488     tid = FLOW_CLASSIFY_TABLE_IP6;
489   else
490     return 0;
491
492   *r = tid;
493   return 1;
494 }
495
496 u8 *
497 format_ip4_address (u8 * s, va_list * args)
498 {
499   u8 *a = va_arg (*args, u8 *);
500   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
501 }
502
503 u8 *
504 format_ip6_address (u8 * s, va_list * args)
505 {
506   ip6_address_t *a = va_arg (*args, ip6_address_t *);
507   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
508
509   i_max_n_zero = ARRAY_LEN (a->as_u16);
510   max_n_zeros = 0;
511   i_first_zero = i_max_n_zero;
512   n_zeros = 0;
513   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
514     {
515       u32 is_zero = a->as_u16[i] == 0;
516       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
517         {
518           i_first_zero = i;
519           n_zeros = 0;
520         }
521       n_zeros += is_zero;
522       if ((!is_zero && n_zeros > max_n_zeros)
523           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
524         {
525           i_max_n_zero = i_first_zero;
526           max_n_zeros = n_zeros;
527           i_first_zero = ARRAY_LEN (a->as_u16);
528           n_zeros = 0;
529         }
530     }
531
532   last_double_colon = 0;
533   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
534     {
535       if (i == i_max_n_zero && max_n_zeros > 1)
536         {
537           s = format (s, "::");
538           i += max_n_zeros - 1;
539           last_double_colon = 1;
540         }
541       else
542         {
543           s = format (s, "%s%x",
544                       (last_double_colon || i == 0) ? "" : ":",
545                       clib_net_to_host_u16 (a->as_u16[i]));
546           last_double_colon = 0;
547         }
548     }
549
550   return s;
551 }
552
553 /* Format an IP46 address. */
554 u8 *
555 format_ip46_address (u8 * s, va_list * args)
556 {
557   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
558   ip46_type_t type = va_arg (*args, ip46_type_t);
559   int is_ip4 = 1;
560
561   switch (type)
562     {
563     case IP46_TYPE_ANY:
564       is_ip4 = ip46_address_is_ip4 (ip46);
565       break;
566     case IP46_TYPE_IP4:
567       is_ip4 = 1;
568       break;
569     case IP46_TYPE_IP6:
570       is_ip4 = 0;
571       break;
572     }
573
574   return is_ip4 ?
575     format (s, "%U", format_ip4_address, &ip46->ip4) :
576     format (s, "%U", format_ip6_address, &ip46->ip6);
577 }
578
579 u8 *
580 format_ethernet_address (u8 * s, va_list * args)
581 {
582   u8 *a = va_arg (*args, u8 *);
583
584   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
585                  a[0], a[1], a[2], a[3], a[4], a[5]);
586 }
587
588 void
589 increment_v4_address (ip4_address_t * a)
590 {
591   u32 v;
592
593   v = ntohl (a->as_u32) + 1;
594   a->as_u32 = ntohl (v);
595 }
596
597 void
598 increment_v6_address (ip6_address_t * a)
599 {
600   u64 v0, v1;
601
602   v0 = clib_net_to_host_u64 (a->as_u64[0]);
603   v1 = clib_net_to_host_u64 (a->as_u64[1]);
604
605   v1 += 1;
606   if (v1 == 0)
607     v0 += 1;
608   a->as_u64[0] = clib_net_to_host_u64 (v0);
609   a->as_u64[1] = clib_net_to_host_u64 (v1);
610 }
611
612 void
613 increment_mac_address (u64 * mac)
614 {
615   u64 tmp = *mac;
616
617   tmp = clib_net_to_host_u64 (tmp);
618   tmp += 1 << 16;               /* skip unused (least significant) octets */
619   tmp = clib_host_to_net_u64 (tmp);
620   *mac = tmp;
621 }
622
623 static void vl_api_create_loopback_reply_t_handler
624   (vl_api_create_loopback_reply_t * mp)
625 {
626   vat_main_t *vam = &vat_main;
627   i32 retval = ntohl (mp->retval);
628
629   vam->retval = retval;
630   vam->regenerate_interface_table = 1;
631   vam->sw_if_index = ntohl (mp->sw_if_index);
632   vam->result_ready = 1;
633 }
634
635 static void vl_api_create_loopback_reply_t_handler_json
636   (vl_api_create_loopback_reply_t * mp)
637 {
638   vat_main_t *vam = &vat_main;
639   vat_json_node_t node;
640
641   vat_json_init_object (&node);
642   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
643   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
644
645   vat_json_print (vam->ofp, &node);
646   vat_json_free (&node);
647   vam->retval = ntohl (mp->retval);
648   vam->result_ready = 1;
649 }
650
651 static void vl_api_af_packet_create_reply_t_handler
652   (vl_api_af_packet_create_reply_t * mp)
653 {
654   vat_main_t *vam = &vat_main;
655   i32 retval = ntohl (mp->retval);
656
657   vam->retval = retval;
658   vam->regenerate_interface_table = 1;
659   vam->sw_if_index = ntohl (mp->sw_if_index);
660   vam->result_ready = 1;
661 }
662
663 static void vl_api_af_packet_create_reply_t_handler_json
664   (vl_api_af_packet_create_reply_t * mp)
665 {
666   vat_main_t *vam = &vat_main;
667   vat_json_node_t node;
668
669   vat_json_init_object (&node);
670   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
671   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
672
673   vat_json_print (vam->ofp, &node);
674   vat_json_free (&node);
675
676   vam->retval = ntohl (mp->retval);
677   vam->result_ready = 1;
678 }
679
680 static void vl_api_create_vlan_subif_reply_t_handler
681   (vl_api_create_vlan_subif_reply_t * mp)
682 {
683   vat_main_t *vam = &vat_main;
684   i32 retval = ntohl (mp->retval);
685
686   vam->retval = retval;
687   vam->regenerate_interface_table = 1;
688   vam->sw_if_index = ntohl (mp->sw_if_index);
689   vam->result_ready = 1;
690 }
691
692 static void vl_api_create_vlan_subif_reply_t_handler_json
693   (vl_api_create_vlan_subif_reply_t * mp)
694 {
695   vat_main_t *vam = &vat_main;
696   vat_json_node_t node;
697
698   vat_json_init_object (&node);
699   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
700   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
701
702   vat_json_print (vam->ofp, &node);
703   vat_json_free (&node);
704
705   vam->retval = ntohl (mp->retval);
706   vam->result_ready = 1;
707 }
708
709 static void vl_api_create_subif_reply_t_handler
710   (vl_api_create_subif_reply_t * mp)
711 {
712   vat_main_t *vam = &vat_main;
713   i32 retval = ntohl (mp->retval);
714
715   vam->retval = retval;
716   vam->regenerate_interface_table = 1;
717   vam->sw_if_index = ntohl (mp->sw_if_index);
718   vam->result_ready = 1;
719 }
720
721 static void vl_api_create_subif_reply_t_handler_json
722   (vl_api_create_subif_reply_t * mp)
723 {
724   vat_main_t *vam = &vat_main;
725   vat_json_node_t node;
726
727   vat_json_init_object (&node);
728   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
729   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
730
731   vat_json_print (vam->ofp, &node);
732   vat_json_free (&node);
733
734   vam->retval = ntohl (mp->retval);
735   vam->result_ready = 1;
736 }
737
738 static void vl_api_interface_name_renumber_reply_t_handler
739   (vl_api_interface_name_renumber_reply_t * mp)
740 {
741   vat_main_t *vam = &vat_main;
742   i32 retval = ntohl (mp->retval);
743
744   vam->retval = retval;
745   vam->regenerate_interface_table = 1;
746   vam->result_ready = 1;
747 }
748
749 static void vl_api_interface_name_renumber_reply_t_handler_json
750   (vl_api_interface_name_renumber_reply_t * mp)
751 {
752   vat_main_t *vam = &vat_main;
753   vat_json_node_t node;
754
755   vat_json_init_object (&node);
756   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
757
758   vat_json_print (vam->ofp, &node);
759   vat_json_free (&node);
760
761   vam->retval = ntohl (mp->retval);
762   vam->result_ready = 1;
763 }
764
765 /*
766  * Special-case: build the interface table, maintain
767  * the next loopback sw_if_index vbl.
768  */
769 static void vl_api_sw_interface_details_t_handler
770   (vl_api_sw_interface_details_t * mp)
771 {
772   vat_main_t *vam = &vat_main;
773   u8 *s = format (0, "%s%c", mp->interface_name, 0);
774
775   hash_set_mem (vam->sw_if_index_by_interface_name, s,
776                 ntohl (mp->sw_if_index));
777
778   /* In sub interface case, fill the sub interface table entry */
779   if (mp->sw_if_index != mp->sup_sw_if_index)
780     {
781       sw_interface_subif_t *sub = NULL;
782
783       vec_add2 (vam->sw_if_subif_table, sub, 1);
784
785       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
786       strncpy ((char *) sub->interface_name, (char *) s,
787                vec_len (sub->interface_name));
788       sub->sw_if_index = ntohl (mp->sw_if_index);
789       sub->sub_id = ntohl (mp->sub_id);
790
791       sub->sub_dot1ad = mp->sub_dot1ad;
792       sub->sub_number_of_tags = mp->sub_number_of_tags;
793       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
794       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
795       sub->sub_exact_match = mp->sub_exact_match;
796       sub->sub_default = mp->sub_default;
797       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
798       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
799
800       /* vlan tag rewrite */
801       sub->vtr_op = ntohl (mp->vtr_op);
802       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
803       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
804       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
805     }
806 }
807
808 static void vl_api_sw_interface_details_t_handler_json
809   (vl_api_sw_interface_details_t * mp)
810 {
811   vat_main_t *vam = &vat_main;
812   vat_json_node_t *node = NULL;
813
814   if (VAT_JSON_ARRAY != vam->json_tree.type)
815     {
816       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
817       vat_json_init_array (&vam->json_tree);
818     }
819   node = vat_json_array_add (&vam->json_tree);
820
821   vat_json_init_object (node);
822   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
823   vat_json_object_add_uint (node, "sup_sw_if_index",
824                             ntohl (mp->sup_sw_if_index));
825   vat_json_object_add_uint (node, "l2_address_length",
826                             ntohl (mp->l2_address_length));
827   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
828                              sizeof (mp->l2_address));
829   vat_json_object_add_string_copy (node, "interface_name",
830                                    mp->interface_name);
831   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
832   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
833   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
834   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
835   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
836   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
837   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
838   vat_json_object_add_uint (node, "sub_number_of_tags",
839                             mp->sub_number_of_tags);
840   vat_json_object_add_uint (node, "sub_outer_vlan_id",
841                             ntohs (mp->sub_outer_vlan_id));
842   vat_json_object_add_uint (node, "sub_inner_vlan_id",
843                             ntohs (mp->sub_inner_vlan_id));
844   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
845   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
846   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
847                             mp->sub_outer_vlan_id_any);
848   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
849                             mp->sub_inner_vlan_id_any);
850   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
851   vat_json_object_add_uint (node, "vtr_push_dot1q",
852                             ntohl (mp->vtr_push_dot1q));
853   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
854   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
855 }
856
857 static void vl_api_sw_interface_set_flags_t_handler
858   (vl_api_sw_interface_set_flags_t * mp)
859 {
860   vat_main_t *vam = &vat_main;
861   if (vam->interface_event_display)
862     errmsg ("interface flags: sw_if_index %d %s %s\n",
863             ntohl (mp->sw_if_index),
864             mp->admin_up_down ? "admin-up" : "admin-down",
865             mp->link_up_down ? "link-up" : "link-down");
866 }
867
868 static void vl_api_sw_interface_set_flags_t_handler_json
869   (vl_api_sw_interface_set_flags_t * mp)
870 {
871   /* JSON output not supported */
872 }
873
874 static void
875 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
876 {
877   vat_main_t *vam = &vat_main;
878   i32 retval = ntohl (mp->retval);
879
880   vam->retval = retval;
881   vam->shmem_result = (u8 *) mp->reply_in_shmem;
882   vam->result_ready = 1;
883 }
884
885 static void
886 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   vat_json_node_t node;
890   api_main_t *am = &api_main;
891   void *oldheap;
892   u8 *reply;
893
894   vat_json_init_object (&node);
895   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
896   vat_json_object_add_uint (&node, "reply_in_shmem",
897                             ntohl (mp->reply_in_shmem));
898   /* Toss the shared-memory original... */
899   pthread_mutex_lock (&am->vlib_rp->mutex);
900   oldheap = svm_push_data_heap (am->vlib_rp);
901
902   reply = (u8 *) (mp->reply_in_shmem);
903   vec_free (reply);
904
905   svm_pop_heap (oldheap);
906   pthread_mutex_unlock (&am->vlib_rp->mutex);
907
908   vat_json_print (vam->ofp, &node);
909   vat_json_free (&node);
910
911   vam->retval = ntohl (mp->retval);
912   vam->result_ready = 1;
913 }
914
915 static void
916 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
917 {
918   vat_main_t *vam = &vat_main;
919   i32 retval = ntohl (mp->retval);
920
921   vam->retval = retval;
922   vam->cmd_reply = mp->reply;
923   vam->result_ready = 1;
924 }
925
926 static void
927 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
928 {
929   vat_main_t *vam = &vat_main;
930   vat_json_node_t node;
931
932   vat_json_init_object (&node);
933   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
934   vat_json_object_add_string_copy (&node, "reply", mp->reply);
935
936   vat_json_print (vam->ofp, &node);
937   vat_json_free (&node);
938
939   vam->retval = ntohl (mp->retval);
940   vam->result_ready = 1;
941 }
942
943 static void vl_api_classify_add_del_table_reply_t_handler
944   (vl_api_classify_add_del_table_reply_t * mp)
945 {
946   vat_main_t *vam = &vat_main;
947   i32 retval = ntohl (mp->retval);
948   if (vam->async_mode)
949     {
950       vam->async_errors += (retval < 0);
951     }
952   else
953     {
954       vam->retval = retval;
955       if (retval == 0 &&
956           ((mp->new_table_index != 0xFFFFFFFF) ||
957            (mp->skip_n_vectors != 0xFFFFFFFF) ||
958            (mp->match_n_vectors != 0xFFFFFFFF)))
959         /*
960          * Note: this is just barely thread-safe, depends on
961          * the main thread spinning waiting for an answer...
962          */
963         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
964                 ntohl (mp->new_table_index),
965                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
966       vam->result_ready = 1;
967     }
968 }
969
970 static void vl_api_classify_add_del_table_reply_t_handler_json
971   (vl_api_classify_add_del_table_reply_t * mp)
972 {
973   vat_main_t *vam = &vat_main;
974   vat_json_node_t node;
975
976   vat_json_init_object (&node);
977   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
978   vat_json_object_add_uint (&node, "new_table_index",
979                             ntohl (mp->new_table_index));
980   vat_json_object_add_uint (&node, "skip_n_vectors",
981                             ntohl (mp->skip_n_vectors));
982   vat_json_object_add_uint (&node, "match_n_vectors",
983                             ntohl (mp->match_n_vectors));
984
985   vat_json_print (vam->ofp, &node);
986   vat_json_free (&node);
987
988   vam->retval = ntohl (mp->retval);
989   vam->result_ready = 1;
990 }
991
992 static void vl_api_get_node_index_reply_t_handler
993   (vl_api_get_node_index_reply_t * mp)
994 {
995   vat_main_t *vam = &vat_main;
996   i32 retval = ntohl (mp->retval);
997   if (vam->async_mode)
998     {
999       vam->async_errors += (retval < 0);
1000     }
1001   else
1002     {
1003       vam->retval = retval;
1004       if (retval == 0)
1005         errmsg ("node index %d\n", ntohl (mp->node_index));
1006       vam->result_ready = 1;
1007     }
1008 }
1009
1010 static void vl_api_get_node_index_reply_t_handler_json
1011   (vl_api_get_node_index_reply_t * mp)
1012 {
1013   vat_main_t *vam = &vat_main;
1014   vat_json_node_t node;
1015
1016   vat_json_init_object (&node);
1017   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1018   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1019
1020   vat_json_print (vam->ofp, &node);
1021   vat_json_free (&node);
1022
1023   vam->retval = ntohl (mp->retval);
1024   vam->result_ready = 1;
1025 }
1026
1027 static void vl_api_get_next_index_reply_t_handler
1028   (vl_api_get_next_index_reply_t * mp)
1029 {
1030   vat_main_t *vam = &vat_main;
1031   i32 retval = ntohl (mp->retval);
1032   if (vam->async_mode)
1033     {
1034       vam->async_errors += (retval < 0);
1035     }
1036   else
1037     {
1038       vam->retval = retval;
1039       if (retval == 0)
1040         errmsg ("next node index %d\n", ntohl (mp->next_index));
1041       vam->result_ready = 1;
1042     }
1043 }
1044
1045 static void vl_api_get_next_index_reply_t_handler_json
1046   (vl_api_get_next_index_reply_t * mp)
1047 {
1048   vat_main_t *vam = &vat_main;
1049   vat_json_node_t node;
1050
1051   vat_json_init_object (&node);
1052   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1053   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1054
1055   vat_json_print (vam->ofp, &node);
1056   vat_json_free (&node);
1057
1058   vam->retval = ntohl (mp->retval);
1059   vam->result_ready = 1;
1060 }
1061
1062 static void vl_api_add_node_next_reply_t_handler
1063   (vl_api_add_node_next_reply_t * mp)
1064 {
1065   vat_main_t *vam = &vat_main;
1066   i32 retval = ntohl (mp->retval);
1067   if (vam->async_mode)
1068     {
1069       vam->async_errors += (retval < 0);
1070     }
1071   else
1072     {
1073       vam->retval = retval;
1074       if (retval == 0)
1075         errmsg ("next index %d\n", ntohl (mp->next_index));
1076       vam->result_ready = 1;
1077     }
1078 }
1079
1080 static void vl_api_add_node_next_reply_t_handler_json
1081   (vl_api_add_node_next_reply_t * mp)
1082 {
1083   vat_main_t *vam = &vat_main;
1084   vat_json_node_t node;
1085
1086   vat_json_init_object (&node);
1087   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1088   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1089
1090   vat_json_print (vam->ofp, &node);
1091   vat_json_free (&node);
1092
1093   vam->retval = ntohl (mp->retval);
1094   vam->result_ready = 1;
1095 }
1096
1097 static void vl_api_show_version_reply_t_handler
1098   (vl_api_show_version_reply_t * mp)
1099 {
1100   vat_main_t *vam = &vat_main;
1101   i32 retval = ntohl (mp->retval);
1102
1103   if (retval >= 0)
1104     {
1105       errmsg ("        program: %s\n", mp->program);
1106       errmsg ("        version: %s\n", mp->version);
1107       errmsg ("     build date: %s\n", mp->build_date);
1108       errmsg ("build directory: %s\n", mp->build_directory);
1109     }
1110   vam->retval = retval;
1111   vam->result_ready = 1;
1112 }
1113
1114 static void vl_api_show_version_reply_t_handler_json
1115   (vl_api_show_version_reply_t * mp)
1116 {
1117   vat_main_t *vam = &vat_main;
1118   vat_json_node_t node;
1119
1120   vat_json_init_object (&node);
1121   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1122   vat_json_object_add_string_copy (&node, "program", mp->program);
1123   vat_json_object_add_string_copy (&node, "version", mp->version);
1124   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1125   vat_json_object_add_string_copy (&node, "build_directory",
1126                                    mp->build_directory);
1127
1128   vat_json_print (vam->ofp, &node);
1129   vat_json_free (&node);
1130
1131   vam->retval = ntohl (mp->retval);
1132   vam->result_ready = 1;
1133 }
1134
1135 static void
1136 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1137 {
1138   vat_main_t *vam = &vat_main;
1139   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1140           mp->mac_ip ? "mac/ip binding" : "address resolution",
1141           format_ip4_address, &mp->address,
1142           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1143 }
1144
1145 static void
1146 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1147 {
1148   /* JSON output not supported */
1149 }
1150
1151 static void
1152 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1153 {
1154   vat_main_t *vam = &vat_main;
1155   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1156           mp->mac_ip ? "mac/ip binding" : "address resolution",
1157           format_ip6_address, mp->address,
1158           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1159 }
1160
1161 static void
1162 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1163 {
1164   /* JSON output not supported */
1165 }
1166
1167 /*
1168  * Special-case: build the bridge domain table, maintain
1169  * the next bd id vbl.
1170  */
1171 static void vl_api_bridge_domain_details_t_handler
1172   (vl_api_bridge_domain_details_t * mp)
1173 {
1174   vat_main_t *vam = &vat_main;
1175   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1176
1177   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1178            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1179
1180   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1181            ntohl (mp->bd_id), mp->learn, mp->forward,
1182            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1183
1184   if (n_sw_ifs)
1185     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1186              "Interface Name");
1187 }
1188
1189 static void vl_api_bridge_domain_details_t_handler_json
1190   (vl_api_bridge_domain_details_t * mp)
1191 {
1192   vat_main_t *vam = &vat_main;
1193   vat_json_node_t *node, *array = NULL;
1194
1195   if (VAT_JSON_ARRAY != vam->json_tree.type)
1196     {
1197       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1198       vat_json_init_array (&vam->json_tree);
1199     }
1200   node = vat_json_array_add (&vam->json_tree);
1201
1202   vat_json_init_object (node);
1203   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1204   vat_json_object_add_uint (node, "flood", mp->flood);
1205   vat_json_object_add_uint (node, "forward", mp->forward);
1206   vat_json_object_add_uint (node, "learn", mp->learn);
1207   vat_json_object_add_uint (node, "bvi_sw_if_index",
1208                             ntohl (mp->bvi_sw_if_index));
1209   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1210   array = vat_json_object_add (node, "sw_if");
1211   vat_json_init_array (array);
1212 }
1213
1214 /*
1215  * Special-case: build the bridge domain sw if table.
1216  */
1217 static void vl_api_bridge_domain_sw_if_details_t_handler
1218   (vl_api_bridge_domain_sw_if_details_t * mp)
1219 {
1220   vat_main_t *vam = &vat_main;
1221   hash_pair_t *p;
1222   u8 *sw_if_name = 0;
1223   u32 sw_if_index;
1224
1225   sw_if_index = ntohl (mp->sw_if_index);
1226   /* *INDENT-OFF* */
1227   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1228   ({
1229     if ((u32) p->value[0] == sw_if_index)
1230       {
1231         sw_if_name = (u8 *)(p->key);
1232         break;
1233       }
1234   }));
1235   /* *INDENT-ON* */
1236
1237   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1238            mp->shg, sw_if_name ? (char *) sw_if_name :
1239            "sw_if_index not found!");
1240 }
1241
1242 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1243   (vl_api_bridge_domain_sw_if_details_t * mp)
1244 {
1245   vat_main_t *vam = &vat_main;
1246   vat_json_node_t *node = NULL;
1247   uword last_index = 0;
1248
1249   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1250   ASSERT (vec_len (vam->json_tree.array) >= 1);
1251   last_index = vec_len (vam->json_tree.array) - 1;
1252   node = &vam->json_tree.array[last_index];
1253   node = vat_json_object_get_element (node, "sw_if");
1254   ASSERT (NULL != node);
1255   node = vat_json_array_add (node);
1256
1257   vat_json_init_object (node);
1258   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1259   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1260   vat_json_object_add_uint (node, "shg", mp->shg);
1261 }
1262
1263 static void vl_api_control_ping_reply_t_handler
1264   (vl_api_control_ping_reply_t * mp)
1265 {
1266   vat_main_t *vam = &vat_main;
1267   i32 retval = ntohl (mp->retval);
1268   if (vam->async_mode)
1269     {
1270       vam->async_errors += (retval < 0);
1271     }
1272   else
1273     {
1274       vam->retval = retval;
1275       vam->result_ready = 1;
1276     }
1277 }
1278
1279 static void vl_api_control_ping_reply_t_handler_json
1280   (vl_api_control_ping_reply_t * mp)
1281 {
1282   vat_main_t *vam = &vat_main;
1283   i32 retval = ntohl (mp->retval);
1284
1285   if (VAT_JSON_NONE != vam->json_tree.type)
1286     {
1287       vat_json_print (vam->ofp, &vam->json_tree);
1288       vat_json_free (&vam->json_tree);
1289       vam->json_tree.type = VAT_JSON_NONE;
1290     }
1291   else
1292     {
1293       /* just print [] */
1294       vat_json_init_array (&vam->json_tree);
1295       vat_json_print (vam->ofp, &vam->json_tree);
1296       vam->json_tree.type = VAT_JSON_NONE;
1297     }
1298
1299   vam->retval = retval;
1300   vam->result_ready = 1;
1301 }
1302
1303 static void
1304 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1305 {
1306   vat_main_t *vam = &vat_main;
1307   i32 retval = ntohl (mp->retval);
1308   if (vam->async_mode)
1309     {
1310       vam->async_errors += (retval < 0);
1311     }
1312   else
1313     {
1314       vam->retval = retval;
1315       vam->result_ready = 1;
1316     }
1317 }
1318
1319 static void vl_api_l2_flags_reply_t_handler_json
1320   (vl_api_l2_flags_reply_t * mp)
1321 {
1322   vat_main_t *vam = &vat_main;
1323   vat_json_node_t node;
1324
1325   vat_json_init_object (&node);
1326   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1327   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1328                             ntohl (mp->resulting_feature_bitmap));
1329
1330   vat_json_print (vam->ofp, &node);
1331   vat_json_free (&node);
1332
1333   vam->retval = ntohl (mp->retval);
1334   vam->result_ready = 1;
1335 }
1336
1337 static void vl_api_bridge_flags_reply_t_handler
1338   (vl_api_bridge_flags_reply_t * mp)
1339 {
1340   vat_main_t *vam = &vat_main;
1341   i32 retval = ntohl (mp->retval);
1342   if (vam->async_mode)
1343     {
1344       vam->async_errors += (retval < 0);
1345     }
1346   else
1347     {
1348       vam->retval = retval;
1349       vam->result_ready = 1;
1350     }
1351 }
1352
1353 static void vl_api_bridge_flags_reply_t_handler_json
1354   (vl_api_bridge_flags_reply_t * mp)
1355 {
1356   vat_main_t *vam = &vat_main;
1357   vat_json_node_t node;
1358
1359   vat_json_init_object (&node);
1360   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1361   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1362                             ntohl (mp->resulting_feature_bitmap));
1363
1364   vat_json_print (vam->ofp, &node);
1365   vat_json_free (&node);
1366
1367   vam->retval = ntohl (mp->retval);
1368   vam->result_ready = 1;
1369 }
1370
1371 static void vl_api_tap_connect_reply_t_handler
1372   (vl_api_tap_connect_reply_t * mp)
1373 {
1374   vat_main_t *vam = &vat_main;
1375   i32 retval = ntohl (mp->retval);
1376   if (vam->async_mode)
1377     {
1378       vam->async_errors += (retval < 0);
1379     }
1380   else
1381     {
1382       vam->retval = retval;
1383       vam->sw_if_index = ntohl (mp->sw_if_index);
1384       vam->result_ready = 1;
1385     }
1386
1387 }
1388
1389 static void vl_api_tap_connect_reply_t_handler_json
1390   (vl_api_tap_connect_reply_t * mp)
1391 {
1392   vat_main_t *vam = &vat_main;
1393   vat_json_node_t node;
1394
1395   vat_json_init_object (&node);
1396   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1397   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1398
1399   vat_json_print (vam->ofp, &node);
1400   vat_json_free (&node);
1401
1402   vam->retval = ntohl (mp->retval);
1403   vam->result_ready = 1;
1404
1405 }
1406
1407 static void
1408 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1409 {
1410   vat_main_t *vam = &vat_main;
1411   i32 retval = ntohl (mp->retval);
1412   if (vam->async_mode)
1413     {
1414       vam->async_errors += (retval < 0);
1415     }
1416   else
1417     {
1418       vam->retval = retval;
1419       vam->sw_if_index = ntohl (mp->sw_if_index);
1420       vam->result_ready = 1;
1421     }
1422 }
1423
1424 static void vl_api_tap_modify_reply_t_handler_json
1425   (vl_api_tap_modify_reply_t * mp)
1426 {
1427   vat_main_t *vam = &vat_main;
1428   vat_json_node_t node;
1429
1430   vat_json_init_object (&node);
1431   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1432   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1433
1434   vat_json_print (vam->ofp, &node);
1435   vat_json_free (&node);
1436
1437   vam->retval = ntohl (mp->retval);
1438   vam->result_ready = 1;
1439 }
1440
1441 static void
1442 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1443 {
1444   vat_main_t *vam = &vat_main;
1445   i32 retval = ntohl (mp->retval);
1446   if (vam->async_mode)
1447     {
1448       vam->async_errors += (retval < 0);
1449     }
1450   else
1451     {
1452       vam->retval = retval;
1453       vam->result_ready = 1;
1454     }
1455 }
1456
1457 static void vl_api_tap_delete_reply_t_handler_json
1458   (vl_api_tap_delete_reply_t * mp)
1459 {
1460   vat_main_t *vam = &vat_main;
1461   vat_json_node_t node;
1462
1463   vat_json_init_object (&node);
1464   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1465
1466   vat_json_print (vam->ofp, &node);
1467   vat_json_free (&node);
1468
1469   vam->retval = ntohl (mp->retval);
1470   vam->result_ready = 1;
1471 }
1472
1473 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1474   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1475 {
1476   vat_main_t *vam = &vat_main;
1477   i32 retval = ntohl (mp->retval);
1478   if (vam->async_mode)
1479     {
1480       vam->async_errors += (retval < 0);
1481     }
1482   else
1483     {
1484       vam->retval = retval;
1485       vam->result_ready = 1;
1486     }
1487 }
1488
1489 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1490   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1491 {
1492   vat_main_t *vam = &vat_main;
1493   vat_json_node_t node;
1494
1495   vat_json_init_object (&node);
1496   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1497   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1498                             ntohl (mp->tunnel_sw_if_index));
1499
1500   vat_json_print (vam->ofp, &node);
1501   vat_json_free (&node);
1502
1503   vam->retval = ntohl (mp->retval);
1504   vam->result_ready = 1;
1505 }
1506
1507 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1508   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1509 {
1510   vat_main_t *vam = &vat_main;
1511   i32 retval = ntohl (mp->retval);
1512   if (vam->async_mode)
1513     {
1514       vam->async_errors += (retval < 0);
1515     }
1516   else
1517     {
1518       vam->retval = retval;
1519       vam->sw_if_index = ntohl (mp->sw_if_index);
1520       vam->result_ready = 1;
1521     }
1522 }
1523
1524 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1525   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1526 {
1527   vat_main_t *vam = &vat_main;
1528   vat_json_node_t node;
1529
1530   vat_json_init_object (&node);
1531   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1532   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1533
1534   vat_json_print (vam->ofp, &node);
1535   vat_json_free (&node);
1536
1537   vam->retval = ntohl (mp->retval);
1538   vam->result_ready = 1;
1539 }
1540
1541
1542 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1543   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1544 {
1545   vat_main_t *vam = &vat_main;
1546   i32 retval = ntohl (mp->retval);
1547   if (vam->async_mode)
1548     {
1549       vam->async_errors += (retval < 0);
1550     }
1551   else
1552     {
1553       vam->retval = retval;
1554       vam->result_ready = 1;
1555     }
1556 }
1557
1558 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1559   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1560 {
1561   vat_main_t *vam = &vat_main;
1562   vat_json_node_t node;
1563
1564   vat_json_init_object (&node);
1565   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1566   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1567
1568   vat_json_print (vam->ofp, &node);
1569   vat_json_free (&node);
1570
1571   vam->retval = ntohl (mp->retval);
1572   vam->result_ready = 1;
1573 }
1574
1575 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1576   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1577 {
1578   vat_main_t *vam = &vat_main;
1579   i32 retval = ntohl (mp->retval);
1580   if (vam->async_mode)
1581     {
1582       vam->async_errors += (retval < 0);
1583     }
1584   else
1585     {
1586       vam->retval = retval;
1587       vam->sw_if_index = ntohl (mp->sw_if_index);
1588       vam->result_ready = 1;
1589     }
1590 }
1591
1592 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1593   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1594 {
1595   vat_main_t *vam = &vat_main;
1596   vat_json_node_t node;
1597
1598   vat_json_init_object (&node);
1599   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1600   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1601
1602   vat_json_print (vam->ofp, &node);
1603   vat_json_free (&node);
1604
1605   vam->retval = ntohl (mp->retval);
1606   vam->result_ready = 1;
1607 }
1608
1609 static void vl_api_gre_add_del_tunnel_reply_t_handler
1610   (vl_api_gre_add_del_tunnel_reply_t * mp)
1611 {
1612   vat_main_t *vam = &vat_main;
1613   i32 retval = ntohl (mp->retval);
1614   if (vam->async_mode)
1615     {
1616       vam->async_errors += (retval < 0);
1617     }
1618   else
1619     {
1620       vam->retval = retval;
1621       vam->sw_if_index = ntohl (mp->sw_if_index);
1622       vam->result_ready = 1;
1623     }
1624 }
1625
1626 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1627   (vl_api_gre_add_del_tunnel_reply_t * mp)
1628 {
1629   vat_main_t *vam = &vat_main;
1630   vat_json_node_t node;
1631
1632   vat_json_init_object (&node);
1633   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1634   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1635
1636   vat_json_print (vam->ofp, &node);
1637   vat_json_free (&node);
1638
1639   vam->retval = ntohl (mp->retval);
1640   vam->result_ready = 1;
1641 }
1642
1643 static void vl_api_create_vhost_user_if_reply_t_handler
1644   (vl_api_create_vhost_user_if_reply_t * mp)
1645 {
1646   vat_main_t *vam = &vat_main;
1647   i32 retval = ntohl (mp->retval);
1648   if (vam->async_mode)
1649     {
1650       vam->async_errors += (retval < 0);
1651     }
1652   else
1653     {
1654       vam->retval = retval;
1655       vam->sw_if_index = ntohl (mp->sw_if_index);
1656       vam->result_ready = 1;
1657     }
1658 }
1659
1660 static void vl_api_create_vhost_user_if_reply_t_handler_json
1661   (vl_api_create_vhost_user_if_reply_t * mp)
1662 {
1663   vat_main_t *vam = &vat_main;
1664   vat_json_node_t node;
1665
1666   vat_json_init_object (&node);
1667   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1668   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1669
1670   vat_json_print (vam->ofp, &node);
1671   vat_json_free (&node);
1672
1673   vam->retval = ntohl (mp->retval);
1674   vam->result_ready = 1;
1675 }
1676
1677 static void vl_api_ip_address_details_t_handler
1678   (vl_api_ip_address_details_t * mp)
1679 {
1680   vat_main_t *vam = &vat_main;
1681   static ip_address_details_t empty_ip_address_details = { {0} };
1682   ip_address_details_t *address = NULL;
1683   ip_details_t *current_ip_details = NULL;
1684   ip_details_t *details = NULL;
1685
1686   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1687
1688   if (!details || vam->current_sw_if_index >= vec_len (details)
1689       || !details[vam->current_sw_if_index].present)
1690     {
1691       errmsg ("ip address details arrived but not stored\n");
1692       errmsg ("ip_dump should be called first\n");
1693       return;
1694     }
1695
1696   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1697
1698 #define addresses (current_ip_details->addr)
1699
1700   vec_validate_init_empty (addresses, vec_len (addresses),
1701                            empty_ip_address_details);
1702
1703   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1704
1705   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1706   address->prefix_length = mp->prefix_length;
1707 #undef addresses
1708 }
1709
1710 static void vl_api_ip_address_details_t_handler_json
1711   (vl_api_ip_address_details_t * mp)
1712 {
1713   vat_main_t *vam = &vat_main;
1714   vat_json_node_t *node = NULL;
1715   struct in6_addr ip6;
1716   struct in_addr ip4;
1717
1718   if (VAT_JSON_ARRAY != vam->json_tree.type)
1719     {
1720       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1721       vat_json_init_array (&vam->json_tree);
1722     }
1723   node = vat_json_array_add (&vam->json_tree);
1724
1725   vat_json_init_object (node);
1726   if (vam->is_ipv6)
1727     {
1728       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1729       vat_json_object_add_ip6 (node, "ip", ip6);
1730     }
1731   else
1732     {
1733       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1734       vat_json_object_add_ip4 (node, "ip", ip4);
1735     }
1736   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1737 }
1738
1739 static void
1740 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1741 {
1742   vat_main_t *vam = &vat_main;
1743   static ip_details_t empty_ip_details = { 0 };
1744   ip_details_t *ip = NULL;
1745   u32 sw_if_index = ~0;
1746
1747   sw_if_index = ntohl (mp->sw_if_index);
1748
1749   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1750                            sw_if_index, empty_ip_details);
1751
1752   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1753                          sw_if_index);
1754
1755   ip->present = 1;
1756 }
1757
1758 static void
1759 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1760 {
1761   vat_main_t *vam = &vat_main;
1762
1763   if (VAT_JSON_ARRAY != vam->json_tree.type)
1764     {
1765       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1766       vat_json_init_array (&vam->json_tree);
1767     }
1768   vat_json_array_add_uint (&vam->json_tree,
1769                            clib_net_to_host_u32 (mp->sw_if_index));
1770 }
1771
1772 static void vl_api_map_domain_details_t_handler_json
1773   (vl_api_map_domain_details_t * mp)
1774 {
1775   vat_json_node_t *node = NULL;
1776   vat_main_t *vam = &vat_main;
1777   struct in6_addr ip6;
1778   struct in_addr ip4;
1779
1780   if (VAT_JSON_ARRAY != vam->json_tree.type)
1781     {
1782       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1783       vat_json_init_array (&vam->json_tree);
1784     }
1785
1786   node = vat_json_array_add (&vam->json_tree);
1787   vat_json_init_object (node);
1788
1789   vat_json_object_add_uint (node, "domain_index",
1790                             clib_net_to_host_u32 (mp->domain_index));
1791   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1792   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1793   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1794   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1795   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1796   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1797   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1798   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1799   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1800   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1801   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1802   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1803   vat_json_object_add_uint (node, "flags", mp->flags);
1804   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1805   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1806 }
1807
1808 static void vl_api_map_domain_details_t_handler
1809   (vl_api_map_domain_details_t * mp)
1810 {
1811   vat_main_t *vam = &vat_main;
1812
1813   if (mp->is_translation)
1814     {
1815       fformat (vam->ofp,
1816                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1817                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1818                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1819                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1820                clib_net_to_host_u32 (mp->domain_index));
1821     }
1822   else
1823     {
1824       fformat (vam->ofp,
1825                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1826                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1827                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1828                format_ip6_address, mp->ip6_src,
1829                clib_net_to_host_u32 (mp->domain_index));
1830     }
1831   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1832            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1833            mp->is_translation ? "map-t" : "");
1834 }
1835
1836 static void vl_api_map_rule_details_t_handler_json
1837   (vl_api_map_rule_details_t * mp)
1838 {
1839   struct in6_addr ip6;
1840   vat_json_node_t *node = NULL;
1841   vat_main_t *vam = &vat_main;
1842
1843   if (VAT_JSON_ARRAY != vam->json_tree.type)
1844     {
1845       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1846       vat_json_init_array (&vam->json_tree);
1847     }
1848
1849   node = vat_json_array_add (&vam->json_tree);
1850   vat_json_init_object (node);
1851
1852   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1853   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1854   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1855 }
1856
1857 static void
1858 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1859 {
1860   vat_main_t *vam = &vat_main;
1861   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1862            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1863 }
1864
1865 static void
1866 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1867 {
1868   vat_main_t *vam = &vat_main;
1869   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1870           "router_addr %U host_mac %U\n",
1871           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1872           format_ip4_address, &mp->host_address,
1873           format_ip4_address, &mp->router_address,
1874           format_ethernet_address, mp->host_mac);
1875 }
1876
1877 static void vl_api_dhcp_compl_event_t_handler_json
1878   (vl_api_dhcp_compl_event_t * mp)
1879 {
1880   /* JSON output not supported */
1881 }
1882
1883 static void
1884 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1885                               u32 counter)
1886 {
1887   vat_main_t *vam = &vat_main;
1888   static u64 default_counter = 0;
1889
1890   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1891                            NULL);
1892   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1893                            sw_if_index, default_counter);
1894   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1895 }
1896
1897 static void
1898 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1899                                 interface_counter_t counter)
1900 {
1901   vat_main_t *vam = &vat_main;
1902   static interface_counter_t default_counter = { 0, };
1903
1904   vec_validate_init_empty (vam->combined_interface_counters,
1905                            vnet_counter_type, NULL);
1906   vec_validate_init_empty (vam->combined_interface_counters
1907                            [vnet_counter_type], sw_if_index, default_counter);
1908   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1909 }
1910
1911 static void vl_api_vnet_interface_counters_t_handler
1912   (vl_api_vnet_interface_counters_t * mp)
1913 {
1914   /* not supported */
1915 }
1916
1917 static void vl_api_vnet_interface_counters_t_handler_json
1918   (vl_api_vnet_interface_counters_t * mp)
1919 {
1920   interface_counter_t counter;
1921   vlib_counter_t *v;
1922   u64 *v_packets;
1923   u64 packets;
1924   u32 count;
1925   u32 first_sw_if_index;
1926   int i;
1927
1928   count = ntohl (mp->count);
1929   first_sw_if_index = ntohl (mp->first_sw_if_index);
1930
1931   if (!mp->is_combined)
1932     {
1933       v_packets = (u64 *) & mp->data;
1934       for (i = 0; i < count; i++)
1935         {
1936           packets =
1937             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1938           set_simple_interface_counter (mp->vnet_counter_type,
1939                                         first_sw_if_index + i, packets);
1940           v_packets++;
1941         }
1942     }
1943   else
1944     {
1945       v = (vlib_counter_t *) & mp->data;
1946       for (i = 0; i < count; i++)
1947         {
1948           counter.packets =
1949             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1950           counter.bytes =
1951             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1952           set_combined_interface_counter (mp->vnet_counter_type,
1953                                           first_sw_if_index + i, counter);
1954           v++;
1955         }
1956     }
1957 }
1958
1959 static u32
1960 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1961 {
1962   vat_main_t *vam = &vat_main;
1963   u32 i;
1964
1965   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1966     {
1967       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1968         {
1969           return i;
1970         }
1971     }
1972   return ~0;
1973 }
1974
1975 static u32
1976 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1977 {
1978   vat_main_t *vam = &vat_main;
1979   u32 i;
1980
1981   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1982     {
1983       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1984         {
1985           return i;
1986         }
1987     }
1988   return ~0;
1989 }
1990
1991 static void vl_api_vnet_ip4_fib_counters_t_handler
1992   (vl_api_vnet_ip4_fib_counters_t * mp)
1993 {
1994   /* not supported */
1995 }
1996
1997 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1998   (vl_api_vnet_ip4_fib_counters_t * mp)
1999 {
2000   vat_main_t *vam = &vat_main;
2001   vl_api_ip4_fib_counter_t *v;
2002   ip4_fib_counter_t *counter;
2003   struct in_addr ip4;
2004   u32 vrf_id;
2005   u32 vrf_index;
2006   u32 count;
2007   int i;
2008
2009   vrf_id = ntohl (mp->vrf_id);
2010   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2011   if (~0 == vrf_index)
2012     {
2013       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
2014       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
2015       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2016       vec_validate (vam->ip4_fib_counters, vrf_index);
2017       vam->ip4_fib_counters[vrf_index] = NULL;
2018     }
2019
2020   vec_free (vam->ip4_fib_counters[vrf_index]);
2021   v = (vl_api_ip4_fib_counter_t *) & mp->c;
2022   count = ntohl (mp->count);
2023   for (i = 0; i < count; i++)
2024     {
2025       vec_validate (vam->ip4_fib_counters[vrf_index], i);
2026       counter = &vam->ip4_fib_counters[vrf_index][i];
2027       clib_memcpy (&ip4, &v->address, sizeof (ip4));
2028       counter->address = ip4;
2029       counter->address_length = v->address_length;
2030       counter->packets = clib_net_to_host_u64 (v->packets);
2031       counter->bytes = clib_net_to_host_u64 (v->bytes);
2032       v++;
2033     }
2034 }
2035
2036 static void vl_api_vnet_ip6_fib_counters_t_handler
2037   (vl_api_vnet_ip6_fib_counters_t * mp)
2038 {
2039   /* not supported */
2040 }
2041
2042 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2043   (vl_api_vnet_ip6_fib_counters_t * mp)
2044 {
2045   vat_main_t *vam = &vat_main;
2046   vl_api_ip6_fib_counter_t *v;
2047   ip6_fib_counter_t *counter;
2048   struct in6_addr ip6;
2049   u32 vrf_id;
2050   u32 vrf_index;
2051   u32 count;
2052   int i;
2053
2054   vrf_id = ntohl (mp->vrf_id);
2055   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2056   if (~0 == vrf_index)
2057     {
2058       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2059       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2060       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2061       vec_validate (vam->ip6_fib_counters, vrf_index);
2062       vam->ip6_fib_counters[vrf_index] = NULL;
2063     }
2064
2065   vec_free (vam->ip6_fib_counters[vrf_index]);
2066   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2067   count = ntohl (mp->count);
2068   for (i = 0; i < count; i++)
2069     {
2070       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2071       counter = &vam->ip6_fib_counters[vrf_index][i];
2072       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2073       counter->address = ip6;
2074       counter->address_length = v->address_length;
2075       counter->packets = clib_net_to_host_u64 (v->packets);
2076       counter->bytes = clib_net_to_host_u64 (v->bytes);
2077       v++;
2078     }
2079 }
2080
2081 static void vl_api_get_first_msg_id_reply_t_handler
2082   (vl_api_get_first_msg_id_reply_t * mp)
2083 {
2084   vat_main_t *vam = &vat_main;
2085   i32 retval = ntohl (mp->retval);
2086
2087   if (vam->async_mode)
2088     {
2089       vam->async_errors += (retval < 0);
2090     }
2091   else
2092     {
2093       vam->retval = retval;
2094       vam->result_ready = 1;
2095     }
2096   if (retval >= 0)
2097     {
2098       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2099     }
2100 }
2101
2102 static void vl_api_get_first_msg_id_reply_t_handler_json
2103   (vl_api_get_first_msg_id_reply_t * mp)
2104 {
2105   vat_main_t *vam = &vat_main;
2106   vat_json_node_t node;
2107
2108   vat_json_init_object (&node);
2109   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2110   vat_json_object_add_uint (&node, "first_msg_id",
2111                             (uint) ntohs (mp->first_msg_id));
2112
2113   vat_json_print (vam->ofp, &node);
2114   vat_json_free (&node);
2115
2116   vam->retval = ntohl (mp->retval);
2117   vam->result_ready = 1;
2118 }
2119
2120 static void vl_api_get_node_graph_reply_t_handler
2121   (vl_api_get_node_graph_reply_t * mp)
2122 {
2123   vat_main_t *vam = &vat_main;
2124   api_main_t *am = &api_main;
2125   i32 retval = ntohl (mp->retval);
2126   u8 *pvt_copy, *reply;
2127   void *oldheap;
2128   vlib_node_t *node;
2129   int i;
2130
2131   if (vam->async_mode)
2132     {
2133       vam->async_errors += (retval < 0);
2134     }
2135   else
2136     {
2137       vam->retval = retval;
2138       vam->result_ready = 1;
2139     }
2140
2141   /* "Should never happen..." */
2142   if (retval != 0)
2143     return;
2144
2145   reply = (u8 *) (mp->reply_in_shmem);
2146   pvt_copy = vec_dup (reply);
2147
2148   /* Toss the shared-memory original... */
2149   pthread_mutex_lock (&am->vlib_rp->mutex);
2150   oldheap = svm_push_data_heap (am->vlib_rp);
2151
2152   vec_free (reply);
2153
2154   svm_pop_heap (oldheap);
2155   pthread_mutex_unlock (&am->vlib_rp->mutex);
2156
2157   if (vam->graph_nodes)
2158     {
2159       hash_free (vam->graph_node_index_by_name);
2160
2161       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2162         {
2163           node = vam->graph_nodes[i];
2164           vec_free (node->name);
2165           vec_free (node->next_nodes);
2166           vec_free (node);
2167         }
2168       vec_free (vam->graph_nodes);
2169     }
2170
2171   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2172   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2173   vec_free (pvt_copy);
2174
2175   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2176     {
2177       node = vam->graph_nodes[i];
2178       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2179     }
2180 }
2181
2182 static void vl_api_get_node_graph_reply_t_handler_json
2183   (vl_api_get_node_graph_reply_t * mp)
2184 {
2185   vat_main_t *vam = &vat_main;
2186   api_main_t *am = &api_main;
2187   void *oldheap;
2188   vat_json_node_t node;
2189   u8 *reply;
2190
2191   /* $$$$ make this real? */
2192   vat_json_init_object (&node);
2193   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2194   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2195
2196   reply = (u8 *) (mp->reply_in_shmem);
2197
2198   /* Toss the shared-memory original... */
2199   pthread_mutex_lock (&am->vlib_rp->mutex);
2200   oldheap = svm_push_data_heap (am->vlib_rp);
2201
2202   vec_free (reply);
2203
2204   svm_pop_heap (oldheap);
2205   pthread_mutex_unlock (&am->vlib_rp->mutex);
2206
2207   vat_json_print (vam->ofp, &node);
2208   vat_json_free (&node);
2209
2210   vam->retval = ntohl (mp->retval);
2211   vam->result_ready = 1;
2212 }
2213
2214 static void
2215 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2216 {
2217   vat_main_t *vam = &vat_main;
2218   u8 *s = 0;
2219
2220   if (mp->local)
2221     {
2222       s = format (s, "%=16d%=16d%=16d\n",
2223                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2224     }
2225   else
2226     {
2227       s = format (s, "%=16U%=16d%=16d\n",
2228                   mp->is_ipv6 ? format_ip6_address :
2229                   format_ip4_address,
2230                   mp->ip_address, mp->priority, mp->weight);
2231     }
2232
2233   fformat (vam->ofp, "%v", s);
2234   vec_free (s);
2235 }
2236
2237 static void
2238 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2239                                             mp)
2240 {
2241   vat_main_t *vam = &vat_main;
2242   vat_json_node_t *node = NULL;
2243   struct in6_addr ip6;
2244   struct in_addr ip4;
2245
2246   if (VAT_JSON_ARRAY != vam->json_tree.type)
2247     {
2248       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2249       vat_json_init_array (&vam->json_tree);
2250     }
2251   node = vat_json_array_add (&vam->json_tree);
2252   vat_json_init_object (node);
2253
2254   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2255   vat_json_object_add_uint (node, "priority", mp->priority);
2256   vat_json_object_add_uint (node, "weight", mp->weight);
2257
2258   if (mp->local)
2259     vat_json_object_add_uint (node, "sw_if_index",
2260                               clib_net_to_host_u32 (mp->sw_if_index));
2261   else
2262     {
2263       if (mp->is_ipv6)
2264         {
2265           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2266           vat_json_object_add_ip6 (node, "address", ip6);
2267         }
2268       else
2269         {
2270           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2271           vat_json_object_add_ip4 (node, "address", ip4);
2272         }
2273     }
2274 }
2275
2276 static void
2277 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2278                                            mp)
2279 {
2280   vat_main_t *vam = &vat_main;
2281   u8 *ls_name = 0;
2282
2283   ls_name = format (0, "%s", mp->ls_name);
2284
2285   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2286            ls_name);
2287   vec_free (ls_name);
2288 }
2289
2290 static void
2291   vl_api_lisp_locator_set_details_t_handler_json
2292   (vl_api_lisp_locator_set_details_t * mp)
2293 {
2294   vat_main_t *vam = &vat_main;
2295   vat_json_node_t *node = 0;
2296   u8 *ls_name = 0;
2297
2298   ls_name = format (0, "%s", mp->ls_name);
2299   vec_add1 (ls_name, 0);
2300
2301   if (VAT_JSON_ARRAY != vam->json_tree.type)
2302     {
2303       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2304       vat_json_init_array (&vam->json_tree);
2305     }
2306   node = vat_json_array_add (&vam->json_tree);
2307
2308   vat_json_init_object (node);
2309   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2310   vat_json_object_add_uint (node, "ls_index",
2311                             clib_net_to_host_u32 (mp->ls_index));
2312   vec_free (ls_name);
2313 }
2314
2315 static u8 *
2316 format_lisp_flat_eid (u8 * s, va_list * args)
2317 {
2318   u32 type = va_arg (*args, u32);
2319   u8 *eid = va_arg (*args, u8 *);
2320   u32 eid_len = va_arg (*args, u32);
2321
2322   switch (type)
2323     {
2324     case 0:
2325       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2326     case 1:
2327       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2328     case 2:
2329       return format (s, "%U", format_ethernet_address, eid);
2330     }
2331   return 0;
2332 }
2333
2334 static u8 *
2335 format_lisp_eid_vat (u8 * s, va_list * args)
2336 {
2337   u32 type = va_arg (*args, u32);
2338   u8 *eid = va_arg (*args, u8 *);
2339   u32 eid_len = va_arg (*args, u32);
2340   u8 *seid = va_arg (*args, u8 *);
2341   u32 seid_len = va_arg (*args, u32);
2342   u32 is_src_dst = va_arg (*args, u32);
2343
2344   if (is_src_dst)
2345     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2346
2347   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2348
2349   return s;
2350 }
2351
2352 static void
2353 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2354 {
2355   vat_main_t *vam = &vat_main;
2356   u8 *s = 0, *eid = 0;
2357
2358   if (~0 == mp->locator_set_index)
2359     s = format (0, "action: %d", mp->action);
2360   else
2361     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2362
2363   eid = format (0, "%U", format_lisp_eid_vat,
2364                 mp->eid_type,
2365                 mp->eid,
2366                 mp->eid_prefix_len,
2367                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2368   vec_add1 (eid, 0);
2369
2370   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2371            clib_net_to_host_u32 (mp->vni),
2372            eid,
2373            mp->is_local ? "local" : "remote",
2374            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2375   vec_free (s);
2376   vec_free (eid);
2377 }
2378
2379 static void
2380 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2381                                               * mp)
2382 {
2383   vat_main_t *vam = &vat_main;
2384   vat_json_node_t *node = 0;
2385   u8 *eid = 0;
2386
2387   if (VAT_JSON_ARRAY != vam->json_tree.type)
2388     {
2389       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2390       vat_json_init_array (&vam->json_tree);
2391     }
2392   node = vat_json_array_add (&vam->json_tree);
2393
2394   vat_json_init_object (node);
2395   if (~0 == mp->locator_set_index)
2396     vat_json_object_add_uint (node, "action", mp->action);
2397   else
2398     vat_json_object_add_uint (node, "locator_set_index",
2399                               clib_net_to_host_u32 (mp->locator_set_index));
2400
2401   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2402   eid = format (0, "%U", format_lisp_eid_vat,
2403                 mp->eid_type,
2404                 mp->eid,
2405                 mp->eid_prefix_len,
2406                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2407   vec_add1 (eid, 0);
2408   vat_json_object_add_string_copy (node, "eid", eid);
2409   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2410   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2411   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2412   vec_free (eid);
2413 }
2414
2415 static void
2416   vl_api_lisp_eid_table_map_details_t_handler
2417   (vl_api_lisp_eid_table_map_details_t * mp)
2418 {
2419   vat_main_t *vam = &vat_main;
2420
2421   u8 *line = format (0, "%=10d%=10d",
2422                      clib_net_to_host_u32 (mp->vni),
2423                      clib_net_to_host_u32 (mp->dp_table));
2424   fformat (vam->ofp, "%v\n", line);
2425   vec_free (line);
2426 }
2427
2428 static void
2429   vl_api_lisp_eid_table_map_details_t_handler_json
2430   (vl_api_lisp_eid_table_map_details_t * mp)
2431 {
2432   vat_main_t *vam = &vat_main;
2433   vat_json_node_t *node = NULL;
2434
2435   if (VAT_JSON_ARRAY != vam->json_tree.type)
2436     {
2437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2438       vat_json_init_array (&vam->json_tree);
2439     }
2440   node = vat_json_array_add (&vam->json_tree);
2441   vat_json_init_object (node);
2442   vat_json_object_add_uint (node, "dp_table",
2443                             clib_net_to_host_u32 (mp->dp_table));
2444   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2445 }
2446
2447 static void
2448   vl_api_lisp_eid_table_vni_details_t_handler
2449   (vl_api_lisp_eid_table_vni_details_t * mp)
2450 {
2451   vat_main_t *vam = &vat_main;
2452
2453   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2454   fformat (vam->ofp, "%v\n", line);
2455   vec_free (line);
2456 }
2457
2458 static void
2459   vl_api_lisp_eid_table_vni_details_t_handler_json
2460   (vl_api_lisp_eid_table_vni_details_t * mp)
2461 {
2462   vat_main_t *vam = &vat_main;
2463   vat_json_node_t *node = NULL;
2464
2465   if (VAT_JSON_ARRAY != vam->json_tree.type)
2466     {
2467       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2468       vat_json_init_array (&vam->json_tree);
2469     }
2470   node = vat_json_array_add (&vam->json_tree);
2471   vat_json_init_object (node);
2472   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2473 }
2474
2475 static u8 *
2476 format_decap_next (u8 * s, va_list * args)
2477 {
2478   u32 next_index = va_arg (*args, u32);
2479
2480   switch (next_index)
2481     {
2482     case LISP_GPE_INPUT_NEXT_DROP:
2483       return format (s, "drop");
2484     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2485       return format (s, "ip4");
2486     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2487       return format (s, "ip6");
2488     default:
2489       return format (s, "unknown %d", next_index);
2490     }
2491   return s;
2492 }
2493
2494 static void
2495 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2496                                           mp)
2497 {
2498   vat_main_t *vam = &vat_main;
2499   u8 *iid_str;
2500   u8 *flag_str = NULL;
2501
2502   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2503
2504 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2505   foreach_lisp_gpe_flag_bit;
2506 #undef _
2507
2508   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2509            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2510            mp->tunnels,
2511            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2512            mp->source_ip,
2513            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2514            mp->destination_ip,
2515            ntohl (mp->encap_fib_id),
2516            ntohl (mp->decap_fib_id),
2517            format_decap_next, ntohl (mp->dcap_next),
2518            mp->ver_res >> 6,
2519            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2520
2521   vec_free (iid_str);
2522 }
2523
2524 static void
2525   vl_api_lisp_gpe_tunnel_details_t_handler_json
2526   (vl_api_lisp_gpe_tunnel_details_t * mp)
2527 {
2528   vat_main_t *vam = &vat_main;
2529   vat_json_node_t *node = NULL;
2530   struct in6_addr ip6;
2531   struct in_addr ip4;
2532   u8 *next_decap_str;
2533
2534   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2535
2536   if (VAT_JSON_ARRAY != vam->json_tree.type)
2537     {
2538       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2539       vat_json_init_array (&vam->json_tree);
2540     }
2541   node = vat_json_array_add (&vam->json_tree);
2542
2543   vat_json_init_object (node);
2544   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2545   if (mp->is_ipv6)
2546     {
2547       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2548       vat_json_object_add_ip6 (node, "source address", ip6);
2549       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2550       vat_json_object_add_ip6 (node, "destination address", ip6);
2551     }
2552   else
2553     {
2554       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2555       vat_json_object_add_ip4 (node, "source address", ip4);
2556       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2557       vat_json_object_add_ip4 (node, "destination address", ip4);
2558     }
2559   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2560   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2561   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2562   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2563   vat_json_object_add_uint (node, "flags", mp->flags);
2564   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2565   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2566   vat_json_object_add_uint (node, "res", mp->res);
2567   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2568
2569   vec_free (next_decap_str);
2570 }
2571
2572 static void
2573   vl_api_lisp_adjacencies_get_reply_t_handler
2574   (vl_api_lisp_adjacencies_get_reply_t * mp)
2575 {
2576   vat_main_t *vam = &vat_main;
2577   u32 i, n;
2578   int retval = clib_net_to_host_u32 (mp->retval);
2579   vl_api_lisp_adjacency_t *a;
2580
2581   if (retval)
2582     goto end;
2583
2584   n = clib_net_to_host_u32 (mp->count);
2585
2586   for (i = 0; i < n; i++)
2587     {
2588       a = &mp->adjacencies[i];
2589       fformat (vam->ofp, "%U %40U\n",
2590                format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2591                format_lisp_flat_eid, a->eid_type, a->reid,
2592                a->reid_prefix_len);
2593     }
2594
2595 end:
2596   vam->retval = retval;
2597   vam->result_ready = 1;
2598 }
2599
2600 static void
2601   vl_api_lisp_adjacencies_get_reply_t_handler_json
2602   (vl_api_lisp_adjacencies_get_reply_t * mp)
2603 {
2604   u8 *s = 0;
2605   vat_main_t *vam = &vat_main;
2606   vat_json_node_t *e = 0, root;
2607   u32 i, n;
2608   int retval = clib_net_to_host_u32 (mp->retval);
2609   vl_api_lisp_adjacency_t *a;
2610
2611   if (retval)
2612     goto end;
2613
2614   n = clib_net_to_host_u32 (mp->count);
2615   vat_json_init_array (&root);
2616
2617   for (i = 0; i < n; i++)
2618     {
2619       e = vat_json_array_add (&root);
2620       a = &mp->adjacencies[i];
2621
2622       vat_json_init_object (e);
2623       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2624                   a->leid_prefix_len);
2625       vec_add1 (s, 0);
2626       vat_json_object_add_string_copy (e, "leid", s);
2627       vec_free (s);
2628
2629       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2630                   a->reid_prefix_len);
2631       vec_add1 (s, 0);
2632       vat_json_object_add_string_copy (e, "reid", s);
2633       vec_free (s);
2634     }
2635
2636   vat_json_print (vam->ofp, &root);
2637   vat_json_free (&root);
2638
2639 end:
2640   vam->retval = retval;
2641   vam->result_ready = 1;
2642 }
2643
2644 static void
2645 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2646                                             * mp)
2647 {
2648   vat_main_t *vam = &vat_main;
2649
2650   fformat (vam->ofp, "%=20U\n",
2651            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2652            mp->ip_address);
2653 }
2654
2655 static void
2656   vl_api_lisp_map_resolver_details_t_handler_json
2657   (vl_api_lisp_map_resolver_details_t * mp)
2658 {
2659   vat_main_t *vam = &vat_main;
2660   vat_json_node_t *node = NULL;
2661   struct in6_addr ip6;
2662   struct in_addr ip4;
2663
2664   if (VAT_JSON_ARRAY != vam->json_tree.type)
2665     {
2666       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2667       vat_json_init_array (&vam->json_tree);
2668     }
2669   node = vat_json_array_add (&vam->json_tree);
2670
2671   vat_json_init_object (node);
2672   if (mp->is_ipv6)
2673     {
2674       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2675       vat_json_object_add_ip6 (node, "map resolver", ip6);
2676     }
2677   else
2678     {
2679       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2680       vat_json_object_add_ip4 (node, "map resolver", ip4);
2681     }
2682 }
2683
2684 static void
2685   vl_api_show_lisp_status_reply_t_handler
2686   (vl_api_show_lisp_status_reply_t * mp)
2687 {
2688   vat_main_t *vam = &vat_main;
2689   i32 retval = ntohl (mp->retval);
2690
2691   if (0 <= retval)
2692     {
2693       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2694                mp->feature_status ? "enabled" : "disabled",
2695                mp->gpe_status ? "enabled" : "disabled");
2696     }
2697
2698   vam->retval = retval;
2699   vam->result_ready = 1;
2700 }
2701
2702 static void
2703   vl_api_show_lisp_status_reply_t_handler_json
2704   (vl_api_show_lisp_status_reply_t * mp)
2705 {
2706   vat_main_t *vam = &vat_main;
2707   vat_json_node_t node;
2708   u8 *gpe_status = NULL;
2709   u8 *feature_status = NULL;
2710
2711   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2712   feature_status = format (0, "%s",
2713                            mp->feature_status ? "enabled" : "disabled");
2714   vec_add1 (gpe_status, 0);
2715   vec_add1 (feature_status, 0);
2716
2717   vat_json_init_object (&node);
2718   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2719   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2720
2721   vec_free (gpe_status);
2722   vec_free (feature_status);
2723
2724   vat_json_print (vam->ofp, &node);
2725   vat_json_free (&node);
2726
2727   vam->retval = ntohl (mp->retval);
2728   vam->result_ready = 1;
2729 }
2730
2731 static void
2732   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2733   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2734 {
2735   vat_main_t *vam = &vat_main;
2736   i32 retval = ntohl (mp->retval);
2737
2738   if (retval >= 0)
2739     {
2740       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2741     }
2742
2743   vam->retval = retval;
2744   vam->result_ready = 1;
2745 }
2746
2747 static void
2748   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2749   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2750 {
2751   vat_main_t *vam = &vat_main;
2752   vat_json_node_t *node = NULL;
2753
2754   if (VAT_JSON_ARRAY != vam->json_tree.type)
2755     {
2756       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2757       vat_json_init_array (&vam->json_tree);
2758     }
2759   node = vat_json_array_add (&vam->json_tree);
2760
2761   vat_json_init_object (node);
2762   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2763
2764   vat_json_print (vam->ofp, node);
2765   vat_json_free (node);
2766
2767   vam->retval = ntohl (mp->retval);
2768   vam->result_ready = 1;
2769 }
2770
2771 static u8 *
2772 format_lisp_map_request_mode (u8 * s, va_list * args)
2773 {
2774   u32 mode = va_arg (*args, u32);
2775
2776   switch (mode)
2777     {
2778     case 0:
2779       return format (0, "dst-only");
2780     case 1:
2781       return format (0, "src-dst");
2782     }
2783   return 0;
2784 }
2785
2786 static void
2787   vl_api_show_lisp_map_request_mode_reply_t_handler
2788   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2789 {
2790   vat_main_t *vam = &vat_main;
2791   i32 retval = ntohl (mp->retval);
2792
2793   if (0 <= retval)
2794     {
2795       u32 mode = mp->mode;
2796       fformat (vam->ofp, "map_request_mode: %U\n",
2797                format_lisp_map_request_mode, mode);
2798     }
2799
2800   vam->retval = retval;
2801   vam->result_ready = 1;
2802 }
2803
2804 static void
2805   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2806   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2807 {
2808   vat_main_t *vam = &vat_main;
2809   vat_json_node_t node;
2810   u8 *s = 0;
2811   u32 mode;
2812
2813   mode = mp->mode;
2814   s = format (0, "%U", format_lisp_map_request_mode, mode);
2815   vec_add1 (s, 0);
2816
2817   vat_json_init_object (&node);
2818   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2819   vat_json_print (vam->ofp, &node);
2820   vat_json_free (&node);
2821
2822   vec_free (s);
2823   vam->retval = ntohl (mp->retval);
2824   vam->result_ready = 1;
2825 }
2826
2827 static void
2828 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2829 {
2830   vat_main_t *vam = &vat_main;
2831   i32 retval = ntohl (mp->retval);
2832
2833   if (0 <= retval)
2834     {
2835       fformat (vam->ofp, "%-20s%-16s\n",
2836                mp->status ? "enabled" : "disabled",
2837                mp->status ? (char *) mp->locator_set_name : "");
2838     }
2839
2840   vam->retval = retval;
2841   vam->result_ready = 1;
2842 }
2843
2844 static void
2845 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2846                                             mp)
2847 {
2848   vat_main_t *vam = &vat_main;
2849   vat_json_node_t node;
2850   u8 *status = 0;
2851
2852   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2853   vec_add1 (status, 0);
2854
2855   vat_json_init_object (&node);
2856   vat_json_object_add_string_copy (&node, "status", status);
2857   if (mp->status)
2858     {
2859       vat_json_object_add_string_copy (&node, "locator_set",
2860                                        mp->locator_set_name);
2861     }
2862
2863   vec_free (status);
2864
2865   vat_json_print (vam->ofp, &node);
2866   vat_json_free (&node);
2867
2868   vam->retval = ntohl (mp->retval);
2869   vam->result_ready = 1;
2870 }
2871
2872 static u8 *
2873 format_policer_type (u8 * s, va_list * va)
2874 {
2875   u32 i = va_arg (*va, u32);
2876
2877   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2878     s = format (s, "1r2c");
2879   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2880     s = format (s, "1r3c");
2881   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2882     s = format (s, "2r3c-2698");
2883   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2884     s = format (s, "2r3c-4115");
2885   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2886     s = format (s, "2r3c-mef5cf1");
2887   else
2888     s = format (s, "ILLEGAL");
2889   return s;
2890 }
2891
2892 static u8 *
2893 format_policer_rate_type (u8 * s, va_list * va)
2894 {
2895   u32 i = va_arg (*va, u32);
2896
2897   if (i == SSE2_QOS_RATE_KBPS)
2898     s = format (s, "kbps");
2899   else if (i == SSE2_QOS_RATE_PPS)
2900     s = format (s, "pps");
2901   else
2902     s = format (s, "ILLEGAL");
2903   return s;
2904 }
2905
2906 static u8 *
2907 format_policer_round_type (u8 * s, va_list * va)
2908 {
2909   u32 i = va_arg (*va, u32);
2910
2911   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2912     s = format (s, "closest");
2913   else if (i == SSE2_QOS_ROUND_TO_UP)
2914     s = format (s, "up");
2915   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2916     s = format (s, "down");
2917   else
2918     s = format (s, "ILLEGAL");
2919   return s;
2920 }
2921
2922 static u8 *
2923 format_policer_action_type (u8 * s, va_list * va)
2924 {
2925   u32 i = va_arg (*va, u32);
2926
2927   if (i == SSE2_QOS_ACTION_DROP)
2928     s = format (s, "drop");
2929   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2930     s = format (s, "transmit");
2931   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2932     s = format (s, "mark-and-transmit");
2933   else
2934     s = format (s, "ILLEGAL");
2935   return s;
2936 }
2937
2938 static u8 *
2939 format_dscp (u8 * s, va_list * va)
2940 {
2941   u32 i = va_arg (*va, u32);
2942   char *t = 0;
2943
2944   switch (i)
2945     {
2946 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2947       foreach_vnet_dscp
2948 #undef _
2949     default:
2950       return format (s, "ILLEGAL");
2951     }
2952   s = format (s, "%s", t);
2953   return s;
2954 }
2955
2956 static void
2957 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2958 {
2959   vat_main_t *vam = &vat_main;
2960   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2961
2962   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2963     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2964   else
2965     conform_dscp_str = format (0, "");
2966
2967   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2968     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2969   else
2970     exceed_dscp_str = format (0, "");
2971
2972   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2973     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2974   else
2975     violate_dscp_str = format (0, "");
2976
2977   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2978            "rate type %U, round type %U, %s rate, %s color-aware, "
2979            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2980            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2981            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2982            mp->name,
2983            format_policer_type, mp->type,
2984            ntohl (mp->cir),
2985            ntohl (mp->eir),
2986            clib_net_to_host_u64 (mp->cb),
2987            clib_net_to_host_u64 (mp->eb),
2988            format_policer_rate_type, mp->rate_type,
2989            format_policer_round_type, mp->round_type,
2990            mp->single_rate ? "single" : "dual",
2991            mp->color_aware ? "is" : "not",
2992            ntohl (mp->cir_tokens_per_period),
2993            ntohl (mp->pir_tokens_per_period),
2994            ntohl (mp->scale),
2995            ntohl (mp->current_limit),
2996            ntohl (mp->current_bucket),
2997            ntohl (mp->extended_limit),
2998            ntohl (mp->extended_bucket),
2999            clib_net_to_host_u64 (mp->last_update_time),
3000            format_policer_action_type, mp->conform_action_type,
3001            conform_dscp_str,
3002            format_policer_action_type, mp->exceed_action_type,
3003            exceed_dscp_str,
3004            format_policer_action_type, mp->violate_action_type,
3005            violate_dscp_str);
3006
3007   vec_free (conform_dscp_str);
3008   vec_free (exceed_dscp_str);
3009   vec_free (violate_dscp_str);
3010 }
3011
3012 static void vl_api_policer_details_t_handler_json
3013   (vl_api_policer_details_t * mp)
3014 {
3015   vat_main_t *vam = &vat_main;
3016   vat_json_node_t *node;
3017   u8 *rate_type_str, *round_type_str, *type_str;
3018   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3019
3020   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3021   round_type_str =
3022     format (0, "%U", format_policer_round_type, mp->round_type);
3023   type_str = format (0, "%U", format_policer_type, mp->type);
3024   conform_action_str = format (0, "%U", format_policer_action_type,
3025                                mp->conform_action_type);
3026   exceed_action_str = format (0, "%U", format_policer_action_type,
3027                               mp->exceed_action_type);
3028   violate_action_str = format (0, "%U", format_policer_action_type,
3029                                mp->violate_action_type);
3030
3031   if (VAT_JSON_ARRAY != vam->json_tree.type)
3032     {
3033       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3034       vat_json_init_array (&vam->json_tree);
3035     }
3036   node = vat_json_array_add (&vam->json_tree);
3037
3038   vat_json_init_object (node);
3039   vat_json_object_add_string_copy (node, "name", mp->name);
3040   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3041   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3042   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3043   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3044   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3045   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3046   vat_json_object_add_string_copy (node, "type", type_str);
3047   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3048   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3049   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3050   vat_json_object_add_uint (node, "cir_tokens_per_period",
3051                             ntohl (mp->cir_tokens_per_period));
3052   vat_json_object_add_uint (node, "eir_tokens_per_period",
3053                             ntohl (mp->pir_tokens_per_period));
3054   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3055   vat_json_object_add_uint (node, "current_bucket",
3056                             ntohl (mp->current_bucket));
3057   vat_json_object_add_uint (node, "extended_limit",
3058                             ntohl (mp->extended_limit));
3059   vat_json_object_add_uint (node, "extended_bucket",
3060                             ntohl (mp->extended_bucket));
3061   vat_json_object_add_uint (node, "last_update_time",
3062                             ntohl (mp->last_update_time));
3063   vat_json_object_add_string_copy (node, "conform_action",
3064                                    conform_action_str);
3065   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3066     {
3067       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3068       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3069       vec_free (dscp_str);
3070     }
3071   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3072   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3073     {
3074       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3075       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3076       vec_free (dscp_str);
3077     }
3078   vat_json_object_add_string_copy (node, "violate_action",
3079                                    violate_action_str);
3080   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3081     {
3082       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3083       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3084       vec_free (dscp_str);
3085     }
3086
3087   vec_free (rate_type_str);
3088   vec_free (round_type_str);
3089   vec_free (type_str);
3090   vec_free (conform_action_str);
3091   vec_free (exceed_action_str);
3092   vec_free (violate_action_str);
3093 }
3094
3095 static void
3096 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3097                                            mp)
3098 {
3099   vat_main_t *vam = &vat_main;
3100   int i, count = ntohl (mp->count);
3101
3102   if (count > 0)
3103     fformat (vam->ofp, "classify table ids (%d) : ", count);
3104   for (i = 0; i < count; i++)
3105     {
3106       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3107       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3108     }
3109   vam->retval = ntohl (mp->retval);
3110   vam->result_ready = 1;
3111 }
3112
3113 static void
3114   vl_api_classify_table_ids_reply_t_handler_json
3115   (vl_api_classify_table_ids_reply_t * mp)
3116 {
3117   vat_main_t *vam = &vat_main;
3118   int i, count = ntohl (mp->count);
3119
3120   if (count > 0)
3121     {
3122       vat_json_node_t node;
3123
3124       vat_json_init_object (&node);
3125       for (i = 0; i < count; i++)
3126         {
3127           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3128         }
3129       vat_json_print (vam->ofp, &node);
3130       vat_json_free (&node);
3131     }
3132   vam->retval = ntohl (mp->retval);
3133   vam->result_ready = 1;
3134 }
3135
3136 static void
3137   vl_api_classify_table_by_interface_reply_t_handler
3138   (vl_api_classify_table_by_interface_reply_t * mp)
3139 {
3140   vat_main_t *vam = &vat_main;
3141   u32 table_id;
3142
3143   table_id = ntohl (mp->l2_table_id);
3144   if (table_id != ~0)
3145     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3146   else
3147     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3148   table_id = ntohl (mp->ip4_table_id);
3149   if (table_id != ~0)
3150     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3151   else
3152     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3153   table_id = ntohl (mp->ip6_table_id);
3154   if (table_id != ~0)
3155     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3156   else
3157     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3158   vam->retval = ntohl (mp->retval);
3159   vam->result_ready = 1;
3160 }
3161
3162 static void
3163   vl_api_classify_table_by_interface_reply_t_handler_json
3164   (vl_api_classify_table_by_interface_reply_t * mp)
3165 {
3166   vat_main_t *vam = &vat_main;
3167   vat_json_node_t node;
3168
3169   vat_json_init_object (&node);
3170
3171   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3172   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3173   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3174
3175   vat_json_print (vam->ofp, &node);
3176   vat_json_free (&node);
3177
3178   vam->retval = ntohl (mp->retval);
3179   vam->result_ready = 1;
3180 }
3181
3182 static void vl_api_policer_add_del_reply_t_handler
3183   (vl_api_policer_add_del_reply_t * mp)
3184 {
3185   vat_main_t *vam = &vat_main;
3186   i32 retval = ntohl (mp->retval);
3187   if (vam->async_mode)
3188     {
3189       vam->async_errors += (retval < 0);
3190     }
3191   else
3192     {
3193       vam->retval = retval;
3194       vam->result_ready = 1;
3195       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3196         /*
3197          * Note: this is just barely thread-safe, depends on
3198          * the main thread spinning waiting for an answer...
3199          */
3200         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3201     }
3202 }
3203
3204 static void vl_api_policer_add_del_reply_t_handler_json
3205   (vl_api_policer_add_del_reply_t * mp)
3206 {
3207   vat_main_t *vam = &vat_main;
3208   vat_json_node_t node;
3209
3210   vat_json_init_object (&node);
3211   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3212   vat_json_object_add_uint (&node, "policer_index",
3213                             ntohl (mp->policer_index));
3214
3215   vat_json_print (vam->ofp, &node);
3216   vat_json_free (&node);
3217
3218   vam->retval = ntohl (mp->retval);
3219   vam->result_ready = 1;
3220 }
3221
3222 /* Format hex dump. */
3223 u8 *
3224 format_hex_bytes (u8 * s, va_list * va)
3225 {
3226   u8 *bytes = va_arg (*va, u8 *);
3227   int n_bytes = va_arg (*va, int);
3228   uword i;
3229
3230   /* Print short or long form depending on byte count. */
3231   uword short_form = n_bytes <= 32;
3232   uword indent = format_get_indent (s);
3233
3234   if (n_bytes == 0)
3235     return s;
3236
3237   for (i = 0; i < n_bytes; i++)
3238     {
3239       if (!short_form && (i % 32) == 0)
3240         s = format (s, "%08x: ", i);
3241       s = format (s, "%02x", bytes[i]);
3242       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3243         s = format (s, "\n%U", format_white_space, indent);
3244     }
3245
3246   return s;
3247 }
3248
3249 static void
3250 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3251                                             * mp)
3252 {
3253   vat_main_t *vam = &vat_main;
3254   i32 retval = ntohl (mp->retval);
3255   if (retval == 0)
3256     {
3257       fformat (vam->ofp, "classify table info :\n");
3258       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3259                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3260                ntohl (mp->miss_next_index));
3261       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3262                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3263                ntohl (mp->match_n_vectors));
3264       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3265                ntohl (mp->mask_length));
3266     }
3267   vam->retval = retval;
3268   vam->result_ready = 1;
3269 }
3270
3271 static void
3272   vl_api_classify_table_info_reply_t_handler_json
3273   (vl_api_classify_table_info_reply_t * mp)
3274 {
3275   vat_main_t *vam = &vat_main;
3276   vat_json_node_t node;
3277
3278   i32 retval = ntohl (mp->retval);
3279   if (retval == 0)
3280     {
3281       vat_json_init_object (&node);
3282
3283       vat_json_object_add_int (&node, "sessions",
3284                                ntohl (mp->active_sessions));
3285       vat_json_object_add_int (&node, "nexttbl",
3286                                ntohl (mp->next_table_index));
3287       vat_json_object_add_int (&node, "nextnode",
3288                                ntohl (mp->miss_next_index));
3289       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3290       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3291       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3292       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3293                       ntohl (mp->mask_length), 0);
3294       vat_json_object_add_string_copy (&node, "mask", s);
3295
3296       vat_json_print (vam->ofp, &node);
3297       vat_json_free (&node);
3298     }
3299   vam->retval = ntohl (mp->retval);
3300   vam->result_ready = 1;
3301 }
3302
3303 static void
3304 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3305                                            mp)
3306 {
3307   vat_main_t *vam = &vat_main;
3308
3309   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3310            ntohl (mp->hit_next_index), ntohl (mp->advance),
3311            ntohl (mp->opaque_index));
3312   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3313            ntohl (mp->match_length));
3314 }
3315
3316 static void
3317   vl_api_classify_session_details_t_handler_json
3318   (vl_api_classify_session_details_t * mp)
3319 {
3320   vat_main_t *vam = &vat_main;
3321   vat_json_node_t *node = NULL;
3322
3323   if (VAT_JSON_ARRAY != vam->json_tree.type)
3324     {
3325       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3326       vat_json_init_array (&vam->json_tree);
3327     }
3328   node = vat_json_array_add (&vam->json_tree);
3329
3330   vat_json_init_object (node);
3331   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3332   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3333   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3334   u8 *s =
3335     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3336             0);
3337   vat_json_object_add_string_copy (node, "match", s);
3338 }
3339
3340 static void vl_api_pg_create_interface_reply_t_handler
3341   (vl_api_pg_create_interface_reply_t * mp)
3342 {
3343   vat_main_t *vam = &vat_main;
3344
3345   vam->retval = ntohl (mp->retval);
3346   vam->result_ready = 1;
3347 }
3348
3349 static void vl_api_pg_create_interface_reply_t_handler_json
3350   (vl_api_pg_create_interface_reply_t * mp)
3351 {
3352   vat_main_t *vam = &vat_main;
3353   vat_json_node_t node;
3354
3355   i32 retval = ntohl (mp->retval);
3356   if (retval == 0)
3357     {
3358       vat_json_init_object (&node);
3359
3360       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3361
3362       vat_json_print (vam->ofp, &node);
3363       vat_json_free (&node);
3364     }
3365   vam->retval = ntohl (mp->retval);
3366   vam->result_ready = 1;
3367 }
3368
3369 static void vl_api_policer_classify_details_t_handler
3370   (vl_api_policer_classify_details_t * mp)
3371 {
3372   vat_main_t *vam = &vat_main;
3373
3374   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3375            ntohl (mp->table_index));
3376 }
3377
3378 static void vl_api_policer_classify_details_t_handler_json
3379   (vl_api_policer_classify_details_t * mp)
3380 {
3381   vat_main_t *vam = &vat_main;
3382   vat_json_node_t *node;
3383
3384   if (VAT_JSON_ARRAY != vam->json_tree.type)
3385     {
3386       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3387       vat_json_init_array (&vam->json_tree);
3388     }
3389   node = vat_json_array_add (&vam->json_tree);
3390
3391   vat_json_init_object (node);
3392   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3393   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3394 }
3395
3396 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3397   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3398 {
3399   vat_main_t *vam = &vat_main;
3400   i32 retval = ntohl (mp->retval);
3401   if (vam->async_mode)
3402     {
3403       vam->async_errors += (retval < 0);
3404     }
3405   else
3406     {
3407       vam->retval = retval;
3408       vam->sw_if_index = ntohl (mp->sw_if_index);
3409       vam->result_ready = 1;
3410     }
3411 }
3412
3413 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3414   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3415 {
3416   vat_main_t *vam = &vat_main;
3417   vat_json_node_t node;
3418
3419   vat_json_init_object (&node);
3420   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3421   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3422
3423   vat_json_print (vam->ofp, &node);
3424   vat_json_free (&node);
3425
3426   vam->retval = ntohl (mp->retval);
3427   vam->result_ready = 1;
3428 }
3429
3430 static void vl_api_flow_classify_details_t_handler
3431   (vl_api_flow_classify_details_t * mp)
3432 {
3433   vat_main_t *vam = &vat_main;
3434
3435   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3436            ntohl (mp->table_index));
3437 }
3438
3439 static void vl_api_flow_classify_details_t_handler_json
3440   (vl_api_flow_classify_details_t * mp)
3441 {
3442   vat_main_t *vam = &vat_main;
3443   vat_json_node_t *node;
3444
3445   if (VAT_JSON_ARRAY != vam->json_tree.type)
3446     {
3447       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3448       vat_json_init_array (&vam->json_tree);
3449     }
3450   node = vat_json_array_add (&vam->json_tree);
3451
3452   vat_json_init_object (node);
3453   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3454   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3455 }
3456
3457
3458
3459 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3460 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3461 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3462 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3463 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3464 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3465
3466 /*
3467  * Generate boilerplate reply handlers, which
3468  * dig the return value out of the xxx_reply_t API message,
3469  * stick it into vam->retval, and set vam->result_ready
3470  *
3471  * Could also do this by pointing N message decode slots at
3472  * a single function, but that could break in subtle ways.
3473  */
3474
3475 #define foreach_standard_reply_retval_handler           \
3476 _(sw_interface_set_flags_reply)                         \
3477 _(sw_interface_add_del_address_reply)                   \
3478 _(sw_interface_set_table_reply)                         \
3479 _(sw_interface_set_mpls_enable_reply)                   \
3480 _(sw_interface_set_vpath_reply)                         \
3481 _(sw_interface_set_l2_bridge_reply)                     \
3482 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3483 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3484 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3485 _(bridge_domain_add_del_reply)                          \
3486 _(sw_interface_set_l2_xconnect_reply)                   \
3487 _(l2fib_add_del_reply)                                  \
3488 _(ip_add_del_route_reply)                               \
3489 _(mpls_route_add_del_reply)                             \
3490 _(mpls_ip_bind_unbind_reply)                            \
3491 _(proxy_arp_add_del_reply)                              \
3492 _(proxy_arp_intfc_enable_disable_reply)                 \
3493 _(mpls_add_del_encap_reply)                             \
3494 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3495 _(sw_interface_set_unnumbered_reply)                    \
3496 _(ip_neighbor_add_del_reply)                            \
3497 _(reset_vrf_reply)                                      \
3498 _(oam_add_del_reply)                                    \
3499 _(reset_fib_reply)                                      \
3500 _(dhcp_proxy_config_reply)                              \
3501 _(dhcp_proxy_config_2_reply)                            \
3502 _(dhcp_proxy_set_vss_reply)                             \
3503 _(dhcp_client_config_reply)                             \
3504 _(set_ip_flow_hash_reply)                               \
3505 _(sw_interface_ip6_enable_disable_reply)                \
3506 _(sw_interface_ip6_set_link_local_address_reply)        \
3507 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3508 _(sw_interface_ip6nd_ra_config_reply)                   \
3509 _(set_arp_neighbor_limit_reply)                         \
3510 _(l2_patch_add_del_reply)                               \
3511 _(sr_tunnel_add_del_reply)                              \
3512 _(sr_policy_add_del_reply)                              \
3513 _(sr_multicast_map_add_del_reply)                       \
3514 _(classify_add_del_session_reply)                       \
3515 _(classify_set_interface_ip_table_reply)                \
3516 _(classify_set_interface_l2_tables_reply)               \
3517 _(l2tpv3_set_tunnel_cookies_reply)                      \
3518 _(l2tpv3_interface_enable_disable_reply)                \
3519 _(l2tpv3_set_lookup_key_reply)                          \
3520 _(l2_fib_clear_table_reply)                             \
3521 _(l2_interface_efp_filter_reply)                        \
3522 _(l2_interface_vlan_tag_rewrite_reply)                  \
3523 _(modify_vhost_user_if_reply)                           \
3524 _(delete_vhost_user_if_reply)                           \
3525 _(want_ip4_arp_events_reply)                            \
3526 _(want_ip6_nd_events_reply)                             \
3527 _(input_acl_set_interface_reply)                        \
3528 _(ipsec_spd_add_del_reply)                              \
3529 _(ipsec_interface_add_del_spd_reply)                    \
3530 _(ipsec_spd_add_del_entry_reply)                        \
3531 _(ipsec_sad_add_del_entry_reply)                        \
3532 _(ipsec_sa_set_key_reply)                               \
3533 _(ikev2_profile_add_del_reply)                          \
3534 _(ikev2_profile_set_auth_reply)                         \
3535 _(ikev2_profile_set_id_reply)                           \
3536 _(ikev2_profile_set_ts_reply)                           \
3537 _(ikev2_set_local_key_reply)                            \
3538 _(delete_loopback_reply)                                \
3539 _(bd_ip_mac_add_del_reply)                              \
3540 _(map_del_domain_reply)                                 \
3541 _(map_add_del_rule_reply)                               \
3542 _(want_interface_events_reply)                          \
3543 _(want_stats_reply)                                     \
3544 _(cop_interface_enable_disable_reply)                   \
3545 _(cop_whitelist_enable_disable_reply)                   \
3546 _(sw_interface_clear_stats_reply)                       \
3547 _(ioam_enable_reply)                              \
3548 _(ioam_disable_reply)                              \
3549 _(lisp_add_del_locator_reply)                           \
3550 _(lisp_add_del_local_eid_reply)                         \
3551 _(lisp_add_del_remote_mapping_reply)                    \
3552 _(lisp_add_del_adjacency_reply)                         \
3553 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3554 _(lisp_add_del_map_resolver_reply)                      \
3555 _(lisp_gpe_enable_disable_reply)                        \
3556 _(lisp_gpe_add_del_iface_reply)                         \
3557 _(lisp_enable_disable_reply)                            \
3558 _(lisp_pitr_set_locator_set_reply)                      \
3559 _(lisp_map_request_mode_reply)                          \
3560 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3561 _(lisp_eid_table_add_del_map_reply)                     \
3562 _(vxlan_gpe_add_del_tunnel_reply)                       \
3563 _(af_packet_delete_reply)                               \
3564 _(policer_classify_set_interface_reply)                 \
3565 _(netmap_create_reply)                                  \
3566 _(netmap_delete_reply)                                  \
3567 _(set_ipfix_exporter_reply)                             \
3568 _(set_ipfix_classify_stream_reply)                      \
3569 _(ipfix_classify_table_add_del_reply)                   \
3570 _(flow_classify_set_interface_reply)                    \
3571 _(sw_interface_span_enable_disable_reply)               \
3572 _(pg_capture_reply)                                     \
3573 _(pg_enable_disable_reply)                              \
3574 _(ip_source_and_port_range_check_add_del_reply)         \
3575 _(ip_source_and_port_range_check_interface_add_del_reply)\
3576 _(delete_subif_reply)                                   \
3577 _(l2_interface_pbb_tag_rewrite_reply)                   \
3578 _(punt_reply)
3579
3580 #define _(n)                                    \
3581     static void vl_api_##n##_t_handler          \
3582     (vl_api_##n##_t * mp)                       \
3583     {                                           \
3584         vat_main_t * vam = &vat_main;           \
3585         i32 retval = ntohl(mp->retval);         \
3586         if (vam->async_mode) {                  \
3587             vam->async_errors += (retval < 0);  \
3588         } else {                                \
3589             vam->retval = retval;               \
3590             vam->result_ready = 1;              \
3591         }                                       \
3592     }
3593 foreach_standard_reply_retval_handler;
3594 #undef _
3595
3596 #define _(n)                                    \
3597     static void vl_api_##n##_t_handler_json     \
3598     (vl_api_##n##_t * mp)                       \
3599     {                                           \
3600         vat_main_t * vam = &vat_main;           \
3601         vat_json_node_t node;                   \
3602         vat_json_init_object(&node);            \
3603         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3604         vat_json_print(vam->ofp, &node);        \
3605         vam->retval = ntohl(mp->retval);        \
3606         vam->result_ready = 1;                  \
3607     }
3608 foreach_standard_reply_retval_handler;
3609 #undef _
3610
3611 /*
3612  * Table of message reply handlers, must include boilerplate handlers
3613  * we just generated
3614  */
3615
3616 #define foreach_vpe_api_reply_msg                                       \
3617 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3618 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3619 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3620 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3621 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3622 _(CLI_REPLY, cli_reply)                                                 \
3623 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3624 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3625   sw_interface_add_del_address_reply)                                   \
3626 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3627 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3628 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3629 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3630   sw_interface_set_l2_xconnect_reply)                                   \
3631 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3632   sw_interface_set_l2_bridge_reply)                                     \
3633 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3634   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3635 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3636   sw_interface_set_dpdk_hqos_subport_reply)                             \
3637 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3638   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3639 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3640 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3641 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3642 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3643 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3644 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3645 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3646 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3647 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3648 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3649 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3650 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3651 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3652 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3653 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3654   proxy_arp_intfc_enable_disable_reply)                                 \
3655 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3656 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3657   mpls_ethernet_add_del_tunnel_reply)                                   \
3658 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3659   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3660 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3661   sw_interface_set_unnumbered_reply)                                    \
3662 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3663 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3664 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3665 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3666 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3667 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3668 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3669 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3670 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3671 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3672 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3673 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3674   sw_interface_ip6_enable_disable_reply)                                \
3675 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3676   sw_interface_ip6_set_link_local_address_reply)                        \
3677 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3678   sw_interface_ip6nd_ra_prefix_reply)                                   \
3679 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3680   sw_interface_ip6nd_ra_config_reply)                                   \
3681 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3682 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3683 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3684 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3685 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3686 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3687 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3688 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3689 classify_set_interface_ip_table_reply)                                  \
3690 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3691   classify_set_interface_l2_tables_reply)                               \
3692 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3693 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3694 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3695 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3696 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3697   l2tpv3_interface_enable_disable_reply)                                \
3698 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3699 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3700 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3701 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3702 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3703 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3704 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3705 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3706 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3707 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3708 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3709 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3710 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3711 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3712 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3713 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3714 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3715 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3716 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3717 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3718 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3719 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3720 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3721 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3722 _(IP_DETAILS, ip_details)                                               \
3723 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3724 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3725 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3726 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3727 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3728 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3729 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3730 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3731 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3732 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3733 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3734 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3735 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3736 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3737 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3738 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3739 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3740 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3741 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3742 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3743 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3744 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3745 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3746 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3747 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3748 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3749 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3750 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3751 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3752 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3753 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3754 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3755 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3756 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3757 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3758 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3759 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3760 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3761 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3762 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3763 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3764 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3765 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3766 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3767 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3768 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3769 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3770 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3771 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3772 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3773 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3774 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3775 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3776   lisp_add_del_map_request_itr_rlocs_reply)                             \
3777 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3778   lisp_get_map_request_itr_rlocs_reply)                                 \
3779 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3780 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3781 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3782 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3783 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3784 _(POLICER_DETAILS, policer_details)                                     \
3785 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3786 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3787 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3788 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3789 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3790 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3791 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3792 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3793 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3794 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3795 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3796 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3797 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3798 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3799 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3800 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3801 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3802 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3803 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3804 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3805 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3806 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3807 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3808 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3809 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3810 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3811  ip_source_and_port_range_check_add_del_reply)                          \
3812 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3813  ip_source_and_port_range_check_interface_add_del_reply)                \
3814 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3815 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3816 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3817 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3818 _(PUNT_REPLY, punt_reply)                                               \
3819 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3820 _(IP6_FIB_DETAILS, ip6_fib_details)
3821
3822 /* M: construct, but don't yet send a message */
3823
3824 #define M(T,t)                                  \
3825 do {                                            \
3826     vam->result_ready = 0;                      \
3827     mp = vl_msg_api_alloc(sizeof(*mp));         \
3828     memset (mp, 0, sizeof (*mp));               \
3829     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3830     mp->client_index = vam->my_client_index;    \
3831 } while(0);
3832
3833 #define M2(T,t,n)                               \
3834 do {                                            \
3835     vam->result_ready = 0;                      \
3836     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3837     memset (mp, 0, sizeof (*mp));               \
3838     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3839     mp->client_index = vam->my_client_index;    \
3840 } while(0);
3841
3842
3843 /* S: send a message */
3844 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3845
3846 /* W: wait for results, with timeout */
3847 #define W                                       \
3848 do {                                            \
3849     timeout = vat_time_now (vam) + 1.0;         \
3850                                                 \
3851     while (vat_time_now (vam) < timeout) {      \
3852         if (vam->result_ready == 1) {           \
3853             return (vam->retval);               \
3854         }                                       \
3855     }                                           \
3856     return -99;                                 \
3857 } while(0);
3858
3859 /* W2: wait for results, with timeout */
3860 #define W2(body)                                \
3861 do {                                            \
3862     timeout = vat_time_now (vam) + 1.0;         \
3863                                                 \
3864     while (vat_time_now (vam) < timeout) {      \
3865         if (vam->result_ready == 1) {           \
3866           (body);                               \
3867           return (vam->retval);                 \
3868         }                                       \
3869     }                                           \
3870     return -99;                                 \
3871 } while(0);
3872
3873 typedef struct
3874 {
3875   u8 *name;
3876   u32 value;
3877 } name_sort_t;
3878
3879
3880 #define STR_VTR_OP_CASE(op)     \
3881     case L2_VTR_ ## op:         \
3882         return "" # op;
3883
3884 static const char *
3885 str_vtr_op (u32 vtr_op)
3886 {
3887   switch (vtr_op)
3888     {
3889       STR_VTR_OP_CASE (DISABLED);
3890       STR_VTR_OP_CASE (PUSH_1);
3891       STR_VTR_OP_CASE (PUSH_2);
3892       STR_VTR_OP_CASE (POP_1);
3893       STR_VTR_OP_CASE (POP_2);
3894       STR_VTR_OP_CASE (TRANSLATE_1_1);
3895       STR_VTR_OP_CASE (TRANSLATE_1_2);
3896       STR_VTR_OP_CASE (TRANSLATE_2_1);
3897       STR_VTR_OP_CASE (TRANSLATE_2_2);
3898     }
3899
3900   return "UNKNOWN";
3901 }
3902
3903 static int
3904 dump_sub_interface_table (vat_main_t * vam)
3905 {
3906   const sw_interface_subif_t *sub = NULL;
3907
3908   if (vam->json_output)
3909     {
3910       clib_warning
3911         ("JSON output supported only for VPE API calls and dump_stats_table");
3912       return -99;
3913     }
3914
3915   fformat (vam->ofp,
3916            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3917            "Interface", "sw_if_index",
3918            "sub id", "dot1ad", "tags", "outer id",
3919            "inner id", "exact", "default", "outer any", "inner any");
3920
3921   vec_foreach (sub, vam->sw_if_subif_table)
3922   {
3923     fformat (vam->ofp,
3924              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3925              sub->interface_name,
3926              sub->sw_if_index,
3927              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3928              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3929              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3930              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3931     if (sub->vtr_op != L2_VTR_DISABLED)
3932       {
3933         fformat (vam->ofp,
3934                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3935                  "tag1: %d tag2: %d ]\n",
3936                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3937                  sub->vtr_tag1, sub->vtr_tag2);
3938       }
3939   }
3940
3941   return 0;
3942 }
3943
3944 static int
3945 name_sort_cmp (void *a1, void *a2)
3946 {
3947   name_sort_t *n1 = a1;
3948   name_sort_t *n2 = a2;
3949
3950   return strcmp ((char *) n1->name, (char *) n2->name);
3951 }
3952
3953 static int
3954 dump_interface_table (vat_main_t * vam)
3955 {
3956   hash_pair_t *p;
3957   name_sort_t *nses = 0, *ns;
3958
3959   if (vam->json_output)
3960     {
3961       clib_warning
3962         ("JSON output supported only for VPE API calls and dump_stats_table");
3963       return -99;
3964     }
3965
3966   /* *INDENT-OFF* */
3967   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3968   ({
3969     vec_add2 (nses, ns, 1);
3970     ns->name = (u8 *)(p->key);
3971     ns->value = (u32) p->value[0];
3972   }));
3973   /* *INDENT-ON* */
3974
3975   vec_sort_with_function (nses, name_sort_cmp);
3976
3977   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3978   vec_foreach (ns, nses)
3979   {
3980     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3981   }
3982   vec_free (nses);
3983   return 0;
3984 }
3985
3986 static int
3987 dump_ip_table (vat_main_t * vam, int is_ipv6)
3988 {
3989   const ip_details_t *det = NULL;
3990   const ip_address_details_t *address = NULL;
3991   u32 i = ~0;
3992
3993   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3994
3995   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3996   {
3997     i++;
3998     if (!det->present)
3999       {
4000         continue;
4001       }
4002     fformat (vam->ofp, "%-12d\n", i);
4003     fformat (vam->ofp,
4004              "            %-30s%-13s\n", "Address", "Prefix length");
4005     if (!det->addr)
4006       {
4007         continue;
4008       }
4009     vec_foreach (address, det->addr)
4010     {
4011       fformat (vam->ofp,
4012                "            %-30U%-13d\n",
4013                is_ipv6 ? format_ip6_address : format_ip4_address,
4014                address->ip, address->prefix_length);
4015     }
4016   }
4017
4018   return 0;
4019 }
4020
4021 static int
4022 dump_ipv4_table (vat_main_t * vam)
4023 {
4024   if (vam->json_output)
4025     {
4026       clib_warning
4027         ("JSON output supported only for VPE API calls and dump_stats_table");
4028       return -99;
4029     }
4030
4031   return dump_ip_table (vam, 0);
4032 }
4033
4034 static int
4035 dump_ipv6_table (vat_main_t * vam)
4036 {
4037   if (vam->json_output)
4038     {
4039       clib_warning
4040         ("JSON output supported only for VPE API calls and dump_stats_table");
4041       return -99;
4042     }
4043
4044   return dump_ip_table (vam, 1);
4045 }
4046
4047 static char *
4048 counter_type_to_str (u8 counter_type, u8 is_combined)
4049 {
4050   if (!is_combined)
4051     {
4052       switch (counter_type)
4053         {
4054         case VNET_INTERFACE_COUNTER_DROP:
4055           return "drop";
4056         case VNET_INTERFACE_COUNTER_PUNT:
4057           return "punt";
4058         case VNET_INTERFACE_COUNTER_IP4:
4059           return "ip4";
4060         case VNET_INTERFACE_COUNTER_IP6:
4061           return "ip6";
4062         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4063           return "rx-no-buf";
4064         case VNET_INTERFACE_COUNTER_RX_MISS:
4065           return "rx-miss";
4066         case VNET_INTERFACE_COUNTER_RX_ERROR:
4067           return "rx-error";
4068         case VNET_INTERFACE_COUNTER_TX_ERROR:
4069           return "tx-error";
4070         default:
4071           return "INVALID-COUNTER-TYPE";
4072         }
4073     }
4074   else
4075     {
4076       switch (counter_type)
4077         {
4078         case VNET_INTERFACE_COUNTER_RX:
4079           return "rx";
4080         case VNET_INTERFACE_COUNTER_TX:
4081           return "tx";
4082         default:
4083           return "INVALID-COUNTER-TYPE";
4084         }
4085     }
4086 }
4087
4088 static int
4089 dump_stats_table (vat_main_t * vam)
4090 {
4091   vat_json_node_t node;
4092   vat_json_node_t *msg_array;
4093   vat_json_node_t *msg;
4094   vat_json_node_t *counter_array;
4095   vat_json_node_t *counter;
4096   interface_counter_t c;
4097   u64 packets;
4098   ip4_fib_counter_t *c4;
4099   ip6_fib_counter_t *c6;
4100   int i, j;
4101
4102   if (!vam->json_output)
4103     {
4104       clib_warning ("dump_stats_table supported only in JSON format");
4105       return -99;
4106     }
4107
4108   vat_json_init_object (&node);
4109
4110   /* interface counters */
4111   msg_array = vat_json_object_add (&node, "interface_counters");
4112   vat_json_init_array (msg_array);
4113   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4114     {
4115       msg = vat_json_array_add (msg_array);
4116       vat_json_init_object (msg);
4117       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4118                                        (u8 *) counter_type_to_str (i, 0));
4119       vat_json_object_add_int (msg, "is_combined", 0);
4120       counter_array = vat_json_object_add (msg, "data");
4121       vat_json_init_array (counter_array);
4122       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4123         {
4124           packets = vam->simple_interface_counters[i][j];
4125           vat_json_array_add_uint (counter_array, packets);
4126         }
4127     }
4128   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4129     {
4130       msg = vat_json_array_add (msg_array);
4131       vat_json_init_object (msg);
4132       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4133                                        (u8 *) counter_type_to_str (i, 1));
4134       vat_json_object_add_int (msg, "is_combined", 1);
4135       counter_array = vat_json_object_add (msg, "data");
4136       vat_json_init_array (counter_array);
4137       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4138         {
4139           c = vam->combined_interface_counters[i][j];
4140           counter = vat_json_array_add (counter_array);
4141           vat_json_init_object (counter);
4142           vat_json_object_add_uint (counter, "packets", c.packets);
4143           vat_json_object_add_uint (counter, "bytes", c.bytes);
4144         }
4145     }
4146
4147   /* ip4 fib counters */
4148   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4149   vat_json_init_array (msg_array);
4150   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4151     {
4152       msg = vat_json_array_add (msg_array);
4153       vat_json_init_object (msg);
4154       vat_json_object_add_uint (msg, "vrf_id",
4155                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4156       counter_array = vat_json_object_add (msg, "c");
4157       vat_json_init_array (counter_array);
4158       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4159         {
4160           counter = vat_json_array_add (counter_array);
4161           vat_json_init_object (counter);
4162           c4 = &vam->ip4_fib_counters[i][j];
4163           vat_json_object_add_ip4 (counter, "address", c4->address);
4164           vat_json_object_add_uint (counter, "address_length",
4165                                     c4->address_length);
4166           vat_json_object_add_uint (counter, "packets", c4->packets);
4167           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4168         }
4169     }
4170
4171   /* ip6 fib counters */
4172   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4173   vat_json_init_array (msg_array);
4174   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4175     {
4176       msg = vat_json_array_add (msg_array);
4177       vat_json_init_object (msg);
4178       vat_json_object_add_uint (msg, "vrf_id",
4179                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4180       counter_array = vat_json_object_add (msg, "c");
4181       vat_json_init_array (counter_array);
4182       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4183         {
4184           counter = vat_json_array_add (counter_array);
4185           vat_json_init_object (counter);
4186           c6 = &vam->ip6_fib_counters[i][j];
4187           vat_json_object_add_ip6 (counter, "address", c6->address);
4188           vat_json_object_add_uint (counter, "address_length",
4189                                     c6->address_length);
4190           vat_json_object_add_uint (counter, "packets", c6->packets);
4191           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4192         }
4193     }
4194
4195   vat_json_print (vam->ofp, &node);
4196   vat_json_free (&node);
4197
4198   return 0;
4199 }
4200
4201 int
4202 exec (vat_main_t * vam)
4203 {
4204   api_main_t *am = &api_main;
4205   vl_api_cli_request_t *mp;
4206   f64 timeout;
4207   void *oldheap;
4208   u8 *cmd = 0;
4209   unformat_input_t *i = vam->input;
4210
4211   if (vec_len (i->buffer) == 0)
4212     return -1;
4213
4214   if (vam->exec_mode == 0 && unformat (i, "mode"))
4215     {
4216       vam->exec_mode = 1;
4217       return 0;
4218     }
4219   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4220     {
4221       vam->exec_mode = 0;
4222       return 0;
4223     }
4224
4225
4226   M (CLI_REQUEST, cli_request);
4227
4228   /*
4229    * Copy cmd into shared memory.
4230    * In order for the CLI command to work, it
4231    * must be a vector ending in \n, not a C-string ending
4232    * in \n\0.
4233    */
4234   pthread_mutex_lock (&am->vlib_rp->mutex);
4235   oldheap = svm_push_data_heap (am->vlib_rp);
4236
4237   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4238   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4239
4240   svm_pop_heap (oldheap);
4241   pthread_mutex_unlock (&am->vlib_rp->mutex);
4242
4243   mp->cmd_in_shmem = (u64) cmd;
4244   S;
4245   timeout = vat_time_now (vam) + 10.0;
4246
4247   while (vat_time_now (vam) < timeout)
4248     {
4249       if (vam->result_ready == 1)
4250         {
4251           u8 *free_me;
4252           if (vam->shmem_result != NULL)
4253             fformat (vam->ofp, "%s", vam->shmem_result);
4254           pthread_mutex_lock (&am->vlib_rp->mutex);
4255           oldheap = svm_push_data_heap (am->vlib_rp);
4256
4257           free_me = (u8 *) vam->shmem_result;
4258           vec_free (free_me);
4259
4260           svm_pop_heap (oldheap);
4261           pthread_mutex_unlock (&am->vlib_rp->mutex);
4262           return 0;
4263         }
4264     }
4265   return -99;
4266 }
4267
4268 /*
4269  * Future replacement of exec() that passes CLI buffers directly in
4270  * the API messages instead of an additional shared memory area.
4271  */
4272 static int
4273 exec_inband (vat_main_t * vam)
4274 {
4275   vl_api_cli_inband_t *mp;
4276   f64 timeout;
4277   unformat_input_t *i = vam->input;
4278
4279   if (vec_len (i->buffer) == 0)
4280     return -1;
4281
4282   if (vam->exec_mode == 0 && unformat (i, "mode"))
4283     {
4284       vam->exec_mode = 1;
4285       return 0;
4286     }
4287   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4288     {
4289       vam->exec_mode = 0;
4290       return 0;
4291     }
4292
4293   /*
4294    * In order for the CLI command to work, it
4295    * must be a vector ending in \n, not a C-string ending
4296    * in \n\0.
4297    */
4298   u32 len = vec_len (vam->input->buffer);
4299   M2 (CLI_INBAND, cli_inband, len);
4300   clib_memcpy (mp->cmd, vam->input->buffer, len);
4301   mp->length = htonl (len);
4302
4303   S;
4304   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4305 }
4306
4307 static int
4308 api_create_loopback (vat_main_t * vam)
4309 {
4310   unformat_input_t *i = vam->input;
4311   vl_api_create_loopback_t *mp;
4312   f64 timeout;
4313   u8 mac_address[6];
4314   u8 mac_set = 0;
4315
4316   memset (mac_address, 0, sizeof (mac_address));
4317
4318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4319     {
4320       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4321         mac_set = 1;
4322       else
4323         break;
4324     }
4325
4326   /* Construct the API message */
4327   M (CREATE_LOOPBACK, create_loopback);
4328   if (mac_set)
4329     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4330
4331   S;
4332   W;
4333 }
4334
4335 static int
4336 api_delete_loopback (vat_main_t * vam)
4337 {
4338   unformat_input_t *i = vam->input;
4339   vl_api_delete_loopback_t *mp;
4340   f64 timeout;
4341   u32 sw_if_index = ~0;
4342
4343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4344     {
4345       if (unformat (i, "sw_if_index %d", &sw_if_index))
4346         ;
4347       else
4348         break;
4349     }
4350
4351   if (sw_if_index == ~0)
4352     {
4353       errmsg ("missing sw_if_index\n");
4354       return -99;
4355     }
4356
4357   /* Construct the API message */
4358   M (DELETE_LOOPBACK, delete_loopback);
4359   mp->sw_if_index = ntohl (sw_if_index);
4360
4361   S;
4362   W;
4363 }
4364
4365 static int
4366 api_want_stats (vat_main_t * vam)
4367 {
4368   unformat_input_t *i = vam->input;
4369   vl_api_want_stats_t *mp;
4370   f64 timeout;
4371   int enable = -1;
4372
4373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4374     {
4375       if (unformat (i, "enable"))
4376         enable = 1;
4377       else if (unformat (i, "disable"))
4378         enable = 0;
4379       else
4380         break;
4381     }
4382
4383   if (enable == -1)
4384     {
4385       errmsg ("missing enable|disable\n");
4386       return -99;
4387     }
4388
4389   M (WANT_STATS, want_stats);
4390   mp->enable_disable = enable;
4391
4392   S;
4393   W;
4394 }
4395
4396 static int
4397 api_want_interface_events (vat_main_t * vam)
4398 {
4399   unformat_input_t *i = vam->input;
4400   vl_api_want_interface_events_t *mp;
4401   f64 timeout;
4402   int enable = -1;
4403
4404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4405     {
4406       if (unformat (i, "enable"))
4407         enable = 1;
4408       else if (unformat (i, "disable"))
4409         enable = 0;
4410       else
4411         break;
4412     }
4413
4414   if (enable == -1)
4415     {
4416       errmsg ("missing enable|disable\n");
4417       return -99;
4418     }
4419
4420   M (WANT_INTERFACE_EVENTS, want_interface_events);
4421   mp->enable_disable = enable;
4422
4423   vam->interface_event_display = enable;
4424
4425   S;
4426   W;
4427 }
4428
4429
4430 /* Note: non-static, called once to set up the initial intfc table */
4431 int
4432 api_sw_interface_dump (vat_main_t * vam)
4433 {
4434   vl_api_sw_interface_dump_t *mp;
4435   f64 timeout;
4436   hash_pair_t *p;
4437   name_sort_t *nses = 0, *ns;
4438   sw_interface_subif_t *sub = NULL;
4439
4440   /* Toss the old name table */
4441   /* *INDENT-OFF* */
4442   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4443   ({
4444     vec_add2 (nses, ns, 1);
4445     ns->name = (u8 *)(p->key);
4446     ns->value = (u32) p->value[0];
4447   }));
4448   /* *INDENT-ON* */
4449
4450   hash_free (vam->sw_if_index_by_interface_name);
4451
4452   vec_foreach (ns, nses) vec_free (ns->name);
4453
4454   vec_free (nses);
4455
4456   vec_foreach (sub, vam->sw_if_subif_table)
4457   {
4458     vec_free (sub->interface_name);
4459   }
4460   vec_free (vam->sw_if_subif_table);
4461
4462   /* recreate the interface name hash table */
4463   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4464
4465   /* Get list of ethernets */
4466   M (SW_INTERFACE_DUMP, sw_interface_dump);
4467   mp->name_filter_valid = 1;
4468   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4469   S;
4470
4471   /* and local / loopback interfaces */
4472   M (SW_INTERFACE_DUMP, sw_interface_dump);
4473   mp->name_filter_valid = 1;
4474   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4475   S;
4476
4477   /* and packet-generator interfaces */
4478   M (SW_INTERFACE_DUMP, sw_interface_dump);
4479   mp->name_filter_valid = 1;
4480   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4481   S;
4482
4483   /* and vxlan-gpe tunnel interfaces */
4484   M (SW_INTERFACE_DUMP, sw_interface_dump);
4485   mp->name_filter_valid = 1;
4486   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4487            sizeof (mp->name_filter) - 1);
4488   S;
4489
4490   /* and vxlan tunnel interfaces */
4491   M (SW_INTERFACE_DUMP, sw_interface_dump);
4492   mp->name_filter_valid = 1;
4493   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4494   S;
4495
4496   /* and host (af_packet) interfaces */
4497   M (SW_INTERFACE_DUMP, sw_interface_dump);
4498   mp->name_filter_valid = 1;
4499   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4500   S;
4501
4502   /* and l2tpv3 tunnel interfaces */
4503   M (SW_INTERFACE_DUMP, sw_interface_dump);
4504   mp->name_filter_valid = 1;
4505   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4506            sizeof (mp->name_filter) - 1);
4507   S;
4508
4509   /* and GRE tunnel interfaces */
4510   M (SW_INTERFACE_DUMP, sw_interface_dump);
4511   mp->name_filter_valid = 1;
4512   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4513   S;
4514
4515   /* and LISP-GPE interfaces */
4516   M (SW_INTERFACE_DUMP, sw_interface_dump);
4517   mp->name_filter_valid = 1;
4518   strncpy ((char *) mp->name_filter, "lisp_gpe",
4519            sizeof (mp->name_filter) - 1);
4520   S;
4521
4522   /* and IPSEC tunnel interfaces */
4523   M (SW_INTERFACE_DUMP, sw_interface_dump);
4524   mp->name_filter_valid = 1;
4525   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4526   S;
4527
4528   /* Use a control ping for synchronization */
4529   {
4530     vl_api_control_ping_t *mp;
4531     M (CONTROL_PING, control_ping);
4532     S;
4533   }
4534   W;
4535 }
4536
4537 static int
4538 api_sw_interface_set_flags (vat_main_t * vam)
4539 {
4540   unformat_input_t *i = vam->input;
4541   vl_api_sw_interface_set_flags_t *mp;
4542   f64 timeout;
4543   u32 sw_if_index;
4544   u8 sw_if_index_set = 0;
4545   u8 admin_up = 0, link_up = 0;
4546
4547   /* Parse args required to build the message */
4548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4549     {
4550       if (unformat (i, "admin-up"))
4551         admin_up = 1;
4552       else if (unformat (i, "admin-down"))
4553         admin_up = 0;
4554       else if (unformat (i, "link-up"))
4555         link_up = 1;
4556       else if (unformat (i, "link-down"))
4557         link_up = 0;
4558       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4559         sw_if_index_set = 1;
4560       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4561         sw_if_index_set = 1;
4562       else
4563         break;
4564     }
4565
4566   if (sw_if_index_set == 0)
4567     {
4568       errmsg ("missing interface name or sw_if_index\n");
4569       return -99;
4570     }
4571
4572   /* Construct the API message */
4573   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4574   mp->sw_if_index = ntohl (sw_if_index);
4575   mp->admin_up_down = admin_up;
4576   mp->link_up_down = link_up;
4577
4578   /* send it... */
4579   S;
4580
4581   /* Wait for a reply, return the good/bad news... */
4582   W;
4583 }
4584
4585 static int
4586 api_sw_interface_clear_stats (vat_main_t * vam)
4587 {
4588   unformat_input_t *i = vam->input;
4589   vl_api_sw_interface_clear_stats_t *mp;
4590   f64 timeout;
4591   u32 sw_if_index;
4592   u8 sw_if_index_set = 0;
4593
4594   /* Parse args required to build the message */
4595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4596     {
4597       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4598         sw_if_index_set = 1;
4599       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4600         sw_if_index_set = 1;
4601       else
4602         break;
4603     }
4604
4605   /* Construct the API message */
4606   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4607
4608   if (sw_if_index_set == 1)
4609     mp->sw_if_index = ntohl (sw_if_index);
4610   else
4611     mp->sw_if_index = ~0;
4612
4613   /* send it... */
4614   S;
4615
4616   /* Wait for a reply, return the good/bad news... */
4617   W;
4618 }
4619
4620 static int
4621 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4622 {
4623   unformat_input_t *i = vam->input;
4624   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4625   f64 timeout;
4626   u32 sw_if_index;
4627   u8 sw_if_index_set = 0;
4628   u32 subport;
4629   u8 subport_set = 0;
4630   u32 pipe;
4631   u8 pipe_set = 0;
4632   u32 profile;
4633   u8 profile_set = 0;
4634
4635   /* Parse args required to build the message */
4636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4637     {
4638       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4639         sw_if_index_set = 1;
4640       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4641         sw_if_index_set = 1;
4642       else if (unformat (i, "subport %u", &subport))
4643         subport_set = 1;
4644       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4645         sw_if_index_set = 1;
4646       else if (unformat (i, "pipe %u", &pipe))
4647         pipe_set = 1;
4648       else if (unformat (i, "profile %u", &profile))
4649         profile_set = 1;
4650       else
4651         break;
4652     }
4653
4654   if (sw_if_index_set == 0)
4655     {
4656       errmsg ("missing interface name or sw_if_index\n");
4657       return -99;
4658     }
4659
4660   if (subport_set == 0)
4661     {
4662       errmsg ("missing subport \n");
4663       return -99;
4664     }
4665
4666   if (pipe_set == 0)
4667     {
4668       errmsg ("missing pipe\n");
4669       return -99;
4670     }
4671
4672   if (profile_set == 0)
4673     {
4674       errmsg ("missing profile\n");
4675       return -99;
4676     }
4677
4678   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4679
4680   mp->sw_if_index = ntohl (sw_if_index);
4681   mp->subport = ntohl (subport);
4682   mp->pipe = ntohl (pipe);
4683   mp->profile = ntohl (profile);
4684
4685
4686   S;
4687   W;
4688   /* NOTREACHED */
4689   return 0;
4690 }
4691
4692 static int
4693 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4694 {
4695   unformat_input_t *i = vam->input;
4696   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4697   f64 timeout;
4698   u32 sw_if_index;
4699   u8 sw_if_index_set = 0;
4700   u32 subport;
4701   u8 subport_set = 0;
4702   u32 tb_rate = 1250000000;     /* 10GbE */
4703   u32 tb_size = 1000000;
4704   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4705   u32 tc_period = 10;
4706
4707   /* Parse args required to build the message */
4708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4709     {
4710       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4711         sw_if_index_set = 1;
4712       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4713         sw_if_index_set = 1;
4714       else if (unformat (i, "subport %u", &subport))
4715         subport_set = 1;
4716       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4717         sw_if_index_set = 1;
4718       else if (unformat (i, "rate %u", &tb_rate))
4719         {
4720           u32 tc_id;
4721
4722           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4723                tc_id++)
4724             tc_rate[tc_id] = tb_rate;
4725         }
4726       else if (unformat (i, "bktsize %u", &tb_size))
4727         ;
4728       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4729         ;
4730       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4731         ;
4732       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4733         ;
4734       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4735         ;
4736       else if (unformat (i, "period %u", &tc_period))
4737         ;
4738       else
4739         break;
4740     }
4741
4742   if (sw_if_index_set == 0)
4743     {
4744       errmsg ("missing interface name or sw_if_index\n");
4745       return -99;
4746     }
4747
4748   if (subport_set == 0)
4749     {
4750       errmsg ("missing subport \n");
4751       return -99;
4752     }
4753
4754   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4755
4756   mp->sw_if_index = ntohl (sw_if_index);
4757   mp->subport = ntohl (subport);
4758   mp->tb_rate = ntohl (tb_rate);
4759   mp->tb_size = ntohl (tb_size);
4760   mp->tc_rate[0] = ntohl (tc_rate[0]);
4761   mp->tc_rate[1] = ntohl (tc_rate[1]);
4762   mp->tc_rate[2] = ntohl (tc_rate[2]);
4763   mp->tc_rate[3] = ntohl (tc_rate[3]);
4764   mp->tc_period = ntohl (tc_period);
4765
4766   S;
4767   W;
4768   /* NOTREACHED */
4769   return 0;
4770 }
4771
4772 static int
4773 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4774 {
4775   unformat_input_t *i = vam->input;
4776   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4777   f64 timeout;
4778   u32 sw_if_index;
4779   u8 sw_if_index_set = 0;
4780   u8 entry_set = 0;
4781   u8 tc_set = 0;
4782   u8 queue_set = 0;
4783   u32 entry, tc, queue;
4784
4785   /* Parse args required to build the message */
4786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4787     {
4788       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4789         sw_if_index_set = 1;
4790       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4791         sw_if_index_set = 1;
4792       else if (unformat (i, "entry %d", &entry))
4793         entry_set = 1;
4794       else if (unformat (i, "tc %d", &tc))
4795         tc_set = 1;
4796       else if (unformat (i, "queue %d", &queue))
4797         queue_set = 1;
4798       else
4799         break;
4800     }
4801
4802   if (sw_if_index_set == 0)
4803     {
4804       errmsg ("missing interface name or sw_if_index\n");
4805       return -99;
4806     }
4807
4808   if (entry_set == 0)
4809     {
4810       errmsg ("missing entry \n");
4811       return -99;
4812     }
4813
4814   if (tc_set == 0)
4815     {
4816       errmsg ("missing traffic class \n");
4817       return -99;
4818     }
4819
4820   if (queue_set == 0)
4821     {
4822       errmsg ("missing queue \n");
4823       return -99;
4824     }
4825
4826   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4827
4828   mp->sw_if_index = ntohl (sw_if_index);
4829   mp->entry = ntohl (entry);
4830   mp->tc = ntohl (tc);
4831   mp->queue = ntohl (queue);
4832
4833   S;
4834   W;
4835   /* NOTREACHED */
4836   return 0;
4837 }
4838
4839 static int
4840 api_sw_interface_add_del_address (vat_main_t * vam)
4841 {
4842   unformat_input_t *i = vam->input;
4843   vl_api_sw_interface_add_del_address_t *mp;
4844   f64 timeout;
4845   u32 sw_if_index;
4846   u8 sw_if_index_set = 0;
4847   u8 is_add = 1, del_all = 0;
4848   u32 address_length = 0;
4849   u8 v4_address_set = 0;
4850   u8 v6_address_set = 0;
4851   ip4_address_t v4address;
4852   ip6_address_t v6address;
4853
4854   /* Parse args required to build the message */
4855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4856     {
4857       if (unformat (i, "del-all"))
4858         del_all = 1;
4859       else if (unformat (i, "del"))
4860         is_add = 0;
4861       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4862         sw_if_index_set = 1;
4863       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4864         sw_if_index_set = 1;
4865       else if (unformat (i, "%U/%d",
4866                          unformat_ip4_address, &v4address, &address_length))
4867         v4_address_set = 1;
4868       else if (unformat (i, "%U/%d",
4869                          unformat_ip6_address, &v6address, &address_length))
4870         v6_address_set = 1;
4871       else
4872         break;
4873     }
4874
4875   if (sw_if_index_set == 0)
4876     {
4877       errmsg ("missing interface name or sw_if_index\n");
4878       return -99;
4879     }
4880   if (v4_address_set && v6_address_set)
4881     {
4882       errmsg ("both v4 and v6 addresses set\n");
4883       return -99;
4884     }
4885   if (!v4_address_set && !v6_address_set && !del_all)
4886     {
4887       errmsg ("no addresses set\n");
4888       return -99;
4889     }
4890
4891   /* Construct the API message */
4892   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4893
4894   mp->sw_if_index = ntohl (sw_if_index);
4895   mp->is_add = is_add;
4896   mp->del_all = del_all;
4897   if (v6_address_set)
4898     {
4899       mp->is_ipv6 = 1;
4900       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4901     }
4902   else
4903     {
4904       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4905     }
4906   mp->address_length = address_length;
4907
4908   /* send it... */
4909   S;
4910
4911   /* Wait for a reply, return good/bad news  */
4912   W;
4913 }
4914
4915 static int
4916 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4917 {
4918   unformat_input_t *i = vam->input;
4919   vl_api_sw_interface_set_mpls_enable_t *mp;
4920   f64 timeout;
4921   u32 sw_if_index;
4922   u8 sw_if_index_set = 0;
4923   u8 enable = 1;
4924
4925   /* Parse args required to build the message */
4926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4927     {
4928       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4929         sw_if_index_set = 1;
4930       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4931         sw_if_index_set = 1;
4932       else if (unformat (i, "disable"))
4933         enable = 0;
4934       else if (unformat (i, "dis"))
4935         enable = 0;
4936       else
4937         break;
4938     }
4939
4940   if (sw_if_index_set == 0)
4941     {
4942       errmsg ("missing interface name or sw_if_index\n");
4943       return -99;
4944     }
4945
4946   /* Construct the API message */
4947   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
4948
4949   mp->sw_if_index = ntohl (sw_if_index);
4950   mp->enable = enable;
4951
4952   /* send it... */
4953   S;
4954
4955   /* Wait for a reply... */
4956   W;
4957 }
4958
4959 static int
4960 api_sw_interface_set_table (vat_main_t * vam)
4961 {
4962   unformat_input_t *i = vam->input;
4963   vl_api_sw_interface_set_table_t *mp;
4964   f64 timeout;
4965   u32 sw_if_index, vrf_id = 0;
4966   u8 sw_if_index_set = 0;
4967   u8 is_ipv6 = 0;
4968
4969   /* Parse args required to build the message */
4970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4971     {
4972       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4973         sw_if_index_set = 1;
4974       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4975         sw_if_index_set = 1;
4976       else if (unformat (i, "vrf %d", &vrf_id))
4977         ;
4978       else if (unformat (i, "ipv6"))
4979         is_ipv6 = 1;
4980       else
4981         break;
4982     }
4983
4984   if (sw_if_index_set == 0)
4985     {
4986       errmsg ("missing interface name or sw_if_index\n");
4987       return -99;
4988     }
4989
4990   /* Construct the API message */
4991   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4992
4993   mp->sw_if_index = ntohl (sw_if_index);
4994   mp->is_ipv6 = is_ipv6;
4995   mp->vrf_id = ntohl (vrf_id);
4996
4997   /* send it... */
4998   S;
4999
5000   /* Wait for a reply... */
5001   W;
5002 }
5003
5004 static int
5005 api_sw_interface_set_vpath (vat_main_t * vam)
5006 {
5007   unformat_input_t *i = vam->input;
5008   vl_api_sw_interface_set_vpath_t *mp;
5009   f64 timeout;
5010   u32 sw_if_index = 0;
5011   u8 sw_if_index_set = 0;
5012   u8 is_enable = 0;
5013
5014   /* Parse args required to build the message */
5015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5016     {
5017       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5018         sw_if_index_set = 1;
5019       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5020         sw_if_index_set = 1;
5021       else if (unformat (i, "enable"))
5022         is_enable = 1;
5023       else if (unformat (i, "disable"))
5024         is_enable = 0;
5025       else
5026         break;
5027     }
5028
5029   if (sw_if_index_set == 0)
5030     {
5031       errmsg ("missing interface name or sw_if_index\n");
5032       return -99;
5033     }
5034
5035   /* Construct the API message */
5036   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5037
5038   mp->sw_if_index = ntohl (sw_if_index);
5039   mp->enable = is_enable;
5040
5041   /* send it... */
5042   S;
5043
5044   /* Wait for a reply... */
5045   W;
5046 }
5047
5048 static int
5049 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5050 {
5051   unformat_input_t *i = vam->input;
5052   vl_api_sw_interface_set_l2_xconnect_t *mp;
5053   f64 timeout;
5054   u32 rx_sw_if_index;
5055   u8 rx_sw_if_index_set = 0;
5056   u32 tx_sw_if_index;
5057   u8 tx_sw_if_index_set = 0;
5058   u8 enable = 1;
5059
5060   /* Parse args required to build the message */
5061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5062     {
5063       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5064         rx_sw_if_index_set = 1;
5065       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5066         tx_sw_if_index_set = 1;
5067       else if (unformat (i, "rx"))
5068         {
5069           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5070             {
5071               if (unformat (i, "%U", unformat_sw_if_index, vam,
5072                             &rx_sw_if_index))
5073                 rx_sw_if_index_set = 1;
5074             }
5075           else
5076             break;
5077         }
5078       else if (unformat (i, "tx"))
5079         {
5080           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5081             {
5082               if (unformat (i, "%U", unformat_sw_if_index, vam,
5083                             &tx_sw_if_index))
5084                 tx_sw_if_index_set = 1;
5085             }
5086           else
5087             break;
5088         }
5089       else if (unformat (i, "enable"))
5090         enable = 1;
5091       else if (unformat (i, "disable"))
5092         enable = 0;
5093       else
5094         break;
5095     }
5096
5097   if (rx_sw_if_index_set == 0)
5098     {
5099       errmsg ("missing rx interface name or rx_sw_if_index\n");
5100       return -99;
5101     }
5102
5103   if (enable && (tx_sw_if_index_set == 0))
5104     {
5105       errmsg ("missing tx interface name or tx_sw_if_index\n");
5106       return -99;
5107     }
5108
5109   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5110
5111   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5112   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5113   mp->enable = enable;
5114
5115   S;
5116   W;
5117   /* NOTREACHED */
5118   return 0;
5119 }
5120
5121 static int
5122 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5123 {
5124   unformat_input_t *i = vam->input;
5125   vl_api_sw_interface_set_l2_bridge_t *mp;
5126   f64 timeout;
5127   u32 rx_sw_if_index;
5128   u8 rx_sw_if_index_set = 0;
5129   u32 bd_id;
5130   u8 bd_id_set = 0;
5131   u8 bvi = 0;
5132   u32 shg = 0;
5133   u8 enable = 1;
5134
5135   /* Parse args required to build the message */
5136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5137     {
5138       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5139         rx_sw_if_index_set = 1;
5140       else if (unformat (i, "bd_id %d", &bd_id))
5141         bd_id_set = 1;
5142       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5143         rx_sw_if_index_set = 1;
5144       else if (unformat (i, "shg %d", &shg))
5145         ;
5146       else if (unformat (i, "bvi"))
5147         bvi = 1;
5148       else if (unformat (i, "enable"))
5149         enable = 1;
5150       else if (unformat (i, "disable"))
5151         enable = 0;
5152       else
5153         break;
5154     }
5155
5156   if (rx_sw_if_index_set == 0)
5157     {
5158       errmsg ("missing rx interface name or sw_if_index\n");
5159       return -99;
5160     }
5161
5162   if (enable && (bd_id_set == 0))
5163     {
5164       errmsg ("missing bridge domain\n");
5165       return -99;
5166     }
5167
5168   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5169
5170   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5171   mp->bd_id = ntohl (bd_id);
5172   mp->shg = (u8) shg;
5173   mp->bvi = bvi;
5174   mp->enable = enable;
5175
5176   S;
5177   W;
5178   /* NOTREACHED */
5179   return 0;
5180 }
5181
5182 static int
5183 api_bridge_domain_dump (vat_main_t * vam)
5184 {
5185   unformat_input_t *i = vam->input;
5186   vl_api_bridge_domain_dump_t *mp;
5187   f64 timeout;
5188   u32 bd_id = ~0;
5189
5190   /* Parse args required to build the message */
5191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5192     {
5193       if (unformat (i, "bd_id %d", &bd_id))
5194         ;
5195       else
5196         break;
5197     }
5198
5199   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5200   mp->bd_id = ntohl (bd_id);
5201   S;
5202
5203   /* Use a control ping for synchronization */
5204   {
5205     vl_api_control_ping_t *mp;
5206     M (CONTROL_PING, control_ping);
5207     S;
5208   }
5209
5210   W;
5211   /* NOTREACHED */
5212   return 0;
5213 }
5214
5215 static int
5216 api_bridge_domain_add_del (vat_main_t * vam)
5217 {
5218   unformat_input_t *i = vam->input;
5219   vl_api_bridge_domain_add_del_t *mp;
5220   f64 timeout;
5221   u32 bd_id = ~0;
5222   u8 is_add = 1;
5223   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5224
5225   /* Parse args required to build the message */
5226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5227     {
5228       if (unformat (i, "bd_id %d", &bd_id))
5229         ;
5230       else if (unformat (i, "flood %d", &flood))
5231         ;
5232       else if (unformat (i, "uu-flood %d", &uu_flood))
5233         ;
5234       else if (unformat (i, "forward %d", &forward))
5235         ;
5236       else if (unformat (i, "learn %d", &learn))
5237         ;
5238       else if (unformat (i, "arp-term %d", &arp_term))
5239         ;
5240       else if (unformat (i, "del"))
5241         {
5242           is_add = 0;
5243           flood = uu_flood = forward = learn = 0;
5244         }
5245       else
5246         break;
5247     }
5248
5249   if (bd_id == ~0)
5250     {
5251       errmsg ("missing bridge domain\n");
5252       return -99;
5253     }
5254
5255   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5256
5257   mp->bd_id = ntohl (bd_id);
5258   mp->flood = flood;
5259   mp->uu_flood = uu_flood;
5260   mp->forward = forward;
5261   mp->learn = learn;
5262   mp->arp_term = arp_term;
5263   mp->is_add = is_add;
5264
5265   S;
5266   W;
5267   /* NOTREACHED */
5268   return 0;
5269 }
5270
5271 static int
5272 api_l2fib_add_del (vat_main_t * vam)
5273 {
5274   unformat_input_t *i = vam->input;
5275   vl_api_l2fib_add_del_t *mp;
5276   f64 timeout;
5277   u64 mac = 0;
5278   u8 mac_set = 0;
5279   u32 bd_id;
5280   u8 bd_id_set = 0;
5281   u32 sw_if_index;
5282   u8 sw_if_index_set = 0;
5283   u8 is_add = 1;
5284   u8 static_mac = 0;
5285   u8 filter_mac = 0;
5286   u8 bvi_mac = 0;
5287   int count = 1;
5288   f64 before = 0;
5289   int j;
5290
5291   /* Parse args required to build the message */
5292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5293     {
5294       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5295         mac_set = 1;
5296       else if (unformat (i, "bd_id %d", &bd_id))
5297         bd_id_set = 1;
5298       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5299         sw_if_index_set = 1;
5300       else if (unformat (i, "sw_if"))
5301         {
5302           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5303             {
5304               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5305                 sw_if_index_set = 1;
5306             }
5307           else
5308             break;
5309         }
5310       else if (unformat (i, "static"))
5311         static_mac = 1;
5312       else if (unformat (i, "filter"))
5313         {
5314           filter_mac = 1;
5315           static_mac = 1;
5316         }
5317       else if (unformat (i, "bvi"))
5318         {
5319           bvi_mac = 1;
5320           static_mac = 1;
5321         }
5322       else if (unformat (i, "del"))
5323         is_add = 0;
5324       else if (unformat (i, "count %d", &count))
5325         ;
5326       else
5327         break;
5328     }
5329
5330   if (mac_set == 0)
5331     {
5332       errmsg ("missing mac address\n");
5333       return -99;
5334     }
5335
5336   if (bd_id_set == 0)
5337     {
5338       errmsg ("missing bridge domain\n");
5339       return -99;
5340     }
5341
5342   if (is_add && (sw_if_index_set == 0))
5343     {
5344       errmsg ("missing interface name or sw_if_index\n");
5345       return -99;
5346     }
5347
5348   if (count > 1)
5349     {
5350       /* Turn on async mode */
5351       vam->async_mode = 1;
5352       vam->async_errors = 0;
5353       before = vat_time_now (vam);
5354     }
5355
5356   for (j = 0; j < count; j++)
5357     {
5358       M (L2FIB_ADD_DEL, l2fib_add_del);
5359
5360       mp->mac = mac;
5361       mp->bd_id = ntohl (bd_id);
5362       mp->is_add = is_add;
5363
5364       if (is_add)
5365         {
5366           mp->sw_if_index = ntohl (sw_if_index);
5367           mp->static_mac = static_mac;
5368           mp->filter_mac = filter_mac;
5369           mp->bvi_mac = bvi_mac;
5370         }
5371       increment_mac_address (&mac);
5372       /* send it... */
5373       S;
5374     }
5375
5376   if (count > 1)
5377     {
5378       vl_api_control_ping_t *mp;
5379       f64 after;
5380
5381       /* Shut off async mode */
5382       vam->async_mode = 0;
5383
5384       M (CONTROL_PING, control_ping);
5385       S;
5386
5387       timeout = vat_time_now (vam) + 1.0;
5388       while (vat_time_now (vam) < timeout)
5389         if (vam->result_ready == 1)
5390           goto out;
5391       vam->retval = -99;
5392
5393     out:
5394       if (vam->retval == -99)
5395         errmsg ("timeout\n");
5396
5397       if (vam->async_errors > 0)
5398         {
5399           errmsg ("%d asynchronous errors\n", vam->async_errors);
5400           vam->retval = -98;
5401         }
5402       vam->async_errors = 0;
5403       after = vat_time_now (vam);
5404
5405       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5406                count, after - before, count / (after - before));
5407     }
5408   else
5409     {
5410       /* Wait for a reply... */
5411       W;
5412     }
5413   /* Return the good/bad news */
5414   return (vam->retval);
5415 }
5416
5417 static int
5418 api_l2_flags (vat_main_t * vam)
5419 {
5420   unformat_input_t *i = vam->input;
5421   vl_api_l2_flags_t *mp;
5422   f64 timeout;
5423   u32 sw_if_index;
5424   u32 feature_bitmap = 0;
5425   u8 sw_if_index_set = 0;
5426
5427   /* Parse args required to build the message */
5428   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5429     {
5430       if (unformat (i, "sw_if_index %d", &sw_if_index))
5431         sw_if_index_set = 1;
5432       else if (unformat (i, "sw_if"))
5433         {
5434           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5435             {
5436               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5437                 sw_if_index_set = 1;
5438             }
5439           else
5440             break;
5441         }
5442       else if (unformat (i, "learn"))
5443         feature_bitmap |= L2INPUT_FEAT_LEARN;
5444       else if (unformat (i, "forward"))
5445         feature_bitmap |= L2INPUT_FEAT_FWD;
5446       else if (unformat (i, "flood"))
5447         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5448       else if (unformat (i, "uu-flood"))
5449         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5450       else
5451         break;
5452     }
5453
5454   if (sw_if_index_set == 0)
5455     {
5456       errmsg ("missing interface name or sw_if_index\n");
5457       return -99;
5458     }
5459
5460   M (L2_FLAGS, l2_flags);
5461
5462   mp->sw_if_index = ntohl (sw_if_index);
5463   mp->feature_bitmap = ntohl (feature_bitmap);
5464
5465   S;
5466   W;
5467   /* NOTREACHED */
5468   return 0;
5469 }
5470
5471 static int
5472 api_bridge_flags (vat_main_t * vam)
5473 {
5474   unformat_input_t *i = vam->input;
5475   vl_api_bridge_flags_t *mp;
5476   f64 timeout;
5477   u32 bd_id;
5478   u8 bd_id_set = 0;
5479   u8 is_set = 1;
5480   u32 flags = 0;
5481
5482   /* Parse args required to build the message */
5483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5484     {
5485       if (unformat (i, "bd_id %d", &bd_id))
5486         bd_id_set = 1;
5487       else if (unformat (i, "learn"))
5488         flags |= L2_LEARN;
5489       else if (unformat (i, "forward"))
5490         flags |= L2_FWD;
5491       else if (unformat (i, "flood"))
5492         flags |= L2_FLOOD;
5493       else if (unformat (i, "uu-flood"))
5494         flags |= L2_UU_FLOOD;
5495       else if (unformat (i, "arp-term"))
5496         flags |= L2_ARP_TERM;
5497       else if (unformat (i, "off"))
5498         is_set = 0;
5499       else if (unformat (i, "disable"))
5500         is_set = 0;
5501       else
5502         break;
5503     }
5504
5505   if (bd_id_set == 0)
5506     {
5507       errmsg ("missing bridge domain\n");
5508       return -99;
5509     }
5510
5511   M (BRIDGE_FLAGS, bridge_flags);
5512
5513   mp->bd_id = ntohl (bd_id);
5514   mp->feature_bitmap = ntohl (flags);
5515   mp->is_set = is_set;
5516
5517   S;
5518   W;
5519   /* NOTREACHED */
5520   return 0;
5521 }
5522
5523 static int
5524 api_bd_ip_mac_add_del (vat_main_t * vam)
5525 {
5526   unformat_input_t *i = vam->input;
5527   vl_api_bd_ip_mac_add_del_t *mp;
5528   f64 timeout;
5529   u32 bd_id;
5530   u8 is_ipv6 = 0;
5531   u8 is_add = 1;
5532   u8 bd_id_set = 0;
5533   u8 ip_set = 0;
5534   u8 mac_set = 0;
5535   ip4_address_t v4addr;
5536   ip6_address_t v6addr;
5537   u8 macaddr[6];
5538
5539
5540   /* Parse args required to build the message */
5541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5542     {
5543       if (unformat (i, "bd_id %d", &bd_id))
5544         {
5545           bd_id_set++;
5546         }
5547       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5548         {
5549           ip_set++;
5550         }
5551       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5552         {
5553           ip_set++;
5554           is_ipv6++;
5555         }
5556       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5557         {
5558           mac_set++;
5559         }
5560       else if (unformat (i, "del"))
5561         is_add = 0;
5562       else
5563         break;
5564     }
5565
5566   if (bd_id_set == 0)
5567     {
5568       errmsg ("missing bridge domain\n");
5569       return -99;
5570     }
5571   else if (ip_set == 0)
5572     {
5573       errmsg ("missing IP address\n");
5574       return -99;
5575     }
5576   else if (mac_set == 0)
5577     {
5578       errmsg ("missing MAC address\n");
5579       return -99;
5580     }
5581
5582   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5583
5584   mp->bd_id = ntohl (bd_id);
5585   mp->is_ipv6 = is_ipv6;
5586   mp->is_add = is_add;
5587   if (is_ipv6)
5588     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5589   else
5590     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5591   clib_memcpy (mp->mac_address, macaddr, 6);
5592   S;
5593   W;
5594   /* NOTREACHED */
5595   return 0;
5596 }
5597
5598 static int
5599 api_tap_connect (vat_main_t * vam)
5600 {
5601   unformat_input_t *i = vam->input;
5602   vl_api_tap_connect_t *mp;
5603   f64 timeout;
5604   u8 mac_address[6];
5605   u8 random_mac = 1;
5606   u8 name_set = 0;
5607   u8 *tap_name;
5608
5609   memset (mac_address, 0, sizeof (mac_address));
5610
5611   /* Parse args required to build the message */
5612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5613     {
5614       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5615         {
5616           random_mac = 0;
5617         }
5618       else if (unformat (i, "random-mac"))
5619         random_mac = 1;
5620       else if (unformat (i, "tapname %s", &tap_name))
5621         name_set = 1;
5622       else
5623         break;
5624     }
5625
5626   if (name_set == 0)
5627     {
5628       errmsg ("missing tap name\n");
5629       return -99;
5630     }
5631   if (vec_len (tap_name) > 63)
5632     {
5633       errmsg ("tap name too long\n");
5634     }
5635   vec_add1 (tap_name, 0);
5636
5637   /* Construct the API message */
5638   M (TAP_CONNECT, tap_connect);
5639
5640   mp->use_random_mac = random_mac;
5641   clib_memcpy (mp->mac_address, mac_address, 6);
5642   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5643   vec_free (tap_name);
5644
5645   /* send it... */
5646   S;
5647
5648   /* Wait for a reply... */
5649   W;
5650 }
5651
5652 static int
5653 api_tap_modify (vat_main_t * vam)
5654 {
5655   unformat_input_t *i = vam->input;
5656   vl_api_tap_modify_t *mp;
5657   f64 timeout;
5658   u8 mac_address[6];
5659   u8 random_mac = 1;
5660   u8 name_set = 0;
5661   u8 *tap_name;
5662   u32 sw_if_index = ~0;
5663   u8 sw_if_index_set = 0;
5664
5665   memset (mac_address, 0, sizeof (mac_address));
5666
5667   /* Parse args required to build the message */
5668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5669     {
5670       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5671         sw_if_index_set = 1;
5672       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5673         sw_if_index_set = 1;
5674       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5675         {
5676           random_mac = 0;
5677         }
5678       else if (unformat (i, "random-mac"))
5679         random_mac = 1;
5680       else if (unformat (i, "tapname %s", &tap_name))
5681         name_set = 1;
5682       else
5683         break;
5684     }
5685
5686   if (sw_if_index_set == 0)
5687     {
5688       errmsg ("missing vpp interface name");
5689       return -99;
5690     }
5691   if (name_set == 0)
5692     {
5693       errmsg ("missing tap name\n");
5694       return -99;
5695     }
5696   if (vec_len (tap_name) > 63)
5697     {
5698       errmsg ("tap name too long\n");
5699     }
5700   vec_add1 (tap_name, 0);
5701
5702   /* Construct the API message */
5703   M (TAP_MODIFY, tap_modify);
5704
5705   mp->use_random_mac = random_mac;
5706   mp->sw_if_index = ntohl (sw_if_index);
5707   clib_memcpy (mp->mac_address, mac_address, 6);
5708   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5709   vec_free (tap_name);
5710
5711   /* send it... */
5712   S;
5713
5714   /* Wait for a reply... */
5715   W;
5716 }
5717
5718 static int
5719 api_tap_delete (vat_main_t * vam)
5720 {
5721   unformat_input_t *i = vam->input;
5722   vl_api_tap_delete_t *mp;
5723   f64 timeout;
5724   u32 sw_if_index = ~0;
5725   u8 sw_if_index_set = 0;
5726
5727   /* Parse args required to build the message */
5728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5729     {
5730       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5731         sw_if_index_set = 1;
5732       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5733         sw_if_index_set = 1;
5734       else
5735         break;
5736     }
5737
5738   if (sw_if_index_set == 0)
5739     {
5740       errmsg ("missing vpp interface name");
5741       return -99;
5742     }
5743
5744   /* Construct the API message */
5745   M (TAP_DELETE, tap_delete);
5746
5747   mp->sw_if_index = ntohl (sw_if_index);
5748
5749   /* send it... */
5750   S;
5751
5752   /* Wait for a reply... */
5753   W;
5754 }
5755
5756 static int
5757 api_ip_add_del_route (vat_main_t * vam)
5758 {
5759   unformat_input_t *i = vam->input;
5760   vl_api_ip_add_del_route_t *mp;
5761   f64 timeout;
5762   u32 sw_if_index = ~0, vrf_id = 0;
5763   u8 sw_if_index_set = 0;
5764   u8 is_ipv6 = 0;
5765   u8 is_local = 0, is_drop = 0;
5766   u8 is_unreach = 0, is_prohibit = 0;
5767   u8 create_vrf_if_needed = 0;
5768   u8 is_add = 1;
5769   u8 next_hop_weight = 1;
5770   u8 not_last = 0;
5771   u8 is_multipath = 0;
5772   u8 address_set = 0;
5773   u8 address_length_set = 0;
5774   u32 next_hop_table_id = 0;
5775   u32 resolve_attempts = 0;
5776   u32 dst_address_length = 0;
5777   u8 next_hop_set = 0;
5778   ip4_address_t v4_dst_address, v4_next_hop_address;
5779   ip6_address_t v6_dst_address, v6_next_hop_address;
5780   int count = 1;
5781   int j;
5782   f64 before = 0;
5783   u32 random_add_del = 0;
5784   u32 *random_vector = 0;
5785   uword *random_hash;
5786   u32 random_seed = 0xdeaddabe;
5787   u32 classify_table_index = ~0;
5788   u8 is_classify = 0;
5789   u8 resolve_host = 0, resolve_attached = 0;
5790   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5791
5792   /* Parse args required to build the message */
5793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5794     {
5795       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5796         sw_if_index_set = 1;
5797       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5798         sw_if_index_set = 1;
5799       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5800         {
5801           address_set = 1;
5802           is_ipv6 = 0;
5803         }
5804       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5805         {
5806           address_set = 1;
5807           is_ipv6 = 1;
5808         }
5809       else if (unformat (i, "/%d", &dst_address_length))
5810         {
5811           address_length_set = 1;
5812         }
5813
5814       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5815                                          &v4_next_hop_address))
5816         {
5817           next_hop_set = 1;
5818         }
5819       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5820                                          &v6_next_hop_address))
5821         {
5822           next_hop_set = 1;
5823         }
5824       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5825         ;
5826       else if (unformat (i, "weight %d", &next_hop_weight))
5827         ;
5828       else if (unformat (i, "drop"))
5829         {
5830           is_drop = 1;
5831         }
5832       else if (unformat (i, "null-send-unreach"))
5833         {
5834           is_unreach = 1;
5835         }
5836       else if (unformat (i, "null-send-prohibit"))
5837         {
5838           is_prohibit = 1;
5839         }
5840       else if (unformat (i, "local"))
5841         {
5842           is_local = 1;
5843         }
5844       else if (unformat (i, "classify %d", &classify_table_index))
5845         {
5846           is_classify = 1;
5847         }
5848       else if (unformat (i, "del"))
5849         is_add = 0;
5850       else if (unformat (i, "add"))
5851         is_add = 1;
5852       else if (unformat (i, "not-last"))
5853         not_last = 1;
5854       else if (unformat (i, "resolve-via-host"))
5855         resolve_host = 1;
5856       else if (unformat (i, "resolve-via-attached"))
5857         resolve_attached = 1;
5858       else if (unformat (i, "multipath"))
5859         is_multipath = 1;
5860       else if (unformat (i, "vrf %d", &vrf_id))
5861         ;
5862       else if (unformat (i, "create-vrf"))
5863         create_vrf_if_needed = 1;
5864       else if (unformat (i, "count %d", &count))
5865         ;
5866       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
5867         ;
5868       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
5869         ;
5870       else if (unformat (i, "out-label %d", &next_hop_out_label))
5871         ;
5872       else if (unformat (i, "random"))
5873         random_add_del = 1;
5874       else if (unformat (i, "seed %d", &random_seed))
5875         ;
5876       else
5877         {
5878           clib_warning ("parse error '%U'", format_unformat_error, i);
5879           return -99;
5880         }
5881     }
5882
5883   if (resolve_attempts > 0 && sw_if_index_set == 0)
5884     {
5885       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5886       return -99;
5887     }
5888
5889   if (!next_hop_set && !is_drop && !is_local &&
5890       !is_classify && !is_unreach && !is_prohibit)
5891     {
5892       errmsg
5893         ("next hop / local / drop / unreach / prohibit / classify not set\n");
5894       return -99;
5895     }
5896
5897   if (address_set == 0)
5898     {
5899       errmsg ("missing addresses\n");
5900       return -99;
5901     }
5902
5903   if (address_length_set == 0)
5904     {
5905       errmsg ("missing address length\n");
5906       return -99;
5907     }
5908
5909   /* Generate a pile of unique, random routes */
5910   if (random_add_del)
5911     {
5912       u32 this_random_address;
5913       random_hash = hash_create (count, sizeof (uword));
5914
5915       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5916       for (j = 0; j <= count; j++)
5917         {
5918           do
5919             {
5920               this_random_address = random_u32 (&random_seed);
5921               this_random_address =
5922                 clib_host_to_net_u32 (this_random_address);
5923             }
5924           while (hash_get (random_hash, this_random_address));
5925           vec_add1 (random_vector, this_random_address);
5926           hash_set (random_hash, this_random_address, 1);
5927         }
5928       hash_free (random_hash);
5929       v4_dst_address.as_u32 = random_vector[0];
5930     }
5931
5932   if (count > 1)
5933     {
5934       /* Turn on async mode */
5935       vam->async_mode = 1;
5936       vam->async_errors = 0;
5937       before = vat_time_now (vam);
5938     }
5939
5940   for (j = 0; j < count; j++)
5941     {
5942       /* Construct the API message */
5943       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5944
5945       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5946       mp->table_id = ntohl (vrf_id);
5947       if (resolve_attempts > 0)
5948         {
5949           mp->resolve_attempts = ntohl (resolve_attempts);
5950           mp->resolve_if_needed = 1;
5951         }
5952       mp->create_vrf_if_needed = create_vrf_if_needed;
5953
5954       mp->is_add = is_add;
5955       mp->is_drop = is_drop;
5956       mp->is_unreach = is_unreach;
5957       mp->is_prohibit = is_prohibit;
5958       mp->is_ipv6 = is_ipv6;
5959       mp->is_local = is_local;
5960       mp->is_classify = is_classify;
5961       mp->is_multipath = is_multipath;
5962       mp->is_resolve_host = resolve_host;
5963       mp->is_resolve_attached = resolve_attached;
5964       mp->not_last = not_last;
5965       mp->next_hop_weight = next_hop_weight;
5966       mp->dst_address_length = dst_address_length;
5967       mp->next_hop_table_id = ntohl (next_hop_table_id);
5968       mp->classify_table_index = ntohl (classify_table_index);
5969       mp->next_hop_out_label = ntohl (next_hop_out_label);
5970
5971       if (is_ipv6)
5972         {
5973           clib_memcpy (mp->dst_address, &v6_dst_address,
5974                        sizeof (v6_dst_address));
5975           if (next_hop_set)
5976             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5977                          sizeof (v6_next_hop_address));
5978           increment_v6_address (&v6_dst_address);
5979         }
5980       else
5981         {
5982           clib_memcpy (mp->dst_address, &v4_dst_address,
5983                        sizeof (v4_dst_address));
5984           if (next_hop_set)
5985             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5986                          sizeof (v4_next_hop_address));
5987           if (random_add_del)
5988             v4_dst_address.as_u32 = random_vector[j + 1];
5989           else
5990             increment_v4_address (&v4_dst_address);
5991         }
5992       /* send it... */
5993       S;
5994       /* If we receive SIGTERM, stop now... */
5995       if (vam->do_exit)
5996         break;
5997     }
5998
5999   /* When testing multiple add/del ops, use a control-ping to sync */
6000   if (count > 1)
6001     {
6002       vl_api_control_ping_t *mp;
6003       f64 after;
6004
6005       /* Shut off async mode */
6006       vam->async_mode = 0;
6007
6008       M (CONTROL_PING, control_ping);
6009       S;
6010
6011       timeout = vat_time_now (vam) + 1.0;
6012       while (vat_time_now (vam) < timeout)
6013         if (vam->result_ready == 1)
6014           goto out;
6015       vam->retval = -99;
6016
6017     out:
6018       if (vam->retval == -99)
6019         errmsg ("timeout\n");
6020
6021       if (vam->async_errors > 0)
6022         {
6023           errmsg ("%d asynchronous errors\n", vam->async_errors);
6024           vam->retval = -98;
6025         }
6026       vam->async_errors = 0;
6027       after = vat_time_now (vam);
6028
6029       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6030       if (j > 0)
6031         count = j;
6032
6033       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6034                count, after - before, count / (after - before));
6035     }
6036   else
6037     {
6038       /* Wait for a reply... */
6039       W;
6040     }
6041
6042   /* Return the good/bad news */
6043   return (vam->retval);
6044 }
6045
6046 static int
6047 api_mpls_route_add_del (vat_main_t * vam)
6048 {
6049   unformat_input_t *i = vam->input;
6050   vl_api_mpls_route_add_del_t *mp;
6051   f64 timeout;
6052   u32 sw_if_index = ~0, table_id = 0;
6053   u8 create_table_if_needed = 0;
6054   u8 is_add = 1;
6055   u8 next_hop_weight = 1;
6056   u8 is_multipath = 0;
6057   u32 next_hop_table_id = 0;
6058   u8 next_hop_set = 0;
6059   ip4_address_t v4_next_hop_address = {
6060     .as_u32 = 0,
6061   };
6062   ip6_address_t v6_next_hop_address = { {0} };
6063   int count = 1;
6064   int j;
6065   f64 before = 0;
6066   u32 classify_table_index = ~0;
6067   u8 is_classify = 0;
6068   u8 resolve_host = 0, resolve_attached = 0;
6069   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6070   mpls_label_t local_label = MPLS_LABEL_INVALID;
6071   u8 is_eos = 1;
6072   u8 next_hop_proto_is_ip4 = 1;
6073
6074   /* Parse args required to build the message */
6075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6076     {
6077       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6078         ;
6079       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6080         ;
6081       else if (unformat (i, "%d", &local_label))
6082         ;
6083       else if (unformat (i, "eos"))
6084         is_eos = 1;
6085       else if (unformat (i, "non-eos"))
6086         is_eos = 0;
6087       else if (unformat (i, "via %U", unformat_ip4_address,
6088                          &v4_next_hop_address))
6089         {
6090           next_hop_set = 1;
6091           next_hop_proto_is_ip4 = 1;
6092         }
6093       else if (unformat (i, "via %U", unformat_ip6_address,
6094                          &v6_next_hop_address))
6095         {
6096           next_hop_set = 1;
6097           next_hop_proto_is_ip4 = 0;
6098         }
6099       else if (unformat (i, "weight %d", &next_hop_weight))
6100         ;
6101       else if (unformat (i, "create-table"))
6102         create_table_if_needed = 1;
6103       else if (unformat (i, "classify %d", &classify_table_index))
6104         {
6105           is_classify = 1;
6106         }
6107       else if (unformat (i, "del"))
6108         is_add = 0;
6109       else if (unformat (i, "add"))
6110         is_add = 1;
6111       else if (unformat (i, "resolve-via-host"))
6112         resolve_host = 1;
6113       else if (unformat (i, "resolve-via-attached"))
6114         resolve_attached = 1;
6115       else if (unformat (i, "multipath"))
6116         is_multipath = 1;
6117       else if (unformat (i, "count %d", &count))
6118         ;
6119       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6120         {
6121           next_hop_set = 1;
6122           next_hop_proto_is_ip4 = 1;
6123         }
6124       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6125         {
6126           next_hop_set = 1;
6127           next_hop_proto_is_ip4 = 0;
6128         }
6129       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6130         ;
6131       else if (unformat (i, "out-label %d", &next_hop_out_label))
6132         ;
6133       else
6134         {
6135           clib_warning ("parse error '%U'", format_unformat_error, i);
6136           return -99;
6137         }
6138     }
6139
6140   if (!next_hop_set && !is_classify)
6141     {
6142       errmsg ("next hop / classify not set\n");
6143       return -99;
6144     }
6145
6146   if (MPLS_LABEL_INVALID == local_label)
6147     {
6148       errmsg ("missing label\n");
6149       return -99;
6150     }
6151
6152   if (count > 1)
6153     {
6154       /* Turn on async mode */
6155       vam->async_mode = 1;
6156       vam->async_errors = 0;
6157       before = vat_time_now (vam);
6158     }
6159
6160   for (j = 0; j < count; j++)
6161     {
6162       /* Construct the API message */
6163       M (MPLS_ROUTE_ADD_DEL, mpls_route_add_del);
6164
6165       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6166       mp->mr_table_id = ntohl (table_id);
6167       mp->mr_create_table_if_needed = create_table_if_needed;
6168
6169       mp->mr_is_add = is_add;
6170       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6171       mp->mr_is_classify = is_classify;
6172       mp->mr_is_multipath = is_multipath;
6173       mp->mr_is_resolve_host = resolve_host;
6174       mp->mr_is_resolve_attached = resolve_attached;
6175       mp->mr_next_hop_weight = next_hop_weight;
6176       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6177       mp->mr_classify_table_index = ntohl (classify_table_index);
6178       mp->mr_next_hop_out_label = ntohl (next_hop_out_label);
6179       mp->mr_label = ntohl (local_label);
6180       mp->mr_eos = is_eos;
6181
6182       if (next_hop_set)
6183         {
6184           if (next_hop_proto_is_ip4)
6185             {
6186               clib_memcpy (mp->mr_next_hop,
6187                            &v4_next_hop_address,
6188                            sizeof (v4_next_hop_address));
6189             }
6190           else
6191             {
6192               clib_memcpy (mp->mr_next_hop,
6193                            &v6_next_hop_address,
6194                            sizeof (v6_next_hop_address));
6195             }
6196         }
6197       local_label++;
6198
6199       /* send it... */
6200       S;
6201       /* If we receive SIGTERM, stop now... */
6202       if (vam->do_exit)
6203         break;
6204     }
6205
6206   /* When testing multiple add/del ops, use a control-ping to sync */
6207   if (count > 1)
6208     {
6209       vl_api_control_ping_t *mp;
6210       f64 after;
6211
6212       /* Shut off async mode */
6213       vam->async_mode = 0;
6214
6215       M (CONTROL_PING, control_ping);
6216       S;
6217
6218       timeout = vat_time_now (vam) + 1.0;
6219       while (vat_time_now (vam) < timeout)
6220         if (vam->result_ready == 1)
6221           goto out;
6222       vam->retval = -99;
6223
6224     out:
6225       if (vam->retval == -99)
6226         errmsg ("timeout\n");
6227
6228       if (vam->async_errors > 0)
6229         {
6230           errmsg ("%d asynchronous errors\n", vam->async_errors);
6231           vam->retval = -98;
6232         }
6233       vam->async_errors = 0;
6234       after = vat_time_now (vam);
6235
6236       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6237       if (j > 0)
6238         count = j;
6239
6240       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6241                count, after - before, count / (after - before));
6242     }
6243   else
6244     {
6245       /* Wait for a reply... */
6246       W;
6247     }
6248
6249   /* Return the good/bad news */
6250   return (vam->retval);
6251 }
6252
6253 static int
6254 api_mpls_ip_bind_unbind (vat_main_t * vam)
6255 {
6256   unformat_input_t *i = vam->input;
6257   vl_api_mpls_ip_bind_unbind_t *mp;
6258   f64 timeout;
6259   u32 ip_table_id = 0;
6260   u8 create_table_if_needed = 0;
6261   u8 is_bind = 1;
6262   u8 is_ip4 = 1;
6263   ip4_address_t v4_address;
6264   ip6_address_t v6_address;
6265   u32 address_length;
6266   u8 address_set = 0;
6267   mpls_label_t local_label = MPLS_LABEL_INVALID;
6268
6269   /* Parse args required to build the message */
6270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6271     {
6272       if (unformat (i, "%U/%d", unformat_ip4_address,
6273                     &v4_address, &address_length))
6274         {
6275           is_ip4 = 1;
6276           address_set = 1;
6277         }
6278       else if (unformat (i, "%U/%d", unformat_ip6_address,
6279                          &v6_address, &address_length))
6280         {
6281           is_ip4 = 0;
6282           address_set = 1;
6283         }
6284       else if (unformat (i, "%d", &local_label))
6285         ;
6286       else if (unformat (i, "create-table"))
6287         create_table_if_needed = 1;
6288       else if (unformat (i, "table-id %d", &ip_table_id))
6289         ;
6290       else if (unformat (i, "unbind"))
6291         is_bind = 0;
6292       else if (unformat (i, "bind"))
6293         is_bind = 1;
6294       else
6295         {
6296           clib_warning ("parse error '%U'", format_unformat_error, i);
6297           return -99;
6298         }
6299     }
6300
6301   if (!address_set)
6302     {
6303       errmsg ("IP addres not set\n");
6304       return -99;
6305     }
6306
6307   if (MPLS_LABEL_INVALID == local_label)
6308     {
6309       errmsg ("missing label\n");
6310       return -99;
6311     }
6312
6313   /* Construct the API message */
6314   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6315
6316   mp->mb_create_table_if_needed = create_table_if_needed;
6317   mp->mb_is_bind = is_bind;
6318   mp->mb_is_ip4 = is_ip4;
6319   mp->mb_ip_table_id = ntohl (ip_table_id);
6320   mp->mb_mpls_table_id = 0;
6321   mp->mb_label = ntohl (local_label);
6322   mp->mb_address_length = address_length;
6323
6324   if (is_ip4)
6325     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6326   else
6327     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6328
6329   /* send it... */
6330   S;
6331
6332   /* Wait for a reply... */
6333   W;
6334 }
6335
6336 static int
6337 api_proxy_arp_add_del (vat_main_t * vam)
6338 {
6339   unformat_input_t *i = vam->input;
6340   vl_api_proxy_arp_add_del_t *mp;
6341   f64 timeout;
6342   u32 vrf_id = 0;
6343   u8 is_add = 1;
6344   ip4_address_t lo, hi;
6345   u8 range_set = 0;
6346
6347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6348     {
6349       if (unformat (i, "vrf %d", &vrf_id))
6350         ;
6351       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6352                          unformat_ip4_address, &hi))
6353         range_set = 1;
6354       else if (unformat (i, "del"))
6355         is_add = 0;
6356       else
6357         {
6358           clib_warning ("parse error '%U'", format_unformat_error, i);
6359           return -99;
6360         }
6361     }
6362
6363   if (range_set == 0)
6364     {
6365       errmsg ("address range not set\n");
6366       return -99;
6367     }
6368
6369   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6370
6371   mp->vrf_id = ntohl (vrf_id);
6372   mp->is_add = is_add;
6373   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6374   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6375
6376   S;
6377   W;
6378   /* NOTREACHED */
6379   return 0;
6380 }
6381
6382 static int
6383 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6384 {
6385   unformat_input_t *i = vam->input;
6386   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6387   f64 timeout;
6388   u32 sw_if_index;
6389   u8 enable = 1;
6390   u8 sw_if_index_set = 0;
6391
6392   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6393     {
6394       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6395         sw_if_index_set = 1;
6396       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6397         sw_if_index_set = 1;
6398       else if (unformat (i, "enable"))
6399         enable = 1;
6400       else if (unformat (i, "disable"))
6401         enable = 0;
6402       else
6403         {
6404           clib_warning ("parse error '%U'", format_unformat_error, i);
6405           return -99;
6406         }
6407     }
6408
6409   if (sw_if_index_set == 0)
6410     {
6411       errmsg ("missing interface name or sw_if_index\n");
6412       return -99;
6413     }
6414
6415   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6416
6417   mp->sw_if_index = ntohl (sw_if_index);
6418   mp->enable_disable = enable;
6419
6420   S;
6421   W;
6422   /* NOTREACHED */
6423   return 0;
6424 }
6425
6426 static int
6427 api_mpls_add_del_encap (vat_main_t * vam)
6428 {
6429   unformat_input_t *i = vam->input;
6430   vl_api_mpls_add_del_encap_t *mp;
6431   f64 timeout;
6432   u32 vrf_id = 0;
6433   u32 *labels = 0;
6434   u32 label;
6435   ip4_address_t dst_address;
6436   u8 is_add = 1;
6437
6438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6439     {
6440       if (unformat (i, "vrf %d", &vrf_id))
6441         ;
6442       else if (unformat (i, "label %d", &label))
6443         vec_add1 (labels, ntohl (label));
6444       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6445         ;
6446       else if (unformat (i, "del"))
6447         is_add = 0;
6448       else
6449         {
6450           clib_warning ("parse error '%U'", format_unformat_error, i);
6451           return -99;
6452         }
6453     }
6454
6455   if (vec_len (labels) == 0)
6456     {
6457       errmsg ("missing encap label stack\n");
6458       return -99;
6459     }
6460
6461   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6462       sizeof (u32) * vec_len (labels));
6463
6464   mp->vrf_id = ntohl (vrf_id);
6465   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6466   mp->is_add = is_add;
6467   mp->nlabels = vec_len (labels);
6468   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6469
6470   vec_free (labels);
6471
6472   S;
6473   W;
6474   /* NOTREACHED */
6475   return 0;
6476 }
6477
6478 static int
6479 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6480 {
6481   unformat_input_t *i = vam->input;
6482   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6483   f64 timeout;
6484   u32 inner_vrf_id = 0;
6485   ip4_address_t intfc_address;
6486   u8 dst_mac_address[6];
6487   int dst_set = 1;
6488   u32 tmp;
6489   u8 intfc_address_length = 0;
6490   u8 is_add = 1;
6491   u8 l2_only = 0;
6492   u32 tx_sw_if_index;
6493   int tx_sw_if_index_set = 0;
6494
6495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6496     {
6497       if (unformat (i, "vrf %d", &inner_vrf_id))
6498         ;
6499       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6500                          &intfc_address, &tmp))
6501         intfc_address_length = tmp;
6502       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6503         tx_sw_if_index_set = 1;
6504       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6505         tx_sw_if_index_set = 1;
6506       else if (unformat (i, "dst %U", unformat_ethernet_address,
6507                          dst_mac_address))
6508         dst_set = 1;
6509       else if (unformat (i, "l2-only"))
6510         l2_only = 1;
6511       else if (unformat (i, "del"))
6512         is_add = 0;
6513       else
6514         {
6515           clib_warning ("parse error '%U'", format_unformat_error, i);
6516           return -99;
6517         }
6518     }
6519
6520   if (!dst_set)
6521     {
6522       errmsg ("dst (mac address) not set\n");
6523       return -99;
6524     }
6525   if (!tx_sw_if_index_set)
6526     {
6527       errmsg ("tx-intfc not set\n");
6528       return -99;
6529     }
6530
6531   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6532
6533   mp->vrf_id = ntohl (inner_vrf_id);
6534   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6535   mp->adj_address_length = intfc_address_length;
6536   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6537                sizeof (dst_mac_address));
6538   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6539   mp->l2_only = l2_only;
6540   mp->is_add = is_add;
6541
6542   S;
6543   W;
6544   /* NOTREACHED */
6545   return 0;
6546 }
6547
6548 static int
6549 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6550 {
6551   unformat_input_t *i = vam->input;
6552   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6553   f64 timeout;
6554   u32 inner_vrf_id = 0;
6555   u32 outer_vrf_id = 0;
6556   ip4_address_t adj_address;
6557   int adj_address_set = 0;
6558   ip4_address_t next_hop_address;
6559   int next_hop_address_set = 0;
6560   u32 tmp;
6561   u8 adj_address_length = 0;
6562   u8 l2_only = 0;
6563   u8 is_add = 1;
6564   u32 resolve_attempts = 5;
6565   u8 resolve_if_needed = 1;
6566
6567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6568     {
6569       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6570         ;
6571       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6572         ;
6573       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6574                          &adj_address, &tmp))
6575         {
6576           adj_address_length = tmp;
6577           adj_address_set = 1;
6578         }
6579       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6580                          &next_hop_address))
6581         next_hop_address_set = 1;
6582       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6583         ;
6584       else if (unformat (i, "resolve-if-needed %d", &tmp))
6585         resolve_if_needed = tmp;
6586       else if (unformat (i, "l2-only"))
6587         l2_only = 1;
6588       else if (unformat (i, "del"))
6589         is_add = 0;
6590       else
6591         {
6592           clib_warning ("parse error '%U'", format_unformat_error, i);
6593           return -99;
6594         }
6595     }
6596
6597   if (!adj_address_set)
6598     {
6599       errmsg ("adjacency address/mask not set\n");
6600       return -99;
6601     }
6602   if (!next_hop_address_set)
6603     {
6604       errmsg ("ip4 next hop address (in outer fib) not set\n");
6605       return -99;
6606     }
6607
6608   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6609
6610   mp->inner_vrf_id = ntohl (inner_vrf_id);
6611   mp->outer_vrf_id = ntohl (outer_vrf_id);
6612   mp->resolve_attempts = ntohl (resolve_attempts);
6613   mp->resolve_if_needed = resolve_if_needed;
6614   mp->is_add = is_add;
6615   mp->l2_only = l2_only;
6616   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6617   mp->adj_address_length = adj_address_length;
6618   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6619                sizeof (next_hop_address));
6620
6621   S;
6622   W;
6623   /* NOTREACHED */
6624   return 0;
6625 }
6626
6627 static int
6628 api_sw_interface_set_unnumbered (vat_main_t * vam)
6629 {
6630   unformat_input_t *i = vam->input;
6631   vl_api_sw_interface_set_unnumbered_t *mp;
6632   f64 timeout;
6633   u32 sw_if_index;
6634   u32 unnum_sw_index = ~0;
6635   u8 is_add = 1;
6636   u8 sw_if_index_set = 0;
6637
6638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6639     {
6640       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6641         sw_if_index_set = 1;
6642       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6643         sw_if_index_set = 1;
6644       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6645         ;
6646       else if (unformat (i, "del"))
6647         is_add = 0;
6648       else
6649         {
6650           clib_warning ("parse error '%U'", format_unformat_error, i);
6651           return -99;
6652         }
6653     }
6654
6655   if (sw_if_index_set == 0)
6656     {
6657       errmsg ("missing interface name or sw_if_index\n");
6658       return -99;
6659     }
6660
6661   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6662
6663   mp->sw_if_index = ntohl (sw_if_index);
6664   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6665   mp->is_add = is_add;
6666
6667   S;
6668   W;
6669   /* NOTREACHED */
6670   return 0;
6671 }
6672
6673 static int
6674 api_ip_neighbor_add_del (vat_main_t * vam)
6675 {
6676   unformat_input_t *i = vam->input;
6677   vl_api_ip_neighbor_add_del_t *mp;
6678   f64 timeout;
6679   u32 sw_if_index;
6680   u8 sw_if_index_set = 0;
6681   u32 vrf_id = 0;
6682   u8 is_add = 1;
6683   u8 is_static = 0;
6684   u8 mac_address[6];
6685   u8 mac_set = 0;
6686   u8 v4_address_set = 0;
6687   u8 v6_address_set = 0;
6688   ip4_address_t v4address;
6689   ip6_address_t v6address;
6690
6691   memset (mac_address, 0, sizeof (mac_address));
6692
6693   /* Parse args required to build the message */
6694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6695     {
6696       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6697         {
6698           mac_set = 1;
6699         }
6700       else if (unformat (i, "del"))
6701         is_add = 0;
6702       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6703         sw_if_index_set = 1;
6704       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6705         sw_if_index_set = 1;
6706       else if (unformat (i, "is_static"))
6707         is_static = 1;
6708       else if (unformat (i, "vrf %d", &vrf_id))
6709         ;
6710       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6711         v4_address_set = 1;
6712       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6713         v6_address_set = 1;
6714       else
6715         {
6716           clib_warning ("parse error '%U'", format_unformat_error, i);
6717           return -99;
6718         }
6719     }
6720
6721   if (sw_if_index_set == 0)
6722     {
6723       errmsg ("missing interface name or sw_if_index\n");
6724       return -99;
6725     }
6726   if (v4_address_set && v6_address_set)
6727     {
6728       errmsg ("both v4 and v6 addresses set\n");
6729       return -99;
6730     }
6731   if (!v4_address_set && !v6_address_set)
6732     {
6733       errmsg ("no address set\n");
6734       return -99;
6735     }
6736
6737   /* Construct the API message */
6738   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6739
6740   mp->sw_if_index = ntohl (sw_if_index);
6741   mp->is_add = is_add;
6742   mp->vrf_id = ntohl (vrf_id);
6743   mp->is_static = is_static;
6744   if (mac_set)
6745     clib_memcpy (mp->mac_address, mac_address, 6);
6746   if (v6_address_set)
6747     {
6748       mp->is_ipv6 = 1;
6749       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6750     }
6751   else
6752     {
6753       /* mp->is_ipv6 = 0; via memset in M macro above */
6754       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6755     }
6756
6757   /* send it... */
6758   S;
6759
6760   /* Wait for a reply, return good/bad news  */
6761   W;
6762
6763   /* NOTREACHED */
6764   return 0;
6765 }
6766
6767 static int
6768 api_reset_vrf (vat_main_t * vam)
6769 {
6770   unformat_input_t *i = vam->input;
6771   vl_api_reset_vrf_t *mp;
6772   f64 timeout;
6773   u32 vrf_id = 0;
6774   u8 is_ipv6 = 0;
6775   u8 vrf_id_set = 0;
6776
6777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6778     {
6779       if (unformat (i, "vrf %d", &vrf_id))
6780         vrf_id_set = 1;
6781       else if (unformat (i, "ipv6"))
6782         is_ipv6 = 1;
6783       else
6784         {
6785           clib_warning ("parse error '%U'", format_unformat_error, i);
6786           return -99;
6787         }
6788     }
6789
6790   if (vrf_id_set == 0)
6791     {
6792       errmsg ("missing vrf id\n");
6793       return -99;
6794     }
6795
6796   M (RESET_VRF, reset_vrf);
6797
6798   mp->vrf_id = ntohl (vrf_id);
6799   mp->is_ipv6 = is_ipv6;
6800
6801   S;
6802   W;
6803   /* NOTREACHED */
6804   return 0;
6805 }
6806
6807 static int
6808 api_create_vlan_subif (vat_main_t * vam)
6809 {
6810   unformat_input_t *i = vam->input;
6811   vl_api_create_vlan_subif_t *mp;
6812   f64 timeout;
6813   u32 sw_if_index;
6814   u8 sw_if_index_set = 0;
6815   u32 vlan_id;
6816   u8 vlan_id_set = 0;
6817
6818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6819     {
6820       if (unformat (i, "sw_if_index %d", &sw_if_index))
6821         sw_if_index_set = 1;
6822       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6823         sw_if_index_set = 1;
6824       else if (unformat (i, "vlan %d", &vlan_id))
6825         vlan_id_set = 1;
6826       else
6827         {
6828           clib_warning ("parse error '%U'", format_unformat_error, i);
6829           return -99;
6830         }
6831     }
6832
6833   if (sw_if_index_set == 0)
6834     {
6835       errmsg ("missing interface name or sw_if_index\n");
6836       return -99;
6837     }
6838
6839   if (vlan_id_set == 0)
6840     {
6841       errmsg ("missing vlan_id\n");
6842       return -99;
6843     }
6844   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6845
6846   mp->sw_if_index = ntohl (sw_if_index);
6847   mp->vlan_id = ntohl (vlan_id);
6848
6849   S;
6850   W;
6851   /* NOTREACHED */
6852   return 0;
6853 }
6854
6855 #define foreach_create_subif_bit                \
6856 _(no_tags)                                      \
6857 _(one_tag)                                      \
6858 _(two_tags)                                     \
6859 _(dot1ad)                                       \
6860 _(exact_match)                                  \
6861 _(default_sub)                                  \
6862 _(outer_vlan_id_any)                            \
6863 _(inner_vlan_id_any)
6864
6865 static int
6866 api_create_subif (vat_main_t * vam)
6867 {
6868   unformat_input_t *i = vam->input;
6869   vl_api_create_subif_t *mp;
6870   f64 timeout;
6871   u32 sw_if_index;
6872   u8 sw_if_index_set = 0;
6873   u32 sub_id;
6874   u8 sub_id_set = 0;
6875   u32 no_tags = 0;
6876   u32 one_tag = 0;
6877   u32 two_tags = 0;
6878   u32 dot1ad = 0;
6879   u32 exact_match = 0;
6880   u32 default_sub = 0;
6881   u32 outer_vlan_id_any = 0;
6882   u32 inner_vlan_id_any = 0;
6883   u32 tmp;
6884   u16 outer_vlan_id = 0;
6885   u16 inner_vlan_id = 0;
6886
6887   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6888     {
6889       if (unformat (i, "sw_if_index %d", &sw_if_index))
6890         sw_if_index_set = 1;
6891       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6892         sw_if_index_set = 1;
6893       else if (unformat (i, "sub_id %d", &sub_id))
6894         sub_id_set = 1;
6895       else if (unformat (i, "outer_vlan_id %d", &tmp))
6896         outer_vlan_id = tmp;
6897       else if (unformat (i, "inner_vlan_id %d", &tmp))
6898         inner_vlan_id = tmp;
6899
6900 #define _(a) else if (unformat (i, #a)) a = 1 ;
6901       foreach_create_subif_bit
6902 #undef _
6903         else
6904         {
6905           clib_warning ("parse error '%U'", format_unformat_error, i);
6906           return -99;
6907         }
6908     }
6909
6910   if (sw_if_index_set == 0)
6911     {
6912       errmsg ("missing interface name or sw_if_index\n");
6913       return -99;
6914     }
6915
6916   if (sub_id_set == 0)
6917     {
6918       errmsg ("missing sub_id\n");
6919       return -99;
6920     }
6921   M (CREATE_SUBIF, create_subif);
6922
6923   mp->sw_if_index = ntohl (sw_if_index);
6924   mp->sub_id = ntohl (sub_id);
6925
6926 #define _(a) mp->a = a;
6927   foreach_create_subif_bit;
6928 #undef _
6929
6930   mp->outer_vlan_id = ntohs (outer_vlan_id);
6931   mp->inner_vlan_id = ntohs (inner_vlan_id);
6932
6933   S;
6934   W;
6935   /* NOTREACHED */
6936   return 0;
6937 }
6938
6939 static int
6940 api_oam_add_del (vat_main_t * vam)
6941 {
6942   unformat_input_t *i = vam->input;
6943   vl_api_oam_add_del_t *mp;
6944   f64 timeout;
6945   u32 vrf_id = 0;
6946   u8 is_add = 1;
6947   ip4_address_t src, dst;
6948   u8 src_set = 0;
6949   u8 dst_set = 0;
6950
6951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6952     {
6953       if (unformat (i, "vrf %d", &vrf_id))
6954         ;
6955       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6956         src_set = 1;
6957       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6958         dst_set = 1;
6959       else if (unformat (i, "del"))
6960         is_add = 0;
6961       else
6962         {
6963           clib_warning ("parse error '%U'", format_unformat_error, i);
6964           return -99;
6965         }
6966     }
6967
6968   if (src_set == 0)
6969     {
6970       errmsg ("missing src addr\n");
6971       return -99;
6972     }
6973
6974   if (dst_set == 0)
6975     {
6976       errmsg ("missing dst addr\n");
6977       return -99;
6978     }
6979
6980   M (OAM_ADD_DEL, oam_add_del);
6981
6982   mp->vrf_id = ntohl (vrf_id);
6983   mp->is_add = is_add;
6984   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6985   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6986
6987   S;
6988   W;
6989   /* NOTREACHED */
6990   return 0;
6991 }
6992
6993 static int
6994 api_reset_fib (vat_main_t * vam)
6995 {
6996   unformat_input_t *i = vam->input;
6997   vl_api_reset_fib_t *mp;
6998   f64 timeout;
6999   u32 vrf_id = 0;
7000   u8 is_ipv6 = 0;
7001   u8 vrf_id_set = 0;
7002
7003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7004     {
7005       if (unformat (i, "vrf %d", &vrf_id))
7006         vrf_id_set = 1;
7007       else if (unformat (i, "ipv6"))
7008         is_ipv6 = 1;
7009       else
7010         {
7011           clib_warning ("parse error '%U'", format_unformat_error, i);
7012           return -99;
7013         }
7014     }
7015
7016   if (vrf_id_set == 0)
7017     {
7018       errmsg ("missing vrf id\n");
7019       return -99;
7020     }
7021
7022   M (RESET_FIB, reset_fib);
7023
7024   mp->vrf_id = ntohl (vrf_id);
7025   mp->is_ipv6 = is_ipv6;
7026
7027   S;
7028   W;
7029   /* NOTREACHED */
7030   return 0;
7031 }
7032
7033 static int
7034 api_dhcp_proxy_config (vat_main_t * vam)
7035 {
7036   unformat_input_t *i = vam->input;
7037   vl_api_dhcp_proxy_config_t *mp;
7038   f64 timeout;
7039   u32 vrf_id = 0;
7040   u8 is_add = 1;
7041   u8 insert_cid = 1;
7042   u8 v4_address_set = 0;
7043   u8 v6_address_set = 0;
7044   ip4_address_t v4address;
7045   ip6_address_t v6address;
7046   u8 v4_src_address_set = 0;
7047   u8 v6_src_address_set = 0;
7048   ip4_address_t v4srcaddress;
7049   ip6_address_t v6srcaddress;
7050
7051   /* Parse args required to build the message */
7052   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7053     {
7054       if (unformat (i, "del"))
7055         is_add = 0;
7056       else if (unformat (i, "vrf %d", &vrf_id))
7057         ;
7058       else if (unformat (i, "insert-cid %d", &insert_cid))
7059         ;
7060       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7061         v4_address_set = 1;
7062       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7063         v6_address_set = 1;
7064       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7065         v4_src_address_set = 1;
7066       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7067         v6_src_address_set = 1;
7068       else
7069         break;
7070     }
7071
7072   if (v4_address_set && v6_address_set)
7073     {
7074       errmsg ("both v4 and v6 server addresses set\n");
7075       return -99;
7076     }
7077   if (!v4_address_set && !v6_address_set)
7078     {
7079       errmsg ("no server addresses set\n");
7080       return -99;
7081     }
7082
7083   if (v4_src_address_set && v6_src_address_set)
7084     {
7085       errmsg ("both v4 and v6  src addresses set\n");
7086       return -99;
7087     }
7088   if (!v4_src_address_set && !v6_src_address_set)
7089     {
7090       errmsg ("no src addresses set\n");
7091       return -99;
7092     }
7093
7094   if (!(v4_src_address_set && v4_address_set) &&
7095       !(v6_src_address_set && v6_address_set))
7096     {
7097       errmsg ("no matching server and src addresses set\n");
7098       return -99;
7099     }
7100
7101   /* Construct the API message */
7102   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7103
7104   mp->insert_circuit_id = insert_cid;
7105   mp->is_add = is_add;
7106   mp->vrf_id = ntohl (vrf_id);
7107   if (v6_address_set)
7108     {
7109       mp->is_ipv6 = 1;
7110       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7111       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7112     }
7113   else
7114     {
7115       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7116       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7117     }
7118
7119   /* send it... */
7120   S;
7121
7122   /* Wait for a reply, return good/bad news  */
7123   W;
7124   /* NOTREACHED */
7125   return 0;
7126 }
7127
7128 static int
7129 api_dhcp_proxy_config_2 (vat_main_t * vam)
7130 {
7131   unformat_input_t *i = vam->input;
7132   vl_api_dhcp_proxy_config_2_t *mp;
7133   f64 timeout;
7134   u32 rx_vrf_id = 0;
7135   u32 server_vrf_id = 0;
7136   u8 is_add = 1;
7137   u8 insert_cid = 1;
7138   u8 v4_address_set = 0;
7139   u8 v6_address_set = 0;
7140   ip4_address_t v4address;
7141   ip6_address_t v6address;
7142   u8 v4_src_address_set = 0;
7143   u8 v6_src_address_set = 0;
7144   ip4_address_t v4srcaddress;
7145   ip6_address_t v6srcaddress;
7146
7147   /* Parse args required to build the message */
7148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7149     {
7150       if (unformat (i, "del"))
7151         is_add = 0;
7152       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7153         ;
7154       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7155         ;
7156       else if (unformat (i, "insert-cid %d", &insert_cid))
7157         ;
7158       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7159         v4_address_set = 1;
7160       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7161         v6_address_set = 1;
7162       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7163         v4_src_address_set = 1;
7164       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7165         v6_src_address_set = 1;
7166       else
7167         break;
7168     }
7169
7170   if (v4_address_set && v6_address_set)
7171     {
7172       errmsg ("both v4 and v6 server addresses set\n");
7173       return -99;
7174     }
7175   if (!v4_address_set && !v6_address_set)
7176     {
7177       errmsg ("no server addresses set\n");
7178       return -99;
7179     }
7180
7181   if (v4_src_address_set && v6_src_address_set)
7182     {
7183       errmsg ("both v4 and v6  src addresses set\n");
7184       return -99;
7185     }
7186   if (!v4_src_address_set && !v6_src_address_set)
7187     {
7188       errmsg ("no src addresses set\n");
7189       return -99;
7190     }
7191
7192   if (!(v4_src_address_set && v4_address_set) &&
7193       !(v6_src_address_set && v6_address_set))
7194     {
7195       errmsg ("no matching server and src addresses set\n");
7196       return -99;
7197     }
7198
7199   /* Construct the API message */
7200   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7201
7202   mp->insert_circuit_id = insert_cid;
7203   mp->is_add = is_add;
7204   mp->rx_vrf_id = ntohl (rx_vrf_id);
7205   mp->server_vrf_id = ntohl (server_vrf_id);
7206   if (v6_address_set)
7207     {
7208       mp->is_ipv6 = 1;
7209       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7210       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7211     }
7212   else
7213     {
7214       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7215       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7216     }
7217
7218   /* send it... */
7219   S;
7220
7221   /* Wait for a reply, return good/bad news  */
7222   W;
7223   /* NOTREACHED */
7224   return 0;
7225 }
7226
7227 static int
7228 api_dhcp_proxy_set_vss (vat_main_t * vam)
7229 {
7230   unformat_input_t *i = vam->input;
7231   vl_api_dhcp_proxy_set_vss_t *mp;
7232   f64 timeout;
7233   u8 is_ipv6 = 0;
7234   u8 is_add = 1;
7235   u32 tbl_id;
7236   u8 tbl_id_set = 0;
7237   u32 oui;
7238   u8 oui_set = 0;
7239   u32 fib_id;
7240   u8 fib_id_set = 0;
7241
7242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7243     {
7244       if (unformat (i, "tbl_id %d", &tbl_id))
7245         tbl_id_set = 1;
7246       if (unformat (i, "fib_id %d", &fib_id))
7247         fib_id_set = 1;
7248       if (unformat (i, "oui %d", &oui))
7249         oui_set = 1;
7250       else if (unformat (i, "ipv6"))
7251         is_ipv6 = 1;
7252       else if (unformat (i, "del"))
7253         is_add = 0;
7254       else
7255         {
7256           clib_warning ("parse error '%U'", format_unformat_error, i);
7257           return -99;
7258         }
7259     }
7260
7261   if (tbl_id_set == 0)
7262     {
7263       errmsg ("missing tbl id\n");
7264       return -99;
7265     }
7266
7267   if (fib_id_set == 0)
7268     {
7269       errmsg ("missing fib id\n");
7270       return -99;
7271     }
7272   if (oui_set == 0)
7273     {
7274       errmsg ("missing oui\n");
7275       return -99;
7276     }
7277
7278   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7279   mp->tbl_id = ntohl (tbl_id);
7280   mp->fib_id = ntohl (fib_id);
7281   mp->oui = ntohl (oui);
7282   mp->is_ipv6 = is_ipv6;
7283   mp->is_add = is_add;
7284
7285   S;
7286   W;
7287   /* NOTREACHED */
7288   return 0;
7289 }
7290
7291 static int
7292 api_dhcp_client_config (vat_main_t * vam)
7293 {
7294   unformat_input_t *i = vam->input;
7295   vl_api_dhcp_client_config_t *mp;
7296   f64 timeout;
7297   u32 sw_if_index;
7298   u8 sw_if_index_set = 0;
7299   u8 is_add = 1;
7300   u8 *hostname = 0;
7301   u8 disable_event = 0;
7302
7303   /* Parse args required to build the message */
7304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7305     {
7306       if (unformat (i, "del"))
7307         is_add = 0;
7308       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7309         sw_if_index_set = 1;
7310       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7311         sw_if_index_set = 1;
7312       else if (unformat (i, "hostname %s", &hostname))
7313         ;
7314       else if (unformat (i, "disable_event"))
7315         disable_event = 1;
7316       else
7317         break;
7318     }
7319
7320   if (sw_if_index_set == 0)
7321     {
7322       errmsg ("missing interface name or sw_if_index\n");
7323       return -99;
7324     }
7325
7326   if (vec_len (hostname) > 63)
7327     {
7328       errmsg ("hostname too long\n");
7329     }
7330   vec_add1 (hostname, 0);
7331
7332   /* Construct the API message */
7333   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7334
7335   mp->sw_if_index = ntohl (sw_if_index);
7336   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7337   vec_free (hostname);
7338   mp->is_add = is_add;
7339   mp->want_dhcp_event = disable_event ? 0 : 1;
7340   mp->pid = getpid ();
7341
7342   /* send it... */
7343   S;
7344
7345   /* Wait for a reply, return good/bad news  */
7346   W;
7347   /* NOTREACHED */
7348   return 0;
7349 }
7350
7351 static int
7352 api_set_ip_flow_hash (vat_main_t * vam)
7353 {
7354   unformat_input_t *i = vam->input;
7355   vl_api_set_ip_flow_hash_t *mp;
7356   f64 timeout;
7357   u32 vrf_id = 0;
7358   u8 is_ipv6 = 0;
7359   u8 vrf_id_set = 0;
7360   u8 src = 0;
7361   u8 dst = 0;
7362   u8 sport = 0;
7363   u8 dport = 0;
7364   u8 proto = 0;
7365   u8 reverse = 0;
7366
7367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7368     {
7369       if (unformat (i, "vrf %d", &vrf_id))
7370         vrf_id_set = 1;
7371       else if (unformat (i, "ipv6"))
7372         is_ipv6 = 1;
7373       else if (unformat (i, "src"))
7374         src = 1;
7375       else if (unformat (i, "dst"))
7376         dst = 1;
7377       else if (unformat (i, "sport"))
7378         sport = 1;
7379       else if (unformat (i, "dport"))
7380         dport = 1;
7381       else if (unformat (i, "proto"))
7382         proto = 1;
7383       else if (unformat (i, "reverse"))
7384         reverse = 1;
7385
7386       else
7387         {
7388           clib_warning ("parse error '%U'", format_unformat_error, i);
7389           return -99;
7390         }
7391     }
7392
7393   if (vrf_id_set == 0)
7394     {
7395       errmsg ("missing vrf id\n");
7396       return -99;
7397     }
7398
7399   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7400   mp->src = src;
7401   mp->dst = dst;
7402   mp->sport = sport;
7403   mp->dport = dport;
7404   mp->proto = proto;
7405   mp->reverse = reverse;
7406   mp->vrf_id = ntohl (vrf_id);
7407   mp->is_ipv6 = is_ipv6;
7408
7409   S;
7410   W;
7411   /* NOTREACHED */
7412   return 0;
7413 }
7414
7415 static int
7416 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7417 {
7418   unformat_input_t *i = vam->input;
7419   vl_api_sw_interface_ip6_enable_disable_t *mp;
7420   f64 timeout;
7421   u32 sw_if_index;
7422   u8 sw_if_index_set = 0;
7423   u8 enable = 0;
7424
7425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7426     {
7427       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7428         sw_if_index_set = 1;
7429       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7430         sw_if_index_set = 1;
7431       else if (unformat (i, "enable"))
7432         enable = 1;
7433       else if (unformat (i, "disable"))
7434         enable = 0;
7435       else
7436         {
7437           clib_warning ("parse error '%U'", format_unformat_error, i);
7438           return -99;
7439         }
7440     }
7441
7442   if (sw_if_index_set == 0)
7443     {
7444       errmsg ("missing interface name or sw_if_index\n");
7445       return -99;
7446     }
7447
7448   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7449
7450   mp->sw_if_index = ntohl (sw_if_index);
7451   mp->enable = enable;
7452
7453   S;
7454   W;
7455   /* NOTREACHED */
7456   return 0;
7457 }
7458
7459 static int
7460 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7461 {
7462   unformat_input_t *i = vam->input;
7463   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7464   f64 timeout;
7465   u32 sw_if_index;
7466   u8 sw_if_index_set = 0;
7467   u32 address_length = 0;
7468   u8 v6_address_set = 0;
7469   ip6_address_t v6address;
7470
7471   /* Parse args required to build the message */
7472   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7473     {
7474       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7475         sw_if_index_set = 1;
7476       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7477         sw_if_index_set = 1;
7478       else if (unformat (i, "%U/%d",
7479                          unformat_ip6_address, &v6address, &address_length))
7480         v6_address_set = 1;
7481       else
7482         break;
7483     }
7484
7485   if (sw_if_index_set == 0)
7486     {
7487       errmsg ("missing interface name or sw_if_index\n");
7488       return -99;
7489     }
7490   if (!v6_address_set)
7491     {
7492       errmsg ("no address set\n");
7493       return -99;
7494     }
7495
7496   /* Construct the API message */
7497   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7498      sw_interface_ip6_set_link_local_address);
7499
7500   mp->sw_if_index = ntohl (sw_if_index);
7501   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7502   mp->address_length = address_length;
7503
7504   /* send it... */
7505   S;
7506
7507   /* Wait for a reply, return good/bad news  */
7508   W;
7509
7510   /* NOTREACHED */
7511   return 0;
7512 }
7513
7514
7515 static int
7516 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7517 {
7518   unformat_input_t *i = vam->input;
7519   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7520   f64 timeout;
7521   u32 sw_if_index;
7522   u8 sw_if_index_set = 0;
7523   u32 address_length = 0;
7524   u8 v6_address_set = 0;
7525   ip6_address_t v6address;
7526   u8 use_default = 0;
7527   u8 no_advertise = 0;
7528   u8 off_link = 0;
7529   u8 no_autoconfig = 0;
7530   u8 no_onlink = 0;
7531   u8 is_no = 0;
7532   u32 val_lifetime = 0;
7533   u32 pref_lifetime = 0;
7534
7535   /* Parse args required to build the message */
7536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7537     {
7538       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7539         sw_if_index_set = 1;
7540       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7541         sw_if_index_set = 1;
7542       else if (unformat (i, "%U/%d",
7543                          unformat_ip6_address, &v6address, &address_length))
7544         v6_address_set = 1;
7545       else if (unformat (i, "val_life %d", &val_lifetime))
7546         ;
7547       else if (unformat (i, "pref_life %d", &pref_lifetime))
7548         ;
7549       else if (unformat (i, "def"))
7550         use_default = 1;
7551       else if (unformat (i, "noadv"))
7552         no_advertise = 1;
7553       else if (unformat (i, "offl"))
7554         off_link = 1;
7555       else if (unformat (i, "noauto"))
7556         no_autoconfig = 1;
7557       else if (unformat (i, "nolink"))
7558         no_onlink = 1;
7559       else if (unformat (i, "isno"))
7560         is_no = 1;
7561       else
7562         {
7563           clib_warning ("parse error '%U'", format_unformat_error, i);
7564           return -99;
7565         }
7566     }
7567
7568   if (sw_if_index_set == 0)
7569     {
7570       errmsg ("missing interface name or sw_if_index\n");
7571       return -99;
7572     }
7573   if (!v6_address_set)
7574     {
7575       errmsg ("no address set\n");
7576       return -99;
7577     }
7578
7579   /* Construct the API message */
7580   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7581
7582   mp->sw_if_index = ntohl (sw_if_index);
7583   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7584   mp->address_length = address_length;
7585   mp->use_default = use_default;
7586   mp->no_advertise = no_advertise;
7587   mp->off_link = off_link;
7588   mp->no_autoconfig = no_autoconfig;
7589   mp->no_onlink = no_onlink;
7590   mp->is_no = is_no;
7591   mp->val_lifetime = ntohl (val_lifetime);
7592   mp->pref_lifetime = ntohl (pref_lifetime);
7593
7594   /* send it... */
7595   S;
7596
7597   /* Wait for a reply, return good/bad news  */
7598   W;
7599
7600   /* NOTREACHED */
7601   return 0;
7602 }
7603
7604 static int
7605 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7606 {
7607   unformat_input_t *i = vam->input;
7608   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7609   f64 timeout;
7610   u32 sw_if_index;
7611   u8 sw_if_index_set = 0;
7612   u8 suppress = 0;
7613   u8 managed = 0;
7614   u8 other = 0;
7615   u8 ll_option = 0;
7616   u8 send_unicast = 0;
7617   u8 cease = 0;
7618   u8 is_no = 0;
7619   u8 default_router = 0;
7620   u32 max_interval = 0;
7621   u32 min_interval = 0;
7622   u32 lifetime = 0;
7623   u32 initial_count = 0;
7624   u32 initial_interval = 0;
7625
7626
7627   /* Parse args required to build the message */
7628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7629     {
7630       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7631         sw_if_index_set = 1;
7632       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7633         sw_if_index_set = 1;
7634       else if (unformat (i, "maxint %d", &max_interval))
7635         ;
7636       else if (unformat (i, "minint %d", &min_interval))
7637         ;
7638       else if (unformat (i, "life %d", &lifetime))
7639         ;
7640       else if (unformat (i, "count %d", &initial_count))
7641         ;
7642       else if (unformat (i, "interval %d", &initial_interval))
7643         ;
7644       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7645         suppress = 1;
7646       else if (unformat (i, "managed"))
7647         managed = 1;
7648       else if (unformat (i, "other"))
7649         other = 1;
7650       else if (unformat (i, "ll"))
7651         ll_option = 1;
7652       else if (unformat (i, "send"))
7653         send_unicast = 1;
7654       else if (unformat (i, "cease"))
7655         cease = 1;
7656       else if (unformat (i, "isno"))
7657         is_no = 1;
7658       else if (unformat (i, "def"))
7659         default_router = 1;
7660       else
7661         {
7662           clib_warning ("parse error '%U'", format_unformat_error, i);
7663           return -99;
7664         }
7665     }
7666
7667   if (sw_if_index_set == 0)
7668     {
7669       errmsg ("missing interface name or sw_if_index\n");
7670       return -99;
7671     }
7672
7673   /* Construct the API message */
7674   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7675
7676   mp->sw_if_index = ntohl (sw_if_index);
7677   mp->max_interval = ntohl (max_interval);
7678   mp->min_interval = ntohl (min_interval);
7679   mp->lifetime = ntohl (lifetime);
7680   mp->initial_count = ntohl (initial_count);
7681   mp->initial_interval = ntohl (initial_interval);
7682   mp->suppress = suppress;
7683   mp->managed = managed;
7684   mp->other = other;
7685   mp->ll_option = ll_option;
7686   mp->send_unicast = send_unicast;
7687   mp->cease = cease;
7688   mp->is_no = is_no;
7689   mp->default_router = default_router;
7690
7691   /* send it... */
7692   S;
7693
7694   /* Wait for a reply, return good/bad news  */
7695   W;
7696
7697   /* NOTREACHED */
7698   return 0;
7699 }
7700
7701 static int
7702 api_set_arp_neighbor_limit (vat_main_t * vam)
7703 {
7704   unformat_input_t *i = vam->input;
7705   vl_api_set_arp_neighbor_limit_t *mp;
7706   f64 timeout;
7707   u32 arp_nbr_limit;
7708   u8 limit_set = 0;
7709   u8 is_ipv6 = 0;
7710
7711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7712     {
7713       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7714         limit_set = 1;
7715       else if (unformat (i, "ipv6"))
7716         is_ipv6 = 1;
7717       else
7718         {
7719           clib_warning ("parse error '%U'", format_unformat_error, i);
7720           return -99;
7721         }
7722     }
7723
7724   if (limit_set == 0)
7725     {
7726       errmsg ("missing limit value\n");
7727       return -99;
7728     }
7729
7730   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7731
7732   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7733   mp->is_ipv6 = is_ipv6;
7734
7735   S;
7736   W;
7737   /* NOTREACHED */
7738   return 0;
7739 }
7740
7741 static int
7742 api_l2_patch_add_del (vat_main_t * vam)
7743 {
7744   unformat_input_t *i = vam->input;
7745   vl_api_l2_patch_add_del_t *mp;
7746   f64 timeout;
7747   u32 rx_sw_if_index;
7748   u8 rx_sw_if_index_set = 0;
7749   u32 tx_sw_if_index;
7750   u8 tx_sw_if_index_set = 0;
7751   u8 is_add = 1;
7752
7753   /* Parse args required to build the message */
7754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7755     {
7756       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7757         rx_sw_if_index_set = 1;
7758       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7759         tx_sw_if_index_set = 1;
7760       else if (unformat (i, "rx"))
7761         {
7762           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7763             {
7764               if (unformat (i, "%U", unformat_sw_if_index, vam,
7765                             &rx_sw_if_index))
7766                 rx_sw_if_index_set = 1;
7767             }
7768           else
7769             break;
7770         }
7771       else if (unformat (i, "tx"))
7772         {
7773           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7774             {
7775               if (unformat (i, "%U", unformat_sw_if_index, vam,
7776                             &tx_sw_if_index))
7777                 tx_sw_if_index_set = 1;
7778             }
7779           else
7780             break;
7781         }
7782       else if (unformat (i, "del"))
7783         is_add = 0;
7784       else
7785         break;
7786     }
7787
7788   if (rx_sw_if_index_set == 0)
7789     {
7790       errmsg ("missing rx interface name or rx_sw_if_index\n");
7791       return -99;
7792     }
7793
7794   if (tx_sw_if_index_set == 0)
7795     {
7796       errmsg ("missing tx interface name or tx_sw_if_index\n");
7797       return -99;
7798     }
7799
7800   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7801
7802   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7803   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7804   mp->is_add = is_add;
7805
7806   S;
7807   W;
7808   /* NOTREACHED */
7809   return 0;
7810 }
7811
7812 static int
7813 api_ioam_enable (vat_main_t * vam)
7814 {
7815   unformat_input_t *input = vam->input;
7816   vl_api_ioam_enable_t *mp;
7817   f64 timeout;
7818   u32 id = 0;
7819   int has_trace_option = 0;
7820   int has_pot_option = 0;
7821   int has_seqno_option = 0;
7822   int has_analyse_option = 0;
7823
7824   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7825     {
7826       if (unformat (input, "trace"))
7827         has_trace_option = 1;
7828       else if (unformat (input, "pot"))
7829         has_pot_option = 1;
7830       else if (unformat (input, "seqno"))
7831         has_seqno_option = 1;
7832       else if (unformat (input, "analyse"))
7833         has_analyse_option = 1;
7834       else
7835         break;
7836     }
7837   M (IOAM_ENABLE, ioam_enable);
7838   mp->id = htons (id);
7839   mp->seqno = has_seqno_option;
7840   mp->analyse = has_analyse_option;
7841   mp->pot_enable = has_pot_option;
7842   mp->trace_enable = has_trace_option;
7843
7844   S;
7845   W;
7846
7847   return (0);
7848
7849 }
7850
7851
7852 static int
7853 api_ioam_disable (vat_main_t * vam)
7854 {
7855   vl_api_ioam_disable_t *mp;
7856   f64 timeout;
7857
7858   M (IOAM_DISABLE, ioam_disable);
7859   S;
7860   W;
7861   return 0;
7862 }
7863
7864 static int
7865 api_sr_tunnel_add_del (vat_main_t * vam)
7866 {
7867   unformat_input_t *i = vam->input;
7868   vl_api_sr_tunnel_add_del_t *mp;
7869   f64 timeout;
7870   int is_del = 0;
7871   int pl_index;
7872   ip6_address_t src_address;
7873   int src_address_set = 0;
7874   ip6_address_t dst_address;
7875   u32 dst_mask_width;
7876   int dst_address_set = 0;
7877   u16 flags = 0;
7878   u32 rx_table_id = 0;
7879   u32 tx_table_id = 0;
7880   ip6_address_t *segments = 0;
7881   ip6_address_t *this_seg;
7882   ip6_address_t *tags = 0;
7883   ip6_address_t *this_tag;
7884   ip6_address_t next_address, tag;
7885   u8 *name = 0;
7886   u8 *policy_name = 0;
7887
7888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7889     {
7890       if (unformat (i, "del"))
7891         is_del = 1;
7892       else if (unformat (i, "name %s", &name))
7893         ;
7894       else if (unformat (i, "policy %s", &policy_name))
7895         ;
7896       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7897         ;
7898       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7899         ;
7900       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7901         src_address_set = 1;
7902       else if (unformat (i, "dst %U/%d",
7903                          unformat_ip6_address, &dst_address, &dst_mask_width))
7904         dst_address_set = 1;
7905       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7906         {
7907           vec_add2 (segments, this_seg, 1);
7908           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7909                        sizeof (*this_seg));
7910         }
7911       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7912         {
7913           vec_add2 (tags, this_tag, 1);
7914           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7915         }
7916       else if (unformat (i, "clean"))
7917         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7918       else if (unformat (i, "protected"))
7919         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7920       else if (unformat (i, "InPE %d", &pl_index))
7921         {
7922           if (pl_index <= 0 || pl_index > 4)
7923             {
7924             pl_index_range_error:
7925               errmsg ("pl index %d out of range\n", pl_index);
7926               return -99;
7927             }
7928           flags |=
7929             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7930         }
7931       else if (unformat (i, "EgPE %d", &pl_index))
7932         {
7933           if (pl_index <= 0 || pl_index > 4)
7934             goto pl_index_range_error;
7935           flags |=
7936             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7937         }
7938       else if (unformat (i, "OrgSrc %d", &pl_index))
7939         {
7940           if (pl_index <= 0 || pl_index > 4)
7941             goto pl_index_range_error;
7942           flags |=
7943             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7944         }
7945       else
7946         break;
7947     }
7948
7949   if (!src_address_set)
7950     {
7951       errmsg ("src address required\n");
7952       return -99;
7953     }
7954
7955   if (!dst_address_set)
7956     {
7957       errmsg ("dst address required\n");
7958       return -99;
7959     }
7960
7961   if (!segments)
7962     {
7963       errmsg ("at least one sr segment required\n");
7964       return -99;
7965     }
7966
7967   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7968       vec_len (segments) * sizeof (ip6_address_t)
7969       + vec_len (tags) * sizeof (ip6_address_t));
7970
7971   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7972   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7973   mp->dst_mask_width = dst_mask_width;
7974   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7975   mp->n_segments = vec_len (segments);
7976   mp->n_tags = vec_len (tags);
7977   mp->is_add = is_del == 0;
7978   clib_memcpy (mp->segs_and_tags, segments,
7979                vec_len (segments) * sizeof (ip6_address_t));
7980   clib_memcpy (mp->segs_and_tags +
7981                vec_len (segments) * sizeof (ip6_address_t), tags,
7982                vec_len (tags) * sizeof (ip6_address_t));
7983
7984   mp->outer_vrf_id = ntohl (rx_table_id);
7985   mp->inner_vrf_id = ntohl (tx_table_id);
7986   memcpy (mp->name, name, vec_len (name));
7987   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7988
7989   vec_free (segments);
7990   vec_free (tags);
7991
7992   S;
7993   W;
7994   /* NOTREACHED */
7995 }
7996
7997 static int
7998 api_sr_policy_add_del (vat_main_t * vam)
7999 {
8000   unformat_input_t *input = vam->input;
8001   vl_api_sr_policy_add_del_t *mp;
8002   f64 timeout;
8003   int is_del = 0;
8004   u8 *name = 0;
8005   u8 *tunnel_name = 0;
8006   u8 **tunnel_names = 0;
8007
8008   int name_set = 0;
8009   int tunnel_set = 0;
8010   int j = 0;
8011   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8012   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8013
8014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8015     {
8016       if (unformat (input, "del"))
8017         is_del = 1;
8018       else if (unformat (input, "name %s", &name))
8019         name_set = 1;
8020       else if (unformat (input, "tunnel %s", &tunnel_name))
8021         {
8022           if (tunnel_name)
8023             {
8024               vec_add1 (tunnel_names, tunnel_name);
8025               /* For serializer:
8026                  - length = #bytes to store in serial vector
8027                  - +1 = byte to store that length
8028                */
8029               tunnel_names_length += (vec_len (tunnel_name) + 1);
8030               tunnel_set = 1;
8031               tunnel_name = 0;
8032             }
8033         }
8034       else
8035         break;
8036     }
8037
8038   if (!name_set)
8039     {
8040       errmsg ("policy name required\n");
8041       return -99;
8042     }
8043
8044   if ((!tunnel_set) && (!is_del))
8045     {
8046       errmsg ("tunnel name required\n");
8047       return -99;
8048     }
8049
8050   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8051
8052
8053
8054   mp->is_add = !is_del;
8055
8056   memcpy (mp->name, name, vec_len (name));
8057   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8058   u8 *serial_orig = 0;
8059   vec_validate (serial_orig, tunnel_names_length);
8060   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8061   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8062
8063   for (j = 0; j < vec_len (tunnel_names); j++)
8064     {
8065       tun_name_len = vec_len (tunnel_names[j]);
8066       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8067       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8068       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8069       serial_orig += tun_name_len;      // Advance past the copy
8070     }
8071   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8072
8073   vec_free (tunnel_names);
8074   vec_free (tunnel_name);
8075
8076   S;
8077   W;
8078   /* NOTREACHED */
8079 }
8080
8081 static int
8082 api_sr_multicast_map_add_del (vat_main_t * vam)
8083 {
8084   unformat_input_t *input = vam->input;
8085   vl_api_sr_multicast_map_add_del_t *mp;
8086   f64 timeout;
8087   int is_del = 0;
8088   ip6_address_t multicast_address;
8089   u8 *policy_name = 0;
8090   int multicast_address_set = 0;
8091
8092   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8093     {
8094       if (unformat (input, "del"))
8095         is_del = 1;
8096       else
8097         if (unformat
8098             (input, "address %U", unformat_ip6_address, &multicast_address))
8099         multicast_address_set = 1;
8100       else if (unformat (input, "sr-policy %s", &policy_name))
8101         ;
8102       else
8103         break;
8104     }
8105
8106   if (!is_del && !policy_name)
8107     {
8108       errmsg ("sr-policy name required\n");
8109       return -99;
8110     }
8111
8112
8113   if (!multicast_address_set)
8114     {
8115       errmsg ("address required\n");
8116       return -99;
8117     }
8118
8119   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8120
8121   mp->is_add = !is_del;
8122   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8123   clib_memcpy (mp->multicast_address, &multicast_address,
8124                sizeof (mp->multicast_address));
8125
8126
8127   vec_free (policy_name);
8128
8129   S;
8130   W;
8131   /* NOTREACHED */
8132 }
8133
8134
8135 #define foreach_tcp_proto_field                 \
8136 _(src_port)                                     \
8137 _(dst_port)
8138
8139 #define foreach_udp_proto_field                 \
8140 _(src_port)                                     \
8141 _(dst_port)
8142
8143 #define foreach_ip4_proto_field                 \
8144 _(src_address)                                  \
8145 _(dst_address)                                  \
8146 _(tos)                                          \
8147 _(length)                                       \
8148 _(fragment_id)                                  \
8149 _(ttl)                                          \
8150 _(protocol)                                     \
8151 _(checksum)
8152
8153 uword
8154 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8155 {
8156   u8 **maskp = va_arg (*args, u8 **);
8157   u8 *mask = 0;
8158   u8 found_something = 0;
8159   tcp_header_t *tcp;
8160
8161 #define _(a) u8 a=0;
8162   foreach_tcp_proto_field;
8163 #undef _
8164
8165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8166     {
8167       if (0);
8168 #define _(a) else if (unformat (input, #a)) a=1;
8169       foreach_tcp_proto_field
8170 #undef _
8171         else
8172         break;
8173     }
8174
8175 #define _(a) found_something += a;
8176   foreach_tcp_proto_field;
8177 #undef _
8178
8179   if (found_something == 0)
8180     return 0;
8181
8182   vec_validate (mask, sizeof (*tcp) - 1);
8183
8184   tcp = (tcp_header_t *) mask;
8185
8186 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8187   foreach_tcp_proto_field;
8188 #undef _
8189
8190   *maskp = mask;
8191   return 1;
8192 }
8193
8194 uword
8195 unformat_udp_mask (unformat_input_t * input, va_list * args)
8196 {
8197   u8 **maskp = va_arg (*args, u8 **);
8198   u8 *mask = 0;
8199   u8 found_something = 0;
8200   udp_header_t *udp;
8201
8202 #define _(a) u8 a=0;
8203   foreach_udp_proto_field;
8204 #undef _
8205
8206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8207     {
8208       if (0);
8209 #define _(a) else if (unformat (input, #a)) a=1;
8210       foreach_udp_proto_field
8211 #undef _
8212         else
8213         break;
8214     }
8215
8216 #define _(a) found_something += a;
8217   foreach_udp_proto_field;
8218 #undef _
8219
8220   if (found_something == 0)
8221     return 0;
8222
8223   vec_validate (mask, sizeof (*udp) - 1);
8224
8225   udp = (udp_header_t *) mask;
8226
8227 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8228   foreach_udp_proto_field;
8229 #undef _
8230
8231   *maskp = mask;
8232   return 1;
8233 }
8234
8235 typedef struct
8236 {
8237   u16 src_port, dst_port;
8238 } tcpudp_header_t;
8239
8240 uword
8241 unformat_l4_mask (unformat_input_t * input, va_list * args)
8242 {
8243   u8 **maskp = va_arg (*args, u8 **);
8244   u16 src_port = 0, dst_port = 0;
8245   tcpudp_header_t *tcpudp;
8246
8247   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8248     {
8249       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8250         return 1;
8251       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8252         return 1;
8253       else if (unformat (input, "src_port"))
8254         src_port = 0xFFFF;
8255       else if (unformat (input, "dst_port"))
8256         dst_port = 0xFFFF;
8257       else
8258         return 0;
8259     }
8260
8261   if (!src_port && !dst_port)
8262     return 0;
8263
8264   u8 *mask = 0;
8265   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8266
8267   tcpudp = (tcpudp_header_t *) mask;
8268   tcpudp->src_port = src_port;
8269   tcpudp->dst_port = dst_port;
8270
8271   *maskp = mask;
8272
8273   return 1;
8274 }
8275
8276 uword
8277 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8278 {
8279   u8 **maskp = va_arg (*args, u8 **);
8280   u8 *mask = 0;
8281   u8 found_something = 0;
8282   ip4_header_t *ip;
8283
8284 #define _(a) u8 a=0;
8285   foreach_ip4_proto_field;
8286 #undef _
8287   u8 version = 0;
8288   u8 hdr_length = 0;
8289
8290
8291   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8292     {
8293       if (unformat (input, "version"))
8294         version = 1;
8295       else if (unformat (input, "hdr_length"))
8296         hdr_length = 1;
8297       else if (unformat (input, "src"))
8298         src_address = 1;
8299       else if (unformat (input, "dst"))
8300         dst_address = 1;
8301       else if (unformat (input, "proto"))
8302         protocol = 1;
8303
8304 #define _(a) else if (unformat (input, #a)) a=1;
8305       foreach_ip4_proto_field
8306 #undef _
8307         else
8308         break;
8309     }
8310
8311 #define _(a) found_something += a;
8312   foreach_ip4_proto_field;
8313 #undef _
8314
8315   if (found_something == 0)
8316     return 0;
8317
8318   vec_validate (mask, sizeof (*ip) - 1);
8319
8320   ip = (ip4_header_t *) mask;
8321
8322 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8323   foreach_ip4_proto_field;
8324 #undef _
8325
8326   ip->ip_version_and_header_length = 0;
8327
8328   if (version)
8329     ip->ip_version_and_header_length |= 0xF0;
8330
8331   if (hdr_length)
8332     ip->ip_version_and_header_length |= 0x0F;
8333
8334   *maskp = mask;
8335   return 1;
8336 }
8337
8338 #define foreach_ip6_proto_field                 \
8339 _(src_address)                                  \
8340 _(dst_address)                                  \
8341 _(payload_length)                               \
8342 _(hop_limit)                                    \
8343 _(protocol)
8344
8345 uword
8346 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8347 {
8348   u8 **maskp = va_arg (*args, u8 **);
8349   u8 *mask = 0;
8350   u8 found_something = 0;
8351   ip6_header_t *ip;
8352   u32 ip_version_traffic_class_and_flow_label;
8353
8354 #define _(a) u8 a=0;
8355   foreach_ip6_proto_field;
8356 #undef _
8357   u8 version = 0;
8358   u8 traffic_class = 0;
8359   u8 flow_label = 0;
8360
8361   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8362     {
8363       if (unformat (input, "version"))
8364         version = 1;
8365       else if (unformat (input, "traffic-class"))
8366         traffic_class = 1;
8367       else if (unformat (input, "flow-label"))
8368         flow_label = 1;
8369       else if (unformat (input, "src"))
8370         src_address = 1;
8371       else if (unformat (input, "dst"))
8372         dst_address = 1;
8373       else if (unformat (input, "proto"))
8374         protocol = 1;
8375
8376 #define _(a) else if (unformat (input, #a)) a=1;
8377       foreach_ip6_proto_field
8378 #undef _
8379         else
8380         break;
8381     }
8382
8383 #define _(a) found_something += a;
8384   foreach_ip6_proto_field;
8385 #undef _
8386
8387   if (found_something == 0)
8388     return 0;
8389
8390   vec_validate (mask, sizeof (*ip) - 1);
8391
8392   ip = (ip6_header_t *) mask;
8393
8394 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8395   foreach_ip6_proto_field;
8396 #undef _
8397
8398   ip_version_traffic_class_and_flow_label = 0;
8399
8400   if (version)
8401     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8402
8403   if (traffic_class)
8404     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8405
8406   if (flow_label)
8407     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8408
8409   ip->ip_version_traffic_class_and_flow_label =
8410     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8411
8412   *maskp = mask;
8413   return 1;
8414 }
8415
8416 uword
8417 unformat_l3_mask (unformat_input_t * input, va_list * args)
8418 {
8419   u8 **maskp = va_arg (*args, u8 **);
8420
8421   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8422     {
8423       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8424         return 1;
8425       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8426         return 1;
8427       else
8428         break;
8429     }
8430   return 0;
8431 }
8432
8433 uword
8434 unformat_l2_mask (unformat_input_t * input, va_list * args)
8435 {
8436   u8 **maskp = va_arg (*args, u8 **);
8437   u8 *mask = 0;
8438   u8 src = 0;
8439   u8 dst = 0;
8440   u8 proto = 0;
8441   u8 tag1 = 0;
8442   u8 tag2 = 0;
8443   u8 ignore_tag1 = 0;
8444   u8 ignore_tag2 = 0;
8445   u8 cos1 = 0;
8446   u8 cos2 = 0;
8447   u8 dot1q = 0;
8448   u8 dot1ad = 0;
8449   int len = 14;
8450
8451   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8452     {
8453       if (unformat (input, "src"))
8454         src = 1;
8455       else if (unformat (input, "dst"))
8456         dst = 1;
8457       else if (unformat (input, "proto"))
8458         proto = 1;
8459       else if (unformat (input, "tag1"))
8460         tag1 = 1;
8461       else if (unformat (input, "tag2"))
8462         tag2 = 1;
8463       else if (unformat (input, "ignore-tag1"))
8464         ignore_tag1 = 1;
8465       else if (unformat (input, "ignore-tag2"))
8466         ignore_tag2 = 1;
8467       else if (unformat (input, "cos1"))
8468         cos1 = 1;
8469       else if (unformat (input, "cos2"))
8470         cos2 = 1;
8471       else if (unformat (input, "dot1q"))
8472         dot1q = 1;
8473       else if (unformat (input, "dot1ad"))
8474         dot1ad = 1;
8475       else
8476         break;
8477     }
8478   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8479        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8480     return 0;
8481
8482   if (tag1 || ignore_tag1 || cos1 || dot1q)
8483     len = 18;
8484   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8485     len = 22;
8486
8487   vec_validate (mask, len - 1);
8488
8489   if (dst)
8490     memset (mask, 0xff, 6);
8491
8492   if (src)
8493     memset (mask + 6, 0xff, 6);
8494
8495   if (tag2 || dot1ad)
8496     {
8497       /* inner vlan tag */
8498       if (tag2)
8499         {
8500           mask[19] = 0xff;
8501           mask[18] = 0x0f;
8502         }
8503       if (cos2)
8504         mask[18] |= 0xe0;
8505       if (proto)
8506         mask[21] = mask[20] = 0xff;
8507       if (tag1)
8508         {
8509           mask[15] = 0xff;
8510           mask[14] = 0x0f;
8511         }
8512       if (cos1)
8513         mask[14] |= 0xe0;
8514       *maskp = mask;
8515       return 1;
8516     }
8517   if (tag1 | dot1q)
8518     {
8519       if (tag1)
8520         {
8521           mask[15] = 0xff;
8522           mask[14] = 0x0f;
8523         }
8524       if (cos1)
8525         mask[14] |= 0xe0;
8526       if (proto)
8527         mask[16] = mask[17] = 0xff;
8528
8529       *maskp = mask;
8530       return 1;
8531     }
8532   if (cos2)
8533     mask[18] |= 0xe0;
8534   if (cos1)
8535     mask[14] |= 0xe0;
8536   if (proto)
8537     mask[12] = mask[13] = 0xff;
8538
8539   *maskp = mask;
8540   return 1;
8541 }
8542
8543 uword
8544 unformat_classify_mask (unformat_input_t * input, va_list * args)
8545 {
8546   u8 **maskp = va_arg (*args, u8 **);
8547   u32 *skipp = va_arg (*args, u32 *);
8548   u32 *matchp = va_arg (*args, u32 *);
8549   u32 match;
8550   u8 *mask = 0;
8551   u8 *l2 = 0;
8552   u8 *l3 = 0;
8553   u8 *l4 = 0;
8554   int i;
8555
8556   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8557     {
8558       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8559         ;
8560       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8561         ;
8562       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8563         ;
8564       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8565         ;
8566       else
8567         break;
8568     }
8569
8570   if (l4 && !l3)
8571     {
8572       vec_free (mask);
8573       vec_free (l2);
8574       vec_free (l4);
8575       return 0;
8576     }
8577
8578   if (mask || l2 || l3 || l4)
8579     {
8580       if (l2 || l3 || l4)
8581         {
8582           /* "With a free Ethernet header in every package" */
8583           if (l2 == 0)
8584             vec_validate (l2, 13);
8585           mask = l2;
8586           if (vec_len (l3))
8587             {
8588               vec_append (mask, l3);
8589               vec_free (l3);
8590             }
8591           if (vec_len (l4))
8592             {
8593               vec_append (mask, l4);
8594               vec_free (l4);
8595             }
8596         }
8597
8598       /* Scan forward looking for the first significant mask octet */
8599       for (i = 0; i < vec_len (mask); i++)
8600         if (mask[i])
8601           break;
8602
8603       /* compute (skip, match) params */
8604       *skipp = i / sizeof (u32x4);
8605       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8606
8607       /* Pad mask to an even multiple of the vector size */
8608       while (vec_len (mask) % sizeof (u32x4))
8609         vec_add1 (mask, 0);
8610
8611       match = vec_len (mask) / sizeof (u32x4);
8612
8613       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8614         {
8615           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8616           if (*tmp || *(tmp + 1))
8617             break;
8618           match--;
8619         }
8620       if (match == 0)
8621         clib_warning ("BUG: match 0");
8622
8623       _vec_len (mask) = match * sizeof (u32x4);
8624
8625       *matchp = match;
8626       *maskp = mask;
8627
8628       return 1;
8629     }
8630
8631   return 0;
8632 }
8633
8634 #define foreach_l2_next                         \
8635 _(drop, DROP)                                   \
8636 _(ethernet, ETHERNET_INPUT)                     \
8637 _(ip4, IP4_INPUT)                               \
8638 _(ip6, IP6_INPUT)
8639
8640 uword
8641 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8642 {
8643   u32 *miss_next_indexp = va_arg (*args, u32 *);
8644   u32 next_index = 0;
8645   u32 tmp;
8646
8647 #define _(n,N) \
8648   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8649   foreach_l2_next;
8650 #undef _
8651
8652   if (unformat (input, "%d", &tmp))
8653     {
8654       next_index = tmp;
8655       goto out;
8656     }
8657
8658   return 0;
8659
8660 out:
8661   *miss_next_indexp = next_index;
8662   return 1;
8663 }
8664
8665 #define foreach_ip_next                         \
8666 _(drop, DROP)                                   \
8667 _(local, LOCAL)                                 \
8668 _(rewrite, REWRITE)
8669
8670 uword
8671 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8672 {
8673   u32 *miss_next_indexp = va_arg (*args, u32 *);
8674   u32 next_index = 0;
8675   u32 tmp;
8676
8677 #define _(n,N) \
8678   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8679   foreach_ip_next;
8680 #undef _
8681
8682   if (unformat (input, "%d", &tmp))
8683     {
8684       next_index = tmp;
8685       goto out;
8686     }
8687
8688   return 0;
8689
8690 out:
8691   *miss_next_indexp = next_index;
8692   return 1;
8693 }
8694
8695 #define foreach_acl_next                        \
8696 _(deny, DENY)
8697
8698 uword
8699 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8700 {
8701   u32 *miss_next_indexp = va_arg (*args, u32 *);
8702   u32 next_index = 0;
8703   u32 tmp;
8704
8705 #define _(n,N) \
8706   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8707   foreach_acl_next;
8708 #undef _
8709
8710   if (unformat (input, "permit"))
8711     {
8712       next_index = ~0;
8713       goto out;
8714     }
8715   else if (unformat (input, "%d", &tmp))
8716     {
8717       next_index = tmp;
8718       goto out;
8719     }
8720
8721   return 0;
8722
8723 out:
8724   *miss_next_indexp = next_index;
8725   return 1;
8726 }
8727
8728 uword
8729 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8730 {
8731   u32 *r = va_arg (*args, u32 *);
8732
8733   if (unformat (input, "conform-color"))
8734     *r = POLICE_CONFORM;
8735   else if (unformat (input, "exceed-color"))
8736     *r = POLICE_EXCEED;
8737   else
8738     return 0;
8739
8740   return 1;
8741 }
8742
8743 static int
8744 api_classify_add_del_table (vat_main_t * vam)
8745 {
8746   unformat_input_t *i = vam->input;
8747   vl_api_classify_add_del_table_t *mp;
8748
8749   u32 nbuckets = 2;
8750   u32 skip = ~0;
8751   u32 match = ~0;
8752   int is_add = 1;
8753   u32 table_index = ~0;
8754   u32 next_table_index = ~0;
8755   u32 miss_next_index = ~0;
8756   u32 memory_size = 32 << 20;
8757   u8 *mask = 0;
8758   f64 timeout;
8759
8760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8761     {
8762       if (unformat (i, "del"))
8763         is_add = 0;
8764       else if (unformat (i, "buckets %d", &nbuckets))
8765         ;
8766       else if (unformat (i, "memory_size %d", &memory_size))
8767         ;
8768       else if (unformat (i, "skip %d", &skip))
8769         ;
8770       else if (unformat (i, "match %d", &match))
8771         ;
8772       else if (unformat (i, "table %d", &table_index))
8773         ;
8774       else if (unformat (i, "mask %U", unformat_classify_mask,
8775                          &mask, &skip, &match))
8776         ;
8777       else if (unformat (i, "next-table %d", &next_table_index))
8778         ;
8779       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8780                          &miss_next_index))
8781         ;
8782       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8783                          &miss_next_index))
8784         ;
8785       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8786                          &miss_next_index))
8787         ;
8788       else
8789         break;
8790     }
8791
8792   if (is_add && mask == 0)
8793     {
8794       errmsg ("Mask required\n");
8795       return -99;
8796     }
8797
8798   if (is_add && skip == ~0)
8799     {
8800       errmsg ("skip count required\n");
8801       return -99;
8802     }
8803
8804   if (is_add && match == ~0)
8805     {
8806       errmsg ("match count required\n");
8807       return -99;
8808     }
8809
8810   if (!is_add && table_index == ~0)
8811     {
8812       errmsg ("table index required for delete\n");
8813       return -99;
8814     }
8815
8816   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8817
8818   mp->is_add = is_add;
8819   mp->table_index = ntohl (table_index);
8820   mp->nbuckets = ntohl (nbuckets);
8821   mp->memory_size = ntohl (memory_size);
8822   mp->skip_n_vectors = ntohl (skip);
8823   mp->match_n_vectors = ntohl (match);
8824   mp->next_table_index = ntohl (next_table_index);
8825   mp->miss_next_index = ntohl (miss_next_index);
8826   clib_memcpy (mp->mask, mask, vec_len (mask));
8827
8828   vec_free (mask);
8829
8830   S;
8831   W;
8832   /* NOTREACHED */
8833 }
8834
8835 uword
8836 unformat_l4_match (unformat_input_t * input, va_list * args)
8837 {
8838   u8 **matchp = va_arg (*args, u8 **);
8839
8840   u8 *proto_header = 0;
8841   int src_port = 0;
8842   int dst_port = 0;
8843
8844   tcpudp_header_t h;
8845
8846   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8847     {
8848       if (unformat (input, "src_port %d", &src_port))
8849         ;
8850       else if (unformat (input, "dst_port %d", &dst_port))
8851         ;
8852       else
8853         return 0;
8854     }
8855
8856   h.src_port = clib_host_to_net_u16 (src_port);
8857   h.dst_port = clib_host_to_net_u16 (dst_port);
8858   vec_validate (proto_header, sizeof (h) - 1);
8859   memcpy (proto_header, &h, sizeof (h));
8860
8861   *matchp = proto_header;
8862
8863   return 1;
8864 }
8865
8866 uword
8867 unformat_ip4_match (unformat_input_t * input, va_list * args)
8868 {
8869   u8 **matchp = va_arg (*args, u8 **);
8870   u8 *match = 0;
8871   ip4_header_t *ip;
8872   int version = 0;
8873   u32 version_val;
8874   int hdr_length = 0;
8875   u32 hdr_length_val;
8876   int src = 0, dst = 0;
8877   ip4_address_t src_val, dst_val;
8878   int proto = 0;
8879   u32 proto_val;
8880   int tos = 0;
8881   u32 tos_val;
8882   int length = 0;
8883   u32 length_val;
8884   int fragment_id = 0;
8885   u32 fragment_id_val;
8886   int ttl = 0;
8887   int ttl_val;
8888   int checksum = 0;
8889   u32 checksum_val;
8890
8891   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8892     {
8893       if (unformat (input, "version %d", &version_val))
8894         version = 1;
8895       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8896         hdr_length = 1;
8897       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8898         src = 1;
8899       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8900         dst = 1;
8901       else if (unformat (input, "proto %d", &proto_val))
8902         proto = 1;
8903       else if (unformat (input, "tos %d", &tos_val))
8904         tos = 1;
8905       else if (unformat (input, "length %d", &length_val))
8906         length = 1;
8907       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8908         fragment_id = 1;
8909       else if (unformat (input, "ttl %d", &ttl_val))
8910         ttl = 1;
8911       else if (unformat (input, "checksum %d", &checksum_val))
8912         checksum = 1;
8913       else
8914         break;
8915     }
8916
8917   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8918       + ttl + checksum == 0)
8919     return 0;
8920
8921   /*
8922    * Aligned because we use the real comparison functions
8923    */
8924   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8925
8926   ip = (ip4_header_t *) match;
8927
8928   /* These are realistically matched in practice */
8929   if (src)
8930     ip->src_address.as_u32 = src_val.as_u32;
8931
8932   if (dst)
8933     ip->dst_address.as_u32 = dst_val.as_u32;
8934
8935   if (proto)
8936     ip->protocol = proto_val;
8937
8938
8939   /* These are not, but they're included for completeness */
8940   if (version)
8941     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8942
8943   if (hdr_length)
8944     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8945
8946   if (tos)
8947     ip->tos = tos_val;
8948
8949   if (length)
8950     ip->length = clib_host_to_net_u16 (length_val);
8951
8952   if (ttl)
8953     ip->ttl = ttl_val;
8954
8955   if (checksum)
8956     ip->checksum = clib_host_to_net_u16 (checksum_val);
8957
8958   *matchp = match;
8959   return 1;
8960 }
8961
8962 uword
8963 unformat_ip6_match (unformat_input_t * input, va_list * args)
8964 {
8965   u8 **matchp = va_arg (*args, u8 **);
8966   u8 *match = 0;
8967   ip6_header_t *ip;
8968   int version = 0;
8969   u32 version_val;
8970   u8 traffic_class = 0;
8971   u32 traffic_class_val = 0;
8972   u8 flow_label = 0;
8973   u8 flow_label_val;
8974   int src = 0, dst = 0;
8975   ip6_address_t src_val, dst_val;
8976   int proto = 0;
8977   u32 proto_val;
8978   int payload_length = 0;
8979   u32 payload_length_val;
8980   int hop_limit = 0;
8981   int hop_limit_val;
8982   u32 ip_version_traffic_class_and_flow_label;
8983
8984   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8985     {
8986       if (unformat (input, "version %d", &version_val))
8987         version = 1;
8988       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8989         traffic_class = 1;
8990       else if (unformat (input, "flow_label %d", &flow_label_val))
8991         flow_label = 1;
8992       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8993         src = 1;
8994       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8995         dst = 1;
8996       else if (unformat (input, "proto %d", &proto_val))
8997         proto = 1;
8998       else if (unformat (input, "payload_length %d", &payload_length_val))
8999         payload_length = 1;
9000       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9001         hop_limit = 1;
9002       else
9003         break;
9004     }
9005
9006   if (version + traffic_class + flow_label + src + dst + proto +
9007       payload_length + hop_limit == 0)
9008     return 0;
9009
9010   /*
9011    * Aligned because we use the real comparison functions
9012    */
9013   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9014
9015   ip = (ip6_header_t *) match;
9016
9017   if (src)
9018     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9019
9020   if (dst)
9021     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9022
9023   if (proto)
9024     ip->protocol = proto_val;
9025
9026   ip_version_traffic_class_and_flow_label = 0;
9027
9028   if (version)
9029     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9030
9031   if (traffic_class)
9032     ip_version_traffic_class_and_flow_label |=
9033       (traffic_class_val & 0xFF) << 20;
9034
9035   if (flow_label)
9036     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9037
9038   ip->ip_version_traffic_class_and_flow_label =
9039     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9040
9041   if (payload_length)
9042     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9043
9044   if (hop_limit)
9045     ip->hop_limit = hop_limit_val;
9046
9047   *matchp = match;
9048   return 1;
9049 }
9050
9051 uword
9052 unformat_l3_match (unformat_input_t * input, va_list * args)
9053 {
9054   u8 **matchp = va_arg (*args, u8 **);
9055
9056   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9057     {
9058       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9059         return 1;
9060       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9061         return 1;
9062       else
9063         break;
9064     }
9065   return 0;
9066 }
9067
9068 uword
9069 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9070 {
9071   u8 *tagp = va_arg (*args, u8 *);
9072   u32 tag;
9073
9074   if (unformat (input, "%d", &tag))
9075     {
9076       tagp[0] = (tag >> 8) & 0x0F;
9077       tagp[1] = tag & 0xFF;
9078       return 1;
9079     }
9080
9081   return 0;
9082 }
9083
9084 uword
9085 unformat_l2_match (unformat_input_t * input, va_list * args)
9086 {
9087   u8 **matchp = va_arg (*args, u8 **);
9088   u8 *match = 0;
9089   u8 src = 0;
9090   u8 src_val[6];
9091   u8 dst = 0;
9092   u8 dst_val[6];
9093   u8 proto = 0;
9094   u16 proto_val;
9095   u8 tag1 = 0;
9096   u8 tag1_val[2];
9097   u8 tag2 = 0;
9098   u8 tag2_val[2];
9099   int len = 14;
9100   u8 ignore_tag1 = 0;
9101   u8 ignore_tag2 = 0;
9102   u8 cos1 = 0;
9103   u8 cos2 = 0;
9104   u32 cos1_val = 0;
9105   u32 cos2_val = 0;
9106
9107   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9108     {
9109       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9110         src = 1;
9111       else
9112         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9113         dst = 1;
9114       else if (unformat (input, "proto %U",
9115                          unformat_ethernet_type_host_byte_order, &proto_val))
9116         proto = 1;
9117       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9118         tag1 = 1;
9119       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9120         tag2 = 1;
9121       else if (unformat (input, "ignore-tag1"))
9122         ignore_tag1 = 1;
9123       else if (unformat (input, "ignore-tag2"))
9124         ignore_tag2 = 1;
9125       else if (unformat (input, "cos1 %d", &cos1_val))
9126         cos1 = 1;
9127       else if (unformat (input, "cos2 %d", &cos2_val))
9128         cos2 = 1;
9129       else
9130         break;
9131     }
9132   if ((src + dst + proto + tag1 + tag2 +
9133        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9134     return 0;
9135
9136   if (tag1 || ignore_tag1 || cos1)
9137     len = 18;
9138   if (tag2 || ignore_tag2 || cos2)
9139     len = 22;
9140
9141   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9142
9143   if (dst)
9144     clib_memcpy (match, dst_val, 6);
9145
9146   if (src)
9147     clib_memcpy (match + 6, src_val, 6);
9148
9149   if (tag2)
9150     {
9151       /* inner vlan tag */
9152       match[19] = tag2_val[1];
9153       match[18] = tag2_val[0];
9154       if (cos2)
9155         match[18] |= (cos2_val & 0x7) << 5;
9156       if (proto)
9157         {
9158           match[21] = proto_val & 0xff;
9159           match[20] = proto_val >> 8;
9160         }
9161       if (tag1)
9162         {
9163           match[15] = tag1_val[1];
9164           match[14] = tag1_val[0];
9165         }
9166       if (cos1)
9167         match[14] |= (cos1_val & 0x7) << 5;
9168       *matchp = match;
9169       return 1;
9170     }
9171   if (tag1)
9172     {
9173       match[15] = tag1_val[1];
9174       match[14] = tag1_val[0];
9175       if (proto)
9176         {
9177           match[17] = proto_val & 0xff;
9178           match[16] = proto_val >> 8;
9179         }
9180       if (cos1)
9181         match[14] |= (cos1_val & 0x7) << 5;
9182
9183       *matchp = match;
9184       return 1;
9185     }
9186   if (cos2)
9187     match[18] |= (cos2_val & 0x7) << 5;
9188   if (cos1)
9189     match[14] |= (cos1_val & 0x7) << 5;
9190   if (proto)
9191     {
9192       match[13] = proto_val & 0xff;
9193       match[12] = proto_val >> 8;
9194     }
9195
9196   *matchp = match;
9197   return 1;
9198 }
9199
9200
9201 uword
9202 unformat_classify_match (unformat_input_t * input, va_list * args)
9203 {
9204   u8 **matchp = va_arg (*args, u8 **);
9205   u32 skip_n_vectors = va_arg (*args, u32);
9206   u32 match_n_vectors = va_arg (*args, u32);
9207
9208   u8 *match = 0;
9209   u8 *l2 = 0;
9210   u8 *l3 = 0;
9211   u8 *l4 = 0;
9212
9213   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9214     {
9215       if (unformat (input, "hex %U", unformat_hex_string, &match))
9216         ;
9217       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9218         ;
9219       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9220         ;
9221       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9222         ;
9223       else
9224         break;
9225     }
9226
9227   if (l4 && !l3)
9228     {
9229       vec_free (match);
9230       vec_free (l2);
9231       vec_free (l4);
9232       return 0;
9233     }
9234
9235   if (match || l2 || l3 || l4)
9236     {
9237       if (l2 || l3 || l4)
9238         {
9239           /* "Win a free Ethernet header in every packet" */
9240           if (l2 == 0)
9241             vec_validate_aligned (l2, 13, sizeof (u32x4));
9242           match = l2;
9243           if (vec_len (l3))
9244             {
9245               vec_append_aligned (match, l3, sizeof (u32x4));
9246               vec_free (l3);
9247             }
9248           if (vec_len (l4))
9249             {
9250               vec_append_aligned (match, l4, sizeof (u32x4));
9251               vec_free (l4);
9252             }
9253         }
9254
9255       /* Make sure the vector is big enough even if key is all 0's */
9256       vec_validate_aligned
9257         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9258          sizeof (u32x4));
9259
9260       /* Set size, include skipped vectors */
9261       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9262
9263       *matchp = match;
9264
9265       return 1;
9266     }
9267
9268   return 0;
9269 }
9270
9271 static int
9272 api_classify_add_del_session (vat_main_t * vam)
9273 {
9274   unformat_input_t *i = vam->input;
9275   vl_api_classify_add_del_session_t *mp;
9276   int is_add = 1;
9277   u32 table_index = ~0;
9278   u32 hit_next_index = ~0;
9279   u32 opaque_index = ~0;
9280   u8 *match = 0;
9281   i32 advance = 0;
9282   f64 timeout;
9283   u32 skip_n_vectors = 0;
9284   u32 match_n_vectors = 0;
9285
9286   /*
9287    * Warning: you have to supply skip_n and match_n
9288    * because the API client cant simply look at the classify
9289    * table object.
9290    */
9291
9292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9293     {
9294       if (unformat (i, "del"))
9295         is_add = 0;
9296       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9297                          &hit_next_index))
9298         ;
9299       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9300                          &hit_next_index))
9301         ;
9302       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9303                          &hit_next_index))
9304         ;
9305       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9306         ;
9307       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9308         ;
9309       else if (unformat (i, "opaque-index %d", &opaque_index))
9310         ;
9311       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9312         ;
9313       else if (unformat (i, "match_n %d", &match_n_vectors))
9314         ;
9315       else if (unformat (i, "match %U", unformat_classify_match,
9316                          &match, skip_n_vectors, match_n_vectors))
9317         ;
9318       else if (unformat (i, "advance %d", &advance))
9319         ;
9320       else if (unformat (i, "table-index %d", &table_index))
9321         ;
9322       else
9323         break;
9324     }
9325
9326   if (table_index == ~0)
9327     {
9328       errmsg ("Table index required\n");
9329       return -99;
9330     }
9331
9332   if (is_add && match == 0)
9333     {
9334       errmsg ("Match value required\n");
9335       return -99;
9336     }
9337
9338   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9339
9340   mp->is_add = is_add;
9341   mp->table_index = ntohl (table_index);
9342   mp->hit_next_index = ntohl (hit_next_index);
9343   mp->opaque_index = ntohl (opaque_index);
9344   mp->advance = ntohl (advance);
9345   clib_memcpy (mp->match, match, vec_len (match));
9346   vec_free (match);
9347
9348   S;
9349   W;
9350   /* NOTREACHED */
9351 }
9352
9353 static int
9354 api_classify_set_interface_ip_table (vat_main_t * vam)
9355 {
9356   unformat_input_t *i = vam->input;
9357   vl_api_classify_set_interface_ip_table_t *mp;
9358   f64 timeout;
9359   u32 sw_if_index;
9360   int sw_if_index_set;
9361   u32 table_index = ~0;
9362   u8 is_ipv6 = 0;
9363
9364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9365     {
9366       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9367         sw_if_index_set = 1;
9368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9369         sw_if_index_set = 1;
9370       else if (unformat (i, "table %d", &table_index))
9371         ;
9372       else
9373         {
9374           clib_warning ("parse error '%U'", format_unformat_error, i);
9375           return -99;
9376         }
9377     }
9378
9379   if (sw_if_index_set == 0)
9380     {
9381       errmsg ("missing interface name or sw_if_index\n");
9382       return -99;
9383     }
9384
9385
9386   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9387
9388   mp->sw_if_index = ntohl (sw_if_index);
9389   mp->table_index = ntohl (table_index);
9390   mp->is_ipv6 = is_ipv6;
9391
9392   S;
9393   W;
9394   /* NOTREACHED */
9395   return 0;
9396 }
9397
9398 static int
9399 api_classify_set_interface_l2_tables (vat_main_t * vam)
9400 {
9401   unformat_input_t *i = vam->input;
9402   vl_api_classify_set_interface_l2_tables_t *mp;
9403   f64 timeout;
9404   u32 sw_if_index;
9405   int sw_if_index_set;
9406   u32 ip4_table_index = ~0;
9407   u32 ip6_table_index = ~0;
9408   u32 other_table_index = ~0;
9409   u32 is_input = 1;
9410
9411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9412     {
9413       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9414         sw_if_index_set = 1;
9415       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9416         sw_if_index_set = 1;
9417       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9418         ;
9419       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9420         ;
9421       else if (unformat (i, "other-table %d", &other_table_index))
9422         ;
9423       else if (unformat (i, "is-input %d", &is_input))
9424         ;
9425       else
9426         {
9427           clib_warning ("parse error '%U'", format_unformat_error, i);
9428           return -99;
9429         }
9430     }
9431
9432   if (sw_if_index_set == 0)
9433     {
9434       errmsg ("missing interface name or sw_if_index\n");
9435       return -99;
9436     }
9437
9438
9439   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9440
9441   mp->sw_if_index = ntohl (sw_if_index);
9442   mp->ip4_table_index = ntohl (ip4_table_index);
9443   mp->ip6_table_index = ntohl (ip6_table_index);
9444   mp->other_table_index = ntohl (other_table_index);
9445   mp->is_input = (u8) is_input;
9446
9447   S;
9448   W;
9449   /* NOTREACHED */
9450   return 0;
9451 }
9452
9453 static int
9454 api_set_ipfix_exporter (vat_main_t * vam)
9455 {
9456   unformat_input_t *i = vam->input;
9457   vl_api_set_ipfix_exporter_t *mp;
9458   ip4_address_t collector_address;
9459   u8 collector_address_set = 0;
9460   u32 collector_port = ~0;
9461   ip4_address_t src_address;
9462   u8 src_address_set = 0;
9463   u32 vrf_id = ~0;
9464   u32 path_mtu = ~0;
9465   u32 template_interval = ~0;
9466   u8 udp_checksum = 0;
9467   f64 timeout;
9468
9469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9470     {
9471       if (unformat (i, "collector_address %U", unformat_ip4_address,
9472                     &collector_address))
9473         collector_address_set = 1;
9474       else if (unformat (i, "collector_port %d", &collector_port))
9475         ;
9476       else if (unformat (i, "src_address %U", unformat_ip4_address,
9477                          &src_address))
9478         src_address_set = 1;
9479       else if (unformat (i, "vrf_id %d", &vrf_id))
9480         ;
9481       else if (unformat (i, "path_mtu %d", &path_mtu))
9482         ;
9483       else if (unformat (i, "template_interval %d", &template_interval))
9484         ;
9485       else if (unformat (i, "udp_checksum"))
9486         udp_checksum = 1;
9487       else
9488         break;
9489     }
9490
9491   if (collector_address_set == 0)
9492     {
9493       errmsg ("collector_address required\n");
9494       return -99;
9495     }
9496
9497   if (src_address_set == 0)
9498     {
9499       errmsg ("src_address required\n");
9500       return -99;
9501     }
9502
9503   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9504
9505   memcpy (mp->collector_address, collector_address.data,
9506           sizeof (collector_address.data));
9507   mp->collector_port = htons ((u16) collector_port);
9508   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9509   mp->vrf_id = htonl (vrf_id);
9510   mp->path_mtu = htonl (path_mtu);
9511   mp->template_interval = htonl (template_interval);
9512   mp->udp_checksum = udp_checksum;
9513
9514   S;
9515   W;
9516   /* NOTREACHED */
9517 }
9518
9519 static int
9520 api_set_ipfix_classify_stream (vat_main_t * vam)
9521 {
9522   unformat_input_t *i = vam->input;
9523   vl_api_set_ipfix_classify_stream_t *mp;
9524   u32 domain_id = 0;
9525   u32 src_port = UDP_DST_PORT_ipfix;
9526   f64 timeout;
9527
9528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9529     {
9530       if (unformat (i, "domain %d", &domain_id))
9531         ;
9532       else if (unformat (i, "src_port %d", &src_port))
9533         ;
9534       else
9535         {
9536           errmsg ("unknown input `%U'", format_unformat_error, i);
9537           return -99;
9538         }
9539     }
9540
9541   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9542
9543   mp->domain_id = htonl (domain_id);
9544   mp->src_port = htons ((u16) src_port);
9545
9546   S;
9547   W;
9548   /* NOTREACHED */
9549 }
9550
9551 static int
9552 api_ipfix_classify_table_add_del (vat_main_t * vam)
9553 {
9554   unformat_input_t *i = vam->input;
9555   vl_api_ipfix_classify_table_add_del_t *mp;
9556   int is_add = -1;
9557   u32 classify_table_index = ~0;
9558   u8 ip_version = 0;
9559   u8 transport_protocol = 255;
9560   f64 timeout;
9561
9562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9563     {
9564       if (unformat (i, "add"))
9565         is_add = 1;
9566       else if (unformat (i, "del"))
9567         is_add = 0;
9568       else if (unformat (i, "table %d", &classify_table_index))
9569         ;
9570       else if (unformat (i, "ip4"))
9571         ip_version = 4;
9572       else if (unformat (i, "ip6"))
9573         ip_version = 6;
9574       else if (unformat (i, "tcp"))
9575         transport_protocol = 6;
9576       else if (unformat (i, "udp"))
9577         transport_protocol = 17;
9578       else
9579         {
9580           errmsg ("unknown input `%U'", format_unformat_error, i);
9581           return -99;
9582         }
9583     }
9584
9585   if (is_add == -1)
9586     {
9587       errmsg ("expecting: add|del");
9588       return -99;
9589     }
9590   if (classify_table_index == ~0)
9591     {
9592       errmsg ("classifier table not specified");
9593       return -99;
9594     }
9595   if (ip_version == 0)
9596     {
9597       errmsg ("IP version not specified");
9598       return -99;
9599     }
9600
9601   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9602
9603   mp->is_add = is_add;
9604   mp->table_id = htonl (classify_table_index);
9605   mp->ip_version = ip_version;
9606   mp->transport_protocol = transport_protocol;
9607
9608   S;
9609   W;
9610   /* NOTREACHED */
9611 }
9612
9613 static int
9614 api_get_node_index (vat_main_t * vam)
9615 {
9616   unformat_input_t *i = vam->input;
9617   vl_api_get_node_index_t *mp;
9618   f64 timeout;
9619   u8 *name = 0;
9620
9621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9622     {
9623       if (unformat (i, "node %s", &name))
9624         ;
9625       else
9626         break;
9627     }
9628   if (name == 0)
9629     {
9630       errmsg ("node name required\n");
9631       return -99;
9632     }
9633   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9634     {
9635       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9636       return -99;
9637     }
9638
9639   M (GET_NODE_INDEX, get_node_index);
9640   clib_memcpy (mp->node_name, name, vec_len (name));
9641   vec_free (name);
9642
9643   S;
9644   W;
9645   /* NOTREACHED */
9646   return 0;
9647 }
9648
9649 static int
9650 api_get_next_index (vat_main_t * vam)
9651 {
9652   unformat_input_t *i = vam->input;
9653   vl_api_get_next_index_t *mp;
9654   f64 timeout;
9655   u8 *node_name = 0, *next_node_name = 0;
9656
9657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9658     {
9659       if (unformat (i, "node-name %s", &node_name))
9660         ;
9661       else if (unformat (i, "next-node-name %s", &next_node_name))
9662         break;
9663     }
9664
9665   if (node_name == 0)
9666     {
9667       errmsg ("node name required\n");
9668       return -99;
9669     }
9670   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9671     {
9672       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9673       return -99;
9674     }
9675
9676   if (next_node_name == 0)
9677     {
9678       errmsg ("next node name required\n");
9679       return -99;
9680     }
9681   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9682     {
9683       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9684       return -99;
9685     }
9686
9687   M (GET_NEXT_INDEX, get_next_index);
9688   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9689   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9690   vec_free (node_name);
9691   vec_free (next_node_name);
9692
9693   S;
9694   W;
9695   /* NOTREACHED */
9696   return 0;
9697 }
9698
9699 static int
9700 api_add_node_next (vat_main_t * vam)
9701 {
9702   unformat_input_t *i = vam->input;
9703   vl_api_add_node_next_t *mp;
9704   f64 timeout;
9705   u8 *name = 0;
9706   u8 *next = 0;
9707
9708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9709     {
9710       if (unformat (i, "node %s", &name))
9711         ;
9712       else if (unformat (i, "next %s", &next))
9713         ;
9714       else
9715         break;
9716     }
9717   if (name == 0)
9718     {
9719       errmsg ("node name required\n");
9720       return -99;
9721     }
9722   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9723     {
9724       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9725       return -99;
9726     }
9727   if (next == 0)
9728     {
9729       errmsg ("next node required\n");
9730       return -99;
9731     }
9732   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9733     {
9734       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9735       return -99;
9736     }
9737
9738   M (ADD_NODE_NEXT, add_node_next);
9739   clib_memcpy (mp->node_name, name, vec_len (name));
9740   clib_memcpy (mp->next_name, next, vec_len (next));
9741   vec_free (name);
9742   vec_free (next);
9743
9744   S;
9745   W;
9746   /* NOTREACHED */
9747   return 0;
9748 }
9749
9750 static int
9751 api_l2tpv3_create_tunnel (vat_main_t * vam)
9752 {
9753   unformat_input_t *i = vam->input;
9754   ip6_address_t client_address, our_address;
9755   int client_address_set = 0;
9756   int our_address_set = 0;
9757   u32 local_session_id = 0;
9758   u32 remote_session_id = 0;
9759   u64 local_cookie = 0;
9760   u64 remote_cookie = 0;
9761   u8 l2_sublayer_present = 0;
9762   vl_api_l2tpv3_create_tunnel_t *mp;
9763   f64 timeout;
9764
9765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9766     {
9767       if (unformat (i, "client_address %U", unformat_ip6_address,
9768                     &client_address))
9769         client_address_set = 1;
9770       else if (unformat (i, "our_address %U", unformat_ip6_address,
9771                          &our_address))
9772         our_address_set = 1;
9773       else if (unformat (i, "local_session_id %d", &local_session_id))
9774         ;
9775       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9776         ;
9777       else if (unformat (i, "local_cookie %lld", &local_cookie))
9778         ;
9779       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9780         ;
9781       else if (unformat (i, "l2-sublayer-present"))
9782         l2_sublayer_present = 1;
9783       else
9784         break;
9785     }
9786
9787   if (client_address_set == 0)
9788     {
9789       errmsg ("client_address required\n");
9790       return -99;
9791     }
9792
9793   if (our_address_set == 0)
9794     {
9795       errmsg ("our_address required\n");
9796       return -99;
9797     }
9798
9799   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9800
9801   clib_memcpy (mp->client_address, client_address.as_u8,
9802                sizeof (mp->client_address));
9803
9804   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9805
9806   mp->local_session_id = ntohl (local_session_id);
9807   mp->remote_session_id = ntohl (remote_session_id);
9808   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9809   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9810   mp->l2_sublayer_present = l2_sublayer_present;
9811   mp->is_ipv6 = 1;
9812
9813   S;
9814   W;
9815   /* NOTREACHED */
9816   return 0;
9817 }
9818
9819 static int
9820 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9821 {
9822   unformat_input_t *i = vam->input;
9823   u32 sw_if_index;
9824   u8 sw_if_index_set = 0;
9825   u64 new_local_cookie = 0;
9826   u64 new_remote_cookie = 0;
9827   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9828   f64 timeout;
9829
9830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9831     {
9832       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9833         sw_if_index_set = 1;
9834       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9835         sw_if_index_set = 1;
9836       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9837         ;
9838       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9839         ;
9840       else
9841         break;
9842     }
9843
9844   if (sw_if_index_set == 0)
9845     {
9846       errmsg ("missing interface name or sw_if_index\n");
9847       return -99;
9848     }
9849
9850   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9851
9852   mp->sw_if_index = ntohl (sw_if_index);
9853   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9854   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9855
9856   S;
9857   W;
9858   /* NOTREACHED */
9859   return 0;
9860 }
9861
9862 static int
9863 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9864 {
9865   unformat_input_t *i = vam->input;
9866   vl_api_l2tpv3_interface_enable_disable_t *mp;
9867   f64 timeout;
9868   u32 sw_if_index;
9869   u8 sw_if_index_set = 0;
9870   u8 enable_disable = 1;
9871
9872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9873     {
9874       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9875         sw_if_index_set = 1;
9876       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9877         sw_if_index_set = 1;
9878       else if (unformat (i, "enable"))
9879         enable_disable = 1;
9880       else if (unformat (i, "disable"))
9881         enable_disable = 0;
9882       else
9883         break;
9884     }
9885
9886   if (sw_if_index_set == 0)
9887     {
9888       errmsg ("missing interface name or sw_if_index\n");
9889       return -99;
9890     }
9891
9892   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9893
9894   mp->sw_if_index = ntohl (sw_if_index);
9895   mp->enable_disable = enable_disable;
9896
9897   S;
9898   W;
9899   /* NOTREACHED */
9900   return 0;
9901 }
9902
9903 static int
9904 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9905 {
9906   unformat_input_t *i = vam->input;
9907   vl_api_l2tpv3_set_lookup_key_t *mp;
9908   f64 timeout;
9909   u8 key = ~0;
9910
9911   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9912     {
9913       if (unformat (i, "lookup_v6_src"))
9914         key = L2T_LOOKUP_SRC_ADDRESS;
9915       else if (unformat (i, "lookup_v6_dst"))
9916         key = L2T_LOOKUP_DST_ADDRESS;
9917       else if (unformat (i, "lookup_session_id"))
9918         key = L2T_LOOKUP_SESSION_ID;
9919       else
9920         break;
9921     }
9922
9923   if (key == (u8) ~ 0)
9924     {
9925       errmsg ("l2tp session lookup key unset\n");
9926       return -99;
9927     }
9928
9929   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9930
9931   mp->key = key;
9932
9933   S;
9934   W;
9935   /* NOTREACHED */
9936   return 0;
9937 }
9938
9939 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9940   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9941 {
9942   vat_main_t *vam = &vat_main;
9943
9944   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9945            format_ip6_address, mp->our_address,
9946            format_ip6_address, mp->client_address,
9947            clib_net_to_host_u32 (mp->sw_if_index));
9948
9949   fformat (vam->ofp,
9950            "   local cookies %016llx %016llx remote cookie %016llx\n",
9951            clib_net_to_host_u64 (mp->local_cookie[0]),
9952            clib_net_to_host_u64 (mp->local_cookie[1]),
9953            clib_net_to_host_u64 (mp->remote_cookie));
9954
9955   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9956            clib_net_to_host_u32 (mp->local_session_id),
9957            clib_net_to_host_u32 (mp->remote_session_id));
9958
9959   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9960            mp->l2_sublayer_present ? "preset" : "absent");
9961
9962 }
9963
9964 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9965   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9966 {
9967   vat_main_t *vam = &vat_main;
9968   vat_json_node_t *node = NULL;
9969   struct in6_addr addr;
9970
9971   if (VAT_JSON_ARRAY != vam->json_tree.type)
9972     {
9973       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9974       vat_json_init_array (&vam->json_tree);
9975     }
9976   node = vat_json_array_add (&vam->json_tree);
9977
9978   vat_json_init_object (node);
9979
9980   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9981   vat_json_object_add_ip6 (node, "our_address", addr);
9982   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9983   vat_json_object_add_ip6 (node, "client_address", addr);
9984
9985   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9986   vat_json_init_array (lc);
9987   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9988   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9989   vat_json_object_add_uint (node, "remote_cookie",
9990                             clib_net_to_host_u64 (mp->remote_cookie));
9991
9992   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9993   vat_json_object_add_uint (node, "local_session_id",
9994                             clib_net_to_host_u32 (mp->local_session_id));
9995   vat_json_object_add_uint (node, "remote_session_id",
9996                             clib_net_to_host_u32 (mp->remote_session_id));
9997   vat_json_object_add_string_copy (node, "l2_sublayer",
9998                                    mp->l2_sublayer_present ? (u8 *) "present"
9999                                    : (u8 *) "absent");
10000 }
10001
10002 static int
10003 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10004 {
10005   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10006   f64 timeout;
10007
10008   /* Get list of l2tpv3-tunnel interfaces */
10009   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10010   S;
10011
10012   /* Use a control ping for synchronization */
10013   {
10014     vl_api_control_ping_t *mp;
10015     M (CONTROL_PING, control_ping);
10016     S;
10017   }
10018   W;
10019 }
10020
10021
10022 static void vl_api_sw_interface_tap_details_t_handler
10023   (vl_api_sw_interface_tap_details_t * mp)
10024 {
10025   vat_main_t *vam = &vat_main;
10026
10027   fformat (vam->ofp, "%-16s %d\n",
10028            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10029 }
10030
10031 static void vl_api_sw_interface_tap_details_t_handler_json
10032   (vl_api_sw_interface_tap_details_t * mp)
10033 {
10034   vat_main_t *vam = &vat_main;
10035   vat_json_node_t *node = NULL;
10036
10037   if (VAT_JSON_ARRAY != vam->json_tree.type)
10038     {
10039       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10040       vat_json_init_array (&vam->json_tree);
10041     }
10042   node = vat_json_array_add (&vam->json_tree);
10043
10044   vat_json_init_object (node);
10045   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10046   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10047 }
10048
10049 static int
10050 api_sw_interface_tap_dump (vat_main_t * vam)
10051 {
10052   vl_api_sw_interface_tap_dump_t *mp;
10053   f64 timeout;
10054
10055   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10056   /* Get list of tap interfaces */
10057   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10058   S;
10059
10060   /* Use a control ping for synchronization */
10061   {
10062     vl_api_control_ping_t *mp;
10063     M (CONTROL_PING, control_ping);
10064     S;
10065   }
10066   W;
10067 }
10068
10069 static uword unformat_vxlan_decap_next
10070   (unformat_input_t * input, va_list * args)
10071 {
10072   u32 *result = va_arg (*args, u32 *);
10073   u32 tmp;
10074
10075   if (unformat (input, "l2"))
10076     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10077   else if (unformat (input, "%d", &tmp))
10078     *result = tmp;
10079   else
10080     return 0;
10081   return 1;
10082 }
10083
10084 static int
10085 api_vxlan_add_del_tunnel (vat_main_t * vam)
10086 {
10087   unformat_input_t *line_input = vam->input;
10088   vl_api_vxlan_add_del_tunnel_t *mp;
10089   f64 timeout;
10090   ip4_address_t src4, dst4;
10091   ip6_address_t src6, dst6;
10092   u8 is_add = 1;
10093   u8 ipv4_set = 0, ipv6_set = 0;
10094   u8 src_set = 0;
10095   u8 dst_set = 0;
10096   u32 encap_vrf_id = 0;
10097   u32 decap_next_index = ~0;
10098   u32 vni = 0;
10099
10100   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10101     {
10102       if (unformat (line_input, "del"))
10103         is_add = 0;
10104       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10105         {
10106           ipv4_set = 1;
10107           src_set = 1;
10108         }
10109       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10110         {
10111           ipv4_set = 1;
10112           dst_set = 1;
10113         }
10114       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
10115         {
10116           ipv6_set = 1;
10117           src_set = 1;
10118         }
10119       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
10120         {
10121           ipv6_set = 1;
10122           dst_set = 1;
10123         }
10124       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10125         ;
10126       else if (unformat (line_input, "decap-next %U",
10127                          unformat_vxlan_decap_next, &decap_next_index))
10128         ;
10129       else if (unformat (line_input, "vni %d", &vni))
10130         ;
10131       else
10132         {
10133           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10134           return -99;
10135         }
10136     }
10137
10138   if (src_set == 0)
10139     {
10140       errmsg ("tunnel src address not specified\n");
10141       return -99;
10142     }
10143   if (dst_set == 0)
10144     {
10145       errmsg ("tunnel dst address not specified\n");
10146       return -99;
10147     }
10148
10149   if (ipv4_set && ipv6_set)
10150     {
10151       errmsg ("both IPv4 and IPv6 addresses specified");
10152       return -99;
10153     }
10154
10155   if ((vni == 0) || (vni >> 24))
10156     {
10157       errmsg ("vni not specified or out of range\n");
10158       return -99;
10159     }
10160
10161   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10162
10163   if (ipv6_set)
10164     {
10165       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
10166       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
10167     }
10168   else
10169     {
10170       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10171       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10172     }
10173   mp->encap_vrf_id = ntohl (encap_vrf_id);
10174   mp->decap_next_index = ntohl (decap_next_index);
10175   mp->vni = ntohl (vni);
10176   mp->is_add = is_add;
10177   mp->is_ipv6 = ipv6_set;
10178
10179   S;
10180   W;
10181   /* NOTREACHED */
10182   return 0;
10183 }
10184
10185 static void vl_api_vxlan_tunnel_details_t_handler
10186   (vl_api_vxlan_tunnel_details_t * mp)
10187 {
10188   vat_main_t *vam = &vat_main;
10189
10190   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
10191            ntohl (mp->sw_if_index),
10192            format_ip46_address, &(mp->src_address[0]),
10193            IP46_TYPE_ANY,
10194            format_ip46_address, &(mp->dst_address[0]),
10195            IP46_TYPE_ANY,
10196            ntohl (mp->encap_vrf_id),
10197            ntohl (mp->decap_next_index), ntohl (mp->vni));
10198 }
10199
10200 static void vl_api_vxlan_tunnel_details_t_handler_json
10201   (vl_api_vxlan_tunnel_details_t * mp)
10202 {
10203   vat_main_t *vam = &vat_main;
10204   vat_json_node_t *node = NULL;
10205   struct in_addr ip4;
10206   struct in6_addr ip6;
10207
10208   if (VAT_JSON_ARRAY != vam->json_tree.type)
10209     {
10210       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10211       vat_json_init_array (&vam->json_tree);
10212     }
10213   node = vat_json_array_add (&vam->json_tree);
10214
10215   vat_json_init_object (node);
10216   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10217   if (mp->is_ipv6)
10218     {
10219       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
10220       vat_json_object_add_ip6 (node, "src_address", ip6);
10221       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
10222       vat_json_object_add_ip6 (node, "dst_address", ip6);
10223     }
10224   else
10225     {
10226       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
10227       vat_json_object_add_ip4 (node, "src_address", ip4);
10228       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
10229       vat_json_object_add_ip4 (node, "dst_address", ip4);
10230     }
10231   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10232   vat_json_object_add_uint (node, "decap_next_index",
10233                             ntohl (mp->decap_next_index));
10234   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10235   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10236 }
10237
10238 static int
10239 api_vxlan_tunnel_dump (vat_main_t * vam)
10240 {
10241   unformat_input_t *i = vam->input;
10242   vl_api_vxlan_tunnel_dump_t *mp;
10243   f64 timeout;
10244   u32 sw_if_index;
10245   u8 sw_if_index_set = 0;
10246
10247   /* Parse args required to build the message */
10248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10249     {
10250       if (unformat (i, "sw_if_index %d", &sw_if_index))
10251         sw_if_index_set = 1;
10252       else
10253         break;
10254     }
10255
10256   if (sw_if_index_set == 0)
10257     {
10258       sw_if_index = ~0;
10259     }
10260
10261   if (!vam->json_output)
10262     {
10263       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
10264                "sw_if_index", "src_address", "dst_address",
10265                "encap_vrf_id", "decap_next_index", "vni");
10266     }
10267
10268   /* Get list of vxlan-tunnel interfaces */
10269   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10270
10271   mp->sw_if_index = htonl (sw_if_index);
10272
10273   S;
10274
10275   /* Use a control ping for synchronization */
10276   {
10277     vl_api_control_ping_t *mp;
10278     M (CONTROL_PING, control_ping);
10279     S;
10280   }
10281   W;
10282 }
10283
10284 static int
10285 api_gre_add_del_tunnel (vat_main_t * vam)
10286 {
10287   unformat_input_t *line_input = vam->input;
10288   vl_api_gre_add_del_tunnel_t *mp;
10289   f64 timeout;
10290   ip4_address_t src4, dst4;
10291   u8 is_add = 1;
10292   u8 teb = 0;
10293   u8 src_set = 0;
10294   u8 dst_set = 0;
10295   u32 outer_fib_id = 0;
10296
10297   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10298     {
10299       if (unformat (line_input, "del"))
10300         is_add = 0;
10301       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10302         src_set = 1;
10303       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10304         dst_set = 1;
10305       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10306         ;
10307       else if (unformat (line_input, "teb"))
10308         teb = 1;
10309       else
10310         {
10311           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10312           return -99;
10313         }
10314     }
10315
10316   if (src_set == 0)
10317     {
10318       errmsg ("tunnel src address not specified\n");
10319       return -99;
10320     }
10321   if (dst_set == 0)
10322     {
10323       errmsg ("tunnel dst address not specified\n");
10324       return -99;
10325     }
10326
10327
10328   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10329
10330   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10331   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10332   mp->outer_fib_id = ntohl (outer_fib_id);
10333   mp->is_add = is_add;
10334   mp->teb = teb;
10335
10336   S;
10337   W;
10338   /* NOTREACHED */
10339   return 0;
10340 }
10341
10342 static void vl_api_gre_tunnel_details_t_handler
10343   (vl_api_gre_tunnel_details_t * mp)
10344 {
10345   vat_main_t *vam = &vat_main;
10346
10347   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10348            ntohl (mp->sw_if_index),
10349            format_ip4_address, &mp->src_address,
10350            format_ip4_address, &mp->dst_address,
10351            mp->teb, ntohl (mp->outer_fib_id));
10352 }
10353
10354 static void vl_api_gre_tunnel_details_t_handler_json
10355   (vl_api_gre_tunnel_details_t * mp)
10356 {
10357   vat_main_t *vam = &vat_main;
10358   vat_json_node_t *node = NULL;
10359   struct in_addr ip4;
10360
10361   if (VAT_JSON_ARRAY != vam->json_tree.type)
10362     {
10363       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10364       vat_json_init_array (&vam->json_tree);
10365     }
10366   node = vat_json_array_add (&vam->json_tree);
10367
10368   vat_json_init_object (node);
10369   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10370   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10371   vat_json_object_add_ip4 (node, "src_address", ip4);
10372   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10373   vat_json_object_add_ip4 (node, "dst_address", ip4);
10374   vat_json_object_add_uint (node, "teb", mp->teb);
10375   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10376 }
10377
10378 static int
10379 api_gre_tunnel_dump (vat_main_t * vam)
10380 {
10381   unformat_input_t *i = vam->input;
10382   vl_api_gre_tunnel_dump_t *mp;
10383   f64 timeout;
10384   u32 sw_if_index;
10385   u8 sw_if_index_set = 0;
10386
10387   /* Parse args required to build the message */
10388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10389     {
10390       if (unformat (i, "sw_if_index %d", &sw_if_index))
10391         sw_if_index_set = 1;
10392       else
10393         break;
10394     }
10395
10396   if (sw_if_index_set == 0)
10397     {
10398       sw_if_index = ~0;
10399     }
10400
10401   if (!vam->json_output)
10402     {
10403       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10404                "sw_if_index", "src_address", "dst_address", "teb",
10405                "outer_fib_id");
10406     }
10407
10408   /* Get list of gre-tunnel interfaces */
10409   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10410
10411   mp->sw_if_index = htonl (sw_if_index);
10412
10413   S;
10414
10415   /* Use a control ping for synchronization */
10416   {
10417     vl_api_control_ping_t *mp;
10418     M (CONTROL_PING, control_ping);
10419     S;
10420   }
10421   W;
10422 }
10423
10424 static int
10425 api_l2_fib_clear_table (vat_main_t * vam)
10426 {
10427 //  unformat_input_t * i = vam->input;
10428   vl_api_l2_fib_clear_table_t *mp;
10429   f64 timeout;
10430
10431   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10432
10433   S;
10434   W;
10435   /* NOTREACHED */
10436   return 0;
10437 }
10438
10439 static int
10440 api_l2_interface_efp_filter (vat_main_t * vam)
10441 {
10442   unformat_input_t *i = vam->input;
10443   vl_api_l2_interface_efp_filter_t *mp;
10444   f64 timeout;
10445   u32 sw_if_index;
10446   u8 enable = 1;
10447   u8 sw_if_index_set = 0;
10448
10449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10450     {
10451       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10452         sw_if_index_set = 1;
10453       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10454         sw_if_index_set = 1;
10455       else if (unformat (i, "enable"))
10456         enable = 1;
10457       else if (unformat (i, "disable"))
10458         enable = 0;
10459       else
10460         {
10461           clib_warning ("parse error '%U'", format_unformat_error, i);
10462           return -99;
10463         }
10464     }
10465
10466   if (sw_if_index_set == 0)
10467     {
10468       errmsg ("missing sw_if_index\n");
10469       return -99;
10470     }
10471
10472   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10473
10474   mp->sw_if_index = ntohl (sw_if_index);
10475   mp->enable_disable = enable;
10476
10477   S;
10478   W;
10479   /* NOTREACHED */
10480   return 0;
10481 }
10482
10483 #define foreach_vtr_op                          \
10484 _("disable",  L2_VTR_DISABLED)                  \
10485 _("push-1",  L2_VTR_PUSH_1)                     \
10486 _("push-2",  L2_VTR_PUSH_2)                     \
10487 _("pop-1",  L2_VTR_POP_1)                       \
10488 _("pop-2",  L2_VTR_POP_2)                       \
10489 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10490 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10491 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10492 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10493
10494 static int
10495 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10496 {
10497   unformat_input_t *i = vam->input;
10498   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10499   f64 timeout;
10500   u32 sw_if_index;
10501   u8 sw_if_index_set = 0;
10502   u8 vtr_op_set = 0;
10503   u32 vtr_op = 0;
10504   u32 push_dot1q = 1;
10505   u32 tag1 = ~0;
10506   u32 tag2 = ~0;
10507
10508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10509     {
10510       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10511         sw_if_index_set = 1;
10512       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10513         sw_if_index_set = 1;
10514       else if (unformat (i, "vtr_op %d", &vtr_op))
10515         vtr_op_set = 1;
10516 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10517       foreach_vtr_op
10518 #undef _
10519         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10520         ;
10521       else if (unformat (i, "tag1 %d", &tag1))
10522         ;
10523       else if (unformat (i, "tag2 %d", &tag2))
10524         ;
10525       else
10526         {
10527           clib_warning ("parse error '%U'", format_unformat_error, i);
10528           return -99;
10529         }
10530     }
10531
10532   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10533     {
10534       errmsg ("missing vtr operation or sw_if_index\n");
10535       return -99;
10536     }
10537
10538   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10539     mp->sw_if_index = ntohl (sw_if_index);
10540   mp->vtr_op = ntohl (vtr_op);
10541   mp->push_dot1q = ntohl (push_dot1q);
10542   mp->tag1 = ntohl (tag1);
10543   mp->tag2 = ntohl (tag2);
10544
10545   S;
10546   W;
10547   /* NOTREACHED */
10548   return 0;
10549 }
10550
10551 static int
10552 api_create_vhost_user_if (vat_main_t * vam)
10553 {
10554   unformat_input_t *i = vam->input;
10555   vl_api_create_vhost_user_if_t *mp;
10556   f64 timeout;
10557   u8 *file_name;
10558   u8 is_server = 0;
10559   u8 file_name_set = 0;
10560   u32 custom_dev_instance = ~0;
10561   u8 hwaddr[6];
10562   u8 use_custom_mac = 0;
10563
10564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10565     {
10566       if (unformat (i, "socket %s", &file_name))
10567         {
10568           file_name_set = 1;
10569         }
10570       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10571         ;
10572       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10573         use_custom_mac = 1;
10574       else if (unformat (i, "server"))
10575         is_server = 1;
10576       else
10577         break;
10578     }
10579
10580   if (file_name_set == 0)
10581     {
10582       errmsg ("missing socket file name\n");
10583       return -99;
10584     }
10585
10586   if (vec_len (file_name) > 255)
10587     {
10588       errmsg ("socket file name too long\n");
10589       return -99;
10590     }
10591   vec_add1 (file_name, 0);
10592
10593   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10594
10595   mp->is_server = is_server;
10596   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10597   vec_free (file_name);
10598   if (custom_dev_instance != ~0)
10599     {
10600       mp->renumber = 1;
10601       mp->custom_dev_instance = ntohl (custom_dev_instance);
10602     }
10603   mp->use_custom_mac = use_custom_mac;
10604   clib_memcpy (mp->mac_address, hwaddr, 6);
10605
10606   S;
10607   W;
10608   /* NOTREACHED */
10609   return 0;
10610 }
10611
10612 static int
10613 api_modify_vhost_user_if (vat_main_t * vam)
10614 {
10615   unformat_input_t *i = vam->input;
10616   vl_api_modify_vhost_user_if_t *mp;
10617   f64 timeout;
10618   u8 *file_name;
10619   u8 is_server = 0;
10620   u8 file_name_set = 0;
10621   u32 custom_dev_instance = ~0;
10622   u8 sw_if_index_set = 0;
10623   u32 sw_if_index = (u32) ~ 0;
10624
10625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10626     {
10627       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10628         sw_if_index_set = 1;
10629       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10630         sw_if_index_set = 1;
10631       else if (unformat (i, "socket %s", &file_name))
10632         {
10633           file_name_set = 1;
10634         }
10635       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10636         ;
10637       else if (unformat (i, "server"))
10638         is_server = 1;
10639       else
10640         break;
10641     }
10642
10643   if (sw_if_index_set == 0)
10644     {
10645       errmsg ("missing sw_if_index or interface name\n");
10646       return -99;
10647     }
10648
10649   if (file_name_set == 0)
10650     {
10651       errmsg ("missing socket file name\n");
10652       return -99;
10653     }
10654
10655   if (vec_len (file_name) > 255)
10656     {
10657       errmsg ("socket file name too long\n");
10658       return -99;
10659     }
10660   vec_add1 (file_name, 0);
10661
10662   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10663
10664   mp->sw_if_index = ntohl (sw_if_index);
10665   mp->is_server = is_server;
10666   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10667   vec_free (file_name);
10668   if (custom_dev_instance != ~0)
10669     {
10670       mp->renumber = 1;
10671       mp->custom_dev_instance = ntohl (custom_dev_instance);
10672     }
10673
10674   S;
10675   W;
10676   /* NOTREACHED */
10677   return 0;
10678 }
10679
10680 static int
10681 api_delete_vhost_user_if (vat_main_t * vam)
10682 {
10683   unformat_input_t *i = vam->input;
10684   vl_api_delete_vhost_user_if_t *mp;
10685   f64 timeout;
10686   u32 sw_if_index = ~0;
10687   u8 sw_if_index_set = 0;
10688
10689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10690     {
10691       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10692         sw_if_index_set = 1;
10693       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10694         sw_if_index_set = 1;
10695       else
10696         break;
10697     }
10698
10699   if (sw_if_index_set == 0)
10700     {
10701       errmsg ("missing sw_if_index or interface name\n");
10702       return -99;
10703     }
10704
10705
10706   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10707
10708   mp->sw_if_index = ntohl (sw_if_index);
10709
10710   S;
10711   W;
10712   /* NOTREACHED */
10713   return 0;
10714 }
10715
10716 static void vl_api_sw_interface_vhost_user_details_t_handler
10717   (vl_api_sw_interface_vhost_user_details_t * mp)
10718 {
10719   vat_main_t *vam = &vat_main;
10720
10721   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10722            (char *) mp->interface_name,
10723            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10724            clib_net_to_host_u64 (mp->features), mp->is_server,
10725            ntohl (mp->num_regions), (char *) mp->sock_filename);
10726   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10727 }
10728
10729 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10730   (vl_api_sw_interface_vhost_user_details_t * mp)
10731 {
10732   vat_main_t *vam = &vat_main;
10733   vat_json_node_t *node = NULL;
10734
10735   if (VAT_JSON_ARRAY != vam->json_tree.type)
10736     {
10737       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10738       vat_json_init_array (&vam->json_tree);
10739     }
10740   node = vat_json_array_add (&vam->json_tree);
10741
10742   vat_json_init_object (node);
10743   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10744   vat_json_object_add_string_copy (node, "interface_name",
10745                                    mp->interface_name);
10746   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10747                             ntohl (mp->virtio_net_hdr_sz));
10748   vat_json_object_add_uint (node, "features",
10749                             clib_net_to_host_u64 (mp->features));
10750   vat_json_object_add_uint (node, "is_server", mp->is_server);
10751   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10752   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10753   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10754 }
10755
10756 static int
10757 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10758 {
10759   vl_api_sw_interface_vhost_user_dump_t *mp;
10760   f64 timeout;
10761   fformat (vam->ofp,
10762            "Interface name           idx hdr_sz features server regions filename\n");
10763
10764   /* Get list of vhost-user interfaces */
10765   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10766   S;
10767
10768   /* Use a control ping for synchronization */
10769   {
10770     vl_api_control_ping_t *mp;
10771     M (CONTROL_PING, control_ping);
10772     S;
10773   }
10774   W;
10775 }
10776
10777 static int
10778 api_show_version (vat_main_t * vam)
10779 {
10780   vl_api_show_version_t *mp;
10781   f64 timeout;
10782
10783   M (SHOW_VERSION, show_version);
10784
10785   S;
10786   W;
10787   /* NOTREACHED */
10788   return 0;
10789 }
10790
10791
10792 static int
10793 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10794 {
10795   unformat_input_t *line_input = vam->input;
10796   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10797   f64 timeout;
10798   ip4_address_t local4, remote4;
10799   ip6_address_t local6, remote6;
10800   u8 is_add = 1;
10801   u8 ipv4_set = 0, ipv6_set = 0;
10802   u8 local_set = 0;
10803   u8 remote_set = 0;
10804   u32 encap_vrf_id = 0;
10805   u32 decap_vrf_id = 0;
10806   u8 protocol = ~0;
10807   u32 vni;
10808   u8 vni_set = 0;
10809
10810   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10811     {
10812       if (unformat (line_input, "del"))
10813         is_add = 0;
10814       else if (unformat (line_input, "local %U",
10815                          unformat_ip4_address, &local4))
10816         {
10817           local_set = 1;
10818           ipv4_set = 1;
10819         }
10820       else if (unformat (line_input, "remote %U",
10821                          unformat_ip4_address, &remote4))
10822         {
10823           remote_set = 1;
10824           ipv4_set = 1;
10825         }
10826       else if (unformat (line_input, "local %U",
10827                          unformat_ip6_address, &local6))
10828         {
10829           local_set = 1;
10830           ipv6_set = 1;
10831         }
10832       else if (unformat (line_input, "remote %U",
10833                          unformat_ip6_address, &remote6))
10834         {
10835           remote_set = 1;
10836           ipv6_set = 1;
10837         }
10838       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10839         ;
10840       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10841         ;
10842       else if (unformat (line_input, "vni %d", &vni))
10843         vni_set = 1;
10844       else if (unformat (line_input, "next-ip4"))
10845         protocol = 1;
10846       else if (unformat (line_input, "next-ip6"))
10847         protocol = 2;
10848       else if (unformat (line_input, "next-ethernet"))
10849         protocol = 3;
10850       else if (unformat (line_input, "next-nsh"))
10851         protocol = 4;
10852       else
10853         {
10854           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10855           return -99;
10856         }
10857     }
10858
10859   if (local_set == 0)
10860     {
10861       errmsg ("tunnel local address not specified\n");
10862       return -99;
10863     }
10864   if (remote_set == 0)
10865     {
10866       errmsg ("tunnel remote address not specified\n");
10867       return -99;
10868     }
10869   if (ipv4_set && ipv6_set)
10870     {
10871       errmsg ("both IPv4 and IPv6 addresses specified");
10872       return -99;
10873     }
10874
10875   if (vni_set == 0)
10876     {
10877       errmsg ("vni not specified\n");
10878       return -99;
10879     }
10880
10881   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10882
10883
10884   if (ipv6_set)
10885     {
10886       clib_memcpy (&mp->local, &local6, sizeof (local6));
10887       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10888     }
10889   else
10890     {
10891       clib_memcpy (&mp->local, &local4, sizeof (local4));
10892       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10893     }
10894
10895   mp->encap_vrf_id = ntohl (encap_vrf_id);
10896   mp->decap_vrf_id = ntohl (decap_vrf_id);
10897   mp->protocol = ntohl (protocol);
10898   mp->vni = ntohl (vni);
10899   mp->is_add = is_add;
10900   mp->is_ipv6 = ipv6_set;
10901
10902   S;
10903   W;
10904   /* NOTREACHED */
10905   return 0;
10906 }
10907
10908 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10909   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10910 {
10911   vat_main_t *vam = &vat_main;
10912
10913   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10914            ntohl (mp->sw_if_index),
10915            format_ip46_address, &(mp->local[0]),
10916            format_ip46_address, &(mp->remote[0]),
10917            ntohl (mp->vni),
10918            ntohl (mp->protocol),
10919            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10920 }
10921
10922 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10923   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10924 {
10925   vat_main_t *vam = &vat_main;
10926   vat_json_node_t *node = NULL;
10927   struct in_addr ip4;
10928   struct in6_addr ip6;
10929
10930   if (VAT_JSON_ARRAY != vam->json_tree.type)
10931     {
10932       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10933       vat_json_init_array (&vam->json_tree);
10934     }
10935   node = vat_json_array_add (&vam->json_tree);
10936
10937   vat_json_init_object (node);
10938   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10939   if (mp->is_ipv6)
10940     {
10941       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10942       vat_json_object_add_ip6 (node, "local", ip6);
10943       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10944       vat_json_object_add_ip6 (node, "remote", ip6);
10945     }
10946   else
10947     {
10948       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10949       vat_json_object_add_ip4 (node, "local", ip4);
10950       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10951       vat_json_object_add_ip4 (node, "remote", ip4);
10952     }
10953   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10954   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10955   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10956   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10957   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10958 }
10959
10960 static int
10961 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10962 {
10963   unformat_input_t *i = vam->input;
10964   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10965   f64 timeout;
10966   u32 sw_if_index;
10967   u8 sw_if_index_set = 0;
10968
10969   /* Parse args required to build the message */
10970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10971     {
10972       if (unformat (i, "sw_if_index %d", &sw_if_index))
10973         sw_if_index_set = 1;
10974       else
10975         break;
10976     }
10977
10978   if (sw_if_index_set == 0)
10979     {
10980       sw_if_index = ~0;
10981     }
10982
10983   if (!vam->json_output)
10984     {
10985       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10986                "sw_if_index", "local", "remote", "vni",
10987                "protocol", "encap_vrf_id", "decap_vrf_id");
10988     }
10989
10990   /* Get list of vxlan-tunnel interfaces */
10991   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10992
10993   mp->sw_if_index = htonl (sw_if_index);
10994
10995   S;
10996
10997   /* Use a control ping for synchronization */
10998   {
10999     vl_api_control_ping_t *mp;
11000     M (CONTROL_PING, control_ping);
11001     S;
11002   }
11003   W;
11004 }
11005
11006 u8 *
11007 format_l2_fib_mac_address (u8 * s, va_list * args)
11008 {
11009   u8 *a = va_arg (*args, u8 *);
11010
11011   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11012                  a[2], a[3], a[4], a[5], a[6], a[7]);
11013 }
11014
11015 static void vl_api_l2_fib_table_entry_t_handler
11016   (vl_api_l2_fib_table_entry_t * mp)
11017 {
11018   vat_main_t *vam = &vat_main;
11019
11020   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11021            "       %d       %d     %d\n",
11022            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11023            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11024            mp->bvi_mac);
11025 }
11026
11027 static void vl_api_l2_fib_table_entry_t_handler_json
11028   (vl_api_l2_fib_table_entry_t * mp)
11029 {
11030   vat_main_t *vam = &vat_main;
11031   vat_json_node_t *node = NULL;
11032
11033   if (VAT_JSON_ARRAY != vam->json_tree.type)
11034     {
11035       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11036       vat_json_init_array (&vam->json_tree);
11037     }
11038   node = vat_json_array_add (&vam->json_tree);
11039
11040   vat_json_init_object (node);
11041   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11042   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11043   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11044   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11045   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11046   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11047 }
11048
11049 static int
11050 api_l2_fib_table_dump (vat_main_t * vam)
11051 {
11052   unformat_input_t *i = vam->input;
11053   vl_api_l2_fib_table_dump_t *mp;
11054   f64 timeout;
11055   u32 bd_id;
11056   u8 bd_id_set = 0;
11057
11058   /* Parse args required to build the message */
11059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11060     {
11061       if (unformat (i, "bd_id %d", &bd_id))
11062         bd_id_set = 1;
11063       else
11064         break;
11065     }
11066
11067   if (bd_id_set == 0)
11068     {
11069       errmsg ("missing bridge domain\n");
11070       return -99;
11071     }
11072
11073   fformat (vam->ofp,
11074            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11075
11076   /* Get list of l2 fib entries */
11077   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11078
11079   mp->bd_id = ntohl (bd_id);
11080   S;
11081
11082   /* Use a control ping for synchronization */
11083   {
11084     vl_api_control_ping_t *mp;
11085     M (CONTROL_PING, control_ping);
11086     S;
11087   }
11088   W;
11089 }
11090
11091
11092 static int
11093 api_interface_name_renumber (vat_main_t * vam)
11094 {
11095   unformat_input_t *line_input = vam->input;
11096   vl_api_interface_name_renumber_t *mp;
11097   u32 sw_if_index = ~0;
11098   f64 timeout;
11099   u32 new_show_dev_instance = ~0;
11100
11101   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11102     {
11103       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11104                     &sw_if_index))
11105         ;
11106       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11107         ;
11108       else if (unformat (line_input, "new_show_dev_instance %d",
11109                          &new_show_dev_instance))
11110         ;
11111       else
11112         break;
11113     }
11114
11115   if (sw_if_index == ~0)
11116     {
11117       errmsg ("missing interface name or sw_if_index\n");
11118       return -99;
11119     }
11120
11121   if (new_show_dev_instance == ~0)
11122     {
11123       errmsg ("missing new_show_dev_instance\n");
11124       return -99;
11125     }
11126
11127   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11128
11129   mp->sw_if_index = ntohl (sw_if_index);
11130   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11131
11132   S;
11133   W;
11134 }
11135
11136 static int
11137 api_want_ip4_arp_events (vat_main_t * vam)
11138 {
11139   unformat_input_t *line_input = vam->input;
11140   vl_api_want_ip4_arp_events_t *mp;
11141   f64 timeout;
11142   ip4_address_t address;
11143   int address_set = 0;
11144   u32 enable_disable = 1;
11145
11146   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11147     {
11148       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11149         address_set = 1;
11150       else if (unformat (line_input, "del"))
11151         enable_disable = 0;
11152       else
11153         break;
11154     }
11155
11156   if (address_set == 0)
11157     {
11158       errmsg ("missing addresses\n");
11159       return -99;
11160     }
11161
11162   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11163   mp->enable_disable = enable_disable;
11164   mp->pid = getpid ();
11165   mp->address = address.as_u32;
11166
11167   S;
11168   W;
11169 }
11170
11171 static int
11172 api_want_ip6_nd_events (vat_main_t * vam)
11173 {
11174   unformat_input_t *line_input = vam->input;
11175   vl_api_want_ip6_nd_events_t *mp;
11176   f64 timeout;
11177   ip6_address_t address;
11178   int address_set = 0;
11179   u32 enable_disable = 1;
11180
11181   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11182     {
11183       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11184         address_set = 1;
11185       else if (unformat (line_input, "del"))
11186         enable_disable = 0;
11187       else
11188         break;
11189     }
11190
11191   if (address_set == 0)
11192     {
11193       errmsg ("missing addresses\n");
11194       return -99;
11195     }
11196
11197   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11198   mp->enable_disable = enable_disable;
11199   mp->pid = getpid ();
11200   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11201
11202   S;
11203   W;
11204 }
11205
11206 static int
11207 api_input_acl_set_interface (vat_main_t * vam)
11208 {
11209   unformat_input_t *i = vam->input;
11210   vl_api_input_acl_set_interface_t *mp;
11211   f64 timeout;
11212   u32 sw_if_index;
11213   int sw_if_index_set;
11214   u32 ip4_table_index = ~0;
11215   u32 ip6_table_index = ~0;
11216   u32 l2_table_index = ~0;
11217   u8 is_add = 1;
11218
11219   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11220     {
11221       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11222         sw_if_index_set = 1;
11223       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11224         sw_if_index_set = 1;
11225       else if (unformat (i, "del"))
11226         is_add = 0;
11227       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11228         ;
11229       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11230         ;
11231       else if (unformat (i, "l2-table %d", &l2_table_index))
11232         ;
11233       else
11234         {
11235           clib_warning ("parse error '%U'", format_unformat_error, i);
11236           return -99;
11237         }
11238     }
11239
11240   if (sw_if_index_set == 0)
11241     {
11242       errmsg ("missing interface name or sw_if_index\n");
11243       return -99;
11244     }
11245
11246   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11247
11248   mp->sw_if_index = ntohl (sw_if_index);
11249   mp->ip4_table_index = ntohl (ip4_table_index);
11250   mp->ip6_table_index = ntohl (ip6_table_index);
11251   mp->l2_table_index = ntohl (l2_table_index);
11252   mp->is_add = is_add;
11253
11254   S;
11255   W;
11256   /* NOTREACHED */
11257   return 0;
11258 }
11259
11260 static int
11261 api_ip_address_dump (vat_main_t * vam)
11262 {
11263   unformat_input_t *i = vam->input;
11264   vl_api_ip_address_dump_t *mp;
11265   u32 sw_if_index = ~0;
11266   u8 sw_if_index_set = 0;
11267   u8 ipv4_set = 0;
11268   u8 ipv6_set = 0;
11269   f64 timeout;
11270
11271   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11272     {
11273       if (unformat (i, "sw_if_index %d", &sw_if_index))
11274         sw_if_index_set = 1;
11275       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11276         sw_if_index_set = 1;
11277       else if (unformat (i, "ipv4"))
11278         ipv4_set = 1;
11279       else if (unformat (i, "ipv6"))
11280         ipv6_set = 1;
11281       else
11282         break;
11283     }
11284
11285   if (ipv4_set && ipv6_set)
11286     {
11287       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11288       return -99;
11289     }
11290
11291   if ((!ipv4_set) && (!ipv6_set))
11292     {
11293       errmsg ("no ipv4 nor ipv6 flag set\n");
11294       return -99;
11295     }
11296
11297   if (sw_if_index_set == 0)
11298     {
11299       errmsg ("missing interface name or sw_if_index\n");
11300       return -99;
11301     }
11302
11303   vam->current_sw_if_index = sw_if_index;
11304   vam->is_ipv6 = ipv6_set;
11305
11306   M (IP_ADDRESS_DUMP, ip_address_dump);
11307   mp->sw_if_index = ntohl (sw_if_index);
11308   mp->is_ipv6 = ipv6_set;
11309   S;
11310
11311   /* Use a control ping for synchronization */
11312   {
11313     vl_api_control_ping_t *mp;
11314     M (CONTROL_PING, control_ping);
11315     S;
11316   }
11317   W;
11318 }
11319
11320 static int
11321 api_ip_dump (vat_main_t * vam)
11322 {
11323   vl_api_ip_dump_t *mp;
11324   unformat_input_t *in = vam->input;
11325   int ipv4_set = 0;
11326   int ipv6_set = 0;
11327   int is_ipv6;
11328   f64 timeout;
11329   int i;
11330
11331   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11332     {
11333       if (unformat (in, "ipv4"))
11334         ipv4_set = 1;
11335       else if (unformat (in, "ipv6"))
11336         ipv6_set = 1;
11337       else
11338         break;
11339     }
11340
11341   if (ipv4_set && ipv6_set)
11342     {
11343       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11344       return -99;
11345     }
11346
11347   if ((!ipv4_set) && (!ipv6_set))
11348     {
11349       errmsg ("no ipv4 nor ipv6 flag set\n");
11350       return -99;
11351     }
11352
11353   is_ipv6 = ipv6_set;
11354   vam->is_ipv6 = is_ipv6;
11355
11356   /* free old data */
11357   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11358     {
11359       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11360     }
11361   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11362
11363   M (IP_DUMP, ip_dump);
11364   mp->is_ipv6 = ipv6_set;
11365   S;
11366
11367   /* Use a control ping for synchronization */
11368   {
11369     vl_api_control_ping_t *mp;
11370     M (CONTROL_PING, control_ping);
11371     S;
11372   }
11373   W;
11374 }
11375
11376 static int
11377 api_ipsec_spd_add_del (vat_main_t * vam)
11378 {
11379 #if DPDK > 0
11380   unformat_input_t *i = vam->input;
11381   vl_api_ipsec_spd_add_del_t *mp;
11382   f64 timeout;
11383   u32 spd_id = ~0;
11384   u8 is_add = 1;
11385
11386   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11387     {
11388       if (unformat (i, "spd_id %d", &spd_id))
11389         ;
11390       else if (unformat (i, "del"))
11391         is_add = 0;
11392       else
11393         {
11394           clib_warning ("parse error '%U'", format_unformat_error, i);
11395           return -99;
11396         }
11397     }
11398   if (spd_id == ~0)
11399     {
11400       errmsg ("spd_id must be set\n");
11401       return -99;
11402     }
11403
11404   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11405
11406   mp->spd_id = ntohl (spd_id);
11407   mp->is_add = is_add;
11408
11409   S;
11410   W;
11411   /* NOTREACHED */
11412   return 0;
11413 #else
11414   clib_warning ("unsupported (no dpdk)");
11415   return -99;
11416 #endif
11417 }
11418
11419 static int
11420 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11421 {
11422 #if DPDK > 0
11423   unformat_input_t *i = vam->input;
11424   vl_api_ipsec_interface_add_del_spd_t *mp;
11425   f64 timeout;
11426   u32 sw_if_index;
11427   u8 sw_if_index_set = 0;
11428   u32 spd_id = (u32) ~ 0;
11429   u8 is_add = 1;
11430
11431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11432     {
11433       if (unformat (i, "del"))
11434         is_add = 0;
11435       else if (unformat (i, "spd_id %d", &spd_id))
11436         ;
11437       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11438         sw_if_index_set = 1;
11439       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11440         sw_if_index_set = 1;
11441       else
11442         {
11443           clib_warning ("parse error '%U'", format_unformat_error, i);
11444           return -99;
11445         }
11446
11447     }
11448
11449   if (spd_id == (u32) ~ 0)
11450     {
11451       errmsg ("spd_id must be set\n");
11452       return -99;
11453     }
11454
11455   if (sw_if_index_set == 0)
11456     {
11457       errmsg ("missing interface name or sw_if_index\n");
11458       return -99;
11459     }
11460
11461   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11462
11463   mp->spd_id = ntohl (spd_id);
11464   mp->sw_if_index = ntohl (sw_if_index);
11465   mp->is_add = is_add;
11466
11467   S;
11468   W;
11469   /* NOTREACHED */
11470   return 0;
11471 #else
11472   clib_warning ("unsupported (no dpdk)");
11473   return -99;
11474 #endif
11475 }
11476
11477 static int
11478 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11479 {
11480 #if DPDK > 0
11481   unformat_input_t *i = vam->input;
11482   vl_api_ipsec_spd_add_del_entry_t *mp;
11483   f64 timeout;
11484   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11485   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11486   i32 priority = 0;
11487   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11488   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11489   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11490   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11491
11492   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11493   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11494   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11495   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11496   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11497   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11498
11499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11500     {
11501       if (unformat (i, "del"))
11502         is_add = 0;
11503       if (unformat (i, "outbound"))
11504         is_outbound = 1;
11505       if (unformat (i, "inbound"))
11506         is_outbound = 0;
11507       else if (unformat (i, "spd_id %d", &spd_id))
11508         ;
11509       else if (unformat (i, "sa_id %d", &sa_id))
11510         ;
11511       else if (unformat (i, "priority %d", &priority))
11512         ;
11513       else if (unformat (i, "protocol %d", &protocol))
11514         ;
11515       else if (unformat (i, "lport_start %d", &lport_start))
11516         ;
11517       else if (unformat (i, "lport_stop %d", &lport_stop))
11518         ;
11519       else if (unformat (i, "rport_start %d", &rport_start))
11520         ;
11521       else if (unformat (i, "rport_stop %d", &rport_stop))
11522         ;
11523       else
11524         if (unformat
11525             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11526         {
11527           is_ipv6 = 0;
11528           is_ip_any = 0;
11529         }
11530       else
11531         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11532         {
11533           is_ipv6 = 0;
11534           is_ip_any = 0;
11535         }
11536       else
11537         if (unformat
11538             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11539         {
11540           is_ipv6 = 0;
11541           is_ip_any = 0;
11542         }
11543       else
11544         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11545         {
11546           is_ipv6 = 0;
11547           is_ip_any = 0;
11548         }
11549       else
11550         if (unformat
11551             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11552         {
11553           is_ipv6 = 1;
11554           is_ip_any = 0;
11555         }
11556       else
11557         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11558         {
11559           is_ipv6 = 1;
11560           is_ip_any = 0;
11561         }
11562       else
11563         if (unformat
11564             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11565         {
11566           is_ipv6 = 1;
11567           is_ip_any = 0;
11568         }
11569       else
11570         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11571         {
11572           is_ipv6 = 1;
11573           is_ip_any = 0;
11574         }
11575       else
11576         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11577         {
11578           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11579             {
11580               clib_warning ("unsupported action: 'resolve'");
11581               return -99;
11582             }
11583         }
11584       else
11585         {
11586           clib_warning ("parse error '%U'", format_unformat_error, i);
11587           return -99;
11588         }
11589
11590     }
11591
11592   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11593
11594   mp->spd_id = ntohl (spd_id);
11595   mp->priority = ntohl (priority);
11596   mp->is_outbound = is_outbound;
11597
11598   mp->is_ipv6 = is_ipv6;
11599   if (is_ipv6 || is_ip_any)
11600     {
11601       clib_memcpy (mp->remote_address_start, &raddr6_start,
11602                    sizeof (ip6_address_t));
11603       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11604                    sizeof (ip6_address_t));
11605       clib_memcpy (mp->local_address_start, &laddr6_start,
11606                    sizeof (ip6_address_t));
11607       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11608                    sizeof (ip6_address_t));
11609     }
11610   else
11611     {
11612       clib_memcpy (mp->remote_address_start, &raddr4_start,
11613                    sizeof (ip4_address_t));
11614       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11615                    sizeof (ip4_address_t));
11616       clib_memcpy (mp->local_address_start, &laddr4_start,
11617                    sizeof (ip4_address_t));
11618       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11619                    sizeof (ip4_address_t));
11620     }
11621   mp->protocol = (u8) protocol;
11622   mp->local_port_start = ntohs ((u16) lport_start);
11623   mp->local_port_stop = ntohs ((u16) lport_stop);
11624   mp->remote_port_start = ntohs ((u16) rport_start);
11625   mp->remote_port_stop = ntohs ((u16) rport_stop);
11626   mp->policy = (u8) policy;
11627   mp->sa_id = ntohl (sa_id);
11628   mp->is_add = is_add;
11629   mp->is_ip_any = is_ip_any;
11630   S;
11631   W;
11632   /* NOTREACHED */
11633   return 0;
11634 #else
11635   clib_warning ("unsupported (no dpdk)");
11636   return -99;
11637 #endif
11638 }
11639
11640 static int
11641 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11642 {
11643 #if DPDK > 0
11644   unformat_input_t *i = vam->input;
11645   vl_api_ipsec_sad_add_del_entry_t *mp;
11646   f64 timeout;
11647   u32 sad_id = 0, spi = 0;
11648   u8 *ck = 0, *ik = 0;
11649   u8 is_add = 1;
11650
11651   u8 protocol = IPSEC_PROTOCOL_AH;
11652   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11653   u32 crypto_alg = 0, integ_alg = 0;
11654   ip4_address_t tun_src4;
11655   ip4_address_t tun_dst4;
11656   ip6_address_t tun_src6;
11657   ip6_address_t tun_dst6;
11658
11659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11660     {
11661       if (unformat (i, "del"))
11662         is_add = 0;
11663       else if (unformat (i, "sad_id %d", &sad_id))
11664         ;
11665       else if (unformat (i, "spi %d", &spi))
11666         ;
11667       else if (unformat (i, "esp"))
11668         protocol = IPSEC_PROTOCOL_ESP;
11669       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11670         {
11671           is_tunnel = 1;
11672           is_tunnel_ipv6 = 0;
11673         }
11674       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11675         {
11676           is_tunnel = 1;
11677           is_tunnel_ipv6 = 0;
11678         }
11679       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11680         {
11681           is_tunnel = 1;
11682           is_tunnel_ipv6 = 1;
11683         }
11684       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11685         {
11686           is_tunnel = 1;
11687           is_tunnel_ipv6 = 1;
11688         }
11689       else
11690         if (unformat
11691             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11692         {
11693           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11694               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11695             {
11696               clib_warning ("unsupported crypto-alg: '%U'",
11697                             format_ipsec_crypto_alg, crypto_alg);
11698               return -99;
11699             }
11700         }
11701       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11702         ;
11703       else
11704         if (unformat
11705             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11706         {
11707           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11708               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11709             {
11710               clib_warning ("unsupported integ-alg: '%U'",
11711                             format_ipsec_integ_alg, integ_alg);
11712               return -99;
11713             }
11714         }
11715       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11716         ;
11717       else
11718         {
11719           clib_warning ("parse error '%U'", format_unformat_error, i);
11720           return -99;
11721         }
11722
11723     }
11724
11725   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11726
11727   mp->sad_id = ntohl (sad_id);
11728   mp->is_add = is_add;
11729   mp->protocol = protocol;
11730   mp->spi = ntohl (spi);
11731   mp->is_tunnel = is_tunnel;
11732   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11733   mp->crypto_algorithm = crypto_alg;
11734   mp->integrity_algorithm = integ_alg;
11735   mp->crypto_key_length = vec_len (ck);
11736   mp->integrity_key_length = vec_len (ik);
11737
11738   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11739     mp->crypto_key_length = sizeof (mp->crypto_key);
11740
11741   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11742     mp->integrity_key_length = sizeof (mp->integrity_key);
11743
11744   if (ck)
11745     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11746   if (ik)
11747     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11748
11749   if (is_tunnel)
11750     {
11751       if (is_tunnel_ipv6)
11752         {
11753           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11754                        sizeof (ip6_address_t));
11755           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11756                        sizeof (ip6_address_t));
11757         }
11758       else
11759         {
11760           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11761                        sizeof (ip4_address_t));
11762           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11763                        sizeof (ip4_address_t));
11764         }
11765     }
11766
11767   S;
11768   W;
11769   /* NOTREACHED */
11770   return 0;
11771 #else
11772   clib_warning ("unsupported (no dpdk)");
11773   return -99;
11774 #endif
11775 }
11776
11777 static int
11778 api_ipsec_sa_set_key (vat_main_t * vam)
11779 {
11780 #if DPDK > 0
11781   unformat_input_t *i = vam->input;
11782   vl_api_ipsec_sa_set_key_t *mp;
11783   f64 timeout;
11784   u32 sa_id;
11785   u8 *ck = 0, *ik = 0;
11786
11787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11788     {
11789       if (unformat (i, "sa_id %d", &sa_id))
11790         ;
11791       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11792         ;
11793       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11794         ;
11795       else
11796         {
11797           clib_warning ("parse error '%U'", format_unformat_error, i);
11798           return -99;
11799         }
11800     }
11801
11802   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11803
11804   mp->sa_id = ntohl (sa_id);
11805   mp->crypto_key_length = vec_len (ck);
11806   mp->integrity_key_length = vec_len (ik);
11807
11808   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11809     mp->crypto_key_length = sizeof (mp->crypto_key);
11810
11811   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11812     mp->integrity_key_length = sizeof (mp->integrity_key);
11813
11814   if (ck)
11815     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11816   if (ik)
11817     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11818
11819   S;
11820   W;
11821   /* NOTREACHED */
11822   return 0;
11823 #else
11824   clib_warning ("unsupported (no dpdk)");
11825   return -99;
11826 #endif
11827 }
11828
11829 static int
11830 api_ikev2_profile_add_del (vat_main_t * vam)
11831 {
11832 #if DPDK > 0
11833   unformat_input_t *i = vam->input;
11834   vl_api_ikev2_profile_add_del_t *mp;
11835   f64 timeout;
11836   u8 is_add = 1;
11837   u8 *name = 0;
11838
11839   const char *valid_chars = "a-zA-Z0-9_";
11840
11841   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11842     {
11843       if (unformat (i, "del"))
11844         is_add = 0;
11845       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11846         vec_add1 (name, 0);
11847       else
11848         {
11849           errmsg ("parse error '%U'", format_unformat_error, i);
11850           return -99;
11851         }
11852     }
11853
11854   if (!vec_len (name))
11855     {
11856       errmsg ("profile name must be specified");
11857       return -99;
11858     }
11859
11860   if (vec_len (name) > 64)
11861     {
11862       errmsg ("profile name too long");
11863       return -99;
11864     }
11865
11866   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11867
11868   clib_memcpy (mp->name, name, vec_len (name));
11869   mp->is_add = is_add;
11870   vec_free (name);
11871
11872   S;
11873   W;
11874   /* NOTREACHED */
11875   return 0;
11876 #else
11877   clib_warning ("unsupported (no dpdk)");
11878   return -99;
11879 #endif
11880 }
11881
11882 static int
11883 api_ikev2_profile_set_auth (vat_main_t * vam)
11884 {
11885 #if DPDK > 0
11886   unformat_input_t *i = vam->input;
11887   vl_api_ikev2_profile_set_auth_t *mp;
11888   f64 timeout;
11889   u8 *name = 0;
11890   u8 *data = 0;
11891   u32 auth_method = 0;
11892   u8 is_hex = 0;
11893
11894   const char *valid_chars = "a-zA-Z0-9_";
11895
11896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11897     {
11898       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11899         vec_add1 (name, 0);
11900       else if (unformat (i, "auth_method %U",
11901                          unformat_ikev2_auth_method, &auth_method))
11902         ;
11903       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11904         is_hex = 1;
11905       else if (unformat (i, "auth_data %v", &data))
11906         ;
11907       else
11908         {
11909           errmsg ("parse error '%U'", format_unformat_error, i);
11910           return -99;
11911         }
11912     }
11913
11914   if (!vec_len (name))
11915     {
11916       errmsg ("profile name must be specified");
11917       return -99;
11918     }
11919
11920   if (vec_len (name) > 64)
11921     {
11922       errmsg ("profile name too long");
11923       return -99;
11924     }
11925
11926   if (!vec_len (data))
11927     {
11928       errmsg ("auth_data must be specified");
11929       return -99;
11930     }
11931
11932   if (!auth_method)
11933     {
11934       errmsg ("auth_method must be specified");
11935       return -99;
11936     }
11937
11938   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11939
11940   mp->is_hex = is_hex;
11941   mp->auth_method = (u8) auth_method;
11942   mp->data_len = vec_len (data);
11943   clib_memcpy (mp->name, name, vec_len (name));
11944   clib_memcpy (mp->data, data, vec_len (data));
11945   vec_free (name);
11946   vec_free (data);
11947
11948   S;
11949   W;
11950   /* NOTREACHED */
11951   return 0;
11952 #else
11953   clib_warning ("unsupported (no dpdk)");
11954   return -99;
11955 #endif
11956 }
11957
11958 static int
11959 api_ikev2_profile_set_id (vat_main_t * vam)
11960 {
11961 #if DPDK > 0
11962   unformat_input_t *i = vam->input;
11963   vl_api_ikev2_profile_set_id_t *mp;
11964   f64 timeout;
11965   u8 *name = 0;
11966   u8 *data = 0;
11967   u8 is_local = 0;
11968   u32 id_type = 0;
11969   ip4_address_t ip4;
11970
11971   const char *valid_chars = "a-zA-Z0-9_";
11972
11973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11974     {
11975       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11976         vec_add1 (name, 0);
11977       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11978         ;
11979       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11980         {
11981           data = vec_new (u8, 4);
11982           clib_memcpy (data, ip4.as_u8, 4);
11983         }
11984       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11985         ;
11986       else if (unformat (i, "id_data %v", &data))
11987         ;
11988       else if (unformat (i, "local"))
11989         is_local = 1;
11990       else if (unformat (i, "remote"))
11991         is_local = 0;
11992       else
11993         {
11994           errmsg ("parse error '%U'", format_unformat_error, i);
11995           return -99;
11996         }
11997     }
11998
11999   if (!vec_len (name))
12000     {
12001       errmsg ("profile name must be specified");
12002       return -99;
12003     }
12004
12005   if (vec_len (name) > 64)
12006     {
12007       errmsg ("profile name too long");
12008       return -99;
12009     }
12010
12011   if (!vec_len (data))
12012     {
12013       errmsg ("id_data must be specified");
12014       return -99;
12015     }
12016
12017   if (!id_type)
12018     {
12019       errmsg ("id_type must be specified");
12020       return -99;
12021     }
12022
12023   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12024
12025   mp->is_local = is_local;
12026   mp->id_type = (u8) id_type;
12027   mp->data_len = vec_len (data);
12028   clib_memcpy (mp->name, name, vec_len (name));
12029   clib_memcpy (mp->data, data, vec_len (data));
12030   vec_free (name);
12031   vec_free (data);
12032
12033   S;
12034   W;
12035   /* NOTREACHED */
12036   return 0;
12037 #else
12038   clib_warning ("unsupported (no dpdk)");
12039   return -99;
12040 #endif
12041 }
12042
12043 static int
12044 api_ikev2_profile_set_ts (vat_main_t * vam)
12045 {
12046 #if DPDK > 0
12047   unformat_input_t *i = vam->input;
12048   vl_api_ikev2_profile_set_ts_t *mp;
12049   f64 timeout;
12050   u8 *name = 0;
12051   u8 is_local = 0;
12052   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12053   ip4_address_t start_addr, end_addr;
12054
12055   const char *valid_chars = "a-zA-Z0-9_";
12056
12057   start_addr.as_u32 = 0;
12058   end_addr.as_u32 = (u32) ~ 0;
12059
12060   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12061     {
12062       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12063         vec_add1 (name, 0);
12064       else if (unformat (i, "protocol %d", &proto))
12065         ;
12066       else if (unformat (i, "start_port %d", &start_port))
12067         ;
12068       else if (unformat (i, "end_port %d", &end_port))
12069         ;
12070       else
12071         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12072         ;
12073       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12074         ;
12075       else if (unformat (i, "local"))
12076         is_local = 1;
12077       else if (unformat (i, "remote"))
12078         is_local = 0;
12079       else
12080         {
12081           errmsg ("parse error '%U'", format_unformat_error, i);
12082           return -99;
12083         }
12084     }
12085
12086   if (!vec_len (name))
12087     {
12088       errmsg ("profile name must be specified");
12089       return -99;
12090     }
12091
12092   if (vec_len (name) > 64)
12093     {
12094       errmsg ("profile name too long");
12095       return -99;
12096     }
12097
12098   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12099
12100   mp->is_local = is_local;
12101   mp->proto = (u8) proto;
12102   mp->start_port = (u16) start_port;
12103   mp->end_port = (u16) end_port;
12104   mp->start_addr = start_addr.as_u32;
12105   mp->end_addr = end_addr.as_u32;
12106   clib_memcpy (mp->name, name, vec_len (name));
12107   vec_free (name);
12108
12109   S;
12110   W;
12111   /* NOTREACHED */
12112   return 0;
12113 #else
12114   clib_warning ("unsupported (no dpdk)");
12115   return -99;
12116 #endif
12117 }
12118
12119 static int
12120 api_ikev2_set_local_key (vat_main_t * vam)
12121 {
12122 #if DPDK > 0
12123   unformat_input_t *i = vam->input;
12124   vl_api_ikev2_set_local_key_t *mp;
12125   f64 timeout;
12126   u8 *file = 0;
12127
12128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12129     {
12130       if (unformat (i, "file %v", &file))
12131         vec_add1 (file, 0);
12132       else
12133         {
12134           errmsg ("parse error '%U'", format_unformat_error, i);
12135           return -99;
12136         }
12137     }
12138
12139   if (!vec_len (file))
12140     {
12141       errmsg ("RSA key file must be specified");
12142       return -99;
12143     }
12144
12145   if (vec_len (file) > 256)
12146     {
12147       errmsg ("file name too long");
12148       return -99;
12149     }
12150
12151   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12152
12153   clib_memcpy (mp->key_file, file, vec_len (file));
12154   vec_free (file);
12155
12156   S;
12157   W;
12158   /* NOTREACHED */
12159   return 0;
12160 #else
12161   clib_warning ("unsupported (no dpdk)");
12162   return -99;
12163 #endif
12164 }
12165
12166 /*
12167  * MAP
12168  */
12169 static int
12170 api_map_add_domain (vat_main_t * vam)
12171 {
12172   unformat_input_t *i = vam->input;
12173   vl_api_map_add_domain_t *mp;
12174   f64 timeout;
12175
12176   ip4_address_t ip4_prefix;
12177   ip6_address_t ip6_prefix;
12178   ip6_address_t ip6_src;
12179   u32 num_m_args = 0;
12180   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12181     0, psid_length = 0;
12182   u8 is_translation = 0;
12183   u32 mtu = 0;
12184   u32 ip6_src_len = 128;
12185
12186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12187     {
12188       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12189                     &ip4_prefix, &ip4_prefix_len))
12190         num_m_args++;
12191       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12192                          &ip6_prefix, &ip6_prefix_len))
12193         num_m_args++;
12194       else
12195         if (unformat
12196             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12197              &ip6_src_len))
12198         num_m_args++;
12199       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12200         num_m_args++;
12201       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12202         num_m_args++;
12203       else if (unformat (i, "psid-offset %d", &psid_offset))
12204         num_m_args++;
12205       else if (unformat (i, "psid-len %d", &psid_length))
12206         num_m_args++;
12207       else if (unformat (i, "mtu %d", &mtu))
12208         num_m_args++;
12209       else if (unformat (i, "map-t"))
12210         is_translation = 1;
12211       else
12212         {
12213           clib_warning ("parse error '%U'", format_unformat_error, i);
12214           return -99;
12215         }
12216     }
12217
12218   if (num_m_args < 3)
12219     {
12220       errmsg ("mandatory argument(s) missing\n");
12221       return -99;
12222     }
12223
12224   /* Construct the API message */
12225   M (MAP_ADD_DOMAIN, map_add_domain);
12226
12227   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12228   mp->ip4_prefix_len = ip4_prefix_len;
12229
12230   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12231   mp->ip6_prefix_len = ip6_prefix_len;
12232
12233   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12234   mp->ip6_src_prefix_len = ip6_src_len;
12235
12236   mp->ea_bits_len = ea_bits_len;
12237   mp->psid_offset = psid_offset;
12238   mp->psid_length = psid_length;
12239   mp->is_translation = is_translation;
12240   mp->mtu = htons (mtu);
12241
12242   /* send it... */
12243   S;
12244
12245   /* Wait for a reply, return good/bad news  */
12246   W;
12247 }
12248
12249 static int
12250 api_map_del_domain (vat_main_t * vam)
12251 {
12252   unformat_input_t *i = vam->input;
12253   vl_api_map_del_domain_t *mp;
12254   f64 timeout;
12255
12256   u32 num_m_args = 0;
12257   u32 index;
12258
12259   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12260     {
12261       if (unformat (i, "index %d", &index))
12262         num_m_args++;
12263       else
12264         {
12265           clib_warning ("parse error '%U'", format_unformat_error, i);
12266           return -99;
12267         }
12268     }
12269
12270   if (num_m_args != 1)
12271     {
12272       errmsg ("mandatory argument(s) missing\n");
12273       return -99;
12274     }
12275
12276   /* Construct the API message */
12277   M (MAP_DEL_DOMAIN, map_del_domain);
12278
12279   mp->index = ntohl (index);
12280
12281   /* send it... */
12282   S;
12283
12284   /* Wait for a reply, return good/bad news  */
12285   W;
12286 }
12287
12288 static int
12289 api_map_add_del_rule (vat_main_t * vam)
12290 {
12291   unformat_input_t *i = vam->input;
12292   vl_api_map_add_del_rule_t *mp;
12293   f64 timeout;
12294   u8 is_add = 1;
12295   ip6_address_t ip6_dst;
12296   u32 num_m_args = 0, index, psid = 0;
12297
12298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12299     {
12300       if (unformat (i, "index %d", &index))
12301         num_m_args++;
12302       else if (unformat (i, "psid %d", &psid))
12303         num_m_args++;
12304       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12305         num_m_args++;
12306       else if (unformat (i, "del"))
12307         {
12308           is_add = 0;
12309         }
12310       else
12311         {
12312           clib_warning ("parse error '%U'", format_unformat_error, i);
12313           return -99;
12314         }
12315     }
12316
12317   /* Construct the API message */
12318   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12319
12320   mp->index = ntohl (index);
12321   mp->is_add = is_add;
12322   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12323   mp->psid = ntohs (psid);
12324
12325   /* send it... */
12326   S;
12327
12328   /* Wait for a reply, return good/bad news  */
12329   W;
12330 }
12331
12332 static int
12333 api_map_domain_dump (vat_main_t * vam)
12334 {
12335   vl_api_map_domain_dump_t *mp;
12336   f64 timeout;
12337
12338   /* Construct the API message */
12339   M (MAP_DOMAIN_DUMP, map_domain_dump);
12340
12341   /* send it... */
12342   S;
12343
12344   /* Use a control ping for synchronization */
12345   {
12346     vl_api_control_ping_t *mp;
12347     M (CONTROL_PING, control_ping);
12348     S;
12349   }
12350   W;
12351 }
12352
12353 static int
12354 api_map_rule_dump (vat_main_t * vam)
12355 {
12356   unformat_input_t *i = vam->input;
12357   vl_api_map_rule_dump_t *mp;
12358   f64 timeout;
12359   u32 domain_index = ~0;
12360
12361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12362     {
12363       if (unformat (i, "index %u", &domain_index))
12364         ;
12365       else
12366         break;
12367     }
12368
12369   if (domain_index == ~0)
12370     {
12371       clib_warning ("parse error: domain index expected");
12372       return -99;
12373     }
12374
12375   /* Construct the API message */
12376   M (MAP_RULE_DUMP, map_rule_dump);
12377
12378   mp->domain_index = htonl (domain_index);
12379
12380   /* send it... */
12381   S;
12382
12383   /* Use a control ping for synchronization */
12384   {
12385     vl_api_control_ping_t *mp;
12386     M (CONTROL_PING, control_ping);
12387     S;
12388   }
12389   W;
12390 }
12391
12392 static void vl_api_map_add_domain_reply_t_handler
12393   (vl_api_map_add_domain_reply_t * mp)
12394 {
12395   vat_main_t *vam = &vat_main;
12396   i32 retval = ntohl (mp->retval);
12397
12398   if (vam->async_mode)
12399     {
12400       vam->async_errors += (retval < 0);
12401     }
12402   else
12403     {
12404       vam->retval = retval;
12405       vam->result_ready = 1;
12406     }
12407 }
12408
12409 static void vl_api_map_add_domain_reply_t_handler_json
12410   (vl_api_map_add_domain_reply_t * mp)
12411 {
12412   vat_main_t *vam = &vat_main;
12413   vat_json_node_t node;
12414
12415   vat_json_init_object (&node);
12416   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12417   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12418
12419   vat_json_print (vam->ofp, &node);
12420   vat_json_free (&node);
12421
12422   vam->retval = ntohl (mp->retval);
12423   vam->result_ready = 1;
12424 }
12425
12426 static int
12427 api_get_first_msg_id (vat_main_t * vam)
12428 {
12429   vl_api_get_first_msg_id_t *mp;
12430   f64 timeout;
12431   unformat_input_t *i = vam->input;
12432   u8 *name;
12433   u8 name_set = 0;
12434
12435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12436     {
12437       if (unformat (i, "client %s", &name))
12438         name_set = 1;
12439       else
12440         break;
12441     }
12442
12443   if (name_set == 0)
12444     {
12445       errmsg ("missing client name\n");
12446       return -99;
12447     }
12448   vec_add1 (name, 0);
12449
12450   if (vec_len (name) > 63)
12451     {
12452       errmsg ("client name too long\n");
12453       return -99;
12454     }
12455
12456   M (GET_FIRST_MSG_ID, get_first_msg_id);
12457   clib_memcpy (mp->name, name, vec_len (name));
12458   S;
12459   W;
12460   /* NOTREACHED */
12461   return 0;
12462 }
12463
12464 static int
12465 api_cop_interface_enable_disable (vat_main_t * vam)
12466 {
12467   unformat_input_t *line_input = vam->input;
12468   vl_api_cop_interface_enable_disable_t *mp;
12469   f64 timeout;
12470   u32 sw_if_index = ~0;
12471   u8 enable_disable = 1;
12472
12473   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12474     {
12475       if (unformat (line_input, "disable"))
12476         enable_disable = 0;
12477       if (unformat (line_input, "enable"))
12478         enable_disable = 1;
12479       else if (unformat (line_input, "%U", unformat_sw_if_index,
12480                          vam, &sw_if_index))
12481         ;
12482       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12483         ;
12484       else
12485         break;
12486     }
12487
12488   if (sw_if_index == ~0)
12489     {
12490       errmsg ("missing interface name or sw_if_index\n");
12491       return -99;
12492     }
12493
12494   /* Construct the API message */
12495   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12496   mp->sw_if_index = ntohl (sw_if_index);
12497   mp->enable_disable = enable_disable;
12498
12499   /* send it... */
12500   S;
12501   /* Wait for the reply */
12502   W;
12503 }
12504
12505 static int
12506 api_cop_whitelist_enable_disable (vat_main_t * vam)
12507 {
12508   unformat_input_t *line_input = vam->input;
12509   vl_api_cop_whitelist_enable_disable_t *mp;
12510   f64 timeout;
12511   u32 sw_if_index = ~0;
12512   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12513   u32 fib_id = 0;
12514
12515   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12516     {
12517       if (unformat (line_input, "ip4"))
12518         ip4 = 1;
12519       else if (unformat (line_input, "ip6"))
12520         ip6 = 1;
12521       else if (unformat (line_input, "default"))
12522         default_cop = 1;
12523       else if (unformat (line_input, "%U", unformat_sw_if_index,
12524                          vam, &sw_if_index))
12525         ;
12526       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12527         ;
12528       else if (unformat (line_input, "fib-id %d", &fib_id))
12529         ;
12530       else
12531         break;
12532     }
12533
12534   if (sw_if_index == ~0)
12535     {
12536       errmsg ("missing interface name or sw_if_index\n");
12537       return -99;
12538     }
12539
12540   /* Construct the API message */
12541   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12542   mp->sw_if_index = ntohl (sw_if_index);
12543   mp->fib_id = ntohl (fib_id);
12544   mp->ip4 = ip4;
12545   mp->ip6 = ip6;
12546   mp->default_cop = default_cop;
12547
12548   /* send it... */
12549   S;
12550   /* Wait for the reply */
12551   W;
12552 }
12553
12554 static int
12555 api_get_node_graph (vat_main_t * vam)
12556 {
12557   vl_api_get_node_graph_t *mp;
12558   f64 timeout;
12559
12560   M (GET_NODE_GRAPH, get_node_graph);
12561
12562   /* send it... */
12563   S;
12564   /* Wait for the reply */
12565   W;
12566 }
12567
12568 /* *INDENT-OFF* */
12569 /** Used for parsing LISP eids */
12570 typedef CLIB_PACKED(struct{
12571   u8 addr[16];   /**< eid address */
12572   u32 len;       /**< prefix length if IP */
12573   u8 type;      /**< type of eid */
12574 }) lisp_eid_vat_t;
12575 /* *INDENT-ON* */
12576
12577 static uword
12578 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12579 {
12580   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12581
12582   memset (a, 0, sizeof (a[0]));
12583
12584   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12585     {
12586       a->type = 0;              /* ipv4 type */
12587     }
12588   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12589     {
12590       a->type = 1;              /* ipv6 type */
12591     }
12592   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12593     {
12594       a->type = 2;              /* mac type */
12595     }
12596   else
12597     {
12598       return 0;
12599     }
12600
12601   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12602     {
12603       return 0;
12604     }
12605
12606   return 1;
12607 }
12608
12609 static int
12610 lisp_eid_size_vat (u8 type)
12611 {
12612   switch (type)
12613     {
12614     case 0:
12615       return 4;
12616     case 1:
12617       return 16;
12618     case 2:
12619       return 6;
12620     }
12621   return 0;
12622 }
12623
12624 static void
12625 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12626 {
12627   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12628 }
12629
12630 /* *INDENT-OFF* */
12631 /** Used for transferring locators via VPP API */
12632 typedef CLIB_PACKED(struct
12633 {
12634   u32 sw_if_index; /**< locator sw_if_index */
12635   u8 priority; /**< locator priority */
12636   u8 weight;   /**< locator weight */
12637 }) ls_locator_t;
12638 /* *INDENT-ON* */
12639
12640 static int
12641 api_lisp_add_del_locator_set (vat_main_t * vam)
12642 {
12643   unformat_input_t *input = vam->input;
12644   vl_api_lisp_add_del_locator_set_t *mp;
12645   f64 timeout = ~0;
12646   u8 is_add = 1;
12647   u8 *locator_set_name = NULL;
12648   u8 locator_set_name_set = 0;
12649   ls_locator_t locator, *locators = 0;
12650   u32 sw_if_index, priority, weight;
12651   u32 data_len = 0;
12652
12653   /* Parse args required to build the message */
12654   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12655     {
12656       if (unformat (input, "del"))
12657         {
12658           is_add = 0;
12659         }
12660       else if (unformat (input, "locator-set %s", &locator_set_name))
12661         {
12662           locator_set_name_set = 1;
12663         }
12664       else if (unformat (input, "sw_if_index %u p %u w %u",
12665                          &sw_if_index, &priority, &weight))
12666         {
12667           locator.sw_if_index = htonl (sw_if_index);
12668           locator.priority = priority;
12669           locator.weight = weight;
12670           vec_add1 (locators, locator);
12671         }
12672       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12673                          vam, &sw_if_index, &priority, &weight))
12674         {
12675           locator.sw_if_index = htonl (sw_if_index);
12676           locator.priority = priority;
12677           locator.weight = weight;
12678           vec_add1 (locators, locator);
12679         }
12680       else
12681         break;
12682     }
12683
12684   if (locator_set_name_set == 0)
12685     {
12686       errmsg ("missing locator-set name");
12687       vec_free (locators);
12688       return -99;
12689     }
12690
12691   if (vec_len (locator_set_name) > 64)
12692     {
12693       errmsg ("locator-set name too long\n");
12694       vec_free (locator_set_name);
12695       vec_free (locators);
12696       return -99;
12697     }
12698   vec_add1 (locator_set_name, 0);
12699
12700   data_len = sizeof (ls_locator_t) * vec_len (locators);
12701
12702   /* Construct the API message */
12703   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12704
12705   mp->is_add = is_add;
12706   clib_memcpy (mp->locator_set_name, locator_set_name,
12707                vec_len (locator_set_name));
12708   vec_free (locator_set_name);
12709
12710   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12711   if (locators)
12712     clib_memcpy (mp->locators, locators, data_len);
12713   vec_free (locators);
12714
12715   /* send it... */
12716   S;
12717
12718   /* Wait for a reply... */
12719   W;
12720
12721   /* NOTREACHED */
12722   return 0;
12723 }
12724
12725 static int
12726 api_lisp_add_del_locator (vat_main_t * vam)
12727 {
12728   unformat_input_t *input = vam->input;
12729   vl_api_lisp_add_del_locator_t *mp;
12730   f64 timeout = ~0;
12731   u32 tmp_if_index = ~0;
12732   u32 sw_if_index = ~0;
12733   u8 sw_if_index_set = 0;
12734   u8 sw_if_index_if_name_set = 0;
12735   u32 priority = ~0;
12736   u8 priority_set = 0;
12737   u32 weight = ~0;
12738   u8 weight_set = 0;
12739   u8 is_add = 1;
12740   u8 *locator_set_name = NULL;
12741   u8 locator_set_name_set = 0;
12742
12743   /* Parse args required to build the message */
12744   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12745     {
12746       if (unformat (input, "del"))
12747         {
12748           is_add = 0;
12749         }
12750       else if (unformat (input, "locator-set %s", &locator_set_name))
12751         {
12752           locator_set_name_set = 1;
12753         }
12754       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12755                          &tmp_if_index))
12756         {
12757           sw_if_index_if_name_set = 1;
12758           sw_if_index = tmp_if_index;
12759         }
12760       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12761         {
12762           sw_if_index_set = 1;
12763           sw_if_index = tmp_if_index;
12764         }
12765       else if (unformat (input, "p %d", &priority))
12766         {
12767           priority_set = 1;
12768         }
12769       else if (unformat (input, "w %d", &weight))
12770         {
12771           weight_set = 1;
12772         }
12773       else
12774         break;
12775     }
12776
12777   if (locator_set_name_set == 0)
12778     {
12779       errmsg ("missing locator-set name");
12780       return -99;
12781     }
12782
12783   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12784     {
12785       errmsg ("missing sw_if_index");
12786       vec_free (locator_set_name);
12787       return -99;
12788     }
12789
12790   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12791     {
12792       errmsg ("cannot use both params interface name and sw_if_index");
12793       vec_free (locator_set_name);
12794       return -99;
12795     }
12796
12797   if (priority_set == 0)
12798     {
12799       errmsg ("missing locator-set priority\n");
12800       vec_free (locator_set_name);
12801       return -99;
12802     }
12803
12804   if (weight_set == 0)
12805     {
12806       errmsg ("missing locator-set weight\n");
12807       vec_free (locator_set_name);
12808       return -99;
12809     }
12810
12811   if (vec_len (locator_set_name) > 64)
12812     {
12813       errmsg ("locator-set name too long\n");
12814       vec_free (locator_set_name);
12815       return -99;
12816     }
12817   vec_add1 (locator_set_name, 0);
12818
12819   /* Construct the API message */
12820   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12821
12822   mp->is_add = is_add;
12823   mp->sw_if_index = ntohl (sw_if_index);
12824   mp->priority = priority;
12825   mp->weight = weight;
12826   clib_memcpy (mp->locator_set_name, locator_set_name,
12827                vec_len (locator_set_name));
12828   vec_free (locator_set_name);
12829
12830   /* send it... */
12831   S;
12832
12833   /* Wait for a reply... */
12834   W;
12835
12836   /* NOTREACHED */
12837   return 0;
12838 }
12839
12840 static int
12841 api_lisp_add_del_local_eid (vat_main_t * vam)
12842 {
12843   unformat_input_t *input = vam->input;
12844   vl_api_lisp_add_del_local_eid_t *mp;
12845   f64 timeout = ~0;
12846   u8 is_add = 1;
12847   u8 eid_set = 0;
12848   lisp_eid_vat_t _eid, *eid = &_eid;
12849   u8 *locator_set_name = 0;
12850   u8 locator_set_name_set = 0;
12851   u32 vni = 0;
12852
12853   /* Parse args required to build the message */
12854   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12855     {
12856       if (unformat (input, "del"))
12857         {
12858           is_add = 0;
12859         }
12860       else if (unformat (input, "vni %d", &vni))
12861         {
12862           ;
12863         }
12864       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12865         {
12866           eid_set = 1;
12867         }
12868       else if (unformat (input, "locator-set %s", &locator_set_name))
12869         {
12870           locator_set_name_set = 1;
12871         }
12872       else
12873         break;
12874     }
12875
12876   if (locator_set_name_set == 0)
12877     {
12878       errmsg ("missing locator-set name\n");
12879       return -99;
12880     }
12881
12882   if (0 == eid_set)
12883     {
12884       errmsg ("EID address not set!");
12885       vec_free (locator_set_name);
12886       return -99;
12887     }
12888
12889   if (vec_len (locator_set_name) > 64)
12890     {
12891       errmsg ("locator-set name too long\n");
12892       vec_free (locator_set_name);
12893       return -99;
12894     }
12895   vec_add1 (locator_set_name, 0);
12896
12897   /* Construct the API message */
12898   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12899
12900   mp->is_add = is_add;
12901   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12902   mp->eid_type = eid->type;
12903   mp->prefix_len = eid->len;
12904   mp->vni = clib_host_to_net_u32 (vni);
12905   clib_memcpy (mp->locator_set_name, locator_set_name,
12906                vec_len (locator_set_name));
12907
12908   vec_free (locator_set_name);
12909
12910   /* send it... */
12911   S;
12912
12913   /* Wait for a reply... */
12914   W;
12915
12916   /* NOTREACHED */
12917   return 0;
12918 }
12919
12920 /* *INDENT-OFF* */
12921 /** Used for transferring locators via VPP API */
12922 typedef CLIB_PACKED(struct
12923 {
12924   u8 is_ip4; /**< is locator an IPv4 address? */
12925   u8 priority; /**< locator priority */
12926   u8 weight;   /**< locator weight */
12927   u8 addr[16]; /**< IPv4/IPv6 address */
12928 }) rloc_t;
12929 /* *INDENT-ON* */
12930
12931 static int
12932 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12933 {
12934   unformat_input_t *input = vam->input;
12935   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12936   f64 timeout = ~0;
12937   u8 is_add = 1;
12938   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12939   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12940   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12941   u32 action = ~0, p, w;
12942   ip4_address_t rmt_rloc4, lcl_rloc4;
12943   ip6_address_t rmt_rloc6, lcl_rloc6;
12944   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12945
12946   memset (&rloc, 0, sizeof (rloc));
12947
12948   /* Parse args required to build the message */
12949   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12950     {
12951       if (unformat (input, "del"))
12952         {
12953           is_add = 0;
12954         }
12955       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12956         {
12957           rmt_eid_set = 1;
12958         }
12959       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12960         {
12961           lcl_eid_set = 1;
12962         }
12963       else if (unformat (input, "p %d w %d", &p, &w))
12964         {
12965           if (!curr_rloc)
12966             {
12967               errmsg ("No RLOC configured for setting priority/weight!");
12968               return -99;
12969             }
12970           curr_rloc->priority = p;
12971           curr_rloc->weight = w;
12972         }
12973       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12974                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12975         {
12976           rloc.is_ip4 = 1;
12977
12978           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12979           rloc.priority = rloc.weight = 0;
12980           vec_add1 (lcl_locs, rloc);
12981
12982           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12983           vec_add1 (rmt_locs, rloc);
12984           /* priority and weight saved in rmt loc */
12985           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12986         }
12987       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12988                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12989         {
12990           rloc.is_ip4 = 0;
12991           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12992           rloc.priority = rloc.weight = 0;
12993           vec_add1 (lcl_locs, rloc);
12994
12995           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12996           vec_add1 (rmt_locs, rloc);
12997           /* priority and weight saved in rmt loc */
12998           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12999         }
13000       else if (unformat (input, "action %d", &action))
13001         {
13002           ;
13003         }
13004       else
13005         {
13006           clib_warning ("parse error '%U'", format_unformat_error, input);
13007           return -99;
13008         }
13009     }
13010
13011   if (!rmt_eid_set)
13012     {
13013       errmsg ("remote eid addresses not set\n");
13014       return -99;
13015     }
13016
13017   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13018     {
13019       errmsg ("eid types don't match\n");
13020       return -99;
13021     }
13022
13023   if (0 == rmt_locs && (u32) ~ 0 == action)
13024     {
13025       errmsg ("action not set for negative mapping\n");
13026       return -99;
13027     }
13028
13029   /* Construct the API message */
13030   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13031
13032   mp->is_add = is_add;
13033   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13034   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13035   mp->eid_type = rmt_eid->type;
13036   mp->rmt_len = rmt_eid->len;
13037   mp->lcl_len = lcl_eid->len;
13038   mp->action = action;
13039
13040   if (0 != rmt_locs && 0 != lcl_locs)
13041     {
13042       mp->loc_num = vec_len (rmt_locs);
13043       clib_memcpy (mp->lcl_locs, lcl_locs,
13044                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13045       clib_memcpy (mp->rmt_locs, rmt_locs,
13046                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13047     }
13048   vec_free (lcl_locs);
13049   vec_free (rmt_locs);
13050
13051   /* send it... */
13052   S;
13053
13054   /* Wait for a reply... */
13055   W;
13056
13057   /* NOTREACHED */
13058   return 0;
13059 }
13060
13061 static int
13062 api_lisp_add_del_map_resolver (vat_main_t * vam)
13063 {
13064   unformat_input_t *input = vam->input;
13065   vl_api_lisp_add_del_map_resolver_t *mp;
13066   f64 timeout = ~0;
13067   u8 is_add = 1;
13068   u8 ipv4_set = 0;
13069   u8 ipv6_set = 0;
13070   ip4_address_t ipv4;
13071   ip6_address_t ipv6;
13072
13073   /* Parse args required to build the message */
13074   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13075     {
13076       if (unformat (input, "del"))
13077         {
13078           is_add = 0;
13079         }
13080       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13081         {
13082           ipv4_set = 1;
13083         }
13084       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13085         {
13086           ipv6_set = 1;
13087         }
13088       else
13089         break;
13090     }
13091
13092   if (ipv4_set && ipv6_set)
13093     {
13094       errmsg ("both eid v4 and v6 addresses set\n");
13095       return -99;
13096     }
13097
13098   if (!ipv4_set && !ipv6_set)
13099     {
13100       errmsg ("eid addresses not set\n");
13101       return -99;
13102     }
13103
13104   /* Construct the API message */
13105   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13106
13107   mp->is_add = is_add;
13108   if (ipv6_set)
13109     {
13110       mp->is_ipv6 = 1;
13111       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13112     }
13113   else
13114     {
13115       mp->is_ipv6 = 0;
13116       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13117     }
13118
13119   /* send it... */
13120   S;
13121
13122   /* Wait for a reply... */
13123   W;
13124
13125   /* NOTREACHED */
13126   return 0;
13127 }
13128
13129 static int
13130 api_lisp_gpe_enable_disable (vat_main_t * vam)
13131 {
13132   unformat_input_t *input = vam->input;
13133   vl_api_lisp_gpe_enable_disable_t *mp;
13134   f64 timeout = ~0;
13135   u8 is_set = 0;
13136   u8 is_en = 1;
13137
13138   /* Parse args required to build the message */
13139   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13140     {
13141       if (unformat (input, "enable"))
13142         {
13143           is_set = 1;
13144           is_en = 1;
13145         }
13146       else if (unformat (input, "disable"))
13147         {
13148           is_set = 1;
13149           is_en = 0;
13150         }
13151       else
13152         break;
13153     }
13154
13155   if (is_set == 0)
13156     {
13157       errmsg ("Value not set\n");
13158       return -99;
13159     }
13160
13161   /* Construct the API message */
13162   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13163
13164   mp->is_en = is_en;
13165
13166   /* send it... */
13167   S;
13168
13169   /* Wait for a reply... */
13170   W;
13171
13172   /* NOTREACHED */
13173   return 0;
13174 }
13175
13176 static int
13177 api_lisp_enable_disable (vat_main_t * vam)
13178 {
13179   unformat_input_t *input = vam->input;
13180   vl_api_lisp_enable_disable_t *mp;
13181   f64 timeout = ~0;
13182   u8 is_set = 0;
13183   u8 is_en = 0;
13184
13185   /* Parse args required to build the message */
13186   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13187     {
13188       if (unformat (input, "enable"))
13189         {
13190           is_set = 1;
13191           is_en = 1;
13192         }
13193       else if (unformat (input, "disable"))
13194         {
13195           is_set = 1;
13196         }
13197       else
13198         break;
13199     }
13200
13201   if (!is_set)
13202     {
13203       errmsg ("Value not set\n");
13204       return -99;
13205     }
13206
13207   /* Construct the API message */
13208   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13209
13210   mp->is_en = is_en;
13211
13212   /* send it... */
13213   S;
13214
13215   /* Wait for a reply... */
13216   W;
13217
13218   /* NOTREACHED */
13219   return 0;
13220 }
13221
13222 static int
13223 api_show_lisp_map_request_mode (vat_main_t * vam)
13224 {
13225   f64 timeout = ~0;
13226   vl_api_show_lisp_map_request_mode_t *mp;
13227
13228   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13229
13230   /* send */
13231   S;
13232
13233   /* wait for reply */
13234   W;
13235
13236   return 0;
13237 }
13238
13239 static int
13240 api_lisp_map_request_mode (vat_main_t * vam)
13241 {
13242   f64 timeout = ~0;
13243   unformat_input_t *input = vam->input;
13244   vl_api_lisp_map_request_mode_t *mp;
13245   u8 mode = 0;
13246
13247   /* Parse args required to build the message */
13248   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13249     {
13250       if (unformat (input, "dst-only"))
13251         mode = 0;
13252       else if (unformat (input, "src-dst"))
13253         mode = 1;
13254       else
13255         {
13256           errmsg ("parse error '%U'", format_unformat_error, input);
13257           return -99;
13258         }
13259     }
13260
13261   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13262
13263   mp->mode = mode;
13264
13265   /* send */
13266   S;
13267
13268   /* wait for reply */
13269   W;
13270
13271   /* notreached */
13272   return 0;
13273 }
13274
13275 /**
13276  * Enable/disable LISP proxy ITR.
13277  *
13278  * @param vam vpp API test context
13279  * @return return code
13280  */
13281 static int
13282 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13283 {
13284   f64 timeout = ~0;
13285   u8 ls_name_set = 0;
13286   unformat_input_t *input = vam->input;
13287   vl_api_lisp_pitr_set_locator_set_t *mp;
13288   u8 is_add = 1;
13289   u8 *ls_name = 0;
13290
13291   /* Parse args required to build the message */
13292   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13293     {
13294       if (unformat (input, "del"))
13295         is_add = 0;
13296       else if (unformat (input, "locator-set %s", &ls_name))
13297         ls_name_set = 1;
13298       else
13299         {
13300           errmsg ("parse error '%U'", format_unformat_error, input);
13301           return -99;
13302         }
13303     }
13304
13305   if (!ls_name_set)
13306     {
13307       errmsg ("locator-set name not set!");
13308       return -99;
13309     }
13310
13311   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13312
13313   mp->is_add = is_add;
13314   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13315   vec_free (ls_name);
13316
13317   /* send */
13318   S;
13319
13320   /* wait for reply */
13321   W;
13322
13323   /* notreached */
13324   return 0;
13325 }
13326
13327 static int
13328 api_show_lisp_pitr (vat_main_t * vam)
13329 {
13330   vl_api_show_lisp_pitr_t *mp;
13331   f64 timeout = ~0;
13332
13333   if (!vam->json_output)
13334     {
13335       fformat (vam->ofp, "%=20s\n", "lisp status:");
13336     }
13337
13338   M (SHOW_LISP_PITR, show_lisp_pitr);
13339   /* send it... */
13340   S;
13341
13342   /* Wait for a reply... */
13343   W;
13344
13345   /* NOTREACHED */
13346   return 0;
13347 }
13348
13349 /**
13350  * Add/delete mapping between vni and vrf
13351  */
13352 static int
13353 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13354 {
13355   f64 timeout = ~0;
13356   unformat_input_t *input = vam->input;
13357   vl_api_lisp_eid_table_add_del_map_t *mp;
13358   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13359   u32 vni, vrf, bd_index;
13360
13361   /* Parse args required to build the message */
13362   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13363     {
13364       if (unformat (input, "del"))
13365         is_add = 0;
13366       else if (unformat (input, "vrf %d", &vrf))
13367         vrf_set = 1;
13368       else if (unformat (input, "bd_index %d", &bd_index))
13369         bd_index_set = 1;
13370       else if (unformat (input, "vni %d", &vni))
13371         vni_set = 1;
13372       else
13373         break;
13374     }
13375
13376   if (!vni_set || (!vrf_set && !bd_index_set))
13377     {
13378       errmsg ("missing arguments!");
13379       return -99;
13380     }
13381
13382   if (vrf_set && bd_index_set)
13383     {
13384       errmsg ("error: both vrf and bd entered!");
13385       return -99;
13386     }
13387
13388   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13389
13390   mp->is_add = is_add;
13391   mp->vni = htonl (vni);
13392   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13393   mp->is_l2 = bd_index_set;
13394
13395   /* send */
13396   S;
13397
13398   /* wait for reply */
13399   W;
13400
13401   /* notreached */
13402   return 0;
13403 }
13404
13405 uword
13406 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13407 {
13408   u32 *action = va_arg (*args, u32 *);
13409   u8 *s = 0;
13410
13411   if (unformat (input, "%s", &s))
13412     {
13413       if (!strcmp ((char *) s, "no-action"))
13414         action[0] = 0;
13415       else if (!strcmp ((char *) s, "natively-forward"))
13416         action[0] = 1;
13417       else if (!strcmp ((char *) s, "send-map-request"))
13418         action[0] = 2;
13419       else if (!strcmp ((char *) s, "drop"))
13420         action[0] = 3;
13421       else
13422         {
13423           clib_warning ("invalid action: '%s'", s);
13424           action[0] = 3;
13425         }
13426     }
13427   else
13428     return 0;
13429
13430   vec_free (s);
13431   return 1;
13432 }
13433
13434 /**
13435  * Add/del remote mapping to/from LISP control plane
13436  *
13437  * @param vam vpp API test context
13438  * @return return code
13439  */
13440 static int
13441 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13442 {
13443   unformat_input_t *input = vam->input;
13444   vl_api_lisp_add_del_remote_mapping_t *mp;
13445   f64 timeout = ~0;
13446   u32 vni = 0;
13447   lisp_eid_vat_t _eid, *eid = &_eid;
13448   lisp_eid_vat_t _seid, *seid = &_seid;
13449   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13450   u32 action = ~0, p, w, data_len;
13451   ip4_address_t rloc4;
13452   ip6_address_t rloc6;
13453   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13454
13455   memset (&rloc, 0, sizeof (rloc));
13456
13457   /* Parse args required to build the message */
13458   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13459     {
13460       if (unformat (input, "del-all"))
13461         {
13462           del_all = 1;
13463         }
13464       else if (unformat (input, "del"))
13465         {
13466           is_add = 0;
13467         }
13468       else if (unformat (input, "add"))
13469         {
13470           is_add = 1;
13471         }
13472       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13473         {
13474           eid_set = 1;
13475         }
13476       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13477         {
13478           seid_set = 1;
13479         }
13480       else if (unformat (input, "vni %d", &vni))
13481         {
13482           ;
13483         }
13484       else if (unformat (input, "p %d w %d", &p, &w))
13485         {
13486           if (!curr_rloc)
13487             {
13488               errmsg ("No RLOC configured for setting priority/weight!");
13489               return -99;
13490             }
13491           curr_rloc->priority = p;
13492           curr_rloc->weight = w;
13493         }
13494       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13495         {
13496           rloc.is_ip4 = 1;
13497           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13498           vec_add1 (rlocs, rloc);
13499           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13500         }
13501       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13502         {
13503           rloc.is_ip4 = 0;
13504           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13505           vec_add1 (rlocs, rloc);
13506           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13507         }
13508       else if (unformat (input, "action %U",
13509                          unformat_negative_mapping_action, &action))
13510         {
13511           ;
13512         }
13513       else
13514         {
13515           clib_warning ("parse error '%U'", format_unformat_error, input);
13516           return -99;
13517         }
13518     }
13519
13520   if (0 == eid_set)
13521     {
13522       errmsg ("missing params!");
13523       return -99;
13524     }
13525
13526   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13527     {
13528       errmsg ("no action set for negative map-reply!");
13529       return -99;
13530     }
13531
13532   data_len = vec_len (rlocs) * sizeof (rloc_t);
13533
13534   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13535   mp->is_add = is_add;
13536   mp->vni = htonl (vni);
13537   mp->action = (u8) action;
13538   mp->is_src_dst = seid_set;
13539   mp->eid_len = eid->len;
13540   mp->seid_len = seid->len;
13541   mp->del_all = del_all;
13542   mp->eid_type = eid->type;
13543   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13544   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13545
13546   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13547   clib_memcpy (mp->rlocs, rlocs, data_len);
13548   vec_free (rlocs);
13549
13550   /* send it... */
13551   S;
13552
13553   /* Wait for a reply... */
13554   W;
13555
13556   /* NOTREACHED */
13557   return 0;
13558 }
13559
13560 /**
13561  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13562  * forwarding entries in data-plane accordingly.
13563  *
13564  * @param vam vpp API test context
13565  * @return return code
13566  */
13567 static int
13568 api_lisp_add_del_adjacency (vat_main_t * vam)
13569 {
13570   unformat_input_t *input = vam->input;
13571   vl_api_lisp_add_del_adjacency_t *mp;
13572   f64 timeout = ~0;
13573   u32 vni = 0;
13574   ip4_address_t leid4, reid4;
13575   ip6_address_t leid6, reid6;
13576   u8 reid_mac[6] = { 0 };
13577   u8 leid_mac[6] = { 0 };
13578   u8 reid_type, leid_type;
13579   u32 leid_len = 0, reid_len = 0, len;
13580   u8 is_add = 1;
13581
13582   leid_type = reid_type = (u8) ~ 0;
13583
13584   /* Parse args required to build the message */
13585   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13586     {
13587       if (unformat (input, "del"))
13588         {
13589           is_add = 0;
13590         }
13591       else if (unformat (input, "add"))
13592         {
13593           is_add = 1;
13594         }
13595       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13596                          &reid4, &len))
13597         {
13598           reid_type = 0;        /* ipv4 */
13599           reid_len = len;
13600         }
13601       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13602                          &reid6, &len))
13603         {
13604           reid_type = 1;        /* ipv6 */
13605           reid_len = len;
13606         }
13607       else if (unformat (input, "reid %U", unformat_ethernet_address,
13608                          reid_mac))
13609         {
13610           reid_type = 2;        /* mac */
13611         }
13612       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13613                          &leid4, &len))
13614         {
13615           leid_type = 0;        /* ipv4 */
13616           leid_len = len;
13617         }
13618       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13619                          &leid6, &len))
13620         {
13621           leid_type = 1;        /* ipv6 */
13622           leid_len = len;
13623         }
13624       else if (unformat (input, "leid %U", unformat_ethernet_address,
13625                          leid_mac))
13626         {
13627           leid_type = 2;        /* mac */
13628         }
13629       else if (unformat (input, "vni %d", &vni))
13630         {
13631           ;
13632         }
13633       else
13634         {
13635           errmsg ("parse error '%U'", format_unformat_error, input);
13636           return -99;
13637         }
13638     }
13639
13640   if ((u8) ~ 0 == reid_type)
13641     {
13642       errmsg ("missing params!");
13643       return -99;
13644     }
13645
13646   if (leid_type != reid_type)
13647     {
13648       errmsg ("remote and local EIDs are of different types!");
13649       return -99;
13650     }
13651
13652   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13653   mp->is_add = is_add;
13654   mp->vni = htonl (vni);
13655   mp->leid_len = leid_len;
13656   mp->reid_len = reid_len;
13657   mp->eid_type = reid_type;
13658
13659   switch (mp->eid_type)
13660     {
13661     case 0:
13662       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13663       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13664       break;
13665     case 1:
13666       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13667       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13668       break;
13669     case 2:
13670       clib_memcpy (mp->leid, leid_mac, 6);
13671       clib_memcpy (mp->reid, reid_mac, 6);
13672       break;
13673     default:
13674       errmsg ("unknown EID type %d!", mp->eid_type);
13675       return 0;
13676     }
13677
13678   /* send it... */
13679   S;
13680
13681   /* Wait for a reply... */
13682   W;
13683
13684   /* NOTREACHED */
13685   return 0;
13686 }
13687
13688 static int
13689 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13690 {
13691   unformat_input_t *input = vam->input;
13692   vl_api_lisp_gpe_add_del_iface_t *mp;
13693   f64 timeout = ~0;
13694   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13695   u32 dp_table = 0, vni = 0;
13696
13697   /* Parse args required to build the message */
13698   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13699     {
13700       if (unformat (input, "up"))
13701         {
13702           action_set = 1;
13703           is_add = 1;
13704         }
13705       else if (unformat (input, "down"))
13706         {
13707           action_set = 1;
13708           is_add = 0;
13709         }
13710       else if (unformat (input, "table_id %d", &dp_table))
13711         {
13712           dp_table_set = 1;
13713         }
13714       else if (unformat (input, "bd_id %d", &dp_table))
13715         {
13716           dp_table_set = 1;
13717           is_l2 = 1;
13718         }
13719       else if (unformat (input, "vni %d", &vni))
13720         {
13721           vni_set = 1;
13722         }
13723       else
13724         break;
13725     }
13726
13727   if (action_set == 0)
13728     {
13729       errmsg ("Action not set\n");
13730       return -99;
13731     }
13732   if (dp_table_set == 0 || vni_set == 0)
13733     {
13734       errmsg ("vni and dp_table must be set\n");
13735       return -99;
13736     }
13737
13738   /* Construct the API message */
13739   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13740
13741   mp->is_add = is_add;
13742   mp->dp_table = dp_table;
13743   mp->is_l2 = is_l2;
13744   mp->vni = vni;
13745
13746   /* send it... */
13747   S;
13748
13749   /* Wait for a reply... */
13750   W;
13751
13752   /* NOTREACHED */
13753   return 0;
13754 }
13755
13756 /**
13757  * Add/del map request itr rlocs from LISP control plane and updates
13758  *
13759  * @param vam vpp API test context
13760  * @return return code
13761  */
13762 static int
13763 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13764 {
13765   unformat_input_t *input = vam->input;
13766   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13767   f64 timeout = ~0;
13768   u8 *locator_set_name = 0;
13769   u8 locator_set_name_set = 0;
13770   u8 is_add = 1;
13771
13772   /* Parse args required to build the message */
13773   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13774     {
13775       if (unformat (input, "del"))
13776         {
13777           is_add = 0;
13778         }
13779       else if (unformat (input, "%_%v%_", &locator_set_name))
13780         {
13781           locator_set_name_set = 1;
13782         }
13783       else
13784         {
13785           clib_warning ("parse error '%U'", format_unformat_error, input);
13786           return -99;
13787         }
13788     }
13789
13790   if (is_add && !locator_set_name_set)
13791     {
13792       errmsg ("itr-rloc is not set!");
13793       return -99;
13794     }
13795
13796   if (is_add && vec_len (locator_set_name) > 64)
13797     {
13798       errmsg ("itr-rloc locator-set name too long\n");
13799       vec_free (locator_set_name);
13800       return -99;
13801     }
13802
13803   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13804   mp->is_add = is_add;
13805   if (is_add)
13806     {
13807       clib_memcpy (mp->locator_set_name, locator_set_name,
13808                    vec_len (locator_set_name));
13809     }
13810   else
13811     {
13812       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13813     }
13814   vec_free (locator_set_name);
13815
13816   /* send it... */
13817   S;
13818
13819   /* Wait for a reply... */
13820   W;
13821
13822   /* NOTREACHED */
13823   return 0;
13824 }
13825
13826 static int
13827 api_lisp_locator_dump (vat_main_t * vam)
13828 {
13829   unformat_input_t *input = vam->input;
13830   vl_api_lisp_locator_dump_t *mp;
13831   f64 timeout = ~0;
13832   u8 is_index_set = 0, is_name_set = 0;
13833   u8 *ls_name = 0;
13834   u32 ls_index = ~0;
13835
13836   /* Parse args required to build the message */
13837   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13838     {
13839       if (unformat (input, "ls_name %_%v%_", &ls_name))
13840         {
13841           is_name_set = 1;
13842         }
13843       else if (unformat (input, "ls_index %d", &ls_index))
13844         {
13845           is_index_set = 1;
13846         }
13847       else
13848         {
13849           errmsg ("parse error '%U'", format_unformat_error, input);
13850           return -99;
13851         }
13852     }
13853
13854   if (!is_index_set && !is_name_set)
13855     {
13856       errmsg ("error: expected one of index or name!\n");
13857       return -99;
13858     }
13859
13860   if (is_index_set && is_name_set)
13861     {
13862       errmsg ("error: only one param expected!\n");
13863       return -99;
13864     }
13865
13866   if (vec_len (ls_name) > 62)
13867     {
13868       errmsg ("error: locator set name too long!");
13869       return -99;
13870     }
13871
13872   if (!vam->json_output)
13873     {
13874       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13875                "weight");
13876     }
13877
13878   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13879   mp->is_index_set = is_index_set;
13880
13881   if (is_index_set)
13882     mp->ls_index = clib_host_to_net_u32 (ls_index);
13883   else
13884     {
13885       vec_add1 (ls_name, 0);
13886       strncpy ((char *) mp->ls_name, (char *) ls_name,
13887                sizeof (mp->ls_name) - 1);
13888     }
13889
13890   /* send it... */
13891   S;
13892
13893   /* Use a control ping for synchronization */
13894   {
13895     vl_api_control_ping_t *mp;
13896     M (CONTROL_PING, control_ping);
13897     S;
13898   }
13899   /* Wait for a reply... */
13900   W;
13901
13902   /* NOTREACHED */
13903   return 0;
13904 }
13905
13906 static int
13907 api_lisp_locator_set_dump (vat_main_t * vam)
13908 {
13909   vl_api_lisp_locator_set_dump_t *mp;
13910   unformat_input_t *input = vam->input;
13911   f64 timeout = ~0;
13912   u8 filter = 0;
13913
13914   /* Parse args required to build the message */
13915   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13916     {
13917       if (unformat (input, "local"))
13918         {
13919           filter = 1;
13920         }
13921       else if (unformat (input, "remote"))
13922         {
13923           filter = 2;
13924         }
13925       else
13926         {
13927           errmsg ("parse error '%U'", format_unformat_error, input);
13928           return -99;
13929         }
13930     }
13931
13932   if (!vam->json_output)
13933     {
13934       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13935     }
13936
13937   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13938
13939   mp->filter = filter;
13940
13941   /* send it... */
13942   S;
13943
13944   /* Use a control ping for synchronization */
13945   {
13946     vl_api_control_ping_t *mp;
13947     M (CONTROL_PING, control_ping);
13948     S;
13949   }
13950   /* Wait for a reply... */
13951   W;
13952
13953   /* NOTREACHED */
13954   return 0;
13955 }
13956
13957 static int
13958 api_lisp_eid_table_map_dump (vat_main_t * vam)
13959 {
13960   u8 is_l2 = 0;
13961   u8 mode_set = 0;
13962   unformat_input_t *input = vam->input;
13963   vl_api_lisp_eid_table_map_dump_t *mp;
13964   f64 timeout = ~0;
13965
13966   /* Parse args required to build the message */
13967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13968     {
13969       if (unformat (input, "l2"))
13970         {
13971           is_l2 = 1;
13972           mode_set = 1;
13973         }
13974       else if (unformat (input, "l3"))
13975         {
13976           is_l2 = 0;
13977           mode_set = 1;
13978         }
13979       else
13980         {
13981           errmsg ("parse error '%U'", format_unformat_error, input);
13982           return -99;
13983         }
13984     }
13985
13986   if (!mode_set)
13987     {
13988       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13989       return -99;
13990     }
13991
13992   if (!vam->json_output)
13993     {
13994       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13995     }
13996
13997   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13998   mp->is_l2 = is_l2;
13999
14000   /* send it... */
14001   S;
14002
14003   /* Use a control ping for synchronization */
14004   {
14005     vl_api_control_ping_t *mp;
14006     M (CONTROL_PING, control_ping);
14007     S;
14008   }
14009   /* Wait for a reply... */
14010   W;
14011
14012   /* NOTREACHED */
14013   return 0;
14014 }
14015
14016 static int
14017 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14018 {
14019   vl_api_lisp_eid_table_vni_dump_t *mp;
14020   f64 timeout = ~0;
14021
14022   if (!vam->json_output)
14023     {
14024       fformat (vam->ofp, "VNI\n");
14025     }
14026
14027   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14028
14029   /* send it... */
14030   S;
14031
14032   /* Use a control ping for synchronization */
14033   {
14034     vl_api_control_ping_t *mp;
14035     M (CONTROL_PING, control_ping);
14036     S;
14037   }
14038   /* Wait for a reply... */
14039   W;
14040
14041   /* NOTREACHED */
14042   return 0;
14043 }
14044
14045 static int
14046 api_lisp_eid_table_dump (vat_main_t * vam)
14047 {
14048   unformat_input_t *i = vam->input;
14049   vl_api_lisp_eid_table_dump_t *mp;
14050   f64 timeout = ~0;
14051   struct in_addr ip4;
14052   struct in6_addr ip6;
14053   u8 mac[6];
14054   u8 eid_type = ~0, eid_set = 0;
14055   u32 prefix_length = ~0, t, vni = 0;
14056   u8 filter = 0;
14057
14058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14059     {
14060       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14061         {
14062           eid_set = 1;
14063           eid_type = 0;
14064           prefix_length = t;
14065         }
14066       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14067         {
14068           eid_set = 1;
14069           eid_type = 1;
14070           prefix_length = t;
14071         }
14072       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14073         {
14074           eid_set = 1;
14075           eid_type = 2;
14076         }
14077       else if (unformat (i, "vni %d", &t))
14078         {
14079           vni = t;
14080         }
14081       else if (unformat (i, "local"))
14082         {
14083           filter = 1;
14084         }
14085       else if (unformat (i, "remote"))
14086         {
14087           filter = 2;
14088         }
14089       else
14090         {
14091           errmsg ("parse error '%U'", format_unformat_error, i);
14092           return -99;
14093         }
14094     }
14095
14096   if (!vam->json_output)
14097     {
14098       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
14099                "ls_index", "ttl", "authoritative");
14100     }
14101
14102   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14103
14104   mp->filter = filter;
14105   if (eid_set)
14106     {
14107       mp->eid_set = 1;
14108       mp->vni = htonl (vni);
14109       mp->eid_type = eid_type;
14110       switch (eid_type)
14111         {
14112         case 0:
14113           mp->prefix_length = prefix_length;
14114           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14115           break;
14116         case 1:
14117           mp->prefix_length = prefix_length;
14118           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14119           break;
14120         case 2:
14121           clib_memcpy (mp->eid, mac, sizeof (mac));
14122           break;
14123         default:
14124           errmsg ("unknown EID type %d!", eid_type);
14125           return -99;
14126         }
14127     }
14128
14129   /* send it... */
14130   S;
14131
14132   /* Use a control ping for synchronization */
14133   {
14134     vl_api_control_ping_t *mp;
14135     M (CONTROL_PING, control_ping);
14136     S;
14137   }
14138
14139   /* Wait for a reply... */
14140   W;
14141
14142   /* NOTREACHED */
14143   return 0;
14144 }
14145
14146 static int
14147 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14148 {
14149   vl_api_lisp_gpe_tunnel_dump_t *mp;
14150   f64 timeout = ~0;
14151
14152   if (!vam->json_output)
14153     {
14154       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14155                "%=16s%=16s%=16s%=16s%=16s\n",
14156                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14157                "Decap next", "Lisp version", "Flags", "Next protocol",
14158                "ver_res", "res", "iid");
14159     }
14160
14161   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14162   /* send it... */
14163   S;
14164
14165   /* Use a control ping for synchronization */
14166   {
14167     vl_api_control_ping_t *mp;
14168     M (CONTROL_PING, control_ping);
14169     S;
14170   }
14171   /* Wait for a reply... */
14172   W;
14173
14174   /* NOTREACHED */
14175   return 0;
14176 }
14177
14178 static int
14179 api_lisp_adjacencies_get (vat_main_t * vam)
14180 {
14181   unformat_input_t *i = vam->input;
14182   vl_api_lisp_adjacencies_get_t *mp;
14183   f64 timeout = ~0;
14184   u8 vni_set = 0;
14185   u32 vni = ~0;
14186
14187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14188     {
14189       if (unformat (i, "vni %d", &vni))
14190         {
14191           vni_set = 1;
14192         }
14193       else
14194         {
14195           errmsg ("parse error '%U'\n", format_unformat_error, i);
14196           return -99;
14197         }
14198     }
14199
14200   if (!vni_set)
14201     {
14202       errmsg ("vni not set!\n");
14203       return -99;
14204     }
14205
14206   if (!vam->json_output)
14207     {
14208       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14209     }
14210
14211   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14212   mp->vni = clib_host_to_net_u32 (vni);
14213
14214   /* send it... */
14215   S;
14216
14217   /* Wait for a reply... */
14218   W;
14219
14220   /* NOTREACHED */
14221   return 0;
14222 }
14223
14224 static int
14225 api_lisp_map_resolver_dump (vat_main_t * vam)
14226 {
14227   vl_api_lisp_map_resolver_dump_t *mp;
14228   f64 timeout = ~0;
14229
14230   if (!vam->json_output)
14231     {
14232       fformat (vam->ofp, "%=20s\n", "Map resolver");
14233     }
14234
14235   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14236   /* send it... */
14237   S;
14238
14239   /* Use a control ping for synchronization */
14240   {
14241     vl_api_control_ping_t *mp;
14242     M (CONTROL_PING, control_ping);
14243     S;
14244   }
14245   /* Wait for a reply... */
14246   W;
14247
14248   /* NOTREACHED */
14249   return 0;
14250 }
14251
14252 static int
14253 api_show_lisp_status (vat_main_t * vam)
14254 {
14255   vl_api_show_lisp_status_t *mp;
14256   f64 timeout = ~0;
14257
14258   if (!vam->json_output)
14259     {
14260       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14261     }
14262
14263   M (SHOW_LISP_STATUS, show_lisp_status);
14264   /* send it... */
14265   S;
14266   /* Wait for a reply... */
14267   W;
14268
14269   /* NOTREACHED */
14270   return 0;
14271 }
14272
14273 static int
14274 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14275 {
14276   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14277   f64 timeout = ~0;
14278
14279   if (!vam->json_output)
14280     {
14281       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14282     }
14283
14284   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14285   /* send it... */
14286   S;
14287   /* Wait for a reply... */
14288   W;
14289
14290   /* NOTREACHED */
14291   return 0;
14292 }
14293
14294 static int
14295 api_af_packet_create (vat_main_t * vam)
14296 {
14297   unformat_input_t *i = vam->input;
14298   vl_api_af_packet_create_t *mp;
14299   f64 timeout;
14300   u8 *host_if_name = 0;
14301   u8 hw_addr[6];
14302   u8 random_hw_addr = 1;
14303
14304   memset (hw_addr, 0, sizeof (hw_addr));
14305
14306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14307     {
14308       if (unformat (i, "name %s", &host_if_name))
14309         vec_add1 (host_if_name, 0);
14310       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14311         random_hw_addr = 0;
14312       else
14313         break;
14314     }
14315
14316   if (!vec_len (host_if_name))
14317     {
14318       errmsg ("host-interface name must be specified");
14319       return -99;
14320     }
14321
14322   if (vec_len (host_if_name) > 64)
14323     {
14324       errmsg ("host-interface name too long");
14325       return -99;
14326     }
14327
14328   M (AF_PACKET_CREATE, af_packet_create);
14329
14330   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14331   clib_memcpy (mp->hw_addr, hw_addr, 6);
14332   mp->use_random_hw_addr = random_hw_addr;
14333   vec_free (host_if_name);
14334
14335   S;
14336   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14337   /* NOTREACHED */
14338   return 0;
14339 }
14340
14341 static int
14342 api_af_packet_delete (vat_main_t * vam)
14343 {
14344   unformat_input_t *i = vam->input;
14345   vl_api_af_packet_delete_t *mp;
14346   f64 timeout;
14347   u8 *host_if_name = 0;
14348
14349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14350     {
14351       if (unformat (i, "name %s", &host_if_name))
14352         vec_add1 (host_if_name, 0);
14353       else
14354         break;
14355     }
14356
14357   if (!vec_len (host_if_name))
14358     {
14359       errmsg ("host-interface name must be specified");
14360       return -99;
14361     }
14362
14363   if (vec_len (host_if_name) > 64)
14364     {
14365       errmsg ("host-interface name too long");
14366       return -99;
14367     }
14368
14369   M (AF_PACKET_DELETE, af_packet_delete);
14370
14371   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14372   vec_free (host_if_name);
14373
14374   S;
14375   W;
14376   /* NOTREACHED */
14377   return 0;
14378 }
14379
14380 static int
14381 api_policer_add_del (vat_main_t * vam)
14382 {
14383   unformat_input_t *i = vam->input;
14384   vl_api_policer_add_del_t *mp;
14385   f64 timeout;
14386   u8 is_add = 1;
14387   u8 *name = 0;
14388   u32 cir = 0;
14389   u32 eir = 0;
14390   u64 cb = 0;
14391   u64 eb = 0;
14392   u8 rate_type = 0;
14393   u8 round_type = 0;
14394   u8 type = 0;
14395   u8 color_aware = 0;
14396   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14397
14398   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14399   conform_action.dscp = 0;
14400   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14401   exceed_action.dscp = 0;
14402   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14403   violate_action.dscp = 0;
14404
14405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14406     {
14407       if (unformat (i, "del"))
14408         is_add = 0;
14409       else if (unformat (i, "name %s", &name))
14410         vec_add1 (name, 0);
14411       else if (unformat (i, "cir %u", &cir))
14412         ;
14413       else if (unformat (i, "eir %u", &eir))
14414         ;
14415       else if (unformat (i, "cb %u", &cb))
14416         ;
14417       else if (unformat (i, "eb %u", &eb))
14418         ;
14419       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14420                          &rate_type))
14421         ;
14422       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14423                          &round_type))
14424         ;
14425       else if (unformat (i, "type %U", unformat_policer_type, &type))
14426         ;
14427       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14428                          &conform_action))
14429         ;
14430       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14431                          &exceed_action))
14432         ;
14433       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14434                          &violate_action))
14435         ;
14436       else if (unformat (i, "color-aware"))
14437         color_aware = 1;
14438       else
14439         break;
14440     }
14441
14442   if (!vec_len (name))
14443     {
14444       errmsg ("policer name must be specified");
14445       return -99;
14446     }
14447
14448   if (vec_len (name) > 64)
14449     {
14450       errmsg ("policer name too long");
14451       return -99;
14452     }
14453
14454   M (POLICER_ADD_DEL, policer_add_del);
14455
14456   clib_memcpy (mp->name, name, vec_len (name));
14457   vec_free (name);
14458   mp->is_add = is_add;
14459   mp->cir = cir;
14460   mp->eir = eir;
14461   mp->cb = cb;
14462   mp->eb = eb;
14463   mp->rate_type = rate_type;
14464   mp->round_type = round_type;
14465   mp->type = type;
14466   mp->conform_action_type = conform_action.action_type;
14467   mp->conform_dscp = conform_action.dscp;
14468   mp->exceed_action_type = exceed_action.action_type;
14469   mp->exceed_dscp = exceed_action.dscp;
14470   mp->violate_action_type = violate_action.action_type;
14471   mp->violate_dscp = violate_action.dscp;
14472   mp->color_aware = color_aware;
14473
14474   S;
14475   W;
14476   /* NOTREACHED */
14477   return 0;
14478 }
14479
14480 static int
14481 api_policer_dump (vat_main_t * vam)
14482 {
14483   unformat_input_t *i = vam->input;
14484   vl_api_policer_dump_t *mp;
14485   f64 timeout = ~0;
14486   u8 *match_name = 0;
14487   u8 match_name_valid = 0;
14488
14489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14490     {
14491       if (unformat (i, "name %s", &match_name))
14492         {
14493           vec_add1 (match_name, 0);
14494           match_name_valid = 1;
14495         }
14496       else
14497         break;
14498     }
14499
14500   M (POLICER_DUMP, policer_dump);
14501   mp->match_name_valid = match_name_valid;
14502   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14503   vec_free (match_name);
14504   /* send it... */
14505   S;
14506
14507   /* Use a control ping for synchronization */
14508   {
14509     vl_api_control_ping_t *mp;
14510     M (CONTROL_PING, control_ping);
14511     S;
14512   }
14513   /* Wait for a reply... */
14514   W;
14515
14516   /* NOTREACHED */
14517   return 0;
14518 }
14519
14520 static int
14521 api_policer_classify_set_interface (vat_main_t * vam)
14522 {
14523   unformat_input_t *i = vam->input;
14524   vl_api_policer_classify_set_interface_t *mp;
14525   f64 timeout;
14526   u32 sw_if_index;
14527   int sw_if_index_set;
14528   u32 ip4_table_index = ~0;
14529   u32 ip6_table_index = ~0;
14530   u32 l2_table_index = ~0;
14531   u8 is_add = 1;
14532
14533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14534     {
14535       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14536         sw_if_index_set = 1;
14537       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14538         sw_if_index_set = 1;
14539       else if (unformat (i, "del"))
14540         is_add = 0;
14541       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14542         ;
14543       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14544         ;
14545       else if (unformat (i, "l2-table %d", &l2_table_index))
14546         ;
14547       else
14548         {
14549           clib_warning ("parse error '%U'", format_unformat_error, i);
14550           return -99;
14551         }
14552     }
14553
14554   if (sw_if_index_set == 0)
14555     {
14556       errmsg ("missing interface name or sw_if_index\n");
14557       return -99;
14558     }
14559
14560   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14561
14562   mp->sw_if_index = ntohl (sw_if_index);
14563   mp->ip4_table_index = ntohl (ip4_table_index);
14564   mp->ip6_table_index = ntohl (ip6_table_index);
14565   mp->l2_table_index = ntohl (l2_table_index);
14566   mp->is_add = is_add;
14567
14568   S;
14569   W;
14570   /* NOTREACHED */
14571   return 0;
14572 }
14573
14574 static int
14575 api_policer_classify_dump (vat_main_t * vam)
14576 {
14577   unformat_input_t *i = vam->input;
14578   vl_api_policer_classify_dump_t *mp;
14579   f64 timeout = ~0;
14580   u8 type = POLICER_CLASSIFY_N_TABLES;
14581
14582   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14583     ;
14584   else
14585     {
14586       errmsg ("classify table type must be specified\n");
14587       return -99;
14588     }
14589
14590   if (!vam->json_output)
14591     {
14592       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14593     }
14594
14595   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14596   mp->type = type;
14597   /* send it... */
14598   S;
14599
14600   /* Use a control ping for synchronization */
14601   {
14602     vl_api_control_ping_t *mp;
14603     M (CONTROL_PING, control_ping);
14604     S;
14605   }
14606   /* Wait for a reply... */
14607   W;
14608
14609   /* NOTREACHED */
14610   return 0;
14611 }
14612
14613 static int
14614 api_netmap_create (vat_main_t * vam)
14615 {
14616   unformat_input_t *i = vam->input;
14617   vl_api_netmap_create_t *mp;
14618   f64 timeout;
14619   u8 *if_name = 0;
14620   u8 hw_addr[6];
14621   u8 random_hw_addr = 1;
14622   u8 is_pipe = 0;
14623   u8 is_master = 0;
14624
14625   memset (hw_addr, 0, sizeof (hw_addr));
14626
14627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14628     {
14629       if (unformat (i, "name %s", &if_name))
14630         vec_add1 (if_name, 0);
14631       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14632         random_hw_addr = 0;
14633       else if (unformat (i, "pipe"))
14634         is_pipe = 1;
14635       else if (unformat (i, "master"))
14636         is_master = 1;
14637       else if (unformat (i, "slave"))
14638         is_master = 0;
14639       else
14640         break;
14641     }
14642
14643   if (!vec_len (if_name))
14644     {
14645       errmsg ("interface name must be specified");
14646       return -99;
14647     }
14648
14649   if (vec_len (if_name) > 64)
14650     {
14651       errmsg ("interface name too long");
14652       return -99;
14653     }
14654
14655   M (NETMAP_CREATE, netmap_create);
14656
14657   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14658   clib_memcpy (mp->hw_addr, hw_addr, 6);
14659   mp->use_random_hw_addr = random_hw_addr;
14660   mp->is_pipe = is_pipe;
14661   mp->is_master = is_master;
14662   vec_free (if_name);
14663
14664   S;
14665   W;
14666   /* NOTREACHED */
14667   return 0;
14668 }
14669
14670 static int
14671 api_netmap_delete (vat_main_t * vam)
14672 {
14673   unformat_input_t *i = vam->input;
14674   vl_api_netmap_delete_t *mp;
14675   f64 timeout;
14676   u8 *if_name = 0;
14677
14678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14679     {
14680       if (unformat (i, "name %s", &if_name))
14681         vec_add1 (if_name, 0);
14682       else
14683         break;
14684     }
14685
14686   if (!vec_len (if_name))
14687     {
14688       errmsg ("interface name must be specified");
14689       return -99;
14690     }
14691
14692   if (vec_len (if_name) > 64)
14693     {
14694       errmsg ("interface name too long");
14695       return -99;
14696     }
14697
14698   M (NETMAP_DELETE, netmap_delete);
14699
14700   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14701   vec_free (if_name);
14702
14703   S;
14704   W;
14705   /* NOTREACHED */
14706   return 0;
14707 }
14708
14709 static void vl_api_mpls_eth_tunnel_details_t_handler
14710   (vl_api_mpls_eth_tunnel_details_t * mp)
14711 {
14712   vat_main_t *vam = &vat_main;
14713   i32 i;
14714   i32 len = ntohl (mp->nlabels);
14715
14716   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14717            ntohl (mp->tunnel_index),
14718            format_ethernet_address, &mp->tunnel_dst_mac,
14719            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14720   for (i = 0; i < len; i++)
14721     {
14722       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14723     }
14724   fformat (vam->ofp, "\n");
14725   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14726            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14727 }
14728
14729 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14730   (vl_api_mpls_eth_tunnel_details_t * mp)
14731 {
14732   vat_main_t *vam = &vat_main;
14733   vat_json_node_t *node = NULL;
14734   struct in_addr ip4;
14735   i32 i;
14736   i32 len = ntohl (mp->nlabels);
14737
14738   if (VAT_JSON_ARRAY != vam->json_tree.type)
14739     {
14740       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14741       vat_json_init_array (&vam->json_tree);
14742     }
14743   node = vat_json_array_add (&vam->json_tree);
14744
14745   vat_json_init_object (node);
14746   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14747   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14748   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14749   vat_json_object_add_uint (node, "inner_fib_index",
14750                             ntohl (mp->inner_fib_index));
14751   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14752   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14753   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14754   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14755   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14756                                    format (0, "%U", format_ethernet_address,
14757                                            &mp->tunnel_dst_mac));
14758   vat_json_object_add_uint (node, "tx_sw_if_index",
14759                             ntohl (mp->tx_sw_if_index));
14760   vat_json_object_add_uint (node, "label_count", len);
14761   for (i = 0; i < len; i++)
14762     {
14763       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14764     }
14765 }
14766
14767 static int
14768 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14769 {
14770   vl_api_mpls_eth_tunnel_dump_t *mp;
14771   f64 timeout;
14772   i32 index = -1;
14773
14774   /* Parse args required to build the message */
14775   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14776     {
14777       if (!unformat (vam->input, "tunnel_index %d", &index))
14778         {
14779           index = -1;
14780           break;
14781         }
14782     }
14783
14784   fformat (vam->ofp, "  tunnel_index %d\n", index);
14785
14786   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14787   mp->tunnel_index = htonl (index);
14788   S;
14789
14790   /* Use a control ping for synchronization */
14791   {
14792     vl_api_control_ping_t *mp;
14793     M (CONTROL_PING, control_ping);
14794     S;
14795   }
14796   W;
14797 }
14798
14799 static void vl_api_mpls_fib_encap_details_t_handler
14800   (vl_api_mpls_fib_encap_details_t * mp)
14801 {
14802   vat_main_t *vam = &vat_main;
14803   i32 i;
14804   i32 len = ntohl (mp->nlabels);
14805
14806   fformat (vam->ofp, "table %d, dest %U, label ",
14807            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14808   for (i = 0; i < len; i++)
14809     {
14810       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14811     }
14812   fformat (vam->ofp, "\n");
14813 }
14814
14815 static void vl_api_mpls_fib_encap_details_t_handler_json
14816   (vl_api_mpls_fib_encap_details_t * mp)
14817 {
14818   vat_main_t *vam = &vat_main;
14819   vat_json_node_t *node = NULL;
14820   i32 i;
14821   i32 len = ntohl (mp->nlabels);
14822   struct in_addr ip4;
14823
14824   if (VAT_JSON_ARRAY != vam->json_tree.type)
14825     {
14826       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14827       vat_json_init_array (&vam->json_tree);
14828     }
14829   node = vat_json_array_add (&vam->json_tree);
14830
14831   vat_json_init_object (node);
14832   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14833   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14834   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14835   vat_json_object_add_ip4 (node, "dest", ip4);
14836   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14837   vat_json_object_add_uint (node, "label_count", len);
14838   for (i = 0; i < len; i++)
14839     {
14840       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14841     }
14842 }
14843
14844 static int
14845 api_mpls_fib_encap_dump (vat_main_t * vam)
14846 {
14847   vl_api_mpls_fib_encap_dump_t *mp;
14848   f64 timeout;
14849
14850   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14851   S;
14852
14853   /* Use a control ping for synchronization */
14854   {
14855     vl_api_control_ping_t *mp;
14856     M (CONTROL_PING, control_ping);
14857     S;
14858   }
14859   W;
14860 }
14861
14862 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
14863 #define vl_api_mpls_fib_details_t_print vl_noop_handler
14864
14865 static void
14866 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
14867 {
14868   vat_main_t *vam = &vat_main;
14869   int count = ntohl (mp->count);
14870   vl_api_fib_path_t *fp;
14871   int i;
14872
14873   fformat (vam->ofp,
14874            "table-id %d, label %u, ess_bit %u\n",
14875            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
14876   fp = mp->path;
14877   for (i = 0; i < count; i++)
14878     {
14879       fformat (vam->ofp,
14880                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, is_unreach %d, "
14881                "is_prohitbit %d, afi %d, next_hop %U\n", ntohl (fp->weight),
14882                ntohl (fp->sw_if_index), fp->is_local, fp->is_drop,
14883                fp->is_unreach, fp->is_prohibit, fp->afi, format_ip46_address,
14884                fp->next_hop, fp->afi);
14885       fp++;
14886     }
14887 }
14888
14889 static void vl_api_mpls_fib_details_t_handler_json
14890   (vl_api_mpls_fib_details_t * mp)
14891 {
14892   vat_main_t *vam = &vat_main;
14893   int count = ntohl (mp->count);
14894   vat_json_node_t *node = NULL;
14895   struct in_addr ip4;
14896   struct in6_addr ip6;
14897   vl_api_fib_path_t *fp;
14898   int i;
14899
14900   if (VAT_JSON_ARRAY != vam->json_tree.type)
14901     {
14902       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14903       vat_json_init_array (&vam->json_tree);
14904     }
14905   node = vat_json_array_add (&vam->json_tree);
14906
14907   vat_json_init_object (node);
14908   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14909   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
14910   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14911   vat_json_object_add_uint (node, "path_count", count);
14912   fp = mp->path;
14913   for (i = 0; i < count; i++)
14914     {
14915       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
14916       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
14917       vat_json_object_add_uint (node, "is_local", fp->is_local);
14918       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
14919       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
14920       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
14921       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
14922       if (fp->afi == IP46_TYPE_IP4)
14923         {
14924           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
14925           vat_json_object_add_ip4 (node, "next_hop", ip4);
14926         }
14927       else if (fp->afi == IP46_TYPE_IP6)
14928         {
14929           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
14930           vat_json_object_add_ip6 (node, "next_hop", ip6);
14931         }
14932     }
14933 }
14934
14935 static int
14936 api_mpls_fib_dump (vat_main_t * vam)
14937 {
14938   vl_api_mpls_fib_dump_t *mp;
14939   f64 timeout;
14940
14941   M (MPLS_FIB_DUMP, mpls_fib_dump);
14942   S;
14943
14944   /* Use a control ping for synchronization */
14945   {
14946     vl_api_control_ping_t *mp;
14947     M (CONTROL_PING, control_ping);
14948     S;
14949   }
14950   W;
14951 }
14952
14953 #define vl_api_ip_fib_details_t_endian vl_noop_handler
14954 #define vl_api_ip_fib_details_t_print vl_noop_handler
14955
14956 static void
14957 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
14958 {
14959   vat_main_t *vam = &vat_main;
14960   int count = ntohl (mp->count);
14961   vl_api_fib_path_t *fp;
14962   int i;
14963
14964   fformat (vam->ofp,
14965            "table-id %d, prefix %U/%d\n",
14966            ntohl (mp->table_id), format_ip4_address, mp->address,
14967            mp->address_length);
14968   fp = mp->path;
14969   for (i = 0; i < count; i++)
14970     {
14971       fformat (vam->ofp,
14972                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, is_unreach %d, "
14973                "is_prohitbit %d, afi %d, next_hop %U\n", ntohl (fp->weight),
14974                ntohl (fp->sw_if_index), fp->is_local, fp->is_drop,
14975                fp->is_unreach, fp->is_prohibit, fp->afi, format_ip46_address,
14976                fp->next_hop, fp->afi);
14977       fp++;
14978     }
14979 }
14980
14981 static void vl_api_ip_fib_details_t_handler_json
14982   (vl_api_ip_fib_details_t * mp)
14983 {
14984   vat_main_t *vam = &vat_main;
14985   int count = ntohl (mp->count);
14986   vat_json_node_t *node = NULL;
14987   struct in_addr ip4;
14988   struct in6_addr ip6;
14989   vl_api_fib_path_t *fp;
14990   int i;
14991
14992   if (VAT_JSON_ARRAY != vam->json_tree.type)
14993     {
14994       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14995       vat_json_init_array (&vam->json_tree);
14996     }
14997   node = vat_json_array_add (&vam->json_tree);
14998
14999   vat_json_init_object (node);
15000   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15001   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15002   vat_json_object_add_ip4 (node, "prefix", ip4);
15003   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15004   vat_json_object_add_uint (node, "path_count", count);
15005   fp = mp->path;
15006   for (i = 0; i < count; i++)
15007     {
15008       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15009       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15010       vat_json_object_add_uint (node, "is_local", fp->is_local);
15011       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15012       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15013       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15014       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15015       if (fp->afi == IP46_TYPE_IP4)
15016         {
15017           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15018           vat_json_object_add_ip4 (node, "next_hop", ip4);
15019         }
15020       else if (fp->afi == IP46_TYPE_IP6)
15021         {
15022           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15023           vat_json_object_add_ip6 (node, "next_hop", ip6);
15024         }
15025     }
15026 }
15027
15028 static int
15029 api_ip_fib_dump (vat_main_t * vam)
15030 {
15031   vl_api_ip_fib_dump_t *mp;
15032   f64 timeout;
15033
15034   M (IP_FIB_DUMP, ip_fib_dump);
15035   S;
15036
15037   /* Use a control ping for synchronization */
15038   {
15039     vl_api_control_ping_t *mp;
15040     M (CONTROL_PING, control_ping);
15041     S;
15042   }
15043   W;
15044 }
15045
15046 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15047 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15048
15049 static void
15050 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15051 {
15052   vat_main_t *vam = &vat_main;
15053   int count = ntohl (mp->count);
15054   vl_api_fib_path_t *fp;
15055   int i;
15056
15057   fformat (vam->ofp,
15058            "table-id %d, prefix %U/%d\n",
15059            ntohl (mp->table_id), format_ip6_address, mp->address,
15060            mp->address_length);
15061   fp = mp->path;
15062   for (i = 0; i < count; i++)
15063     {
15064       fformat (vam->ofp,
15065                "  weight %d, sw_if_index %d, is_local %d, is_drop %d, is_unreach %d, "
15066                "is_prohitbit %d, afi %d, next_hop %U\n", ntohl (fp->weight),
15067                ntohl (fp->sw_if_index), fp->is_local, fp->is_drop,
15068                fp->is_unreach, fp->is_prohibit, fp->afi, format_ip46_address,
15069                fp->next_hop, fp->afi);
15070       fp++;
15071     }
15072 }
15073
15074 static void vl_api_ip6_fib_details_t_handler_json
15075   (vl_api_ip6_fib_details_t * mp)
15076 {
15077   vat_main_t *vam = &vat_main;
15078   int count = ntohl (mp->count);
15079   vat_json_node_t *node = NULL;
15080   struct in_addr ip4;
15081   struct in6_addr ip6;
15082   vl_api_fib_path_t *fp;
15083   int i;
15084
15085   if (VAT_JSON_ARRAY != vam->json_tree.type)
15086     {
15087       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15088       vat_json_init_array (&vam->json_tree);
15089     }
15090   node = vat_json_array_add (&vam->json_tree);
15091
15092   vat_json_init_object (node);
15093   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15094   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15095   vat_json_object_add_ip6 (node, "prefix", ip6);
15096   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15097   vat_json_object_add_uint (node, "path_count", count);
15098   fp = mp->path;
15099   for (i = 0; i < count; i++)
15100     {
15101       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15102       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15103       vat_json_object_add_uint (node, "is_local", fp->is_local);
15104       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15105       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15106       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15107       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15108       if (fp->afi == IP46_TYPE_IP4)
15109         {
15110           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15111           vat_json_object_add_ip4 (node, "next_hop", ip4);
15112         }
15113       else if (fp->afi == IP46_TYPE_IP6)
15114         {
15115           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15116           vat_json_object_add_ip6 (node, "next_hop", ip6);
15117         }
15118     }
15119 }
15120
15121 static int
15122 api_ip6_fib_dump (vat_main_t * vam)
15123 {
15124   vl_api_ip6_fib_dump_t *mp;
15125   f64 timeout;
15126
15127   M (IP6_FIB_DUMP, ip6_fib_dump);
15128   S;
15129
15130   /* Use a control ping for synchronization */
15131   {
15132     vl_api_control_ping_t *mp;
15133     M (CONTROL_PING, control_ping);
15134     S;
15135   }
15136   W;
15137 }
15138
15139 int
15140 api_classify_table_ids (vat_main_t * vam)
15141 {
15142   vl_api_classify_table_ids_t *mp;
15143   f64 timeout;
15144
15145   /* Construct the API message */
15146   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15147   mp->context = 0;
15148
15149   S;
15150   W;
15151   /* NOTREACHED */
15152   return 0;
15153 }
15154
15155 int
15156 api_classify_table_by_interface (vat_main_t * vam)
15157 {
15158   unformat_input_t *input = vam->input;
15159   vl_api_classify_table_by_interface_t *mp;
15160   f64 timeout;
15161
15162   u32 sw_if_index = ~0;
15163   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15164     {
15165       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15166         ;
15167       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15168         ;
15169       else
15170         break;
15171     }
15172   if (sw_if_index == ~0)
15173     {
15174       errmsg ("missing interface name or sw_if_index\n");
15175       return -99;
15176     }
15177
15178   /* Construct the API message */
15179   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15180   mp->context = 0;
15181   mp->sw_if_index = ntohl (sw_if_index);
15182
15183   S;
15184   W;
15185   /* NOTREACHED */
15186   return 0;
15187 }
15188
15189 int
15190 api_classify_table_info (vat_main_t * vam)
15191 {
15192   unformat_input_t *input = vam->input;
15193   vl_api_classify_table_info_t *mp;
15194   f64 timeout;
15195
15196   u32 table_id = ~0;
15197   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15198     {
15199       if (unformat (input, "table_id %d", &table_id))
15200         ;
15201       else
15202         break;
15203     }
15204   if (table_id == ~0)
15205     {
15206       errmsg ("missing table id\n");
15207       return -99;
15208     }
15209
15210   /* Construct the API message */
15211   M (CLASSIFY_TABLE_INFO, classify_table_info);
15212   mp->context = 0;
15213   mp->table_id = ntohl (table_id);
15214
15215   S;
15216   W;
15217   /* NOTREACHED */
15218   return 0;
15219 }
15220
15221 int
15222 api_classify_session_dump (vat_main_t * vam)
15223 {
15224   unformat_input_t *input = vam->input;
15225   vl_api_classify_session_dump_t *mp;
15226   f64 timeout;
15227
15228   u32 table_id = ~0;
15229   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15230     {
15231       if (unformat (input, "table_id %d", &table_id))
15232         ;
15233       else
15234         break;
15235     }
15236   if (table_id == ~0)
15237     {
15238       errmsg ("missing table id\n");
15239       return -99;
15240     }
15241
15242   /* Construct the API message */
15243   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15244   mp->context = 0;
15245   mp->table_id = ntohl (table_id);
15246   S;
15247
15248   /* Use a control ping for synchronization */
15249   {
15250     vl_api_control_ping_t *mp;
15251     M (CONTROL_PING, control_ping);
15252     S;
15253   }
15254   W;
15255   /* NOTREACHED */
15256   return 0;
15257 }
15258
15259 static void
15260 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15261 {
15262   vat_main_t *vam = &vat_main;
15263
15264   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15265            "src_address %U, vrf_id %d, path_mtu %u, "
15266            "template_interval %u, udp_checksum %d\n",
15267            format_ip4_address, mp->collector_address,
15268            ntohs (mp->collector_port),
15269            format_ip4_address, mp->src_address,
15270            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15271            ntohl (mp->template_interval), mp->udp_checksum);
15272
15273   vam->retval = 0;
15274   vam->result_ready = 1;
15275 }
15276
15277 static void
15278   vl_api_ipfix_exporter_details_t_handler_json
15279   (vl_api_ipfix_exporter_details_t * mp)
15280 {
15281   vat_main_t *vam = &vat_main;
15282   vat_json_node_t node;
15283   struct in_addr collector_address;
15284   struct in_addr src_address;
15285
15286   vat_json_init_object (&node);
15287   clib_memcpy (&collector_address, &mp->collector_address,
15288                sizeof (collector_address));
15289   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15290   vat_json_object_add_uint (&node, "collector_port",
15291                             ntohs (mp->collector_port));
15292   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15293   vat_json_object_add_ip4 (&node, "src_address", src_address);
15294   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15295   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15296   vat_json_object_add_uint (&node, "template_interval",
15297                             ntohl (mp->template_interval));
15298   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15299
15300   vat_json_print (vam->ofp, &node);
15301   vat_json_free (&node);
15302   vam->retval = 0;
15303   vam->result_ready = 1;
15304 }
15305
15306 int
15307 api_ipfix_exporter_dump (vat_main_t * vam)
15308 {
15309   vl_api_ipfix_exporter_dump_t *mp;
15310   f64 timeout;
15311
15312   /* Construct the API message */
15313   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15314   mp->context = 0;
15315
15316   S;
15317   W;
15318   /* NOTREACHED */
15319   return 0;
15320 }
15321
15322 static int
15323 api_ipfix_classify_stream_dump (vat_main_t * vam)
15324 {
15325   vl_api_ipfix_classify_stream_dump_t *mp;
15326   f64 timeout;
15327
15328   /* Construct the API message */
15329   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15330   mp->context = 0;
15331
15332   S;
15333   W;
15334   /* NOTREACHED */
15335   return 0;
15336 }
15337
15338 static void
15339   vl_api_ipfix_classify_stream_details_t_handler
15340   (vl_api_ipfix_classify_stream_details_t * mp)
15341 {
15342   vat_main_t *vam = &vat_main;
15343   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15344            ntohl (mp->domain_id), ntohs (mp->src_port));
15345   vam->retval = 0;
15346   vam->result_ready = 1;
15347 }
15348
15349 static void
15350   vl_api_ipfix_classify_stream_details_t_handler_json
15351   (vl_api_ipfix_classify_stream_details_t * mp)
15352 {
15353   vat_main_t *vam = &vat_main;
15354   vat_json_node_t node;
15355
15356   vat_json_init_object (&node);
15357   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15358   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15359
15360   vat_json_print (vam->ofp, &node);
15361   vat_json_free (&node);
15362   vam->retval = 0;
15363   vam->result_ready = 1;
15364 }
15365
15366 static int
15367 api_ipfix_classify_table_dump (vat_main_t * vam)
15368 {
15369   vl_api_ipfix_classify_table_dump_t *mp;
15370   f64 timeout;
15371
15372   if (!vam->json_output)
15373     {
15374       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15375                "transport_protocol");
15376     }
15377
15378   /* Construct the API message */
15379   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15380
15381   /* send it... */
15382   S;
15383
15384   /* Use a control ping for synchronization */
15385   {
15386     vl_api_control_ping_t *mp;
15387     M (CONTROL_PING, control_ping);
15388     S;
15389   }
15390   W;
15391 }
15392
15393 static void
15394   vl_api_ipfix_classify_table_details_t_handler
15395   (vl_api_ipfix_classify_table_details_t * mp)
15396 {
15397   vat_main_t *vam = &vat_main;
15398   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15399            mp->transport_protocol);
15400 }
15401
15402 static void
15403   vl_api_ipfix_classify_table_details_t_handler_json
15404   (vl_api_ipfix_classify_table_details_t * mp)
15405 {
15406   vat_json_node_t *node = NULL;
15407   vat_main_t *vam = &vat_main;
15408
15409   if (VAT_JSON_ARRAY != vam->json_tree.type)
15410     {
15411       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15412       vat_json_init_array (&vam->json_tree);
15413     }
15414
15415   node = vat_json_array_add (&vam->json_tree);
15416   vat_json_init_object (node);
15417
15418   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15419   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15420   vat_json_object_add_uint (node, "transport_protocol",
15421                             mp->transport_protocol);
15422 }
15423
15424 static int
15425 api_sw_interface_span_enable_disable (vat_main_t * vam)
15426 {
15427   unformat_input_t *i = vam->input;
15428   vl_api_sw_interface_span_enable_disable_t *mp;
15429   f64 timeout;
15430   u32 src_sw_if_index = ~0;
15431   u32 dst_sw_if_index = ~0;
15432   u8 enable = 1;
15433
15434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15435     {
15436       if (unformat (i, "src %U", unformat_sw_if_index, vam, &src_sw_if_index))
15437         ;
15438       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15439         ;
15440       else
15441         if (unformat
15442             (i, "dst %U", unformat_sw_if_index, vam, &dst_sw_if_index))
15443         ;
15444       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15445         ;
15446       else if (unformat (i, "disable"))
15447         enable = 0;
15448       else
15449         break;
15450     }
15451
15452   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15453
15454   mp->sw_if_index_from = htonl (src_sw_if_index);
15455   mp->sw_if_index_to = htonl (dst_sw_if_index);
15456   mp->enable = enable;
15457
15458   S;
15459   W;
15460   /* NOTREACHED */
15461   return 0;
15462 }
15463
15464 static void
15465 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
15466                                             * mp)
15467 {
15468   vat_main_t *vam = &vat_main;
15469
15470   fformat (vam->ofp, "%u => %u\n",
15471            ntohl (mp->sw_if_index_from), ntohl (mp->sw_if_index_to));
15472 }
15473
15474 static void
15475   vl_api_sw_interface_span_details_t_handler_json
15476   (vl_api_sw_interface_span_details_t * mp)
15477 {
15478   vat_main_t *vam = &vat_main;
15479   vat_json_node_t *node = NULL;
15480
15481   if (VAT_JSON_ARRAY != vam->json_tree.type)
15482     {
15483       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15484       vat_json_init_array (&vam->json_tree);
15485     }
15486   node = vat_json_array_add (&vam->json_tree);
15487
15488   vat_json_init_object (node);
15489   vat_json_object_add_uint (node, "src-if-index",
15490                             ntohl (mp->sw_if_index_from));
15491   vat_json_object_add_uint (node, "dst-if-index", ntohl (mp->sw_if_index_to));
15492 }
15493
15494 static int
15495 api_sw_interface_span_dump (vat_main_t * vam)
15496 {
15497   vl_api_sw_interface_span_dump_t *mp;
15498   f64 timeout;
15499
15500   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
15501   S;
15502
15503   /* Use a control ping for synchronization */
15504   {
15505     vl_api_control_ping_t *mp;
15506     M (CONTROL_PING, control_ping);
15507     S;
15508   }
15509   W;
15510 }
15511
15512 int
15513 api_pg_create_interface (vat_main_t * vam)
15514 {
15515   unformat_input_t *input = vam->input;
15516   vl_api_pg_create_interface_t *mp;
15517   f64 timeout;
15518
15519   u32 if_id = ~0;
15520   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15521     {
15522       if (unformat (input, "if_id %d", &if_id))
15523         ;
15524       else
15525         break;
15526     }
15527   if (if_id == ~0)
15528     {
15529       errmsg ("missing pg interface index\n");
15530       return -99;
15531     }
15532
15533   /* Construct the API message */
15534   M (PG_CREATE_INTERFACE, pg_create_interface);
15535   mp->context = 0;
15536   mp->interface_id = ntohl (if_id);
15537
15538   S;
15539   W;
15540   /* NOTREACHED */
15541   return 0;
15542 }
15543
15544 int
15545 api_pg_capture (vat_main_t * vam)
15546 {
15547   unformat_input_t *input = vam->input;
15548   vl_api_pg_capture_t *mp;
15549   f64 timeout;
15550
15551   u32 if_id = ~0;
15552   u8 enable = 1;
15553   u32 count = 1;
15554   u8 pcap_file_set = 0;
15555   u8 *pcap_file = 0;
15556   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15557     {
15558       if (unformat (input, "if_id %d", &if_id))
15559         ;
15560       else if (unformat (input, "pcap %s", &pcap_file))
15561         pcap_file_set = 1;
15562       else if (unformat (input, "count %d", &count))
15563         ;
15564       else if (unformat (input, "disable"))
15565         enable = 0;
15566       else
15567         break;
15568     }
15569   if (if_id == ~0)
15570     {
15571       errmsg ("missing pg interface index\n");
15572       return -99;
15573     }
15574   if (pcap_file_set > 0)
15575     {
15576       if (vec_len (pcap_file) > 255)
15577         {
15578           errmsg ("pcap file name is too long\n");
15579           return -99;
15580         }
15581     }
15582
15583   u32 name_len = vec_len (pcap_file);
15584   /* Construct the API message */
15585   M (PG_CAPTURE, pg_capture);
15586   mp->context = 0;
15587   mp->interface_id = ntohl (if_id);
15588   mp->is_enabled = enable;
15589   mp->count = ntohl (count);
15590   mp->pcap_name_length = ntohl (name_len);
15591   if (pcap_file_set != 0)
15592     {
15593       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15594     }
15595   vec_free (pcap_file);
15596
15597   S;
15598   W;
15599   /* NOTREACHED */
15600   return 0;
15601 }
15602
15603 int
15604 api_pg_enable_disable (vat_main_t * vam)
15605 {
15606   unformat_input_t *input = vam->input;
15607   vl_api_pg_enable_disable_t *mp;
15608   f64 timeout;
15609
15610   u8 enable = 1;
15611   u8 stream_name_set = 0;
15612   u8 *stream_name = 0;
15613   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15614     {
15615       if (unformat (input, "stream %s", &stream_name))
15616         stream_name_set = 1;
15617       else if (unformat (input, "disable"))
15618         enable = 0;
15619       else
15620         break;
15621     }
15622
15623   if (stream_name_set > 0)
15624     {
15625       if (vec_len (stream_name) > 255)
15626         {
15627           errmsg ("stream name too long\n");
15628           return -99;
15629         }
15630     }
15631
15632   u32 name_len = vec_len (stream_name);
15633   /* Construct the API message */
15634   M (PG_ENABLE_DISABLE, pg_enable_disable);
15635   mp->context = 0;
15636   mp->is_enabled = enable;
15637   if (stream_name_set != 0)
15638     {
15639       mp->stream_name_length = ntohl (name_len);
15640       clib_memcpy (mp->stream_name, stream_name, name_len);
15641     }
15642   vec_free (stream_name);
15643
15644   S;
15645   W;
15646   /* NOTREACHED */
15647   return 0;
15648 }
15649
15650 int
15651 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15652 {
15653   unformat_input_t *input = vam->input;
15654   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15655   f64 timeout;
15656
15657   u16 *low_ports = 0;
15658   u16 *high_ports = 0;
15659   u16 this_low;
15660   u16 this_hi;
15661   ip4_address_t ip4_addr;
15662   ip6_address_t ip6_addr;
15663   u32 length;
15664   u32 tmp, tmp2;
15665   u8 prefix_set = 0;
15666   u32 vrf_id = ~0;
15667   u8 is_add = 1;
15668   u8 is_ipv6 = 0;
15669
15670   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15671     {
15672       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15673         {
15674           prefix_set = 1;
15675         }
15676       else
15677         if (unformat
15678             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15679         {
15680           prefix_set = 1;
15681           is_ipv6 = 1;
15682         }
15683       else if (unformat (input, "vrf %d", &vrf_id))
15684         ;
15685       else if (unformat (input, "del"))
15686         is_add = 0;
15687       else if (unformat (input, "port %d", &tmp))
15688         {
15689           if (tmp == 0 || tmp > 65535)
15690             {
15691               errmsg ("port %d out of range", tmp);
15692               return -99;
15693             }
15694           this_low = tmp;
15695           this_hi = this_low + 1;
15696           vec_add1 (low_ports, this_low);
15697           vec_add1 (high_ports, this_hi);
15698         }
15699       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15700         {
15701           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15702             {
15703               errmsg ("incorrect range parameters\n");
15704               return -99;
15705             }
15706           this_low = tmp;
15707           /* Note: in debug CLI +1 is added to high before
15708              passing to real fn that does "the work"
15709              (ip_source_and_port_range_check_add_del).
15710              This fn is a wrapper around the binary API fn a
15711              control plane will call, which expects this increment
15712              to have occurred. Hence letting the binary API control
15713              plane fn do the increment for consistency between VAT
15714              and other control planes.
15715            */
15716           this_hi = tmp2;
15717           vec_add1 (low_ports, this_low);
15718           vec_add1 (high_ports, this_hi);
15719         }
15720       else
15721         break;
15722     }
15723
15724   if (prefix_set == 0)
15725     {
15726       errmsg ("<address>/<mask> not specified\n");
15727       return -99;
15728     }
15729
15730   if (vrf_id == ~0)
15731     {
15732       errmsg ("VRF ID required, not specified\n");
15733       return -99;
15734     }
15735
15736   if (vrf_id == 0)
15737     {
15738       errmsg
15739         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15740       return -99;
15741     }
15742
15743   if (vec_len (low_ports) == 0)
15744     {
15745       errmsg ("At least one port or port range required\n");
15746       return -99;
15747     }
15748
15749   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15750      ip_source_and_port_range_check_add_del);
15751
15752   mp->is_add = is_add;
15753
15754   if (is_ipv6)
15755     {
15756       mp->is_ipv6 = 1;
15757       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15758     }
15759   else
15760     {
15761       mp->is_ipv6 = 0;
15762       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15763     }
15764
15765   mp->mask_length = length;
15766   mp->number_of_ranges = vec_len (low_ports);
15767
15768   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15769   vec_free (low_ports);
15770
15771   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15772   vec_free (high_ports);
15773
15774   mp->vrf_id = ntohl (vrf_id);
15775
15776   S;
15777   W;
15778   /* NOTREACHED */
15779   return 0;
15780 }
15781
15782 int
15783 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15784 {
15785   unformat_input_t *input = vam->input;
15786   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15787   f64 timeout;
15788   u32 sw_if_index = ~0;
15789   int vrf_set = 0;
15790   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15791   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15792   u8 is_add = 1;
15793
15794   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15795     {
15796       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15797         ;
15798       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15799         ;
15800       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15801         vrf_set = 1;
15802       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15803         vrf_set = 1;
15804       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15805         vrf_set = 1;
15806       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15807         vrf_set = 1;
15808       else if (unformat (input, "del"))
15809         is_add = 0;
15810       else
15811         break;
15812     }
15813
15814   if (sw_if_index == ~0)
15815     {
15816       errmsg ("Interface required but not specified\n");
15817       return -99;
15818     }
15819
15820   if (vrf_set == 0)
15821     {
15822       errmsg ("VRF ID required but not specified\n");
15823       return -99;
15824     }
15825
15826   if (tcp_out_vrf_id == 0
15827       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15828     {
15829       errmsg
15830         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15831       return -99;
15832     }
15833
15834   /* Construct the API message */
15835   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15836      ip_source_and_port_range_check_interface_add_del);
15837
15838   mp->sw_if_index = ntohl (sw_if_index);
15839   mp->is_add = is_add;
15840   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15841   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15842   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15843   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15844
15845   /* send it... */
15846   S;
15847
15848   /* Wait for a reply... */
15849   W;
15850 }
15851
15852 static int
15853 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15854 {
15855   unformat_input_t *i = vam->input;
15856   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15857   f64 timeout;
15858   u32 local_sa_id = 0;
15859   u32 remote_sa_id = 0;
15860   ip4_address_t src_address;
15861   ip4_address_t dst_address;
15862   u8 is_add = 1;
15863
15864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15865     {
15866       if (unformat (i, "local_sa %d", &local_sa_id))
15867         ;
15868       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15869         ;
15870       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15871         ;
15872       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15873         ;
15874       else if (unformat (i, "del"))
15875         is_add = 0;
15876       else
15877         {
15878           clib_warning ("parse error '%U'", format_unformat_error, i);
15879           return -99;
15880         }
15881     }
15882
15883   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15884
15885   mp->local_sa_id = ntohl (local_sa_id);
15886   mp->remote_sa_id = ntohl (remote_sa_id);
15887   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15888   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15889   mp->is_add = is_add;
15890
15891   S;
15892   W;
15893   /* NOTREACHED */
15894   return 0;
15895 }
15896
15897 static int
15898 api_punt (vat_main_t * vam)
15899 {
15900   unformat_input_t *i = vam->input;
15901   vl_api_punt_t *mp;
15902   f64 timeout;
15903   u32 ipv = ~0;
15904   u32 protocol = ~0;
15905   u32 port = ~0;
15906   int is_add = 1;
15907
15908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15909     {
15910       if (unformat (i, "ip %d", &ipv))
15911         ;
15912       else if (unformat (i, "protocol %d", &protocol))
15913         ;
15914       else if (unformat (i, "port %d", &port))
15915         ;
15916       else if (unformat (i, "del"))
15917         is_add = 0;
15918       else
15919         {
15920           clib_warning ("parse error '%U'", format_unformat_error, i);
15921           return -99;
15922         }
15923     }
15924
15925   M (PUNT, punt);
15926
15927   mp->is_add = (u8) is_add;
15928   mp->ipv = (u8) ipv;
15929   mp->l4_protocol = (u8) protocol;
15930   mp->l4_port = htons ((u16) port);
15931
15932   S;
15933   W;
15934   /* NOTREACHED */
15935   return 0;
15936 }
15937
15938 static void vl_api_ipsec_gre_tunnel_details_t_handler
15939   (vl_api_ipsec_gre_tunnel_details_t * mp)
15940 {
15941   vat_main_t *vam = &vat_main;
15942
15943   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15944            ntohl (mp->sw_if_index),
15945            format_ip4_address, &mp->src_address,
15946            format_ip4_address, &mp->dst_address,
15947            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15948 }
15949
15950 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15951   (vl_api_ipsec_gre_tunnel_details_t * mp)
15952 {
15953   vat_main_t *vam = &vat_main;
15954   vat_json_node_t *node = NULL;
15955   struct in_addr ip4;
15956
15957   if (VAT_JSON_ARRAY != vam->json_tree.type)
15958     {
15959       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15960       vat_json_init_array (&vam->json_tree);
15961     }
15962   node = vat_json_array_add (&vam->json_tree);
15963
15964   vat_json_init_object (node);
15965   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15966   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15967   vat_json_object_add_ip4 (node, "src_address", ip4);
15968   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15969   vat_json_object_add_ip4 (node, "dst_address", ip4);
15970   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15971   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15972 }
15973
15974 static int
15975 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15976 {
15977   unformat_input_t *i = vam->input;
15978   vl_api_ipsec_gre_tunnel_dump_t *mp;
15979   f64 timeout;
15980   u32 sw_if_index;
15981   u8 sw_if_index_set = 0;
15982
15983   /* Parse args required to build the message */
15984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15985     {
15986       if (unformat (i, "sw_if_index %d", &sw_if_index))
15987         sw_if_index_set = 1;
15988       else
15989         break;
15990     }
15991
15992   if (sw_if_index_set == 0)
15993     {
15994       sw_if_index = ~0;
15995     }
15996
15997   if (!vam->json_output)
15998     {
15999       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
16000                "sw_if_index", "src_address", "dst_address",
16001                "local_sa_id", "remote_sa_id");
16002     }
16003
16004   /* Get list of gre-tunnel interfaces */
16005   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16006
16007   mp->sw_if_index = htonl (sw_if_index);
16008
16009   S;
16010
16011   /* Use a control ping for synchronization */
16012   {
16013     vl_api_control_ping_t *mp;
16014     M (CONTROL_PING, control_ping);
16015     S;
16016   }
16017   W;
16018 }
16019
16020 static int
16021 api_delete_subif (vat_main_t * vam)
16022 {
16023   unformat_input_t *i = vam->input;
16024   vl_api_delete_subif_t *mp;
16025   f64 timeout;
16026   u32 sw_if_index = ~0;
16027
16028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16029     {
16030       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16031         ;
16032       if (unformat (i, "sw_if_index %d", &sw_if_index))
16033         ;
16034       else
16035         break;
16036     }
16037
16038   if (sw_if_index == ~0)
16039     {
16040       errmsg ("missing sw_if_index\n");
16041       return -99;
16042     }
16043
16044   /* Construct the API message */
16045   M (DELETE_SUBIF, delete_subif);
16046   mp->sw_if_index = ntohl (sw_if_index);
16047
16048   S;
16049   W;
16050 }
16051
16052 #define foreach_pbb_vtr_op      \
16053 _("disable",  L2_VTR_DISABLED)  \
16054 _("pop",  L2_VTR_POP_2)         \
16055 _("push",  L2_VTR_PUSH_2)
16056
16057 static int
16058 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16059 {
16060   unformat_input_t *i = vam->input;
16061   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16062   f64 timeout;
16063   u32 sw_if_index = ~0, vtr_op = ~0;
16064   u16 outer_tag = ~0;
16065   u8 dmac[6], smac[6];
16066   u8 dmac_set = 0, smac_set = 0;
16067   u16 vlanid = 0;
16068   u32 sid = ~0;
16069   u32 tmp;
16070
16071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16072     {
16073       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16074         ;
16075       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16076         ;
16077       else if (unformat (i, "vtr_op %d", &vtr_op))
16078         ;
16079 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16080       foreach_pbb_vtr_op
16081 #undef _
16082         else if (unformat (i, "translate_pbb_stag"))
16083         {
16084           if (unformat (i, "%d", &tmp))
16085             {
16086               vtr_op = L2_VTR_TRANSLATE_2_1;
16087               outer_tag = tmp;
16088             }
16089           else
16090             {
16091               errmsg
16092                 ("translate_pbb_stag operation requires outer tag definition\n");
16093               return -99;
16094             }
16095         }
16096       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16097         dmac_set++;
16098       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16099         smac_set++;
16100       else if (unformat (i, "sid %d", &sid))
16101         ;
16102       else if (unformat (i, "vlanid %d", &tmp))
16103         vlanid = tmp;
16104       else
16105         {
16106           clib_warning ("parse error '%U'", format_unformat_error, i);
16107           return -99;
16108         }
16109     }
16110
16111   if ((sw_if_index == ~0) || (vtr_op == ~0))
16112     {
16113       errmsg ("missing sw_if_index or vtr operation\n");
16114       return -99;
16115     }
16116   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16117       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16118     {
16119       errmsg
16120         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
16121       return -99;
16122     }
16123
16124   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16125   mp->sw_if_index = ntohl (sw_if_index);
16126   mp->vtr_op = ntohl (vtr_op);
16127   mp->outer_tag = ntohs (outer_tag);
16128   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16129   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16130   mp->b_vlanid = ntohs (vlanid);
16131   mp->i_sid = ntohl (sid);
16132
16133   S;
16134   W;
16135   /* NOTREACHED */
16136   return 0;
16137 }
16138
16139 static int
16140 api_flow_classify_set_interface (vat_main_t * vam)
16141 {
16142   unformat_input_t *i = vam->input;
16143   vl_api_flow_classify_set_interface_t *mp;
16144   f64 timeout;
16145   u32 sw_if_index;
16146   int sw_if_index_set;
16147   u32 ip4_table_index = ~0;
16148   u32 ip6_table_index = ~0;
16149   u8 is_add = 1;
16150
16151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16152     {
16153       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16154         sw_if_index_set = 1;
16155       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16156         sw_if_index_set = 1;
16157       else if (unformat (i, "del"))
16158         is_add = 0;
16159       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16160         ;
16161       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16162         ;
16163       else
16164         {
16165           clib_warning ("parse error '%U'", format_unformat_error, i);
16166           return -99;
16167         }
16168     }
16169
16170   if (sw_if_index_set == 0)
16171     {
16172       errmsg ("missing interface name or sw_if_index\n");
16173       return -99;
16174     }
16175
16176   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16177
16178   mp->sw_if_index = ntohl (sw_if_index);
16179   mp->ip4_table_index = ntohl (ip4_table_index);
16180   mp->ip6_table_index = ntohl (ip6_table_index);
16181   mp->is_add = is_add;
16182
16183   S;
16184   W;
16185   /* NOTREACHED */
16186   return 0;
16187 }
16188
16189 static int
16190 api_flow_classify_dump (vat_main_t * vam)
16191 {
16192   unformat_input_t *i = vam->input;
16193   vl_api_flow_classify_dump_t *mp;
16194   f64 timeout = ~0;
16195   u8 type = FLOW_CLASSIFY_N_TABLES;
16196
16197   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16198     ;
16199   else
16200     {
16201       errmsg ("classify table type must be specified\n");
16202       return -99;
16203     }
16204
16205   if (!vam->json_output)
16206     {
16207       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
16208     }
16209
16210   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16211   mp->type = type;
16212   /* send it... */
16213   S;
16214
16215   /* Use a control ping for synchronization */
16216   {
16217     vl_api_control_ping_t *mp;
16218     M (CONTROL_PING, control_ping);
16219     S;
16220   }
16221   /* Wait for a reply... */
16222   W;
16223
16224   /* NOTREACHED */
16225   return 0;
16226 }
16227
16228 static int
16229 q_or_quit (vat_main_t * vam)
16230 {
16231   longjmp (vam->jump_buf, 1);
16232   return 0;                     /* not so much */
16233 }
16234
16235 static int
16236 q (vat_main_t * vam)
16237 {
16238   return q_or_quit (vam);
16239 }
16240
16241 static int
16242 quit (vat_main_t * vam)
16243 {
16244   return q_or_quit (vam);
16245 }
16246
16247 static int
16248 comment (vat_main_t * vam)
16249 {
16250   return 0;
16251 }
16252
16253 static int
16254 cmd_cmp (void *a1, void *a2)
16255 {
16256   u8 **c1 = a1;
16257   u8 **c2 = a2;
16258
16259   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
16260 }
16261
16262 static int
16263 help (vat_main_t * vam)
16264 {
16265   u8 **cmds = 0;
16266   u8 *name = 0;
16267   hash_pair_t *p;
16268   unformat_input_t *i = vam->input;
16269   int j;
16270
16271   if (unformat (i, "%s", &name))
16272     {
16273       uword *hs;
16274
16275       vec_add1 (name, 0);
16276
16277       hs = hash_get_mem (vam->help_by_name, name);
16278       if (hs)
16279         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
16280       else
16281         fformat (vam->ofp, "No such msg / command '%s'\n", name);
16282       vec_free (name);
16283       return 0;
16284     }
16285
16286   fformat (vam->ofp, "Help is available for the following:\n");
16287
16288     /* *INDENT-OFF* */
16289     hash_foreach_pair (p, vam->function_by_name,
16290     ({
16291       vec_add1 (cmds, (u8 *)(p->key));
16292     }));
16293     /* *INDENT-ON* */
16294
16295   vec_sort_with_function (cmds, cmd_cmp);
16296
16297   for (j = 0; j < vec_len (cmds); j++)
16298     fformat (vam->ofp, "%s\n", cmds[j]);
16299
16300   vec_free (cmds);
16301   return 0;
16302 }
16303
16304 static int
16305 set (vat_main_t * vam)
16306 {
16307   u8 *name = 0, *value = 0;
16308   unformat_input_t *i = vam->input;
16309
16310   if (unformat (i, "%s", &name))
16311     {
16312       /* The input buffer is a vector, not a string. */
16313       value = vec_dup (i->buffer);
16314       vec_delete (value, i->index, 0);
16315       /* Almost certainly has a trailing newline */
16316       if (value[vec_len (value) - 1] == '\n')
16317         value[vec_len (value) - 1] = 0;
16318       /* Make sure it's a proper string, one way or the other */
16319       vec_add1 (value, 0);
16320       (void) clib_macro_set_value (&vam->macro_main,
16321                                    (char *) name, (char *) value);
16322     }
16323   else
16324     errmsg ("usage: set <name> <value>\n");
16325
16326   vec_free (name);
16327   vec_free (value);
16328   return 0;
16329 }
16330
16331 static int
16332 unset (vat_main_t * vam)
16333 {
16334   u8 *name = 0;
16335
16336   if (unformat (vam->input, "%s", &name))
16337     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
16338       errmsg ("unset: %s wasn't set\n", name);
16339   vec_free (name);
16340   return 0;
16341 }
16342
16343 typedef struct
16344 {
16345   u8 *name;
16346   u8 *value;
16347 } macro_sort_t;
16348
16349
16350 static int
16351 macro_sort_cmp (void *a1, void *a2)
16352 {
16353   macro_sort_t *s1 = a1;
16354   macro_sort_t *s2 = a2;
16355
16356   return strcmp ((char *) (s1->name), (char *) (s2->name));
16357 }
16358
16359 static int
16360 dump_macro_table (vat_main_t * vam)
16361 {
16362   macro_sort_t *sort_me = 0, *sm;
16363   int i;
16364   hash_pair_t *p;
16365
16366     /* *INDENT-OFF* */
16367     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
16368     ({
16369       vec_add2 (sort_me, sm, 1);
16370       sm->name = (u8 *)(p->key);
16371       sm->value = (u8 *) (p->value[0]);
16372     }));
16373     /* *INDENT-ON* */
16374
16375   vec_sort_with_function (sort_me, macro_sort_cmp);
16376
16377   if (vec_len (sort_me))
16378     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
16379   else
16380     fformat (vam->ofp, "The macro table is empty...\n");
16381
16382   for (i = 0; i < vec_len (sort_me); i++)
16383     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
16384   return 0;
16385 }
16386
16387 static int
16388 dump_node_table (vat_main_t * vam)
16389 {
16390   int i, j;
16391   vlib_node_t *node, *next_node;
16392
16393   if (vec_len (vam->graph_nodes) == 0)
16394     {
16395       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16396       return 0;
16397     }
16398
16399   for (i = 0; i < vec_len (vam->graph_nodes); i++)
16400     {
16401       node = vam->graph_nodes[i];
16402       fformat (vam->ofp, "[%d] %s\n", i, node->name);
16403       for (j = 0; j < vec_len (node->next_nodes); j++)
16404         {
16405           if (node->next_nodes[j] != ~0)
16406             {
16407               next_node = vam->graph_nodes[node->next_nodes[j]];
16408               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16409             }
16410         }
16411     }
16412   return 0;
16413 }
16414
16415 static int
16416 search_node_table (vat_main_t * vam)
16417 {
16418   unformat_input_t *line_input = vam->input;
16419   u8 *node_to_find;
16420   int j;
16421   vlib_node_t *node, *next_node;
16422   uword *p;
16423
16424   if (vam->graph_node_index_by_name == 0)
16425     {
16426       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16427       return 0;
16428     }
16429
16430   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16431     {
16432       if (unformat (line_input, "%s", &node_to_find))
16433         {
16434           vec_add1 (node_to_find, 0);
16435           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
16436           if (p == 0)
16437             {
16438               fformat (vam->ofp, "%s not found...\n", node_to_find);
16439               goto out;
16440             }
16441           node = vam->graph_nodes[p[0]];
16442           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
16443           for (j = 0; j < vec_len (node->next_nodes); j++)
16444             {
16445               if (node->next_nodes[j] != ~0)
16446                 {
16447                   next_node = vam->graph_nodes[node->next_nodes[j]];
16448                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16449                 }
16450             }
16451         }
16452
16453       else
16454         {
16455           clib_warning ("parse error '%U'", format_unformat_error,
16456                         line_input);
16457           return -99;
16458         }
16459
16460     out:
16461       vec_free (node_to_find);
16462
16463     }
16464
16465   return 0;
16466 }
16467
16468
16469 static int
16470 script (vat_main_t * vam)
16471 {
16472   u8 *s = 0;
16473   char *save_current_file;
16474   unformat_input_t save_input;
16475   jmp_buf save_jump_buf;
16476   u32 save_line_number;
16477
16478   FILE *new_fp, *save_ifp;
16479
16480   if (unformat (vam->input, "%s", &s))
16481     {
16482       new_fp = fopen ((char *) s, "r");
16483       if (new_fp == 0)
16484         {
16485           errmsg ("Couldn't open script file %s\n", s);
16486           vec_free (s);
16487           return -99;
16488         }
16489     }
16490   else
16491     {
16492       errmsg ("Missing script name\n");
16493       return -99;
16494     }
16495
16496   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
16497   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
16498   save_ifp = vam->ifp;
16499   save_line_number = vam->input_line_number;
16500   save_current_file = (char *) vam->current_file;
16501
16502   vam->input_line_number = 0;
16503   vam->ifp = new_fp;
16504   vam->current_file = s;
16505   do_one_file (vam);
16506
16507   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
16508   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
16509   vam->ifp = save_ifp;
16510   vam->input_line_number = save_line_number;
16511   vam->current_file = (u8 *) save_current_file;
16512   vec_free (s);
16513
16514   return 0;
16515 }
16516
16517 static int
16518 echo (vat_main_t * vam)
16519 {
16520   fformat (vam->ofp, "%v", vam->input->buffer);
16521   return 0;
16522 }
16523
16524 /* List of API message constructors, CLI names map to api_xxx */
16525 #define foreach_vpe_api_msg                                             \
16526 _(create_loopback,"[mac <mac-addr>]")                                   \
16527 _(sw_interface_dump,"")                                                 \
16528 _(sw_interface_set_flags,                                               \
16529   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
16530 _(sw_interface_add_del_address,                                         \
16531   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
16532 _(sw_interface_set_table,                                               \
16533   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
16534 _(sw_interface_set_mpls_enable,                                                \
16535   "<intfc> | sw_if_index [disable | dis]")                                \
16536 _(sw_interface_set_vpath,                                               \
16537   "<intfc> | sw_if_index <id> enable | disable")                        \
16538 _(sw_interface_set_l2_xconnect,                                         \
16539   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16540   "enable | disable")                                                   \
16541 _(sw_interface_set_l2_bridge,                                           \
16542   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16543   "[shg <split-horizon-group>] [bvi]\n"                                 \
16544   "enable | disable")                                                   \
16545 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16546   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16547   "profile <profile-id>\n")                                             \
16548 _(sw_interface_set_dpdk_hqos_subport,                                   \
16549   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16550   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16551 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16552   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16553 _(bridge_domain_add_del,                                                \
16554   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16555 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16556 _(l2fib_add_del,                                                        \
16557   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16558 _(l2_flags,                                                             \
16559   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16560 _(bridge_flags,                                                         \
16561   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16562 _(tap_connect,                                                          \
16563   "tapname <name> mac <mac-addr> | random-mac")                         \
16564 _(tap_modify,                                                           \
16565   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16566 _(tap_delete,                                                           \
16567   "<vpp-if-name> | sw_if_index <id>")                                   \
16568 _(sw_interface_tap_dump, "")                                            \
16569 _(ip_add_del_route,                                                     \
16570   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
16571   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16572   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16573   "[multipath] [count <n>]")                                            \
16574 _(mpls_route_add_del,                                                   \
16575   "<label> <eos> via <addr> [table-id <n>]\n"                           \
16576   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16577   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16578   "[multipath] [count <n>]")                                            \
16579 _(mpls_ip_bind_unbind,                                                  \
16580   "<label> <addr/len>")                                                 \
16581 _(proxy_arp_add_del,                                                    \
16582   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16583 _(proxy_arp_intfc_enable_disable,                                       \
16584   "<intfc> | sw_if_index <id> enable | disable")                        \
16585 _(mpls_add_del_encap,                                                   \
16586   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
16587 _(sw_interface_set_unnumbered,                                          \
16588   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16589 _(ip_neighbor_add_del,                                                  \
16590   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16591   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16592 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16593 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16594 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16595   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16596   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16597   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16598 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16599 _(reset_fib, "vrf <n> [ipv6]")                                          \
16600 _(dhcp_proxy_config,                                                    \
16601   "svr <v46-address> src <v46-address>\n"                               \
16602    "insert-cid <n> [del]")                                              \
16603 _(dhcp_proxy_config_2,                                                  \
16604   "svr <v46-address> src <v46-address>\n"                               \
16605    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16606 _(dhcp_proxy_set_vss,                                                   \
16607   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16608 _(dhcp_client_config,                                                   \
16609   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16610 _(set_ip_flow_hash,                                                     \
16611   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16612 _(sw_interface_ip6_enable_disable,                                      \
16613   "<intfc> | sw_if_index <id> enable | disable")                        \
16614 _(sw_interface_ip6_set_link_local_address,                              \
16615   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16616 _(sw_interface_ip6nd_ra_prefix,                                         \
16617   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16618   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16619   "[nolink] [isno]")                                                    \
16620 _(sw_interface_ip6nd_ra_config,                                         \
16621   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16622   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16623   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16624 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16625 _(l2_patch_add_del,                                                     \
16626   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16627   "enable | disable")                                                   \
16628 _(mpls_ethernet_add_del_tunnel,                                         \
16629   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
16630   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
16631 _(mpls_ethernet_add_del_tunnel_2,                                       \
16632   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
16633   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
16634 _(sr_tunnel_add_del,                                                    \
16635   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16636   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16637   "[policy <policy_name>]")                                             \
16638 _(sr_policy_add_del,                                                    \
16639   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16640 _(sr_multicast_map_add_del,                                             \
16641   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16642 _(classify_add_del_table,                                               \
16643   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16644   "[del] mask <mask-value>\n"                                           \
16645   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>")              \
16646 _(classify_add_del_session,                                             \
16647   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16648   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16649   "  [l3 [ip4|ip6]]")                                                   \
16650 _(classify_set_interface_ip_table,                                      \
16651   "<intfc> | sw_if_index <nn> table <nn>")                              \
16652 _(classify_set_interface_l2_tables,                                     \
16653   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16654   "  [other-table <nn>]")                                               \
16655 _(get_node_index, "node <node-name")                                    \
16656 _(add_node_next, "node <node-name> next <next-node-name>")              \
16657 _(l2tpv3_create_tunnel,                                                 \
16658   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16659   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16660   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16661 _(l2tpv3_set_tunnel_cookies,                                            \
16662   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16663   "[new_remote_cookie <nn>]\n")                                         \
16664 _(l2tpv3_interface_enable_disable,                                      \
16665   "<intfc> | sw_if_index <nn> enable | disable")                        \
16666 _(l2tpv3_set_lookup_key,                                                \
16667   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16668 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16669 _(vxlan_add_del_tunnel,                                                 \
16670   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
16671   " [decap-next l2|ip4|ip6] [del]")                                     \
16672 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16673 _(gre_add_del_tunnel,                                                   \
16674   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16675 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16676 _(l2_fib_clear_table, "")                                               \
16677 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16678 _(l2_interface_vlan_tag_rewrite,                                        \
16679   "<intfc> | sw_if_index <nn> \n"                                       \
16680   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
16681   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
16682 _(create_vhost_user_if,                                                 \
16683         "socket <filename> [server] [renumber <dev_instance>] "         \
16684         "[mac <mac_address>]")                                          \
16685 _(modify_vhost_user_if,                                                 \
16686         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
16687         "[server] [renumber <dev_instance>]")                           \
16688 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
16689 _(sw_interface_vhost_user_dump, "")                                     \
16690 _(show_version, "")                                                     \
16691 _(vxlan_gpe_add_del_tunnel,                                             \
16692   "local <addr> remote <addr> vni <nn>\n"                               \
16693     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
16694   "[next-ethernet] [next-nsh]\n")                                       \
16695 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
16696 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
16697 _(interface_name_renumber,                                              \
16698   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
16699 _(input_acl_set_interface,                                              \
16700   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16701   "  [l2-table <nn>] [del]")                                            \
16702 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
16703 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
16704 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
16705 _(ip_dump, "ipv4 | ipv6")                                               \
16706 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
16707 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
16708   "  spid_id <n> ")                                                     \
16709 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
16710   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
16711   "  integ_alg <alg> integ_key <hex>")                                  \
16712 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
16713   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
16714   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
16715   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
16716 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
16717 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
16718 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
16719   "(auth_data 0x<data> | auth_data <data>)")                            \
16720 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
16721   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
16722 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16723   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16724   "(local|remote)")                                                     \
16725 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16726 _(delete_loopback,"sw_if_index <nn>")                                   \
16727 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16728 _(map_add_domain,                                                       \
16729   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16730   "ip6-src <ip6addr> "                                                  \
16731   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16732 _(map_del_domain, "index <n>")                                          \
16733 _(map_add_del_rule,                                                     \
16734   "index <n> psid <n> dst <ip6addr> [del]")                             \
16735 _(map_domain_dump, "")                                                  \
16736 _(map_rule_dump, "index <map-domain>")                                  \
16737 _(want_interface_events,  "enable|disable")                             \
16738 _(want_stats,"enable|disable")                                          \
16739 _(get_first_msg_id, "client <name>")                                    \
16740 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16741 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16742   "fib-id <nn> [ip4][ip6][default]")                                    \
16743 _(get_node_graph, " ")                                                  \
16744 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16745 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16746 _(ioam_disable, "")                                                \
16747 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16748                             " sw_if_index <sw_if_index> p <priority> "  \
16749                             "w <weight>] [del]")                        \
16750 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16751                         "iface <intf> | sw_if_index <sw_if_index> "     \
16752                         "p <priority> w <weight> [del]")                \
16753 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16754                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16755                           "locator-set <locator_name> [del]")           \
16756 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16757   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16758 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16759 _(lisp_gpe_enable_disable, "enable|disable")                            \
16760 _(lisp_enable_disable, "enable|disable")                                \
16761 _(lisp_gpe_add_del_iface, "up|down")                                    \
16762 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
16763                                "[seid <seid>] "                         \
16764                                "rloc <locator> p <prio> "               \
16765                                "w <weight> [rloc <loc> ... ] "          \
16766                                "action <action> [del-all]")             \
16767 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
16768                           "<local-eid>")                                \
16769 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16770 _(lisp_map_request_mode, "src-dst|dst-only")                            \
16771 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16772 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16773 _(lisp_locator_set_dump, "[local | remote]")                            \
16774 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
16775 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16776                        "[local] | [remote]")                            \
16777 _(lisp_eid_table_vni_dump, "")                                          \
16778 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16779 _(lisp_gpe_tunnel_dump, "")                                             \
16780 _(lisp_map_resolver_dump, "")                                           \
16781 _(lisp_adjacencies_get, "vni <vni>")                                    \
16782 _(show_lisp_status, "")                                                 \
16783 _(lisp_get_map_request_itr_rlocs, "")                                   \
16784 _(show_lisp_pitr, "")                                                   \
16785 _(show_lisp_map_request_mode, "")                                       \
16786 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16787 _(af_packet_delete, "name <host interface name>")                       \
16788 _(policer_add_del, "name <policer name> <params> [del]")                \
16789 _(policer_dump, "[name <policer name>]")                                \
16790 _(policer_classify_set_interface,                                       \
16791   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16792   "  [l2-table <nn>] [del]")                                            \
16793 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16794 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16795     "[master|slave]")                                                   \
16796 _(netmap_delete, "name <interface name>")                               \
16797 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16798 _(mpls_fib_encap_dump, "")                                              \
16799 _(mpls_fib_dump, "")                                                    \
16800 _(classify_table_ids, "")                                               \
16801 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16802 _(classify_table_info, "table_id <nn>")                                 \
16803 _(classify_session_dump, "table_id <nn>")                               \
16804 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
16805     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
16806     "[template_interval <nn>] [udp_checksum]")                          \
16807 _(ipfix_exporter_dump, "")                                              \
16808 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
16809 _(ipfix_classify_stream_dump, "")                                       \
16810 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
16811 _(ipfix_classify_table_dump, "")                                        \
16812 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [[dst <intfc> | dst_sw_if_index <id>] | disable]") \
16813 _(sw_interface_span_dump, "")                                           \
16814 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
16815 _(pg_create_interface, "if_id <nn>")                                    \
16816 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
16817 _(pg_enable_disable, "[stream <id>] disable")                           \
16818 _(ip_source_and_port_range_check_add_del,                               \
16819   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
16820 _(ip_source_and_port_range_check_interface_add_del,                     \
16821   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
16822   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
16823 _(ipsec_gre_add_del_tunnel,                                             \
16824   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
16825 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
16826 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
16827 _(l2_interface_pbb_tag_rewrite,                                         \
16828   "<intfc> | sw_if_index <nn> \n"                                       \
16829   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
16830   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
16831 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
16832 _(flow_classify_set_interface,                                          \
16833   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
16834 _(flow_classify_dump, "type [ip4|ip6]")                                 \
16835 _(ip_fib_dump, "")                                                      \
16836 _(ip6_fib_dump, "")
16837
16838 /* List of command functions, CLI names map directly to functions */
16839 #define foreach_cli_function                                    \
16840 _(comment, "usage: comment <ignore-rest-of-line>")              \
16841 _(dump_interface_table, "usage: dump_interface_table")          \
16842 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
16843 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
16844 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
16845 _(dump_stats_table, "usage: dump_stats_table")                  \
16846 _(dump_macro_table, "usage: dump_macro_table ")                 \
16847 _(dump_node_table, "usage: dump_node_table")                    \
16848 _(echo, "usage: echo <message>")                                \
16849 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
16850 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
16851 _(help, "usage: help")                                          \
16852 _(q, "usage: quit")                                             \
16853 _(quit, "usage: quit")                                          \
16854 _(search_node_table, "usage: search_node_table <name>...")      \
16855 _(set, "usage: set <variable-name> <value>")                    \
16856 _(script, "usage: script <file-name>")                          \
16857 _(unset, "usage: unset <variable-name>")
16858
16859 #define _(N,n)                                  \
16860     static void vl_api_##n##_t_handler_uni      \
16861     (vl_api_##n##_t * mp)                       \
16862     {                                           \
16863         vat_main_t * vam = &vat_main;           \
16864         if (vam->json_output) {                 \
16865             vl_api_##n##_t_handler_json(mp);    \
16866         } else {                                \
16867             vl_api_##n##_t_handler(mp);         \
16868         }                                       \
16869     }
16870 foreach_vpe_api_reply_msg;
16871 #undef _
16872
16873 void
16874 vat_api_hookup (vat_main_t * vam)
16875 {
16876 #define _(N,n)                                                  \
16877     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
16878                            vl_api_##n##_t_handler_uni,          \
16879                            vl_noop_handler,                     \
16880                            vl_api_##n##_t_endian,               \
16881                            vl_api_##n##_t_print,                \
16882                            sizeof(vl_api_##n##_t), 1);
16883   foreach_vpe_api_reply_msg;
16884 #undef _
16885
16886   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
16887
16888   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
16889
16890   vam->function_by_name = hash_create_string (0, sizeof (uword));
16891
16892   vam->help_by_name = hash_create_string (0, sizeof (uword));
16893
16894   /* API messages we can send */
16895 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
16896   foreach_vpe_api_msg;
16897 #undef _
16898
16899   /* Help strings */
16900 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16901   foreach_vpe_api_msg;
16902 #undef _
16903
16904   /* CLI functions */
16905 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
16906   foreach_cli_function;
16907 #undef _
16908
16909   /* Help strings */
16910 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
16911   foreach_cli_function;
16912 #undef _
16913 }
16914
16915 #undef vl_api_version
16916 #define vl_api_version(n,v) static u32 vpe_api_version = v;
16917 #include <vpp-api/vpe.api.h>
16918 #undef vl_api_version
16919
16920 void
16921 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
16922 {
16923   /*
16924    * Send the main API signature in slot 0. This bit of code must
16925    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
16926    */
16927   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
16928 }
16929
16930 /*
16931  * fd.io coding-style-patch-verification: ON
16932  *
16933  * Local Variables:
16934  * eval: (c-set-style "gnu")
16935  * End:
16936  */