feature: API/CLI to enable/disable feature per interface
[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 _(feature_enable_disable_reply)
3580
3581 #define _(n)                                    \
3582     static void vl_api_##n##_t_handler          \
3583     (vl_api_##n##_t * mp)                       \
3584     {                                           \
3585         vat_main_t * vam = &vat_main;           \
3586         i32 retval = ntohl(mp->retval);         \
3587         if (vam->async_mode) {                  \
3588             vam->async_errors += (retval < 0);  \
3589         } else {                                \
3590             vam->retval = retval;               \
3591             vam->result_ready = 1;              \
3592         }                                       \
3593     }
3594 foreach_standard_reply_retval_handler;
3595 #undef _
3596
3597 #define _(n)                                    \
3598     static void vl_api_##n##_t_handler_json     \
3599     (vl_api_##n##_t * mp)                       \
3600     {                                           \
3601         vat_main_t * vam = &vat_main;           \
3602         vat_json_node_t node;                   \
3603         vat_json_init_object(&node);            \
3604         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3605         vat_json_print(vam->ofp, &node);        \
3606         vam->retval = ntohl(mp->retval);        \
3607         vam->result_ready = 1;                  \
3608     }
3609 foreach_standard_reply_retval_handler;
3610 #undef _
3611
3612 /*
3613  * Table of message reply handlers, must include boilerplate handlers
3614  * we just generated
3615  */
3616
3617 #define foreach_vpe_api_reply_msg                                       \
3618 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3619 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3620 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3621 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3622 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3623 _(CLI_REPLY, cli_reply)                                                 \
3624 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3625 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3626   sw_interface_add_del_address_reply)                                   \
3627 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3628 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3629 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3630 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3631   sw_interface_set_l2_xconnect_reply)                                   \
3632 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3633   sw_interface_set_l2_bridge_reply)                                     \
3634 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3635   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3636 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3637   sw_interface_set_dpdk_hqos_subport_reply)                             \
3638 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3639   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3640 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3641 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3642 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3643 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3644 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3645 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3646 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3647 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3648 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3649 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3650 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3651 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3652 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3653 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3654 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3655   proxy_arp_intfc_enable_disable_reply)                                 \
3656 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3657 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3658   mpls_ethernet_add_del_tunnel_reply)                                   \
3659 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3660   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3661 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3662   sw_interface_set_unnumbered_reply)                                    \
3663 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3664 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3665 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3666 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3667 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3668 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3669 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3670 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3671 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3672 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3673 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3674 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3675   sw_interface_ip6_enable_disable_reply)                                \
3676 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3677   sw_interface_ip6_set_link_local_address_reply)                        \
3678 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3679   sw_interface_ip6nd_ra_prefix_reply)                                   \
3680 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3681   sw_interface_ip6nd_ra_config_reply)                                   \
3682 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3683 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3684 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3685 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3686 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3687 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3688 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3689 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3690 classify_set_interface_ip_table_reply)                                  \
3691 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3692   classify_set_interface_l2_tables_reply)                               \
3693 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3694 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3695 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3696 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3697 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3698   l2tpv3_interface_enable_disable_reply)                                \
3699 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3700 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3701 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3702 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3703 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3704 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3705 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3706 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3707 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3708 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3709 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3710 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3711 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3712 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3713 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3714 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3715 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3716 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3717 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3718 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3719 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3720 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3721 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3722 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3723 _(IP_DETAILS, ip_details)                                               \
3724 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3725 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3726 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3727 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3728 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3729 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3730 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3731 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3732 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3733 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3734 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3735 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3736 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3737 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3738 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3739 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3740 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3741 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3742 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3743 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3744 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3745 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3746 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3747 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3748 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3749 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3750 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3751 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3752 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3753 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3754 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3755 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3756 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3757 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3758 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3759 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3760 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3761 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3762 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3763 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3764 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3765 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3766 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3767 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3768 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3769 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3770 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3771 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3772 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3773 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3774 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3775 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3776 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3777   lisp_add_del_map_request_itr_rlocs_reply)                             \
3778 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3779   lisp_get_map_request_itr_rlocs_reply)                                 \
3780 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3781 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3782 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3783 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3784 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3785 _(POLICER_DETAILS, policer_details)                                     \
3786 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3787 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3788 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3789 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3790 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3791 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3792 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3793 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3794 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3795 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3796 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3797 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3798 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3799 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3800 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3801 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3802 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3803 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3804 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3805 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3806 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3807 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3808 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3809 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3810 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3811 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3812  ip_source_and_port_range_check_add_del_reply)                          \
3813 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3814  ip_source_and_port_range_check_interface_add_del_reply)                \
3815 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3816 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3817 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3818 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3819 _(PUNT_REPLY, punt_reply)                                               \
3820 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3821 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3822 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)
3823
3824 /* M: construct, but don't yet send a message */
3825
3826 #define M(T,t)                                  \
3827 do {                                            \
3828     vam->result_ready = 0;                      \
3829     mp = vl_msg_api_alloc(sizeof(*mp));         \
3830     memset (mp, 0, sizeof (*mp));               \
3831     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3832     mp->client_index = vam->my_client_index;    \
3833 } while(0);
3834
3835 #define M2(T,t,n)                               \
3836 do {                                            \
3837     vam->result_ready = 0;                      \
3838     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3839     memset (mp, 0, sizeof (*mp));               \
3840     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3841     mp->client_index = vam->my_client_index;    \
3842 } while(0);
3843
3844
3845 /* S: send a message */
3846 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3847
3848 /* W: wait for results, with timeout */
3849 #define W                                       \
3850 do {                                            \
3851     timeout = vat_time_now (vam) + 1.0;         \
3852                                                 \
3853     while (vat_time_now (vam) < timeout) {      \
3854         if (vam->result_ready == 1) {           \
3855             return (vam->retval);               \
3856         }                                       \
3857     }                                           \
3858     return -99;                                 \
3859 } while(0);
3860
3861 /* W2: wait for results, with timeout */
3862 #define W2(body)                                \
3863 do {                                            \
3864     timeout = vat_time_now (vam) + 1.0;         \
3865                                                 \
3866     while (vat_time_now (vam) < timeout) {      \
3867         if (vam->result_ready == 1) {           \
3868           (body);                               \
3869           return (vam->retval);                 \
3870         }                                       \
3871     }                                           \
3872     return -99;                                 \
3873 } while(0);
3874
3875 typedef struct
3876 {
3877   u8 *name;
3878   u32 value;
3879 } name_sort_t;
3880
3881
3882 #define STR_VTR_OP_CASE(op)     \
3883     case L2_VTR_ ## op:         \
3884         return "" # op;
3885
3886 static const char *
3887 str_vtr_op (u32 vtr_op)
3888 {
3889   switch (vtr_op)
3890     {
3891       STR_VTR_OP_CASE (DISABLED);
3892       STR_VTR_OP_CASE (PUSH_1);
3893       STR_VTR_OP_CASE (PUSH_2);
3894       STR_VTR_OP_CASE (POP_1);
3895       STR_VTR_OP_CASE (POP_2);
3896       STR_VTR_OP_CASE (TRANSLATE_1_1);
3897       STR_VTR_OP_CASE (TRANSLATE_1_2);
3898       STR_VTR_OP_CASE (TRANSLATE_2_1);
3899       STR_VTR_OP_CASE (TRANSLATE_2_2);
3900     }
3901
3902   return "UNKNOWN";
3903 }
3904
3905 static int
3906 dump_sub_interface_table (vat_main_t * vam)
3907 {
3908   const sw_interface_subif_t *sub = NULL;
3909
3910   if (vam->json_output)
3911     {
3912       clib_warning
3913         ("JSON output supported only for VPE API calls and dump_stats_table");
3914       return -99;
3915     }
3916
3917   fformat (vam->ofp,
3918            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3919            "Interface", "sw_if_index",
3920            "sub id", "dot1ad", "tags", "outer id",
3921            "inner id", "exact", "default", "outer any", "inner any");
3922
3923   vec_foreach (sub, vam->sw_if_subif_table)
3924   {
3925     fformat (vam->ofp,
3926              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3927              sub->interface_name,
3928              sub->sw_if_index,
3929              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3930              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3931              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3932              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3933     if (sub->vtr_op != L2_VTR_DISABLED)
3934       {
3935         fformat (vam->ofp,
3936                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3937                  "tag1: %d tag2: %d ]\n",
3938                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3939                  sub->vtr_tag1, sub->vtr_tag2);
3940       }
3941   }
3942
3943   return 0;
3944 }
3945
3946 static int
3947 name_sort_cmp (void *a1, void *a2)
3948 {
3949   name_sort_t *n1 = a1;
3950   name_sort_t *n2 = a2;
3951
3952   return strcmp ((char *) n1->name, (char *) n2->name);
3953 }
3954
3955 static int
3956 dump_interface_table (vat_main_t * vam)
3957 {
3958   hash_pair_t *p;
3959   name_sort_t *nses = 0, *ns;
3960
3961   if (vam->json_output)
3962     {
3963       clib_warning
3964         ("JSON output supported only for VPE API calls and dump_stats_table");
3965       return -99;
3966     }
3967
3968   /* *INDENT-OFF* */
3969   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3970   ({
3971     vec_add2 (nses, ns, 1);
3972     ns->name = (u8 *)(p->key);
3973     ns->value = (u32) p->value[0];
3974   }));
3975   /* *INDENT-ON* */
3976
3977   vec_sort_with_function (nses, name_sort_cmp);
3978
3979   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3980   vec_foreach (ns, nses)
3981   {
3982     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3983   }
3984   vec_free (nses);
3985   return 0;
3986 }
3987
3988 static int
3989 dump_ip_table (vat_main_t * vam, int is_ipv6)
3990 {
3991   const ip_details_t *det = NULL;
3992   const ip_address_details_t *address = NULL;
3993   u32 i = ~0;
3994
3995   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3996
3997   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3998   {
3999     i++;
4000     if (!det->present)
4001       {
4002         continue;
4003       }
4004     fformat (vam->ofp, "%-12d\n", i);
4005     fformat (vam->ofp,
4006              "            %-30s%-13s\n", "Address", "Prefix length");
4007     if (!det->addr)
4008       {
4009         continue;
4010       }
4011     vec_foreach (address, det->addr)
4012     {
4013       fformat (vam->ofp,
4014                "            %-30U%-13d\n",
4015                is_ipv6 ? format_ip6_address : format_ip4_address,
4016                address->ip, address->prefix_length);
4017     }
4018   }
4019
4020   return 0;
4021 }
4022
4023 static int
4024 dump_ipv4_table (vat_main_t * vam)
4025 {
4026   if (vam->json_output)
4027     {
4028       clib_warning
4029         ("JSON output supported only for VPE API calls and dump_stats_table");
4030       return -99;
4031     }
4032
4033   return dump_ip_table (vam, 0);
4034 }
4035
4036 static int
4037 dump_ipv6_table (vat_main_t * vam)
4038 {
4039   if (vam->json_output)
4040     {
4041       clib_warning
4042         ("JSON output supported only for VPE API calls and dump_stats_table");
4043       return -99;
4044     }
4045
4046   return dump_ip_table (vam, 1);
4047 }
4048
4049 static char *
4050 counter_type_to_str (u8 counter_type, u8 is_combined)
4051 {
4052   if (!is_combined)
4053     {
4054       switch (counter_type)
4055         {
4056         case VNET_INTERFACE_COUNTER_DROP:
4057           return "drop";
4058         case VNET_INTERFACE_COUNTER_PUNT:
4059           return "punt";
4060         case VNET_INTERFACE_COUNTER_IP4:
4061           return "ip4";
4062         case VNET_INTERFACE_COUNTER_IP6:
4063           return "ip6";
4064         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4065           return "rx-no-buf";
4066         case VNET_INTERFACE_COUNTER_RX_MISS:
4067           return "rx-miss";
4068         case VNET_INTERFACE_COUNTER_RX_ERROR:
4069           return "rx-error";
4070         case VNET_INTERFACE_COUNTER_TX_ERROR:
4071           return "tx-error";
4072         default:
4073           return "INVALID-COUNTER-TYPE";
4074         }
4075     }
4076   else
4077     {
4078       switch (counter_type)
4079         {
4080         case VNET_INTERFACE_COUNTER_RX:
4081           return "rx";
4082         case VNET_INTERFACE_COUNTER_TX:
4083           return "tx";
4084         default:
4085           return "INVALID-COUNTER-TYPE";
4086         }
4087     }
4088 }
4089
4090 static int
4091 dump_stats_table (vat_main_t * vam)
4092 {
4093   vat_json_node_t node;
4094   vat_json_node_t *msg_array;
4095   vat_json_node_t *msg;
4096   vat_json_node_t *counter_array;
4097   vat_json_node_t *counter;
4098   interface_counter_t c;
4099   u64 packets;
4100   ip4_fib_counter_t *c4;
4101   ip6_fib_counter_t *c6;
4102   int i, j;
4103
4104   if (!vam->json_output)
4105     {
4106       clib_warning ("dump_stats_table supported only in JSON format");
4107       return -99;
4108     }
4109
4110   vat_json_init_object (&node);
4111
4112   /* interface counters */
4113   msg_array = vat_json_object_add (&node, "interface_counters");
4114   vat_json_init_array (msg_array);
4115   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4116     {
4117       msg = vat_json_array_add (msg_array);
4118       vat_json_init_object (msg);
4119       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4120                                        (u8 *) counter_type_to_str (i, 0));
4121       vat_json_object_add_int (msg, "is_combined", 0);
4122       counter_array = vat_json_object_add (msg, "data");
4123       vat_json_init_array (counter_array);
4124       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4125         {
4126           packets = vam->simple_interface_counters[i][j];
4127           vat_json_array_add_uint (counter_array, packets);
4128         }
4129     }
4130   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4131     {
4132       msg = vat_json_array_add (msg_array);
4133       vat_json_init_object (msg);
4134       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4135                                        (u8 *) counter_type_to_str (i, 1));
4136       vat_json_object_add_int (msg, "is_combined", 1);
4137       counter_array = vat_json_object_add (msg, "data");
4138       vat_json_init_array (counter_array);
4139       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4140         {
4141           c = vam->combined_interface_counters[i][j];
4142           counter = vat_json_array_add (counter_array);
4143           vat_json_init_object (counter);
4144           vat_json_object_add_uint (counter, "packets", c.packets);
4145           vat_json_object_add_uint (counter, "bytes", c.bytes);
4146         }
4147     }
4148
4149   /* ip4 fib counters */
4150   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4151   vat_json_init_array (msg_array);
4152   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4153     {
4154       msg = vat_json_array_add (msg_array);
4155       vat_json_init_object (msg);
4156       vat_json_object_add_uint (msg, "vrf_id",
4157                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4158       counter_array = vat_json_object_add (msg, "c");
4159       vat_json_init_array (counter_array);
4160       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4161         {
4162           counter = vat_json_array_add (counter_array);
4163           vat_json_init_object (counter);
4164           c4 = &vam->ip4_fib_counters[i][j];
4165           vat_json_object_add_ip4 (counter, "address", c4->address);
4166           vat_json_object_add_uint (counter, "address_length",
4167                                     c4->address_length);
4168           vat_json_object_add_uint (counter, "packets", c4->packets);
4169           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4170         }
4171     }
4172
4173   /* ip6 fib counters */
4174   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4175   vat_json_init_array (msg_array);
4176   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4177     {
4178       msg = vat_json_array_add (msg_array);
4179       vat_json_init_object (msg);
4180       vat_json_object_add_uint (msg, "vrf_id",
4181                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4182       counter_array = vat_json_object_add (msg, "c");
4183       vat_json_init_array (counter_array);
4184       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4185         {
4186           counter = vat_json_array_add (counter_array);
4187           vat_json_init_object (counter);
4188           c6 = &vam->ip6_fib_counters[i][j];
4189           vat_json_object_add_ip6 (counter, "address", c6->address);
4190           vat_json_object_add_uint (counter, "address_length",
4191                                     c6->address_length);
4192           vat_json_object_add_uint (counter, "packets", c6->packets);
4193           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4194         }
4195     }
4196
4197   vat_json_print (vam->ofp, &node);
4198   vat_json_free (&node);
4199
4200   return 0;
4201 }
4202
4203 int
4204 exec (vat_main_t * vam)
4205 {
4206   api_main_t *am = &api_main;
4207   vl_api_cli_request_t *mp;
4208   f64 timeout;
4209   void *oldheap;
4210   u8 *cmd = 0;
4211   unformat_input_t *i = vam->input;
4212
4213   if (vec_len (i->buffer) == 0)
4214     return -1;
4215
4216   if (vam->exec_mode == 0 && unformat (i, "mode"))
4217     {
4218       vam->exec_mode = 1;
4219       return 0;
4220     }
4221   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4222     {
4223       vam->exec_mode = 0;
4224       return 0;
4225     }
4226
4227
4228   M (CLI_REQUEST, cli_request);
4229
4230   /*
4231    * Copy cmd into shared memory.
4232    * In order for the CLI command to work, it
4233    * must be a vector ending in \n, not a C-string ending
4234    * in \n\0.
4235    */
4236   pthread_mutex_lock (&am->vlib_rp->mutex);
4237   oldheap = svm_push_data_heap (am->vlib_rp);
4238
4239   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4240   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4241
4242   svm_pop_heap (oldheap);
4243   pthread_mutex_unlock (&am->vlib_rp->mutex);
4244
4245   mp->cmd_in_shmem = (u64) cmd;
4246   S;
4247   timeout = vat_time_now (vam) + 10.0;
4248
4249   while (vat_time_now (vam) < timeout)
4250     {
4251       if (vam->result_ready == 1)
4252         {
4253           u8 *free_me;
4254           if (vam->shmem_result != NULL)
4255             fformat (vam->ofp, "%s", vam->shmem_result);
4256           pthread_mutex_lock (&am->vlib_rp->mutex);
4257           oldheap = svm_push_data_heap (am->vlib_rp);
4258
4259           free_me = (u8 *) vam->shmem_result;
4260           vec_free (free_me);
4261
4262           svm_pop_heap (oldheap);
4263           pthread_mutex_unlock (&am->vlib_rp->mutex);
4264           return 0;
4265         }
4266     }
4267   return -99;
4268 }
4269
4270 /*
4271  * Future replacement of exec() that passes CLI buffers directly in
4272  * the API messages instead of an additional shared memory area.
4273  */
4274 static int
4275 exec_inband (vat_main_t * vam)
4276 {
4277   vl_api_cli_inband_t *mp;
4278   f64 timeout;
4279   unformat_input_t *i = vam->input;
4280
4281   if (vec_len (i->buffer) == 0)
4282     return -1;
4283
4284   if (vam->exec_mode == 0 && unformat (i, "mode"))
4285     {
4286       vam->exec_mode = 1;
4287       return 0;
4288     }
4289   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4290     {
4291       vam->exec_mode = 0;
4292       return 0;
4293     }
4294
4295   /*
4296    * In order for the CLI command to work, it
4297    * must be a vector ending in \n, not a C-string ending
4298    * in \n\0.
4299    */
4300   u32 len = vec_len (vam->input->buffer);
4301   M2 (CLI_INBAND, cli_inband, len);
4302   clib_memcpy (mp->cmd, vam->input->buffer, len);
4303   mp->length = htonl (len);
4304
4305   S;
4306   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4307 }
4308
4309 static int
4310 api_create_loopback (vat_main_t * vam)
4311 {
4312   unformat_input_t *i = vam->input;
4313   vl_api_create_loopback_t *mp;
4314   f64 timeout;
4315   u8 mac_address[6];
4316   u8 mac_set = 0;
4317
4318   memset (mac_address, 0, sizeof (mac_address));
4319
4320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4321     {
4322       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4323         mac_set = 1;
4324       else
4325         break;
4326     }
4327
4328   /* Construct the API message */
4329   M (CREATE_LOOPBACK, create_loopback);
4330   if (mac_set)
4331     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4332
4333   S;
4334   W;
4335 }
4336
4337 static int
4338 api_delete_loopback (vat_main_t * vam)
4339 {
4340   unformat_input_t *i = vam->input;
4341   vl_api_delete_loopback_t *mp;
4342   f64 timeout;
4343   u32 sw_if_index = ~0;
4344
4345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4346     {
4347       if (unformat (i, "sw_if_index %d", &sw_if_index))
4348         ;
4349       else
4350         break;
4351     }
4352
4353   if (sw_if_index == ~0)
4354     {
4355       errmsg ("missing sw_if_index\n");
4356       return -99;
4357     }
4358
4359   /* Construct the API message */
4360   M (DELETE_LOOPBACK, delete_loopback);
4361   mp->sw_if_index = ntohl (sw_if_index);
4362
4363   S;
4364   W;
4365 }
4366
4367 static int
4368 api_want_stats (vat_main_t * vam)
4369 {
4370   unformat_input_t *i = vam->input;
4371   vl_api_want_stats_t *mp;
4372   f64 timeout;
4373   int enable = -1;
4374
4375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4376     {
4377       if (unformat (i, "enable"))
4378         enable = 1;
4379       else if (unformat (i, "disable"))
4380         enable = 0;
4381       else
4382         break;
4383     }
4384
4385   if (enable == -1)
4386     {
4387       errmsg ("missing enable|disable\n");
4388       return -99;
4389     }
4390
4391   M (WANT_STATS, want_stats);
4392   mp->enable_disable = enable;
4393
4394   S;
4395   W;
4396 }
4397
4398 static int
4399 api_want_interface_events (vat_main_t * vam)
4400 {
4401   unformat_input_t *i = vam->input;
4402   vl_api_want_interface_events_t *mp;
4403   f64 timeout;
4404   int enable = -1;
4405
4406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4407     {
4408       if (unformat (i, "enable"))
4409         enable = 1;
4410       else if (unformat (i, "disable"))
4411         enable = 0;
4412       else
4413         break;
4414     }
4415
4416   if (enable == -1)
4417     {
4418       errmsg ("missing enable|disable\n");
4419       return -99;
4420     }
4421
4422   M (WANT_INTERFACE_EVENTS, want_interface_events);
4423   mp->enable_disable = enable;
4424
4425   vam->interface_event_display = enable;
4426
4427   S;
4428   W;
4429 }
4430
4431
4432 /* Note: non-static, called once to set up the initial intfc table */
4433 int
4434 api_sw_interface_dump (vat_main_t * vam)
4435 {
4436   vl_api_sw_interface_dump_t *mp;
4437   f64 timeout;
4438   hash_pair_t *p;
4439   name_sort_t *nses = 0, *ns;
4440   sw_interface_subif_t *sub = NULL;
4441
4442   /* Toss the old name table */
4443   /* *INDENT-OFF* */
4444   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4445   ({
4446     vec_add2 (nses, ns, 1);
4447     ns->name = (u8 *)(p->key);
4448     ns->value = (u32) p->value[0];
4449   }));
4450   /* *INDENT-ON* */
4451
4452   hash_free (vam->sw_if_index_by_interface_name);
4453
4454   vec_foreach (ns, nses) vec_free (ns->name);
4455
4456   vec_free (nses);
4457
4458   vec_foreach (sub, vam->sw_if_subif_table)
4459   {
4460     vec_free (sub->interface_name);
4461   }
4462   vec_free (vam->sw_if_subif_table);
4463
4464   /* recreate the interface name hash table */
4465   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4466
4467   /* Get list of ethernets */
4468   M (SW_INTERFACE_DUMP, sw_interface_dump);
4469   mp->name_filter_valid = 1;
4470   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4471   S;
4472
4473   /* and local / loopback interfaces */
4474   M (SW_INTERFACE_DUMP, sw_interface_dump);
4475   mp->name_filter_valid = 1;
4476   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4477   S;
4478
4479   /* and packet-generator interfaces */
4480   M (SW_INTERFACE_DUMP, sw_interface_dump);
4481   mp->name_filter_valid = 1;
4482   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4483   S;
4484
4485   /* and vxlan-gpe tunnel interfaces */
4486   M (SW_INTERFACE_DUMP, sw_interface_dump);
4487   mp->name_filter_valid = 1;
4488   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4489            sizeof (mp->name_filter) - 1);
4490   S;
4491
4492   /* and vxlan tunnel interfaces */
4493   M (SW_INTERFACE_DUMP, sw_interface_dump);
4494   mp->name_filter_valid = 1;
4495   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4496   S;
4497
4498   /* and host (af_packet) interfaces */
4499   M (SW_INTERFACE_DUMP, sw_interface_dump);
4500   mp->name_filter_valid = 1;
4501   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4502   S;
4503
4504   /* and l2tpv3 tunnel interfaces */
4505   M (SW_INTERFACE_DUMP, sw_interface_dump);
4506   mp->name_filter_valid = 1;
4507   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4508            sizeof (mp->name_filter) - 1);
4509   S;
4510
4511   /* and GRE tunnel interfaces */
4512   M (SW_INTERFACE_DUMP, sw_interface_dump);
4513   mp->name_filter_valid = 1;
4514   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4515   S;
4516
4517   /* and LISP-GPE interfaces */
4518   M (SW_INTERFACE_DUMP, sw_interface_dump);
4519   mp->name_filter_valid = 1;
4520   strncpy ((char *) mp->name_filter, "lisp_gpe",
4521            sizeof (mp->name_filter) - 1);
4522   S;
4523
4524   /* and IPSEC tunnel interfaces */
4525   M (SW_INTERFACE_DUMP, sw_interface_dump);
4526   mp->name_filter_valid = 1;
4527   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4528   S;
4529
4530   /* Use a control ping for synchronization */
4531   {
4532     vl_api_control_ping_t *mp;
4533     M (CONTROL_PING, control_ping);
4534     S;
4535   }
4536   W;
4537 }
4538
4539 static int
4540 api_sw_interface_set_flags (vat_main_t * vam)
4541 {
4542   unformat_input_t *i = vam->input;
4543   vl_api_sw_interface_set_flags_t *mp;
4544   f64 timeout;
4545   u32 sw_if_index;
4546   u8 sw_if_index_set = 0;
4547   u8 admin_up = 0, link_up = 0;
4548
4549   /* Parse args required to build the message */
4550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4551     {
4552       if (unformat (i, "admin-up"))
4553         admin_up = 1;
4554       else if (unformat (i, "admin-down"))
4555         admin_up = 0;
4556       else if (unformat (i, "link-up"))
4557         link_up = 1;
4558       else if (unformat (i, "link-down"))
4559         link_up = 0;
4560       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4561         sw_if_index_set = 1;
4562       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4563         sw_if_index_set = 1;
4564       else
4565         break;
4566     }
4567
4568   if (sw_if_index_set == 0)
4569     {
4570       errmsg ("missing interface name or sw_if_index\n");
4571       return -99;
4572     }
4573
4574   /* Construct the API message */
4575   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4576   mp->sw_if_index = ntohl (sw_if_index);
4577   mp->admin_up_down = admin_up;
4578   mp->link_up_down = link_up;
4579
4580   /* send it... */
4581   S;
4582
4583   /* Wait for a reply, return the good/bad news... */
4584   W;
4585 }
4586
4587 static int
4588 api_sw_interface_clear_stats (vat_main_t * vam)
4589 {
4590   unformat_input_t *i = vam->input;
4591   vl_api_sw_interface_clear_stats_t *mp;
4592   f64 timeout;
4593   u32 sw_if_index;
4594   u8 sw_if_index_set = 0;
4595
4596   /* Parse args required to build the message */
4597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4598     {
4599       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4600         sw_if_index_set = 1;
4601       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4602         sw_if_index_set = 1;
4603       else
4604         break;
4605     }
4606
4607   /* Construct the API message */
4608   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4609
4610   if (sw_if_index_set == 1)
4611     mp->sw_if_index = ntohl (sw_if_index);
4612   else
4613     mp->sw_if_index = ~0;
4614
4615   /* send it... */
4616   S;
4617
4618   /* Wait for a reply, return the good/bad news... */
4619   W;
4620 }
4621
4622 static int
4623 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4624 {
4625   unformat_input_t *i = vam->input;
4626   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4627   f64 timeout;
4628   u32 sw_if_index;
4629   u8 sw_if_index_set = 0;
4630   u32 subport;
4631   u8 subport_set = 0;
4632   u32 pipe;
4633   u8 pipe_set = 0;
4634   u32 profile;
4635   u8 profile_set = 0;
4636
4637   /* Parse args required to build the message */
4638   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4639     {
4640       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4641         sw_if_index_set = 1;
4642       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4643         sw_if_index_set = 1;
4644       else if (unformat (i, "subport %u", &subport))
4645         subport_set = 1;
4646       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4647         sw_if_index_set = 1;
4648       else if (unformat (i, "pipe %u", &pipe))
4649         pipe_set = 1;
4650       else if (unformat (i, "profile %u", &profile))
4651         profile_set = 1;
4652       else
4653         break;
4654     }
4655
4656   if (sw_if_index_set == 0)
4657     {
4658       errmsg ("missing interface name or sw_if_index\n");
4659       return -99;
4660     }
4661
4662   if (subport_set == 0)
4663     {
4664       errmsg ("missing subport \n");
4665       return -99;
4666     }
4667
4668   if (pipe_set == 0)
4669     {
4670       errmsg ("missing pipe\n");
4671       return -99;
4672     }
4673
4674   if (profile_set == 0)
4675     {
4676       errmsg ("missing profile\n");
4677       return -99;
4678     }
4679
4680   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4681
4682   mp->sw_if_index = ntohl (sw_if_index);
4683   mp->subport = ntohl (subport);
4684   mp->pipe = ntohl (pipe);
4685   mp->profile = ntohl (profile);
4686
4687
4688   S;
4689   W;
4690   /* NOTREACHED */
4691   return 0;
4692 }
4693
4694 static int
4695 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4696 {
4697   unformat_input_t *i = vam->input;
4698   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4699   f64 timeout;
4700   u32 sw_if_index;
4701   u8 sw_if_index_set = 0;
4702   u32 subport;
4703   u8 subport_set = 0;
4704   u32 tb_rate = 1250000000;     /* 10GbE */
4705   u32 tb_size = 1000000;
4706   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4707   u32 tc_period = 10;
4708
4709   /* Parse args required to build the message */
4710   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4711     {
4712       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4713         sw_if_index_set = 1;
4714       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4715         sw_if_index_set = 1;
4716       else if (unformat (i, "subport %u", &subport))
4717         subport_set = 1;
4718       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4719         sw_if_index_set = 1;
4720       else if (unformat (i, "rate %u", &tb_rate))
4721         {
4722           u32 tc_id;
4723
4724           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4725                tc_id++)
4726             tc_rate[tc_id] = tb_rate;
4727         }
4728       else if (unformat (i, "bktsize %u", &tb_size))
4729         ;
4730       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4731         ;
4732       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4733         ;
4734       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4735         ;
4736       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4737         ;
4738       else if (unformat (i, "period %u", &tc_period))
4739         ;
4740       else
4741         break;
4742     }
4743
4744   if (sw_if_index_set == 0)
4745     {
4746       errmsg ("missing interface name or sw_if_index\n");
4747       return -99;
4748     }
4749
4750   if (subport_set == 0)
4751     {
4752       errmsg ("missing subport \n");
4753       return -99;
4754     }
4755
4756   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4757
4758   mp->sw_if_index = ntohl (sw_if_index);
4759   mp->subport = ntohl (subport);
4760   mp->tb_rate = ntohl (tb_rate);
4761   mp->tb_size = ntohl (tb_size);
4762   mp->tc_rate[0] = ntohl (tc_rate[0]);
4763   mp->tc_rate[1] = ntohl (tc_rate[1]);
4764   mp->tc_rate[2] = ntohl (tc_rate[2]);
4765   mp->tc_rate[3] = ntohl (tc_rate[3]);
4766   mp->tc_period = ntohl (tc_period);
4767
4768   S;
4769   W;
4770   /* NOTREACHED */
4771   return 0;
4772 }
4773
4774 static int
4775 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4776 {
4777   unformat_input_t *i = vam->input;
4778   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4779   f64 timeout;
4780   u32 sw_if_index;
4781   u8 sw_if_index_set = 0;
4782   u8 entry_set = 0;
4783   u8 tc_set = 0;
4784   u8 queue_set = 0;
4785   u32 entry, tc, queue;
4786
4787   /* Parse args required to build the message */
4788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4789     {
4790       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4791         sw_if_index_set = 1;
4792       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4793         sw_if_index_set = 1;
4794       else if (unformat (i, "entry %d", &entry))
4795         entry_set = 1;
4796       else if (unformat (i, "tc %d", &tc))
4797         tc_set = 1;
4798       else if (unformat (i, "queue %d", &queue))
4799         queue_set = 1;
4800       else
4801         break;
4802     }
4803
4804   if (sw_if_index_set == 0)
4805     {
4806       errmsg ("missing interface name or sw_if_index\n");
4807       return -99;
4808     }
4809
4810   if (entry_set == 0)
4811     {
4812       errmsg ("missing entry \n");
4813       return -99;
4814     }
4815
4816   if (tc_set == 0)
4817     {
4818       errmsg ("missing traffic class \n");
4819       return -99;
4820     }
4821
4822   if (queue_set == 0)
4823     {
4824       errmsg ("missing queue \n");
4825       return -99;
4826     }
4827
4828   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4829
4830   mp->sw_if_index = ntohl (sw_if_index);
4831   mp->entry = ntohl (entry);
4832   mp->tc = ntohl (tc);
4833   mp->queue = ntohl (queue);
4834
4835   S;
4836   W;
4837   /* NOTREACHED */
4838   return 0;
4839 }
4840
4841 static int
4842 api_sw_interface_add_del_address (vat_main_t * vam)
4843 {
4844   unformat_input_t *i = vam->input;
4845   vl_api_sw_interface_add_del_address_t *mp;
4846   f64 timeout;
4847   u32 sw_if_index;
4848   u8 sw_if_index_set = 0;
4849   u8 is_add = 1, del_all = 0;
4850   u32 address_length = 0;
4851   u8 v4_address_set = 0;
4852   u8 v6_address_set = 0;
4853   ip4_address_t v4address;
4854   ip6_address_t v6address;
4855
4856   /* Parse args required to build the message */
4857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4858     {
4859       if (unformat (i, "del-all"))
4860         del_all = 1;
4861       else if (unformat (i, "del"))
4862         is_add = 0;
4863       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4864         sw_if_index_set = 1;
4865       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4866         sw_if_index_set = 1;
4867       else if (unformat (i, "%U/%d",
4868                          unformat_ip4_address, &v4address, &address_length))
4869         v4_address_set = 1;
4870       else if (unformat (i, "%U/%d",
4871                          unformat_ip6_address, &v6address, &address_length))
4872         v6_address_set = 1;
4873       else
4874         break;
4875     }
4876
4877   if (sw_if_index_set == 0)
4878     {
4879       errmsg ("missing interface name or sw_if_index\n");
4880       return -99;
4881     }
4882   if (v4_address_set && v6_address_set)
4883     {
4884       errmsg ("both v4 and v6 addresses set\n");
4885       return -99;
4886     }
4887   if (!v4_address_set && !v6_address_set && !del_all)
4888     {
4889       errmsg ("no addresses set\n");
4890       return -99;
4891     }
4892
4893   /* Construct the API message */
4894   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4895
4896   mp->sw_if_index = ntohl (sw_if_index);
4897   mp->is_add = is_add;
4898   mp->del_all = del_all;
4899   if (v6_address_set)
4900     {
4901       mp->is_ipv6 = 1;
4902       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4903     }
4904   else
4905     {
4906       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4907     }
4908   mp->address_length = address_length;
4909
4910   /* send it... */
4911   S;
4912
4913   /* Wait for a reply, return good/bad news  */
4914   W;
4915 }
4916
4917 static int
4918 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4919 {
4920   unformat_input_t *i = vam->input;
4921   vl_api_sw_interface_set_mpls_enable_t *mp;
4922   f64 timeout;
4923   u32 sw_if_index;
4924   u8 sw_if_index_set = 0;
4925   u8 enable = 1;
4926
4927   /* Parse args required to build the message */
4928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4929     {
4930       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4931         sw_if_index_set = 1;
4932       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4933         sw_if_index_set = 1;
4934       else if (unformat (i, "disable"))
4935         enable = 0;
4936       else if (unformat (i, "dis"))
4937         enable = 0;
4938       else
4939         break;
4940     }
4941
4942   if (sw_if_index_set == 0)
4943     {
4944       errmsg ("missing interface name or sw_if_index\n");
4945       return -99;
4946     }
4947
4948   /* Construct the API message */
4949   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
4950
4951   mp->sw_if_index = ntohl (sw_if_index);
4952   mp->enable = enable;
4953
4954   /* send it... */
4955   S;
4956
4957   /* Wait for a reply... */
4958   W;
4959 }
4960
4961 static int
4962 api_sw_interface_set_table (vat_main_t * vam)
4963 {
4964   unformat_input_t *i = vam->input;
4965   vl_api_sw_interface_set_table_t *mp;
4966   f64 timeout;
4967   u32 sw_if_index, vrf_id = 0;
4968   u8 sw_if_index_set = 0;
4969   u8 is_ipv6 = 0;
4970
4971   /* Parse args required to build the message */
4972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4973     {
4974       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4975         sw_if_index_set = 1;
4976       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4977         sw_if_index_set = 1;
4978       else if (unformat (i, "vrf %d", &vrf_id))
4979         ;
4980       else if (unformat (i, "ipv6"))
4981         is_ipv6 = 1;
4982       else
4983         break;
4984     }
4985
4986   if (sw_if_index_set == 0)
4987     {
4988       errmsg ("missing interface name or sw_if_index\n");
4989       return -99;
4990     }
4991
4992   /* Construct the API message */
4993   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4994
4995   mp->sw_if_index = ntohl (sw_if_index);
4996   mp->is_ipv6 = is_ipv6;
4997   mp->vrf_id = ntohl (vrf_id);
4998
4999   /* send it... */
5000   S;
5001
5002   /* Wait for a reply... */
5003   W;
5004 }
5005
5006 static int
5007 api_sw_interface_set_vpath (vat_main_t * vam)
5008 {
5009   unformat_input_t *i = vam->input;
5010   vl_api_sw_interface_set_vpath_t *mp;
5011   f64 timeout;
5012   u32 sw_if_index = 0;
5013   u8 sw_if_index_set = 0;
5014   u8 is_enable = 0;
5015
5016   /* Parse args required to build the message */
5017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5018     {
5019       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5020         sw_if_index_set = 1;
5021       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5022         sw_if_index_set = 1;
5023       else if (unformat (i, "enable"))
5024         is_enable = 1;
5025       else if (unformat (i, "disable"))
5026         is_enable = 0;
5027       else
5028         break;
5029     }
5030
5031   if (sw_if_index_set == 0)
5032     {
5033       errmsg ("missing interface name or sw_if_index\n");
5034       return -99;
5035     }
5036
5037   /* Construct the API message */
5038   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5039
5040   mp->sw_if_index = ntohl (sw_if_index);
5041   mp->enable = is_enable;
5042
5043   /* send it... */
5044   S;
5045
5046   /* Wait for a reply... */
5047   W;
5048 }
5049
5050 static int
5051 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5052 {
5053   unformat_input_t *i = vam->input;
5054   vl_api_sw_interface_set_l2_xconnect_t *mp;
5055   f64 timeout;
5056   u32 rx_sw_if_index;
5057   u8 rx_sw_if_index_set = 0;
5058   u32 tx_sw_if_index;
5059   u8 tx_sw_if_index_set = 0;
5060   u8 enable = 1;
5061
5062   /* Parse args required to build the message */
5063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5064     {
5065       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5066         rx_sw_if_index_set = 1;
5067       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5068         tx_sw_if_index_set = 1;
5069       else if (unformat (i, "rx"))
5070         {
5071           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5072             {
5073               if (unformat (i, "%U", unformat_sw_if_index, vam,
5074                             &rx_sw_if_index))
5075                 rx_sw_if_index_set = 1;
5076             }
5077           else
5078             break;
5079         }
5080       else if (unformat (i, "tx"))
5081         {
5082           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5083             {
5084               if (unformat (i, "%U", unformat_sw_if_index, vam,
5085                             &tx_sw_if_index))
5086                 tx_sw_if_index_set = 1;
5087             }
5088           else
5089             break;
5090         }
5091       else if (unformat (i, "enable"))
5092         enable = 1;
5093       else if (unformat (i, "disable"))
5094         enable = 0;
5095       else
5096         break;
5097     }
5098
5099   if (rx_sw_if_index_set == 0)
5100     {
5101       errmsg ("missing rx interface name or rx_sw_if_index\n");
5102       return -99;
5103     }
5104
5105   if (enable && (tx_sw_if_index_set == 0))
5106     {
5107       errmsg ("missing tx interface name or tx_sw_if_index\n");
5108       return -99;
5109     }
5110
5111   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5112
5113   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5114   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5115   mp->enable = enable;
5116
5117   S;
5118   W;
5119   /* NOTREACHED */
5120   return 0;
5121 }
5122
5123 static int
5124 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5125 {
5126   unformat_input_t *i = vam->input;
5127   vl_api_sw_interface_set_l2_bridge_t *mp;
5128   f64 timeout;
5129   u32 rx_sw_if_index;
5130   u8 rx_sw_if_index_set = 0;
5131   u32 bd_id;
5132   u8 bd_id_set = 0;
5133   u8 bvi = 0;
5134   u32 shg = 0;
5135   u8 enable = 1;
5136
5137   /* Parse args required to build the message */
5138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5139     {
5140       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5141         rx_sw_if_index_set = 1;
5142       else if (unformat (i, "bd_id %d", &bd_id))
5143         bd_id_set = 1;
5144       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5145         rx_sw_if_index_set = 1;
5146       else if (unformat (i, "shg %d", &shg))
5147         ;
5148       else if (unformat (i, "bvi"))
5149         bvi = 1;
5150       else if (unformat (i, "enable"))
5151         enable = 1;
5152       else if (unformat (i, "disable"))
5153         enable = 0;
5154       else
5155         break;
5156     }
5157
5158   if (rx_sw_if_index_set == 0)
5159     {
5160       errmsg ("missing rx interface name or sw_if_index\n");
5161       return -99;
5162     }
5163
5164   if (enable && (bd_id_set == 0))
5165     {
5166       errmsg ("missing bridge domain\n");
5167       return -99;
5168     }
5169
5170   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5171
5172   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5173   mp->bd_id = ntohl (bd_id);
5174   mp->shg = (u8) shg;
5175   mp->bvi = bvi;
5176   mp->enable = enable;
5177
5178   S;
5179   W;
5180   /* NOTREACHED */
5181   return 0;
5182 }
5183
5184 static int
5185 api_bridge_domain_dump (vat_main_t * vam)
5186 {
5187   unformat_input_t *i = vam->input;
5188   vl_api_bridge_domain_dump_t *mp;
5189   f64 timeout;
5190   u32 bd_id = ~0;
5191
5192   /* Parse args required to build the message */
5193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5194     {
5195       if (unformat (i, "bd_id %d", &bd_id))
5196         ;
5197       else
5198         break;
5199     }
5200
5201   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5202   mp->bd_id = ntohl (bd_id);
5203   S;
5204
5205   /* Use a control ping for synchronization */
5206   {
5207     vl_api_control_ping_t *mp;
5208     M (CONTROL_PING, control_ping);
5209     S;
5210   }
5211
5212   W;
5213   /* NOTREACHED */
5214   return 0;
5215 }
5216
5217 static int
5218 api_bridge_domain_add_del (vat_main_t * vam)
5219 {
5220   unformat_input_t *i = vam->input;
5221   vl_api_bridge_domain_add_del_t *mp;
5222   f64 timeout;
5223   u32 bd_id = ~0;
5224   u8 is_add = 1;
5225   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5226
5227   /* Parse args required to build the message */
5228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5229     {
5230       if (unformat (i, "bd_id %d", &bd_id))
5231         ;
5232       else if (unformat (i, "flood %d", &flood))
5233         ;
5234       else if (unformat (i, "uu-flood %d", &uu_flood))
5235         ;
5236       else if (unformat (i, "forward %d", &forward))
5237         ;
5238       else if (unformat (i, "learn %d", &learn))
5239         ;
5240       else if (unformat (i, "arp-term %d", &arp_term))
5241         ;
5242       else if (unformat (i, "del"))
5243         {
5244           is_add = 0;
5245           flood = uu_flood = forward = learn = 0;
5246         }
5247       else
5248         break;
5249     }
5250
5251   if (bd_id == ~0)
5252     {
5253       errmsg ("missing bridge domain\n");
5254       return -99;
5255     }
5256
5257   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5258
5259   mp->bd_id = ntohl (bd_id);
5260   mp->flood = flood;
5261   mp->uu_flood = uu_flood;
5262   mp->forward = forward;
5263   mp->learn = learn;
5264   mp->arp_term = arp_term;
5265   mp->is_add = is_add;
5266
5267   S;
5268   W;
5269   /* NOTREACHED */
5270   return 0;
5271 }
5272
5273 static int
5274 api_l2fib_add_del (vat_main_t * vam)
5275 {
5276   unformat_input_t *i = vam->input;
5277   vl_api_l2fib_add_del_t *mp;
5278   f64 timeout;
5279   u64 mac = 0;
5280   u8 mac_set = 0;
5281   u32 bd_id;
5282   u8 bd_id_set = 0;
5283   u32 sw_if_index;
5284   u8 sw_if_index_set = 0;
5285   u8 is_add = 1;
5286   u8 static_mac = 0;
5287   u8 filter_mac = 0;
5288   u8 bvi_mac = 0;
5289   int count = 1;
5290   f64 before = 0;
5291   int j;
5292
5293   /* Parse args required to build the message */
5294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5295     {
5296       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5297         mac_set = 1;
5298       else if (unformat (i, "bd_id %d", &bd_id))
5299         bd_id_set = 1;
5300       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5301         sw_if_index_set = 1;
5302       else if (unformat (i, "sw_if"))
5303         {
5304           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5305             {
5306               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5307                 sw_if_index_set = 1;
5308             }
5309           else
5310             break;
5311         }
5312       else if (unformat (i, "static"))
5313         static_mac = 1;
5314       else if (unformat (i, "filter"))
5315         {
5316           filter_mac = 1;
5317           static_mac = 1;
5318         }
5319       else if (unformat (i, "bvi"))
5320         {
5321           bvi_mac = 1;
5322           static_mac = 1;
5323         }
5324       else if (unformat (i, "del"))
5325         is_add = 0;
5326       else if (unformat (i, "count %d", &count))
5327         ;
5328       else
5329         break;
5330     }
5331
5332   if (mac_set == 0)
5333     {
5334       errmsg ("missing mac address\n");
5335       return -99;
5336     }
5337
5338   if (bd_id_set == 0)
5339     {
5340       errmsg ("missing bridge domain\n");
5341       return -99;
5342     }
5343
5344   if (is_add && (sw_if_index_set == 0))
5345     {
5346       errmsg ("missing interface name or sw_if_index\n");
5347       return -99;
5348     }
5349
5350   if (count > 1)
5351     {
5352       /* Turn on async mode */
5353       vam->async_mode = 1;
5354       vam->async_errors = 0;
5355       before = vat_time_now (vam);
5356     }
5357
5358   for (j = 0; j < count; j++)
5359     {
5360       M (L2FIB_ADD_DEL, l2fib_add_del);
5361
5362       mp->mac = mac;
5363       mp->bd_id = ntohl (bd_id);
5364       mp->is_add = is_add;
5365
5366       if (is_add)
5367         {
5368           mp->sw_if_index = ntohl (sw_if_index);
5369           mp->static_mac = static_mac;
5370           mp->filter_mac = filter_mac;
5371           mp->bvi_mac = bvi_mac;
5372         }
5373       increment_mac_address (&mac);
5374       /* send it... */
5375       S;
5376     }
5377
5378   if (count > 1)
5379     {
5380       vl_api_control_ping_t *mp;
5381       f64 after;
5382
5383       /* Shut off async mode */
5384       vam->async_mode = 0;
5385
5386       M (CONTROL_PING, control_ping);
5387       S;
5388
5389       timeout = vat_time_now (vam) + 1.0;
5390       while (vat_time_now (vam) < timeout)
5391         if (vam->result_ready == 1)
5392           goto out;
5393       vam->retval = -99;
5394
5395     out:
5396       if (vam->retval == -99)
5397         errmsg ("timeout\n");
5398
5399       if (vam->async_errors > 0)
5400         {
5401           errmsg ("%d asynchronous errors\n", vam->async_errors);
5402           vam->retval = -98;
5403         }
5404       vam->async_errors = 0;
5405       after = vat_time_now (vam);
5406
5407       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5408                count, after - before, count / (after - before));
5409     }
5410   else
5411     {
5412       /* Wait for a reply... */
5413       W;
5414     }
5415   /* Return the good/bad news */
5416   return (vam->retval);
5417 }
5418
5419 static int
5420 api_l2_flags (vat_main_t * vam)
5421 {
5422   unformat_input_t *i = vam->input;
5423   vl_api_l2_flags_t *mp;
5424   f64 timeout;
5425   u32 sw_if_index;
5426   u32 feature_bitmap = 0;
5427   u8 sw_if_index_set = 0;
5428
5429   /* Parse args required to build the message */
5430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5431     {
5432       if (unformat (i, "sw_if_index %d", &sw_if_index))
5433         sw_if_index_set = 1;
5434       else if (unformat (i, "sw_if"))
5435         {
5436           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5437             {
5438               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5439                 sw_if_index_set = 1;
5440             }
5441           else
5442             break;
5443         }
5444       else if (unformat (i, "learn"))
5445         feature_bitmap |= L2INPUT_FEAT_LEARN;
5446       else if (unformat (i, "forward"))
5447         feature_bitmap |= L2INPUT_FEAT_FWD;
5448       else if (unformat (i, "flood"))
5449         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5450       else if (unformat (i, "uu-flood"))
5451         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5452       else
5453         break;
5454     }
5455
5456   if (sw_if_index_set == 0)
5457     {
5458       errmsg ("missing interface name or sw_if_index\n");
5459       return -99;
5460     }
5461
5462   M (L2_FLAGS, l2_flags);
5463
5464   mp->sw_if_index = ntohl (sw_if_index);
5465   mp->feature_bitmap = ntohl (feature_bitmap);
5466
5467   S;
5468   W;
5469   /* NOTREACHED */
5470   return 0;
5471 }
5472
5473 static int
5474 api_bridge_flags (vat_main_t * vam)
5475 {
5476   unformat_input_t *i = vam->input;
5477   vl_api_bridge_flags_t *mp;
5478   f64 timeout;
5479   u32 bd_id;
5480   u8 bd_id_set = 0;
5481   u8 is_set = 1;
5482   u32 flags = 0;
5483
5484   /* Parse args required to build the message */
5485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5486     {
5487       if (unformat (i, "bd_id %d", &bd_id))
5488         bd_id_set = 1;
5489       else if (unformat (i, "learn"))
5490         flags |= L2_LEARN;
5491       else if (unformat (i, "forward"))
5492         flags |= L2_FWD;
5493       else if (unformat (i, "flood"))
5494         flags |= L2_FLOOD;
5495       else if (unformat (i, "uu-flood"))
5496         flags |= L2_UU_FLOOD;
5497       else if (unformat (i, "arp-term"))
5498         flags |= L2_ARP_TERM;
5499       else if (unformat (i, "off"))
5500         is_set = 0;
5501       else if (unformat (i, "disable"))
5502         is_set = 0;
5503       else
5504         break;
5505     }
5506
5507   if (bd_id_set == 0)
5508     {
5509       errmsg ("missing bridge domain\n");
5510       return -99;
5511     }
5512
5513   M (BRIDGE_FLAGS, bridge_flags);
5514
5515   mp->bd_id = ntohl (bd_id);
5516   mp->feature_bitmap = ntohl (flags);
5517   mp->is_set = is_set;
5518
5519   S;
5520   W;
5521   /* NOTREACHED */
5522   return 0;
5523 }
5524
5525 static int
5526 api_bd_ip_mac_add_del (vat_main_t * vam)
5527 {
5528   unformat_input_t *i = vam->input;
5529   vl_api_bd_ip_mac_add_del_t *mp;
5530   f64 timeout;
5531   u32 bd_id;
5532   u8 is_ipv6 = 0;
5533   u8 is_add = 1;
5534   u8 bd_id_set = 0;
5535   u8 ip_set = 0;
5536   u8 mac_set = 0;
5537   ip4_address_t v4addr;
5538   ip6_address_t v6addr;
5539   u8 macaddr[6];
5540
5541
5542   /* Parse args required to build the message */
5543   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5544     {
5545       if (unformat (i, "bd_id %d", &bd_id))
5546         {
5547           bd_id_set++;
5548         }
5549       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5550         {
5551           ip_set++;
5552         }
5553       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5554         {
5555           ip_set++;
5556           is_ipv6++;
5557         }
5558       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5559         {
5560           mac_set++;
5561         }
5562       else if (unformat (i, "del"))
5563         is_add = 0;
5564       else
5565         break;
5566     }
5567
5568   if (bd_id_set == 0)
5569     {
5570       errmsg ("missing bridge domain\n");
5571       return -99;
5572     }
5573   else if (ip_set == 0)
5574     {
5575       errmsg ("missing IP address\n");
5576       return -99;
5577     }
5578   else if (mac_set == 0)
5579     {
5580       errmsg ("missing MAC address\n");
5581       return -99;
5582     }
5583
5584   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5585
5586   mp->bd_id = ntohl (bd_id);
5587   mp->is_ipv6 = is_ipv6;
5588   mp->is_add = is_add;
5589   if (is_ipv6)
5590     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5591   else
5592     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5593   clib_memcpy (mp->mac_address, macaddr, 6);
5594   S;
5595   W;
5596   /* NOTREACHED */
5597   return 0;
5598 }
5599
5600 static int
5601 api_tap_connect (vat_main_t * vam)
5602 {
5603   unformat_input_t *i = vam->input;
5604   vl_api_tap_connect_t *mp;
5605   f64 timeout;
5606   u8 mac_address[6];
5607   u8 random_mac = 1;
5608   u8 name_set = 0;
5609   u8 *tap_name;
5610
5611   memset (mac_address, 0, sizeof (mac_address));
5612
5613   /* Parse args required to build the message */
5614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5615     {
5616       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5617         {
5618           random_mac = 0;
5619         }
5620       else if (unformat (i, "random-mac"))
5621         random_mac = 1;
5622       else if (unformat (i, "tapname %s", &tap_name))
5623         name_set = 1;
5624       else
5625         break;
5626     }
5627
5628   if (name_set == 0)
5629     {
5630       errmsg ("missing tap name\n");
5631       return -99;
5632     }
5633   if (vec_len (tap_name) > 63)
5634     {
5635       errmsg ("tap name too long\n");
5636     }
5637   vec_add1 (tap_name, 0);
5638
5639   /* Construct the API message */
5640   M (TAP_CONNECT, tap_connect);
5641
5642   mp->use_random_mac = random_mac;
5643   clib_memcpy (mp->mac_address, mac_address, 6);
5644   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5645   vec_free (tap_name);
5646
5647   /* send it... */
5648   S;
5649
5650   /* Wait for a reply... */
5651   W;
5652 }
5653
5654 static int
5655 api_tap_modify (vat_main_t * vam)
5656 {
5657   unformat_input_t *i = vam->input;
5658   vl_api_tap_modify_t *mp;
5659   f64 timeout;
5660   u8 mac_address[6];
5661   u8 random_mac = 1;
5662   u8 name_set = 0;
5663   u8 *tap_name;
5664   u32 sw_if_index = ~0;
5665   u8 sw_if_index_set = 0;
5666
5667   memset (mac_address, 0, sizeof (mac_address));
5668
5669   /* Parse args required to build the message */
5670   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5671     {
5672       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5673         sw_if_index_set = 1;
5674       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5675         sw_if_index_set = 1;
5676       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5677         {
5678           random_mac = 0;
5679         }
5680       else if (unformat (i, "random-mac"))
5681         random_mac = 1;
5682       else if (unformat (i, "tapname %s", &tap_name))
5683         name_set = 1;
5684       else
5685         break;
5686     }
5687
5688   if (sw_if_index_set == 0)
5689     {
5690       errmsg ("missing vpp interface name");
5691       return -99;
5692     }
5693   if (name_set == 0)
5694     {
5695       errmsg ("missing tap name\n");
5696       return -99;
5697     }
5698   if (vec_len (tap_name) > 63)
5699     {
5700       errmsg ("tap name too long\n");
5701     }
5702   vec_add1 (tap_name, 0);
5703
5704   /* Construct the API message */
5705   M (TAP_MODIFY, tap_modify);
5706
5707   mp->use_random_mac = random_mac;
5708   mp->sw_if_index = ntohl (sw_if_index);
5709   clib_memcpy (mp->mac_address, mac_address, 6);
5710   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5711   vec_free (tap_name);
5712
5713   /* send it... */
5714   S;
5715
5716   /* Wait for a reply... */
5717   W;
5718 }
5719
5720 static int
5721 api_tap_delete (vat_main_t * vam)
5722 {
5723   unformat_input_t *i = vam->input;
5724   vl_api_tap_delete_t *mp;
5725   f64 timeout;
5726   u32 sw_if_index = ~0;
5727   u8 sw_if_index_set = 0;
5728
5729   /* Parse args required to build the message */
5730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5731     {
5732       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5733         sw_if_index_set = 1;
5734       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5735         sw_if_index_set = 1;
5736       else
5737         break;
5738     }
5739
5740   if (sw_if_index_set == 0)
5741     {
5742       errmsg ("missing vpp interface name");
5743       return -99;
5744     }
5745
5746   /* Construct the API message */
5747   M (TAP_DELETE, tap_delete);
5748
5749   mp->sw_if_index = ntohl (sw_if_index);
5750
5751   /* send it... */
5752   S;
5753
5754   /* Wait for a reply... */
5755   W;
5756 }
5757
5758 static int
5759 api_ip_add_del_route (vat_main_t * vam)
5760 {
5761   unformat_input_t *i = vam->input;
5762   vl_api_ip_add_del_route_t *mp;
5763   f64 timeout;
5764   u32 sw_if_index = ~0, vrf_id = 0;
5765   u8 sw_if_index_set = 0;
5766   u8 is_ipv6 = 0;
5767   u8 is_local = 0, is_drop = 0;
5768   u8 is_unreach = 0, is_prohibit = 0;
5769   u8 create_vrf_if_needed = 0;
5770   u8 is_add = 1;
5771   u8 next_hop_weight = 1;
5772   u8 not_last = 0;
5773   u8 is_multipath = 0;
5774   u8 address_set = 0;
5775   u8 address_length_set = 0;
5776   u32 next_hop_table_id = 0;
5777   u32 resolve_attempts = 0;
5778   u32 dst_address_length = 0;
5779   u8 next_hop_set = 0;
5780   ip4_address_t v4_dst_address, v4_next_hop_address;
5781   ip6_address_t v6_dst_address, v6_next_hop_address;
5782   int count = 1;
5783   int j;
5784   f64 before = 0;
5785   u32 random_add_del = 0;
5786   u32 *random_vector = 0;
5787   uword *random_hash;
5788   u32 random_seed = 0xdeaddabe;
5789   u32 classify_table_index = ~0;
5790   u8 is_classify = 0;
5791   u8 resolve_host = 0, resolve_attached = 0;
5792   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5793
5794   /* Parse args required to build the message */
5795   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5796     {
5797       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5798         sw_if_index_set = 1;
5799       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5800         sw_if_index_set = 1;
5801       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5802         {
5803           address_set = 1;
5804           is_ipv6 = 0;
5805         }
5806       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5807         {
5808           address_set = 1;
5809           is_ipv6 = 1;
5810         }
5811       else if (unformat (i, "/%d", &dst_address_length))
5812         {
5813           address_length_set = 1;
5814         }
5815
5816       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5817                                          &v4_next_hop_address))
5818         {
5819           next_hop_set = 1;
5820         }
5821       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5822                                          &v6_next_hop_address))
5823         {
5824           next_hop_set = 1;
5825         }
5826       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5827         ;
5828       else if (unformat (i, "weight %d", &next_hop_weight))
5829         ;
5830       else if (unformat (i, "drop"))
5831         {
5832           is_drop = 1;
5833         }
5834       else if (unformat (i, "null-send-unreach"))
5835         {
5836           is_unreach = 1;
5837         }
5838       else if (unformat (i, "null-send-prohibit"))
5839         {
5840           is_prohibit = 1;
5841         }
5842       else if (unformat (i, "local"))
5843         {
5844           is_local = 1;
5845         }
5846       else if (unformat (i, "classify %d", &classify_table_index))
5847         {
5848           is_classify = 1;
5849         }
5850       else if (unformat (i, "del"))
5851         is_add = 0;
5852       else if (unformat (i, "add"))
5853         is_add = 1;
5854       else if (unformat (i, "not-last"))
5855         not_last = 1;
5856       else if (unformat (i, "resolve-via-host"))
5857         resolve_host = 1;
5858       else if (unformat (i, "resolve-via-attached"))
5859         resolve_attached = 1;
5860       else if (unformat (i, "multipath"))
5861         is_multipath = 1;
5862       else if (unformat (i, "vrf %d", &vrf_id))
5863         ;
5864       else if (unformat (i, "create-vrf"))
5865         create_vrf_if_needed = 1;
5866       else if (unformat (i, "count %d", &count))
5867         ;
5868       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
5869         ;
5870       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
5871         ;
5872       else if (unformat (i, "out-label %d", &next_hop_out_label))
5873         ;
5874       else if (unformat (i, "random"))
5875         random_add_del = 1;
5876       else if (unformat (i, "seed %d", &random_seed))
5877         ;
5878       else
5879         {
5880           clib_warning ("parse error '%U'", format_unformat_error, i);
5881           return -99;
5882         }
5883     }
5884
5885   if (resolve_attempts > 0 && sw_if_index_set == 0)
5886     {
5887       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5888       return -99;
5889     }
5890
5891   if (!next_hop_set && !is_drop && !is_local &&
5892       !is_classify && !is_unreach && !is_prohibit)
5893     {
5894       errmsg
5895         ("next hop / local / drop / unreach / prohibit / classify not set\n");
5896       return -99;
5897     }
5898
5899   if (address_set == 0)
5900     {
5901       errmsg ("missing addresses\n");
5902       return -99;
5903     }
5904
5905   if (address_length_set == 0)
5906     {
5907       errmsg ("missing address length\n");
5908       return -99;
5909     }
5910
5911   /* Generate a pile of unique, random routes */
5912   if (random_add_del)
5913     {
5914       u32 this_random_address;
5915       random_hash = hash_create (count, sizeof (uword));
5916
5917       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5918       for (j = 0; j <= count; j++)
5919         {
5920           do
5921             {
5922               this_random_address = random_u32 (&random_seed);
5923               this_random_address =
5924                 clib_host_to_net_u32 (this_random_address);
5925             }
5926           while (hash_get (random_hash, this_random_address));
5927           vec_add1 (random_vector, this_random_address);
5928           hash_set (random_hash, this_random_address, 1);
5929         }
5930       hash_free (random_hash);
5931       v4_dst_address.as_u32 = random_vector[0];
5932     }
5933
5934   if (count > 1)
5935     {
5936       /* Turn on async mode */
5937       vam->async_mode = 1;
5938       vam->async_errors = 0;
5939       before = vat_time_now (vam);
5940     }
5941
5942   for (j = 0; j < count; j++)
5943     {
5944       /* Construct the API message */
5945       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5946
5947       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5948       mp->table_id = ntohl (vrf_id);
5949       if (resolve_attempts > 0)
5950         {
5951           mp->resolve_attempts = ntohl (resolve_attempts);
5952           mp->resolve_if_needed = 1;
5953         }
5954       mp->create_vrf_if_needed = create_vrf_if_needed;
5955
5956       mp->is_add = is_add;
5957       mp->is_drop = is_drop;
5958       mp->is_unreach = is_unreach;
5959       mp->is_prohibit = is_prohibit;
5960       mp->is_ipv6 = is_ipv6;
5961       mp->is_local = is_local;
5962       mp->is_classify = is_classify;
5963       mp->is_multipath = is_multipath;
5964       mp->is_resolve_host = resolve_host;
5965       mp->is_resolve_attached = resolve_attached;
5966       mp->not_last = not_last;
5967       mp->next_hop_weight = next_hop_weight;
5968       mp->dst_address_length = dst_address_length;
5969       mp->next_hop_table_id = ntohl (next_hop_table_id);
5970       mp->classify_table_index = ntohl (classify_table_index);
5971       mp->next_hop_out_label = ntohl (next_hop_out_label);
5972
5973       if (is_ipv6)
5974         {
5975           clib_memcpy (mp->dst_address, &v6_dst_address,
5976                        sizeof (v6_dst_address));
5977           if (next_hop_set)
5978             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5979                          sizeof (v6_next_hop_address));
5980           increment_v6_address (&v6_dst_address);
5981         }
5982       else
5983         {
5984           clib_memcpy (mp->dst_address, &v4_dst_address,
5985                        sizeof (v4_dst_address));
5986           if (next_hop_set)
5987             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5988                          sizeof (v4_next_hop_address));
5989           if (random_add_del)
5990             v4_dst_address.as_u32 = random_vector[j + 1];
5991           else
5992             increment_v4_address (&v4_dst_address);
5993         }
5994       /* send it... */
5995       S;
5996       /* If we receive SIGTERM, stop now... */
5997       if (vam->do_exit)
5998         break;
5999     }
6000
6001   /* When testing multiple add/del ops, use a control-ping to sync */
6002   if (count > 1)
6003     {
6004       vl_api_control_ping_t *mp;
6005       f64 after;
6006
6007       /* Shut off async mode */
6008       vam->async_mode = 0;
6009
6010       M (CONTROL_PING, control_ping);
6011       S;
6012
6013       timeout = vat_time_now (vam) + 1.0;
6014       while (vat_time_now (vam) < timeout)
6015         if (vam->result_ready == 1)
6016           goto out;
6017       vam->retval = -99;
6018
6019     out:
6020       if (vam->retval == -99)
6021         errmsg ("timeout\n");
6022
6023       if (vam->async_errors > 0)
6024         {
6025           errmsg ("%d asynchronous errors\n", vam->async_errors);
6026           vam->retval = -98;
6027         }
6028       vam->async_errors = 0;
6029       after = vat_time_now (vam);
6030
6031       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6032       if (j > 0)
6033         count = j;
6034
6035       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6036                count, after - before, count / (after - before));
6037     }
6038   else
6039     {
6040       /* Wait for a reply... */
6041       W;
6042     }
6043
6044   /* Return the good/bad news */
6045   return (vam->retval);
6046 }
6047
6048 static int
6049 api_mpls_route_add_del (vat_main_t * vam)
6050 {
6051   unformat_input_t *i = vam->input;
6052   vl_api_mpls_route_add_del_t *mp;
6053   f64 timeout;
6054   u32 sw_if_index = ~0, table_id = 0;
6055   u8 create_table_if_needed = 0;
6056   u8 is_add = 1;
6057   u8 next_hop_weight = 1;
6058   u8 is_multipath = 0;
6059   u32 next_hop_table_id = 0;
6060   u8 next_hop_set = 0;
6061   ip4_address_t v4_next_hop_address = {
6062     .as_u32 = 0,
6063   };
6064   ip6_address_t v6_next_hop_address = { {0} };
6065   int count = 1;
6066   int j;
6067   f64 before = 0;
6068   u32 classify_table_index = ~0;
6069   u8 is_classify = 0;
6070   u8 resolve_host = 0, resolve_attached = 0;
6071   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6072   mpls_label_t local_label = MPLS_LABEL_INVALID;
6073   u8 is_eos = 1;
6074   u8 next_hop_proto_is_ip4 = 1;
6075
6076   /* Parse args required to build the message */
6077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6078     {
6079       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6080         ;
6081       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6082         ;
6083       else if (unformat (i, "%d", &local_label))
6084         ;
6085       else if (unformat (i, "eos"))
6086         is_eos = 1;
6087       else if (unformat (i, "non-eos"))
6088         is_eos = 0;
6089       else if (unformat (i, "via %U", unformat_ip4_address,
6090                          &v4_next_hop_address))
6091         {
6092           next_hop_set = 1;
6093           next_hop_proto_is_ip4 = 1;
6094         }
6095       else if (unformat (i, "via %U", unformat_ip6_address,
6096                          &v6_next_hop_address))
6097         {
6098           next_hop_set = 1;
6099           next_hop_proto_is_ip4 = 0;
6100         }
6101       else if (unformat (i, "weight %d", &next_hop_weight))
6102         ;
6103       else if (unformat (i, "create-table"))
6104         create_table_if_needed = 1;
6105       else if (unformat (i, "classify %d", &classify_table_index))
6106         {
6107           is_classify = 1;
6108         }
6109       else if (unformat (i, "del"))
6110         is_add = 0;
6111       else if (unformat (i, "add"))
6112         is_add = 1;
6113       else if (unformat (i, "resolve-via-host"))
6114         resolve_host = 1;
6115       else if (unformat (i, "resolve-via-attached"))
6116         resolve_attached = 1;
6117       else if (unformat (i, "multipath"))
6118         is_multipath = 1;
6119       else if (unformat (i, "count %d", &count))
6120         ;
6121       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6122         {
6123           next_hop_set = 1;
6124           next_hop_proto_is_ip4 = 1;
6125         }
6126       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6127         {
6128           next_hop_set = 1;
6129           next_hop_proto_is_ip4 = 0;
6130         }
6131       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6132         ;
6133       else if (unformat (i, "out-label %d", &next_hop_out_label))
6134         ;
6135       else
6136         {
6137           clib_warning ("parse error '%U'", format_unformat_error, i);
6138           return -99;
6139         }
6140     }
6141
6142   if (!next_hop_set && !is_classify)
6143     {
6144       errmsg ("next hop / classify not set\n");
6145       return -99;
6146     }
6147
6148   if (MPLS_LABEL_INVALID == local_label)
6149     {
6150       errmsg ("missing label\n");
6151       return -99;
6152     }
6153
6154   if (count > 1)
6155     {
6156       /* Turn on async mode */
6157       vam->async_mode = 1;
6158       vam->async_errors = 0;
6159       before = vat_time_now (vam);
6160     }
6161
6162   for (j = 0; j < count; j++)
6163     {
6164       /* Construct the API message */
6165       M (MPLS_ROUTE_ADD_DEL, mpls_route_add_del);
6166
6167       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6168       mp->mr_table_id = ntohl (table_id);
6169       mp->mr_create_table_if_needed = create_table_if_needed;
6170
6171       mp->mr_is_add = is_add;
6172       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6173       mp->mr_is_classify = is_classify;
6174       mp->mr_is_multipath = is_multipath;
6175       mp->mr_is_resolve_host = resolve_host;
6176       mp->mr_is_resolve_attached = resolve_attached;
6177       mp->mr_next_hop_weight = next_hop_weight;
6178       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6179       mp->mr_classify_table_index = ntohl (classify_table_index);
6180       mp->mr_next_hop_out_label = ntohl (next_hop_out_label);
6181       mp->mr_label = ntohl (local_label);
6182       mp->mr_eos = is_eos;
6183
6184       if (next_hop_set)
6185         {
6186           if (next_hop_proto_is_ip4)
6187             {
6188               clib_memcpy (mp->mr_next_hop,
6189                            &v4_next_hop_address,
6190                            sizeof (v4_next_hop_address));
6191             }
6192           else
6193             {
6194               clib_memcpy (mp->mr_next_hop,
6195                            &v6_next_hop_address,
6196                            sizeof (v6_next_hop_address));
6197             }
6198         }
6199       local_label++;
6200
6201       /* send it... */
6202       S;
6203       /* If we receive SIGTERM, stop now... */
6204       if (vam->do_exit)
6205         break;
6206     }
6207
6208   /* When testing multiple add/del ops, use a control-ping to sync */
6209   if (count > 1)
6210     {
6211       vl_api_control_ping_t *mp;
6212       f64 after;
6213
6214       /* Shut off async mode */
6215       vam->async_mode = 0;
6216
6217       M (CONTROL_PING, control_ping);
6218       S;
6219
6220       timeout = vat_time_now (vam) + 1.0;
6221       while (vat_time_now (vam) < timeout)
6222         if (vam->result_ready == 1)
6223           goto out;
6224       vam->retval = -99;
6225
6226     out:
6227       if (vam->retval == -99)
6228         errmsg ("timeout\n");
6229
6230       if (vam->async_errors > 0)
6231         {
6232           errmsg ("%d asynchronous errors\n", vam->async_errors);
6233           vam->retval = -98;
6234         }
6235       vam->async_errors = 0;
6236       after = vat_time_now (vam);
6237
6238       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6239       if (j > 0)
6240         count = j;
6241
6242       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6243                count, after - before, count / (after - before));
6244     }
6245   else
6246     {
6247       /* Wait for a reply... */
6248       W;
6249     }
6250
6251   /* Return the good/bad news */
6252   return (vam->retval);
6253 }
6254
6255 static int
6256 api_mpls_ip_bind_unbind (vat_main_t * vam)
6257 {
6258   unformat_input_t *i = vam->input;
6259   vl_api_mpls_ip_bind_unbind_t *mp;
6260   f64 timeout;
6261   u32 ip_table_id = 0;
6262   u8 create_table_if_needed = 0;
6263   u8 is_bind = 1;
6264   u8 is_ip4 = 1;
6265   ip4_address_t v4_address;
6266   ip6_address_t v6_address;
6267   u32 address_length;
6268   u8 address_set = 0;
6269   mpls_label_t local_label = MPLS_LABEL_INVALID;
6270
6271   /* Parse args required to build the message */
6272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6273     {
6274       if (unformat (i, "%U/%d", unformat_ip4_address,
6275                     &v4_address, &address_length))
6276         {
6277           is_ip4 = 1;
6278           address_set = 1;
6279         }
6280       else if (unformat (i, "%U/%d", unformat_ip6_address,
6281                          &v6_address, &address_length))
6282         {
6283           is_ip4 = 0;
6284           address_set = 1;
6285         }
6286       else if (unformat (i, "%d", &local_label))
6287         ;
6288       else if (unformat (i, "create-table"))
6289         create_table_if_needed = 1;
6290       else if (unformat (i, "table-id %d", &ip_table_id))
6291         ;
6292       else if (unformat (i, "unbind"))
6293         is_bind = 0;
6294       else if (unformat (i, "bind"))
6295         is_bind = 1;
6296       else
6297         {
6298           clib_warning ("parse error '%U'", format_unformat_error, i);
6299           return -99;
6300         }
6301     }
6302
6303   if (!address_set)
6304     {
6305       errmsg ("IP addres not set\n");
6306       return -99;
6307     }
6308
6309   if (MPLS_LABEL_INVALID == local_label)
6310     {
6311       errmsg ("missing label\n");
6312       return -99;
6313     }
6314
6315   /* Construct the API message */
6316   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6317
6318   mp->mb_create_table_if_needed = create_table_if_needed;
6319   mp->mb_is_bind = is_bind;
6320   mp->mb_is_ip4 = is_ip4;
6321   mp->mb_ip_table_id = ntohl (ip_table_id);
6322   mp->mb_mpls_table_id = 0;
6323   mp->mb_label = ntohl (local_label);
6324   mp->mb_address_length = address_length;
6325
6326   if (is_ip4)
6327     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6328   else
6329     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6330
6331   /* send it... */
6332   S;
6333
6334   /* Wait for a reply... */
6335   W;
6336 }
6337
6338 static int
6339 api_proxy_arp_add_del (vat_main_t * vam)
6340 {
6341   unformat_input_t *i = vam->input;
6342   vl_api_proxy_arp_add_del_t *mp;
6343   f64 timeout;
6344   u32 vrf_id = 0;
6345   u8 is_add = 1;
6346   ip4_address_t lo, hi;
6347   u8 range_set = 0;
6348
6349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6350     {
6351       if (unformat (i, "vrf %d", &vrf_id))
6352         ;
6353       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6354                          unformat_ip4_address, &hi))
6355         range_set = 1;
6356       else if (unformat (i, "del"))
6357         is_add = 0;
6358       else
6359         {
6360           clib_warning ("parse error '%U'", format_unformat_error, i);
6361           return -99;
6362         }
6363     }
6364
6365   if (range_set == 0)
6366     {
6367       errmsg ("address range not set\n");
6368       return -99;
6369     }
6370
6371   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6372
6373   mp->vrf_id = ntohl (vrf_id);
6374   mp->is_add = is_add;
6375   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6376   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6377
6378   S;
6379   W;
6380   /* NOTREACHED */
6381   return 0;
6382 }
6383
6384 static int
6385 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6386 {
6387   unformat_input_t *i = vam->input;
6388   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6389   f64 timeout;
6390   u32 sw_if_index;
6391   u8 enable = 1;
6392   u8 sw_if_index_set = 0;
6393
6394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6395     {
6396       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6397         sw_if_index_set = 1;
6398       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6399         sw_if_index_set = 1;
6400       else if (unformat (i, "enable"))
6401         enable = 1;
6402       else if (unformat (i, "disable"))
6403         enable = 0;
6404       else
6405         {
6406           clib_warning ("parse error '%U'", format_unformat_error, i);
6407           return -99;
6408         }
6409     }
6410
6411   if (sw_if_index_set == 0)
6412     {
6413       errmsg ("missing interface name or sw_if_index\n");
6414       return -99;
6415     }
6416
6417   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6418
6419   mp->sw_if_index = ntohl (sw_if_index);
6420   mp->enable_disable = enable;
6421
6422   S;
6423   W;
6424   /* NOTREACHED */
6425   return 0;
6426 }
6427
6428 static int
6429 api_mpls_add_del_encap (vat_main_t * vam)
6430 {
6431   unformat_input_t *i = vam->input;
6432   vl_api_mpls_add_del_encap_t *mp;
6433   f64 timeout;
6434   u32 vrf_id = 0;
6435   u32 *labels = 0;
6436   u32 label;
6437   ip4_address_t dst_address;
6438   u8 is_add = 1;
6439
6440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6441     {
6442       if (unformat (i, "vrf %d", &vrf_id))
6443         ;
6444       else if (unformat (i, "label %d", &label))
6445         vec_add1 (labels, ntohl (label));
6446       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6447         ;
6448       else if (unformat (i, "del"))
6449         is_add = 0;
6450       else
6451         {
6452           clib_warning ("parse error '%U'", format_unformat_error, i);
6453           return -99;
6454         }
6455     }
6456
6457   if (vec_len (labels) == 0)
6458     {
6459       errmsg ("missing encap label stack\n");
6460       return -99;
6461     }
6462
6463   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6464       sizeof (u32) * vec_len (labels));
6465
6466   mp->vrf_id = ntohl (vrf_id);
6467   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6468   mp->is_add = is_add;
6469   mp->nlabels = vec_len (labels);
6470   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6471
6472   vec_free (labels);
6473
6474   S;
6475   W;
6476   /* NOTREACHED */
6477   return 0;
6478 }
6479
6480 static int
6481 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6482 {
6483   unformat_input_t *i = vam->input;
6484   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6485   f64 timeout;
6486   u32 inner_vrf_id = 0;
6487   ip4_address_t intfc_address;
6488   u8 dst_mac_address[6];
6489   int dst_set = 1;
6490   u32 tmp;
6491   u8 intfc_address_length = 0;
6492   u8 is_add = 1;
6493   u8 l2_only = 0;
6494   u32 tx_sw_if_index;
6495   int tx_sw_if_index_set = 0;
6496
6497   /* Shut up coverity */
6498   memset (dst_mac_address, 0, sizeof (dst_mac_address));
6499
6500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6501     {
6502       if (unformat (i, "vrf %d", &inner_vrf_id))
6503         ;
6504       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6505                          &intfc_address, &tmp))
6506         intfc_address_length = tmp;
6507       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6508         tx_sw_if_index_set = 1;
6509       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6510         tx_sw_if_index_set = 1;
6511       else if (unformat (i, "dst %U", unformat_ethernet_address,
6512                          dst_mac_address))
6513         dst_set = 1;
6514       else if (unformat (i, "l2-only"))
6515         l2_only = 1;
6516       else if (unformat (i, "del"))
6517         is_add = 0;
6518       else
6519         {
6520           clib_warning ("parse error '%U'", format_unformat_error, i);
6521           return -99;
6522         }
6523     }
6524
6525   if (!dst_set)
6526     {
6527       errmsg ("dst (mac address) not set\n");
6528       return -99;
6529     }
6530   if (!tx_sw_if_index_set)
6531     {
6532       errmsg ("tx-intfc not set\n");
6533       return -99;
6534     }
6535
6536   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6537
6538   mp->vrf_id = ntohl (inner_vrf_id);
6539   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6540   mp->adj_address_length = intfc_address_length;
6541   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6542                sizeof (dst_mac_address));
6543   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6544   mp->l2_only = l2_only;
6545   mp->is_add = is_add;
6546
6547   S;
6548   W;
6549   /* NOTREACHED */
6550   return 0;
6551 }
6552
6553 static int
6554 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6555 {
6556   unformat_input_t *i = vam->input;
6557   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6558   f64 timeout;
6559   u32 inner_vrf_id = 0;
6560   u32 outer_vrf_id = 0;
6561   ip4_address_t adj_address;
6562   int adj_address_set = 0;
6563   ip4_address_t next_hop_address;
6564   int next_hop_address_set = 0;
6565   u32 tmp;
6566   u8 adj_address_length = 0;
6567   u8 l2_only = 0;
6568   u8 is_add = 1;
6569   u32 resolve_attempts = 5;
6570   u8 resolve_if_needed = 1;
6571
6572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6573     {
6574       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6575         ;
6576       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6577         ;
6578       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6579                          &adj_address, &tmp))
6580         {
6581           adj_address_length = tmp;
6582           adj_address_set = 1;
6583         }
6584       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6585                          &next_hop_address))
6586         next_hop_address_set = 1;
6587       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6588         ;
6589       else if (unformat (i, "resolve-if-needed %d", &tmp))
6590         resolve_if_needed = tmp;
6591       else if (unformat (i, "l2-only"))
6592         l2_only = 1;
6593       else if (unformat (i, "del"))
6594         is_add = 0;
6595       else
6596         {
6597           clib_warning ("parse error '%U'", format_unformat_error, i);
6598           return -99;
6599         }
6600     }
6601
6602   if (!adj_address_set)
6603     {
6604       errmsg ("adjacency address/mask not set\n");
6605       return -99;
6606     }
6607   if (!next_hop_address_set)
6608     {
6609       errmsg ("ip4 next hop address (in outer fib) not set\n");
6610       return -99;
6611     }
6612
6613   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6614
6615   mp->inner_vrf_id = ntohl (inner_vrf_id);
6616   mp->outer_vrf_id = ntohl (outer_vrf_id);
6617   mp->resolve_attempts = ntohl (resolve_attempts);
6618   mp->resolve_if_needed = resolve_if_needed;
6619   mp->is_add = is_add;
6620   mp->l2_only = l2_only;
6621   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6622   mp->adj_address_length = adj_address_length;
6623   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6624                sizeof (next_hop_address));
6625
6626   S;
6627   W;
6628   /* NOTREACHED */
6629   return 0;
6630 }
6631
6632 static int
6633 api_sw_interface_set_unnumbered (vat_main_t * vam)
6634 {
6635   unformat_input_t *i = vam->input;
6636   vl_api_sw_interface_set_unnumbered_t *mp;
6637   f64 timeout;
6638   u32 sw_if_index;
6639   u32 unnum_sw_index = ~0;
6640   u8 is_add = 1;
6641   u8 sw_if_index_set = 0;
6642
6643   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6644     {
6645       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6646         sw_if_index_set = 1;
6647       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6648         sw_if_index_set = 1;
6649       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6650         ;
6651       else if (unformat (i, "del"))
6652         is_add = 0;
6653       else
6654         {
6655           clib_warning ("parse error '%U'", format_unformat_error, i);
6656           return -99;
6657         }
6658     }
6659
6660   if (sw_if_index_set == 0)
6661     {
6662       errmsg ("missing interface name or sw_if_index\n");
6663       return -99;
6664     }
6665
6666   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6667
6668   mp->sw_if_index = ntohl (sw_if_index);
6669   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6670   mp->is_add = is_add;
6671
6672   S;
6673   W;
6674   /* NOTREACHED */
6675   return 0;
6676 }
6677
6678 static int
6679 api_ip_neighbor_add_del (vat_main_t * vam)
6680 {
6681   unformat_input_t *i = vam->input;
6682   vl_api_ip_neighbor_add_del_t *mp;
6683   f64 timeout;
6684   u32 sw_if_index;
6685   u8 sw_if_index_set = 0;
6686   u32 vrf_id = 0;
6687   u8 is_add = 1;
6688   u8 is_static = 0;
6689   u8 mac_address[6];
6690   u8 mac_set = 0;
6691   u8 v4_address_set = 0;
6692   u8 v6_address_set = 0;
6693   ip4_address_t v4address;
6694   ip6_address_t v6address;
6695
6696   memset (mac_address, 0, sizeof (mac_address));
6697
6698   /* Parse args required to build the message */
6699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6700     {
6701       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6702         {
6703           mac_set = 1;
6704         }
6705       else if (unformat (i, "del"))
6706         is_add = 0;
6707       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6708         sw_if_index_set = 1;
6709       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6710         sw_if_index_set = 1;
6711       else if (unformat (i, "is_static"))
6712         is_static = 1;
6713       else if (unformat (i, "vrf %d", &vrf_id))
6714         ;
6715       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6716         v4_address_set = 1;
6717       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6718         v6_address_set = 1;
6719       else
6720         {
6721           clib_warning ("parse error '%U'", format_unformat_error, i);
6722           return -99;
6723         }
6724     }
6725
6726   if (sw_if_index_set == 0)
6727     {
6728       errmsg ("missing interface name or sw_if_index\n");
6729       return -99;
6730     }
6731   if (v4_address_set && v6_address_set)
6732     {
6733       errmsg ("both v4 and v6 addresses set\n");
6734       return -99;
6735     }
6736   if (!v4_address_set && !v6_address_set)
6737     {
6738       errmsg ("no address set\n");
6739       return -99;
6740     }
6741
6742   /* Construct the API message */
6743   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6744
6745   mp->sw_if_index = ntohl (sw_if_index);
6746   mp->is_add = is_add;
6747   mp->vrf_id = ntohl (vrf_id);
6748   mp->is_static = is_static;
6749   if (mac_set)
6750     clib_memcpy (mp->mac_address, mac_address, 6);
6751   if (v6_address_set)
6752     {
6753       mp->is_ipv6 = 1;
6754       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6755     }
6756   else
6757     {
6758       /* mp->is_ipv6 = 0; via memset in M macro above */
6759       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6760     }
6761
6762   /* send it... */
6763   S;
6764
6765   /* Wait for a reply, return good/bad news  */
6766   W;
6767
6768   /* NOTREACHED */
6769   return 0;
6770 }
6771
6772 static int
6773 api_reset_vrf (vat_main_t * vam)
6774 {
6775   unformat_input_t *i = vam->input;
6776   vl_api_reset_vrf_t *mp;
6777   f64 timeout;
6778   u32 vrf_id = 0;
6779   u8 is_ipv6 = 0;
6780   u8 vrf_id_set = 0;
6781
6782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6783     {
6784       if (unformat (i, "vrf %d", &vrf_id))
6785         vrf_id_set = 1;
6786       else if (unformat (i, "ipv6"))
6787         is_ipv6 = 1;
6788       else
6789         {
6790           clib_warning ("parse error '%U'", format_unformat_error, i);
6791           return -99;
6792         }
6793     }
6794
6795   if (vrf_id_set == 0)
6796     {
6797       errmsg ("missing vrf id\n");
6798       return -99;
6799     }
6800
6801   M (RESET_VRF, reset_vrf);
6802
6803   mp->vrf_id = ntohl (vrf_id);
6804   mp->is_ipv6 = is_ipv6;
6805
6806   S;
6807   W;
6808   /* NOTREACHED */
6809   return 0;
6810 }
6811
6812 static int
6813 api_create_vlan_subif (vat_main_t * vam)
6814 {
6815   unformat_input_t *i = vam->input;
6816   vl_api_create_vlan_subif_t *mp;
6817   f64 timeout;
6818   u32 sw_if_index;
6819   u8 sw_if_index_set = 0;
6820   u32 vlan_id;
6821   u8 vlan_id_set = 0;
6822
6823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6824     {
6825       if (unformat (i, "sw_if_index %d", &sw_if_index))
6826         sw_if_index_set = 1;
6827       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6828         sw_if_index_set = 1;
6829       else if (unformat (i, "vlan %d", &vlan_id))
6830         vlan_id_set = 1;
6831       else
6832         {
6833           clib_warning ("parse error '%U'", format_unformat_error, i);
6834           return -99;
6835         }
6836     }
6837
6838   if (sw_if_index_set == 0)
6839     {
6840       errmsg ("missing interface name or sw_if_index\n");
6841       return -99;
6842     }
6843
6844   if (vlan_id_set == 0)
6845     {
6846       errmsg ("missing vlan_id\n");
6847       return -99;
6848     }
6849   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6850
6851   mp->sw_if_index = ntohl (sw_if_index);
6852   mp->vlan_id = ntohl (vlan_id);
6853
6854   S;
6855   W;
6856   /* NOTREACHED */
6857   return 0;
6858 }
6859
6860 #define foreach_create_subif_bit                \
6861 _(no_tags)                                      \
6862 _(one_tag)                                      \
6863 _(two_tags)                                     \
6864 _(dot1ad)                                       \
6865 _(exact_match)                                  \
6866 _(default_sub)                                  \
6867 _(outer_vlan_id_any)                            \
6868 _(inner_vlan_id_any)
6869
6870 static int
6871 api_create_subif (vat_main_t * vam)
6872 {
6873   unformat_input_t *i = vam->input;
6874   vl_api_create_subif_t *mp;
6875   f64 timeout;
6876   u32 sw_if_index;
6877   u8 sw_if_index_set = 0;
6878   u32 sub_id;
6879   u8 sub_id_set = 0;
6880   u32 no_tags = 0;
6881   u32 one_tag = 0;
6882   u32 two_tags = 0;
6883   u32 dot1ad = 0;
6884   u32 exact_match = 0;
6885   u32 default_sub = 0;
6886   u32 outer_vlan_id_any = 0;
6887   u32 inner_vlan_id_any = 0;
6888   u32 tmp;
6889   u16 outer_vlan_id = 0;
6890   u16 inner_vlan_id = 0;
6891
6892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6893     {
6894       if (unformat (i, "sw_if_index %d", &sw_if_index))
6895         sw_if_index_set = 1;
6896       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6897         sw_if_index_set = 1;
6898       else if (unformat (i, "sub_id %d", &sub_id))
6899         sub_id_set = 1;
6900       else if (unformat (i, "outer_vlan_id %d", &tmp))
6901         outer_vlan_id = tmp;
6902       else if (unformat (i, "inner_vlan_id %d", &tmp))
6903         inner_vlan_id = tmp;
6904
6905 #define _(a) else if (unformat (i, #a)) a = 1 ;
6906       foreach_create_subif_bit
6907 #undef _
6908         else
6909         {
6910           clib_warning ("parse error '%U'", format_unformat_error, i);
6911           return -99;
6912         }
6913     }
6914
6915   if (sw_if_index_set == 0)
6916     {
6917       errmsg ("missing interface name or sw_if_index\n");
6918       return -99;
6919     }
6920
6921   if (sub_id_set == 0)
6922     {
6923       errmsg ("missing sub_id\n");
6924       return -99;
6925     }
6926   M (CREATE_SUBIF, create_subif);
6927
6928   mp->sw_if_index = ntohl (sw_if_index);
6929   mp->sub_id = ntohl (sub_id);
6930
6931 #define _(a) mp->a = a;
6932   foreach_create_subif_bit;
6933 #undef _
6934
6935   mp->outer_vlan_id = ntohs (outer_vlan_id);
6936   mp->inner_vlan_id = ntohs (inner_vlan_id);
6937
6938   S;
6939   W;
6940   /* NOTREACHED */
6941   return 0;
6942 }
6943
6944 static int
6945 api_oam_add_del (vat_main_t * vam)
6946 {
6947   unformat_input_t *i = vam->input;
6948   vl_api_oam_add_del_t *mp;
6949   f64 timeout;
6950   u32 vrf_id = 0;
6951   u8 is_add = 1;
6952   ip4_address_t src, dst;
6953   u8 src_set = 0;
6954   u8 dst_set = 0;
6955
6956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6957     {
6958       if (unformat (i, "vrf %d", &vrf_id))
6959         ;
6960       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6961         src_set = 1;
6962       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6963         dst_set = 1;
6964       else if (unformat (i, "del"))
6965         is_add = 0;
6966       else
6967         {
6968           clib_warning ("parse error '%U'", format_unformat_error, i);
6969           return -99;
6970         }
6971     }
6972
6973   if (src_set == 0)
6974     {
6975       errmsg ("missing src addr\n");
6976       return -99;
6977     }
6978
6979   if (dst_set == 0)
6980     {
6981       errmsg ("missing dst addr\n");
6982       return -99;
6983     }
6984
6985   M (OAM_ADD_DEL, oam_add_del);
6986
6987   mp->vrf_id = ntohl (vrf_id);
6988   mp->is_add = is_add;
6989   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6990   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6991
6992   S;
6993   W;
6994   /* NOTREACHED */
6995   return 0;
6996 }
6997
6998 static int
6999 api_reset_fib (vat_main_t * vam)
7000 {
7001   unformat_input_t *i = vam->input;
7002   vl_api_reset_fib_t *mp;
7003   f64 timeout;
7004   u32 vrf_id = 0;
7005   u8 is_ipv6 = 0;
7006   u8 vrf_id_set = 0;
7007
7008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7009     {
7010       if (unformat (i, "vrf %d", &vrf_id))
7011         vrf_id_set = 1;
7012       else if (unformat (i, "ipv6"))
7013         is_ipv6 = 1;
7014       else
7015         {
7016           clib_warning ("parse error '%U'", format_unformat_error, i);
7017           return -99;
7018         }
7019     }
7020
7021   if (vrf_id_set == 0)
7022     {
7023       errmsg ("missing vrf id\n");
7024       return -99;
7025     }
7026
7027   M (RESET_FIB, reset_fib);
7028
7029   mp->vrf_id = ntohl (vrf_id);
7030   mp->is_ipv6 = is_ipv6;
7031
7032   S;
7033   W;
7034   /* NOTREACHED */
7035   return 0;
7036 }
7037
7038 static int
7039 api_dhcp_proxy_config (vat_main_t * vam)
7040 {
7041   unformat_input_t *i = vam->input;
7042   vl_api_dhcp_proxy_config_t *mp;
7043   f64 timeout;
7044   u32 vrf_id = 0;
7045   u8 is_add = 1;
7046   u8 insert_cid = 1;
7047   u8 v4_address_set = 0;
7048   u8 v6_address_set = 0;
7049   ip4_address_t v4address;
7050   ip6_address_t v6address;
7051   u8 v4_src_address_set = 0;
7052   u8 v6_src_address_set = 0;
7053   ip4_address_t v4srcaddress;
7054   ip6_address_t v6srcaddress;
7055
7056   /* Parse args required to build the message */
7057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7058     {
7059       if (unformat (i, "del"))
7060         is_add = 0;
7061       else if (unformat (i, "vrf %d", &vrf_id))
7062         ;
7063       else if (unformat (i, "insert-cid %d", &insert_cid))
7064         ;
7065       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7066         v4_address_set = 1;
7067       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7068         v6_address_set = 1;
7069       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7070         v4_src_address_set = 1;
7071       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7072         v6_src_address_set = 1;
7073       else
7074         break;
7075     }
7076
7077   if (v4_address_set && v6_address_set)
7078     {
7079       errmsg ("both v4 and v6 server addresses set\n");
7080       return -99;
7081     }
7082   if (!v4_address_set && !v6_address_set)
7083     {
7084       errmsg ("no server addresses set\n");
7085       return -99;
7086     }
7087
7088   if (v4_src_address_set && v6_src_address_set)
7089     {
7090       errmsg ("both v4 and v6  src addresses set\n");
7091       return -99;
7092     }
7093   if (!v4_src_address_set && !v6_src_address_set)
7094     {
7095       errmsg ("no src addresses set\n");
7096       return -99;
7097     }
7098
7099   if (!(v4_src_address_set && v4_address_set) &&
7100       !(v6_src_address_set && v6_address_set))
7101     {
7102       errmsg ("no matching server and src addresses set\n");
7103       return -99;
7104     }
7105
7106   /* Construct the API message */
7107   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7108
7109   mp->insert_circuit_id = insert_cid;
7110   mp->is_add = is_add;
7111   mp->vrf_id = ntohl (vrf_id);
7112   if (v6_address_set)
7113     {
7114       mp->is_ipv6 = 1;
7115       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7116       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7117     }
7118   else
7119     {
7120       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7121       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7122     }
7123
7124   /* send it... */
7125   S;
7126
7127   /* Wait for a reply, return good/bad news  */
7128   W;
7129   /* NOTREACHED */
7130   return 0;
7131 }
7132
7133 static int
7134 api_dhcp_proxy_config_2 (vat_main_t * vam)
7135 {
7136   unformat_input_t *i = vam->input;
7137   vl_api_dhcp_proxy_config_2_t *mp;
7138   f64 timeout;
7139   u32 rx_vrf_id = 0;
7140   u32 server_vrf_id = 0;
7141   u8 is_add = 1;
7142   u8 insert_cid = 1;
7143   u8 v4_address_set = 0;
7144   u8 v6_address_set = 0;
7145   ip4_address_t v4address;
7146   ip6_address_t v6address;
7147   u8 v4_src_address_set = 0;
7148   u8 v6_src_address_set = 0;
7149   ip4_address_t v4srcaddress;
7150   ip6_address_t v6srcaddress;
7151
7152   /* Parse args required to build the message */
7153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7154     {
7155       if (unformat (i, "del"))
7156         is_add = 0;
7157       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7158         ;
7159       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7160         ;
7161       else if (unformat (i, "insert-cid %d", &insert_cid))
7162         ;
7163       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7164         v4_address_set = 1;
7165       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7166         v6_address_set = 1;
7167       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7168         v4_src_address_set = 1;
7169       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7170         v6_src_address_set = 1;
7171       else
7172         break;
7173     }
7174
7175   if (v4_address_set && v6_address_set)
7176     {
7177       errmsg ("both v4 and v6 server addresses set\n");
7178       return -99;
7179     }
7180   if (!v4_address_set && !v6_address_set)
7181     {
7182       errmsg ("no server addresses set\n");
7183       return -99;
7184     }
7185
7186   if (v4_src_address_set && v6_src_address_set)
7187     {
7188       errmsg ("both v4 and v6  src addresses set\n");
7189       return -99;
7190     }
7191   if (!v4_src_address_set && !v6_src_address_set)
7192     {
7193       errmsg ("no src addresses set\n");
7194       return -99;
7195     }
7196
7197   if (!(v4_src_address_set && v4_address_set) &&
7198       !(v6_src_address_set && v6_address_set))
7199     {
7200       errmsg ("no matching server and src addresses set\n");
7201       return -99;
7202     }
7203
7204   /* Construct the API message */
7205   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7206
7207   mp->insert_circuit_id = insert_cid;
7208   mp->is_add = is_add;
7209   mp->rx_vrf_id = ntohl (rx_vrf_id);
7210   mp->server_vrf_id = ntohl (server_vrf_id);
7211   if (v6_address_set)
7212     {
7213       mp->is_ipv6 = 1;
7214       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7215       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7216     }
7217   else
7218     {
7219       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7220       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7221     }
7222
7223   /* send it... */
7224   S;
7225
7226   /* Wait for a reply, return good/bad news  */
7227   W;
7228   /* NOTREACHED */
7229   return 0;
7230 }
7231
7232 static int
7233 api_dhcp_proxy_set_vss (vat_main_t * vam)
7234 {
7235   unformat_input_t *i = vam->input;
7236   vl_api_dhcp_proxy_set_vss_t *mp;
7237   f64 timeout;
7238   u8 is_ipv6 = 0;
7239   u8 is_add = 1;
7240   u32 tbl_id;
7241   u8 tbl_id_set = 0;
7242   u32 oui;
7243   u8 oui_set = 0;
7244   u32 fib_id;
7245   u8 fib_id_set = 0;
7246
7247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7248     {
7249       if (unformat (i, "tbl_id %d", &tbl_id))
7250         tbl_id_set = 1;
7251       if (unformat (i, "fib_id %d", &fib_id))
7252         fib_id_set = 1;
7253       if (unformat (i, "oui %d", &oui))
7254         oui_set = 1;
7255       else if (unformat (i, "ipv6"))
7256         is_ipv6 = 1;
7257       else if (unformat (i, "del"))
7258         is_add = 0;
7259       else
7260         {
7261           clib_warning ("parse error '%U'", format_unformat_error, i);
7262           return -99;
7263         }
7264     }
7265
7266   if (tbl_id_set == 0)
7267     {
7268       errmsg ("missing tbl id\n");
7269       return -99;
7270     }
7271
7272   if (fib_id_set == 0)
7273     {
7274       errmsg ("missing fib id\n");
7275       return -99;
7276     }
7277   if (oui_set == 0)
7278     {
7279       errmsg ("missing oui\n");
7280       return -99;
7281     }
7282
7283   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7284   mp->tbl_id = ntohl (tbl_id);
7285   mp->fib_id = ntohl (fib_id);
7286   mp->oui = ntohl (oui);
7287   mp->is_ipv6 = is_ipv6;
7288   mp->is_add = is_add;
7289
7290   S;
7291   W;
7292   /* NOTREACHED */
7293   return 0;
7294 }
7295
7296 static int
7297 api_dhcp_client_config (vat_main_t * vam)
7298 {
7299   unformat_input_t *i = vam->input;
7300   vl_api_dhcp_client_config_t *mp;
7301   f64 timeout;
7302   u32 sw_if_index;
7303   u8 sw_if_index_set = 0;
7304   u8 is_add = 1;
7305   u8 *hostname = 0;
7306   u8 disable_event = 0;
7307
7308   /* Parse args required to build the message */
7309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7310     {
7311       if (unformat (i, "del"))
7312         is_add = 0;
7313       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7314         sw_if_index_set = 1;
7315       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7316         sw_if_index_set = 1;
7317       else if (unformat (i, "hostname %s", &hostname))
7318         ;
7319       else if (unformat (i, "disable_event"))
7320         disable_event = 1;
7321       else
7322         break;
7323     }
7324
7325   if (sw_if_index_set == 0)
7326     {
7327       errmsg ("missing interface name or sw_if_index\n");
7328       return -99;
7329     }
7330
7331   if (vec_len (hostname) > 63)
7332     {
7333       errmsg ("hostname too long\n");
7334     }
7335   vec_add1 (hostname, 0);
7336
7337   /* Construct the API message */
7338   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7339
7340   mp->sw_if_index = ntohl (sw_if_index);
7341   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7342   vec_free (hostname);
7343   mp->is_add = is_add;
7344   mp->want_dhcp_event = disable_event ? 0 : 1;
7345   mp->pid = getpid ();
7346
7347   /* send it... */
7348   S;
7349
7350   /* Wait for a reply, return good/bad news  */
7351   W;
7352   /* NOTREACHED */
7353   return 0;
7354 }
7355
7356 static int
7357 api_set_ip_flow_hash (vat_main_t * vam)
7358 {
7359   unformat_input_t *i = vam->input;
7360   vl_api_set_ip_flow_hash_t *mp;
7361   f64 timeout;
7362   u32 vrf_id = 0;
7363   u8 is_ipv6 = 0;
7364   u8 vrf_id_set = 0;
7365   u8 src = 0;
7366   u8 dst = 0;
7367   u8 sport = 0;
7368   u8 dport = 0;
7369   u8 proto = 0;
7370   u8 reverse = 0;
7371
7372   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7373     {
7374       if (unformat (i, "vrf %d", &vrf_id))
7375         vrf_id_set = 1;
7376       else if (unformat (i, "ipv6"))
7377         is_ipv6 = 1;
7378       else if (unformat (i, "src"))
7379         src = 1;
7380       else if (unformat (i, "dst"))
7381         dst = 1;
7382       else if (unformat (i, "sport"))
7383         sport = 1;
7384       else if (unformat (i, "dport"))
7385         dport = 1;
7386       else if (unformat (i, "proto"))
7387         proto = 1;
7388       else if (unformat (i, "reverse"))
7389         reverse = 1;
7390
7391       else
7392         {
7393           clib_warning ("parse error '%U'", format_unformat_error, i);
7394           return -99;
7395         }
7396     }
7397
7398   if (vrf_id_set == 0)
7399     {
7400       errmsg ("missing vrf id\n");
7401       return -99;
7402     }
7403
7404   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7405   mp->src = src;
7406   mp->dst = dst;
7407   mp->sport = sport;
7408   mp->dport = dport;
7409   mp->proto = proto;
7410   mp->reverse = reverse;
7411   mp->vrf_id = ntohl (vrf_id);
7412   mp->is_ipv6 = is_ipv6;
7413
7414   S;
7415   W;
7416   /* NOTREACHED */
7417   return 0;
7418 }
7419
7420 static int
7421 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7422 {
7423   unformat_input_t *i = vam->input;
7424   vl_api_sw_interface_ip6_enable_disable_t *mp;
7425   f64 timeout;
7426   u32 sw_if_index;
7427   u8 sw_if_index_set = 0;
7428   u8 enable = 0;
7429
7430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7431     {
7432       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7433         sw_if_index_set = 1;
7434       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7435         sw_if_index_set = 1;
7436       else if (unformat (i, "enable"))
7437         enable = 1;
7438       else if (unformat (i, "disable"))
7439         enable = 0;
7440       else
7441         {
7442           clib_warning ("parse error '%U'", format_unformat_error, i);
7443           return -99;
7444         }
7445     }
7446
7447   if (sw_if_index_set == 0)
7448     {
7449       errmsg ("missing interface name or sw_if_index\n");
7450       return -99;
7451     }
7452
7453   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7454
7455   mp->sw_if_index = ntohl (sw_if_index);
7456   mp->enable = enable;
7457
7458   S;
7459   W;
7460   /* NOTREACHED */
7461   return 0;
7462 }
7463
7464 static int
7465 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7466 {
7467   unformat_input_t *i = vam->input;
7468   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7469   f64 timeout;
7470   u32 sw_if_index;
7471   u8 sw_if_index_set = 0;
7472   u32 address_length = 0;
7473   u8 v6_address_set = 0;
7474   ip6_address_t v6address;
7475
7476   /* Parse args required to build the message */
7477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7478     {
7479       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7480         sw_if_index_set = 1;
7481       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7482         sw_if_index_set = 1;
7483       else if (unformat (i, "%U/%d",
7484                          unformat_ip6_address, &v6address, &address_length))
7485         v6_address_set = 1;
7486       else
7487         break;
7488     }
7489
7490   if (sw_if_index_set == 0)
7491     {
7492       errmsg ("missing interface name or sw_if_index\n");
7493       return -99;
7494     }
7495   if (!v6_address_set)
7496     {
7497       errmsg ("no address set\n");
7498       return -99;
7499     }
7500
7501   /* Construct the API message */
7502   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7503      sw_interface_ip6_set_link_local_address);
7504
7505   mp->sw_if_index = ntohl (sw_if_index);
7506   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7507   mp->address_length = address_length;
7508
7509   /* send it... */
7510   S;
7511
7512   /* Wait for a reply, return good/bad news  */
7513   W;
7514
7515   /* NOTREACHED */
7516   return 0;
7517 }
7518
7519
7520 static int
7521 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7522 {
7523   unformat_input_t *i = vam->input;
7524   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7525   f64 timeout;
7526   u32 sw_if_index;
7527   u8 sw_if_index_set = 0;
7528   u32 address_length = 0;
7529   u8 v6_address_set = 0;
7530   ip6_address_t v6address;
7531   u8 use_default = 0;
7532   u8 no_advertise = 0;
7533   u8 off_link = 0;
7534   u8 no_autoconfig = 0;
7535   u8 no_onlink = 0;
7536   u8 is_no = 0;
7537   u32 val_lifetime = 0;
7538   u32 pref_lifetime = 0;
7539
7540   /* Parse args required to build the message */
7541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7542     {
7543       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7544         sw_if_index_set = 1;
7545       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7546         sw_if_index_set = 1;
7547       else if (unformat (i, "%U/%d",
7548                          unformat_ip6_address, &v6address, &address_length))
7549         v6_address_set = 1;
7550       else if (unformat (i, "val_life %d", &val_lifetime))
7551         ;
7552       else if (unformat (i, "pref_life %d", &pref_lifetime))
7553         ;
7554       else if (unformat (i, "def"))
7555         use_default = 1;
7556       else if (unformat (i, "noadv"))
7557         no_advertise = 1;
7558       else if (unformat (i, "offl"))
7559         off_link = 1;
7560       else if (unformat (i, "noauto"))
7561         no_autoconfig = 1;
7562       else if (unformat (i, "nolink"))
7563         no_onlink = 1;
7564       else if (unformat (i, "isno"))
7565         is_no = 1;
7566       else
7567         {
7568           clib_warning ("parse error '%U'", format_unformat_error, i);
7569           return -99;
7570         }
7571     }
7572
7573   if (sw_if_index_set == 0)
7574     {
7575       errmsg ("missing interface name or sw_if_index\n");
7576       return -99;
7577     }
7578   if (!v6_address_set)
7579     {
7580       errmsg ("no address set\n");
7581       return -99;
7582     }
7583
7584   /* Construct the API message */
7585   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7586
7587   mp->sw_if_index = ntohl (sw_if_index);
7588   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7589   mp->address_length = address_length;
7590   mp->use_default = use_default;
7591   mp->no_advertise = no_advertise;
7592   mp->off_link = off_link;
7593   mp->no_autoconfig = no_autoconfig;
7594   mp->no_onlink = no_onlink;
7595   mp->is_no = is_no;
7596   mp->val_lifetime = ntohl (val_lifetime);
7597   mp->pref_lifetime = ntohl (pref_lifetime);
7598
7599   /* send it... */
7600   S;
7601
7602   /* Wait for a reply, return good/bad news  */
7603   W;
7604
7605   /* NOTREACHED */
7606   return 0;
7607 }
7608
7609 static int
7610 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7611 {
7612   unformat_input_t *i = vam->input;
7613   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7614   f64 timeout;
7615   u32 sw_if_index;
7616   u8 sw_if_index_set = 0;
7617   u8 suppress = 0;
7618   u8 managed = 0;
7619   u8 other = 0;
7620   u8 ll_option = 0;
7621   u8 send_unicast = 0;
7622   u8 cease = 0;
7623   u8 is_no = 0;
7624   u8 default_router = 0;
7625   u32 max_interval = 0;
7626   u32 min_interval = 0;
7627   u32 lifetime = 0;
7628   u32 initial_count = 0;
7629   u32 initial_interval = 0;
7630
7631
7632   /* Parse args required to build the message */
7633   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7634     {
7635       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7636         sw_if_index_set = 1;
7637       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7638         sw_if_index_set = 1;
7639       else if (unformat (i, "maxint %d", &max_interval))
7640         ;
7641       else if (unformat (i, "minint %d", &min_interval))
7642         ;
7643       else if (unformat (i, "life %d", &lifetime))
7644         ;
7645       else if (unformat (i, "count %d", &initial_count))
7646         ;
7647       else if (unformat (i, "interval %d", &initial_interval))
7648         ;
7649       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7650         suppress = 1;
7651       else if (unformat (i, "managed"))
7652         managed = 1;
7653       else if (unformat (i, "other"))
7654         other = 1;
7655       else if (unformat (i, "ll"))
7656         ll_option = 1;
7657       else if (unformat (i, "send"))
7658         send_unicast = 1;
7659       else if (unformat (i, "cease"))
7660         cease = 1;
7661       else if (unformat (i, "isno"))
7662         is_no = 1;
7663       else if (unformat (i, "def"))
7664         default_router = 1;
7665       else
7666         {
7667           clib_warning ("parse error '%U'", format_unformat_error, i);
7668           return -99;
7669         }
7670     }
7671
7672   if (sw_if_index_set == 0)
7673     {
7674       errmsg ("missing interface name or sw_if_index\n");
7675       return -99;
7676     }
7677
7678   /* Construct the API message */
7679   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7680
7681   mp->sw_if_index = ntohl (sw_if_index);
7682   mp->max_interval = ntohl (max_interval);
7683   mp->min_interval = ntohl (min_interval);
7684   mp->lifetime = ntohl (lifetime);
7685   mp->initial_count = ntohl (initial_count);
7686   mp->initial_interval = ntohl (initial_interval);
7687   mp->suppress = suppress;
7688   mp->managed = managed;
7689   mp->other = other;
7690   mp->ll_option = ll_option;
7691   mp->send_unicast = send_unicast;
7692   mp->cease = cease;
7693   mp->is_no = is_no;
7694   mp->default_router = default_router;
7695
7696   /* send it... */
7697   S;
7698
7699   /* Wait for a reply, return good/bad news  */
7700   W;
7701
7702   /* NOTREACHED */
7703   return 0;
7704 }
7705
7706 static int
7707 api_set_arp_neighbor_limit (vat_main_t * vam)
7708 {
7709   unformat_input_t *i = vam->input;
7710   vl_api_set_arp_neighbor_limit_t *mp;
7711   f64 timeout;
7712   u32 arp_nbr_limit;
7713   u8 limit_set = 0;
7714   u8 is_ipv6 = 0;
7715
7716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7717     {
7718       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7719         limit_set = 1;
7720       else if (unformat (i, "ipv6"))
7721         is_ipv6 = 1;
7722       else
7723         {
7724           clib_warning ("parse error '%U'", format_unformat_error, i);
7725           return -99;
7726         }
7727     }
7728
7729   if (limit_set == 0)
7730     {
7731       errmsg ("missing limit value\n");
7732       return -99;
7733     }
7734
7735   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7736
7737   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7738   mp->is_ipv6 = is_ipv6;
7739
7740   S;
7741   W;
7742   /* NOTREACHED */
7743   return 0;
7744 }
7745
7746 static int
7747 api_l2_patch_add_del (vat_main_t * vam)
7748 {
7749   unformat_input_t *i = vam->input;
7750   vl_api_l2_patch_add_del_t *mp;
7751   f64 timeout;
7752   u32 rx_sw_if_index;
7753   u8 rx_sw_if_index_set = 0;
7754   u32 tx_sw_if_index;
7755   u8 tx_sw_if_index_set = 0;
7756   u8 is_add = 1;
7757
7758   /* Parse args required to build the message */
7759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7760     {
7761       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7762         rx_sw_if_index_set = 1;
7763       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7764         tx_sw_if_index_set = 1;
7765       else if (unformat (i, "rx"))
7766         {
7767           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7768             {
7769               if (unformat (i, "%U", unformat_sw_if_index, vam,
7770                             &rx_sw_if_index))
7771                 rx_sw_if_index_set = 1;
7772             }
7773           else
7774             break;
7775         }
7776       else if (unformat (i, "tx"))
7777         {
7778           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7779             {
7780               if (unformat (i, "%U", unformat_sw_if_index, vam,
7781                             &tx_sw_if_index))
7782                 tx_sw_if_index_set = 1;
7783             }
7784           else
7785             break;
7786         }
7787       else if (unformat (i, "del"))
7788         is_add = 0;
7789       else
7790         break;
7791     }
7792
7793   if (rx_sw_if_index_set == 0)
7794     {
7795       errmsg ("missing rx interface name or rx_sw_if_index\n");
7796       return -99;
7797     }
7798
7799   if (tx_sw_if_index_set == 0)
7800     {
7801       errmsg ("missing tx interface name or tx_sw_if_index\n");
7802       return -99;
7803     }
7804
7805   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7806
7807   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7808   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7809   mp->is_add = is_add;
7810
7811   S;
7812   W;
7813   /* NOTREACHED */
7814   return 0;
7815 }
7816
7817 static int
7818 api_ioam_enable (vat_main_t * vam)
7819 {
7820   unformat_input_t *input = vam->input;
7821   vl_api_ioam_enable_t *mp;
7822   f64 timeout;
7823   u32 id = 0;
7824   int has_trace_option = 0;
7825   int has_pot_option = 0;
7826   int has_seqno_option = 0;
7827   int has_analyse_option = 0;
7828
7829   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7830     {
7831       if (unformat (input, "trace"))
7832         has_trace_option = 1;
7833       else if (unformat (input, "pot"))
7834         has_pot_option = 1;
7835       else if (unformat (input, "seqno"))
7836         has_seqno_option = 1;
7837       else if (unformat (input, "analyse"))
7838         has_analyse_option = 1;
7839       else
7840         break;
7841     }
7842   M (IOAM_ENABLE, ioam_enable);
7843   mp->id = htons (id);
7844   mp->seqno = has_seqno_option;
7845   mp->analyse = has_analyse_option;
7846   mp->pot_enable = has_pot_option;
7847   mp->trace_enable = has_trace_option;
7848
7849   S;
7850   W;
7851
7852   return (0);
7853
7854 }
7855
7856
7857 static int
7858 api_ioam_disable (vat_main_t * vam)
7859 {
7860   vl_api_ioam_disable_t *mp;
7861   f64 timeout;
7862
7863   M (IOAM_DISABLE, ioam_disable);
7864   S;
7865   W;
7866   return 0;
7867 }
7868
7869 static int
7870 api_sr_tunnel_add_del (vat_main_t * vam)
7871 {
7872   unformat_input_t *i = vam->input;
7873   vl_api_sr_tunnel_add_del_t *mp;
7874   f64 timeout;
7875   int is_del = 0;
7876   int pl_index;
7877   ip6_address_t src_address;
7878   int src_address_set = 0;
7879   ip6_address_t dst_address;
7880   u32 dst_mask_width;
7881   int dst_address_set = 0;
7882   u16 flags = 0;
7883   u32 rx_table_id = 0;
7884   u32 tx_table_id = 0;
7885   ip6_address_t *segments = 0;
7886   ip6_address_t *this_seg;
7887   ip6_address_t *tags = 0;
7888   ip6_address_t *this_tag;
7889   ip6_address_t next_address, tag;
7890   u8 *name = 0;
7891   u8 *policy_name = 0;
7892
7893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7894     {
7895       if (unformat (i, "del"))
7896         is_del = 1;
7897       else if (unformat (i, "name %s", &name))
7898         ;
7899       else if (unformat (i, "policy %s", &policy_name))
7900         ;
7901       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7902         ;
7903       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7904         ;
7905       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7906         src_address_set = 1;
7907       else if (unformat (i, "dst %U/%d",
7908                          unformat_ip6_address, &dst_address, &dst_mask_width))
7909         dst_address_set = 1;
7910       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7911         {
7912           vec_add2 (segments, this_seg, 1);
7913           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7914                        sizeof (*this_seg));
7915         }
7916       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7917         {
7918           vec_add2 (tags, this_tag, 1);
7919           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7920         }
7921       else if (unformat (i, "clean"))
7922         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7923       else if (unformat (i, "protected"))
7924         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7925       else if (unformat (i, "InPE %d", &pl_index))
7926         {
7927           if (pl_index <= 0 || pl_index > 4)
7928             {
7929             pl_index_range_error:
7930               errmsg ("pl index %d out of range\n", pl_index);
7931               return -99;
7932             }
7933           flags |=
7934             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7935         }
7936       else if (unformat (i, "EgPE %d", &pl_index))
7937         {
7938           if (pl_index <= 0 || pl_index > 4)
7939             goto pl_index_range_error;
7940           flags |=
7941             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7942         }
7943       else if (unformat (i, "OrgSrc %d", &pl_index))
7944         {
7945           if (pl_index <= 0 || pl_index > 4)
7946             goto pl_index_range_error;
7947           flags |=
7948             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7949         }
7950       else
7951         break;
7952     }
7953
7954   if (!src_address_set)
7955     {
7956       errmsg ("src address required\n");
7957       return -99;
7958     }
7959
7960   if (!dst_address_set)
7961     {
7962       errmsg ("dst address required\n");
7963       return -99;
7964     }
7965
7966   if (!segments)
7967     {
7968       errmsg ("at least one sr segment required\n");
7969       return -99;
7970     }
7971
7972   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7973       vec_len (segments) * sizeof (ip6_address_t)
7974       + vec_len (tags) * sizeof (ip6_address_t));
7975
7976   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7977   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7978   mp->dst_mask_width = dst_mask_width;
7979   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7980   mp->n_segments = vec_len (segments);
7981   mp->n_tags = vec_len (tags);
7982   mp->is_add = is_del == 0;
7983   clib_memcpy (mp->segs_and_tags, segments,
7984                vec_len (segments) * sizeof (ip6_address_t));
7985   clib_memcpy (mp->segs_and_tags +
7986                vec_len (segments) * sizeof (ip6_address_t), tags,
7987                vec_len (tags) * sizeof (ip6_address_t));
7988
7989   mp->outer_vrf_id = ntohl (rx_table_id);
7990   mp->inner_vrf_id = ntohl (tx_table_id);
7991   memcpy (mp->name, name, vec_len (name));
7992   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7993
7994   vec_free (segments);
7995   vec_free (tags);
7996
7997   S;
7998   W;
7999   /* NOTREACHED */
8000 }
8001
8002 static int
8003 api_sr_policy_add_del (vat_main_t * vam)
8004 {
8005   unformat_input_t *input = vam->input;
8006   vl_api_sr_policy_add_del_t *mp;
8007   f64 timeout;
8008   int is_del = 0;
8009   u8 *name = 0;
8010   u8 *tunnel_name = 0;
8011   u8 **tunnel_names = 0;
8012
8013   int name_set = 0;
8014   int tunnel_set = 0;
8015   int j = 0;
8016   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8017   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8018
8019   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8020     {
8021       if (unformat (input, "del"))
8022         is_del = 1;
8023       else if (unformat (input, "name %s", &name))
8024         name_set = 1;
8025       else if (unformat (input, "tunnel %s", &tunnel_name))
8026         {
8027           if (tunnel_name)
8028             {
8029               vec_add1 (tunnel_names, tunnel_name);
8030               /* For serializer:
8031                  - length = #bytes to store in serial vector
8032                  - +1 = byte to store that length
8033                */
8034               tunnel_names_length += (vec_len (tunnel_name) + 1);
8035               tunnel_set = 1;
8036               tunnel_name = 0;
8037             }
8038         }
8039       else
8040         break;
8041     }
8042
8043   if (!name_set)
8044     {
8045       errmsg ("policy name required\n");
8046       return -99;
8047     }
8048
8049   if ((!tunnel_set) && (!is_del))
8050     {
8051       errmsg ("tunnel name required\n");
8052       return -99;
8053     }
8054
8055   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8056
8057
8058
8059   mp->is_add = !is_del;
8060
8061   memcpy (mp->name, name, vec_len (name));
8062   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8063   u8 *serial_orig = 0;
8064   vec_validate (serial_orig, tunnel_names_length);
8065   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8066   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8067
8068   for (j = 0; j < vec_len (tunnel_names); j++)
8069     {
8070       tun_name_len = vec_len (tunnel_names[j]);
8071       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8072       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8073       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8074       serial_orig += tun_name_len;      // Advance past the copy
8075     }
8076   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8077
8078   vec_free (tunnel_names);
8079   vec_free (tunnel_name);
8080
8081   S;
8082   W;
8083   /* NOTREACHED */
8084 }
8085
8086 static int
8087 api_sr_multicast_map_add_del (vat_main_t * vam)
8088 {
8089   unformat_input_t *input = vam->input;
8090   vl_api_sr_multicast_map_add_del_t *mp;
8091   f64 timeout;
8092   int is_del = 0;
8093   ip6_address_t multicast_address;
8094   u8 *policy_name = 0;
8095   int multicast_address_set = 0;
8096
8097   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8098     {
8099       if (unformat (input, "del"))
8100         is_del = 1;
8101       else
8102         if (unformat
8103             (input, "address %U", unformat_ip6_address, &multicast_address))
8104         multicast_address_set = 1;
8105       else if (unformat (input, "sr-policy %s", &policy_name))
8106         ;
8107       else
8108         break;
8109     }
8110
8111   if (!is_del && !policy_name)
8112     {
8113       errmsg ("sr-policy name required\n");
8114       return -99;
8115     }
8116
8117
8118   if (!multicast_address_set)
8119     {
8120       errmsg ("address required\n");
8121       return -99;
8122     }
8123
8124   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8125
8126   mp->is_add = !is_del;
8127   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8128   clib_memcpy (mp->multicast_address, &multicast_address,
8129                sizeof (mp->multicast_address));
8130
8131
8132   vec_free (policy_name);
8133
8134   S;
8135   W;
8136   /* NOTREACHED */
8137 }
8138
8139
8140 #define foreach_tcp_proto_field                 \
8141 _(src_port)                                     \
8142 _(dst_port)
8143
8144 #define foreach_udp_proto_field                 \
8145 _(src_port)                                     \
8146 _(dst_port)
8147
8148 #define foreach_ip4_proto_field                 \
8149 _(src_address)                                  \
8150 _(dst_address)                                  \
8151 _(tos)                                          \
8152 _(length)                                       \
8153 _(fragment_id)                                  \
8154 _(ttl)                                          \
8155 _(protocol)                                     \
8156 _(checksum)
8157
8158 uword
8159 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8160 {
8161   u8 **maskp = va_arg (*args, u8 **);
8162   u8 *mask = 0;
8163   u8 found_something = 0;
8164   tcp_header_t *tcp;
8165
8166 #define _(a) u8 a=0;
8167   foreach_tcp_proto_field;
8168 #undef _
8169
8170   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8171     {
8172       if (0);
8173 #define _(a) else if (unformat (input, #a)) a=1;
8174       foreach_tcp_proto_field
8175 #undef _
8176         else
8177         break;
8178     }
8179
8180 #define _(a) found_something += a;
8181   foreach_tcp_proto_field;
8182 #undef _
8183
8184   if (found_something == 0)
8185     return 0;
8186
8187   vec_validate (mask, sizeof (*tcp) - 1);
8188
8189   tcp = (tcp_header_t *) mask;
8190
8191 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8192   foreach_tcp_proto_field;
8193 #undef _
8194
8195   *maskp = mask;
8196   return 1;
8197 }
8198
8199 uword
8200 unformat_udp_mask (unformat_input_t * input, va_list * args)
8201 {
8202   u8 **maskp = va_arg (*args, u8 **);
8203   u8 *mask = 0;
8204   u8 found_something = 0;
8205   udp_header_t *udp;
8206
8207 #define _(a) u8 a=0;
8208   foreach_udp_proto_field;
8209 #undef _
8210
8211   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8212     {
8213       if (0);
8214 #define _(a) else if (unformat (input, #a)) a=1;
8215       foreach_udp_proto_field
8216 #undef _
8217         else
8218         break;
8219     }
8220
8221 #define _(a) found_something += a;
8222   foreach_udp_proto_field;
8223 #undef _
8224
8225   if (found_something == 0)
8226     return 0;
8227
8228   vec_validate (mask, sizeof (*udp) - 1);
8229
8230   udp = (udp_header_t *) mask;
8231
8232 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8233   foreach_udp_proto_field;
8234 #undef _
8235
8236   *maskp = mask;
8237   return 1;
8238 }
8239
8240 typedef struct
8241 {
8242   u16 src_port, dst_port;
8243 } tcpudp_header_t;
8244
8245 uword
8246 unformat_l4_mask (unformat_input_t * input, va_list * args)
8247 {
8248   u8 **maskp = va_arg (*args, u8 **);
8249   u16 src_port = 0, dst_port = 0;
8250   tcpudp_header_t *tcpudp;
8251
8252   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8253     {
8254       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8255         return 1;
8256       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8257         return 1;
8258       else if (unformat (input, "src_port"))
8259         src_port = 0xFFFF;
8260       else if (unformat (input, "dst_port"))
8261         dst_port = 0xFFFF;
8262       else
8263         return 0;
8264     }
8265
8266   if (!src_port && !dst_port)
8267     return 0;
8268
8269   u8 *mask = 0;
8270   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8271
8272   tcpudp = (tcpudp_header_t *) mask;
8273   tcpudp->src_port = src_port;
8274   tcpudp->dst_port = dst_port;
8275
8276   *maskp = mask;
8277
8278   return 1;
8279 }
8280
8281 uword
8282 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8283 {
8284   u8 **maskp = va_arg (*args, u8 **);
8285   u8 *mask = 0;
8286   u8 found_something = 0;
8287   ip4_header_t *ip;
8288
8289 #define _(a) u8 a=0;
8290   foreach_ip4_proto_field;
8291 #undef _
8292   u8 version = 0;
8293   u8 hdr_length = 0;
8294
8295
8296   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8297     {
8298       if (unformat (input, "version"))
8299         version = 1;
8300       else if (unformat (input, "hdr_length"))
8301         hdr_length = 1;
8302       else if (unformat (input, "src"))
8303         src_address = 1;
8304       else if (unformat (input, "dst"))
8305         dst_address = 1;
8306       else if (unformat (input, "proto"))
8307         protocol = 1;
8308
8309 #define _(a) else if (unformat (input, #a)) a=1;
8310       foreach_ip4_proto_field
8311 #undef _
8312         else
8313         break;
8314     }
8315
8316 #define _(a) found_something += a;
8317   foreach_ip4_proto_field;
8318 #undef _
8319
8320   if (found_something == 0)
8321     return 0;
8322
8323   vec_validate (mask, sizeof (*ip) - 1);
8324
8325   ip = (ip4_header_t *) mask;
8326
8327 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8328   foreach_ip4_proto_field;
8329 #undef _
8330
8331   ip->ip_version_and_header_length = 0;
8332
8333   if (version)
8334     ip->ip_version_and_header_length |= 0xF0;
8335
8336   if (hdr_length)
8337     ip->ip_version_and_header_length |= 0x0F;
8338
8339   *maskp = mask;
8340   return 1;
8341 }
8342
8343 #define foreach_ip6_proto_field                 \
8344 _(src_address)                                  \
8345 _(dst_address)                                  \
8346 _(payload_length)                               \
8347 _(hop_limit)                                    \
8348 _(protocol)
8349
8350 uword
8351 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8352 {
8353   u8 **maskp = va_arg (*args, u8 **);
8354   u8 *mask = 0;
8355   u8 found_something = 0;
8356   ip6_header_t *ip;
8357   u32 ip_version_traffic_class_and_flow_label;
8358
8359 #define _(a) u8 a=0;
8360   foreach_ip6_proto_field;
8361 #undef _
8362   u8 version = 0;
8363   u8 traffic_class = 0;
8364   u8 flow_label = 0;
8365
8366   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8367     {
8368       if (unformat (input, "version"))
8369         version = 1;
8370       else if (unformat (input, "traffic-class"))
8371         traffic_class = 1;
8372       else if (unformat (input, "flow-label"))
8373         flow_label = 1;
8374       else if (unformat (input, "src"))
8375         src_address = 1;
8376       else if (unformat (input, "dst"))
8377         dst_address = 1;
8378       else if (unformat (input, "proto"))
8379         protocol = 1;
8380
8381 #define _(a) else if (unformat (input, #a)) a=1;
8382       foreach_ip6_proto_field
8383 #undef _
8384         else
8385         break;
8386     }
8387
8388 #define _(a) found_something += a;
8389   foreach_ip6_proto_field;
8390 #undef _
8391
8392   if (found_something == 0)
8393     return 0;
8394
8395   vec_validate (mask, sizeof (*ip) - 1);
8396
8397   ip = (ip6_header_t *) mask;
8398
8399 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8400   foreach_ip6_proto_field;
8401 #undef _
8402
8403   ip_version_traffic_class_and_flow_label = 0;
8404
8405   if (version)
8406     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8407
8408   if (traffic_class)
8409     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8410
8411   if (flow_label)
8412     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8413
8414   ip->ip_version_traffic_class_and_flow_label =
8415     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8416
8417   *maskp = mask;
8418   return 1;
8419 }
8420
8421 uword
8422 unformat_l3_mask (unformat_input_t * input, va_list * args)
8423 {
8424   u8 **maskp = va_arg (*args, u8 **);
8425
8426   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8427     {
8428       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8429         return 1;
8430       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8431         return 1;
8432       else
8433         break;
8434     }
8435   return 0;
8436 }
8437
8438 uword
8439 unformat_l2_mask (unformat_input_t * input, va_list * args)
8440 {
8441   u8 **maskp = va_arg (*args, u8 **);
8442   u8 *mask = 0;
8443   u8 src = 0;
8444   u8 dst = 0;
8445   u8 proto = 0;
8446   u8 tag1 = 0;
8447   u8 tag2 = 0;
8448   u8 ignore_tag1 = 0;
8449   u8 ignore_tag2 = 0;
8450   u8 cos1 = 0;
8451   u8 cos2 = 0;
8452   u8 dot1q = 0;
8453   u8 dot1ad = 0;
8454   int len = 14;
8455
8456   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8457     {
8458       if (unformat (input, "src"))
8459         src = 1;
8460       else if (unformat (input, "dst"))
8461         dst = 1;
8462       else if (unformat (input, "proto"))
8463         proto = 1;
8464       else if (unformat (input, "tag1"))
8465         tag1 = 1;
8466       else if (unformat (input, "tag2"))
8467         tag2 = 1;
8468       else if (unformat (input, "ignore-tag1"))
8469         ignore_tag1 = 1;
8470       else if (unformat (input, "ignore-tag2"))
8471         ignore_tag2 = 1;
8472       else if (unformat (input, "cos1"))
8473         cos1 = 1;
8474       else if (unformat (input, "cos2"))
8475         cos2 = 1;
8476       else if (unformat (input, "dot1q"))
8477         dot1q = 1;
8478       else if (unformat (input, "dot1ad"))
8479         dot1ad = 1;
8480       else
8481         break;
8482     }
8483   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8484        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8485     return 0;
8486
8487   if (tag1 || ignore_tag1 || cos1 || dot1q)
8488     len = 18;
8489   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8490     len = 22;
8491
8492   vec_validate (mask, len - 1);
8493
8494   if (dst)
8495     memset (mask, 0xff, 6);
8496
8497   if (src)
8498     memset (mask + 6, 0xff, 6);
8499
8500   if (tag2 || dot1ad)
8501     {
8502       /* inner vlan tag */
8503       if (tag2)
8504         {
8505           mask[19] = 0xff;
8506           mask[18] = 0x0f;
8507         }
8508       if (cos2)
8509         mask[18] |= 0xe0;
8510       if (proto)
8511         mask[21] = mask[20] = 0xff;
8512       if (tag1)
8513         {
8514           mask[15] = 0xff;
8515           mask[14] = 0x0f;
8516         }
8517       if (cos1)
8518         mask[14] |= 0xe0;
8519       *maskp = mask;
8520       return 1;
8521     }
8522   if (tag1 | dot1q)
8523     {
8524       if (tag1)
8525         {
8526           mask[15] = 0xff;
8527           mask[14] = 0x0f;
8528         }
8529       if (cos1)
8530         mask[14] |= 0xe0;
8531       if (proto)
8532         mask[16] = mask[17] = 0xff;
8533
8534       *maskp = mask;
8535       return 1;
8536     }
8537   if (cos2)
8538     mask[18] |= 0xe0;
8539   if (cos1)
8540     mask[14] |= 0xe0;
8541   if (proto)
8542     mask[12] = mask[13] = 0xff;
8543
8544   *maskp = mask;
8545   return 1;
8546 }
8547
8548 uword
8549 unformat_classify_mask (unformat_input_t * input, va_list * args)
8550 {
8551   u8 **maskp = va_arg (*args, u8 **);
8552   u32 *skipp = va_arg (*args, u32 *);
8553   u32 *matchp = va_arg (*args, u32 *);
8554   u32 match;
8555   u8 *mask = 0;
8556   u8 *l2 = 0;
8557   u8 *l3 = 0;
8558   u8 *l4 = 0;
8559   int i;
8560
8561   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8562     {
8563       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8564         ;
8565       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8566         ;
8567       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8568         ;
8569       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8570         ;
8571       else
8572         break;
8573     }
8574
8575   if (l4 && !l3)
8576     {
8577       vec_free (mask);
8578       vec_free (l2);
8579       vec_free (l4);
8580       return 0;
8581     }
8582
8583   if (mask || l2 || l3 || l4)
8584     {
8585       if (l2 || l3 || l4)
8586         {
8587           /* "With a free Ethernet header in every package" */
8588           if (l2 == 0)
8589             vec_validate (l2, 13);
8590           mask = l2;
8591           if (vec_len (l3))
8592             {
8593               vec_append (mask, l3);
8594               vec_free (l3);
8595             }
8596           if (vec_len (l4))
8597             {
8598               vec_append (mask, l4);
8599               vec_free (l4);
8600             }
8601         }
8602
8603       /* Scan forward looking for the first significant mask octet */
8604       for (i = 0; i < vec_len (mask); i++)
8605         if (mask[i])
8606           break;
8607
8608       /* compute (skip, match) params */
8609       *skipp = i / sizeof (u32x4);
8610       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8611
8612       /* Pad mask to an even multiple of the vector size */
8613       while (vec_len (mask) % sizeof (u32x4))
8614         vec_add1 (mask, 0);
8615
8616       match = vec_len (mask) / sizeof (u32x4);
8617
8618       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8619         {
8620           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8621           if (*tmp || *(tmp + 1))
8622             break;
8623           match--;
8624         }
8625       if (match == 0)
8626         clib_warning ("BUG: match 0");
8627
8628       _vec_len (mask) = match * sizeof (u32x4);
8629
8630       *matchp = match;
8631       *maskp = mask;
8632
8633       return 1;
8634     }
8635
8636   return 0;
8637 }
8638
8639 #define foreach_l2_next                         \
8640 _(drop, DROP)                                   \
8641 _(ethernet, ETHERNET_INPUT)                     \
8642 _(ip4, IP4_INPUT)                               \
8643 _(ip6, IP6_INPUT)
8644
8645 uword
8646 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8647 {
8648   u32 *miss_next_indexp = va_arg (*args, u32 *);
8649   u32 next_index = 0;
8650   u32 tmp;
8651
8652 #define _(n,N) \
8653   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8654   foreach_l2_next;
8655 #undef _
8656
8657   if (unformat (input, "%d", &tmp))
8658     {
8659       next_index = tmp;
8660       goto out;
8661     }
8662
8663   return 0;
8664
8665 out:
8666   *miss_next_indexp = next_index;
8667   return 1;
8668 }
8669
8670 #define foreach_ip_next                         \
8671 _(drop, DROP)                                   \
8672 _(local, LOCAL)                                 \
8673 _(rewrite, REWRITE)
8674
8675 uword
8676 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8677 {
8678   u32 *miss_next_indexp = va_arg (*args, u32 *);
8679   u32 next_index = 0;
8680   u32 tmp;
8681
8682 #define _(n,N) \
8683   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8684   foreach_ip_next;
8685 #undef _
8686
8687   if (unformat (input, "%d", &tmp))
8688     {
8689       next_index = tmp;
8690       goto out;
8691     }
8692
8693   return 0;
8694
8695 out:
8696   *miss_next_indexp = next_index;
8697   return 1;
8698 }
8699
8700 #define foreach_acl_next                        \
8701 _(deny, DENY)
8702
8703 uword
8704 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8705 {
8706   u32 *miss_next_indexp = va_arg (*args, u32 *);
8707   u32 next_index = 0;
8708   u32 tmp;
8709
8710 #define _(n,N) \
8711   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8712   foreach_acl_next;
8713 #undef _
8714
8715   if (unformat (input, "permit"))
8716     {
8717       next_index = ~0;
8718       goto out;
8719     }
8720   else if (unformat (input, "%d", &tmp))
8721     {
8722       next_index = tmp;
8723       goto out;
8724     }
8725
8726   return 0;
8727
8728 out:
8729   *miss_next_indexp = next_index;
8730   return 1;
8731 }
8732
8733 uword
8734 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8735 {
8736   u32 *r = va_arg (*args, u32 *);
8737
8738   if (unformat (input, "conform-color"))
8739     *r = POLICE_CONFORM;
8740   else if (unformat (input, "exceed-color"))
8741     *r = POLICE_EXCEED;
8742   else
8743     return 0;
8744
8745   return 1;
8746 }
8747
8748 static int
8749 api_classify_add_del_table (vat_main_t * vam)
8750 {
8751   unformat_input_t *i = vam->input;
8752   vl_api_classify_add_del_table_t *mp;
8753
8754   u32 nbuckets = 2;
8755   u32 skip = ~0;
8756   u32 match = ~0;
8757   int is_add = 1;
8758   u32 table_index = ~0;
8759   u32 next_table_index = ~0;
8760   u32 miss_next_index = ~0;
8761   u32 memory_size = 32 << 20;
8762   u8 *mask = 0;
8763   f64 timeout;
8764   u32 current_data_flag = 0;
8765   int current_data_offset = 0;
8766
8767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8768     {
8769       if (unformat (i, "del"))
8770         is_add = 0;
8771       else if (unformat (i, "buckets %d", &nbuckets))
8772         ;
8773       else if (unformat (i, "memory_size %d", &memory_size))
8774         ;
8775       else if (unformat (i, "skip %d", &skip))
8776         ;
8777       else if (unformat (i, "match %d", &match))
8778         ;
8779       else if (unformat (i, "table %d", &table_index))
8780         ;
8781       else if (unformat (i, "mask %U", unformat_classify_mask,
8782                          &mask, &skip, &match))
8783         ;
8784       else if (unformat (i, "next-table %d", &next_table_index))
8785         ;
8786       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8787                          &miss_next_index))
8788         ;
8789       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8790                          &miss_next_index))
8791         ;
8792       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8793                          &miss_next_index))
8794         ;
8795       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8796         ;
8797       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8798         ;
8799       else
8800         break;
8801     }
8802
8803   if (is_add && mask == 0)
8804     {
8805       errmsg ("Mask required\n");
8806       return -99;
8807     }
8808
8809   if (is_add && skip == ~0)
8810     {
8811       errmsg ("skip count required\n");
8812       return -99;
8813     }
8814
8815   if (is_add && match == ~0)
8816     {
8817       errmsg ("match count required\n");
8818       return -99;
8819     }
8820
8821   if (!is_add && table_index == ~0)
8822     {
8823       errmsg ("table index required for delete\n");
8824       return -99;
8825     }
8826
8827   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8828
8829   mp->is_add = is_add;
8830   mp->table_index = ntohl (table_index);
8831   mp->nbuckets = ntohl (nbuckets);
8832   mp->memory_size = ntohl (memory_size);
8833   mp->skip_n_vectors = ntohl (skip);
8834   mp->match_n_vectors = ntohl (match);
8835   mp->next_table_index = ntohl (next_table_index);
8836   mp->miss_next_index = ntohl (miss_next_index);
8837   mp->current_data_flag = ntohl (current_data_flag);
8838   mp->current_data_offset = ntohl (current_data_offset);
8839   clib_memcpy (mp->mask, mask, vec_len (mask));
8840
8841   vec_free (mask);
8842
8843   S;
8844   W;
8845   /* NOTREACHED */
8846 }
8847
8848 uword
8849 unformat_l4_match (unformat_input_t * input, va_list * args)
8850 {
8851   u8 **matchp = va_arg (*args, u8 **);
8852
8853   u8 *proto_header = 0;
8854   int src_port = 0;
8855   int dst_port = 0;
8856
8857   tcpudp_header_t h;
8858
8859   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8860     {
8861       if (unformat (input, "src_port %d", &src_port))
8862         ;
8863       else if (unformat (input, "dst_port %d", &dst_port))
8864         ;
8865       else
8866         return 0;
8867     }
8868
8869   h.src_port = clib_host_to_net_u16 (src_port);
8870   h.dst_port = clib_host_to_net_u16 (dst_port);
8871   vec_validate (proto_header, sizeof (h) - 1);
8872   memcpy (proto_header, &h, sizeof (h));
8873
8874   *matchp = proto_header;
8875
8876   return 1;
8877 }
8878
8879 uword
8880 unformat_ip4_match (unformat_input_t * input, va_list * args)
8881 {
8882   u8 **matchp = va_arg (*args, u8 **);
8883   u8 *match = 0;
8884   ip4_header_t *ip;
8885   int version = 0;
8886   u32 version_val;
8887   int hdr_length = 0;
8888   u32 hdr_length_val;
8889   int src = 0, dst = 0;
8890   ip4_address_t src_val, dst_val;
8891   int proto = 0;
8892   u32 proto_val;
8893   int tos = 0;
8894   u32 tos_val;
8895   int length = 0;
8896   u32 length_val;
8897   int fragment_id = 0;
8898   u32 fragment_id_val;
8899   int ttl = 0;
8900   int ttl_val;
8901   int checksum = 0;
8902   u32 checksum_val;
8903
8904   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8905     {
8906       if (unformat (input, "version %d", &version_val))
8907         version = 1;
8908       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8909         hdr_length = 1;
8910       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8911         src = 1;
8912       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8913         dst = 1;
8914       else if (unformat (input, "proto %d", &proto_val))
8915         proto = 1;
8916       else if (unformat (input, "tos %d", &tos_val))
8917         tos = 1;
8918       else if (unformat (input, "length %d", &length_val))
8919         length = 1;
8920       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8921         fragment_id = 1;
8922       else if (unformat (input, "ttl %d", &ttl_val))
8923         ttl = 1;
8924       else if (unformat (input, "checksum %d", &checksum_val))
8925         checksum = 1;
8926       else
8927         break;
8928     }
8929
8930   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8931       + ttl + checksum == 0)
8932     return 0;
8933
8934   /*
8935    * Aligned because we use the real comparison functions
8936    */
8937   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8938
8939   ip = (ip4_header_t *) match;
8940
8941   /* These are realistically matched in practice */
8942   if (src)
8943     ip->src_address.as_u32 = src_val.as_u32;
8944
8945   if (dst)
8946     ip->dst_address.as_u32 = dst_val.as_u32;
8947
8948   if (proto)
8949     ip->protocol = proto_val;
8950
8951
8952   /* These are not, but they're included for completeness */
8953   if (version)
8954     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8955
8956   if (hdr_length)
8957     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8958
8959   if (tos)
8960     ip->tos = tos_val;
8961
8962   if (length)
8963     ip->length = clib_host_to_net_u16 (length_val);
8964
8965   if (ttl)
8966     ip->ttl = ttl_val;
8967
8968   if (checksum)
8969     ip->checksum = clib_host_to_net_u16 (checksum_val);
8970
8971   *matchp = match;
8972   return 1;
8973 }
8974
8975 uword
8976 unformat_ip6_match (unformat_input_t * input, va_list * args)
8977 {
8978   u8 **matchp = va_arg (*args, u8 **);
8979   u8 *match = 0;
8980   ip6_header_t *ip;
8981   int version = 0;
8982   u32 version_val;
8983   u8 traffic_class = 0;
8984   u32 traffic_class_val = 0;
8985   u8 flow_label = 0;
8986   u8 flow_label_val;
8987   int src = 0, dst = 0;
8988   ip6_address_t src_val, dst_val;
8989   int proto = 0;
8990   u32 proto_val;
8991   int payload_length = 0;
8992   u32 payload_length_val;
8993   int hop_limit = 0;
8994   int hop_limit_val;
8995   u32 ip_version_traffic_class_and_flow_label;
8996
8997   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8998     {
8999       if (unformat (input, "version %d", &version_val))
9000         version = 1;
9001       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9002         traffic_class = 1;
9003       else if (unformat (input, "flow_label %d", &flow_label_val))
9004         flow_label = 1;
9005       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9006         src = 1;
9007       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9008         dst = 1;
9009       else if (unformat (input, "proto %d", &proto_val))
9010         proto = 1;
9011       else if (unformat (input, "payload_length %d", &payload_length_val))
9012         payload_length = 1;
9013       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9014         hop_limit = 1;
9015       else
9016         break;
9017     }
9018
9019   if (version + traffic_class + flow_label + src + dst + proto +
9020       payload_length + hop_limit == 0)
9021     return 0;
9022
9023   /*
9024    * Aligned because we use the real comparison functions
9025    */
9026   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9027
9028   ip = (ip6_header_t *) match;
9029
9030   if (src)
9031     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9032
9033   if (dst)
9034     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9035
9036   if (proto)
9037     ip->protocol = proto_val;
9038
9039   ip_version_traffic_class_and_flow_label = 0;
9040
9041   if (version)
9042     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9043
9044   if (traffic_class)
9045     ip_version_traffic_class_and_flow_label |=
9046       (traffic_class_val & 0xFF) << 20;
9047
9048   if (flow_label)
9049     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9050
9051   ip->ip_version_traffic_class_and_flow_label =
9052     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9053
9054   if (payload_length)
9055     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9056
9057   if (hop_limit)
9058     ip->hop_limit = hop_limit_val;
9059
9060   *matchp = match;
9061   return 1;
9062 }
9063
9064 uword
9065 unformat_l3_match (unformat_input_t * input, va_list * args)
9066 {
9067   u8 **matchp = va_arg (*args, u8 **);
9068
9069   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9070     {
9071       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9072         return 1;
9073       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9074         return 1;
9075       else
9076         break;
9077     }
9078   return 0;
9079 }
9080
9081 uword
9082 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9083 {
9084   u8 *tagp = va_arg (*args, u8 *);
9085   u32 tag;
9086
9087   if (unformat (input, "%d", &tag))
9088     {
9089       tagp[0] = (tag >> 8) & 0x0F;
9090       tagp[1] = tag & 0xFF;
9091       return 1;
9092     }
9093
9094   return 0;
9095 }
9096
9097 uword
9098 unformat_l2_match (unformat_input_t * input, va_list * args)
9099 {
9100   u8 **matchp = va_arg (*args, u8 **);
9101   u8 *match = 0;
9102   u8 src = 0;
9103   u8 src_val[6];
9104   u8 dst = 0;
9105   u8 dst_val[6];
9106   u8 proto = 0;
9107   u16 proto_val;
9108   u8 tag1 = 0;
9109   u8 tag1_val[2];
9110   u8 tag2 = 0;
9111   u8 tag2_val[2];
9112   int len = 14;
9113   u8 ignore_tag1 = 0;
9114   u8 ignore_tag2 = 0;
9115   u8 cos1 = 0;
9116   u8 cos2 = 0;
9117   u32 cos1_val = 0;
9118   u32 cos2_val = 0;
9119
9120   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9121     {
9122       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9123         src = 1;
9124       else
9125         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9126         dst = 1;
9127       else if (unformat (input, "proto %U",
9128                          unformat_ethernet_type_host_byte_order, &proto_val))
9129         proto = 1;
9130       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9131         tag1 = 1;
9132       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9133         tag2 = 1;
9134       else if (unformat (input, "ignore-tag1"))
9135         ignore_tag1 = 1;
9136       else if (unformat (input, "ignore-tag2"))
9137         ignore_tag2 = 1;
9138       else if (unformat (input, "cos1 %d", &cos1_val))
9139         cos1 = 1;
9140       else if (unformat (input, "cos2 %d", &cos2_val))
9141         cos2 = 1;
9142       else
9143         break;
9144     }
9145   if ((src + dst + proto + tag1 + tag2 +
9146        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9147     return 0;
9148
9149   if (tag1 || ignore_tag1 || cos1)
9150     len = 18;
9151   if (tag2 || ignore_tag2 || cos2)
9152     len = 22;
9153
9154   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9155
9156   if (dst)
9157     clib_memcpy (match, dst_val, 6);
9158
9159   if (src)
9160     clib_memcpy (match + 6, src_val, 6);
9161
9162   if (tag2)
9163     {
9164       /* inner vlan tag */
9165       match[19] = tag2_val[1];
9166       match[18] = tag2_val[0];
9167       if (cos2)
9168         match[18] |= (cos2_val & 0x7) << 5;
9169       if (proto)
9170         {
9171           match[21] = proto_val & 0xff;
9172           match[20] = proto_val >> 8;
9173         }
9174       if (tag1)
9175         {
9176           match[15] = tag1_val[1];
9177           match[14] = tag1_val[0];
9178         }
9179       if (cos1)
9180         match[14] |= (cos1_val & 0x7) << 5;
9181       *matchp = match;
9182       return 1;
9183     }
9184   if (tag1)
9185     {
9186       match[15] = tag1_val[1];
9187       match[14] = tag1_val[0];
9188       if (proto)
9189         {
9190           match[17] = proto_val & 0xff;
9191           match[16] = proto_val >> 8;
9192         }
9193       if (cos1)
9194         match[14] |= (cos1_val & 0x7) << 5;
9195
9196       *matchp = match;
9197       return 1;
9198     }
9199   if (cos2)
9200     match[18] |= (cos2_val & 0x7) << 5;
9201   if (cos1)
9202     match[14] |= (cos1_val & 0x7) << 5;
9203   if (proto)
9204     {
9205       match[13] = proto_val & 0xff;
9206       match[12] = proto_val >> 8;
9207     }
9208
9209   *matchp = match;
9210   return 1;
9211 }
9212
9213
9214 uword
9215 unformat_classify_match (unformat_input_t * input, va_list * args)
9216 {
9217   u8 **matchp = va_arg (*args, u8 **);
9218   u32 skip_n_vectors = va_arg (*args, u32);
9219   u32 match_n_vectors = va_arg (*args, u32);
9220
9221   u8 *match = 0;
9222   u8 *l2 = 0;
9223   u8 *l3 = 0;
9224   u8 *l4 = 0;
9225
9226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9227     {
9228       if (unformat (input, "hex %U", unformat_hex_string, &match))
9229         ;
9230       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9231         ;
9232       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9233         ;
9234       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9235         ;
9236       else
9237         break;
9238     }
9239
9240   if (l4 && !l3)
9241     {
9242       vec_free (match);
9243       vec_free (l2);
9244       vec_free (l4);
9245       return 0;
9246     }
9247
9248   if (match || l2 || l3 || l4)
9249     {
9250       if (l2 || l3 || l4)
9251         {
9252           /* "Win a free Ethernet header in every packet" */
9253           if (l2 == 0)
9254             vec_validate_aligned (l2, 13, sizeof (u32x4));
9255           match = l2;
9256           if (vec_len (l3))
9257             {
9258               vec_append_aligned (match, l3, sizeof (u32x4));
9259               vec_free (l3);
9260             }
9261           if (vec_len (l4))
9262             {
9263               vec_append_aligned (match, l4, sizeof (u32x4));
9264               vec_free (l4);
9265             }
9266         }
9267
9268       /* Make sure the vector is big enough even if key is all 0's */
9269       vec_validate_aligned
9270         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9271          sizeof (u32x4));
9272
9273       /* Set size, include skipped vectors */
9274       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9275
9276       *matchp = match;
9277
9278       return 1;
9279     }
9280
9281   return 0;
9282 }
9283
9284 static int
9285 api_classify_add_del_session (vat_main_t * vam)
9286 {
9287   unformat_input_t *i = vam->input;
9288   vl_api_classify_add_del_session_t *mp;
9289   int is_add = 1;
9290   u32 table_index = ~0;
9291   u32 hit_next_index = ~0;
9292   u32 opaque_index = ~0;
9293   u8 *match = 0;
9294   i32 advance = 0;
9295   f64 timeout;
9296   u32 skip_n_vectors = 0;
9297   u32 match_n_vectors = 0;
9298   u32 action = 0;
9299   u32 metadata = 0;
9300
9301   /*
9302    * Warning: you have to supply skip_n and match_n
9303    * because the API client cant simply look at the classify
9304    * table object.
9305    */
9306
9307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9308     {
9309       if (unformat (i, "del"))
9310         is_add = 0;
9311       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9312                          &hit_next_index))
9313         ;
9314       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9315                          &hit_next_index))
9316         ;
9317       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9318                          &hit_next_index))
9319         ;
9320       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9321         ;
9322       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9323         ;
9324       else if (unformat (i, "opaque-index %d", &opaque_index))
9325         ;
9326       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9327         ;
9328       else if (unformat (i, "match_n %d", &match_n_vectors))
9329         ;
9330       else if (unformat (i, "match %U", unformat_classify_match,
9331                          &match, skip_n_vectors, match_n_vectors))
9332         ;
9333       else if (unformat (i, "advance %d", &advance))
9334         ;
9335       else if (unformat (i, "table-index %d", &table_index))
9336         ;
9337       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9338         action = 1;
9339       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9340         action = 2;
9341       else if (unformat (i, "action %d", &action))
9342         ;
9343       else if (unformat (i, "metadata %d", &metadata))
9344         ;
9345       else
9346         break;
9347     }
9348
9349   if (table_index == ~0)
9350     {
9351       errmsg ("Table index required\n");
9352       return -99;
9353     }
9354
9355   if (is_add && match == 0)
9356     {
9357       errmsg ("Match value required\n");
9358       return -99;
9359     }
9360
9361   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9362
9363   mp->is_add = is_add;
9364   mp->table_index = ntohl (table_index);
9365   mp->hit_next_index = ntohl (hit_next_index);
9366   mp->opaque_index = ntohl (opaque_index);
9367   mp->advance = ntohl (advance);
9368   mp->action = action;
9369   mp->metadata = ntohl (metadata);
9370   clib_memcpy (mp->match, match, vec_len (match));
9371   vec_free (match);
9372
9373   S;
9374   W;
9375   /* NOTREACHED */
9376 }
9377
9378 static int
9379 api_classify_set_interface_ip_table (vat_main_t * vam)
9380 {
9381   unformat_input_t *i = vam->input;
9382   vl_api_classify_set_interface_ip_table_t *mp;
9383   f64 timeout;
9384   u32 sw_if_index;
9385   int sw_if_index_set;
9386   u32 table_index = ~0;
9387   u8 is_ipv6 = 0;
9388
9389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9390     {
9391       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9392         sw_if_index_set = 1;
9393       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9394         sw_if_index_set = 1;
9395       else if (unformat (i, "table %d", &table_index))
9396         ;
9397       else
9398         {
9399           clib_warning ("parse error '%U'", format_unformat_error, i);
9400           return -99;
9401         }
9402     }
9403
9404   if (sw_if_index_set == 0)
9405     {
9406       errmsg ("missing interface name or sw_if_index\n");
9407       return -99;
9408     }
9409
9410
9411   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9412
9413   mp->sw_if_index = ntohl (sw_if_index);
9414   mp->table_index = ntohl (table_index);
9415   mp->is_ipv6 = is_ipv6;
9416
9417   S;
9418   W;
9419   /* NOTREACHED */
9420   return 0;
9421 }
9422
9423 static int
9424 api_classify_set_interface_l2_tables (vat_main_t * vam)
9425 {
9426   unformat_input_t *i = vam->input;
9427   vl_api_classify_set_interface_l2_tables_t *mp;
9428   f64 timeout;
9429   u32 sw_if_index;
9430   int sw_if_index_set;
9431   u32 ip4_table_index = ~0;
9432   u32 ip6_table_index = ~0;
9433   u32 other_table_index = ~0;
9434   u32 is_input = 1;
9435
9436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9437     {
9438       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9439         sw_if_index_set = 1;
9440       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9441         sw_if_index_set = 1;
9442       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9443         ;
9444       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9445         ;
9446       else if (unformat (i, "other-table %d", &other_table_index))
9447         ;
9448       else if (unformat (i, "is-input %d", &is_input))
9449         ;
9450       else
9451         {
9452           clib_warning ("parse error '%U'", format_unformat_error, i);
9453           return -99;
9454         }
9455     }
9456
9457   if (sw_if_index_set == 0)
9458     {
9459       errmsg ("missing interface name or sw_if_index\n");
9460       return -99;
9461     }
9462
9463
9464   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9465
9466   mp->sw_if_index = ntohl (sw_if_index);
9467   mp->ip4_table_index = ntohl (ip4_table_index);
9468   mp->ip6_table_index = ntohl (ip6_table_index);
9469   mp->other_table_index = ntohl (other_table_index);
9470   mp->is_input = (u8) is_input;
9471
9472   S;
9473   W;
9474   /* NOTREACHED */
9475   return 0;
9476 }
9477
9478 static int
9479 api_set_ipfix_exporter (vat_main_t * vam)
9480 {
9481   unformat_input_t *i = vam->input;
9482   vl_api_set_ipfix_exporter_t *mp;
9483   ip4_address_t collector_address;
9484   u8 collector_address_set = 0;
9485   u32 collector_port = ~0;
9486   ip4_address_t src_address;
9487   u8 src_address_set = 0;
9488   u32 vrf_id = ~0;
9489   u32 path_mtu = ~0;
9490   u32 template_interval = ~0;
9491   u8 udp_checksum = 0;
9492   f64 timeout;
9493
9494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9495     {
9496       if (unformat (i, "collector_address %U", unformat_ip4_address,
9497                     &collector_address))
9498         collector_address_set = 1;
9499       else if (unformat (i, "collector_port %d", &collector_port))
9500         ;
9501       else if (unformat (i, "src_address %U", unformat_ip4_address,
9502                          &src_address))
9503         src_address_set = 1;
9504       else if (unformat (i, "vrf_id %d", &vrf_id))
9505         ;
9506       else if (unformat (i, "path_mtu %d", &path_mtu))
9507         ;
9508       else if (unformat (i, "template_interval %d", &template_interval))
9509         ;
9510       else if (unformat (i, "udp_checksum"))
9511         udp_checksum = 1;
9512       else
9513         break;
9514     }
9515
9516   if (collector_address_set == 0)
9517     {
9518       errmsg ("collector_address required\n");
9519       return -99;
9520     }
9521
9522   if (src_address_set == 0)
9523     {
9524       errmsg ("src_address required\n");
9525       return -99;
9526     }
9527
9528   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9529
9530   memcpy (mp->collector_address, collector_address.data,
9531           sizeof (collector_address.data));
9532   mp->collector_port = htons ((u16) collector_port);
9533   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9534   mp->vrf_id = htonl (vrf_id);
9535   mp->path_mtu = htonl (path_mtu);
9536   mp->template_interval = htonl (template_interval);
9537   mp->udp_checksum = udp_checksum;
9538
9539   S;
9540   W;
9541   /* NOTREACHED */
9542 }
9543
9544 static int
9545 api_set_ipfix_classify_stream (vat_main_t * vam)
9546 {
9547   unformat_input_t *i = vam->input;
9548   vl_api_set_ipfix_classify_stream_t *mp;
9549   u32 domain_id = 0;
9550   u32 src_port = UDP_DST_PORT_ipfix;
9551   f64 timeout;
9552
9553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9554     {
9555       if (unformat (i, "domain %d", &domain_id))
9556         ;
9557       else if (unformat (i, "src_port %d", &src_port))
9558         ;
9559       else
9560         {
9561           errmsg ("unknown input `%U'", format_unformat_error, i);
9562           return -99;
9563         }
9564     }
9565
9566   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9567
9568   mp->domain_id = htonl (domain_id);
9569   mp->src_port = htons ((u16) src_port);
9570
9571   S;
9572   W;
9573   /* NOTREACHED */
9574 }
9575
9576 static int
9577 api_ipfix_classify_table_add_del (vat_main_t * vam)
9578 {
9579   unformat_input_t *i = vam->input;
9580   vl_api_ipfix_classify_table_add_del_t *mp;
9581   int is_add = -1;
9582   u32 classify_table_index = ~0;
9583   u8 ip_version = 0;
9584   u8 transport_protocol = 255;
9585   f64 timeout;
9586
9587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9588     {
9589       if (unformat (i, "add"))
9590         is_add = 1;
9591       else if (unformat (i, "del"))
9592         is_add = 0;
9593       else if (unformat (i, "table %d", &classify_table_index))
9594         ;
9595       else if (unformat (i, "ip4"))
9596         ip_version = 4;
9597       else if (unformat (i, "ip6"))
9598         ip_version = 6;
9599       else if (unformat (i, "tcp"))
9600         transport_protocol = 6;
9601       else if (unformat (i, "udp"))
9602         transport_protocol = 17;
9603       else
9604         {
9605           errmsg ("unknown input `%U'", format_unformat_error, i);
9606           return -99;
9607         }
9608     }
9609
9610   if (is_add == -1)
9611     {
9612       errmsg ("expecting: add|del");
9613       return -99;
9614     }
9615   if (classify_table_index == ~0)
9616     {
9617       errmsg ("classifier table not specified");
9618       return -99;
9619     }
9620   if (ip_version == 0)
9621     {
9622       errmsg ("IP version not specified");
9623       return -99;
9624     }
9625
9626   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9627
9628   mp->is_add = is_add;
9629   mp->table_id = htonl (classify_table_index);
9630   mp->ip_version = ip_version;
9631   mp->transport_protocol = transport_protocol;
9632
9633   S;
9634   W;
9635   /* NOTREACHED */
9636 }
9637
9638 static int
9639 api_get_node_index (vat_main_t * vam)
9640 {
9641   unformat_input_t *i = vam->input;
9642   vl_api_get_node_index_t *mp;
9643   f64 timeout;
9644   u8 *name = 0;
9645
9646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9647     {
9648       if (unformat (i, "node %s", &name))
9649         ;
9650       else
9651         break;
9652     }
9653   if (name == 0)
9654     {
9655       errmsg ("node name required\n");
9656       return -99;
9657     }
9658   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9659     {
9660       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9661       return -99;
9662     }
9663
9664   M (GET_NODE_INDEX, get_node_index);
9665   clib_memcpy (mp->node_name, name, vec_len (name));
9666   vec_free (name);
9667
9668   S;
9669   W;
9670   /* NOTREACHED */
9671   return 0;
9672 }
9673
9674 static int
9675 api_get_next_index (vat_main_t * vam)
9676 {
9677   unformat_input_t *i = vam->input;
9678   vl_api_get_next_index_t *mp;
9679   f64 timeout;
9680   u8 *node_name = 0, *next_node_name = 0;
9681
9682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9683     {
9684       if (unformat (i, "node-name %s", &node_name))
9685         ;
9686       else if (unformat (i, "next-node-name %s", &next_node_name))
9687         break;
9688     }
9689
9690   if (node_name == 0)
9691     {
9692       errmsg ("node name required\n");
9693       return -99;
9694     }
9695   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9696     {
9697       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9698       return -99;
9699     }
9700
9701   if (next_node_name == 0)
9702     {
9703       errmsg ("next node name required\n");
9704       return -99;
9705     }
9706   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9707     {
9708       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9709       return -99;
9710     }
9711
9712   M (GET_NEXT_INDEX, get_next_index);
9713   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9714   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9715   vec_free (node_name);
9716   vec_free (next_node_name);
9717
9718   S;
9719   W;
9720   /* NOTREACHED */
9721   return 0;
9722 }
9723
9724 static int
9725 api_add_node_next (vat_main_t * vam)
9726 {
9727   unformat_input_t *i = vam->input;
9728   vl_api_add_node_next_t *mp;
9729   f64 timeout;
9730   u8 *name = 0;
9731   u8 *next = 0;
9732
9733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9734     {
9735       if (unformat (i, "node %s", &name))
9736         ;
9737       else if (unformat (i, "next %s", &next))
9738         ;
9739       else
9740         break;
9741     }
9742   if (name == 0)
9743     {
9744       errmsg ("node name required\n");
9745       return -99;
9746     }
9747   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9748     {
9749       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9750       return -99;
9751     }
9752   if (next == 0)
9753     {
9754       errmsg ("next node required\n");
9755       return -99;
9756     }
9757   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9758     {
9759       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9760       return -99;
9761     }
9762
9763   M (ADD_NODE_NEXT, add_node_next);
9764   clib_memcpy (mp->node_name, name, vec_len (name));
9765   clib_memcpy (mp->next_name, next, vec_len (next));
9766   vec_free (name);
9767   vec_free (next);
9768
9769   S;
9770   W;
9771   /* NOTREACHED */
9772   return 0;
9773 }
9774
9775 static int
9776 api_l2tpv3_create_tunnel (vat_main_t * vam)
9777 {
9778   unformat_input_t *i = vam->input;
9779   ip6_address_t client_address, our_address;
9780   int client_address_set = 0;
9781   int our_address_set = 0;
9782   u32 local_session_id = 0;
9783   u32 remote_session_id = 0;
9784   u64 local_cookie = 0;
9785   u64 remote_cookie = 0;
9786   u8 l2_sublayer_present = 0;
9787   vl_api_l2tpv3_create_tunnel_t *mp;
9788   f64 timeout;
9789
9790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9791     {
9792       if (unformat (i, "client_address %U", unformat_ip6_address,
9793                     &client_address))
9794         client_address_set = 1;
9795       else if (unformat (i, "our_address %U", unformat_ip6_address,
9796                          &our_address))
9797         our_address_set = 1;
9798       else if (unformat (i, "local_session_id %d", &local_session_id))
9799         ;
9800       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9801         ;
9802       else if (unformat (i, "local_cookie %lld", &local_cookie))
9803         ;
9804       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9805         ;
9806       else if (unformat (i, "l2-sublayer-present"))
9807         l2_sublayer_present = 1;
9808       else
9809         break;
9810     }
9811
9812   if (client_address_set == 0)
9813     {
9814       errmsg ("client_address required\n");
9815       return -99;
9816     }
9817
9818   if (our_address_set == 0)
9819     {
9820       errmsg ("our_address required\n");
9821       return -99;
9822     }
9823
9824   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9825
9826   clib_memcpy (mp->client_address, client_address.as_u8,
9827                sizeof (mp->client_address));
9828
9829   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9830
9831   mp->local_session_id = ntohl (local_session_id);
9832   mp->remote_session_id = ntohl (remote_session_id);
9833   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9834   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9835   mp->l2_sublayer_present = l2_sublayer_present;
9836   mp->is_ipv6 = 1;
9837
9838   S;
9839   W;
9840   /* NOTREACHED */
9841   return 0;
9842 }
9843
9844 static int
9845 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9846 {
9847   unformat_input_t *i = vam->input;
9848   u32 sw_if_index;
9849   u8 sw_if_index_set = 0;
9850   u64 new_local_cookie = 0;
9851   u64 new_remote_cookie = 0;
9852   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9853   f64 timeout;
9854
9855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9856     {
9857       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9858         sw_if_index_set = 1;
9859       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9860         sw_if_index_set = 1;
9861       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9862         ;
9863       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9864         ;
9865       else
9866         break;
9867     }
9868
9869   if (sw_if_index_set == 0)
9870     {
9871       errmsg ("missing interface name or sw_if_index\n");
9872       return -99;
9873     }
9874
9875   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9876
9877   mp->sw_if_index = ntohl (sw_if_index);
9878   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9879   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9880
9881   S;
9882   W;
9883   /* NOTREACHED */
9884   return 0;
9885 }
9886
9887 static int
9888 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9889 {
9890   unformat_input_t *i = vam->input;
9891   vl_api_l2tpv3_interface_enable_disable_t *mp;
9892   f64 timeout;
9893   u32 sw_if_index;
9894   u8 sw_if_index_set = 0;
9895   u8 enable_disable = 1;
9896
9897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9898     {
9899       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9900         sw_if_index_set = 1;
9901       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9902         sw_if_index_set = 1;
9903       else if (unformat (i, "enable"))
9904         enable_disable = 1;
9905       else if (unformat (i, "disable"))
9906         enable_disable = 0;
9907       else
9908         break;
9909     }
9910
9911   if (sw_if_index_set == 0)
9912     {
9913       errmsg ("missing interface name or sw_if_index\n");
9914       return -99;
9915     }
9916
9917   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9918
9919   mp->sw_if_index = ntohl (sw_if_index);
9920   mp->enable_disable = enable_disable;
9921
9922   S;
9923   W;
9924   /* NOTREACHED */
9925   return 0;
9926 }
9927
9928 static int
9929 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9930 {
9931   unformat_input_t *i = vam->input;
9932   vl_api_l2tpv3_set_lookup_key_t *mp;
9933   f64 timeout;
9934   u8 key = ~0;
9935
9936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9937     {
9938       if (unformat (i, "lookup_v6_src"))
9939         key = L2T_LOOKUP_SRC_ADDRESS;
9940       else if (unformat (i, "lookup_v6_dst"))
9941         key = L2T_LOOKUP_DST_ADDRESS;
9942       else if (unformat (i, "lookup_session_id"))
9943         key = L2T_LOOKUP_SESSION_ID;
9944       else
9945         break;
9946     }
9947
9948   if (key == (u8) ~ 0)
9949     {
9950       errmsg ("l2tp session lookup key unset\n");
9951       return -99;
9952     }
9953
9954   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9955
9956   mp->key = key;
9957
9958   S;
9959   W;
9960   /* NOTREACHED */
9961   return 0;
9962 }
9963
9964 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9965   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9966 {
9967   vat_main_t *vam = &vat_main;
9968
9969   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9970            format_ip6_address, mp->our_address,
9971            format_ip6_address, mp->client_address,
9972            clib_net_to_host_u32 (mp->sw_if_index));
9973
9974   fformat (vam->ofp,
9975            "   local cookies %016llx %016llx remote cookie %016llx\n",
9976            clib_net_to_host_u64 (mp->local_cookie[0]),
9977            clib_net_to_host_u64 (mp->local_cookie[1]),
9978            clib_net_to_host_u64 (mp->remote_cookie));
9979
9980   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9981            clib_net_to_host_u32 (mp->local_session_id),
9982            clib_net_to_host_u32 (mp->remote_session_id));
9983
9984   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9985            mp->l2_sublayer_present ? "preset" : "absent");
9986
9987 }
9988
9989 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9990   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9991 {
9992   vat_main_t *vam = &vat_main;
9993   vat_json_node_t *node = NULL;
9994   struct in6_addr addr;
9995
9996   if (VAT_JSON_ARRAY != vam->json_tree.type)
9997     {
9998       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9999       vat_json_init_array (&vam->json_tree);
10000     }
10001   node = vat_json_array_add (&vam->json_tree);
10002
10003   vat_json_init_object (node);
10004
10005   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10006   vat_json_object_add_ip6 (node, "our_address", addr);
10007   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10008   vat_json_object_add_ip6 (node, "client_address", addr);
10009
10010   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10011   vat_json_init_array (lc);
10012   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10013   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10014   vat_json_object_add_uint (node, "remote_cookie",
10015                             clib_net_to_host_u64 (mp->remote_cookie));
10016
10017   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10018   vat_json_object_add_uint (node, "local_session_id",
10019                             clib_net_to_host_u32 (mp->local_session_id));
10020   vat_json_object_add_uint (node, "remote_session_id",
10021                             clib_net_to_host_u32 (mp->remote_session_id));
10022   vat_json_object_add_string_copy (node, "l2_sublayer",
10023                                    mp->l2_sublayer_present ? (u8 *) "present"
10024                                    : (u8 *) "absent");
10025 }
10026
10027 static int
10028 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10029 {
10030   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10031   f64 timeout;
10032
10033   /* Get list of l2tpv3-tunnel interfaces */
10034   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10035   S;
10036
10037   /* Use a control ping for synchronization */
10038   {
10039     vl_api_control_ping_t *mp;
10040     M (CONTROL_PING, control_ping);
10041     S;
10042   }
10043   W;
10044 }
10045
10046
10047 static void vl_api_sw_interface_tap_details_t_handler
10048   (vl_api_sw_interface_tap_details_t * mp)
10049 {
10050   vat_main_t *vam = &vat_main;
10051
10052   fformat (vam->ofp, "%-16s %d\n",
10053            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10054 }
10055
10056 static void vl_api_sw_interface_tap_details_t_handler_json
10057   (vl_api_sw_interface_tap_details_t * mp)
10058 {
10059   vat_main_t *vam = &vat_main;
10060   vat_json_node_t *node = NULL;
10061
10062   if (VAT_JSON_ARRAY != vam->json_tree.type)
10063     {
10064       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10065       vat_json_init_array (&vam->json_tree);
10066     }
10067   node = vat_json_array_add (&vam->json_tree);
10068
10069   vat_json_init_object (node);
10070   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10071   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10072 }
10073
10074 static int
10075 api_sw_interface_tap_dump (vat_main_t * vam)
10076 {
10077   vl_api_sw_interface_tap_dump_t *mp;
10078   f64 timeout;
10079
10080   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10081   /* Get list of tap interfaces */
10082   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10083   S;
10084
10085   /* Use a control ping for synchronization */
10086   {
10087     vl_api_control_ping_t *mp;
10088     M (CONTROL_PING, control_ping);
10089     S;
10090   }
10091   W;
10092 }
10093
10094 static uword unformat_vxlan_decap_next
10095   (unformat_input_t * input, va_list * args)
10096 {
10097   u32 *result = va_arg (*args, u32 *);
10098   u32 tmp;
10099
10100   if (unformat (input, "l2"))
10101     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10102   else if (unformat (input, "%d", &tmp))
10103     *result = tmp;
10104   else
10105     return 0;
10106   return 1;
10107 }
10108
10109 static int
10110 api_vxlan_add_del_tunnel (vat_main_t * vam)
10111 {
10112   unformat_input_t *line_input = vam->input;
10113   vl_api_vxlan_add_del_tunnel_t *mp;
10114   f64 timeout;
10115   ip4_address_t src4, dst4;
10116   ip6_address_t src6, dst6;
10117   u8 is_add = 1;
10118   u8 ipv4_set = 0, ipv6_set = 0;
10119   u8 src_set = 0;
10120   u8 dst_set = 0;
10121   u32 encap_vrf_id = 0;
10122   u32 decap_next_index = ~0;
10123   u32 vni = 0;
10124
10125   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10126     {
10127       if (unformat (line_input, "del"))
10128         is_add = 0;
10129       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10130         {
10131           ipv4_set = 1;
10132           src_set = 1;
10133         }
10134       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10135         {
10136           ipv4_set = 1;
10137           dst_set = 1;
10138         }
10139       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
10140         {
10141           ipv6_set = 1;
10142           src_set = 1;
10143         }
10144       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
10145         {
10146           ipv6_set = 1;
10147           dst_set = 1;
10148         }
10149       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10150         ;
10151       else if (unformat (line_input, "decap-next %U",
10152                          unformat_vxlan_decap_next, &decap_next_index))
10153         ;
10154       else if (unformat (line_input, "vni %d", &vni))
10155         ;
10156       else
10157         {
10158           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10159           return -99;
10160         }
10161     }
10162
10163   if (src_set == 0)
10164     {
10165       errmsg ("tunnel src address not specified\n");
10166       return -99;
10167     }
10168   if (dst_set == 0)
10169     {
10170       errmsg ("tunnel dst address not specified\n");
10171       return -99;
10172     }
10173
10174   if (ipv4_set && ipv6_set)
10175     {
10176       errmsg ("both IPv4 and IPv6 addresses specified");
10177       return -99;
10178     }
10179
10180   if ((vni == 0) || (vni >> 24))
10181     {
10182       errmsg ("vni not specified or out of range\n");
10183       return -99;
10184     }
10185
10186   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10187
10188   if (ipv6_set)
10189     {
10190       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
10191       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
10192     }
10193   else
10194     {
10195       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10196       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10197     }
10198   mp->encap_vrf_id = ntohl (encap_vrf_id);
10199   mp->decap_next_index = ntohl (decap_next_index);
10200   mp->vni = ntohl (vni);
10201   mp->is_add = is_add;
10202   mp->is_ipv6 = ipv6_set;
10203
10204   S;
10205   W;
10206   /* NOTREACHED */
10207   return 0;
10208 }
10209
10210 static void vl_api_vxlan_tunnel_details_t_handler
10211   (vl_api_vxlan_tunnel_details_t * mp)
10212 {
10213   vat_main_t *vam = &vat_main;
10214
10215   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
10216            ntohl (mp->sw_if_index),
10217            format_ip46_address, &(mp->src_address[0]),
10218            IP46_TYPE_ANY,
10219            format_ip46_address, &(mp->dst_address[0]),
10220            IP46_TYPE_ANY,
10221            ntohl (mp->encap_vrf_id),
10222            ntohl (mp->decap_next_index), ntohl (mp->vni));
10223 }
10224
10225 static void vl_api_vxlan_tunnel_details_t_handler_json
10226   (vl_api_vxlan_tunnel_details_t * mp)
10227 {
10228   vat_main_t *vam = &vat_main;
10229   vat_json_node_t *node = NULL;
10230   struct in_addr ip4;
10231   struct in6_addr ip6;
10232
10233   if (VAT_JSON_ARRAY != vam->json_tree.type)
10234     {
10235       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10236       vat_json_init_array (&vam->json_tree);
10237     }
10238   node = vat_json_array_add (&vam->json_tree);
10239
10240   vat_json_init_object (node);
10241   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10242   if (mp->is_ipv6)
10243     {
10244       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
10245       vat_json_object_add_ip6 (node, "src_address", ip6);
10246       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
10247       vat_json_object_add_ip6 (node, "dst_address", ip6);
10248     }
10249   else
10250     {
10251       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
10252       vat_json_object_add_ip4 (node, "src_address", ip4);
10253       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
10254       vat_json_object_add_ip4 (node, "dst_address", ip4);
10255     }
10256   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10257   vat_json_object_add_uint (node, "decap_next_index",
10258                             ntohl (mp->decap_next_index));
10259   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10260   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10261 }
10262
10263 static int
10264 api_vxlan_tunnel_dump (vat_main_t * vam)
10265 {
10266   unformat_input_t *i = vam->input;
10267   vl_api_vxlan_tunnel_dump_t *mp;
10268   f64 timeout;
10269   u32 sw_if_index;
10270   u8 sw_if_index_set = 0;
10271
10272   /* Parse args required to build the message */
10273   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10274     {
10275       if (unformat (i, "sw_if_index %d", &sw_if_index))
10276         sw_if_index_set = 1;
10277       else
10278         break;
10279     }
10280
10281   if (sw_if_index_set == 0)
10282     {
10283       sw_if_index = ~0;
10284     }
10285
10286   if (!vam->json_output)
10287     {
10288       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
10289                "sw_if_index", "src_address", "dst_address",
10290                "encap_vrf_id", "decap_next_index", "vni");
10291     }
10292
10293   /* Get list of vxlan-tunnel interfaces */
10294   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10295
10296   mp->sw_if_index = htonl (sw_if_index);
10297
10298   S;
10299
10300   /* Use a control ping for synchronization */
10301   {
10302     vl_api_control_ping_t *mp;
10303     M (CONTROL_PING, control_ping);
10304     S;
10305   }
10306   W;
10307 }
10308
10309 static int
10310 api_gre_add_del_tunnel (vat_main_t * vam)
10311 {
10312   unformat_input_t *line_input = vam->input;
10313   vl_api_gre_add_del_tunnel_t *mp;
10314   f64 timeout;
10315   ip4_address_t src4, dst4;
10316   u8 is_add = 1;
10317   u8 teb = 0;
10318   u8 src_set = 0;
10319   u8 dst_set = 0;
10320   u32 outer_fib_id = 0;
10321
10322   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10323     {
10324       if (unformat (line_input, "del"))
10325         is_add = 0;
10326       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10327         src_set = 1;
10328       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10329         dst_set = 1;
10330       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10331         ;
10332       else if (unformat (line_input, "teb"))
10333         teb = 1;
10334       else
10335         {
10336           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10337           return -99;
10338         }
10339     }
10340
10341   if (src_set == 0)
10342     {
10343       errmsg ("tunnel src address not specified\n");
10344       return -99;
10345     }
10346   if (dst_set == 0)
10347     {
10348       errmsg ("tunnel dst address not specified\n");
10349       return -99;
10350     }
10351
10352
10353   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10354
10355   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10356   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10357   mp->outer_fib_id = ntohl (outer_fib_id);
10358   mp->is_add = is_add;
10359   mp->teb = teb;
10360
10361   S;
10362   W;
10363   /* NOTREACHED */
10364   return 0;
10365 }
10366
10367 static void vl_api_gre_tunnel_details_t_handler
10368   (vl_api_gre_tunnel_details_t * mp)
10369 {
10370   vat_main_t *vam = &vat_main;
10371
10372   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10373            ntohl (mp->sw_if_index),
10374            format_ip4_address, &mp->src_address,
10375            format_ip4_address, &mp->dst_address,
10376            mp->teb, ntohl (mp->outer_fib_id));
10377 }
10378
10379 static void vl_api_gre_tunnel_details_t_handler_json
10380   (vl_api_gre_tunnel_details_t * mp)
10381 {
10382   vat_main_t *vam = &vat_main;
10383   vat_json_node_t *node = NULL;
10384   struct in_addr ip4;
10385
10386   if (VAT_JSON_ARRAY != vam->json_tree.type)
10387     {
10388       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10389       vat_json_init_array (&vam->json_tree);
10390     }
10391   node = vat_json_array_add (&vam->json_tree);
10392
10393   vat_json_init_object (node);
10394   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10395   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10396   vat_json_object_add_ip4 (node, "src_address", ip4);
10397   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10398   vat_json_object_add_ip4 (node, "dst_address", ip4);
10399   vat_json_object_add_uint (node, "teb", mp->teb);
10400   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10401 }
10402
10403 static int
10404 api_gre_tunnel_dump (vat_main_t * vam)
10405 {
10406   unformat_input_t *i = vam->input;
10407   vl_api_gre_tunnel_dump_t *mp;
10408   f64 timeout;
10409   u32 sw_if_index;
10410   u8 sw_if_index_set = 0;
10411
10412   /* Parse args required to build the message */
10413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10414     {
10415       if (unformat (i, "sw_if_index %d", &sw_if_index))
10416         sw_if_index_set = 1;
10417       else
10418         break;
10419     }
10420
10421   if (sw_if_index_set == 0)
10422     {
10423       sw_if_index = ~0;
10424     }
10425
10426   if (!vam->json_output)
10427     {
10428       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10429                "sw_if_index", "src_address", "dst_address", "teb",
10430                "outer_fib_id");
10431     }
10432
10433   /* Get list of gre-tunnel interfaces */
10434   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10435
10436   mp->sw_if_index = htonl (sw_if_index);
10437
10438   S;
10439
10440   /* Use a control ping for synchronization */
10441   {
10442     vl_api_control_ping_t *mp;
10443     M (CONTROL_PING, control_ping);
10444     S;
10445   }
10446   W;
10447 }
10448
10449 static int
10450 api_l2_fib_clear_table (vat_main_t * vam)
10451 {
10452 //  unformat_input_t * i = vam->input;
10453   vl_api_l2_fib_clear_table_t *mp;
10454   f64 timeout;
10455
10456   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10457
10458   S;
10459   W;
10460   /* NOTREACHED */
10461   return 0;
10462 }
10463
10464 static int
10465 api_l2_interface_efp_filter (vat_main_t * vam)
10466 {
10467   unformat_input_t *i = vam->input;
10468   vl_api_l2_interface_efp_filter_t *mp;
10469   f64 timeout;
10470   u32 sw_if_index;
10471   u8 enable = 1;
10472   u8 sw_if_index_set = 0;
10473
10474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10475     {
10476       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10477         sw_if_index_set = 1;
10478       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10479         sw_if_index_set = 1;
10480       else if (unformat (i, "enable"))
10481         enable = 1;
10482       else if (unformat (i, "disable"))
10483         enable = 0;
10484       else
10485         {
10486           clib_warning ("parse error '%U'", format_unformat_error, i);
10487           return -99;
10488         }
10489     }
10490
10491   if (sw_if_index_set == 0)
10492     {
10493       errmsg ("missing sw_if_index\n");
10494       return -99;
10495     }
10496
10497   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10498
10499   mp->sw_if_index = ntohl (sw_if_index);
10500   mp->enable_disable = enable;
10501
10502   S;
10503   W;
10504   /* NOTREACHED */
10505   return 0;
10506 }
10507
10508 #define foreach_vtr_op                          \
10509 _("disable",  L2_VTR_DISABLED)                  \
10510 _("push-1",  L2_VTR_PUSH_1)                     \
10511 _("push-2",  L2_VTR_PUSH_2)                     \
10512 _("pop-1",  L2_VTR_POP_1)                       \
10513 _("pop-2",  L2_VTR_POP_2)                       \
10514 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10515 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10516 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10517 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10518
10519 static int
10520 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10521 {
10522   unformat_input_t *i = vam->input;
10523   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10524   f64 timeout;
10525   u32 sw_if_index;
10526   u8 sw_if_index_set = 0;
10527   u8 vtr_op_set = 0;
10528   u32 vtr_op = 0;
10529   u32 push_dot1q = 1;
10530   u32 tag1 = ~0;
10531   u32 tag2 = ~0;
10532
10533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10534     {
10535       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10536         sw_if_index_set = 1;
10537       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10538         sw_if_index_set = 1;
10539       else if (unformat (i, "vtr_op %d", &vtr_op))
10540         vtr_op_set = 1;
10541 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10542       foreach_vtr_op
10543 #undef _
10544         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10545         ;
10546       else if (unformat (i, "tag1 %d", &tag1))
10547         ;
10548       else if (unformat (i, "tag2 %d", &tag2))
10549         ;
10550       else
10551         {
10552           clib_warning ("parse error '%U'", format_unformat_error, i);
10553           return -99;
10554         }
10555     }
10556
10557   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10558     {
10559       errmsg ("missing vtr operation or sw_if_index\n");
10560       return -99;
10561     }
10562
10563   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10564     mp->sw_if_index = ntohl (sw_if_index);
10565   mp->vtr_op = ntohl (vtr_op);
10566   mp->push_dot1q = ntohl (push_dot1q);
10567   mp->tag1 = ntohl (tag1);
10568   mp->tag2 = ntohl (tag2);
10569
10570   S;
10571   W;
10572   /* NOTREACHED */
10573   return 0;
10574 }
10575
10576 static int
10577 api_create_vhost_user_if (vat_main_t * vam)
10578 {
10579   unformat_input_t *i = vam->input;
10580   vl_api_create_vhost_user_if_t *mp;
10581   f64 timeout;
10582   u8 *file_name;
10583   u8 is_server = 0;
10584   u8 file_name_set = 0;
10585   u32 custom_dev_instance = ~0;
10586   u8 hwaddr[6];
10587   u8 use_custom_mac = 0;
10588
10589   /* Shut up coverity */
10590   memset (hwaddr, 0, sizeof (hwaddr));
10591
10592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10593     {
10594       if (unformat (i, "socket %s", &file_name))
10595         {
10596           file_name_set = 1;
10597         }
10598       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10599         ;
10600       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10601         use_custom_mac = 1;
10602       else if (unformat (i, "server"))
10603         is_server = 1;
10604       else
10605         break;
10606     }
10607
10608   if (file_name_set == 0)
10609     {
10610       errmsg ("missing socket file name\n");
10611       return -99;
10612     }
10613
10614   if (vec_len (file_name) > 255)
10615     {
10616       errmsg ("socket file name too long\n");
10617       return -99;
10618     }
10619   vec_add1 (file_name, 0);
10620
10621   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10622
10623   mp->is_server = is_server;
10624   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10625   vec_free (file_name);
10626   if (custom_dev_instance != ~0)
10627     {
10628       mp->renumber = 1;
10629       mp->custom_dev_instance = ntohl (custom_dev_instance);
10630     }
10631   mp->use_custom_mac = use_custom_mac;
10632   clib_memcpy (mp->mac_address, hwaddr, 6);
10633
10634   S;
10635   W;
10636   /* NOTREACHED */
10637   return 0;
10638 }
10639
10640 static int
10641 api_modify_vhost_user_if (vat_main_t * vam)
10642 {
10643   unformat_input_t *i = vam->input;
10644   vl_api_modify_vhost_user_if_t *mp;
10645   f64 timeout;
10646   u8 *file_name;
10647   u8 is_server = 0;
10648   u8 file_name_set = 0;
10649   u32 custom_dev_instance = ~0;
10650   u8 sw_if_index_set = 0;
10651   u32 sw_if_index = (u32) ~ 0;
10652
10653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10654     {
10655       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10656         sw_if_index_set = 1;
10657       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10658         sw_if_index_set = 1;
10659       else if (unformat (i, "socket %s", &file_name))
10660         {
10661           file_name_set = 1;
10662         }
10663       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10664         ;
10665       else if (unformat (i, "server"))
10666         is_server = 1;
10667       else
10668         break;
10669     }
10670
10671   if (sw_if_index_set == 0)
10672     {
10673       errmsg ("missing sw_if_index or interface name\n");
10674       return -99;
10675     }
10676
10677   if (file_name_set == 0)
10678     {
10679       errmsg ("missing socket file name\n");
10680       return -99;
10681     }
10682
10683   if (vec_len (file_name) > 255)
10684     {
10685       errmsg ("socket file name too long\n");
10686       return -99;
10687     }
10688   vec_add1 (file_name, 0);
10689
10690   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10691
10692   mp->sw_if_index = ntohl (sw_if_index);
10693   mp->is_server = is_server;
10694   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10695   vec_free (file_name);
10696   if (custom_dev_instance != ~0)
10697     {
10698       mp->renumber = 1;
10699       mp->custom_dev_instance = ntohl (custom_dev_instance);
10700     }
10701
10702   S;
10703   W;
10704   /* NOTREACHED */
10705   return 0;
10706 }
10707
10708 static int
10709 api_delete_vhost_user_if (vat_main_t * vam)
10710 {
10711   unformat_input_t *i = vam->input;
10712   vl_api_delete_vhost_user_if_t *mp;
10713   f64 timeout;
10714   u32 sw_if_index = ~0;
10715   u8 sw_if_index_set = 0;
10716
10717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10718     {
10719       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10720         sw_if_index_set = 1;
10721       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10722         sw_if_index_set = 1;
10723       else
10724         break;
10725     }
10726
10727   if (sw_if_index_set == 0)
10728     {
10729       errmsg ("missing sw_if_index or interface name\n");
10730       return -99;
10731     }
10732
10733
10734   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10735
10736   mp->sw_if_index = ntohl (sw_if_index);
10737
10738   S;
10739   W;
10740   /* NOTREACHED */
10741   return 0;
10742 }
10743
10744 static void vl_api_sw_interface_vhost_user_details_t_handler
10745   (vl_api_sw_interface_vhost_user_details_t * mp)
10746 {
10747   vat_main_t *vam = &vat_main;
10748
10749   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10750            (char *) mp->interface_name,
10751            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10752            clib_net_to_host_u64 (mp->features), mp->is_server,
10753            ntohl (mp->num_regions), (char *) mp->sock_filename);
10754   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10755 }
10756
10757 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10758   (vl_api_sw_interface_vhost_user_details_t * mp)
10759 {
10760   vat_main_t *vam = &vat_main;
10761   vat_json_node_t *node = NULL;
10762
10763   if (VAT_JSON_ARRAY != vam->json_tree.type)
10764     {
10765       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10766       vat_json_init_array (&vam->json_tree);
10767     }
10768   node = vat_json_array_add (&vam->json_tree);
10769
10770   vat_json_init_object (node);
10771   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10772   vat_json_object_add_string_copy (node, "interface_name",
10773                                    mp->interface_name);
10774   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10775                             ntohl (mp->virtio_net_hdr_sz));
10776   vat_json_object_add_uint (node, "features",
10777                             clib_net_to_host_u64 (mp->features));
10778   vat_json_object_add_uint (node, "is_server", mp->is_server);
10779   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10780   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10781   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10782 }
10783
10784 static int
10785 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10786 {
10787   vl_api_sw_interface_vhost_user_dump_t *mp;
10788   f64 timeout;
10789   fformat (vam->ofp,
10790            "Interface name           idx hdr_sz features server regions filename\n");
10791
10792   /* Get list of vhost-user interfaces */
10793   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10794   S;
10795
10796   /* Use a control ping for synchronization */
10797   {
10798     vl_api_control_ping_t *mp;
10799     M (CONTROL_PING, control_ping);
10800     S;
10801   }
10802   W;
10803 }
10804
10805 static int
10806 api_show_version (vat_main_t * vam)
10807 {
10808   vl_api_show_version_t *mp;
10809   f64 timeout;
10810
10811   M (SHOW_VERSION, show_version);
10812
10813   S;
10814   W;
10815   /* NOTREACHED */
10816   return 0;
10817 }
10818
10819
10820 static int
10821 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10822 {
10823   unformat_input_t *line_input = vam->input;
10824   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10825   f64 timeout;
10826   ip4_address_t local4, remote4;
10827   ip6_address_t local6, remote6;
10828   u8 is_add = 1;
10829   u8 ipv4_set = 0, ipv6_set = 0;
10830   u8 local_set = 0;
10831   u8 remote_set = 0;
10832   u32 encap_vrf_id = 0;
10833   u32 decap_vrf_id = 0;
10834   u8 protocol = ~0;
10835   u32 vni;
10836   u8 vni_set = 0;
10837
10838   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10839     {
10840       if (unformat (line_input, "del"))
10841         is_add = 0;
10842       else if (unformat (line_input, "local %U",
10843                          unformat_ip4_address, &local4))
10844         {
10845           local_set = 1;
10846           ipv4_set = 1;
10847         }
10848       else if (unformat (line_input, "remote %U",
10849                          unformat_ip4_address, &remote4))
10850         {
10851           remote_set = 1;
10852           ipv4_set = 1;
10853         }
10854       else if (unformat (line_input, "local %U",
10855                          unformat_ip6_address, &local6))
10856         {
10857           local_set = 1;
10858           ipv6_set = 1;
10859         }
10860       else if (unformat (line_input, "remote %U",
10861                          unformat_ip6_address, &remote6))
10862         {
10863           remote_set = 1;
10864           ipv6_set = 1;
10865         }
10866       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10867         ;
10868       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10869         ;
10870       else if (unformat (line_input, "vni %d", &vni))
10871         vni_set = 1;
10872       else if (unformat (line_input, "next-ip4"))
10873         protocol = 1;
10874       else if (unformat (line_input, "next-ip6"))
10875         protocol = 2;
10876       else if (unformat (line_input, "next-ethernet"))
10877         protocol = 3;
10878       else if (unformat (line_input, "next-nsh"))
10879         protocol = 4;
10880       else
10881         {
10882           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10883           return -99;
10884         }
10885     }
10886
10887   if (local_set == 0)
10888     {
10889       errmsg ("tunnel local address not specified\n");
10890       return -99;
10891     }
10892   if (remote_set == 0)
10893     {
10894       errmsg ("tunnel remote address not specified\n");
10895       return -99;
10896     }
10897   if (ipv4_set && ipv6_set)
10898     {
10899       errmsg ("both IPv4 and IPv6 addresses specified");
10900       return -99;
10901     }
10902
10903   if (vni_set == 0)
10904     {
10905       errmsg ("vni not specified\n");
10906       return -99;
10907     }
10908
10909   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10910
10911
10912   if (ipv6_set)
10913     {
10914       clib_memcpy (&mp->local, &local6, sizeof (local6));
10915       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10916     }
10917   else
10918     {
10919       clib_memcpy (&mp->local, &local4, sizeof (local4));
10920       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10921     }
10922
10923   mp->encap_vrf_id = ntohl (encap_vrf_id);
10924   mp->decap_vrf_id = ntohl (decap_vrf_id);
10925   mp->protocol = ntohl (protocol);
10926   mp->vni = ntohl (vni);
10927   mp->is_add = is_add;
10928   mp->is_ipv6 = ipv6_set;
10929
10930   S;
10931   W;
10932   /* NOTREACHED */
10933   return 0;
10934 }
10935
10936 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10937   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10938 {
10939   vat_main_t *vam = &vat_main;
10940
10941   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10942            ntohl (mp->sw_if_index),
10943            format_ip46_address, &(mp->local[0]),
10944            format_ip46_address, &(mp->remote[0]),
10945            ntohl (mp->vni),
10946            ntohl (mp->protocol),
10947            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10948 }
10949
10950 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10951   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10952 {
10953   vat_main_t *vam = &vat_main;
10954   vat_json_node_t *node = NULL;
10955   struct in_addr ip4;
10956   struct in6_addr ip6;
10957
10958   if (VAT_JSON_ARRAY != vam->json_tree.type)
10959     {
10960       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10961       vat_json_init_array (&vam->json_tree);
10962     }
10963   node = vat_json_array_add (&vam->json_tree);
10964
10965   vat_json_init_object (node);
10966   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10967   if (mp->is_ipv6)
10968     {
10969       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10970       vat_json_object_add_ip6 (node, "local", ip6);
10971       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10972       vat_json_object_add_ip6 (node, "remote", ip6);
10973     }
10974   else
10975     {
10976       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10977       vat_json_object_add_ip4 (node, "local", ip4);
10978       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10979       vat_json_object_add_ip4 (node, "remote", ip4);
10980     }
10981   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10982   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10983   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10984   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10985   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10986 }
10987
10988 static int
10989 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10990 {
10991   unformat_input_t *i = vam->input;
10992   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10993   f64 timeout;
10994   u32 sw_if_index;
10995   u8 sw_if_index_set = 0;
10996
10997   /* Parse args required to build the message */
10998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10999     {
11000       if (unformat (i, "sw_if_index %d", &sw_if_index))
11001         sw_if_index_set = 1;
11002       else
11003         break;
11004     }
11005
11006   if (sw_if_index_set == 0)
11007     {
11008       sw_if_index = ~0;
11009     }
11010
11011   if (!vam->json_output)
11012     {
11013       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
11014                "sw_if_index", "local", "remote", "vni",
11015                "protocol", "encap_vrf_id", "decap_vrf_id");
11016     }
11017
11018   /* Get list of vxlan-tunnel interfaces */
11019   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11020
11021   mp->sw_if_index = htonl (sw_if_index);
11022
11023   S;
11024
11025   /* Use a control ping for synchronization */
11026   {
11027     vl_api_control_ping_t *mp;
11028     M (CONTROL_PING, control_ping);
11029     S;
11030   }
11031   W;
11032 }
11033
11034 u8 *
11035 format_l2_fib_mac_address (u8 * s, va_list * args)
11036 {
11037   u8 *a = va_arg (*args, u8 *);
11038
11039   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11040                  a[2], a[3], a[4], a[5], a[6], a[7]);
11041 }
11042
11043 static void vl_api_l2_fib_table_entry_t_handler
11044   (vl_api_l2_fib_table_entry_t * mp)
11045 {
11046   vat_main_t *vam = &vat_main;
11047
11048   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11049            "       %d       %d     %d\n",
11050            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11051            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11052            mp->bvi_mac);
11053 }
11054
11055 static void vl_api_l2_fib_table_entry_t_handler_json
11056   (vl_api_l2_fib_table_entry_t * mp)
11057 {
11058   vat_main_t *vam = &vat_main;
11059   vat_json_node_t *node = NULL;
11060
11061   if (VAT_JSON_ARRAY != vam->json_tree.type)
11062     {
11063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11064       vat_json_init_array (&vam->json_tree);
11065     }
11066   node = vat_json_array_add (&vam->json_tree);
11067
11068   vat_json_init_object (node);
11069   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11070   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11071   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11072   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11073   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11074   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11075 }
11076
11077 static int
11078 api_l2_fib_table_dump (vat_main_t * vam)
11079 {
11080   unformat_input_t *i = vam->input;
11081   vl_api_l2_fib_table_dump_t *mp;
11082   f64 timeout;
11083   u32 bd_id;
11084   u8 bd_id_set = 0;
11085
11086   /* Parse args required to build the message */
11087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11088     {
11089       if (unformat (i, "bd_id %d", &bd_id))
11090         bd_id_set = 1;
11091       else
11092         break;
11093     }
11094
11095   if (bd_id_set == 0)
11096     {
11097       errmsg ("missing bridge domain\n");
11098       return -99;
11099     }
11100
11101   fformat (vam->ofp,
11102            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11103
11104   /* Get list of l2 fib entries */
11105   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11106
11107   mp->bd_id = ntohl (bd_id);
11108   S;
11109
11110   /* Use a control ping for synchronization */
11111   {
11112     vl_api_control_ping_t *mp;
11113     M (CONTROL_PING, control_ping);
11114     S;
11115   }
11116   W;
11117 }
11118
11119
11120 static int
11121 api_interface_name_renumber (vat_main_t * vam)
11122 {
11123   unformat_input_t *line_input = vam->input;
11124   vl_api_interface_name_renumber_t *mp;
11125   u32 sw_if_index = ~0;
11126   f64 timeout;
11127   u32 new_show_dev_instance = ~0;
11128
11129   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11130     {
11131       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11132                     &sw_if_index))
11133         ;
11134       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11135         ;
11136       else if (unformat (line_input, "new_show_dev_instance %d",
11137                          &new_show_dev_instance))
11138         ;
11139       else
11140         break;
11141     }
11142
11143   if (sw_if_index == ~0)
11144     {
11145       errmsg ("missing interface name or sw_if_index\n");
11146       return -99;
11147     }
11148
11149   if (new_show_dev_instance == ~0)
11150     {
11151       errmsg ("missing new_show_dev_instance\n");
11152       return -99;
11153     }
11154
11155   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11156
11157   mp->sw_if_index = ntohl (sw_if_index);
11158   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11159
11160   S;
11161   W;
11162 }
11163
11164 static int
11165 api_want_ip4_arp_events (vat_main_t * vam)
11166 {
11167   unformat_input_t *line_input = vam->input;
11168   vl_api_want_ip4_arp_events_t *mp;
11169   f64 timeout;
11170   ip4_address_t address;
11171   int address_set = 0;
11172   u32 enable_disable = 1;
11173
11174   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11175     {
11176       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11177         address_set = 1;
11178       else if (unformat (line_input, "del"))
11179         enable_disable = 0;
11180       else
11181         break;
11182     }
11183
11184   if (address_set == 0)
11185     {
11186       errmsg ("missing addresses\n");
11187       return -99;
11188     }
11189
11190   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11191   mp->enable_disable = enable_disable;
11192   mp->pid = getpid ();
11193   mp->address = address.as_u32;
11194
11195   S;
11196   W;
11197 }
11198
11199 static int
11200 api_want_ip6_nd_events (vat_main_t * vam)
11201 {
11202   unformat_input_t *line_input = vam->input;
11203   vl_api_want_ip6_nd_events_t *mp;
11204   f64 timeout;
11205   ip6_address_t address;
11206   int address_set = 0;
11207   u32 enable_disable = 1;
11208
11209   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11210     {
11211       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11212         address_set = 1;
11213       else if (unformat (line_input, "del"))
11214         enable_disable = 0;
11215       else
11216         break;
11217     }
11218
11219   if (address_set == 0)
11220     {
11221       errmsg ("missing addresses\n");
11222       return -99;
11223     }
11224
11225   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11226   mp->enable_disable = enable_disable;
11227   mp->pid = getpid ();
11228   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11229
11230   S;
11231   W;
11232 }
11233
11234 static int
11235 api_input_acl_set_interface (vat_main_t * vam)
11236 {
11237   unformat_input_t *i = vam->input;
11238   vl_api_input_acl_set_interface_t *mp;
11239   f64 timeout;
11240   u32 sw_if_index;
11241   int sw_if_index_set;
11242   u32 ip4_table_index = ~0;
11243   u32 ip6_table_index = ~0;
11244   u32 l2_table_index = ~0;
11245   u8 is_add = 1;
11246
11247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11248     {
11249       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11250         sw_if_index_set = 1;
11251       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11252         sw_if_index_set = 1;
11253       else if (unformat (i, "del"))
11254         is_add = 0;
11255       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11256         ;
11257       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11258         ;
11259       else if (unformat (i, "l2-table %d", &l2_table_index))
11260         ;
11261       else
11262         {
11263           clib_warning ("parse error '%U'", format_unformat_error, i);
11264           return -99;
11265         }
11266     }
11267
11268   if (sw_if_index_set == 0)
11269     {
11270       errmsg ("missing interface name or sw_if_index\n");
11271       return -99;
11272     }
11273
11274   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11275
11276   mp->sw_if_index = ntohl (sw_if_index);
11277   mp->ip4_table_index = ntohl (ip4_table_index);
11278   mp->ip6_table_index = ntohl (ip6_table_index);
11279   mp->l2_table_index = ntohl (l2_table_index);
11280   mp->is_add = is_add;
11281
11282   S;
11283   W;
11284   /* NOTREACHED */
11285   return 0;
11286 }
11287
11288 static int
11289 api_ip_address_dump (vat_main_t * vam)
11290 {
11291   unformat_input_t *i = vam->input;
11292   vl_api_ip_address_dump_t *mp;
11293   u32 sw_if_index = ~0;
11294   u8 sw_if_index_set = 0;
11295   u8 ipv4_set = 0;
11296   u8 ipv6_set = 0;
11297   f64 timeout;
11298
11299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11300     {
11301       if (unformat (i, "sw_if_index %d", &sw_if_index))
11302         sw_if_index_set = 1;
11303       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11304         sw_if_index_set = 1;
11305       else if (unformat (i, "ipv4"))
11306         ipv4_set = 1;
11307       else if (unformat (i, "ipv6"))
11308         ipv6_set = 1;
11309       else
11310         break;
11311     }
11312
11313   if (ipv4_set && ipv6_set)
11314     {
11315       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11316       return -99;
11317     }
11318
11319   if ((!ipv4_set) && (!ipv6_set))
11320     {
11321       errmsg ("no ipv4 nor ipv6 flag set\n");
11322       return -99;
11323     }
11324
11325   if (sw_if_index_set == 0)
11326     {
11327       errmsg ("missing interface name or sw_if_index\n");
11328       return -99;
11329     }
11330
11331   vam->current_sw_if_index = sw_if_index;
11332   vam->is_ipv6 = ipv6_set;
11333
11334   M (IP_ADDRESS_DUMP, ip_address_dump);
11335   mp->sw_if_index = ntohl (sw_if_index);
11336   mp->is_ipv6 = ipv6_set;
11337   S;
11338
11339   /* Use a control ping for synchronization */
11340   {
11341     vl_api_control_ping_t *mp;
11342     M (CONTROL_PING, control_ping);
11343     S;
11344   }
11345   W;
11346 }
11347
11348 static int
11349 api_ip_dump (vat_main_t * vam)
11350 {
11351   vl_api_ip_dump_t *mp;
11352   unformat_input_t *in = vam->input;
11353   int ipv4_set = 0;
11354   int ipv6_set = 0;
11355   int is_ipv6;
11356   f64 timeout;
11357   int i;
11358
11359   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11360     {
11361       if (unformat (in, "ipv4"))
11362         ipv4_set = 1;
11363       else if (unformat (in, "ipv6"))
11364         ipv6_set = 1;
11365       else
11366         break;
11367     }
11368
11369   if (ipv4_set && ipv6_set)
11370     {
11371       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11372       return -99;
11373     }
11374
11375   if ((!ipv4_set) && (!ipv6_set))
11376     {
11377       errmsg ("no ipv4 nor ipv6 flag set\n");
11378       return -99;
11379     }
11380
11381   is_ipv6 = ipv6_set;
11382   vam->is_ipv6 = is_ipv6;
11383
11384   /* free old data */
11385   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11386     {
11387       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11388     }
11389   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11390
11391   M (IP_DUMP, ip_dump);
11392   mp->is_ipv6 = ipv6_set;
11393   S;
11394
11395   /* Use a control ping for synchronization */
11396   {
11397     vl_api_control_ping_t *mp;
11398     M (CONTROL_PING, control_ping);
11399     S;
11400   }
11401   W;
11402 }
11403
11404 static int
11405 api_ipsec_spd_add_del (vat_main_t * vam)
11406 {
11407 #if DPDK > 0
11408   unformat_input_t *i = vam->input;
11409   vl_api_ipsec_spd_add_del_t *mp;
11410   f64 timeout;
11411   u32 spd_id = ~0;
11412   u8 is_add = 1;
11413
11414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11415     {
11416       if (unformat (i, "spd_id %d", &spd_id))
11417         ;
11418       else if (unformat (i, "del"))
11419         is_add = 0;
11420       else
11421         {
11422           clib_warning ("parse error '%U'", format_unformat_error, i);
11423           return -99;
11424         }
11425     }
11426   if (spd_id == ~0)
11427     {
11428       errmsg ("spd_id must be set\n");
11429       return -99;
11430     }
11431
11432   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11433
11434   mp->spd_id = ntohl (spd_id);
11435   mp->is_add = is_add;
11436
11437   S;
11438   W;
11439   /* NOTREACHED */
11440   return 0;
11441 #else
11442   clib_warning ("unsupported (no dpdk)");
11443   return -99;
11444 #endif
11445 }
11446
11447 static int
11448 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11449 {
11450 #if DPDK > 0
11451   unformat_input_t *i = vam->input;
11452   vl_api_ipsec_interface_add_del_spd_t *mp;
11453   f64 timeout;
11454   u32 sw_if_index;
11455   u8 sw_if_index_set = 0;
11456   u32 spd_id = (u32) ~ 0;
11457   u8 is_add = 1;
11458
11459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11460     {
11461       if (unformat (i, "del"))
11462         is_add = 0;
11463       else if (unformat (i, "spd_id %d", &spd_id))
11464         ;
11465       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11466         sw_if_index_set = 1;
11467       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11468         sw_if_index_set = 1;
11469       else
11470         {
11471           clib_warning ("parse error '%U'", format_unformat_error, i);
11472           return -99;
11473         }
11474
11475     }
11476
11477   if (spd_id == (u32) ~ 0)
11478     {
11479       errmsg ("spd_id must be set\n");
11480       return -99;
11481     }
11482
11483   if (sw_if_index_set == 0)
11484     {
11485       errmsg ("missing interface name or sw_if_index\n");
11486       return -99;
11487     }
11488
11489   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11490
11491   mp->spd_id = ntohl (spd_id);
11492   mp->sw_if_index = ntohl (sw_if_index);
11493   mp->is_add = is_add;
11494
11495   S;
11496   W;
11497   /* NOTREACHED */
11498   return 0;
11499 #else
11500   clib_warning ("unsupported (no dpdk)");
11501   return -99;
11502 #endif
11503 }
11504
11505 static int
11506 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11507 {
11508 #if DPDK > 0
11509   unformat_input_t *i = vam->input;
11510   vl_api_ipsec_spd_add_del_entry_t *mp;
11511   f64 timeout;
11512   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11513   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11514   i32 priority = 0;
11515   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11516   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11517   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11518   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11519
11520   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11521   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11522   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11523   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11524   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11525   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11526
11527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11528     {
11529       if (unformat (i, "del"))
11530         is_add = 0;
11531       if (unformat (i, "outbound"))
11532         is_outbound = 1;
11533       if (unformat (i, "inbound"))
11534         is_outbound = 0;
11535       else if (unformat (i, "spd_id %d", &spd_id))
11536         ;
11537       else if (unformat (i, "sa_id %d", &sa_id))
11538         ;
11539       else if (unformat (i, "priority %d", &priority))
11540         ;
11541       else if (unformat (i, "protocol %d", &protocol))
11542         ;
11543       else if (unformat (i, "lport_start %d", &lport_start))
11544         ;
11545       else if (unformat (i, "lport_stop %d", &lport_stop))
11546         ;
11547       else if (unformat (i, "rport_start %d", &rport_start))
11548         ;
11549       else if (unformat (i, "rport_stop %d", &rport_stop))
11550         ;
11551       else
11552         if (unformat
11553             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11554         {
11555           is_ipv6 = 0;
11556           is_ip_any = 0;
11557         }
11558       else
11559         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11560         {
11561           is_ipv6 = 0;
11562           is_ip_any = 0;
11563         }
11564       else
11565         if (unformat
11566             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11567         {
11568           is_ipv6 = 0;
11569           is_ip_any = 0;
11570         }
11571       else
11572         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11573         {
11574           is_ipv6 = 0;
11575           is_ip_any = 0;
11576         }
11577       else
11578         if (unformat
11579             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11580         {
11581           is_ipv6 = 1;
11582           is_ip_any = 0;
11583         }
11584       else
11585         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11586         {
11587           is_ipv6 = 1;
11588           is_ip_any = 0;
11589         }
11590       else
11591         if (unformat
11592             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11593         {
11594           is_ipv6 = 1;
11595           is_ip_any = 0;
11596         }
11597       else
11598         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11599         {
11600           is_ipv6 = 1;
11601           is_ip_any = 0;
11602         }
11603       else
11604         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11605         {
11606           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11607             {
11608               clib_warning ("unsupported action: 'resolve'");
11609               return -99;
11610             }
11611         }
11612       else
11613         {
11614           clib_warning ("parse error '%U'", format_unformat_error, i);
11615           return -99;
11616         }
11617
11618     }
11619
11620   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11621
11622   mp->spd_id = ntohl (spd_id);
11623   mp->priority = ntohl (priority);
11624   mp->is_outbound = is_outbound;
11625
11626   mp->is_ipv6 = is_ipv6;
11627   if (is_ipv6 || is_ip_any)
11628     {
11629       clib_memcpy (mp->remote_address_start, &raddr6_start,
11630                    sizeof (ip6_address_t));
11631       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11632                    sizeof (ip6_address_t));
11633       clib_memcpy (mp->local_address_start, &laddr6_start,
11634                    sizeof (ip6_address_t));
11635       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11636                    sizeof (ip6_address_t));
11637     }
11638   else
11639     {
11640       clib_memcpy (mp->remote_address_start, &raddr4_start,
11641                    sizeof (ip4_address_t));
11642       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11643                    sizeof (ip4_address_t));
11644       clib_memcpy (mp->local_address_start, &laddr4_start,
11645                    sizeof (ip4_address_t));
11646       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11647                    sizeof (ip4_address_t));
11648     }
11649   mp->protocol = (u8) protocol;
11650   mp->local_port_start = ntohs ((u16) lport_start);
11651   mp->local_port_stop = ntohs ((u16) lport_stop);
11652   mp->remote_port_start = ntohs ((u16) rport_start);
11653   mp->remote_port_stop = ntohs ((u16) rport_stop);
11654   mp->policy = (u8) policy;
11655   mp->sa_id = ntohl (sa_id);
11656   mp->is_add = is_add;
11657   mp->is_ip_any = is_ip_any;
11658   S;
11659   W;
11660   /* NOTREACHED */
11661   return 0;
11662 #else
11663   clib_warning ("unsupported (no dpdk)");
11664   return -99;
11665 #endif
11666 }
11667
11668 static int
11669 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11670 {
11671 #if DPDK > 0
11672   unformat_input_t *i = vam->input;
11673   vl_api_ipsec_sad_add_del_entry_t *mp;
11674   f64 timeout;
11675   u32 sad_id = 0, spi = 0;
11676   u8 *ck = 0, *ik = 0;
11677   u8 is_add = 1;
11678
11679   u8 protocol = IPSEC_PROTOCOL_AH;
11680   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11681   u32 crypto_alg = 0, integ_alg = 0;
11682   ip4_address_t tun_src4;
11683   ip4_address_t tun_dst4;
11684   ip6_address_t tun_src6;
11685   ip6_address_t tun_dst6;
11686
11687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11688     {
11689       if (unformat (i, "del"))
11690         is_add = 0;
11691       else if (unformat (i, "sad_id %d", &sad_id))
11692         ;
11693       else if (unformat (i, "spi %d", &spi))
11694         ;
11695       else if (unformat (i, "esp"))
11696         protocol = IPSEC_PROTOCOL_ESP;
11697       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11698         {
11699           is_tunnel = 1;
11700           is_tunnel_ipv6 = 0;
11701         }
11702       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11703         {
11704           is_tunnel = 1;
11705           is_tunnel_ipv6 = 0;
11706         }
11707       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11708         {
11709           is_tunnel = 1;
11710           is_tunnel_ipv6 = 1;
11711         }
11712       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11713         {
11714           is_tunnel = 1;
11715           is_tunnel_ipv6 = 1;
11716         }
11717       else
11718         if (unformat
11719             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11720         {
11721           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11722               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11723             {
11724               clib_warning ("unsupported crypto-alg: '%U'",
11725                             format_ipsec_crypto_alg, crypto_alg);
11726               return -99;
11727             }
11728         }
11729       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11730         ;
11731       else
11732         if (unformat
11733             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11734         {
11735           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11736               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11737             {
11738               clib_warning ("unsupported integ-alg: '%U'",
11739                             format_ipsec_integ_alg, integ_alg);
11740               return -99;
11741             }
11742         }
11743       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11744         ;
11745       else
11746         {
11747           clib_warning ("parse error '%U'", format_unformat_error, i);
11748           return -99;
11749         }
11750
11751     }
11752
11753   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11754
11755   mp->sad_id = ntohl (sad_id);
11756   mp->is_add = is_add;
11757   mp->protocol = protocol;
11758   mp->spi = ntohl (spi);
11759   mp->is_tunnel = is_tunnel;
11760   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11761   mp->crypto_algorithm = crypto_alg;
11762   mp->integrity_algorithm = integ_alg;
11763   mp->crypto_key_length = vec_len (ck);
11764   mp->integrity_key_length = vec_len (ik);
11765
11766   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11767     mp->crypto_key_length = sizeof (mp->crypto_key);
11768
11769   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11770     mp->integrity_key_length = sizeof (mp->integrity_key);
11771
11772   if (ck)
11773     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11774   if (ik)
11775     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11776
11777   if (is_tunnel)
11778     {
11779       if (is_tunnel_ipv6)
11780         {
11781           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11782                        sizeof (ip6_address_t));
11783           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11784                        sizeof (ip6_address_t));
11785         }
11786       else
11787         {
11788           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11789                        sizeof (ip4_address_t));
11790           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11791                        sizeof (ip4_address_t));
11792         }
11793     }
11794
11795   S;
11796   W;
11797   /* NOTREACHED */
11798   return 0;
11799 #else
11800   clib_warning ("unsupported (no dpdk)");
11801   return -99;
11802 #endif
11803 }
11804
11805 static int
11806 api_ipsec_sa_set_key (vat_main_t * vam)
11807 {
11808 #if DPDK > 0
11809   unformat_input_t *i = vam->input;
11810   vl_api_ipsec_sa_set_key_t *mp;
11811   f64 timeout;
11812   u32 sa_id;
11813   u8 *ck = 0, *ik = 0;
11814
11815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11816     {
11817       if (unformat (i, "sa_id %d", &sa_id))
11818         ;
11819       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11820         ;
11821       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11822         ;
11823       else
11824         {
11825           clib_warning ("parse error '%U'", format_unformat_error, i);
11826           return -99;
11827         }
11828     }
11829
11830   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11831
11832   mp->sa_id = ntohl (sa_id);
11833   mp->crypto_key_length = vec_len (ck);
11834   mp->integrity_key_length = vec_len (ik);
11835
11836   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11837     mp->crypto_key_length = sizeof (mp->crypto_key);
11838
11839   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11840     mp->integrity_key_length = sizeof (mp->integrity_key);
11841
11842   if (ck)
11843     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11844   if (ik)
11845     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11846
11847   S;
11848   W;
11849   /* NOTREACHED */
11850   return 0;
11851 #else
11852   clib_warning ("unsupported (no dpdk)");
11853   return -99;
11854 #endif
11855 }
11856
11857 static int
11858 api_ikev2_profile_add_del (vat_main_t * vam)
11859 {
11860 #if DPDK > 0
11861   unformat_input_t *i = vam->input;
11862   vl_api_ikev2_profile_add_del_t *mp;
11863   f64 timeout;
11864   u8 is_add = 1;
11865   u8 *name = 0;
11866
11867   const char *valid_chars = "a-zA-Z0-9_";
11868
11869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11870     {
11871       if (unformat (i, "del"))
11872         is_add = 0;
11873       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11874         vec_add1 (name, 0);
11875       else
11876         {
11877           errmsg ("parse error '%U'", format_unformat_error, i);
11878           return -99;
11879         }
11880     }
11881
11882   if (!vec_len (name))
11883     {
11884       errmsg ("profile name must be specified");
11885       return -99;
11886     }
11887
11888   if (vec_len (name) > 64)
11889     {
11890       errmsg ("profile name too long");
11891       return -99;
11892     }
11893
11894   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11895
11896   clib_memcpy (mp->name, name, vec_len (name));
11897   mp->is_add = is_add;
11898   vec_free (name);
11899
11900   S;
11901   W;
11902   /* NOTREACHED */
11903   return 0;
11904 #else
11905   clib_warning ("unsupported (no dpdk)");
11906   return -99;
11907 #endif
11908 }
11909
11910 static int
11911 api_ikev2_profile_set_auth (vat_main_t * vam)
11912 {
11913 #if DPDK > 0
11914   unformat_input_t *i = vam->input;
11915   vl_api_ikev2_profile_set_auth_t *mp;
11916   f64 timeout;
11917   u8 *name = 0;
11918   u8 *data = 0;
11919   u32 auth_method = 0;
11920   u8 is_hex = 0;
11921
11922   const char *valid_chars = "a-zA-Z0-9_";
11923
11924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11925     {
11926       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11927         vec_add1 (name, 0);
11928       else if (unformat (i, "auth_method %U",
11929                          unformat_ikev2_auth_method, &auth_method))
11930         ;
11931       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11932         is_hex = 1;
11933       else if (unformat (i, "auth_data %v", &data))
11934         ;
11935       else
11936         {
11937           errmsg ("parse error '%U'", format_unformat_error, i);
11938           return -99;
11939         }
11940     }
11941
11942   if (!vec_len (name))
11943     {
11944       errmsg ("profile name must be specified");
11945       return -99;
11946     }
11947
11948   if (vec_len (name) > 64)
11949     {
11950       errmsg ("profile name too long");
11951       return -99;
11952     }
11953
11954   if (!vec_len (data))
11955     {
11956       errmsg ("auth_data must be specified");
11957       return -99;
11958     }
11959
11960   if (!auth_method)
11961     {
11962       errmsg ("auth_method must be specified");
11963       return -99;
11964     }
11965
11966   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11967
11968   mp->is_hex = is_hex;
11969   mp->auth_method = (u8) auth_method;
11970   mp->data_len = vec_len (data);
11971   clib_memcpy (mp->name, name, vec_len (name));
11972   clib_memcpy (mp->data, data, vec_len (data));
11973   vec_free (name);
11974   vec_free (data);
11975
11976   S;
11977   W;
11978   /* NOTREACHED */
11979   return 0;
11980 #else
11981   clib_warning ("unsupported (no dpdk)");
11982   return -99;
11983 #endif
11984 }
11985
11986 static int
11987 api_ikev2_profile_set_id (vat_main_t * vam)
11988 {
11989 #if DPDK > 0
11990   unformat_input_t *i = vam->input;
11991   vl_api_ikev2_profile_set_id_t *mp;
11992   f64 timeout;
11993   u8 *name = 0;
11994   u8 *data = 0;
11995   u8 is_local = 0;
11996   u32 id_type = 0;
11997   ip4_address_t ip4;
11998
11999   const char *valid_chars = "a-zA-Z0-9_";
12000
12001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12002     {
12003       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12004         vec_add1 (name, 0);
12005       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12006         ;
12007       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12008         {
12009           data = vec_new (u8, 4);
12010           clib_memcpy (data, ip4.as_u8, 4);
12011         }
12012       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12013         ;
12014       else if (unformat (i, "id_data %v", &data))
12015         ;
12016       else if (unformat (i, "local"))
12017         is_local = 1;
12018       else if (unformat (i, "remote"))
12019         is_local = 0;
12020       else
12021         {
12022           errmsg ("parse error '%U'", format_unformat_error, i);
12023           return -99;
12024         }
12025     }
12026
12027   if (!vec_len (name))
12028     {
12029       errmsg ("profile name must be specified");
12030       return -99;
12031     }
12032
12033   if (vec_len (name) > 64)
12034     {
12035       errmsg ("profile name too long");
12036       return -99;
12037     }
12038
12039   if (!vec_len (data))
12040     {
12041       errmsg ("id_data must be specified");
12042       return -99;
12043     }
12044
12045   if (!id_type)
12046     {
12047       errmsg ("id_type must be specified");
12048       return -99;
12049     }
12050
12051   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12052
12053   mp->is_local = is_local;
12054   mp->id_type = (u8) id_type;
12055   mp->data_len = vec_len (data);
12056   clib_memcpy (mp->name, name, vec_len (name));
12057   clib_memcpy (mp->data, data, vec_len (data));
12058   vec_free (name);
12059   vec_free (data);
12060
12061   S;
12062   W;
12063   /* NOTREACHED */
12064   return 0;
12065 #else
12066   clib_warning ("unsupported (no dpdk)");
12067   return -99;
12068 #endif
12069 }
12070
12071 static int
12072 api_ikev2_profile_set_ts (vat_main_t * vam)
12073 {
12074 #if DPDK > 0
12075   unformat_input_t *i = vam->input;
12076   vl_api_ikev2_profile_set_ts_t *mp;
12077   f64 timeout;
12078   u8 *name = 0;
12079   u8 is_local = 0;
12080   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12081   ip4_address_t start_addr, end_addr;
12082
12083   const char *valid_chars = "a-zA-Z0-9_";
12084
12085   start_addr.as_u32 = 0;
12086   end_addr.as_u32 = (u32) ~ 0;
12087
12088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12089     {
12090       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12091         vec_add1 (name, 0);
12092       else if (unformat (i, "protocol %d", &proto))
12093         ;
12094       else if (unformat (i, "start_port %d", &start_port))
12095         ;
12096       else if (unformat (i, "end_port %d", &end_port))
12097         ;
12098       else
12099         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12100         ;
12101       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12102         ;
12103       else if (unformat (i, "local"))
12104         is_local = 1;
12105       else if (unformat (i, "remote"))
12106         is_local = 0;
12107       else
12108         {
12109           errmsg ("parse error '%U'", format_unformat_error, i);
12110           return -99;
12111         }
12112     }
12113
12114   if (!vec_len (name))
12115     {
12116       errmsg ("profile name must be specified");
12117       return -99;
12118     }
12119
12120   if (vec_len (name) > 64)
12121     {
12122       errmsg ("profile name too long");
12123       return -99;
12124     }
12125
12126   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12127
12128   mp->is_local = is_local;
12129   mp->proto = (u8) proto;
12130   mp->start_port = (u16) start_port;
12131   mp->end_port = (u16) end_port;
12132   mp->start_addr = start_addr.as_u32;
12133   mp->end_addr = end_addr.as_u32;
12134   clib_memcpy (mp->name, name, vec_len (name));
12135   vec_free (name);
12136
12137   S;
12138   W;
12139   /* NOTREACHED */
12140   return 0;
12141 #else
12142   clib_warning ("unsupported (no dpdk)");
12143   return -99;
12144 #endif
12145 }
12146
12147 static int
12148 api_ikev2_set_local_key (vat_main_t * vam)
12149 {
12150 #if DPDK > 0
12151   unformat_input_t *i = vam->input;
12152   vl_api_ikev2_set_local_key_t *mp;
12153   f64 timeout;
12154   u8 *file = 0;
12155
12156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12157     {
12158       if (unformat (i, "file %v", &file))
12159         vec_add1 (file, 0);
12160       else
12161         {
12162           errmsg ("parse error '%U'", format_unformat_error, i);
12163           return -99;
12164         }
12165     }
12166
12167   if (!vec_len (file))
12168     {
12169       errmsg ("RSA key file must be specified");
12170       return -99;
12171     }
12172
12173   if (vec_len (file) > 256)
12174     {
12175       errmsg ("file name too long");
12176       return -99;
12177     }
12178
12179   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12180
12181   clib_memcpy (mp->key_file, file, vec_len (file));
12182   vec_free (file);
12183
12184   S;
12185   W;
12186   /* NOTREACHED */
12187   return 0;
12188 #else
12189   clib_warning ("unsupported (no dpdk)");
12190   return -99;
12191 #endif
12192 }
12193
12194 /*
12195  * MAP
12196  */
12197 static int
12198 api_map_add_domain (vat_main_t * vam)
12199 {
12200   unformat_input_t *i = vam->input;
12201   vl_api_map_add_domain_t *mp;
12202   f64 timeout;
12203
12204   ip4_address_t ip4_prefix;
12205   ip6_address_t ip6_prefix;
12206   ip6_address_t ip6_src;
12207   u32 num_m_args = 0;
12208   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12209     0, psid_length = 0;
12210   u8 is_translation = 0;
12211   u32 mtu = 0;
12212   u32 ip6_src_len = 128;
12213
12214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12215     {
12216       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12217                     &ip4_prefix, &ip4_prefix_len))
12218         num_m_args++;
12219       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12220                          &ip6_prefix, &ip6_prefix_len))
12221         num_m_args++;
12222       else
12223         if (unformat
12224             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12225              &ip6_src_len))
12226         num_m_args++;
12227       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12228         num_m_args++;
12229       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12230         num_m_args++;
12231       else if (unformat (i, "psid-offset %d", &psid_offset))
12232         num_m_args++;
12233       else if (unformat (i, "psid-len %d", &psid_length))
12234         num_m_args++;
12235       else if (unformat (i, "mtu %d", &mtu))
12236         num_m_args++;
12237       else if (unformat (i, "map-t"))
12238         is_translation = 1;
12239       else
12240         {
12241           clib_warning ("parse error '%U'", format_unformat_error, i);
12242           return -99;
12243         }
12244     }
12245
12246   if (num_m_args < 3)
12247     {
12248       errmsg ("mandatory argument(s) missing\n");
12249       return -99;
12250     }
12251
12252   /* Construct the API message */
12253   M (MAP_ADD_DOMAIN, map_add_domain);
12254
12255   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12256   mp->ip4_prefix_len = ip4_prefix_len;
12257
12258   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12259   mp->ip6_prefix_len = ip6_prefix_len;
12260
12261   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12262   mp->ip6_src_prefix_len = ip6_src_len;
12263
12264   mp->ea_bits_len = ea_bits_len;
12265   mp->psid_offset = psid_offset;
12266   mp->psid_length = psid_length;
12267   mp->is_translation = is_translation;
12268   mp->mtu = htons (mtu);
12269
12270   /* send it... */
12271   S;
12272
12273   /* Wait for a reply, return good/bad news  */
12274   W;
12275 }
12276
12277 static int
12278 api_map_del_domain (vat_main_t * vam)
12279 {
12280   unformat_input_t *i = vam->input;
12281   vl_api_map_del_domain_t *mp;
12282   f64 timeout;
12283
12284   u32 num_m_args = 0;
12285   u32 index;
12286
12287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12288     {
12289       if (unformat (i, "index %d", &index))
12290         num_m_args++;
12291       else
12292         {
12293           clib_warning ("parse error '%U'", format_unformat_error, i);
12294           return -99;
12295         }
12296     }
12297
12298   if (num_m_args != 1)
12299     {
12300       errmsg ("mandatory argument(s) missing\n");
12301       return -99;
12302     }
12303
12304   /* Construct the API message */
12305   M (MAP_DEL_DOMAIN, map_del_domain);
12306
12307   mp->index = ntohl (index);
12308
12309   /* send it... */
12310   S;
12311
12312   /* Wait for a reply, return good/bad news  */
12313   W;
12314 }
12315
12316 static int
12317 api_map_add_del_rule (vat_main_t * vam)
12318 {
12319   unformat_input_t *i = vam->input;
12320   vl_api_map_add_del_rule_t *mp;
12321   f64 timeout;
12322   u8 is_add = 1;
12323   ip6_address_t ip6_dst;
12324   u32 num_m_args = 0, index, psid = 0;
12325
12326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12327     {
12328       if (unformat (i, "index %d", &index))
12329         num_m_args++;
12330       else if (unformat (i, "psid %d", &psid))
12331         num_m_args++;
12332       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12333         num_m_args++;
12334       else if (unformat (i, "del"))
12335         {
12336           is_add = 0;
12337         }
12338       else
12339         {
12340           clib_warning ("parse error '%U'", format_unformat_error, i);
12341           return -99;
12342         }
12343     }
12344
12345   /* Construct the API message */
12346   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12347
12348   mp->index = ntohl (index);
12349   mp->is_add = is_add;
12350   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12351   mp->psid = ntohs (psid);
12352
12353   /* send it... */
12354   S;
12355
12356   /* Wait for a reply, return good/bad news  */
12357   W;
12358 }
12359
12360 static int
12361 api_map_domain_dump (vat_main_t * vam)
12362 {
12363   vl_api_map_domain_dump_t *mp;
12364   f64 timeout;
12365
12366   /* Construct the API message */
12367   M (MAP_DOMAIN_DUMP, map_domain_dump);
12368
12369   /* send it... */
12370   S;
12371
12372   /* Use a control ping for synchronization */
12373   {
12374     vl_api_control_ping_t *mp;
12375     M (CONTROL_PING, control_ping);
12376     S;
12377   }
12378   W;
12379 }
12380
12381 static int
12382 api_map_rule_dump (vat_main_t * vam)
12383 {
12384   unformat_input_t *i = vam->input;
12385   vl_api_map_rule_dump_t *mp;
12386   f64 timeout;
12387   u32 domain_index = ~0;
12388
12389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12390     {
12391       if (unformat (i, "index %u", &domain_index))
12392         ;
12393       else
12394         break;
12395     }
12396
12397   if (domain_index == ~0)
12398     {
12399       clib_warning ("parse error: domain index expected");
12400       return -99;
12401     }
12402
12403   /* Construct the API message */
12404   M (MAP_RULE_DUMP, map_rule_dump);
12405
12406   mp->domain_index = htonl (domain_index);
12407
12408   /* send it... */
12409   S;
12410
12411   /* Use a control ping for synchronization */
12412   {
12413     vl_api_control_ping_t *mp;
12414     M (CONTROL_PING, control_ping);
12415     S;
12416   }
12417   W;
12418 }
12419
12420 static void vl_api_map_add_domain_reply_t_handler
12421   (vl_api_map_add_domain_reply_t * mp)
12422 {
12423   vat_main_t *vam = &vat_main;
12424   i32 retval = ntohl (mp->retval);
12425
12426   if (vam->async_mode)
12427     {
12428       vam->async_errors += (retval < 0);
12429     }
12430   else
12431     {
12432       vam->retval = retval;
12433       vam->result_ready = 1;
12434     }
12435 }
12436
12437 static void vl_api_map_add_domain_reply_t_handler_json
12438   (vl_api_map_add_domain_reply_t * mp)
12439 {
12440   vat_main_t *vam = &vat_main;
12441   vat_json_node_t node;
12442
12443   vat_json_init_object (&node);
12444   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12445   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12446
12447   vat_json_print (vam->ofp, &node);
12448   vat_json_free (&node);
12449
12450   vam->retval = ntohl (mp->retval);
12451   vam->result_ready = 1;
12452 }
12453
12454 static int
12455 api_get_first_msg_id (vat_main_t * vam)
12456 {
12457   vl_api_get_first_msg_id_t *mp;
12458   f64 timeout;
12459   unformat_input_t *i = vam->input;
12460   u8 *name;
12461   u8 name_set = 0;
12462
12463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12464     {
12465       if (unformat (i, "client %s", &name))
12466         name_set = 1;
12467       else
12468         break;
12469     }
12470
12471   if (name_set == 0)
12472     {
12473       errmsg ("missing client name\n");
12474       return -99;
12475     }
12476   vec_add1 (name, 0);
12477
12478   if (vec_len (name) > 63)
12479     {
12480       errmsg ("client name too long\n");
12481       return -99;
12482     }
12483
12484   M (GET_FIRST_MSG_ID, get_first_msg_id);
12485   clib_memcpy (mp->name, name, vec_len (name));
12486   S;
12487   W;
12488   /* NOTREACHED */
12489   return 0;
12490 }
12491
12492 static int
12493 api_cop_interface_enable_disable (vat_main_t * vam)
12494 {
12495   unformat_input_t *line_input = vam->input;
12496   vl_api_cop_interface_enable_disable_t *mp;
12497   f64 timeout;
12498   u32 sw_if_index = ~0;
12499   u8 enable_disable = 1;
12500
12501   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12502     {
12503       if (unformat (line_input, "disable"))
12504         enable_disable = 0;
12505       if (unformat (line_input, "enable"))
12506         enable_disable = 1;
12507       else if (unformat (line_input, "%U", unformat_sw_if_index,
12508                          vam, &sw_if_index))
12509         ;
12510       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12511         ;
12512       else
12513         break;
12514     }
12515
12516   if (sw_if_index == ~0)
12517     {
12518       errmsg ("missing interface name or sw_if_index\n");
12519       return -99;
12520     }
12521
12522   /* Construct the API message */
12523   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12524   mp->sw_if_index = ntohl (sw_if_index);
12525   mp->enable_disable = enable_disable;
12526
12527   /* send it... */
12528   S;
12529   /* Wait for the reply */
12530   W;
12531 }
12532
12533 static int
12534 api_cop_whitelist_enable_disable (vat_main_t * vam)
12535 {
12536   unformat_input_t *line_input = vam->input;
12537   vl_api_cop_whitelist_enable_disable_t *mp;
12538   f64 timeout;
12539   u32 sw_if_index = ~0;
12540   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12541   u32 fib_id = 0;
12542
12543   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12544     {
12545       if (unformat (line_input, "ip4"))
12546         ip4 = 1;
12547       else if (unformat (line_input, "ip6"))
12548         ip6 = 1;
12549       else if (unformat (line_input, "default"))
12550         default_cop = 1;
12551       else if (unformat (line_input, "%U", unformat_sw_if_index,
12552                          vam, &sw_if_index))
12553         ;
12554       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12555         ;
12556       else if (unformat (line_input, "fib-id %d", &fib_id))
12557         ;
12558       else
12559         break;
12560     }
12561
12562   if (sw_if_index == ~0)
12563     {
12564       errmsg ("missing interface name or sw_if_index\n");
12565       return -99;
12566     }
12567
12568   /* Construct the API message */
12569   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12570   mp->sw_if_index = ntohl (sw_if_index);
12571   mp->fib_id = ntohl (fib_id);
12572   mp->ip4 = ip4;
12573   mp->ip6 = ip6;
12574   mp->default_cop = default_cop;
12575
12576   /* send it... */
12577   S;
12578   /* Wait for the reply */
12579   W;
12580 }
12581
12582 static int
12583 api_get_node_graph (vat_main_t * vam)
12584 {
12585   vl_api_get_node_graph_t *mp;
12586   f64 timeout;
12587
12588   M (GET_NODE_GRAPH, get_node_graph);
12589
12590   /* send it... */
12591   S;
12592   /* Wait for the reply */
12593   W;
12594 }
12595
12596 /* *INDENT-OFF* */
12597 /** Used for parsing LISP eids */
12598 typedef CLIB_PACKED(struct{
12599   u8 addr[16];   /**< eid address */
12600   u32 len;       /**< prefix length if IP */
12601   u8 type;      /**< type of eid */
12602 }) lisp_eid_vat_t;
12603 /* *INDENT-ON* */
12604
12605 static uword
12606 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12607 {
12608   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12609
12610   memset (a, 0, sizeof (a[0]));
12611
12612   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12613     {
12614       a->type = 0;              /* ipv4 type */
12615     }
12616   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12617     {
12618       a->type = 1;              /* ipv6 type */
12619     }
12620   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12621     {
12622       a->type = 2;              /* mac type */
12623     }
12624   else
12625     {
12626       return 0;
12627     }
12628
12629   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12630     {
12631       return 0;
12632     }
12633
12634   return 1;
12635 }
12636
12637 static int
12638 lisp_eid_size_vat (u8 type)
12639 {
12640   switch (type)
12641     {
12642     case 0:
12643       return 4;
12644     case 1:
12645       return 16;
12646     case 2:
12647       return 6;
12648     }
12649   return 0;
12650 }
12651
12652 static void
12653 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12654 {
12655   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12656 }
12657
12658 /* *INDENT-OFF* */
12659 /** Used for transferring locators via VPP API */
12660 typedef CLIB_PACKED(struct
12661 {
12662   u32 sw_if_index; /**< locator sw_if_index */
12663   u8 priority; /**< locator priority */
12664   u8 weight;   /**< locator weight */
12665 }) ls_locator_t;
12666 /* *INDENT-ON* */
12667
12668 static int
12669 api_lisp_add_del_locator_set (vat_main_t * vam)
12670 {
12671   unformat_input_t *input = vam->input;
12672   vl_api_lisp_add_del_locator_set_t *mp;
12673   f64 timeout = ~0;
12674   u8 is_add = 1;
12675   u8 *locator_set_name = NULL;
12676   u8 locator_set_name_set = 0;
12677   ls_locator_t locator, *locators = 0;
12678   u32 sw_if_index, priority, weight;
12679   u32 data_len = 0;
12680
12681   /* Parse args required to build the message */
12682   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12683     {
12684       if (unformat (input, "del"))
12685         {
12686           is_add = 0;
12687         }
12688       else if (unformat (input, "locator-set %s", &locator_set_name))
12689         {
12690           locator_set_name_set = 1;
12691         }
12692       else if (unformat (input, "sw_if_index %u p %u w %u",
12693                          &sw_if_index, &priority, &weight))
12694         {
12695           locator.sw_if_index = htonl (sw_if_index);
12696           locator.priority = priority;
12697           locator.weight = weight;
12698           vec_add1 (locators, locator);
12699         }
12700       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12701                          vam, &sw_if_index, &priority, &weight))
12702         {
12703           locator.sw_if_index = htonl (sw_if_index);
12704           locator.priority = priority;
12705           locator.weight = weight;
12706           vec_add1 (locators, locator);
12707         }
12708       else
12709         break;
12710     }
12711
12712   if (locator_set_name_set == 0)
12713     {
12714       errmsg ("missing locator-set name");
12715       vec_free (locators);
12716       return -99;
12717     }
12718
12719   if (vec_len (locator_set_name) > 64)
12720     {
12721       errmsg ("locator-set name too long\n");
12722       vec_free (locator_set_name);
12723       vec_free (locators);
12724       return -99;
12725     }
12726   vec_add1 (locator_set_name, 0);
12727
12728   data_len = sizeof (ls_locator_t) * vec_len (locators);
12729
12730   /* Construct the API message */
12731   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12732
12733   mp->is_add = is_add;
12734   clib_memcpy (mp->locator_set_name, locator_set_name,
12735                vec_len (locator_set_name));
12736   vec_free (locator_set_name);
12737
12738   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12739   if (locators)
12740     clib_memcpy (mp->locators, locators, data_len);
12741   vec_free (locators);
12742
12743   /* send it... */
12744   S;
12745
12746   /* Wait for a reply... */
12747   W;
12748
12749   /* NOTREACHED */
12750   return 0;
12751 }
12752
12753 static int
12754 api_lisp_add_del_locator (vat_main_t * vam)
12755 {
12756   unformat_input_t *input = vam->input;
12757   vl_api_lisp_add_del_locator_t *mp;
12758   f64 timeout = ~0;
12759   u32 tmp_if_index = ~0;
12760   u32 sw_if_index = ~0;
12761   u8 sw_if_index_set = 0;
12762   u8 sw_if_index_if_name_set = 0;
12763   u32 priority = ~0;
12764   u8 priority_set = 0;
12765   u32 weight = ~0;
12766   u8 weight_set = 0;
12767   u8 is_add = 1;
12768   u8 *locator_set_name = NULL;
12769   u8 locator_set_name_set = 0;
12770
12771   /* Parse args required to build the message */
12772   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12773     {
12774       if (unformat (input, "del"))
12775         {
12776           is_add = 0;
12777         }
12778       else if (unformat (input, "locator-set %s", &locator_set_name))
12779         {
12780           locator_set_name_set = 1;
12781         }
12782       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12783                          &tmp_if_index))
12784         {
12785           sw_if_index_if_name_set = 1;
12786           sw_if_index = tmp_if_index;
12787         }
12788       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12789         {
12790           sw_if_index_set = 1;
12791           sw_if_index = tmp_if_index;
12792         }
12793       else if (unformat (input, "p %d", &priority))
12794         {
12795           priority_set = 1;
12796         }
12797       else if (unformat (input, "w %d", &weight))
12798         {
12799           weight_set = 1;
12800         }
12801       else
12802         break;
12803     }
12804
12805   if (locator_set_name_set == 0)
12806     {
12807       errmsg ("missing locator-set name");
12808       return -99;
12809     }
12810
12811   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12812     {
12813       errmsg ("missing sw_if_index");
12814       vec_free (locator_set_name);
12815       return -99;
12816     }
12817
12818   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12819     {
12820       errmsg ("cannot use both params interface name and sw_if_index");
12821       vec_free (locator_set_name);
12822       return -99;
12823     }
12824
12825   if (priority_set == 0)
12826     {
12827       errmsg ("missing locator-set priority\n");
12828       vec_free (locator_set_name);
12829       return -99;
12830     }
12831
12832   if (weight_set == 0)
12833     {
12834       errmsg ("missing locator-set weight\n");
12835       vec_free (locator_set_name);
12836       return -99;
12837     }
12838
12839   if (vec_len (locator_set_name) > 64)
12840     {
12841       errmsg ("locator-set name too long\n");
12842       vec_free (locator_set_name);
12843       return -99;
12844     }
12845   vec_add1 (locator_set_name, 0);
12846
12847   /* Construct the API message */
12848   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12849
12850   mp->is_add = is_add;
12851   mp->sw_if_index = ntohl (sw_if_index);
12852   mp->priority = priority;
12853   mp->weight = weight;
12854   clib_memcpy (mp->locator_set_name, locator_set_name,
12855                vec_len (locator_set_name));
12856   vec_free (locator_set_name);
12857
12858   /* send it... */
12859   S;
12860
12861   /* Wait for a reply... */
12862   W;
12863
12864   /* NOTREACHED */
12865   return 0;
12866 }
12867
12868 static int
12869 api_lisp_add_del_local_eid (vat_main_t * vam)
12870 {
12871   unformat_input_t *input = vam->input;
12872   vl_api_lisp_add_del_local_eid_t *mp;
12873   f64 timeout = ~0;
12874   u8 is_add = 1;
12875   u8 eid_set = 0;
12876   lisp_eid_vat_t _eid, *eid = &_eid;
12877   u8 *locator_set_name = 0;
12878   u8 locator_set_name_set = 0;
12879   u32 vni = 0;
12880
12881   /* Parse args required to build the message */
12882   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12883     {
12884       if (unformat (input, "del"))
12885         {
12886           is_add = 0;
12887         }
12888       else if (unformat (input, "vni %d", &vni))
12889         {
12890           ;
12891         }
12892       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12893         {
12894           eid_set = 1;
12895         }
12896       else if (unformat (input, "locator-set %s", &locator_set_name))
12897         {
12898           locator_set_name_set = 1;
12899         }
12900       else
12901         break;
12902     }
12903
12904   if (locator_set_name_set == 0)
12905     {
12906       errmsg ("missing locator-set name\n");
12907       return -99;
12908     }
12909
12910   if (0 == eid_set)
12911     {
12912       errmsg ("EID address not set!");
12913       vec_free (locator_set_name);
12914       return -99;
12915     }
12916
12917   if (vec_len (locator_set_name) > 64)
12918     {
12919       errmsg ("locator-set name too long\n");
12920       vec_free (locator_set_name);
12921       return -99;
12922     }
12923   vec_add1 (locator_set_name, 0);
12924
12925   /* Construct the API message */
12926   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12927
12928   mp->is_add = is_add;
12929   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12930   mp->eid_type = eid->type;
12931   mp->prefix_len = eid->len;
12932   mp->vni = clib_host_to_net_u32 (vni);
12933   clib_memcpy (mp->locator_set_name, locator_set_name,
12934                vec_len (locator_set_name));
12935
12936   vec_free (locator_set_name);
12937
12938   /* send it... */
12939   S;
12940
12941   /* Wait for a reply... */
12942   W;
12943
12944   /* NOTREACHED */
12945   return 0;
12946 }
12947
12948 /* *INDENT-OFF* */
12949 /** Used for transferring locators via VPP API */
12950 typedef CLIB_PACKED(struct
12951 {
12952   u8 is_ip4; /**< is locator an IPv4 address? */
12953   u8 priority; /**< locator priority */
12954   u8 weight;   /**< locator weight */
12955   u8 addr[16]; /**< IPv4/IPv6 address */
12956 }) rloc_t;
12957 /* *INDENT-ON* */
12958
12959 static int
12960 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12961 {
12962   unformat_input_t *input = vam->input;
12963   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12964   f64 timeout = ~0;
12965   u8 is_add = 1;
12966   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12967   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12968   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12969   u32 action = ~0, p, w;
12970   ip4_address_t rmt_rloc4, lcl_rloc4;
12971   ip6_address_t rmt_rloc6, lcl_rloc6;
12972   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12973
12974   memset (&rloc, 0, sizeof (rloc));
12975
12976   /* Parse args required to build the message */
12977   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12978     {
12979       if (unformat (input, "del"))
12980         {
12981           is_add = 0;
12982         }
12983       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12984         {
12985           rmt_eid_set = 1;
12986         }
12987       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12988         {
12989           lcl_eid_set = 1;
12990         }
12991       else if (unformat (input, "p %d w %d", &p, &w))
12992         {
12993           if (!curr_rloc)
12994             {
12995               errmsg ("No RLOC configured for setting priority/weight!");
12996               return -99;
12997             }
12998           curr_rloc->priority = p;
12999           curr_rloc->weight = w;
13000         }
13001       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13002                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13003         {
13004           rloc.is_ip4 = 1;
13005
13006           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13007           rloc.priority = rloc.weight = 0;
13008           vec_add1 (lcl_locs, rloc);
13009
13010           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13011           vec_add1 (rmt_locs, rloc);
13012           /* priority and weight saved in rmt loc */
13013           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13014         }
13015       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13016                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13017         {
13018           rloc.is_ip4 = 0;
13019           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13020           rloc.priority = rloc.weight = 0;
13021           vec_add1 (lcl_locs, rloc);
13022
13023           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13024           vec_add1 (rmt_locs, rloc);
13025           /* priority and weight saved in rmt loc */
13026           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13027         }
13028       else if (unformat (input, "action %d", &action))
13029         {
13030           ;
13031         }
13032       else
13033         {
13034           clib_warning ("parse error '%U'", format_unformat_error, input);
13035           return -99;
13036         }
13037     }
13038
13039   if (!rmt_eid_set)
13040     {
13041       errmsg ("remote eid addresses not set\n");
13042       return -99;
13043     }
13044
13045   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13046     {
13047       errmsg ("eid types don't match\n");
13048       return -99;
13049     }
13050
13051   if (0 == rmt_locs && (u32) ~ 0 == action)
13052     {
13053       errmsg ("action not set for negative mapping\n");
13054       return -99;
13055     }
13056
13057   /* Construct the API message */
13058   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13059
13060   mp->is_add = is_add;
13061   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13062   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13063   mp->eid_type = rmt_eid->type;
13064   mp->rmt_len = rmt_eid->len;
13065   mp->lcl_len = lcl_eid->len;
13066   mp->action = action;
13067
13068   if (0 != rmt_locs && 0 != lcl_locs)
13069     {
13070       mp->loc_num = vec_len (rmt_locs);
13071       clib_memcpy (mp->lcl_locs, lcl_locs,
13072                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13073       clib_memcpy (mp->rmt_locs, rmt_locs,
13074                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13075     }
13076   vec_free (lcl_locs);
13077   vec_free (rmt_locs);
13078
13079   /* send it... */
13080   S;
13081
13082   /* Wait for a reply... */
13083   W;
13084
13085   /* NOTREACHED */
13086   return 0;
13087 }
13088
13089 static int
13090 api_lisp_add_del_map_resolver (vat_main_t * vam)
13091 {
13092   unformat_input_t *input = vam->input;
13093   vl_api_lisp_add_del_map_resolver_t *mp;
13094   f64 timeout = ~0;
13095   u8 is_add = 1;
13096   u8 ipv4_set = 0;
13097   u8 ipv6_set = 0;
13098   ip4_address_t ipv4;
13099   ip6_address_t ipv6;
13100
13101   /* Parse args required to build the message */
13102   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13103     {
13104       if (unformat (input, "del"))
13105         {
13106           is_add = 0;
13107         }
13108       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13109         {
13110           ipv4_set = 1;
13111         }
13112       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13113         {
13114           ipv6_set = 1;
13115         }
13116       else
13117         break;
13118     }
13119
13120   if (ipv4_set && ipv6_set)
13121     {
13122       errmsg ("both eid v4 and v6 addresses set\n");
13123       return -99;
13124     }
13125
13126   if (!ipv4_set && !ipv6_set)
13127     {
13128       errmsg ("eid addresses not set\n");
13129       return -99;
13130     }
13131
13132   /* Construct the API message */
13133   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13134
13135   mp->is_add = is_add;
13136   if (ipv6_set)
13137     {
13138       mp->is_ipv6 = 1;
13139       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13140     }
13141   else
13142     {
13143       mp->is_ipv6 = 0;
13144       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13145     }
13146
13147   /* send it... */
13148   S;
13149
13150   /* Wait for a reply... */
13151   W;
13152
13153   /* NOTREACHED */
13154   return 0;
13155 }
13156
13157 static int
13158 api_lisp_gpe_enable_disable (vat_main_t * vam)
13159 {
13160   unformat_input_t *input = vam->input;
13161   vl_api_lisp_gpe_enable_disable_t *mp;
13162   f64 timeout = ~0;
13163   u8 is_set = 0;
13164   u8 is_en = 1;
13165
13166   /* Parse args required to build the message */
13167   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13168     {
13169       if (unformat (input, "enable"))
13170         {
13171           is_set = 1;
13172           is_en = 1;
13173         }
13174       else if (unformat (input, "disable"))
13175         {
13176           is_set = 1;
13177           is_en = 0;
13178         }
13179       else
13180         break;
13181     }
13182
13183   if (is_set == 0)
13184     {
13185       errmsg ("Value not set\n");
13186       return -99;
13187     }
13188
13189   /* Construct the API message */
13190   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13191
13192   mp->is_en = is_en;
13193
13194   /* send it... */
13195   S;
13196
13197   /* Wait for a reply... */
13198   W;
13199
13200   /* NOTREACHED */
13201   return 0;
13202 }
13203
13204 static int
13205 api_lisp_enable_disable (vat_main_t * vam)
13206 {
13207   unformat_input_t *input = vam->input;
13208   vl_api_lisp_enable_disable_t *mp;
13209   f64 timeout = ~0;
13210   u8 is_set = 0;
13211   u8 is_en = 0;
13212
13213   /* Parse args required to build the message */
13214   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13215     {
13216       if (unformat (input, "enable"))
13217         {
13218           is_set = 1;
13219           is_en = 1;
13220         }
13221       else if (unformat (input, "disable"))
13222         {
13223           is_set = 1;
13224         }
13225       else
13226         break;
13227     }
13228
13229   if (!is_set)
13230     {
13231       errmsg ("Value not set\n");
13232       return -99;
13233     }
13234
13235   /* Construct the API message */
13236   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13237
13238   mp->is_en = is_en;
13239
13240   /* send it... */
13241   S;
13242
13243   /* Wait for a reply... */
13244   W;
13245
13246   /* NOTREACHED */
13247   return 0;
13248 }
13249
13250 static int
13251 api_show_lisp_map_request_mode (vat_main_t * vam)
13252 {
13253   f64 timeout = ~0;
13254   vl_api_show_lisp_map_request_mode_t *mp;
13255
13256   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13257
13258   /* send */
13259   S;
13260
13261   /* wait for reply */
13262   W;
13263
13264   return 0;
13265 }
13266
13267 static int
13268 api_lisp_map_request_mode (vat_main_t * vam)
13269 {
13270   f64 timeout = ~0;
13271   unformat_input_t *input = vam->input;
13272   vl_api_lisp_map_request_mode_t *mp;
13273   u8 mode = 0;
13274
13275   /* Parse args required to build the message */
13276   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13277     {
13278       if (unformat (input, "dst-only"))
13279         mode = 0;
13280       else if (unformat (input, "src-dst"))
13281         mode = 1;
13282       else
13283         {
13284           errmsg ("parse error '%U'", format_unformat_error, input);
13285           return -99;
13286         }
13287     }
13288
13289   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13290
13291   mp->mode = mode;
13292
13293   /* send */
13294   S;
13295
13296   /* wait for reply */
13297   W;
13298
13299   /* notreached */
13300   return 0;
13301 }
13302
13303 /**
13304  * Enable/disable LISP proxy ITR.
13305  *
13306  * @param vam vpp API test context
13307  * @return return code
13308  */
13309 static int
13310 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13311 {
13312   f64 timeout = ~0;
13313   u8 ls_name_set = 0;
13314   unformat_input_t *input = vam->input;
13315   vl_api_lisp_pitr_set_locator_set_t *mp;
13316   u8 is_add = 1;
13317   u8 *ls_name = 0;
13318
13319   /* Parse args required to build the message */
13320   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13321     {
13322       if (unformat (input, "del"))
13323         is_add = 0;
13324       else if (unformat (input, "locator-set %s", &ls_name))
13325         ls_name_set = 1;
13326       else
13327         {
13328           errmsg ("parse error '%U'", format_unformat_error, input);
13329           return -99;
13330         }
13331     }
13332
13333   if (!ls_name_set)
13334     {
13335       errmsg ("locator-set name not set!");
13336       return -99;
13337     }
13338
13339   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13340
13341   mp->is_add = is_add;
13342   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13343   vec_free (ls_name);
13344
13345   /* send */
13346   S;
13347
13348   /* wait for reply */
13349   W;
13350
13351   /* notreached */
13352   return 0;
13353 }
13354
13355 static int
13356 api_show_lisp_pitr (vat_main_t * vam)
13357 {
13358   vl_api_show_lisp_pitr_t *mp;
13359   f64 timeout = ~0;
13360
13361   if (!vam->json_output)
13362     {
13363       fformat (vam->ofp, "%=20s\n", "lisp status:");
13364     }
13365
13366   M (SHOW_LISP_PITR, show_lisp_pitr);
13367   /* send it... */
13368   S;
13369
13370   /* Wait for a reply... */
13371   W;
13372
13373   /* NOTREACHED */
13374   return 0;
13375 }
13376
13377 /**
13378  * Add/delete mapping between vni and vrf
13379  */
13380 static int
13381 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13382 {
13383   f64 timeout = ~0;
13384   unformat_input_t *input = vam->input;
13385   vl_api_lisp_eid_table_add_del_map_t *mp;
13386   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13387   u32 vni, vrf, bd_index;
13388
13389   /* Parse args required to build the message */
13390   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13391     {
13392       if (unformat (input, "del"))
13393         is_add = 0;
13394       else if (unformat (input, "vrf %d", &vrf))
13395         vrf_set = 1;
13396       else if (unformat (input, "bd_index %d", &bd_index))
13397         bd_index_set = 1;
13398       else if (unformat (input, "vni %d", &vni))
13399         vni_set = 1;
13400       else
13401         break;
13402     }
13403
13404   if (!vni_set || (!vrf_set && !bd_index_set))
13405     {
13406       errmsg ("missing arguments!");
13407       return -99;
13408     }
13409
13410   if (vrf_set && bd_index_set)
13411     {
13412       errmsg ("error: both vrf and bd entered!");
13413       return -99;
13414     }
13415
13416   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13417
13418   mp->is_add = is_add;
13419   mp->vni = htonl (vni);
13420   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13421   mp->is_l2 = bd_index_set;
13422
13423   /* send */
13424   S;
13425
13426   /* wait for reply */
13427   W;
13428
13429   /* notreached */
13430   return 0;
13431 }
13432
13433 uword
13434 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13435 {
13436   u32 *action = va_arg (*args, u32 *);
13437   u8 *s = 0;
13438
13439   if (unformat (input, "%s", &s))
13440     {
13441       if (!strcmp ((char *) s, "no-action"))
13442         action[0] = 0;
13443       else if (!strcmp ((char *) s, "natively-forward"))
13444         action[0] = 1;
13445       else if (!strcmp ((char *) s, "send-map-request"))
13446         action[0] = 2;
13447       else if (!strcmp ((char *) s, "drop"))
13448         action[0] = 3;
13449       else
13450         {
13451           clib_warning ("invalid action: '%s'", s);
13452           action[0] = 3;
13453         }
13454     }
13455   else
13456     return 0;
13457
13458   vec_free (s);
13459   return 1;
13460 }
13461
13462 /**
13463  * Add/del remote mapping to/from LISP control plane
13464  *
13465  * @param vam vpp API test context
13466  * @return return code
13467  */
13468 static int
13469 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13470 {
13471   unformat_input_t *input = vam->input;
13472   vl_api_lisp_add_del_remote_mapping_t *mp;
13473   f64 timeout = ~0;
13474   u32 vni = 0;
13475   lisp_eid_vat_t _eid, *eid = &_eid;
13476   lisp_eid_vat_t _seid, *seid = &_seid;
13477   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13478   u32 action = ~0, p, w, data_len;
13479   ip4_address_t rloc4;
13480   ip6_address_t rloc6;
13481   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13482
13483   memset (&rloc, 0, sizeof (rloc));
13484
13485   /* Parse args required to build the message */
13486   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13487     {
13488       if (unformat (input, "del-all"))
13489         {
13490           del_all = 1;
13491         }
13492       else if (unformat (input, "del"))
13493         {
13494           is_add = 0;
13495         }
13496       else if (unformat (input, "add"))
13497         {
13498           is_add = 1;
13499         }
13500       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13501         {
13502           eid_set = 1;
13503         }
13504       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13505         {
13506           seid_set = 1;
13507         }
13508       else if (unformat (input, "vni %d", &vni))
13509         {
13510           ;
13511         }
13512       else if (unformat (input, "p %d w %d", &p, &w))
13513         {
13514           if (!curr_rloc)
13515             {
13516               errmsg ("No RLOC configured for setting priority/weight!");
13517               return -99;
13518             }
13519           curr_rloc->priority = p;
13520           curr_rloc->weight = w;
13521         }
13522       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13523         {
13524           rloc.is_ip4 = 1;
13525           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13526           vec_add1 (rlocs, rloc);
13527           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13528         }
13529       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13530         {
13531           rloc.is_ip4 = 0;
13532           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13533           vec_add1 (rlocs, rloc);
13534           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13535         }
13536       else if (unformat (input, "action %U",
13537                          unformat_negative_mapping_action, &action))
13538         {
13539           ;
13540         }
13541       else
13542         {
13543           clib_warning ("parse error '%U'", format_unformat_error, input);
13544           return -99;
13545         }
13546     }
13547
13548   if (0 == eid_set)
13549     {
13550       errmsg ("missing params!");
13551       return -99;
13552     }
13553
13554   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13555     {
13556       errmsg ("no action set for negative map-reply!");
13557       return -99;
13558     }
13559
13560   data_len = vec_len (rlocs) * sizeof (rloc_t);
13561
13562   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13563   mp->is_add = is_add;
13564   mp->vni = htonl (vni);
13565   mp->action = (u8) action;
13566   mp->is_src_dst = seid_set;
13567   mp->eid_len = eid->len;
13568   mp->seid_len = seid->len;
13569   mp->del_all = del_all;
13570   mp->eid_type = eid->type;
13571   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13572   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13573
13574   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13575   clib_memcpy (mp->rlocs, rlocs, data_len);
13576   vec_free (rlocs);
13577
13578   /* send it... */
13579   S;
13580
13581   /* Wait for a reply... */
13582   W;
13583
13584   /* NOTREACHED */
13585   return 0;
13586 }
13587
13588 /**
13589  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13590  * forwarding entries in data-plane accordingly.
13591  *
13592  * @param vam vpp API test context
13593  * @return return code
13594  */
13595 static int
13596 api_lisp_add_del_adjacency (vat_main_t * vam)
13597 {
13598   unformat_input_t *input = vam->input;
13599   vl_api_lisp_add_del_adjacency_t *mp;
13600   f64 timeout = ~0;
13601   u32 vni = 0;
13602   ip4_address_t leid4, reid4;
13603   ip6_address_t leid6, reid6;
13604   u8 reid_mac[6] = { 0 };
13605   u8 leid_mac[6] = { 0 };
13606   u8 reid_type, leid_type;
13607   u32 leid_len = 0, reid_len = 0, len;
13608   u8 is_add = 1;
13609
13610   leid_type = reid_type = (u8) ~ 0;
13611
13612   /* Parse args required to build the message */
13613   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13614     {
13615       if (unformat (input, "del"))
13616         {
13617           is_add = 0;
13618         }
13619       else if (unformat (input, "add"))
13620         {
13621           is_add = 1;
13622         }
13623       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13624                          &reid4, &len))
13625         {
13626           reid_type = 0;        /* ipv4 */
13627           reid_len = len;
13628         }
13629       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13630                          &reid6, &len))
13631         {
13632           reid_type = 1;        /* ipv6 */
13633           reid_len = len;
13634         }
13635       else if (unformat (input, "reid %U", unformat_ethernet_address,
13636                          reid_mac))
13637         {
13638           reid_type = 2;        /* mac */
13639         }
13640       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13641                          &leid4, &len))
13642         {
13643           leid_type = 0;        /* ipv4 */
13644           leid_len = len;
13645         }
13646       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13647                          &leid6, &len))
13648         {
13649           leid_type = 1;        /* ipv6 */
13650           leid_len = len;
13651         }
13652       else if (unformat (input, "leid %U", unformat_ethernet_address,
13653                          leid_mac))
13654         {
13655           leid_type = 2;        /* mac */
13656         }
13657       else if (unformat (input, "vni %d", &vni))
13658         {
13659           ;
13660         }
13661       else
13662         {
13663           errmsg ("parse error '%U'", format_unformat_error, input);
13664           return -99;
13665         }
13666     }
13667
13668   if ((u8) ~ 0 == reid_type)
13669     {
13670       errmsg ("missing params!");
13671       return -99;
13672     }
13673
13674   if (leid_type != reid_type)
13675     {
13676       errmsg ("remote and local EIDs are of different types!");
13677       return -99;
13678     }
13679
13680   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13681   mp->is_add = is_add;
13682   mp->vni = htonl (vni);
13683   mp->leid_len = leid_len;
13684   mp->reid_len = reid_len;
13685   mp->eid_type = reid_type;
13686
13687   switch (mp->eid_type)
13688     {
13689     case 0:
13690       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13691       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13692       break;
13693     case 1:
13694       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13695       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13696       break;
13697     case 2:
13698       clib_memcpy (mp->leid, leid_mac, 6);
13699       clib_memcpy (mp->reid, reid_mac, 6);
13700       break;
13701     default:
13702       errmsg ("unknown EID type %d!", mp->eid_type);
13703       return 0;
13704     }
13705
13706   /* send it... */
13707   S;
13708
13709   /* Wait for a reply... */
13710   W;
13711
13712   /* NOTREACHED */
13713   return 0;
13714 }
13715
13716 static int
13717 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13718 {
13719   unformat_input_t *input = vam->input;
13720   vl_api_lisp_gpe_add_del_iface_t *mp;
13721   f64 timeout = ~0;
13722   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13723   u32 dp_table = 0, vni = 0;
13724
13725   /* Parse args required to build the message */
13726   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13727     {
13728       if (unformat (input, "up"))
13729         {
13730           action_set = 1;
13731           is_add = 1;
13732         }
13733       else if (unformat (input, "down"))
13734         {
13735           action_set = 1;
13736           is_add = 0;
13737         }
13738       else if (unformat (input, "table_id %d", &dp_table))
13739         {
13740           dp_table_set = 1;
13741         }
13742       else if (unformat (input, "bd_id %d", &dp_table))
13743         {
13744           dp_table_set = 1;
13745           is_l2 = 1;
13746         }
13747       else if (unformat (input, "vni %d", &vni))
13748         {
13749           vni_set = 1;
13750         }
13751       else
13752         break;
13753     }
13754
13755   if (action_set == 0)
13756     {
13757       errmsg ("Action not set\n");
13758       return -99;
13759     }
13760   if (dp_table_set == 0 || vni_set == 0)
13761     {
13762       errmsg ("vni and dp_table must be set\n");
13763       return -99;
13764     }
13765
13766   /* Construct the API message */
13767   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13768
13769   mp->is_add = is_add;
13770   mp->dp_table = dp_table;
13771   mp->is_l2 = is_l2;
13772   mp->vni = vni;
13773
13774   /* send it... */
13775   S;
13776
13777   /* Wait for a reply... */
13778   W;
13779
13780   /* NOTREACHED */
13781   return 0;
13782 }
13783
13784 /**
13785  * Add/del map request itr rlocs from LISP control plane and updates
13786  *
13787  * @param vam vpp API test context
13788  * @return return code
13789  */
13790 static int
13791 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13792 {
13793   unformat_input_t *input = vam->input;
13794   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13795   f64 timeout = ~0;
13796   u8 *locator_set_name = 0;
13797   u8 locator_set_name_set = 0;
13798   u8 is_add = 1;
13799
13800   /* Parse args required to build the message */
13801   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13802     {
13803       if (unformat (input, "del"))
13804         {
13805           is_add = 0;
13806         }
13807       else if (unformat (input, "%_%v%_", &locator_set_name))
13808         {
13809           locator_set_name_set = 1;
13810         }
13811       else
13812         {
13813           clib_warning ("parse error '%U'", format_unformat_error, input);
13814           return -99;
13815         }
13816     }
13817
13818   if (is_add && !locator_set_name_set)
13819     {
13820       errmsg ("itr-rloc is not set!");
13821       return -99;
13822     }
13823
13824   if (is_add && vec_len (locator_set_name) > 64)
13825     {
13826       errmsg ("itr-rloc locator-set name too long\n");
13827       vec_free (locator_set_name);
13828       return -99;
13829     }
13830
13831   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13832   mp->is_add = is_add;
13833   if (is_add)
13834     {
13835       clib_memcpy (mp->locator_set_name, locator_set_name,
13836                    vec_len (locator_set_name));
13837     }
13838   else
13839     {
13840       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13841     }
13842   vec_free (locator_set_name);
13843
13844   /* send it... */
13845   S;
13846
13847   /* Wait for a reply... */
13848   W;
13849
13850   /* NOTREACHED */
13851   return 0;
13852 }
13853
13854 static int
13855 api_lisp_locator_dump (vat_main_t * vam)
13856 {
13857   unformat_input_t *input = vam->input;
13858   vl_api_lisp_locator_dump_t *mp;
13859   f64 timeout = ~0;
13860   u8 is_index_set = 0, is_name_set = 0;
13861   u8 *ls_name = 0;
13862   u32 ls_index = ~0;
13863
13864   /* Parse args required to build the message */
13865   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13866     {
13867       if (unformat (input, "ls_name %_%v%_", &ls_name))
13868         {
13869           is_name_set = 1;
13870         }
13871       else if (unformat (input, "ls_index %d", &ls_index))
13872         {
13873           is_index_set = 1;
13874         }
13875       else
13876         {
13877           errmsg ("parse error '%U'", format_unformat_error, input);
13878           return -99;
13879         }
13880     }
13881
13882   if (!is_index_set && !is_name_set)
13883     {
13884       errmsg ("error: expected one of index or name!\n");
13885       return -99;
13886     }
13887
13888   if (is_index_set && is_name_set)
13889     {
13890       errmsg ("error: only one param expected!\n");
13891       return -99;
13892     }
13893
13894   if (vec_len (ls_name) > 62)
13895     {
13896       errmsg ("error: locator set name too long!");
13897       return -99;
13898     }
13899
13900   if (!vam->json_output)
13901     {
13902       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13903                "weight");
13904     }
13905
13906   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13907   mp->is_index_set = is_index_set;
13908
13909   if (is_index_set)
13910     mp->ls_index = clib_host_to_net_u32 (ls_index);
13911   else
13912     {
13913       vec_add1 (ls_name, 0);
13914       strncpy ((char *) mp->ls_name, (char *) ls_name,
13915                sizeof (mp->ls_name) - 1);
13916     }
13917
13918   /* send it... */
13919   S;
13920
13921   /* Use a control ping for synchronization */
13922   {
13923     vl_api_control_ping_t *mp;
13924     M (CONTROL_PING, control_ping);
13925     S;
13926   }
13927   /* Wait for a reply... */
13928   W;
13929
13930   /* NOTREACHED */
13931   return 0;
13932 }
13933
13934 static int
13935 api_lisp_locator_set_dump (vat_main_t * vam)
13936 {
13937   vl_api_lisp_locator_set_dump_t *mp;
13938   unformat_input_t *input = vam->input;
13939   f64 timeout = ~0;
13940   u8 filter = 0;
13941
13942   /* Parse args required to build the message */
13943   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13944     {
13945       if (unformat (input, "local"))
13946         {
13947           filter = 1;
13948         }
13949       else if (unformat (input, "remote"))
13950         {
13951           filter = 2;
13952         }
13953       else
13954         {
13955           errmsg ("parse error '%U'", format_unformat_error, input);
13956           return -99;
13957         }
13958     }
13959
13960   if (!vam->json_output)
13961     {
13962       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13963     }
13964
13965   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13966
13967   mp->filter = filter;
13968
13969   /* send it... */
13970   S;
13971
13972   /* Use a control ping for synchronization */
13973   {
13974     vl_api_control_ping_t *mp;
13975     M (CONTROL_PING, control_ping);
13976     S;
13977   }
13978   /* Wait for a reply... */
13979   W;
13980
13981   /* NOTREACHED */
13982   return 0;
13983 }
13984
13985 static int
13986 api_lisp_eid_table_map_dump (vat_main_t * vam)
13987 {
13988   u8 is_l2 = 0;
13989   u8 mode_set = 0;
13990   unformat_input_t *input = vam->input;
13991   vl_api_lisp_eid_table_map_dump_t *mp;
13992   f64 timeout = ~0;
13993
13994   /* Parse args required to build the message */
13995   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13996     {
13997       if (unformat (input, "l2"))
13998         {
13999           is_l2 = 1;
14000           mode_set = 1;
14001         }
14002       else if (unformat (input, "l3"))
14003         {
14004           is_l2 = 0;
14005           mode_set = 1;
14006         }
14007       else
14008         {
14009           errmsg ("parse error '%U'", format_unformat_error, input);
14010           return -99;
14011         }
14012     }
14013
14014   if (!mode_set)
14015     {
14016       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
14017       return -99;
14018     }
14019
14020   if (!vam->json_output)
14021     {
14022       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
14023     }
14024
14025   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14026   mp->is_l2 = is_l2;
14027
14028   /* send it... */
14029   S;
14030
14031   /* Use a control ping for synchronization */
14032   {
14033     vl_api_control_ping_t *mp;
14034     M (CONTROL_PING, control_ping);
14035     S;
14036   }
14037   /* Wait for a reply... */
14038   W;
14039
14040   /* NOTREACHED */
14041   return 0;
14042 }
14043
14044 static int
14045 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14046 {
14047   vl_api_lisp_eid_table_vni_dump_t *mp;
14048   f64 timeout = ~0;
14049
14050   if (!vam->json_output)
14051     {
14052       fformat (vam->ofp, "VNI\n");
14053     }
14054
14055   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14056
14057   /* send it... */
14058   S;
14059
14060   /* Use a control ping for synchronization */
14061   {
14062     vl_api_control_ping_t *mp;
14063     M (CONTROL_PING, control_ping);
14064     S;
14065   }
14066   /* Wait for a reply... */
14067   W;
14068
14069   /* NOTREACHED */
14070   return 0;
14071 }
14072
14073 static int
14074 api_lisp_eid_table_dump (vat_main_t * vam)
14075 {
14076   unformat_input_t *i = vam->input;
14077   vl_api_lisp_eid_table_dump_t *mp;
14078   f64 timeout = ~0;
14079   struct in_addr ip4;
14080   struct in6_addr ip6;
14081   u8 mac[6];
14082   u8 eid_type = ~0, eid_set = 0;
14083   u32 prefix_length = ~0, t, vni = 0;
14084   u8 filter = 0;
14085
14086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14087     {
14088       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14089         {
14090           eid_set = 1;
14091           eid_type = 0;
14092           prefix_length = t;
14093         }
14094       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14095         {
14096           eid_set = 1;
14097           eid_type = 1;
14098           prefix_length = t;
14099         }
14100       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14101         {
14102           eid_set = 1;
14103           eid_type = 2;
14104         }
14105       else if (unformat (i, "vni %d", &t))
14106         {
14107           vni = t;
14108         }
14109       else if (unformat (i, "local"))
14110         {
14111           filter = 1;
14112         }
14113       else if (unformat (i, "remote"))
14114         {
14115           filter = 2;
14116         }
14117       else
14118         {
14119           errmsg ("parse error '%U'", format_unformat_error, i);
14120           return -99;
14121         }
14122     }
14123
14124   if (!vam->json_output)
14125     {
14126       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
14127                "ls_index", "ttl", "authoritative");
14128     }
14129
14130   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14131
14132   mp->filter = filter;
14133   if (eid_set)
14134     {
14135       mp->eid_set = 1;
14136       mp->vni = htonl (vni);
14137       mp->eid_type = eid_type;
14138       switch (eid_type)
14139         {
14140         case 0:
14141           mp->prefix_length = prefix_length;
14142           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14143           break;
14144         case 1:
14145           mp->prefix_length = prefix_length;
14146           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14147           break;
14148         case 2:
14149           clib_memcpy (mp->eid, mac, sizeof (mac));
14150           break;
14151         default:
14152           errmsg ("unknown EID type %d!", eid_type);
14153           return -99;
14154         }
14155     }
14156
14157   /* send it... */
14158   S;
14159
14160   /* Use a control ping for synchronization */
14161   {
14162     vl_api_control_ping_t *mp;
14163     M (CONTROL_PING, control_ping);
14164     S;
14165   }
14166
14167   /* Wait for a reply... */
14168   W;
14169
14170   /* NOTREACHED */
14171   return 0;
14172 }
14173
14174 static int
14175 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14176 {
14177   vl_api_lisp_gpe_tunnel_dump_t *mp;
14178   f64 timeout = ~0;
14179
14180   if (!vam->json_output)
14181     {
14182       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14183                "%=16s%=16s%=16s%=16s%=16s\n",
14184                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14185                "Decap next", "Lisp version", "Flags", "Next protocol",
14186                "ver_res", "res", "iid");
14187     }
14188
14189   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14190   /* send it... */
14191   S;
14192
14193   /* Use a control ping for synchronization */
14194   {
14195     vl_api_control_ping_t *mp;
14196     M (CONTROL_PING, control_ping);
14197     S;
14198   }
14199   /* Wait for a reply... */
14200   W;
14201
14202   /* NOTREACHED */
14203   return 0;
14204 }
14205
14206 static int
14207 api_lisp_adjacencies_get (vat_main_t * vam)
14208 {
14209   unformat_input_t *i = vam->input;
14210   vl_api_lisp_adjacencies_get_t *mp;
14211   f64 timeout = ~0;
14212   u8 vni_set = 0;
14213   u32 vni = ~0;
14214
14215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14216     {
14217       if (unformat (i, "vni %d", &vni))
14218         {
14219           vni_set = 1;
14220         }
14221       else
14222         {
14223           errmsg ("parse error '%U'\n", format_unformat_error, i);
14224           return -99;
14225         }
14226     }
14227
14228   if (!vni_set)
14229     {
14230       errmsg ("vni not set!\n");
14231       return -99;
14232     }
14233
14234   if (!vam->json_output)
14235     {
14236       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14237     }
14238
14239   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14240   mp->vni = clib_host_to_net_u32 (vni);
14241
14242   /* send it... */
14243   S;
14244
14245   /* Wait for a reply... */
14246   W;
14247
14248   /* NOTREACHED */
14249   return 0;
14250 }
14251
14252 static int
14253 api_lisp_map_resolver_dump (vat_main_t * vam)
14254 {
14255   vl_api_lisp_map_resolver_dump_t *mp;
14256   f64 timeout = ~0;
14257
14258   if (!vam->json_output)
14259     {
14260       fformat (vam->ofp, "%=20s\n", "Map resolver");
14261     }
14262
14263   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14264   /* send it... */
14265   S;
14266
14267   /* Use a control ping for synchronization */
14268   {
14269     vl_api_control_ping_t *mp;
14270     M (CONTROL_PING, control_ping);
14271     S;
14272   }
14273   /* Wait for a reply... */
14274   W;
14275
14276   /* NOTREACHED */
14277   return 0;
14278 }
14279
14280 static int
14281 api_show_lisp_status (vat_main_t * vam)
14282 {
14283   vl_api_show_lisp_status_t *mp;
14284   f64 timeout = ~0;
14285
14286   if (!vam->json_output)
14287     {
14288       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14289     }
14290
14291   M (SHOW_LISP_STATUS, show_lisp_status);
14292   /* send it... */
14293   S;
14294   /* Wait for a reply... */
14295   W;
14296
14297   /* NOTREACHED */
14298   return 0;
14299 }
14300
14301 static int
14302 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14303 {
14304   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14305   f64 timeout = ~0;
14306
14307   if (!vam->json_output)
14308     {
14309       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14310     }
14311
14312   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14313   /* send it... */
14314   S;
14315   /* Wait for a reply... */
14316   W;
14317
14318   /* NOTREACHED */
14319   return 0;
14320 }
14321
14322 static int
14323 api_af_packet_create (vat_main_t * vam)
14324 {
14325   unformat_input_t *i = vam->input;
14326   vl_api_af_packet_create_t *mp;
14327   f64 timeout;
14328   u8 *host_if_name = 0;
14329   u8 hw_addr[6];
14330   u8 random_hw_addr = 1;
14331
14332   memset (hw_addr, 0, sizeof (hw_addr));
14333
14334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14335     {
14336       if (unformat (i, "name %s", &host_if_name))
14337         vec_add1 (host_if_name, 0);
14338       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14339         random_hw_addr = 0;
14340       else
14341         break;
14342     }
14343
14344   if (!vec_len (host_if_name))
14345     {
14346       errmsg ("host-interface name must be specified");
14347       return -99;
14348     }
14349
14350   if (vec_len (host_if_name) > 64)
14351     {
14352       errmsg ("host-interface name too long");
14353       return -99;
14354     }
14355
14356   M (AF_PACKET_CREATE, af_packet_create);
14357
14358   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14359   clib_memcpy (mp->hw_addr, hw_addr, 6);
14360   mp->use_random_hw_addr = random_hw_addr;
14361   vec_free (host_if_name);
14362
14363   S;
14364   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14365   /* NOTREACHED */
14366   return 0;
14367 }
14368
14369 static int
14370 api_af_packet_delete (vat_main_t * vam)
14371 {
14372   unformat_input_t *i = vam->input;
14373   vl_api_af_packet_delete_t *mp;
14374   f64 timeout;
14375   u8 *host_if_name = 0;
14376
14377   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14378     {
14379       if (unformat (i, "name %s", &host_if_name))
14380         vec_add1 (host_if_name, 0);
14381       else
14382         break;
14383     }
14384
14385   if (!vec_len (host_if_name))
14386     {
14387       errmsg ("host-interface name must be specified");
14388       return -99;
14389     }
14390
14391   if (vec_len (host_if_name) > 64)
14392     {
14393       errmsg ("host-interface name too long");
14394       return -99;
14395     }
14396
14397   M (AF_PACKET_DELETE, af_packet_delete);
14398
14399   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14400   vec_free (host_if_name);
14401
14402   S;
14403   W;
14404   /* NOTREACHED */
14405   return 0;
14406 }
14407
14408 static int
14409 api_policer_add_del (vat_main_t * vam)
14410 {
14411   unformat_input_t *i = vam->input;
14412   vl_api_policer_add_del_t *mp;
14413   f64 timeout;
14414   u8 is_add = 1;
14415   u8 *name = 0;
14416   u32 cir = 0;
14417   u32 eir = 0;
14418   u64 cb = 0;
14419   u64 eb = 0;
14420   u8 rate_type = 0;
14421   u8 round_type = 0;
14422   u8 type = 0;
14423   u8 color_aware = 0;
14424   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14425
14426   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14427   conform_action.dscp = 0;
14428   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14429   exceed_action.dscp = 0;
14430   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14431   violate_action.dscp = 0;
14432
14433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14434     {
14435       if (unformat (i, "del"))
14436         is_add = 0;
14437       else if (unformat (i, "name %s", &name))
14438         vec_add1 (name, 0);
14439       else if (unformat (i, "cir %u", &cir))
14440         ;
14441       else if (unformat (i, "eir %u", &eir))
14442         ;
14443       else if (unformat (i, "cb %u", &cb))
14444         ;
14445       else if (unformat (i, "eb %u", &eb))
14446         ;
14447       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14448                          &rate_type))
14449         ;
14450       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14451                          &round_type))
14452         ;
14453       else if (unformat (i, "type %U", unformat_policer_type, &type))
14454         ;
14455       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14456                          &conform_action))
14457         ;
14458       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14459                          &exceed_action))
14460         ;
14461       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14462                          &violate_action))
14463         ;
14464       else if (unformat (i, "color-aware"))
14465         color_aware = 1;
14466       else
14467         break;
14468     }
14469
14470   if (!vec_len (name))
14471     {
14472       errmsg ("policer name must be specified");
14473       return -99;
14474     }
14475
14476   if (vec_len (name) > 64)
14477     {
14478       errmsg ("policer name too long");
14479       return -99;
14480     }
14481
14482   M (POLICER_ADD_DEL, policer_add_del);
14483
14484   clib_memcpy (mp->name, name, vec_len (name));
14485   vec_free (name);
14486   mp->is_add = is_add;
14487   mp->cir = cir;
14488   mp->eir = eir;
14489   mp->cb = cb;
14490   mp->eb = eb;
14491   mp->rate_type = rate_type;
14492   mp->round_type = round_type;
14493   mp->type = type;
14494   mp->conform_action_type = conform_action.action_type;
14495   mp->conform_dscp = conform_action.dscp;
14496   mp->exceed_action_type = exceed_action.action_type;
14497   mp->exceed_dscp = exceed_action.dscp;
14498   mp->violate_action_type = violate_action.action_type;
14499   mp->violate_dscp = violate_action.dscp;
14500   mp->color_aware = color_aware;
14501
14502   S;
14503   W;
14504   /* NOTREACHED */
14505   return 0;
14506 }
14507
14508 static int
14509 api_policer_dump (vat_main_t * vam)
14510 {
14511   unformat_input_t *i = vam->input;
14512   vl_api_policer_dump_t *mp;
14513   f64 timeout = ~0;
14514   u8 *match_name = 0;
14515   u8 match_name_valid = 0;
14516
14517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14518     {
14519       if (unformat (i, "name %s", &match_name))
14520         {
14521           vec_add1 (match_name, 0);
14522           match_name_valid = 1;
14523         }
14524       else
14525         break;
14526     }
14527
14528   M (POLICER_DUMP, policer_dump);
14529   mp->match_name_valid = match_name_valid;
14530   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14531   vec_free (match_name);
14532   /* send it... */
14533   S;
14534
14535   /* Use a control ping for synchronization */
14536   {
14537     vl_api_control_ping_t *mp;
14538     M (CONTROL_PING, control_ping);
14539     S;
14540   }
14541   /* Wait for a reply... */
14542   W;
14543
14544   /* NOTREACHED */
14545   return 0;
14546 }
14547
14548 static int
14549 api_policer_classify_set_interface (vat_main_t * vam)
14550 {
14551   unformat_input_t *i = vam->input;
14552   vl_api_policer_classify_set_interface_t *mp;
14553   f64 timeout;
14554   u32 sw_if_index;
14555   int sw_if_index_set;
14556   u32 ip4_table_index = ~0;
14557   u32 ip6_table_index = ~0;
14558   u32 l2_table_index = ~0;
14559   u8 is_add = 1;
14560
14561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14562     {
14563       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14564         sw_if_index_set = 1;
14565       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14566         sw_if_index_set = 1;
14567       else if (unformat (i, "del"))
14568         is_add = 0;
14569       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14570         ;
14571       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14572         ;
14573       else if (unformat (i, "l2-table %d", &l2_table_index))
14574         ;
14575       else
14576         {
14577           clib_warning ("parse error '%U'", format_unformat_error, i);
14578           return -99;
14579         }
14580     }
14581
14582   if (sw_if_index_set == 0)
14583     {
14584       errmsg ("missing interface name or sw_if_index\n");
14585       return -99;
14586     }
14587
14588   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14589
14590   mp->sw_if_index = ntohl (sw_if_index);
14591   mp->ip4_table_index = ntohl (ip4_table_index);
14592   mp->ip6_table_index = ntohl (ip6_table_index);
14593   mp->l2_table_index = ntohl (l2_table_index);
14594   mp->is_add = is_add;
14595
14596   S;
14597   W;
14598   /* NOTREACHED */
14599   return 0;
14600 }
14601
14602 static int
14603 api_policer_classify_dump (vat_main_t * vam)
14604 {
14605   unformat_input_t *i = vam->input;
14606   vl_api_policer_classify_dump_t *mp;
14607   f64 timeout = ~0;
14608   u8 type = POLICER_CLASSIFY_N_TABLES;
14609
14610   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14611     ;
14612   else
14613     {
14614       errmsg ("classify table type must be specified\n");
14615       return -99;
14616     }
14617
14618   if (!vam->json_output)
14619     {
14620       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14621     }
14622
14623   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14624   mp->type = type;
14625   /* send it... */
14626   S;
14627
14628   /* Use a control ping for synchronization */
14629   {
14630     vl_api_control_ping_t *mp;
14631     M (CONTROL_PING, control_ping);
14632     S;
14633   }
14634   /* Wait for a reply... */
14635   W;
14636
14637   /* NOTREACHED */
14638   return 0;
14639 }
14640
14641 static int
14642 api_netmap_create (vat_main_t * vam)
14643 {
14644   unformat_input_t *i = vam->input;
14645   vl_api_netmap_create_t *mp;
14646   f64 timeout;
14647   u8 *if_name = 0;
14648   u8 hw_addr[6];
14649   u8 random_hw_addr = 1;
14650   u8 is_pipe = 0;
14651   u8 is_master = 0;
14652
14653   memset (hw_addr, 0, sizeof (hw_addr));
14654
14655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14656     {
14657       if (unformat (i, "name %s", &if_name))
14658         vec_add1 (if_name, 0);
14659       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14660         random_hw_addr = 0;
14661       else if (unformat (i, "pipe"))
14662         is_pipe = 1;
14663       else if (unformat (i, "master"))
14664         is_master = 1;
14665       else if (unformat (i, "slave"))
14666         is_master = 0;
14667       else
14668         break;
14669     }
14670
14671   if (!vec_len (if_name))
14672     {
14673       errmsg ("interface name must be specified");
14674       return -99;
14675     }
14676
14677   if (vec_len (if_name) > 64)
14678     {
14679       errmsg ("interface name too long");
14680       return -99;
14681     }
14682
14683   M (NETMAP_CREATE, netmap_create);
14684
14685   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14686   clib_memcpy (mp->hw_addr, hw_addr, 6);
14687   mp->use_random_hw_addr = random_hw_addr;
14688   mp->is_pipe = is_pipe;
14689   mp->is_master = is_master;
14690   vec_free (if_name);
14691
14692   S;
14693   W;
14694   /* NOTREACHED */
14695   return 0;
14696 }
14697
14698 static int
14699 api_netmap_delete (vat_main_t * vam)
14700 {
14701   unformat_input_t *i = vam->input;
14702   vl_api_netmap_delete_t *mp;
14703   f64 timeout;
14704   u8 *if_name = 0;
14705
14706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14707     {
14708       if (unformat (i, "name %s", &if_name))
14709         vec_add1 (if_name, 0);
14710       else
14711         break;
14712     }
14713
14714   if (!vec_len (if_name))
14715     {
14716       errmsg ("interface name must be specified");
14717       return -99;
14718     }
14719
14720   if (vec_len (if_name) > 64)
14721     {
14722       errmsg ("interface name too long");
14723       return -99;
14724     }
14725
14726   M (NETMAP_DELETE, netmap_delete);
14727
14728   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14729   vec_free (if_name);
14730
14731   S;
14732   W;
14733   /* NOTREACHED */
14734   return 0;
14735 }
14736
14737 static void vl_api_mpls_eth_tunnel_details_t_handler
14738   (vl_api_mpls_eth_tunnel_details_t * mp)
14739 {
14740   vat_main_t *vam = &vat_main;
14741   i32 i;
14742   i32 len = ntohl (mp->nlabels);
14743
14744   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14745            ntohl (mp->tunnel_index),
14746            format_ethernet_address, &mp->tunnel_dst_mac,
14747            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14748   for (i = 0; i < len; i++)
14749     {
14750       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14751     }
14752   fformat (vam->ofp, "\n");
14753   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14754            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14755 }
14756
14757 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14758   (vl_api_mpls_eth_tunnel_details_t * mp)
14759 {
14760   vat_main_t *vam = &vat_main;
14761   vat_json_node_t *node = NULL;
14762   struct in_addr ip4;
14763   i32 i;
14764   i32 len = ntohl (mp->nlabels);
14765
14766   if (VAT_JSON_ARRAY != vam->json_tree.type)
14767     {
14768       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14769       vat_json_init_array (&vam->json_tree);
14770     }
14771   node = vat_json_array_add (&vam->json_tree);
14772
14773   vat_json_init_object (node);
14774   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14775   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14776   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14777   vat_json_object_add_uint (node, "inner_fib_index",
14778                             ntohl (mp->inner_fib_index));
14779   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14780   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14781   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14782   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14783   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14784                                    format (0, "%U", format_ethernet_address,
14785                                            &mp->tunnel_dst_mac));
14786   vat_json_object_add_uint (node, "tx_sw_if_index",
14787                             ntohl (mp->tx_sw_if_index));
14788   vat_json_object_add_uint (node, "label_count", len);
14789   for (i = 0; i < len; i++)
14790     {
14791       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14792     }
14793 }
14794
14795 static int
14796 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14797 {
14798   vl_api_mpls_eth_tunnel_dump_t *mp;
14799   f64 timeout;
14800   i32 index = -1;
14801
14802   /* Parse args required to build the message */
14803   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14804     {
14805       if (!unformat (vam->input, "tunnel_index %d", &index))
14806         {
14807           index = -1;
14808           break;
14809         }
14810     }
14811
14812   fformat (vam->ofp, "  tunnel_index %d\n", index);
14813
14814   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14815   mp->tunnel_index = htonl (index);
14816   S;
14817
14818   /* Use a control ping for synchronization */
14819   {
14820     vl_api_control_ping_t *mp;
14821     M (CONTROL_PING, control_ping);
14822     S;
14823   }
14824   W;
14825 }
14826
14827 static void vl_api_mpls_fib_encap_details_t_handler
14828   (vl_api_mpls_fib_encap_details_t * mp)
14829 {
14830   vat_main_t *vam = &vat_main;
14831   i32 i;
14832   i32 len = ntohl (mp->nlabels);
14833
14834   fformat (vam->ofp, "table %d, dest %U, label ",
14835            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14836   for (i = 0; i < len; i++)
14837     {
14838       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14839     }
14840   fformat (vam->ofp, "\n");
14841 }
14842
14843 static void vl_api_mpls_fib_encap_details_t_handler_json
14844   (vl_api_mpls_fib_encap_details_t * mp)
14845 {
14846   vat_main_t *vam = &vat_main;
14847   vat_json_node_t *node = NULL;
14848   i32 i;
14849   i32 len = ntohl (mp->nlabels);
14850   struct in_addr ip4;
14851
14852   if (VAT_JSON_ARRAY != vam->json_tree.type)
14853     {
14854       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14855       vat_json_init_array (&vam->json_tree);
14856     }
14857   node = vat_json_array_add (&vam->json_tree);
14858
14859   vat_json_init_object (node);
14860   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14861   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14862   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14863   vat_json_object_add_ip4 (node, "dest", ip4);
14864   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14865   vat_json_object_add_uint (node, "label_count", len);
14866   for (i = 0; i < len; i++)
14867     {
14868       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14869     }
14870 }
14871
14872 static int
14873 api_mpls_fib_encap_dump (vat_main_t * vam)
14874 {
14875   vl_api_mpls_fib_encap_dump_t *mp;
14876   f64 timeout;
14877
14878   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14879   S;
14880
14881   /* Use a control ping for synchronization */
14882   {
14883     vl_api_control_ping_t *mp;
14884     M (CONTROL_PING, control_ping);
14885     S;
14886   }
14887   W;
14888 }
14889
14890 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
14891 #define vl_api_mpls_fib_details_t_print vl_noop_handler
14892
14893 static void
14894 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
14895 {
14896   vat_main_t *vam = &vat_main;
14897   int count = ntohl (mp->count);
14898   vl_api_fib_path_t *fp;
14899   int i;
14900
14901   fformat (vam->ofp,
14902            "table-id %d, label %u, ess_bit %u\n",
14903            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
14904   fp = mp->path;
14905   for (i = 0; i < count; i++)
14906     {
14907       if (fp->afi == IP46_TYPE_IP6)
14908         fformat (vam->ofp,
14909                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14910                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14911                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14912                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14913                  format_ip6_address, fp->next_hop);
14914       else if (fp->afi == IP46_TYPE_IP4)
14915         fformat (vam->ofp,
14916                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14917                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14918                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14919                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14920                  format_ip4_address, fp->next_hop);
14921       fp++;
14922     }
14923 }
14924
14925 static void vl_api_mpls_fib_details_t_handler_json
14926   (vl_api_mpls_fib_details_t * mp)
14927 {
14928   vat_main_t *vam = &vat_main;
14929   int count = ntohl (mp->count);
14930   vat_json_node_t *node = NULL;
14931   struct in_addr ip4;
14932   struct in6_addr ip6;
14933   vl_api_fib_path_t *fp;
14934   int i;
14935
14936   if (VAT_JSON_ARRAY != vam->json_tree.type)
14937     {
14938       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14939       vat_json_init_array (&vam->json_tree);
14940     }
14941   node = vat_json_array_add (&vam->json_tree);
14942
14943   vat_json_init_object (node);
14944   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14945   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
14946   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14947   vat_json_object_add_uint (node, "path_count", count);
14948   fp = mp->path;
14949   for (i = 0; i < count; i++)
14950     {
14951       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
14952       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
14953       vat_json_object_add_uint (node, "is_local", fp->is_local);
14954       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
14955       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
14956       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
14957       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
14958       if (fp->afi == IP46_TYPE_IP4)
14959         {
14960           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
14961           vat_json_object_add_ip4 (node, "next_hop", ip4);
14962         }
14963       else if (fp->afi == IP46_TYPE_IP6)
14964         {
14965           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
14966           vat_json_object_add_ip6 (node, "next_hop", ip6);
14967         }
14968     }
14969 }
14970
14971 static int
14972 api_mpls_fib_dump (vat_main_t * vam)
14973 {
14974   vl_api_mpls_fib_dump_t *mp;
14975   f64 timeout;
14976
14977   M (MPLS_FIB_DUMP, mpls_fib_dump);
14978   S;
14979
14980   /* Use a control ping for synchronization */
14981   {
14982     vl_api_control_ping_t *mp;
14983     M (CONTROL_PING, control_ping);
14984     S;
14985   }
14986   W;
14987 }
14988
14989 #define vl_api_ip_fib_details_t_endian vl_noop_handler
14990 #define vl_api_ip_fib_details_t_print vl_noop_handler
14991
14992 static void
14993 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
14994 {
14995   vat_main_t *vam = &vat_main;
14996   int count = ntohl (mp->count);
14997   vl_api_fib_path_t *fp;
14998   int i;
14999
15000   fformat (vam->ofp,
15001            "table-id %d, prefix %U/%d\n",
15002            ntohl (mp->table_id), format_ip4_address, mp->address,
15003            mp->address_length);
15004   fp = mp->path;
15005   for (i = 0; i < count; i++)
15006     {
15007       if (fp->afi == IP46_TYPE_IP6)
15008         fformat (vam->ofp,
15009                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15010                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15011                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15012                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15013                  format_ip6_address, fp->next_hop);
15014       else if (fp->afi == IP46_TYPE_IP4)
15015         fformat (vam->ofp,
15016                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15017                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15018                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15019                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15020                  format_ip4_address, fp->next_hop);
15021       fp++;
15022     }
15023 }
15024
15025 static void vl_api_ip_fib_details_t_handler_json
15026   (vl_api_ip_fib_details_t * mp)
15027 {
15028   vat_main_t *vam = &vat_main;
15029   int count = ntohl (mp->count);
15030   vat_json_node_t *node = NULL;
15031   struct in_addr ip4;
15032   struct in6_addr ip6;
15033   vl_api_fib_path_t *fp;
15034   int i;
15035
15036   if (VAT_JSON_ARRAY != vam->json_tree.type)
15037     {
15038       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15039       vat_json_init_array (&vam->json_tree);
15040     }
15041   node = vat_json_array_add (&vam->json_tree);
15042
15043   vat_json_init_object (node);
15044   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15045   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15046   vat_json_object_add_ip4 (node, "prefix", ip4);
15047   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15048   vat_json_object_add_uint (node, "path_count", count);
15049   fp = mp->path;
15050   for (i = 0; i < count; i++)
15051     {
15052       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15053       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15054       vat_json_object_add_uint (node, "is_local", fp->is_local);
15055       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15056       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15057       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15058       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15059       if (fp->afi == IP46_TYPE_IP4)
15060         {
15061           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15062           vat_json_object_add_ip4 (node, "next_hop", ip4);
15063         }
15064       else if (fp->afi == IP46_TYPE_IP6)
15065         {
15066           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15067           vat_json_object_add_ip6 (node, "next_hop", ip6);
15068         }
15069     }
15070 }
15071
15072 static int
15073 api_ip_fib_dump (vat_main_t * vam)
15074 {
15075   vl_api_ip_fib_dump_t *mp;
15076   f64 timeout;
15077
15078   M (IP_FIB_DUMP, ip_fib_dump);
15079   S;
15080
15081   /* Use a control ping for synchronization */
15082   {
15083     vl_api_control_ping_t *mp;
15084     M (CONTROL_PING, control_ping);
15085     S;
15086   }
15087   W;
15088 }
15089
15090 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15091 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15092
15093 static void
15094 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15095 {
15096   vat_main_t *vam = &vat_main;
15097   int count = ntohl (mp->count);
15098   vl_api_fib_path_t *fp;
15099   int i;
15100
15101   fformat (vam->ofp,
15102            "table-id %d, prefix %U/%d\n",
15103            ntohl (mp->table_id), format_ip6_address, mp->address,
15104            mp->address_length);
15105   fp = mp->path;
15106   for (i = 0; i < count; i++)
15107     {
15108       if (fp->afi == IP46_TYPE_IP6)
15109         fformat (vam->ofp,
15110                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15111                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15112                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15113                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15114                  format_ip6_address, fp->next_hop);
15115       else if (fp->afi == IP46_TYPE_IP4)
15116         fformat (vam->ofp,
15117                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15118                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15119                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15120                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15121                  format_ip4_address, fp->next_hop);
15122       fp++;
15123     }
15124 }
15125
15126 static void vl_api_ip6_fib_details_t_handler_json
15127   (vl_api_ip6_fib_details_t * mp)
15128 {
15129   vat_main_t *vam = &vat_main;
15130   int count = ntohl (mp->count);
15131   vat_json_node_t *node = NULL;
15132   struct in_addr ip4;
15133   struct in6_addr ip6;
15134   vl_api_fib_path_t *fp;
15135   int i;
15136
15137   if (VAT_JSON_ARRAY != vam->json_tree.type)
15138     {
15139       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15140       vat_json_init_array (&vam->json_tree);
15141     }
15142   node = vat_json_array_add (&vam->json_tree);
15143
15144   vat_json_init_object (node);
15145   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15146   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15147   vat_json_object_add_ip6 (node, "prefix", ip6);
15148   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15149   vat_json_object_add_uint (node, "path_count", count);
15150   fp = mp->path;
15151   for (i = 0; i < count; i++)
15152     {
15153       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15154       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15155       vat_json_object_add_uint (node, "is_local", fp->is_local);
15156       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15157       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15158       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15159       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15160       if (fp->afi == IP46_TYPE_IP4)
15161         {
15162           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15163           vat_json_object_add_ip4 (node, "next_hop", ip4);
15164         }
15165       else if (fp->afi == IP46_TYPE_IP6)
15166         {
15167           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15168           vat_json_object_add_ip6 (node, "next_hop", ip6);
15169         }
15170     }
15171 }
15172
15173 static int
15174 api_ip6_fib_dump (vat_main_t * vam)
15175 {
15176   vl_api_ip6_fib_dump_t *mp;
15177   f64 timeout;
15178
15179   M (IP6_FIB_DUMP, ip6_fib_dump);
15180   S;
15181
15182   /* Use a control ping for synchronization */
15183   {
15184     vl_api_control_ping_t *mp;
15185     M (CONTROL_PING, control_ping);
15186     S;
15187   }
15188   W;
15189 }
15190
15191 int
15192 api_classify_table_ids (vat_main_t * vam)
15193 {
15194   vl_api_classify_table_ids_t *mp;
15195   f64 timeout;
15196
15197   /* Construct the API message */
15198   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15199   mp->context = 0;
15200
15201   S;
15202   W;
15203   /* NOTREACHED */
15204   return 0;
15205 }
15206
15207 int
15208 api_classify_table_by_interface (vat_main_t * vam)
15209 {
15210   unformat_input_t *input = vam->input;
15211   vl_api_classify_table_by_interface_t *mp;
15212   f64 timeout;
15213
15214   u32 sw_if_index = ~0;
15215   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15216     {
15217       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15218         ;
15219       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15220         ;
15221       else
15222         break;
15223     }
15224   if (sw_if_index == ~0)
15225     {
15226       errmsg ("missing interface name or sw_if_index\n");
15227       return -99;
15228     }
15229
15230   /* Construct the API message */
15231   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15232   mp->context = 0;
15233   mp->sw_if_index = ntohl (sw_if_index);
15234
15235   S;
15236   W;
15237   /* NOTREACHED */
15238   return 0;
15239 }
15240
15241 int
15242 api_classify_table_info (vat_main_t * vam)
15243 {
15244   unformat_input_t *input = vam->input;
15245   vl_api_classify_table_info_t *mp;
15246   f64 timeout;
15247
15248   u32 table_id = ~0;
15249   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15250     {
15251       if (unformat (input, "table_id %d", &table_id))
15252         ;
15253       else
15254         break;
15255     }
15256   if (table_id == ~0)
15257     {
15258       errmsg ("missing table id\n");
15259       return -99;
15260     }
15261
15262   /* Construct the API message */
15263   M (CLASSIFY_TABLE_INFO, classify_table_info);
15264   mp->context = 0;
15265   mp->table_id = ntohl (table_id);
15266
15267   S;
15268   W;
15269   /* NOTREACHED */
15270   return 0;
15271 }
15272
15273 int
15274 api_classify_session_dump (vat_main_t * vam)
15275 {
15276   unformat_input_t *input = vam->input;
15277   vl_api_classify_session_dump_t *mp;
15278   f64 timeout;
15279
15280   u32 table_id = ~0;
15281   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15282     {
15283       if (unformat (input, "table_id %d", &table_id))
15284         ;
15285       else
15286         break;
15287     }
15288   if (table_id == ~0)
15289     {
15290       errmsg ("missing table id\n");
15291       return -99;
15292     }
15293
15294   /* Construct the API message */
15295   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15296   mp->context = 0;
15297   mp->table_id = ntohl (table_id);
15298   S;
15299
15300   /* Use a control ping for synchronization */
15301   {
15302     vl_api_control_ping_t *mp;
15303     M (CONTROL_PING, control_ping);
15304     S;
15305   }
15306   W;
15307   /* NOTREACHED */
15308   return 0;
15309 }
15310
15311 static void
15312 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15313 {
15314   vat_main_t *vam = &vat_main;
15315
15316   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15317            "src_address %U, vrf_id %d, path_mtu %u, "
15318            "template_interval %u, udp_checksum %d\n",
15319            format_ip4_address, mp->collector_address,
15320            ntohs (mp->collector_port),
15321            format_ip4_address, mp->src_address,
15322            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15323            ntohl (mp->template_interval), mp->udp_checksum);
15324
15325   vam->retval = 0;
15326   vam->result_ready = 1;
15327 }
15328
15329 static void
15330   vl_api_ipfix_exporter_details_t_handler_json
15331   (vl_api_ipfix_exporter_details_t * mp)
15332 {
15333   vat_main_t *vam = &vat_main;
15334   vat_json_node_t node;
15335   struct in_addr collector_address;
15336   struct in_addr src_address;
15337
15338   vat_json_init_object (&node);
15339   clib_memcpy (&collector_address, &mp->collector_address,
15340                sizeof (collector_address));
15341   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15342   vat_json_object_add_uint (&node, "collector_port",
15343                             ntohs (mp->collector_port));
15344   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15345   vat_json_object_add_ip4 (&node, "src_address", src_address);
15346   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15347   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15348   vat_json_object_add_uint (&node, "template_interval",
15349                             ntohl (mp->template_interval));
15350   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15351
15352   vat_json_print (vam->ofp, &node);
15353   vat_json_free (&node);
15354   vam->retval = 0;
15355   vam->result_ready = 1;
15356 }
15357
15358 int
15359 api_ipfix_exporter_dump (vat_main_t * vam)
15360 {
15361   vl_api_ipfix_exporter_dump_t *mp;
15362   f64 timeout;
15363
15364   /* Construct the API message */
15365   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15366   mp->context = 0;
15367
15368   S;
15369   W;
15370   /* NOTREACHED */
15371   return 0;
15372 }
15373
15374 static int
15375 api_ipfix_classify_stream_dump (vat_main_t * vam)
15376 {
15377   vl_api_ipfix_classify_stream_dump_t *mp;
15378   f64 timeout;
15379
15380   /* Construct the API message */
15381   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15382   mp->context = 0;
15383
15384   S;
15385   W;
15386   /* NOTREACHED */
15387   return 0;
15388 }
15389
15390 static void
15391   vl_api_ipfix_classify_stream_details_t_handler
15392   (vl_api_ipfix_classify_stream_details_t * mp)
15393 {
15394   vat_main_t *vam = &vat_main;
15395   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15396            ntohl (mp->domain_id), ntohs (mp->src_port));
15397   vam->retval = 0;
15398   vam->result_ready = 1;
15399 }
15400
15401 static void
15402   vl_api_ipfix_classify_stream_details_t_handler_json
15403   (vl_api_ipfix_classify_stream_details_t * mp)
15404 {
15405   vat_main_t *vam = &vat_main;
15406   vat_json_node_t node;
15407
15408   vat_json_init_object (&node);
15409   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15410   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15411
15412   vat_json_print (vam->ofp, &node);
15413   vat_json_free (&node);
15414   vam->retval = 0;
15415   vam->result_ready = 1;
15416 }
15417
15418 static int
15419 api_ipfix_classify_table_dump (vat_main_t * vam)
15420 {
15421   vl_api_ipfix_classify_table_dump_t *mp;
15422   f64 timeout;
15423
15424   if (!vam->json_output)
15425     {
15426       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15427                "transport_protocol");
15428     }
15429
15430   /* Construct the API message */
15431   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15432
15433   /* send it... */
15434   S;
15435
15436   /* Use a control ping for synchronization */
15437   {
15438     vl_api_control_ping_t *mp;
15439     M (CONTROL_PING, control_ping);
15440     S;
15441   }
15442   W;
15443 }
15444
15445 static void
15446   vl_api_ipfix_classify_table_details_t_handler
15447   (vl_api_ipfix_classify_table_details_t * mp)
15448 {
15449   vat_main_t *vam = &vat_main;
15450   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15451            mp->transport_protocol);
15452 }
15453
15454 static void
15455   vl_api_ipfix_classify_table_details_t_handler_json
15456   (vl_api_ipfix_classify_table_details_t * mp)
15457 {
15458   vat_json_node_t *node = NULL;
15459   vat_main_t *vam = &vat_main;
15460
15461   if (VAT_JSON_ARRAY != vam->json_tree.type)
15462     {
15463       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15464       vat_json_init_array (&vam->json_tree);
15465     }
15466
15467   node = vat_json_array_add (&vam->json_tree);
15468   vat_json_init_object (node);
15469
15470   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15471   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15472   vat_json_object_add_uint (node, "transport_protocol",
15473                             mp->transport_protocol);
15474 }
15475
15476 static int
15477 api_sw_interface_span_enable_disable (vat_main_t * vam)
15478 {
15479   unformat_input_t *i = vam->input;
15480   vl_api_sw_interface_span_enable_disable_t *mp;
15481   f64 timeout;
15482   u32 src_sw_if_index = ~0;
15483   u32 dst_sw_if_index = ~0;
15484   u8 enable = 1;
15485
15486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15487     {
15488       if (unformat (i, "src %U", unformat_sw_if_index, vam, &src_sw_if_index))
15489         ;
15490       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15491         ;
15492       else
15493         if (unformat
15494             (i, "dst %U", unformat_sw_if_index, vam, &dst_sw_if_index))
15495         ;
15496       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15497         ;
15498       else if (unformat (i, "disable"))
15499         enable = 0;
15500       else
15501         break;
15502     }
15503
15504   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15505
15506   mp->sw_if_index_from = htonl (src_sw_if_index);
15507   mp->sw_if_index_to = htonl (dst_sw_if_index);
15508   mp->enable = enable;
15509
15510   S;
15511   W;
15512   /* NOTREACHED */
15513   return 0;
15514 }
15515
15516 static void
15517 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
15518                                             * mp)
15519 {
15520   vat_main_t *vam = &vat_main;
15521
15522   fformat (vam->ofp, "%u => %u\n",
15523            ntohl (mp->sw_if_index_from), ntohl (mp->sw_if_index_to));
15524 }
15525
15526 static void
15527   vl_api_sw_interface_span_details_t_handler_json
15528   (vl_api_sw_interface_span_details_t * mp)
15529 {
15530   vat_main_t *vam = &vat_main;
15531   vat_json_node_t *node = NULL;
15532
15533   if (VAT_JSON_ARRAY != vam->json_tree.type)
15534     {
15535       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15536       vat_json_init_array (&vam->json_tree);
15537     }
15538   node = vat_json_array_add (&vam->json_tree);
15539
15540   vat_json_init_object (node);
15541   vat_json_object_add_uint (node, "src-if-index",
15542                             ntohl (mp->sw_if_index_from));
15543   vat_json_object_add_uint (node, "dst-if-index", ntohl (mp->sw_if_index_to));
15544 }
15545
15546 static int
15547 api_sw_interface_span_dump (vat_main_t * vam)
15548 {
15549   vl_api_sw_interface_span_dump_t *mp;
15550   f64 timeout;
15551
15552   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
15553   S;
15554
15555   /* Use a control ping for synchronization */
15556   {
15557     vl_api_control_ping_t *mp;
15558     M (CONTROL_PING, control_ping);
15559     S;
15560   }
15561   W;
15562 }
15563
15564 int
15565 api_pg_create_interface (vat_main_t * vam)
15566 {
15567   unformat_input_t *input = vam->input;
15568   vl_api_pg_create_interface_t *mp;
15569   f64 timeout;
15570
15571   u32 if_id = ~0;
15572   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15573     {
15574       if (unformat (input, "if_id %d", &if_id))
15575         ;
15576       else
15577         break;
15578     }
15579   if (if_id == ~0)
15580     {
15581       errmsg ("missing pg interface index\n");
15582       return -99;
15583     }
15584
15585   /* Construct the API message */
15586   M (PG_CREATE_INTERFACE, pg_create_interface);
15587   mp->context = 0;
15588   mp->interface_id = ntohl (if_id);
15589
15590   S;
15591   W;
15592   /* NOTREACHED */
15593   return 0;
15594 }
15595
15596 int
15597 api_pg_capture (vat_main_t * vam)
15598 {
15599   unformat_input_t *input = vam->input;
15600   vl_api_pg_capture_t *mp;
15601   f64 timeout;
15602
15603   u32 if_id = ~0;
15604   u8 enable = 1;
15605   u32 count = 1;
15606   u8 pcap_file_set = 0;
15607   u8 *pcap_file = 0;
15608   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15609     {
15610       if (unformat (input, "if_id %d", &if_id))
15611         ;
15612       else if (unformat (input, "pcap %s", &pcap_file))
15613         pcap_file_set = 1;
15614       else if (unformat (input, "count %d", &count))
15615         ;
15616       else if (unformat (input, "disable"))
15617         enable = 0;
15618       else
15619         break;
15620     }
15621   if (if_id == ~0)
15622     {
15623       errmsg ("missing pg interface index\n");
15624       return -99;
15625     }
15626   if (pcap_file_set > 0)
15627     {
15628       if (vec_len (pcap_file) > 255)
15629         {
15630           errmsg ("pcap file name is too long\n");
15631           return -99;
15632         }
15633     }
15634
15635   u32 name_len = vec_len (pcap_file);
15636   /* Construct the API message */
15637   M (PG_CAPTURE, pg_capture);
15638   mp->context = 0;
15639   mp->interface_id = ntohl (if_id);
15640   mp->is_enabled = enable;
15641   mp->count = ntohl (count);
15642   mp->pcap_name_length = ntohl (name_len);
15643   if (pcap_file_set != 0)
15644     {
15645       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15646     }
15647   vec_free (pcap_file);
15648
15649   S;
15650   W;
15651   /* NOTREACHED */
15652   return 0;
15653 }
15654
15655 int
15656 api_pg_enable_disable (vat_main_t * vam)
15657 {
15658   unformat_input_t *input = vam->input;
15659   vl_api_pg_enable_disable_t *mp;
15660   f64 timeout;
15661
15662   u8 enable = 1;
15663   u8 stream_name_set = 0;
15664   u8 *stream_name = 0;
15665   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15666     {
15667       if (unformat (input, "stream %s", &stream_name))
15668         stream_name_set = 1;
15669       else if (unformat (input, "disable"))
15670         enable = 0;
15671       else
15672         break;
15673     }
15674
15675   if (stream_name_set > 0)
15676     {
15677       if (vec_len (stream_name) > 255)
15678         {
15679           errmsg ("stream name too long\n");
15680           return -99;
15681         }
15682     }
15683
15684   u32 name_len = vec_len (stream_name);
15685   /* Construct the API message */
15686   M (PG_ENABLE_DISABLE, pg_enable_disable);
15687   mp->context = 0;
15688   mp->is_enabled = enable;
15689   if (stream_name_set != 0)
15690     {
15691       mp->stream_name_length = ntohl (name_len);
15692       clib_memcpy (mp->stream_name, stream_name, name_len);
15693     }
15694   vec_free (stream_name);
15695
15696   S;
15697   W;
15698   /* NOTREACHED */
15699   return 0;
15700 }
15701
15702 int
15703 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15704 {
15705   unformat_input_t *input = vam->input;
15706   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15707   f64 timeout;
15708
15709   u16 *low_ports = 0;
15710   u16 *high_ports = 0;
15711   u16 this_low;
15712   u16 this_hi;
15713   ip4_address_t ip4_addr;
15714   ip6_address_t ip6_addr;
15715   u32 length;
15716   u32 tmp, tmp2;
15717   u8 prefix_set = 0;
15718   u32 vrf_id = ~0;
15719   u8 is_add = 1;
15720   u8 is_ipv6 = 0;
15721
15722   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15723     {
15724       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15725         {
15726           prefix_set = 1;
15727         }
15728       else
15729         if (unformat
15730             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15731         {
15732           prefix_set = 1;
15733           is_ipv6 = 1;
15734         }
15735       else if (unformat (input, "vrf %d", &vrf_id))
15736         ;
15737       else if (unformat (input, "del"))
15738         is_add = 0;
15739       else if (unformat (input, "port %d", &tmp))
15740         {
15741           if (tmp == 0 || tmp > 65535)
15742             {
15743               errmsg ("port %d out of range", tmp);
15744               return -99;
15745             }
15746           this_low = tmp;
15747           this_hi = this_low + 1;
15748           vec_add1 (low_ports, this_low);
15749           vec_add1 (high_ports, this_hi);
15750         }
15751       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15752         {
15753           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15754             {
15755               errmsg ("incorrect range parameters\n");
15756               return -99;
15757             }
15758           this_low = tmp;
15759           /* Note: in debug CLI +1 is added to high before
15760              passing to real fn that does "the work"
15761              (ip_source_and_port_range_check_add_del).
15762              This fn is a wrapper around the binary API fn a
15763              control plane will call, which expects this increment
15764              to have occurred. Hence letting the binary API control
15765              plane fn do the increment for consistency between VAT
15766              and other control planes.
15767            */
15768           this_hi = tmp2;
15769           vec_add1 (low_ports, this_low);
15770           vec_add1 (high_ports, this_hi);
15771         }
15772       else
15773         break;
15774     }
15775
15776   if (prefix_set == 0)
15777     {
15778       errmsg ("<address>/<mask> not specified\n");
15779       return -99;
15780     }
15781
15782   if (vrf_id == ~0)
15783     {
15784       errmsg ("VRF ID required, not specified\n");
15785       return -99;
15786     }
15787
15788   if (vrf_id == 0)
15789     {
15790       errmsg
15791         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15792       return -99;
15793     }
15794
15795   if (vec_len (low_ports) == 0)
15796     {
15797       errmsg ("At least one port or port range required\n");
15798       return -99;
15799     }
15800
15801   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15802      ip_source_and_port_range_check_add_del);
15803
15804   mp->is_add = is_add;
15805
15806   if (is_ipv6)
15807     {
15808       mp->is_ipv6 = 1;
15809       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15810     }
15811   else
15812     {
15813       mp->is_ipv6 = 0;
15814       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15815     }
15816
15817   mp->mask_length = length;
15818   mp->number_of_ranges = vec_len (low_ports);
15819
15820   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15821   vec_free (low_ports);
15822
15823   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15824   vec_free (high_ports);
15825
15826   mp->vrf_id = ntohl (vrf_id);
15827
15828   S;
15829   W;
15830   /* NOTREACHED */
15831   return 0;
15832 }
15833
15834 int
15835 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15836 {
15837   unformat_input_t *input = vam->input;
15838   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15839   f64 timeout;
15840   u32 sw_if_index = ~0;
15841   int vrf_set = 0;
15842   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15843   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15844   u8 is_add = 1;
15845
15846   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15847     {
15848       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15849         ;
15850       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15851         ;
15852       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15853         vrf_set = 1;
15854       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15855         vrf_set = 1;
15856       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15857         vrf_set = 1;
15858       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15859         vrf_set = 1;
15860       else if (unformat (input, "del"))
15861         is_add = 0;
15862       else
15863         break;
15864     }
15865
15866   if (sw_if_index == ~0)
15867     {
15868       errmsg ("Interface required but not specified\n");
15869       return -99;
15870     }
15871
15872   if (vrf_set == 0)
15873     {
15874       errmsg ("VRF ID required but not specified\n");
15875       return -99;
15876     }
15877
15878   if (tcp_out_vrf_id == 0
15879       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15880     {
15881       errmsg
15882         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15883       return -99;
15884     }
15885
15886   /* Construct the API message */
15887   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15888      ip_source_and_port_range_check_interface_add_del);
15889
15890   mp->sw_if_index = ntohl (sw_if_index);
15891   mp->is_add = is_add;
15892   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15893   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15894   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15895   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15896
15897   /* send it... */
15898   S;
15899
15900   /* Wait for a reply... */
15901   W;
15902 }
15903
15904 static int
15905 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15906 {
15907   unformat_input_t *i = vam->input;
15908   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15909   f64 timeout;
15910   u32 local_sa_id = 0;
15911   u32 remote_sa_id = 0;
15912   ip4_address_t src_address;
15913   ip4_address_t dst_address;
15914   u8 is_add = 1;
15915
15916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15917     {
15918       if (unformat (i, "local_sa %d", &local_sa_id))
15919         ;
15920       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15921         ;
15922       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15923         ;
15924       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15925         ;
15926       else if (unformat (i, "del"))
15927         is_add = 0;
15928       else
15929         {
15930           clib_warning ("parse error '%U'", format_unformat_error, i);
15931           return -99;
15932         }
15933     }
15934
15935   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15936
15937   mp->local_sa_id = ntohl (local_sa_id);
15938   mp->remote_sa_id = ntohl (remote_sa_id);
15939   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15940   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15941   mp->is_add = is_add;
15942
15943   S;
15944   W;
15945   /* NOTREACHED */
15946   return 0;
15947 }
15948
15949 static int
15950 api_punt (vat_main_t * vam)
15951 {
15952   unformat_input_t *i = vam->input;
15953   vl_api_punt_t *mp;
15954   f64 timeout;
15955   u32 ipv = ~0;
15956   u32 protocol = ~0;
15957   u32 port = ~0;
15958   int is_add = 1;
15959
15960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15961     {
15962       if (unformat (i, "ip %d", &ipv))
15963         ;
15964       else if (unformat (i, "protocol %d", &protocol))
15965         ;
15966       else if (unformat (i, "port %d", &port))
15967         ;
15968       else if (unformat (i, "del"))
15969         is_add = 0;
15970       else
15971         {
15972           clib_warning ("parse error '%U'", format_unformat_error, i);
15973           return -99;
15974         }
15975     }
15976
15977   M (PUNT, punt);
15978
15979   mp->is_add = (u8) is_add;
15980   mp->ipv = (u8) ipv;
15981   mp->l4_protocol = (u8) protocol;
15982   mp->l4_port = htons ((u16) port);
15983
15984   S;
15985   W;
15986   /* NOTREACHED */
15987   return 0;
15988 }
15989
15990 static void vl_api_ipsec_gre_tunnel_details_t_handler
15991   (vl_api_ipsec_gre_tunnel_details_t * mp)
15992 {
15993   vat_main_t *vam = &vat_main;
15994
15995   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15996            ntohl (mp->sw_if_index),
15997            format_ip4_address, &mp->src_address,
15998            format_ip4_address, &mp->dst_address,
15999            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16000 }
16001
16002 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16003   (vl_api_ipsec_gre_tunnel_details_t * mp)
16004 {
16005   vat_main_t *vam = &vat_main;
16006   vat_json_node_t *node = NULL;
16007   struct in_addr ip4;
16008
16009   if (VAT_JSON_ARRAY != vam->json_tree.type)
16010     {
16011       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16012       vat_json_init_array (&vam->json_tree);
16013     }
16014   node = vat_json_array_add (&vam->json_tree);
16015
16016   vat_json_init_object (node);
16017   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16018   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16019   vat_json_object_add_ip4 (node, "src_address", ip4);
16020   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16021   vat_json_object_add_ip4 (node, "dst_address", ip4);
16022   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16023   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16024 }
16025
16026 static int
16027 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16028 {
16029   unformat_input_t *i = vam->input;
16030   vl_api_ipsec_gre_tunnel_dump_t *mp;
16031   f64 timeout;
16032   u32 sw_if_index;
16033   u8 sw_if_index_set = 0;
16034
16035   /* Parse args required to build the message */
16036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16037     {
16038       if (unformat (i, "sw_if_index %d", &sw_if_index))
16039         sw_if_index_set = 1;
16040       else
16041         break;
16042     }
16043
16044   if (sw_if_index_set == 0)
16045     {
16046       sw_if_index = ~0;
16047     }
16048
16049   if (!vam->json_output)
16050     {
16051       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
16052                "sw_if_index", "src_address", "dst_address",
16053                "local_sa_id", "remote_sa_id");
16054     }
16055
16056   /* Get list of gre-tunnel interfaces */
16057   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16058
16059   mp->sw_if_index = htonl (sw_if_index);
16060
16061   S;
16062
16063   /* Use a control ping for synchronization */
16064   {
16065     vl_api_control_ping_t *mp;
16066     M (CONTROL_PING, control_ping);
16067     S;
16068   }
16069   W;
16070 }
16071
16072 static int
16073 api_delete_subif (vat_main_t * vam)
16074 {
16075   unformat_input_t *i = vam->input;
16076   vl_api_delete_subif_t *mp;
16077   f64 timeout;
16078   u32 sw_if_index = ~0;
16079
16080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16081     {
16082       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16083         ;
16084       if (unformat (i, "sw_if_index %d", &sw_if_index))
16085         ;
16086       else
16087         break;
16088     }
16089
16090   if (sw_if_index == ~0)
16091     {
16092       errmsg ("missing sw_if_index\n");
16093       return -99;
16094     }
16095
16096   /* Construct the API message */
16097   M (DELETE_SUBIF, delete_subif);
16098   mp->sw_if_index = ntohl (sw_if_index);
16099
16100   S;
16101   W;
16102 }
16103
16104 #define foreach_pbb_vtr_op      \
16105 _("disable",  L2_VTR_DISABLED)  \
16106 _("pop",  L2_VTR_POP_2)         \
16107 _("push",  L2_VTR_PUSH_2)
16108
16109 static int
16110 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16111 {
16112   unformat_input_t *i = vam->input;
16113   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16114   f64 timeout;
16115   u32 sw_if_index = ~0, vtr_op = ~0;
16116   u16 outer_tag = ~0;
16117   u8 dmac[6], smac[6];
16118   u8 dmac_set = 0, smac_set = 0;
16119   u16 vlanid = 0;
16120   u32 sid = ~0;
16121   u32 tmp;
16122
16123   /* Shut up coverity */
16124   memset (dmac, 0, sizeof (dmac));
16125   memset (smac, 0, sizeof (smac));
16126
16127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16128     {
16129       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16130         ;
16131       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16132         ;
16133       else if (unformat (i, "vtr_op %d", &vtr_op))
16134         ;
16135 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16136       foreach_pbb_vtr_op
16137 #undef _
16138         else if (unformat (i, "translate_pbb_stag"))
16139         {
16140           if (unformat (i, "%d", &tmp))
16141             {
16142               vtr_op = L2_VTR_TRANSLATE_2_1;
16143               outer_tag = tmp;
16144             }
16145           else
16146             {
16147               errmsg
16148                 ("translate_pbb_stag operation requires outer tag definition\n");
16149               return -99;
16150             }
16151         }
16152       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16153         dmac_set++;
16154       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16155         smac_set++;
16156       else if (unformat (i, "sid %d", &sid))
16157         ;
16158       else if (unformat (i, "vlanid %d", &tmp))
16159         vlanid = tmp;
16160       else
16161         {
16162           clib_warning ("parse error '%U'", format_unformat_error, i);
16163           return -99;
16164         }
16165     }
16166
16167   if ((sw_if_index == ~0) || (vtr_op == ~0))
16168     {
16169       errmsg ("missing sw_if_index or vtr operation\n");
16170       return -99;
16171     }
16172   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16173       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16174     {
16175       errmsg
16176         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
16177       return -99;
16178     }
16179
16180   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16181   mp->sw_if_index = ntohl (sw_if_index);
16182   mp->vtr_op = ntohl (vtr_op);
16183   mp->outer_tag = ntohs (outer_tag);
16184   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16185   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16186   mp->b_vlanid = ntohs (vlanid);
16187   mp->i_sid = ntohl (sid);
16188
16189   S;
16190   W;
16191   /* NOTREACHED */
16192   return 0;
16193 }
16194
16195 static int
16196 api_flow_classify_set_interface (vat_main_t * vam)
16197 {
16198   unformat_input_t *i = vam->input;
16199   vl_api_flow_classify_set_interface_t *mp;
16200   f64 timeout;
16201   u32 sw_if_index;
16202   int sw_if_index_set;
16203   u32 ip4_table_index = ~0;
16204   u32 ip6_table_index = ~0;
16205   u8 is_add = 1;
16206
16207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16208     {
16209       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16210         sw_if_index_set = 1;
16211       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16212         sw_if_index_set = 1;
16213       else if (unformat (i, "del"))
16214         is_add = 0;
16215       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16216         ;
16217       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16218         ;
16219       else
16220         {
16221           clib_warning ("parse error '%U'", format_unformat_error, i);
16222           return -99;
16223         }
16224     }
16225
16226   if (sw_if_index_set == 0)
16227     {
16228       errmsg ("missing interface name or sw_if_index\n");
16229       return -99;
16230     }
16231
16232   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16233
16234   mp->sw_if_index = ntohl (sw_if_index);
16235   mp->ip4_table_index = ntohl (ip4_table_index);
16236   mp->ip6_table_index = ntohl (ip6_table_index);
16237   mp->is_add = is_add;
16238
16239   S;
16240   W;
16241   /* NOTREACHED */
16242   return 0;
16243 }
16244
16245 static int
16246 api_flow_classify_dump (vat_main_t * vam)
16247 {
16248   unformat_input_t *i = vam->input;
16249   vl_api_flow_classify_dump_t *mp;
16250   f64 timeout = ~0;
16251   u8 type = FLOW_CLASSIFY_N_TABLES;
16252
16253   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16254     ;
16255   else
16256     {
16257       errmsg ("classify table type must be specified\n");
16258       return -99;
16259     }
16260
16261   if (!vam->json_output)
16262     {
16263       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
16264     }
16265
16266   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16267   mp->type = type;
16268   /* send it... */
16269   S;
16270
16271   /* Use a control ping for synchronization */
16272   {
16273     vl_api_control_ping_t *mp;
16274     M (CONTROL_PING, control_ping);
16275     S;
16276   }
16277   /* Wait for a reply... */
16278   W;
16279
16280   /* NOTREACHED */
16281   return 0;
16282 }
16283
16284 static int
16285 api_feature_enable_disable (vat_main_t * vam)
16286 {
16287   unformat_input_t *i = vam->input;
16288   vl_api_feature_enable_disable_t *mp;
16289   f64 timeout;
16290   u8 *arc_name = 0;
16291   u8 *feature_name = 0;
16292   u32 sw_if_index = ~0;
16293   u8 enable = 1;
16294
16295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16296     {
16297       if (unformat (i, "arc_name %s", &arc_name))
16298         ;
16299       else if (unformat (i, "feature_name %s", &feature_name))
16300         ;
16301       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16302         ;
16303       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16304         ;
16305       else if (unformat (i, "disable"))
16306         enable = 0;
16307       else
16308         break;
16309     }
16310
16311   if (arc_name == 0)
16312     {
16313       errmsg ("missing arc name\n");
16314       return -99;
16315     }
16316   if (vec_len (arc_name) > 63)
16317     {
16318       errmsg ("arc name too long\n");
16319     }
16320
16321   if (feature_name == 0)
16322     {
16323       errmsg ("missing feature name\n");
16324       return -99;
16325     }
16326   if (vec_len (feature_name) > 63)
16327     {
16328       errmsg ("feature name too long\n");
16329     }
16330
16331   if (sw_if_index == ~0)
16332     {
16333       errmsg ("missing interface name or sw_if_index\n");
16334       return -99;
16335     }
16336
16337   /* Construct the API message */
16338   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16339   mp->sw_if_index = ntohl (sw_if_index);
16340   mp->enable = enable;
16341   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16342   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16343   vec_free (arc_name);
16344   vec_free (feature_name);
16345
16346   S;
16347   W;
16348 }
16349
16350 static int
16351 q_or_quit (vat_main_t * vam)
16352 {
16353   longjmp (vam->jump_buf, 1);
16354   return 0;                     /* not so much */
16355 }
16356
16357 static int
16358 q (vat_main_t * vam)
16359 {
16360   return q_or_quit (vam);
16361 }
16362
16363 static int
16364 quit (vat_main_t * vam)
16365 {
16366   return q_or_quit (vam);
16367 }
16368
16369 static int
16370 comment (vat_main_t * vam)
16371 {
16372   return 0;
16373 }
16374
16375 static int
16376 cmd_cmp (void *a1, void *a2)
16377 {
16378   u8 **c1 = a1;
16379   u8 **c2 = a2;
16380
16381   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
16382 }
16383
16384 static int
16385 help (vat_main_t * vam)
16386 {
16387   u8 **cmds = 0;
16388   u8 *name = 0;
16389   hash_pair_t *p;
16390   unformat_input_t *i = vam->input;
16391   int j;
16392
16393   if (unformat (i, "%s", &name))
16394     {
16395       uword *hs;
16396
16397       vec_add1 (name, 0);
16398
16399       hs = hash_get_mem (vam->help_by_name, name);
16400       if (hs)
16401         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
16402       else
16403         fformat (vam->ofp, "No such msg / command '%s'\n", name);
16404       vec_free (name);
16405       return 0;
16406     }
16407
16408   fformat (vam->ofp, "Help is available for the following:\n");
16409
16410     /* *INDENT-OFF* */
16411     hash_foreach_pair (p, vam->function_by_name,
16412     ({
16413       vec_add1 (cmds, (u8 *)(p->key));
16414     }));
16415     /* *INDENT-ON* */
16416
16417   vec_sort_with_function (cmds, cmd_cmp);
16418
16419   for (j = 0; j < vec_len (cmds); j++)
16420     fformat (vam->ofp, "%s\n", cmds[j]);
16421
16422   vec_free (cmds);
16423   return 0;
16424 }
16425
16426 static int
16427 set (vat_main_t * vam)
16428 {
16429   u8 *name = 0, *value = 0;
16430   unformat_input_t *i = vam->input;
16431
16432   if (unformat (i, "%s", &name))
16433     {
16434       /* The input buffer is a vector, not a string. */
16435       value = vec_dup (i->buffer);
16436       vec_delete (value, i->index, 0);
16437       /* Almost certainly has a trailing newline */
16438       if (value[vec_len (value) - 1] == '\n')
16439         value[vec_len (value) - 1] = 0;
16440       /* Make sure it's a proper string, one way or the other */
16441       vec_add1 (value, 0);
16442       (void) clib_macro_set_value (&vam->macro_main,
16443                                    (char *) name, (char *) value);
16444     }
16445   else
16446     errmsg ("usage: set <name> <value>\n");
16447
16448   vec_free (name);
16449   vec_free (value);
16450   return 0;
16451 }
16452
16453 static int
16454 unset (vat_main_t * vam)
16455 {
16456   u8 *name = 0;
16457
16458   if (unformat (vam->input, "%s", &name))
16459     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
16460       errmsg ("unset: %s wasn't set\n", name);
16461   vec_free (name);
16462   return 0;
16463 }
16464
16465 typedef struct
16466 {
16467   u8 *name;
16468   u8 *value;
16469 } macro_sort_t;
16470
16471
16472 static int
16473 macro_sort_cmp (void *a1, void *a2)
16474 {
16475   macro_sort_t *s1 = a1;
16476   macro_sort_t *s2 = a2;
16477
16478   return strcmp ((char *) (s1->name), (char *) (s2->name));
16479 }
16480
16481 static int
16482 dump_macro_table (vat_main_t * vam)
16483 {
16484   macro_sort_t *sort_me = 0, *sm;
16485   int i;
16486   hash_pair_t *p;
16487
16488     /* *INDENT-OFF* */
16489     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
16490     ({
16491       vec_add2 (sort_me, sm, 1);
16492       sm->name = (u8 *)(p->key);
16493       sm->value = (u8 *) (p->value[0]);
16494     }));
16495     /* *INDENT-ON* */
16496
16497   vec_sort_with_function (sort_me, macro_sort_cmp);
16498
16499   if (vec_len (sort_me))
16500     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
16501   else
16502     fformat (vam->ofp, "The macro table is empty...\n");
16503
16504   for (i = 0; i < vec_len (sort_me); i++)
16505     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
16506   return 0;
16507 }
16508
16509 static int
16510 dump_node_table (vat_main_t * vam)
16511 {
16512   int i, j;
16513   vlib_node_t *node, *next_node;
16514
16515   if (vec_len (vam->graph_nodes) == 0)
16516     {
16517       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16518       return 0;
16519     }
16520
16521   for (i = 0; i < vec_len (vam->graph_nodes); i++)
16522     {
16523       node = vam->graph_nodes[i];
16524       fformat (vam->ofp, "[%d] %s\n", i, node->name);
16525       for (j = 0; j < vec_len (node->next_nodes); j++)
16526         {
16527           if (node->next_nodes[j] != ~0)
16528             {
16529               next_node = vam->graph_nodes[node->next_nodes[j]];
16530               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16531             }
16532         }
16533     }
16534   return 0;
16535 }
16536
16537 static int
16538 search_node_table (vat_main_t * vam)
16539 {
16540   unformat_input_t *line_input = vam->input;
16541   u8 *node_to_find;
16542   int j;
16543   vlib_node_t *node, *next_node;
16544   uword *p;
16545
16546   if (vam->graph_node_index_by_name == 0)
16547     {
16548       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16549       return 0;
16550     }
16551
16552   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16553     {
16554       if (unformat (line_input, "%s", &node_to_find))
16555         {
16556           vec_add1 (node_to_find, 0);
16557           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
16558           if (p == 0)
16559             {
16560               fformat (vam->ofp, "%s not found...\n", node_to_find);
16561               goto out;
16562             }
16563           node = vam->graph_nodes[p[0]];
16564           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
16565           for (j = 0; j < vec_len (node->next_nodes); j++)
16566             {
16567               if (node->next_nodes[j] != ~0)
16568                 {
16569                   next_node = vam->graph_nodes[node->next_nodes[j]];
16570                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16571                 }
16572             }
16573         }
16574
16575       else
16576         {
16577           clib_warning ("parse error '%U'", format_unformat_error,
16578                         line_input);
16579           return -99;
16580         }
16581
16582     out:
16583       vec_free (node_to_find);
16584
16585     }
16586
16587   return 0;
16588 }
16589
16590
16591 static int
16592 script (vat_main_t * vam)
16593 {
16594   u8 *s = 0;
16595   char *save_current_file;
16596   unformat_input_t save_input;
16597   jmp_buf save_jump_buf;
16598   u32 save_line_number;
16599
16600   FILE *new_fp, *save_ifp;
16601
16602   if (unformat (vam->input, "%s", &s))
16603     {
16604       new_fp = fopen ((char *) s, "r");
16605       if (new_fp == 0)
16606         {
16607           errmsg ("Couldn't open script file %s\n", s);
16608           vec_free (s);
16609           return -99;
16610         }
16611     }
16612   else
16613     {
16614       errmsg ("Missing script name\n");
16615       return -99;
16616     }
16617
16618   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
16619   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
16620   save_ifp = vam->ifp;
16621   save_line_number = vam->input_line_number;
16622   save_current_file = (char *) vam->current_file;
16623
16624   vam->input_line_number = 0;
16625   vam->ifp = new_fp;
16626   vam->current_file = s;
16627   do_one_file (vam);
16628
16629   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
16630   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
16631   vam->ifp = save_ifp;
16632   vam->input_line_number = save_line_number;
16633   vam->current_file = (u8 *) save_current_file;
16634   vec_free (s);
16635
16636   return 0;
16637 }
16638
16639 static int
16640 echo (vat_main_t * vam)
16641 {
16642   fformat (vam->ofp, "%v", vam->input->buffer);
16643   return 0;
16644 }
16645
16646 /* List of API message constructors, CLI names map to api_xxx */
16647 #define foreach_vpe_api_msg                                             \
16648 _(create_loopback,"[mac <mac-addr>]")                                   \
16649 _(sw_interface_dump,"")                                                 \
16650 _(sw_interface_set_flags,                                               \
16651   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
16652 _(sw_interface_add_del_address,                                         \
16653   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
16654 _(sw_interface_set_table,                                               \
16655   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
16656 _(sw_interface_set_mpls_enable,                                                \
16657   "<intfc> | sw_if_index [disable | dis]")                                \
16658 _(sw_interface_set_vpath,                                               \
16659   "<intfc> | sw_if_index <id> enable | disable")                        \
16660 _(sw_interface_set_l2_xconnect,                                         \
16661   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16662   "enable | disable")                                                   \
16663 _(sw_interface_set_l2_bridge,                                           \
16664   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16665   "[shg <split-horizon-group>] [bvi]\n"                                 \
16666   "enable | disable")                                                   \
16667 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16668   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16669   "profile <profile-id>\n")                                             \
16670 _(sw_interface_set_dpdk_hqos_subport,                                   \
16671   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16672   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16673 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16674   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16675 _(bridge_domain_add_del,                                                \
16676   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16677 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16678 _(l2fib_add_del,                                                        \
16679   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16680 _(l2_flags,                                                             \
16681   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16682 _(bridge_flags,                                                         \
16683   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16684 _(tap_connect,                                                          \
16685   "tapname <name> mac <mac-addr> | random-mac")                         \
16686 _(tap_modify,                                                           \
16687   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16688 _(tap_delete,                                                           \
16689   "<vpp-if-name> | sw_if_index <id>")                                   \
16690 _(sw_interface_tap_dump, "")                                            \
16691 _(ip_add_del_route,                                                     \
16692   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
16693   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16694   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16695   "[multipath] [count <n>]")                                            \
16696 _(mpls_route_add_del,                                                   \
16697   "<label> <eos> via <addr> [table-id <n>]\n"                           \
16698   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16699   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16700   "[multipath] [count <n>]")                                            \
16701 _(mpls_ip_bind_unbind,                                                  \
16702   "<label> <addr/len>")                                                 \
16703 _(proxy_arp_add_del,                                                    \
16704   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16705 _(proxy_arp_intfc_enable_disable,                                       \
16706   "<intfc> | sw_if_index <id> enable | disable")                        \
16707 _(mpls_add_del_encap,                                                   \
16708   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
16709 _(sw_interface_set_unnumbered,                                          \
16710   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16711 _(ip_neighbor_add_del,                                                  \
16712   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16713   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16714 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16715 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16716 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16717   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16718   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16719   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16720 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16721 _(reset_fib, "vrf <n> [ipv6]")                                          \
16722 _(dhcp_proxy_config,                                                    \
16723   "svr <v46-address> src <v46-address>\n"                               \
16724    "insert-cid <n> [del]")                                              \
16725 _(dhcp_proxy_config_2,                                                  \
16726   "svr <v46-address> src <v46-address>\n"                               \
16727    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16728 _(dhcp_proxy_set_vss,                                                   \
16729   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16730 _(dhcp_client_config,                                                   \
16731   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16732 _(set_ip_flow_hash,                                                     \
16733   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16734 _(sw_interface_ip6_enable_disable,                                      \
16735   "<intfc> | sw_if_index <id> enable | disable")                        \
16736 _(sw_interface_ip6_set_link_local_address,                              \
16737   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16738 _(sw_interface_ip6nd_ra_prefix,                                         \
16739   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16740   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16741   "[nolink] [isno]")                                                    \
16742 _(sw_interface_ip6nd_ra_config,                                         \
16743   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16744   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16745   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16746 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16747 _(l2_patch_add_del,                                                     \
16748   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16749   "enable | disable")                                                   \
16750 _(mpls_ethernet_add_del_tunnel,                                         \
16751   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
16752   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
16753 _(mpls_ethernet_add_del_tunnel_2,                                       \
16754   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
16755   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
16756 _(sr_tunnel_add_del,                                                    \
16757   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16758   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16759   "[policy <policy_name>]")                                             \
16760 _(sr_policy_add_del,                                                    \
16761   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16762 _(sr_multicast_map_add_del,                                             \
16763   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16764 _(classify_add_del_table,                                               \
16765   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16766   " [del] mask <mask-value>\n"                                          \
16767   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
16768   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
16769 _(classify_add_del_session,                                             \
16770   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16771   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16772   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
16773   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
16774 _(classify_set_interface_ip_table,                                      \
16775   "<intfc> | sw_if_index <nn> table <nn>")                              \
16776 _(classify_set_interface_l2_tables,                                     \
16777   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16778   "  [other-table <nn>]")                                               \
16779 _(get_node_index, "node <node-name")                                    \
16780 _(add_node_next, "node <node-name> next <next-node-name>")              \
16781 _(l2tpv3_create_tunnel,                                                 \
16782   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16783   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16784   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16785 _(l2tpv3_set_tunnel_cookies,                                            \
16786   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16787   "[new_remote_cookie <nn>]\n")                                         \
16788 _(l2tpv3_interface_enable_disable,                                      \
16789   "<intfc> | sw_if_index <nn> enable | disable")                        \
16790 _(l2tpv3_set_lookup_key,                                                \
16791   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16792 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16793 _(vxlan_add_del_tunnel,                                                 \
16794   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
16795   " [decap-next l2|ip4|ip6] [del]")                                     \
16796 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16797 _(gre_add_del_tunnel,                                                   \
16798   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16799 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16800 _(l2_fib_clear_table, "")                                               \
16801 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16802 _(l2_interface_vlan_tag_rewrite,                                        \
16803   "<intfc> | sw_if_index <nn> \n"                                       \
16804   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
16805   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
16806 _(create_vhost_user_if,                                                 \
16807         "socket <filename> [server] [renumber <dev_instance>] "         \
16808         "[mac <mac_address>]")                                          \
16809 _(modify_vhost_user_if,                                                 \
16810         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
16811         "[server] [renumber <dev_instance>]")                           \
16812 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
16813 _(sw_interface_vhost_user_dump, "")                                     \
16814 _(show_version, "")                                                     \
16815 _(vxlan_gpe_add_del_tunnel,                                             \
16816   "local <addr> remote <addr> vni <nn>\n"                               \
16817     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
16818   "[next-ethernet] [next-nsh]\n")                                       \
16819 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
16820 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
16821 _(interface_name_renumber,                                              \
16822   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
16823 _(input_acl_set_interface,                                              \
16824   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16825   "  [l2-table <nn>] [del]")                                            \
16826 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
16827 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
16828 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
16829 _(ip_dump, "ipv4 | ipv6")                                               \
16830 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
16831 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
16832   "  spid_id <n> ")                                                     \
16833 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
16834   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
16835   "  integ_alg <alg> integ_key <hex>")                                  \
16836 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
16837   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
16838   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
16839   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
16840 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
16841 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
16842 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
16843   "(auth_data 0x<data> | auth_data <data>)")                            \
16844 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
16845   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
16846 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16847   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16848   "(local|remote)")                                                     \
16849 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16850 _(delete_loopback,"sw_if_index <nn>")                                   \
16851 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16852 _(map_add_domain,                                                       \
16853   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16854   "ip6-src <ip6addr> "                                                  \
16855   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16856 _(map_del_domain, "index <n>")                                          \
16857 _(map_add_del_rule,                                                     \
16858   "index <n> psid <n> dst <ip6addr> [del]")                             \
16859 _(map_domain_dump, "")                                                  \
16860 _(map_rule_dump, "index <map-domain>")                                  \
16861 _(want_interface_events,  "enable|disable")                             \
16862 _(want_stats,"enable|disable")                                          \
16863 _(get_first_msg_id, "client <name>")                                    \
16864 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16865 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16866   "fib-id <nn> [ip4][ip6][default]")                                    \
16867 _(get_node_graph, " ")                                                  \
16868 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16869 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16870 _(ioam_disable, "")                                                \
16871 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16872                             " sw_if_index <sw_if_index> p <priority> "  \
16873                             "w <weight>] [del]")                        \
16874 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16875                         "iface <intf> | sw_if_index <sw_if_index> "     \
16876                         "p <priority> w <weight> [del]")                \
16877 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16878                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16879                           "locator-set <locator_name> [del]")           \
16880 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16881   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16882 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16883 _(lisp_gpe_enable_disable, "enable|disable")                            \
16884 _(lisp_enable_disable, "enable|disable")                                \
16885 _(lisp_gpe_add_del_iface, "up|down")                                    \
16886 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
16887                                "[seid <seid>] "                         \
16888                                "rloc <locator> p <prio> "               \
16889                                "w <weight> [rloc <loc> ... ] "          \
16890                                "action <action> [del-all]")             \
16891 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
16892                           "<local-eid>")                                \
16893 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16894 _(lisp_map_request_mode, "src-dst|dst-only")                            \
16895 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16896 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16897 _(lisp_locator_set_dump, "[local | remote]")                            \
16898 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
16899 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16900                        "[local] | [remote]")                            \
16901 _(lisp_eid_table_vni_dump, "")                                          \
16902 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16903 _(lisp_gpe_tunnel_dump, "")                                             \
16904 _(lisp_map_resolver_dump, "")                                           \
16905 _(lisp_adjacencies_get, "vni <vni>")                                    \
16906 _(show_lisp_status, "")                                                 \
16907 _(lisp_get_map_request_itr_rlocs, "")                                   \
16908 _(show_lisp_pitr, "")                                                   \
16909 _(show_lisp_map_request_mode, "")                                       \
16910 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16911 _(af_packet_delete, "name <host interface name>")                       \
16912 _(policer_add_del, "name <policer name> <params> [del]")                \
16913 _(policer_dump, "[name <policer name>]")                                \
16914 _(policer_classify_set_interface,                                       \
16915   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16916   "  [l2-table <nn>] [del]")                                            \
16917 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16918 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16919     "[master|slave]")                                                   \
16920 _(netmap_delete, "name <interface name>")                               \
16921 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16922 _(mpls_fib_encap_dump, "")                                              \
16923 _(mpls_fib_dump, "")                                                    \
16924 _(classify_table_ids, "")                                               \
16925 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16926 _(classify_table_info, "table_id <nn>")                                 \
16927 _(classify_session_dump, "table_id <nn>")                               \
16928 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
16929     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
16930     "[template_interval <nn>] [udp_checksum]")                          \
16931 _(ipfix_exporter_dump, "")                                              \
16932 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
16933 _(ipfix_classify_stream_dump, "")                                       \
16934 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
16935 _(ipfix_classify_table_dump, "")                                        \
16936 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [[dst <intfc> | dst_sw_if_index <id>] | disable]") \
16937 _(sw_interface_span_dump, "")                                           \
16938 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
16939 _(pg_create_interface, "if_id <nn>")                                    \
16940 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
16941 _(pg_enable_disable, "[stream <id>] disable")                           \
16942 _(ip_source_and_port_range_check_add_del,                               \
16943   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
16944 _(ip_source_and_port_range_check_interface_add_del,                     \
16945   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
16946   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
16947 _(ipsec_gre_add_del_tunnel,                                             \
16948   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
16949 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
16950 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
16951 _(l2_interface_pbb_tag_rewrite,                                         \
16952   "<intfc> | sw_if_index <nn> \n"                                       \
16953   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
16954   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
16955 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
16956 _(flow_classify_set_interface,                                          \
16957   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
16958 _(flow_classify_dump, "type [ip4|ip6]")                                 \
16959 _(ip_fib_dump, "")                                                      \
16960 _(ip6_fib_dump, "")                                                     \
16961 _(feature_enable_disable, "arc_name <arc_name> "                        \
16962   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")
16963
16964 /* List of command functions, CLI names map directly to functions */
16965 #define foreach_cli_function                                    \
16966 _(comment, "usage: comment <ignore-rest-of-line>")              \
16967 _(dump_interface_table, "usage: dump_interface_table")          \
16968 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
16969 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
16970 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
16971 _(dump_stats_table, "usage: dump_stats_table")                  \
16972 _(dump_macro_table, "usage: dump_macro_table ")                 \
16973 _(dump_node_table, "usage: dump_node_table")                    \
16974 _(echo, "usage: echo <message>")                                \
16975 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
16976 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
16977 _(help, "usage: help")                                          \
16978 _(q, "usage: quit")                                             \
16979 _(quit, "usage: quit")                                          \
16980 _(search_node_table, "usage: search_node_table <name>...")      \
16981 _(set, "usage: set <variable-name> <value>")                    \
16982 _(script, "usage: script <file-name>")                          \
16983 _(unset, "usage: unset <variable-name>")
16984
16985 #define _(N,n)                                  \
16986     static void vl_api_##n##_t_handler_uni      \
16987     (vl_api_##n##_t * mp)                       \
16988     {                                           \
16989         vat_main_t * vam = &vat_main;           \
16990         if (vam->json_output) {                 \
16991             vl_api_##n##_t_handler_json(mp);    \
16992         } else {                                \
16993             vl_api_##n##_t_handler(mp);         \
16994         }                                       \
16995     }
16996 foreach_vpe_api_reply_msg;
16997 #undef _
16998
16999 void
17000 vat_api_hookup (vat_main_t * vam)
17001 {
17002 #define _(N,n)                                                  \
17003     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17004                            vl_api_##n##_t_handler_uni,          \
17005                            vl_noop_handler,                     \
17006                            vl_api_##n##_t_endian,               \
17007                            vl_api_##n##_t_print,                \
17008                            sizeof(vl_api_##n##_t), 1);
17009   foreach_vpe_api_reply_msg;
17010 #undef _
17011
17012   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17013
17014   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17015
17016   vam->function_by_name = hash_create_string (0, sizeof (uword));
17017
17018   vam->help_by_name = hash_create_string (0, sizeof (uword));
17019
17020   /* API messages we can send */
17021 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17022   foreach_vpe_api_msg;
17023 #undef _
17024
17025   /* Help strings */
17026 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17027   foreach_vpe_api_msg;
17028 #undef _
17029
17030   /* CLI functions */
17031 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17032   foreach_cli_function;
17033 #undef _
17034
17035   /* Help strings */
17036 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17037   foreach_cli_function;
17038 #undef _
17039 }
17040
17041 #undef vl_api_version
17042 #define vl_api_version(n,v) static u32 vpe_api_version = v;
17043 #include <vpp-api/vpe.api.h>
17044 #undef vl_api_version
17045
17046 void
17047 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
17048 {
17049   /*
17050    * Send the main API signature in slot 0. This bit of code must
17051    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
17052    */
17053   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
17054 }
17055
17056 /*
17057  * fd.io coding-style-patch-verification: ON
17058  *
17059  * Local Variables:
17060  * eval: (c-set-style "gnu")
17061  * End:
17062  */