Enabling AES-GCM-128 with 16B ICV support
[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 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248   u32 *r = va_arg (*args, u32 *);
249
250   if (0);
251 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
252   foreach_ipsec_policy_action
253 #undef _
254     else
255     return 0;
256   return 1;
257 }
258
259 uword
260 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
261 {
262   u32 *r = va_arg (*args, u32 *);
263
264   if (0);
265 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
266   foreach_ipsec_crypto_alg
267 #undef _
268     else
269     return 0;
270   return 1;
271 }
272
273 u8 *
274 format_ipsec_crypto_alg (u8 * s, va_list * args)
275 {
276   u32 i = va_arg (*args, u32);
277   u8 *t = 0;
278
279   switch (i)
280     {
281 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
282       foreach_ipsec_crypto_alg
283 #undef _
284     default:
285       return format (s, "unknown");
286     }
287   return format (s, "%s", t);
288 }
289
290 uword
291 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
292 {
293   u32 *r = va_arg (*args, u32 *);
294
295   if (0);
296 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
297   foreach_ipsec_integ_alg
298 #undef _
299     else
300     return 0;
301   return 1;
302 }
303
304 u8 *
305 format_ipsec_integ_alg (u8 * s, va_list * args)
306 {
307   u32 i = va_arg (*args, u32);
308   u8 *t = 0;
309
310   switch (i)
311     {
312 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
313       foreach_ipsec_integ_alg
314 #undef _
315     default:
316       return format (s, "unknown");
317     }
318   return format (s, "%s", t);
319 }
320
321 uword
322 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
323 {
324   u32 *r = va_arg (*args, u32 *);
325
326   if (0);
327 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
328   foreach_ikev2_auth_method
329 #undef _
330     else
331     return 0;
332   return 1;
333 }
334
335 uword
336 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
337 {
338   u32 *r = va_arg (*args, u32 *);
339
340   if (0);
341 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
342   foreach_ikev2_id_type
343 #undef _
344     else
345     return 0;
346   return 1;
347 }
348
349 uword
350 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
351 {
352   u8 *r = va_arg (*args, u8 *);
353
354   if (unformat (input, "kbps"))
355     *r = SSE2_QOS_RATE_KBPS;
356   else if (unformat (input, "pps"))
357     *r = SSE2_QOS_RATE_PPS;
358   else
359     return 0;
360   return 1;
361 }
362
363 uword
364 unformat_policer_round_type (unformat_input_t * input, va_list * args)
365 {
366   u8 *r = va_arg (*args, u8 *);
367
368   if (unformat (input, "closest"))
369     *r = SSE2_QOS_ROUND_TO_CLOSEST;
370   else if (unformat (input, "up"))
371     *r = SSE2_QOS_ROUND_TO_UP;
372   else if (unformat (input, "down"))
373     *r = SSE2_QOS_ROUND_TO_DOWN;
374   else
375     return 0;
376   return 1;
377 }
378
379 uword
380 unformat_policer_type (unformat_input_t * input, va_list * args)
381 {
382   u8 *r = va_arg (*args, u8 *);
383
384   if (unformat (input, "1r2c"))
385     *r = SSE2_QOS_POLICER_TYPE_1R2C;
386   else if (unformat (input, "1r3c"))
387     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
388   else if (unformat (input, "2r3c-2698"))
389     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
390   else if (unformat (input, "2r3c-4115"))
391     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
392   else if (unformat (input, "2r3c-mef5cf1"))
393     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
394   else
395     return 0;
396   return 1;
397 }
398
399 uword
400 unformat_dscp (unformat_input_t * input, va_list * va)
401 {
402   u8 *r = va_arg (*va, u8 *);
403
404   if (0);
405 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
406   foreach_vnet_dscp
407 #undef _
408     else
409     return 0;
410   return 1;
411 }
412
413 uword
414 unformat_policer_action_type (unformat_input_t * input, va_list * va)
415 {
416   sse2_qos_pol_action_params_st *a
417     = va_arg (*va, sse2_qos_pol_action_params_st *);
418
419   if (unformat (input, "drop"))
420     a->action_type = SSE2_QOS_ACTION_DROP;
421   else if (unformat (input, "transmit"))
422     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
423   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
424     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
425   else
426     return 0;
427   return 1;
428 }
429
430 uword
431 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
432 {
433   u32 *r = va_arg (*va, u32 *);
434   u32 tid;
435
436   if (unformat (input, "ip4"))
437     tid = POLICER_CLASSIFY_TABLE_IP4;
438   else if (unformat (input, "ip6"))
439     tid = POLICER_CLASSIFY_TABLE_IP6;
440   else if (unformat (input, "l2"))
441     tid = POLICER_CLASSIFY_TABLE_L2;
442   else
443     return 0;
444
445   *r = tid;
446   return 1;
447 }
448
449 uword
450 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
451 {
452   u32 *r = va_arg (*va, u32 *);
453   u32 tid;
454
455   if (unformat (input, "ip4"))
456     tid = FLOW_CLASSIFY_TABLE_IP4;
457   else if (unformat (input, "ip6"))
458     tid = FLOW_CLASSIFY_TABLE_IP6;
459   else
460     return 0;
461
462   *r = tid;
463   return 1;
464 }
465
466 u8 *
467 format_ip4_address (u8 * s, va_list * args)
468 {
469   u8 *a = va_arg (*args, u8 *);
470   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
471 }
472
473 u8 *
474 format_ip6_address (u8 * s, va_list * args)
475 {
476   ip6_address_t *a = va_arg (*args, ip6_address_t *);
477   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
478
479   i_max_n_zero = ARRAY_LEN (a->as_u16);
480   max_n_zeros = 0;
481   i_first_zero = i_max_n_zero;
482   n_zeros = 0;
483   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
484     {
485       u32 is_zero = a->as_u16[i] == 0;
486       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
487         {
488           i_first_zero = i;
489           n_zeros = 0;
490         }
491       n_zeros += is_zero;
492       if ((!is_zero && n_zeros > max_n_zeros)
493           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
494         {
495           i_max_n_zero = i_first_zero;
496           max_n_zeros = n_zeros;
497           i_first_zero = ARRAY_LEN (a->as_u16);
498           n_zeros = 0;
499         }
500     }
501
502   last_double_colon = 0;
503   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
504     {
505       if (i == i_max_n_zero && max_n_zeros > 1)
506         {
507           s = format (s, "::");
508           i += max_n_zeros - 1;
509           last_double_colon = 1;
510         }
511       else
512         {
513           s = format (s, "%s%x",
514                       (last_double_colon || i == 0) ? "" : ":",
515                       clib_net_to_host_u16 (a->as_u16[i]));
516           last_double_colon = 0;
517         }
518     }
519
520   return s;
521 }
522
523 /* Format an IP46 address. */
524 u8 *
525 format_ip46_address (u8 * s, va_list * args)
526 {
527   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
528   ip46_type_t type = va_arg (*args, ip46_type_t);
529   int is_ip4 = 1;
530
531   switch (type)
532     {
533     case IP46_TYPE_ANY:
534       is_ip4 = ip46_address_is_ip4 (ip46);
535       break;
536     case IP46_TYPE_IP4:
537       is_ip4 = 1;
538       break;
539     case IP46_TYPE_IP6:
540       is_ip4 = 0;
541       break;
542     }
543
544   return is_ip4 ?
545     format (s, "%U", format_ip4_address, &ip46->ip4) :
546     format (s, "%U", format_ip6_address, &ip46->ip6);
547 }
548
549 u8 *
550 format_ethernet_address (u8 * s, va_list * args)
551 {
552   u8 *a = va_arg (*args, u8 *);
553
554   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
555                  a[0], a[1], a[2], a[3], a[4], a[5]);
556 }
557
558 void
559 increment_v4_address (ip4_address_t * a)
560 {
561   u32 v;
562
563   v = ntohl (a->as_u32) + 1;
564   a->as_u32 = ntohl (v);
565 }
566
567 void
568 increment_v6_address (ip6_address_t * a)
569 {
570   u64 v0, v1;
571
572   v0 = clib_net_to_host_u64 (a->as_u64[0]);
573   v1 = clib_net_to_host_u64 (a->as_u64[1]);
574
575   v1 += 1;
576   if (v1 == 0)
577     v0 += 1;
578   a->as_u64[0] = clib_net_to_host_u64 (v0);
579   a->as_u64[1] = clib_net_to_host_u64 (v1);
580 }
581
582 void
583 increment_mac_address (u64 * mac)
584 {
585   u64 tmp = *mac;
586
587   tmp = clib_net_to_host_u64 (tmp);
588   tmp += 1 << 16;               /* skip unused (least significant) octets */
589   tmp = clib_host_to_net_u64 (tmp);
590   *mac = tmp;
591 }
592
593 static void vl_api_create_loopback_reply_t_handler
594   (vl_api_create_loopback_reply_t * mp)
595 {
596   vat_main_t *vam = &vat_main;
597   i32 retval = ntohl (mp->retval);
598
599   vam->retval = retval;
600   vam->regenerate_interface_table = 1;
601   vam->sw_if_index = ntohl (mp->sw_if_index);
602   vam->result_ready = 1;
603 }
604
605 static void vl_api_create_loopback_reply_t_handler_json
606   (vl_api_create_loopback_reply_t * mp)
607 {
608   vat_main_t *vam = &vat_main;
609   vat_json_node_t node;
610
611   vat_json_init_object (&node);
612   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
613   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
614
615   vat_json_print (vam->ofp, &node);
616   vat_json_free (&node);
617   vam->retval = ntohl (mp->retval);
618   vam->result_ready = 1;
619 }
620
621 static void vl_api_af_packet_create_reply_t_handler
622   (vl_api_af_packet_create_reply_t * mp)
623 {
624   vat_main_t *vam = &vat_main;
625   i32 retval = ntohl (mp->retval);
626
627   vam->retval = retval;
628   vam->regenerate_interface_table = 1;
629   vam->sw_if_index = ntohl (mp->sw_if_index);
630   vam->result_ready = 1;
631 }
632
633 static void vl_api_af_packet_create_reply_t_handler_json
634   (vl_api_af_packet_create_reply_t * mp)
635 {
636   vat_main_t *vam = &vat_main;
637   vat_json_node_t node;
638
639   vat_json_init_object (&node);
640   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
641   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
642
643   vat_json_print (vam->ofp, &node);
644   vat_json_free (&node);
645
646   vam->retval = ntohl (mp->retval);
647   vam->result_ready = 1;
648 }
649
650 static void vl_api_create_vlan_subif_reply_t_handler
651   (vl_api_create_vlan_subif_reply_t * mp)
652 {
653   vat_main_t *vam = &vat_main;
654   i32 retval = ntohl (mp->retval);
655
656   vam->retval = retval;
657   vam->regenerate_interface_table = 1;
658   vam->sw_if_index = ntohl (mp->sw_if_index);
659   vam->result_ready = 1;
660 }
661
662 static void vl_api_create_vlan_subif_reply_t_handler_json
663   (vl_api_create_vlan_subif_reply_t * mp)
664 {
665   vat_main_t *vam = &vat_main;
666   vat_json_node_t node;
667
668   vat_json_init_object (&node);
669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
670   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
671
672   vat_json_print (vam->ofp, &node);
673   vat_json_free (&node);
674
675   vam->retval = ntohl (mp->retval);
676   vam->result_ready = 1;
677 }
678
679 static void vl_api_create_subif_reply_t_handler
680   (vl_api_create_subif_reply_t * mp)
681 {
682   vat_main_t *vam = &vat_main;
683   i32 retval = ntohl (mp->retval);
684
685   vam->retval = retval;
686   vam->regenerate_interface_table = 1;
687   vam->sw_if_index = ntohl (mp->sw_if_index);
688   vam->result_ready = 1;
689 }
690
691 static void vl_api_create_subif_reply_t_handler_json
692   (vl_api_create_subif_reply_t * mp)
693 {
694   vat_main_t *vam = &vat_main;
695   vat_json_node_t node;
696
697   vat_json_init_object (&node);
698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
699   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
700
701   vat_json_print (vam->ofp, &node);
702   vat_json_free (&node);
703
704   vam->retval = ntohl (mp->retval);
705   vam->result_ready = 1;
706 }
707
708 static void vl_api_interface_name_renumber_reply_t_handler
709   (vl_api_interface_name_renumber_reply_t * mp)
710 {
711   vat_main_t *vam = &vat_main;
712   i32 retval = ntohl (mp->retval);
713
714   vam->retval = retval;
715   vam->regenerate_interface_table = 1;
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler_json
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   vat_json_node_t node;
724
725   vat_json_init_object (&node);
726   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
727
728   vat_json_print (vam->ofp, &node);
729   vat_json_free (&node);
730
731   vam->retval = ntohl (mp->retval);
732   vam->result_ready = 1;
733 }
734
735 /*
736  * Special-case: build the interface table, maintain
737  * the next loopback sw_if_index vbl.
738  */
739 static void vl_api_sw_interface_details_t_handler
740   (vl_api_sw_interface_details_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   u8 *s = format (0, "%s%c", mp->interface_name, 0);
744
745   hash_set_mem (vam->sw_if_index_by_interface_name, s,
746                 ntohl (mp->sw_if_index));
747
748   /* In sub interface case, fill the sub interface table entry */
749   if (mp->sw_if_index != mp->sup_sw_if_index)
750     {
751       sw_interface_subif_t *sub = NULL;
752
753       vec_add2 (vam->sw_if_subif_table, sub, 1);
754
755       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
756       strncpy ((char *) sub->interface_name, (char *) s,
757                vec_len (sub->interface_name));
758       sub->sw_if_index = ntohl (mp->sw_if_index);
759       sub->sub_id = ntohl (mp->sub_id);
760
761       sub->sub_dot1ad = mp->sub_dot1ad;
762       sub->sub_number_of_tags = mp->sub_number_of_tags;
763       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
764       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
765       sub->sub_exact_match = mp->sub_exact_match;
766       sub->sub_default = mp->sub_default;
767       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
768       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
769
770       /* vlan tag rewrite */
771       sub->vtr_op = ntohl (mp->vtr_op);
772       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
773       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
774       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
775     }
776 }
777
778 static void vl_api_sw_interface_details_t_handler_json
779   (vl_api_sw_interface_details_t * mp)
780 {
781   vat_main_t *vam = &vat_main;
782   vat_json_node_t *node = NULL;
783
784   if (VAT_JSON_ARRAY != vam->json_tree.type)
785     {
786       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
787       vat_json_init_array (&vam->json_tree);
788     }
789   node = vat_json_array_add (&vam->json_tree);
790
791   vat_json_init_object (node);
792   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
793   vat_json_object_add_uint (node, "sup_sw_if_index",
794                             ntohl (mp->sup_sw_if_index));
795   vat_json_object_add_uint (node, "l2_address_length",
796                             ntohl (mp->l2_address_length));
797   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
798                              sizeof (mp->l2_address));
799   vat_json_object_add_string_copy (node, "interface_name",
800                                    mp->interface_name);
801   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
802   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
803   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
804   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
805   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
806   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
807   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
808   vat_json_object_add_uint (node, "sub_number_of_tags",
809                             mp->sub_number_of_tags);
810   vat_json_object_add_uint (node, "sub_outer_vlan_id",
811                             ntohs (mp->sub_outer_vlan_id));
812   vat_json_object_add_uint (node, "sub_inner_vlan_id",
813                             ntohs (mp->sub_inner_vlan_id));
814   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
815   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
816   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
817                             mp->sub_outer_vlan_id_any);
818   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
819                             mp->sub_inner_vlan_id_any);
820   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
821   vat_json_object_add_uint (node, "vtr_push_dot1q",
822                             ntohl (mp->vtr_push_dot1q));
823   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
824   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
825 }
826
827 static void vl_api_sw_interface_set_flags_t_handler
828   (vl_api_sw_interface_set_flags_t * mp)
829 {
830   vat_main_t *vam = &vat_main;
831   if (vam->interface_event_display)
832     errmsg ("interface flags: sw_if_index %d %s %s\n",
833             ntohl (mp->sw_if_index),
834             mp->admin_up_down ? "admin-up" : "admin-down",
835             mp->link_up_down ? "link-up" : "link-down");
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler_json
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   /* JSON output not supported */
842 }
843
844 static void
845 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
846 {
847   vat_main_t *vam = &vat_main;
848   i32 retval = ntohl (mp->retval);
849
850   vam->retval = retval;
851   vam->shmem_result = (u8 *) mp->reply_in_shmem;
852   vam->result_ready = 1;
853 }
854
855 static void
856 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   vat_json_node_t node;
860   api_main_t *am = &api_main;
861   void *oldheap;
862   u8 *reply;
863
864   vat_json_init_object (&node);
865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
866   vat_json_object_add_uint (&node, "reply_in_shmem",
867                             ntohl (mp->reply_in_shmem));
868   /* Toss the shared-memory original... */
869   pthread_mutex_lock (&am->vlib_rp->mutex);
870   oldheap = svm_push_data_heap (am->vlib_rp);
871
872   reply = (u8 *) (mp->reply_in_shmem);
873   vec_free (reply);
874
875   svm_pop_heap (oldheap);
876   pthread_mutex_unlock (&am->vlib_rp->mutex);
877
878   vat_json_print (vam->ofp, &node);
879   vat_json_free (&node);
880
881   vam->retval = ntohl (mp->retval);
882   vam->result_ready = 1;
883 }
884
885 static void
886 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   i32 retval = ntohl (mp->retval);
890
891   vam->retval = retval;
892   vam->cmd_reply = mp->reply;
893   vam->result_ready = 1;
894 }
895
896 static void
897 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   vat_json_node_t node;
901
902   vat_json_init_object (&node);
903   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
904   vat_json_object_add_string_copy (&node, "reply", mp->reply);
905
906   vat_json_print (vam->ofp, &node);
907   vat_json_free (&node);
908
909   vam->retval = ntohl (mp->retval);
910   vam->result_ready = 1;
911 }
912
913 static void vl_api_classify_add_del_table_reply_t_handler
914   (vl_api_classify_add_del_table_reply_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   i32 retval = ntohl (mp->retval);
918   if (vam->async_mode)
919     {
920       vam->async_errors += (retval < 0);
921     }
922   else
923     {
924       vam->retval = retval;
925       if (retval == 0 &&
926           ((mp->new_table_index != 0xFFFFFFFF) ||
927            (mp->skip_n_vectors != 0xFFFFFFFF) ||
928            (mp->match_n_vectors != 0xFFFFFFFF)))
929         /*
930          * Note: this is just barely thread-safe, depends on
931          * the main thread spinning waiting for an answer...
932          */
933         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
934                 ntohl (mp->new_table_index),
935                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
936       vam->result_ready = 1;
937     }
938 }
939
940 static void vl_api_classify_add_del_table_reply_t_handler_json
941   (vl_api_classify_add_del_table_reply_t * mp)
942 {
943   vat_main_t *vam = &vat_main;
944   vat_json_node_t node;
945
946   vat_json_init_object (&node);
947   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
948   vat_json_object_add_uint (&node, "new_table_index",
949                             ntohl (mp->new_table_index));
950   vat_json_object_add_uint (&node, "skip_n_vectors",
951                             ntohl (mp->skip_n_vectors));
952   vat_json_object_add_uint (&node, "match_n_vectors",
953                             ntohl (mp->match_n_vectors));
954
955   vat_json_print (vam->ofp, &node);
956   vat_json_free (&node);
957
958   vam->retval = ntohl (mp->retval);
959   vam->result_ready = 1;
960 }
961
962 static void vl_api_get_node_index_reply_t_handler
963   (vl_api_get_node_index_reply_t * mp)
964 {
965   vat_main_t *vam = &vat_main;
966   i32 retval = ntohl (mp->retval);
967   if (vam->async_mode)
968     {
969       vam->async_errors += (retval < 0);
970     }
971   else
972     {
973       vam->retval = retval;
974       if (retval == 0)
975         errmsg ("node index %d\n", ntohl (mp->node_index));
976       vam->result_ready = 1;
977     }
978 }
979
980 static void vl_api_get_node_index_reply_t_handler_json
981   (vl_api_get_node_index_reply_t * mp)
982 {
983   vat_main_t *vam = &vat_main;
984   vat_json_node_t node;
985
986   vat_json_init_object (&node);
987   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
988   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
989
990   vat_json_print (vam->ofp, &node);
991   vat_json_free (&node);
992
993   vam->retval = ntohl (mp->retval);
994   vam->result_ready = 1;
995 }
996
997 static void vl_api_get_next_index_reply_t_handler
998   (vl_api_get_next_index_reply_t * mp)
999 {
1000   vat_main_t *vam = &vat_main;
1001   i32 retval = ntohl (mp->retval);
1002   if (vam->async_mode)
1003     {
1004       vam->async_errors += (retval < 0);
1005     }
1006   else
1007     {
1008       vam->retval = retval;
1009       if (retval == 0)
1010         errmsg ("next node index %d\n", ntohl (mp->next_index));
1011       vam->result_ready = 1;
1012     }
1013 }
1014
1015 static void vl_api_get_next_index_reply_t_handler_json
1016   (vl_api_get_next_index_reply_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   vat_json_node_t node;
1020
1021   vat_json_init_object (&node);
1022   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1023   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1024
1025   vat_json_print (vam->ofp, &node);
1026   vat_json_free (&node);
1027
1028   vam->retval = ntohl (mp->retval);
1029   vam->result_ready = 1;
1030 }
1031
1032 static void vl_api_add_node_next_reply_t_handler
1033   (vl_api_add_node_next_reply_t * mp)
1034 {
1035   vat_main_t *vam = &vat_main;
1036   i32 retval = ntohl (mp->retval);
1037   if (vam->async_mode)
1038     {
1039       vam->async_errors += (retval < 0);
1040     }
1041   else
1042     {
1043       vam->retval = retval;
1044       if (retval == 0)
1045         errmsg ("next index %d\n", ntohl (mp->next_index));
1046       vam->result_ready = 1;
1047     }
1048 }
1049
1050 static void vl_api_add_node_next_reply_t_handler_json
1051   (vl_api_add_node_next_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   vat_json_node_t node;
1055
1056   vat_json_init_object (&node);
1057   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1058   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1059
1060   vat_json_print (vam->ofp, &node);
1061   vat_json_free (&node);
1062
1063   vam->retval = ntohl (mp->retval);
1064   vam->result_ready = 1;
1065 }
1066
1067 static void vl_api_show_version_reply_t_handler
1068   (vl_api_show_version_reply_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   i32 retval = ntohl (mp->retval);
1072
1073   if (retval >= 0)
1074     {
1075       errmsg ("        program: %s\n", mp->program);
1076       errmsg ("        version: %s\n", mp->version);
1077       errmsg ("     build date: %s\n", mp->build_date);
1078       errmsg ("build directory: %s\n", mp->build_directory);
1079     }
1080   vam->retval = retval;
1081   vam->result_ready = 1;
1082 }
1083
1084 static void vl_api_show_version_reply_t_handler_json
1085   (vl_api_show_version_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   vat_json_node_t node;
1089
1090   vat_json_init_object (&node);
1091   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1092   vat_json_object_add_string_copy (&node, "program", mp->program);
1093   vat_json_object_add_string_copy (&node, "version", mp->version);
1094   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1095   vat_json_object_add_string_copy (&node, "build_directory",
1096                                    mp->build_directory);
1097
1098   vat_json_print (vam->ofp, &node);
1099   vat_json_free (&node);
1100
1101   vam->retval = ntohl (mp->retval);
1102   vam->result_ready = 1;
1103 }
1104
1105 static void
1106 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1107 {
1108   vat_main_t *vam = &vat_main;
1109   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1110           mp->mac_ip ? "mac/ip binding" : "address resolution",
1111           format_ip4_address, &mp->address,
1112           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1113 }
1114
1115 static void
1116 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1117 {
1118   /* JSON output not supported */
1119 }
1120
1121 static void
1122 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1123 {
1124   vat_main_t *vam = &vat_main;
1125   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1126           mp->mac_ip ? "mac/ip binding" : "address resolution",
1127           format_ip6_address, mp->address,
1128           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1129 }
1130
1131 static void
1132 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1133 {
1134   /* JSON output not supported */
1135 }
1136
1137 /*
1138  * Special-case: build the bridge domain table, maintain
1139  * the next bd id vbl.
1140  */
1141 static void vl_api_bridge_domain_details_t_handler
1142   (vl_api_bridge_domain_details_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1146
1147   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1148            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1149
1150   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1151            ntohl (mp->bd_id), mp->learn, mp->forward,
1152            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1153
1154   if (n_sw_ifs)
1155     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1156              "Interface Name");
1157 }
1158
1159 static void vl_api_bridge_domain_details_t_handler_json
1160   (vl_api_bridge_domain_details_t * mp)
1161 {
1162   vat_main_t *vam = &vat_main;
1163   vat_json_node_t *node, *array = NULL;
1164
1165   if (VAT_JSON_ARRAY != vam->json_tree.type)
1166     {
1167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1168       vat_json_init_array (&vam->json_tree);
1169     }
1170   node = vat_json_array_add (&vam->json_tree);
1171
1172   vat_json_init_object (node);
1173   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1174   vat_json_object_add_uint (node, "flood", mp->flood);
1175   vat_json_object_add_uint (node, "forward", mp->forward);
1176   vat_json_object_add_uint (node, "learn", mp->learn);
1177   vat_json_object_add_uint (node, "bvi_sw_if_index",
1178                             ntohl (mp->bvi_sw_if_index));
1179   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1180   array = vat_json_object_add (node, "sw_if");
1181   vat_json_init_array (array);
1182 }
1183
1184 /*
1185  * Special-case: build the bridge domain sw if table.
1186  */
1187 static void vl_api_bridge_domain_sw_if_details_t_handler
1188   (vl_api_bridge_domain_sw_if_details_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   hash_pair_t *p;
1192   u8 *sw_if_name = 0;
1193   u32 sw_if_index;
1194
1195   sw_if_index = ntohl (mp->sw_if_index);
1196   /* *INDENT-OFF* */
1197   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1198   ({
1199     if ((u32) p->value[0] == sw_if_index)
1200       {
1201         sw_if_name = (u8 *)(p->key);
1202         break;
1203       }
1204   }));
1205   /* *INDENT-ON* */
1206
1207   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1208            mp->shg, sw_if_name ? (char *) sw_if_name :
1209            "sw_if_index not found!");
1210 }
1211
1212 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1213   (vl_api_bridge_domain_sw_if_details_t * mp)
1214 {
1215   vat_main_t *vam = &vat_main;
1216   vat_json_node_t *node = NULL;
1217   uword last_index = 0;
1218
1219   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1220   ASSERT (vec_len (vam->json_tree.array) >= 1);
1221   last_index = vec_len (vam->json_tree.array) - 1;
1222   node = &vam->json_tree.array[last_index];
1223   node = vat_json_object_get_element (node, "sw_if");
1224   ASSERT (NULL != node);
1225   node = vat_json_array_add (node);
1226
1227   vat_json_init_object (node);
1228   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1230   vat_json_object_add_uint (node, "shg", mp->shg);
1231 }
1232
1233 static void vl_api_control_ping_reply_t_handler
1234   (vl_api_control_ping_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   i32 retval = ntohl (mp->retval);
1238   if (vam->async_mode)
1239     {
1240       vam->async_errors += (retval < 0);
1241     }
1242   else
1243     {
1244       vam->retval = retval;
1245       vam->result_ready = 1;
1246     }
1247 }
1248
1249 static void vl_api_control_ping_reply_t_handler_json
1250   (vl_api_control_ping_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254
1255   if (VAT_JSON_NONE != vam->json_tree.type)
1256     {
1257       vat_json_print (vam->ofp, &vam->json_tree);
1258       vat_json_free (&vam->json_tree);
1259       vam->json_tree.type = VAT_JSON_NONE;
1260     }
1261   else
1262     {
1263       /* just print [] */
1264       vat_json_init_array (&vam->json_tree);
1265       vat_json_print (vam->ofp, &vam->json_tree);
1266       vam->json_tree.type = VAT_JSON_NONE;
1267     }
1268
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void
1274 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278   if (vam->async_mode)
1279     {
1280       vam->async_errors += (retval < 0);
1281     }
1282   else
1283     {
1284       vam->retval = retval;
1285       vam->result_ready = 1;
1286     }
1287 }
1288
1289 static void vl_api_l2_flags_reply_t_handler_json
1290   (vl_api_l2_flags_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   vat_json_node_t node;
1294
1295   vat_json_init_object (&node);
1296   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1297   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1298                             ntohl (mp->resulting_feature_bitmap));
1299
1300   vat_json_print (vam->ofp, &node);
1301   vat_json_free (&node);
1302
1303   vam->retval = ntohl (mp->retval);
1304   vam->result_ready = 1;
1305 }
1306
1307 static void vl_api_bridge_flags_reply_t_handler
1308   (vl_api_bridge_flags_reply_t * mp)
1309 {
1310   vat_main_t *vam = &vat_main;
1311   i32 retval = ntohl (mp->retval);
1312   if (vam->async_mode)
1313     {
1314       vam->async_errors += (retval < 0);
1315     }
1316   else
1317     {
1318       vam->retval = retval;
1319       vam->result_ready = 1;
1320     }
1321 }
1322
1323 static void vl_api_bridge_flags_reply_t_handler_json
1324   (vl_api_bridge_flags_reply_t * mp)
1325 {
1326   vat_main_t *vam = &vat_main;
1327   vat_json_node_t node;
1328
1329   vat_json_init_object (&node);
1330   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1331   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1332                             ntohl (mp->resulting_feature_bitmap));
1333
1334   vat_json_print (vam->ofp, &node);
1335   vat_json_free (&node);
1336
1337   vam->retval = ntohl (mp->retval);
1338   vam->result_ready = 1;
1339 }
1340
1341 static void vl_api_tap_connect_reply_t_handler
1342   (vl_api_tap_connect_reply_t * mp)
1343 {
1344   vat_main_t *vam = &vat_main;
1345   i32 retval = ntohl (mp->retval);
1346   if (vam->async_mode)
1347     {
1348       vam->async_errors += (retval < 0);
1349     }
1350   else
1351     {
1352       vam->retval = retval;
1353       vam->sw_if_index = ntohl (mp->sw_if_index);
1354       vam->result_ready = 1;
1355     }
1356
1357 }
1358
1359 static void vl_api_tap_connect_reply_t_handler_json
1360   (vl_api_tap_connect_reply_t * mp)
1361 {
1362   vat_main_t *vam = &vat_main;
1363   vat_json_node_t node;
1364
1365   vat_json_init_object (&node);
1366   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1367   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1368
1369   vat_json_print (vam->ofp, &node);
1370   vat_json_free (&node);
1371
1372   vam->retval = ntohl (mp->retval);
1373   vam->result_ready = 1;
1374
1375 }
1376
1377 static void
1378 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1379 {
1380   vat_main_t *vam = &vat_main;
1381   i32 retval = ntohl (mp->retval);
1382   if (vam->async_mode)
1383     {
1384       vam->async_errors += (retval < 0);
1385     }
1386   else
1387     {
1388       vam->retval = retval;
1389       vam->sw_if_index = ntohl (mp->sw_if_index);
1390       vam->result_ready = 1;
1391     }
1392 }
1393
1394 static void vl_api_tap_modify_reply_t_handler_json
1395   (vl_api_tap_modify_reply_t * mp)
1396 {
1397   vat_main_t *vam = &vat_main;
1398   vat_json_node_t node;
1399
1400   vat_json_init_object (&node);
1401   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1402   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1403
1404   vat_json_print (vam->ofp, &node);
1405   vat_json_free (&node);
1406
1407   vam->retval = ntohl (mp->retval);
1408   vam->result_ready = 1;
1409 }
1410
1411 static void
1412 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1413 {
1414   vat_main_t *vam = &vat_main;
1415   i32 retval = ntohl (mp->retval);
1416   if (vam->async_mode)
1417     {
1418       vam->async_errors += (retval < 0);
1419     }
1420   else
1421     {
1422       vam->retval = retval;
1423       vam->result_ready = 1;
1424     }
1425 }
1426
1427 static void vl_api_tap_delete_reply_t_handler_json
1428   (vl_api_tap_delete_reply_t * mp)
1429 {
1430   vat_main_t *vam = &vat_main;
1431   vat_json_node_t node;
1432
1433   vat_json_init_object (&node);
1434   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1435
1436   vat_json_print (vam->ofp, &node);
1437   vat_json_free (&node);
1438
1439   vam->retval = ntohl (mp->retval);
1440   vam->result_ready = 1;
1441 }
1442
1443 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1444   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   i32 retval = ntohl (mp->retval);
1448   if (vam->async_mode)
1449     {
1450       vam->async_errors += (retval < 0);
1451     }
1452   else
1453     {
1454       vam->retval = retval;
1455       vam->result_ready = 1;
1456     }
1457 }
1458
1459 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1460   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   vat_json_node_t node;
1464
1465   vat_json_init_object (&node);
1466   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1467   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1468                             ntohl (mp->tunnel_sw_if_index));
1469
1470   vat_json_print (vam->ofp, &node);
1471   vat_json_free (&node);
1472
1473   vam->retval = ntohl (mp->retval);
1474   vam->result_ready = 1;
1475 }
1476
1477 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1478   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1479 {
1480   vat_main_t *vam = &vat_main;
1481   i32 retval = ntohl (mp->retval);
1482   if (vam->async_mode)
1483     {
1484       vam->async_errors += (retval < 0);
1485     }
1486   else
1487     {
1488       vam->retval = retval;
1489       vam->sw_if_index = ntohl (mp->sw_if_index);
1490       vam->result_ready = 1;
1491     }
1492 }
1493
1494 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1495   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   vat_json_node_t node;
1499
1500   vat_json_init_object (&node);
1501   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1502   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1503
1504   vat_json_print (vam->ofp, &node);
1505   vat_json_free (&node);
1506
1507   vam->retval = ntohl (mp->retval);
1508   vam->result_ready = 1;
1509 }
1510
1511
1512 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1513   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1514 {
1515   vat_main_t *vam = &vat_main;
1516   i32 retval = ntohl (mp->retval);
1517   if (vam->async_mode)
1518     {
1519       vam->async_errors += (retval < 0);
1520     }
1521   else
1522     {
1523       vam->retval = retval;
1524       vam->result_ready = 1;
1525     }
1526 }
1527
1528 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1529   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1530 {
1531   vat_main_t *vam = &vat_main;
1532   vat_json_node_t node;
1533
1534   vat_json_init_object (&node);
1535   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1536   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1537
1538   vat_json_print (vam->ofp, &node);
1539   vat_json_free (&node);
1540
1541   vam->retval = ntohl (mp->retval);
1542   vam->result_ready = 1;
1543 }
1544
1545 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1546   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   i32 retval = ntohl (mp->retval);
1550   if (vam->async_mode)
1551     {
1552       vam->async_errors += (retval < 0);
1553     }
1554   else
1555     {
1556       vam->retval = retval;
1557       vam->sw_if_index = ntohl (mp->sw_if_index);
1558       vam->result_ready = 1;
1559     }
1560 }
1561
1562 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1563   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1564 {
1565   vat_main_t *vam = &vat_main;
1566   vat_json_node_t node;
1567
1568   vat_json_init_object (&node);
1569   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1570   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1571
1572   vat_json_print (vam->ofp, &node);
1573   vat_json_free (&node);
1574
1575   vam->retval = ntohl (mp->retval);
1576   vam->result_ready = 1;
1577 }
1578
1579 static void vl_api_gre_add_del_tunnel_reply_t_handler
1580   (vl_api_gre_add_del_tunnel_reply_t * mp)
1581 {
1582   vat_main_t *vam = &vat_main;
1583   i32 retval = ntohl (mp->retval);
1584   if (vam->async_mode)
1585     {
1586       vam->async_errors += (retval < 0);
1587     }
1588   else
1589     {
1590       vam->retval = retval;
1591       vam->sw_if_index = ntohl (mp->sw_if_index);
1592       vam->result_ready = 1;
1593     }
1594 }
1595
1596 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1597   (vl_api_gre_add_del_tunnel_reply_t * mp)
1598 {
1599   vat_main_t *vam = &vat_main;
1600   vat_json_node_t node;
1601
1602   vat_json_init_object (&node);
1603   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1604   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1605
1606   vat_json_print (vam->ofp, &node);
1607   vat_json_free (&node);
1608
1609   vam->retval = ntohl (mp->retval);
1610   vam->result_ready = 1;
1611 }
1612
1613 static void vl_api_create_vhost_user_if_reply_t_handler
1614   (vl_api_create_vhost_user_if_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   i32 retval = ntohl (mp->retval);
1618   if (vam->async_mode)
1619     {
1620       vam->async_errors += (retval < 0);
1621     }
1622   else
1623     {
1624       vam->retval = retval;
1625       vam->sw_if_index = ntohl (mp->sw_if_index);
1626       vam->result_ready = 1;
1627     }
1628 }
1629
1630 static void vl_api_create_vhost_user_if_reply_t_handler_json
1631   (vl_api_create_vhost_user_if_reply_t * mp)
1632 {
1633   vat_main_t *vam = &vat_main;
1634   vat_json_node_t node;
1635
1636   vat_json_init_object (&node);
1637   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1638   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1639
1640   vat_json_print (vam->ofp, &node);
1641   vat_json_free (&node);
1642
1643   vam->retval = ntohl (mp->retval);
1644   vam->result_ready = 1;
1645 }
1646
1647 static void vl_api_ip_address_details_t_handler
1648   (vl_api_ip_address_details_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   static ip_address_details_t empty_ip_address_details = { {0} };
1652   ip_address_details_t *address = NULL;
1653   ip_details_t *current_ip_details = NULL;
1654   ip_details_t *details = NULL;
1655
1656   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1657
1658   if (!details || vam->current_sw_if_index >= vec_len (details)
1659       || !details[vam->current_sw_if_index].present)
1660     {
1661       errmsg ("ip address details arrived but not stored\n");
1662       errmsg ("ip_dump should be called first\n");
1663       return;
1664     }
1665
1666   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1667
1668 #define addresses (current_ip_details->addr)
1669
1670   vec_validate_init_empty (addresses, vec_len (addresses),
1671                            empty_ip_address_details);
1672
1673   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1674
1675   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1676   address->prefix_length = mp->prefix_length;
1677 #undef addresses
1678 }
1679
1680 static void vl_api_ip_address_details_t_handler_json
1681   (vl_api_ip_address_details_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t *node = NULL;
1685   struct in6_addr ip6;
1686   struct in_addr ip4;
1687
1688   if (VAT_JSON_ARRAY != vam->json_tree.type)
1689     {
1690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1691       vat_json_init_array (&vam->json_tree);
1692     }
1693   node = vat_json_array_add (&vam->json_tree);
1694
1695   vat_json_init_object (node);
1696   if (vam->is_ipv6)
1697     {
1698       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1699       vat_json_object_add_ip6 (node, "ip", ip6);
1700     }
1701   else
1702     {
1703       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1704       vat_json_object_add_ip4 (node, "ip", ip4);
1705     }
1706   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1707 }
1708
1709 static void
1710 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   static ip_details_t empty_ip_details = { 0 };
1714   ip_details_t *ip = NULL;
1715   u32 sw_if_index = ~0;
1716
1717   sw_if_index = ntohl (mp->sw_if_index);
1718
1719   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1720                            sw_if_index, empty_ip_details);
1721
1722   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1723                          sw_if_index);
1724
1725   ip->present = 1;
1726 }
1727
1728 static void
1729 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732
1733   if (VAT_JSON_ARRAY != vam->json_tree.type)
1734     {
1735       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1736       vat_json_init_array (&vam->json_tree);
1737     }
1738   vat_json_array_add_uint (&vam->json_tree,
1739                            clib_net_to_host_u32 (mp->sw_if_index));
1740 }
1741
1742 static void vl_api_map_domain_details_t_handler_json
1743   (vl_api_map_domain_details_t * mp)
1744 {
1745   vat_json_node_t *node = NULL;
1746   vat_main_t *vam = &vat_main;
1747   struct in6_addr ip6;
1748   struct in_addr ip4;
1749
1750   if (VAT_JSON_ARRAY != vam->json_tree.type)
1751     {
1752       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1753       vat_json_init_array (&vam->json_tree);
1754     }
1755
1756   node = vat_json_array_add (&vam->json_tree);
1757   vat_json_init_object (node);
1758
1759   vat_json_object_add_uint (node, "domain_index",
1760                             clib_net_to_host_u32 (mp->domain_index));
1761   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1762   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1763   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1764   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1765   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1766   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1767   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1768   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1769   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1770   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1771   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1772   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1773   vat_json_object_add_uint (node, "flags", mp->flags);
1774   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1775   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1776 }
1777
1778 static void vl_api_map_domain_details_t_handler
1779   (vl_api_map_domain_details_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782
1783   if (mp->is_translation)
1784     {
1785       fformat (vam->ofp,
1786                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1787                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1788                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1789                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1790                clib_net_to_host_u32 (mp->domain_index));
1791     }
1792   else
1793     {
1794       fformat (vam->ofp,
1795                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1796                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1797                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1798                format_ip6_address, mp->ip6_src,
1799                clib_net_to_host_u32 (mp->domain_index));
1800     }
1801   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1802            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1803            mp->is_translation ? "map-t" : "");
1804 }
1805
1806 static void vl_api_map_rule_details_t_handler_json
1807   (vl_api_map_rule_details_t * mp)
1808 {
1809   struct in6_addr ip6;
1810   vat_json_node_t *node = NULL;
1811   vat_main_t *vam = &vat_main;
1812
1813   if (VAT_JSON_ARRAY != vam->json_tree.type)
1814     {
1815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1816       vat_json_init_array (&vam->json_tree);
1817     }
1818
1819   node = vat_json_array_add (&vam->json_tree);
1820   vat_json_init_object (node);
1821
1822   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1823   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1824   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1825 }
1826
1827 static void
1828 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1829 {
1830   vat_main_t *vam = &vat_main;
1831   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1832            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1833 }
1834
1835 static void
1836 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1837 {
1838   vat_main_t *vam = &vat_main;
1839   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1840           "router_addr %U host_mac %U\n",
1841           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1842           format_ip4_address, &mp->host_address,
1843           format_ip4_address, &mp->router_address,
1844           format_ethernet_address, mp->host_mac);
1845 }
1846
1847 static void vl_api_dhcp_compl_event_t_handler_json
1848   (vl_api_dhcp_compl_event_t * mp)
1849 {
1850   /* JSON output not supported */
1851 }
1852
1853 static void
1854 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1855                               u32 counter)
1856 {
1857   vat_main_t *vam = &vat_main;
1858   static u64 default_counter = 0;
1859
1860   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1861                            NULL);
1862   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1863                            sw_if_index, default_counter);
1864   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1865 }
1866
1867 static void
1868 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1869                                 interface_counter_t counter)
1870 {
1871   vat_main_t *vam = &vat_main;
1872   static interface_counter_t default_counter = { 0, };
1873
1874   vec_validate_init_empty (vam->combined_interface_counters,
1875                            vnet_counter_type, NULL);
1876   vec_validate_init_empty (vam->combined_interface_counters
1877                            [vnet_counter_type], sw_if_index, default_counter);
1878   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1879 }
1880
1881 static void vl_api_vnet_interface_counters_t_handler
1882   (vl_api_vnet_interface_counters_t * mp)
1883 {
1884   /* not supported */
1885 }
1886
1887 static void vl_api_vnet_interface_counters_t_handler_json
1888   (vl_api_vnet_interface_counters_t * mp)
1889 {
1890   interface_counter_t counter;
1891   vlib_counter_t *v;
1892   u64 *v_packets;
1893   u64 packets;
1894   u32 count;
1895   u32 first_sw_if_index;
1896   int i;
1897
1898   count = ntohl (mp->count);
1899   first_sw_if_index = ntohl (mp->first_sw_if_index);
1900
1901   if (!mp->is_combined)
1902     {
1903       v_packets = (u64 *) & mp->data;
1904       for (i = 0; i < count; i++)
1905         {
1906           packets =
1907             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1908           set_simple_interface_counter (mp->vnet_counter_type,
1909                                         first_sw_if_index + i, packets);
1910           v_packets++;
1911         }
1912     }
1913   else
1914     {
1915       v = (vlib_counter_t *) & mp->data;
1916       for (i = 0; i < count; i++)
1917         {
1918           counter.packets =
1919             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1920           counter.bytes =
1921             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1922           set_combined_interface_counter (mp->vnet_counter_type,
1923                                           first_sw_if_index + i, counter);
1924           v++;
1925         }
1926     }
1927 }
1928
1929 static u32
1930 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1931 {
1932   vat_main_t *vam = &vat_main;
1933   u32 i;
1934
1935   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1936     {
1937       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1938         {
1939           return i;
1940         }
1941     }
1942   return ~0;
1943 }
1944
1945 static u32
1946 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1947 {
1948   vat_main_t *vam = &vat_main;
1949   u32 i;
1950
1951   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1952     {
1953       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1954         {
1955           return i;
1956         }
1957     }
1958   return ~0;
1959 }
1960
1961 static void vl_api_vnet_ip4_fib_counters_t_handler
1962   (vl_api_vnet_ip4_fib_counters_t * mp)
1963 {
1964   /* not supported */
1965 }
1966
1967 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1968   (vl_api_vnet_ip4_fib_counters_t * mp)
1969 {
1970   vat_main_t *vam = &vat_main;
1971   vl_api_ip4_fib_counter_t *v;
1972   ip4_fib_counter_t *counter;
1973   struct in_addr ip4;
1974   u32 vrf_id;
1975   u32 vrf_index;
1976   u32 count;
1977   int i;
1978
1979   vrf_id = ntohl (mp->vrf_id);
1980   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
1981   if (~0 == vrf_index)
1982     {
1983       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
1984       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1985       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1986       vec_validate (vam->ip4_fib_counters, vrf_index);
1987       vam->ip4_fib_counters[vrf_index] = NULL;
1988     }
1989
1990   vec_free (vam->ip4_fib_counters[vrf_index]);
1991   v = (vl_api_ip4_fib_counter_t *) & mp->c;
1992   count = ntohl (mp->count);
1993   for (i = 0; i < count; i++)
1994     {
1995       vec_validate (vam->ip4_fib_counters[vrf_index], i);
1996       counter = &vam->ip4_fib_counters[vrf_index][i];
1997       clib_memcpy (&ip4, &v->address, sizeof (ip4));
1998       counter->address = ip4;
1999       counter->address_length = v->address_length;
2000       counter->packets = clib_net_to_host_u64 (v->packets);
2001       counter->bytes = clib_net_to_host_u64 (v->bytes);
2002       v++;
2003     }
2004 }
2005
2006 static void vl_api_vnet_ip6_fib_counters_t_handler
2007   (vl_api_vnet_ip6_fib_counters_t * mp)
2008 {
2009   /* not supported */
2010 }
2011
2012 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2013   (vl_api_vnet_ip6_fib_counters_t * mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016   vl_api_ip6_fib_counter_t *v;
2017   ip6_fib_counter_t *counter;
2018   struct in6_addr ip6;
2019   u32 vrf_id;
2020   u32 vrf_index;
2021   u32 count;
2022   int i;
2023
2024   vrf_id = ntohl (mp->vrf_id);
2025   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2026   if (~0 == vrf_index)
2027     {
2028       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2029       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2030       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2031       vec_validate (vam->ip6_fib_counters, vrf_index);
2032       vam->ip6_fib_counters[vrf_index] = NULL;
2033     }
2034
2035   vec_free (vam->ip6_fib_counters[vrf_index]);
2036   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2037   count = ntohl (mp->count);
2038   for (i = 0; i < count; i++)
2039     {
2040       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2041       counter = &vam->ip6_fib_counters[vrf_index][i];
2042       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2043       counter->address = ip6;
2044       counter->address_length = v->address_length;
2045       counter->packets = clib_net_to_host_u64 (v->packets);
2046       counter->bytes = clib_net_to_host_u64 (v->bytes);
2047       v++;
2048     }
2049 }
2050
2051 static void vl_api_get_first_msg_id_reply_t_handler
2052   (vl_api_get_first_msg_id_reply_t * mp)
2053 {
2054   vat_main_t *vam = &vat_main;
2055   i32 retval = ntohl (mp->retval);
2056
2057   if (vam->async_mode)
2058     {
2059       vam->async_errors += (retval < 0);
2060     }
2061   else
2062     {
2063       vam->retval = retval;
2064       vam->result_ready = 1;
2065     }
2066   if (retval >= 0)
2067     {
2068       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2069     }
2070 }
2071
2072 static void vl_api_get_first_msg_id_reply_t_handler_json
2073   (vl_api_get_first_msg_id_reply_t * mp)
2074 {
2075   vat_main_t *vam = &vat_main;
2076   vat_json_node_t node;
2077
2078   vat_json_init_object (&node);
2079   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2080   vat_json_object_add_uint (&node, "first_msg_id",
2081                             (uint) ntohs (mp->first_msg_id));
2082
2083   vat_json_print (vam->ofp, &node);
2084   vat_json_free (&node);
2085
2086   vam->retval = ntohl (mp->retval);
2087   vam->result_ready = 1;
2088 }
2089
2090 static void vl_api_get_node_graph_reply_t_handler
2091   (vl_api_get_node_graph_reply_t * mp)
2092 {
2093   vat_main_t *vam = &vat_main;
2094   api_main_t *am = &api_main;
2095   i32 retval = ntohl (mp->retval);
2096   u8 *pvt_copy, *reply;
2097   void *oldheap;
2098   vlib_node_t *node;
2099   int i;
2100
2101   if (vam->async_mode)
2102     {
2103       vam->async_errors += (retval < 0);
2104     }
2105   else
2106     {
2107       vam->retval = retval;
2108       vam->result_ready = 1;
2109     }
2110
2111   /* "Should never happen..." */
2112   if (retval != 0)
2113     return;
2114
2115   reply = (u8 *) (mp->reply_in_shmem);
2116   pvt_copy = vec_dup (reply);
2117
2118   /* Toss the shared-memory original... */
2119   pthread_mutex_lock (&am->vlib_rp->mutex);
2120   oldheap = svm_push_data_heap (am->vlib_rp);
2121
2122   vec_free (reply);
2123
2124   svm_pop_heap (oldheap);
2125   pthread_mutex_unlock (&am->vlib_rp->mutex);
2126
2127   if (vam->graph_nodes)
2128     {
2129       hash_free (vam->graph_node_index_by_name);
2130
2131       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2132         {
2133           node = vam->graph_nodes[i];
2134           vec_free (node->name);
2135           vec_free (node->next_nodes);
2136           vec_free (node);
2137         }
2138       vec_free (vam->graph_nodes);
2139     }
2140
2141   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2142   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2143   vec_free (pvt_copy);
2144
2145   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2146     {
2147       node = vam->graph_nodes[i];
2148       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2149     }
2150 }
2151
2152 static void vl_api_get_node_graph_reply_t_handler_json
2153   (vl_api_get_node_graph_reply_t * mp)
2154 {
2155   vat_main_t *vam = &vat_main;
2156   api_main_t *am = &api_main;
2157   void *oldheap;
2158   vat_json_node_t node;
2159   u8 *reply;
2160
2161   /* $$$$ make this real? */
2162   vat_json_init_object (&node);
2163   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2164   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2165
2166   reply = (u8 *) (mp->reply_in_shmem);
2167
2168   /* Toss the shared-memory original... */
2169   pthread_mutex_lock (&am->vlib_rp->mutex);
2170   oldheap = svm_push_data_heap (am->vlib_rp);
2171
2172   vec_free (reply);
2173
2174   svm_pop_heap (oldheap);
2175   pthread_mutex_unlock (&am->vlib_rp->mutex);
2176
2177   vat_json_print (vam->ofp, &node);
2178   vat_json_free (&node);
2179
2180   vam->retval = ntohl (mp->retval);
2181   vam->result_ready = 1;
2182 }
2183
2184 static void
2185 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2186 {
2187   vat_main_t *vam = &vat_main;
2188   u8 *s = 0;
2189
2190   if (mp->local)
2191     {
2192       s = format (s, "%=16d%=16d%=16d\n",
2193                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2194     }
2195   else
2196     {
2197       s = format (s, "%=16U%=16d%=16d\n",
2198                   mp->is_ipv6 ? format_ip6_address :
2199                   format_ip4_address,
2200                   mp->ip_address, mp->priority, mp->weight);
2201     }
2202
2203   fformat (vam->ofp, "%v", s);
2204   vec_free (s);
2205 }
2206
2207 static void
2208 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2209                                             mp)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   vat_json_node_t *node = NULL;
2213   struct in6_addr ip6;
2214   struct in_addr ip4;
2215
2216   if (VAT_JSON_ARRAY != vam->json_tree.type)
2217     {
2218       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2219       vat_json_init_array (&vam->json_tree);
2220     }
2221   node = vat_json_array_add (&vam->json_tree);
2222   vat_json_init_object (node);
2223
2224   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2225   vat_json_object_add_uint (node, "priority", mp->priority);
2226   vat_json_object_add_uint (node, "weight", mp->weight);
2227
2228   if (mp->local)
2229     vat_json_object_add_uint (node, "sw_if_index",
2230                               clib_net_to_host_u32 (mp->sw_if_index));
2231   else
2232     {
2233       if (mp->is_ipv6)
2234         {
2235           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2236           vat_json_object_add_ip6 (node, "address", ip6);
2237         }
2238       else
2239         {
2240           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2241           vat_json_object_add_ip4 (node, "address", ip4);
2242         }
2243     }
2244 }
2245
2246 static void
2247 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2248                                            mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   u8 *ls_name = 0;
2252
2253   ls_name = format (0, "%s", mp->ls_name);
2254
2255   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2256            ls_name);
2257   vec_free (ls_name);
2258 }
2259
2260 static void
2261   vl_api_lisp_locator_set_details_t_handler_json
2262   (vl_api_lisp_locator_set_details_t * mp)
2263 {
2264   vat_main_t *vam = &vat_main;
2265   vat_json_node_t *node = 0;
2266   u8 *ls_name = 0;
2267
2268   ls_name = format (0, "%s", mp->ls_name);
2269   vec_add1 (ls_name, 0);
2270
2271   if (VAT_JSON_ARRAY != vam->json_tree.type)
2272     {
2273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2274       vat_json_init_array (&vam->json_tree);
2275     }
2276   node = vat_json_array_add (&vam->json_tree);
2277
2278   vat_json_init_object (node);
2279   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2280   vat_json_object_add_uint (node, "ls_index",
2281                             clib_net_to_host_u32 (mp->ls_index));
2282   vec_free (ls_name);
2283 }
2284
2285 static u8 *
2286 format_lisp_flat_eid (u8 * s, va_list * args)
2287 {
2288   u32 type = va_arg (*args, u32);
2289   u8 *eid = va_arg (*args, u8 *);
2290   u32 eid_len = va_arg (*args, u32);
2291
2292   switch (type)
2293     {
2294     case 0:
2295       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2296     case 1:
2297       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2298     case 2:
2299       return format (s, "%U", format_ethernet_address, eid);
2300     }
2301   return 0;
2302 }
2303
2304 static u8 *
2305 format_lisp_eid_vat (u8 * s, va_list * args)
2306 {
2307   u32 type = va_arg (*args, u32);
2308   u8 *eid = va_arg (*args, u8 *);
2309   u32 eid_len = va_arg (*args, u32);
2310   u8 *seid = va_arg (*args, u8 *);
2311   u32 seid_len = va_arg (*args, u32);
2312   u32 is_src_dst = va_arg (*args, u32);
2313
2314   if (is_src_dst)
2315     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2316
2317   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2318
2319   return s;
2320 }
2321
2322 static void
2323 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2324 {
2325   vat_main_t *vam = &vat_main;
2326   u8 *s = 0, *eid = 0;
2327
2328   if (~0 == mp->locator_set_index)
2329     s = format (0, "action: %d", mp->action);
2330   else
2331     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2332
2333   eid = format (0, "%U", format_lisp_eid_vat,
2334                 mp->eid_type,
2335                 mp->eid,
2336                 mp->eid_prefix_len,
2337                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2338   vec_add1 (eid, 0);
2339
2340   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2341            clib_net_to_host_u32 (mp->vni),
2342            eid,
2343            mp->is_local ? "local" : "remote",
2344            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2345   vec_free (s);
2346   vec_free (eid);
2347 }
2348
2349 static void
2350 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2351                                               * mp)
2352 {
2353   vat_main_t *vam = &vat_main;
2354   vat_json_node_t *node = 0;
2355   u8 *eid = 0;
2356
2357   if (VAT_JSON_ARRAY != vam->json_tree.type)
2358     {
2359       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2360       vat_json_init_array (&vam->json_tree);
2361     }
2362   node = vat_json_array_add (&vam->json_tree);
2363
2364   vat_json_init_object (node);
2365   if (~0 == mp->locator_set_index)
2366     vat_json_object_add_uint (node, "action", mp->action);
2367   else
2368     vat_json_object_add_uint (node, "locator_set_index",
2369                               clib_net_to_host_u32 (mp->locator_set_index));
2370
2371   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2372   eid = format (0, "%U", format_lisp_eid_vat,
2373                 mp->eid_type,
2374                 mp->eid,
2375                 mp->eid_prefix_len,
2376                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2377   vec_add1 (eid, 0);
2378   vat_json_object_add_string_copy (node, "eid", eid);
2379   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2380   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2381   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2382   vec_free (eid);
2383 }
2384
2385 static void
2386   vl_api_lisp_eid_table_map_details_t_handler
2387   (vl_api_lisp_eid_table_map_details_t * mp)
2388 {
2389   vat_main_t *vam = &vat_main;
2390
2391   u8 *line = format (0, "%=10d%=10d",
2392                      clib_net_to_host_u32 (mp->vni),
2393                      clib_net_to_host_u32 (mp->dp_table));
2394   fformat (vam->ofp, "%v\n", line);
2395   vec_free (line);
2396 }
2397
2398 static void
2399   vl_api_lisp_eid_table_map_details_t_handler_json
2400   (vl_api_lisp_eid_table_map_details_t * mp)
2401 {
2402   vat_main_t *vam = &vat_main;
2403   vat_json_node_t *node = NULL;
2404
2405   if (VAT_JSON_ARRAY != vam->json_tree.type)
2406     {
2407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2408       vat_json_init_array (&vam->json_tree);
2409     }
2410   node = vat_json_array_add (&vam->json_tree);
2411   vat_json_init_object (node);
2412   vat_json_object_add_uint (node, "dp_table",
2413                             clib_net_to_host_u32 (mp->dp_table));
2414   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2415 }
2416
2417 static void
2418   vl_api_lisp_eid_table_vni_details_t_handler
2419   (vl_api_lisp_eid_table_vni_details_t * mp)
2420 {
2421   vat_main_t *vam = &vat_main;
2422
2423   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2424   fformat (vam->ofp, "%v\n", line);
2425   vec_free (line);
2426 }
2427
2428 static void
2429   vl_api_lisp_eid_table_vni_details_t_handler_json
2430   (vl_api_lisp_eid_table_vni_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, "vni", clib_net_to_host_u32 (mp->vni));
2443 }
2444
2445 static u8 *
2446 format_decap_next (u8 * s, va_list * args)
2447 {
2448   u32 next_index = va_arg (*args, u32);
2449
2450   switch (next_index)
2451     {
2452     case LISP_GPE_INPUT_NEXT_DROP:
2453       return format (s, "drop");
2454     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2455       return format (s, "ip4");
2456     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2457       return format (s, "ip6");
2458     default:
2459       return format (s, "unknown %d", next_index);
2460     }
2461   return s;
2462 }
2463
2464 static void
2465 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2466                                           mp)
2467 {
2468   vat_main_t *vam = &vat_main;
2469   u8 *iid_str;
2470   u8 *flag_str = NULL;
2471
2472   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2473
2474 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2475   foreach_lisp_gpe_flag_bit;
2476 #undef _
2477
2478   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2479            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2480            mp->tunnels,
2481            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2482            mp->source_ip,
2483            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2484            mp->destination_ip,
2485            ntohl (mp->encap_fib_id),
2486            ntohl (mp->decap_fib_id),
2487            format_decap_next, ntohl (mp->dcap_next),
2488            mp->ver_res >> 6,
2489            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2490
2491   vec_free (iid_str);
2492 }
2493
2494 static void
2495   vl_api_lisp_gpe_tunnel_details_t_handler_json
2496   (vl_api_lisp_gpe_tunnel_details_t * mp)
2497 {
2498   vat_main_t *vam = &vat_main;
2499   vat_json_node_t *node = NULL;
2500   struct in6_addr ip6;
2501   struct in_addr ip4;
2502   u8 *next_decap_str;
2503
2504   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2505
2506   if (VAT_JSON_ARRAY != vam->json_tree.type)
2507     {
2508       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2509       vat_json_init_array (&vam->json_tree);
2510     }
2511   node = vat_json_array_add (&vam->json_tree);
2512
2513   vat_json_init_object (node);
2514   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2515   if (mp->is_ipv6)
2516     {
2517       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2518       vat_json_object_add_ip6 (node, "source address", ip6);
2519       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2520       vat_json_object_add_ip6 (node, "destination address", ip6);
2521     }
2522   else
2523     {
2524       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2525       vat_json_object_add_ip4 (node, "source address", ip4);
2526       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2527       vat_json_object_add_ip4 (node, "destination address", ip4);
2528     }
2529   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2530   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2531   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2532   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2533   vat_json_object_add_uint (node, "flags", mp->flags);
2534   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2535   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2536   vat_json_object_add_uint (node, "res", mp->res);
2537   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2538
2539   vec_free (next_decap_str);
2540 }
2541
2542 static void
2543   vl_api_lisp_adjacencies_get_reply_t_handler
2544   (vl_api_lisp_adjacencies_get_reply_t * mp)
2545 {
2546   vat_main_t *vam = &vat_main;
2547   u32 i, n;
2548   int retval = clib_net_to_host_u32 (mp->retval);
2549   vl_api_lisp_adjacency_t *a;
2550
2551   if (retval)
2552     goto end;
2553
2554   n = clib_net_to_host_u32 (mp->count);
2555
2556   for (i = 0; i < n; i++)
2557     {
2558       a = &mp->adjacencies[i];
2559       fformat (vam->ofp, "%U %40U\n",
2560                format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2561                format_lisp_flat_eid, a->eid_type, a->reid,
2562                a->reid_prefix_len);
2563     }
2564
2565 end:
2566   vam->retval = retval;
2567   vam->result_ready = 1;
2568 }
2569
2570 static void
2571   vl_api_lisp_adjacencies_get_reply_t_handler_json
2572   (vl_api_lisp_adjacencies_get_reply_t * mp)
2573 {
2574   u8 *s = 0;
2575   vat_main_t *vam = &vat_main;
2576   vat_json_node_t *e = 0, root;
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   vat_json_init_array (&root);
2586
2587   for (i = 0; i < n; i++)
2588     {
2589       e = vat_json_array_add (&root);
2590       a = &mp->adjacencies[i];
2591
2592       vat_json_init_object (e);
2593       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2594                   a->leid_prefix_len);
2595       vec_add1 (s, 0);
2596       vat_json_object_add_string_copy (e, "leid", s);
2597       vec_free (s);
2598
2599       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2600                   a->reid_prefix_len);
2601       vec_add1 (s, 0);
2602       vat_json_object_add_string_copy (e, "reid", s);
2603       vec_free (s);
2604     }
2605
2606   vat_json_print (vam->ofp, &root);
2607   vat_json_free (&root);
2608
2609 end:
2610   vam->retval = retval;
2611   vam->result_ready = 1;
2612 }
2613
2614 static void
2615 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2616                                             * mp)
2617 {
2618   vat_main_t *vam = &vat_main;
2619
2620   fformat (vam->ofp, "%=20U\n",
2621            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2622            mp->ip_address);
2623 }
2624
2625 static void
2626   vl_api_lisp_map_resolver_details_t_handler_json
2627   (vl_api_lisp_map_resolver_details_t * mp)
2628 {
2629   vat_main_t *vam = &vat_main;
2630   vat_json_node_t *node = NULL;
2631   struct in6_addr ip6;
2632   struct in_addr ip4;
2633
2634   if (VAT_JSON_ARRAY != vam->json_tree.type)
2635     {
2636       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2637       vat_json_init_array (&vam->json_tree);
2638     }
2639   node = vat_json_array_add (&vam->json_tree);
2640
2641   vat_json_init_object (node);
2642   if (mp->is_ipv6)
2643     {
2644       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2645       vat_json_object_add_ip6 (node, "map resolver", ip6);
2646     }
2647   else
2648     {
2649       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2650       vat_json_object_add_ip4 (node, "map resolver", ip4);
2651     }
2652 }
2653
2654 static void
2655   vl_api_show_lisp_status_reply_t_handler
2656   (vl_api_show_lisp_status_reply_t * mp)
2657 {
2658   vat_main_t *vam = &vat_main;
2659   i32 retval = ntohl (mp->retval);
2660
2661   if (0 <= retval)
2662     {
2663       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2664                mp->feature_status ? "enabled" : "disabled",
2665                mp->gpe_status ? "enabled" : "disabled");
2666     }
2667
2668   vam->retval = retval;
2669   vam->result_ready = 1;
2670 }
2671
2672 static void
2673   vl_api_show_lisp_status_reply_t_handler_json
2674   (vl_api_show_lisp_status_reply_t * mp)
2675 {
2676   vat_main_t *vam = &vat_main;
2677   vat_json_node_t node;
2678   u8 *gpe_status = NULL;
2679   u8 *feature_status = NULL;
2680
2681   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2682   feature_status = format (0, "%s",
2683                            mp->feature_status ? "enabled" : "disabled");
2684   vec_add1 (gpe_status, 0);
2685   vec_add1 (feature_status, 0);
2686
2687   vat_json_init_object (&node);
2688   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2689   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2690
2691   vec_free (gpe_status);
2692   vec_free (feature_status);
2693
2694   vat_json_print (vam->ofp, &node);
2695   vat_json_free (&node);
2696
2697   vam->retval = ntohl (mp->retval);
2698   vam->result_ready = 1;
2699 }
2700
2701 static void
2702   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2703   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2704 {
2705   vat_main_t *vam = &vat_main;
2706   i32 retval = ntohl (mp->retval);
2707
2708   if (retval >= 0)
2709     {
2710       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2711     }
2712
2713   vam->retval = retval;
2714   vam->result_ready = 1;
2715 }
2716
2717 static void
2718   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2719   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2720 {
2721   vat_main_t *vam = &vat_main;
2722   vat_json_node_t *node = NULL;
2723
2724   if (VAT_JSON_ARRAY != vam->json_tree.type)
2725     {
2726       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2727       vat_json_init_array (&vam->json_tree);
2728     }
2729   node = vat_json_array_add (&vam->json_tree);
2730
2731   vat_json_init_object (node);
2732   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2733
2734   vat_json_print (vam->ofp, node);
2735   vat_json_free (node);
2736
2737   vam->retval = ntohl (mp->retval);
2738   vam->result_ready = 1;
2739 }
2740
2741 static u8 *
2742 format_lisp_map_request_mode (u8 * s, va_list * args)
2743 {
2744   u32 mode = va_arg (*args, u32);
2745
2746   switch (mode)
2747     {
2748     case 0:
2749       return format (0, "dst-only");
2750     case 1:
2751       return format (0, "src-dst");
2752     }
2753   return 0;
2754 }
2755
2756 static void
2757   vl_api_show_lisp_map_request_mode_reply_t_handler
2758   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2759 {
2760   vat_main_t *vam = &vat_main;
2761   i32 retval = ntohl (mp->retval);
2762
2763   if (0 <= retval)
2764     {
2765       u32 mode = mp->mode;
2766       fformat (vam->ofp, "map_request_mode: %U\n",
2767                format_lisp_map_request_mode, mode);
2768     }
2769
2770   vam->retval = retval;
2771   vam->result_ready = 1;
2772 }
2773
2774 static void
2775   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2776   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2777 {
2778   vat_main_t *vam = &vat_main;
2779   vat_json_node_t node;
2780   u8 *s = 0;
2781   u32 mode;
2782
2783   mode = mp->mode;
2784   s = format (0, "%U", format_lisp_map_request_mode, mode);
2785   vec_add1 (s, 0);
2786
2787   vat_json_init_object (&node);
2788   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2789   vat_json_print (vam->ofp, &node);
2790   vat_json_free (&node);
2791
2792   vec_free (s);
2793   vam->retval = ntohl (mp->retval);
2794   vam->result_ready = 1;
2795 }
2796
2797 static void
2798 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2799 {
2800   vat_main_t *vam = &vat_main;
2801   i32 retval = ntohl (mp->retval);
2802
2803   if (0 <= retval)
2804     {
2805       fformat (vam->ofp, "%-20s%-16s\n",
2806                mp->status ? "enabled" : "disabled",
2807                mp->status ? (char *) mp->locator_set_name : "");
2808     }
2809
2810   vam->retval = retval;
2811   vam->result_ready = 1;
2812 }
2813
2814 static void
2815 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2816                                             mp)
2817 {
2818   vat_main_t *vam = &vat_main;
2819   vat_json_node_t node;
2820   u8 *status = 0;
2821
2822   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2823   vec_add1 (status, 0);
2824
2825   vat_json_init_object (&node);
2826   vat_json_object_add_string_copy (&node, "status", status);
2827   if (mp->status)
2828     {
2829       vat_json_object_add_string_copy (&node, "locator_set",
2830                                        mp->locator_set_name);
2831     }
2832
2833   vec_free (status);
2834
2835   vat_json_print (vam->ofp, &node);
2836   vat_json_free (&node);
2837
2838   vam->retval = ntohl (mp->retval);
2839   vam->result_ready = 1;
2840 }
2841
2842 static u8 *
2843 format_policer_type (u8 * s, va_list * va)
2844 {
2845   u32 i = va_arg (*va, u32);
2846
2847   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2848     s = format (s, "1r2c");
2849   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2850     s = format (s, "1r3c");
2851   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2852     s = format (s, "2r3c-2698");
2853   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2854     s = format (s, "2r3c-4115");
2855   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2856     s = format (s, "2r3c-mef5cf1");
2857   else
2858     s = format (s, "ILLEGAL");
2859   return s;
2860 }
2861
2862 static u8 *
2863 format_policer_rate_type (u8 * s, va_list * va)
2864 {
2865   u32 i = va_arg (*va, u32);
2866
2867   if (i == SSE2_QOS_RATE_KBPS)
2868     s = format (s, "kbps");
2869   else if (i == SSE2_QOS_RATE_PPS)
2870     s = format (s, "pps");
2871   else
2872     s = format (s, "ILLEGAL");
2873   return s;
2874 }
2875
2876 static u8 *
2877 format_policer_round_type (u8 * s, va_list * va)
2878 {
2879   u32 i = va_arg (*va, u32);
2880
2881   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2882     s = format (s, "closest");
2883   else if (i == SSE2_QOS_ROUND_TO_UP)
2884     s = format (s, "up");
2885   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2886     s = format (s, "down");
2887   else
2888     s = format (s, "ILLEGAL");
2889   return s;
2890 }
2891
2892 static u8 *
2893 format_policer_action_type (u8 * s, va_list * va)
2894 {
2895   u32 i = va_arg (*va, u32);
2896
2897   if (i == SSE2_QOS_ACTION_DROP)
2898     s = format (s, "drop");
2899   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2900     s = format (s, "transmit");
2901   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2902     s = format (s, "mark-and-transmit");
2903   else
2904     s = format (s, "ILLEGAL");
2905   return s;
2906 }
2907
2908 static u8 *
2909 format_dscp (u8 * s, va_list * va)
2910 {
2911   u32 i = va_arg (*va, u32);
2912   char *t = 0;
2913
2914   switch (i)
2915     {
2916 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2917       foreach_vnet_dscp
2918 #undef _
2919     default:
2920       return format (s, "ILLEGAL");
2921     }
2922   s = format (s, "%s", t);
2923   return s;
2924 }
2925
2926 static void
2927 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2928 {
2929   vat_main_t *vam = &vat_main;
2930   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2931
2932   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2933     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2934   else
2935     conform_dscp_str = format (0, "");
2936
2937   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2938     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2939   else
2940     exceed_dscp_str = format (0, "");
2941
2942   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2943     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2944   else
2945     violate_dscp_str = format (0, "");
2946
2947   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2948            "rate type %U, round type %U, %s rate, %s color-aware, "
2949            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2950            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2951            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2952            mp->name,
2953            format_policer_type, mp->type,
2954            ntohl (mp->cir),
2955            ntohl (mp->eir),
2956            clib_net_to_host_u64 (mp->cb),
2957            clib_net_to_host_u64 (mp->eb),
2958            format_policer_rate_type, mp->rate_type,
2959            format_policer_round_type, mp->round_type,
2960            mp->single_rate ? "single" : "dual",
2961            mp->color_aware ? "is" : "not",
2962            ntohl (mp->cir_tokens_per_period),
2963            ntohl (mp->pir_tokens_per_period),
2964            ntohl (mp->scale),
2965            ntohl (mp->current_limit),
2966            ntohl (mp->current_bucket),
2967            ntohl (mp->extended_limit),
2968            ntohl (mp->extended_bucket),
2969            clib_net_to_host_u64 (mp->last_update_time),
2970            format_policer_action_type, mp->conform_action_type,
2971            conform_dscp_str,
2972            format_policer_action_type, mp->exceed_action_type,
2973            exceed_dscp_str,
2974            format_policer_action_type, mp->violate_action_type,
2975            violate_dscp_str);
2976
2977   vec_free (conform_dscp_str);
2978   vec_free (exceed_dscp_str);
2979   vec_free (violate_dscp_str);
2980 }
2981
2982 static void vl_api_policer_details_t_handler_json
2983   (vl_api_policer_details_t * mp)
2984 {
2985   vat_main_t *vam = &vat_main;
2986   vat_json_node_t *node;
2987   u8 *rate_type_str, *round_type_str, *type_str;
2988   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2989
2990   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2991   round_type_str =
2992     format (0, "%U", format_policer_round_type, mp->round_type);
2993   type_str = format (0, "%U", format_policer_type, mp->type);
2994   conform_action_str = format (0, "%U", format_policer_action_type,
2995                                mp->conform_action_type);
2996   exceed_action_str = format (0, "%U", format_policer_action_type,
2997                               mp->exceed_action_type);
2998   violate_action_str = format (0, "%U", format_policer_action_type,
2999                                mp->violate_action_type);
3000
3001   if (VAT_JSON_ARRAY != vam->json_tree.type)
3002     {
3003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3004       vat_json_init_array (&vam->json_tree);
3005     }
3006   node = vat_json_array_add (&vam->json_tree);
3007
3008   vat_json_init_object (node);
3009   vat_json_object_add_string_copy (node, "name", mp->name);
3010   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3011   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3012   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3013   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3014   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3015   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3016   vat_json_object_add_string_copy (node, "type", type_str);
3017   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3018   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3019   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3020   vat_json_object_add_uint (node, "cir_tokens_per_period",
3021                             ntohl (mp->cir_tokens_per_period));
3022   vat_json_object_add_uint (node, "eir_tokens_per_period",
3023                             ntohl (mp->pir_tokens_per_period));
3024   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3025   vat_json_object_add_uint (node, "current_bucket",
3026                             ntohl (mp->current_bucket));
3027   vat_json_object_add_uint (node, "extended_limit",
3028                             ntohl (mp->extended_limit));
3029   vat_json_object_add_uint (node, "extended_bucket",
3030                             ntohl (mp->extended_bucket));
3031   vat_json_object_add_uint (node, "last_update_time",
3032                             ntohl (mp->last_update_time));
3033   vat_json_object_add_string_copy (node, "conform_action",
3034                                    conform_action_str);
3035   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3036     {
3037       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3038       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3039       vec_free (dscp_str);
3040     }
3041   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3042   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3043     {
3044       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3045       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3046       vec_free (dscp_str);
3047     }
3048   vat_json_object_add_string_copy (node, "violate_action",
3049                                    violate_action_str);
3050   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3051     {
3052       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3053       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3054       vec_free (dscp_str);
3055     }
3056
3057   vec_free (rate_type_str);
3058   vec_free (round_type_str);
3059   vec_free (type_str);
3060   vec_free (conform_action_str);
3061   vec_free (exceed_action_str);
3062   vec_free (violate_action_str);
3063 }
3064
3065 static void
3066 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3067                                            mp)
3068 {
3069   vat_main_t *vam = &vat_main;
3070   int i, count = ntohl (mp->count);
3071
3072   if (count > 0)
3073     fformat (vam->ofp, "classify table ids (%d) : ", count);
3074   for (i = 0; i < count; i++)
3075     {
3076       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3077       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3078     }
3079   vam->retval = ntohl (mp->retval);
3080   vam->result_ready = 1;
3081 }
3082
3083 static void
3084   vl_api_classify_table_ids_reply_t_handler_json
3085   (vl_api_classify_table_ids_reply_t * mp)
3086 {
3087   vat_main_t *vam = &vat_main;
3088   int i, count = ntohl (mp->count);
3089
3090   if (count > 0)
3091     {
3092       vat_json_node_t node;
3093
3094       vat_json_init_object (&node);
3095       for (i = 0; i < count; i++)
3096         {
3097           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3098         }
3099       vat_json_print (vam->ofp, &node);
3100       vat_json_free (&node);
3101     }
3102   vam->retval = ntohl (mp->retval);
3103   vam->result_ready = 1;
3104 }
3105
3106 static void
3107   vl_api_classify_table_by_interface_reply_t_handler
3108   (vl_api_classify_table_by_interface_reply_t * mp)
3109 {
3110   vat_main_t *vam = &vat_main;
3111   u32 table_id;
3112
3113   table_id = ntohl (mp->l2_table_id);
3114   if (table_id != ~0)
3115     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3116   else
3117     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3118   table_id = ntohl (mp->ip4_table_id);
3119   if (table_id != ~0)
3120     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3121   else
3122     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3123   table_id = ntohl (mp->ip6_table_id);
3124   if (table_id != ~0)
3125     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3126   else
3127     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3128   vam->retval = ntohl (mp->retval);
3129   vam->result_ready = 1;
3130 }
3131
3132 static void
3133   vl_api_classify_table_by_interface_reply_t_handler_json
3134   (vl_api_classify_table_by_interface_reply_t * mp)
3135 {
3136   vat_main_t *vam = &vat_main;
3137   vat_json_node_t node;
3138
3139   vat_json_init_object (&node);
3140
3141   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3142   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3143   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3144
3145   vat_json_print (vam->ofp, &node);
3146   vat_json_free (&node);
3147
3148   vam->retval = ntohl (mp->retval);
3149   vam->result_ready = 1;
3150 }
3151
3152 static void vl_api_policer_add_del_reply_t_handler
3153   (vl_api_policer_add_del_reply_t * mp)
3154 {
3155   vat_main_t *vam = &vat_main;
3156   i32 retval = ntohl (mp->retval);
3157   if (vam->async_mode)
3158     {
3159       vam->async_errors += (retval < 0);
3160     }
3161   else
3162     {
3163       vam->retval = retval;
3164       vam->result_ready = 1;
3165       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3166         /*
3167          * Note: this is just barely thread-safe, depends on
3168          * the main thread spinning waiting for an answer...
3169          */
3170         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3171     }
3172 }
3173
3174 static void vl_api_policer_add_del_reply_t_handler_json
3175   (vl_api_policer_add_del_reply_t * mp)
3176 {
3177   vat_main_t *vam = &vat_main;
3178   vat_json_node_t node;
3179
3180   vat_json_init_object (&node);
3181   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3182   vat_json_object_add_uint (&node, "policer_index",
3183                             ntohl (mp->policer_index));
3184
3185   vat_json_print (vam->ofp, &node);
3186   vat_json_free (&node);
3187
3188   vam->retval = ntohl (mp->retval);
3189   vam->result_ready = 1;
3190 }
3191
3192 /* Format hex dump. */
3193 u8 *
3194 format_hex_bytes (u8 * s, va_list * va)
3195 {
3196   u8 *bytes = va_arg (*va, u8 *);
3197   int n_bytes = va_arg (*va, int);
3198   uword i;
3199
3200   /* Print short or long form depending on byte count. */
3201   uword short_form = n_bytes <= 32;
3202   uword indent = format_get_indent (s);
3203
3204   if (n_bytes == 0)
3205     return s;
3206
3207   for (i = 0; i < n_bytes; i++)
3208     {
3209       if (!short_form && (i % 32) == 0)
3210         s = format (s, "%08x: ", i);
3211       s = format (s, "%02x", bytes[i]);
3212       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3213         s = format (s, "\n%U", format_white_space, indent);
3214     }
3215
3216   return s;
3217 }
3218
3219 static void
3220 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3221                                             * mp)
3222 {
3223   vat_main_t *vam = &vat_main;
3224   i32 retval = ntohl (mp->retval);
3225   if (retval == 0)
3226     {
3227       fformat (vam->ofp, "classify table info :\n");
3228       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3229                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3230                ntohl (mp->miss_next_index));
3231       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3232                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3233                ntohl (mp->match_n_vectors));
3234       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3235                ntohl (mp->mask_length));
3236     }
3237   vam->retval = retval;
3238   vam->result_ready = 1;
3239 }
3240
3241 static void
3242   vl_api_classify_table_info_reply_t_handler_json
3243   (vl_api_classify_table_info_reply_t * mp)
3244 {
3245   vat_main_t *vam = &vat_main;
3246   vat_json_node_t node;
3247
3248   i32 retval = ntohl (mp->retval);
3249   if (retval == 0)
3250     {
3251       vat_json_init_object (&node);
3252
3253       vat_json_object_add_int (&node, "sessions",
3254                                ntohl (mp->active_sessions));
3255       vat_json_object_add_int (&node, "nexttbl",
3256                                ntohl (mp->next_table_index));
3257       vat_json_object_add_int (&node, "nextnode",
3258                                ntohl (mp->miss_next_index));
3259       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3260       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3261       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3262       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3263                       ntohl (mp->mask_length), 0);
3264       vat_json_object_add_string_copy (&node, "mask", s);
3265
3266       vat_json_print (vam->ofp, &node);
3267       vat_json_free (&node);
3268     }
3269   vam->retval = ntohl (mp->retval);
3270   vam->result_ready = 1;
3271 }
3272
3273 static void
3274 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3275                                            mp)
3276 {
3277   vat_main_t *vam = &vat_main;
3278
3279   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3280            ntohl (mp->hit_next_index), ntohl (mp->advance),
3281            ntohl (mp->opaque_index));
3282   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3283            ntohl (mp->match_length));
3284 }
3285
3286 static void
3287   vl_api_classify_session_details_t_handler_json
3288   (vl_api_classify_session_details_t * mp)
3289 {
3290   vat_main_t *vam = &vat_main;
3291   vat_json_node_t *node = NULL;
3292
3293   if (VAT_JSON_ARRAY != vam->json_tree.type)
3294     {
3295       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3296       vat_json_init_array (&vam->json_tree);
3297     }
3298   node = vat_json_array_add (&vam->json_tree);
3299
3300   vat_json_init_object (node);
3301   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3302   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3303   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3304   u8 *s =
3305     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3306             0);
3307   vat_json_object_add_string_copy (node, "match", s);
3308 }
3309
3310 static void vl_api_pg_create_interface_reply_t_handler
3311   (vl_api_pg_create_interface_reply_t * mp)
3312 {
3313   vat_main_t *vam = &vat_main;
3314
3315   vam->retval = ntohl (mp->retval);
3316   vam->result_ready = 1;
3317 }
3318
3319 static void vl_api_pg_create_interface_reply_t_handler_json
3320   (vl_api_pg_create_interface_reply_t * mp)
3321 {
3322   vat_main_t *vam = &vat_main;
3323   vat_json_node_t node;
3324
3325   i32 retval = ntohl (mp->retval);
3326   if (retval == 0)
3327     {
3328       vat_json_init_object (&node);
3329
3330       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3331
3332       vat_json_print (vam->ofp, &node);
3333       vat_json_free (&node);
3334     }
3335   vam->retval = ntohl (mp->retval);
3336   vam->result_ready = 1;
3337 }
3338
3339 static void vl_api_policer_classify_details_t_handler
3340   (vl_api_policer_classify_details_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343
3344   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3345            ntohl (mp->table_index));
3346 }
3347
3348 static void vl_api_policer_classify_details_t_handler_json
3349   (vl_api_policer_classify_details_t * mp)
3350 {
3351   vat_main_t *vam = &vat_main;
3352   vat_json_node_t *node;
3353
3354   if (VAT_JSON_ARRAY != vam->json_tree.type)
3355     {
3356       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3357       vat_json_init_array (&vam->json_tree);
3358     }
3359   node = vat_json_array_add (&vam->json_tree);
3360
3361   vat_json_init_object (node);
3362   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3363   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3364 }
3365
3366 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3367   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3368 {
3369   vat_main_t *vam = &vat_main;
3370   i32 retval = ntohl (mp->retval);
3371   if (vam->async_mode)
3372     {
3373       vam->async_errors += (retval < 0);
3374     }
3375   else
3376     {
3377       vam->retval = retval;
3378       vam->sw_if_index = ntohl (mp->sw_if_index);
3379       vam->result_ready = 1;
3380     }
3381 }
3382
3383 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3384   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3385 {
3386   vat_main_t *vam = &vat_main;
3387   vat_json_node_t node;
3388
3389   vat_json_init_object (&node);
3390   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3391   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3392
3393   vat_json_print (vam->ofp, &node);
3394   vat_json_free (&node);
3395
3396   vam->retval = ntohl (mp->retval);
3397   vam->result_ready = 1;
3398 }
3399
3400 static void vl_api_flow_classify_details_t_handler
3401   (vl_api_flow_classify_details_t * mp)
3402 {
3403   vat_main_t *vam = &vat_main;
3404
3405   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3406            ntohl (mp->table_index));
3407 }
3408
3409 static void vl_api_flow_classify_details_t_handler_json
3410   (vl_api_flow_classify_details_t * mp)
3411 {
3412   vat_main_t *vam = &vat_main;
3413   vat_json_node_t *node;
3414
3415   if (VAT_JSON_ARRAY != vam->json_tree.type)
3416     {
3417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3418       vat_json_init_array (&vam->json_tree);
3419     }
3420   node = vat_json_array_add (&vam->json_tree);
3421
3422   vat_json_init_object (node);
3423   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3424   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3425 }
3426
3427
3428
3429 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3430 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3431 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3432 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3433 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3434 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3435
3436 /*
3437  * Generate boilerplate reply handlers, which
3438  * dig the return value out of the xxx_reply_t API message,
3439  * stick it into vam->retval, and set vam->result_ready
3440  *
3441  * Could also do this by pointing N message decode slots at
3442  * a single function, but that could break in subtle ways.
3443  */
3444
3445 #define foreach_standard_reply_retval_handler           \
3446 _(sw_interface_set_flags_reply)                         \
3447 _(sw_interface_add_del_address_reply)                   \
3448 _(sw_interface_set_table_reply)                         \
3449 _(sw_interface_set_mpls_enable_reply)                   \
3450 _(sw_interface_set_vpath_reply)                         \
3451 _(sw_interface_set_l2_bridge_reply)                     \
3452 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3453 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3454 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3455 _(bridge_domain_add_del_reply)                          \
3456 _(sw_interface_set_l2_xconnect_reply)                   \
3457 _(l2fib_add_del_reply)                                  \
3458 _(ip_add_del_route_reply)                               \
3459 _(mpls_route_add_del_reply)                             \
3460 _(mpls_ip_bind_unbind_reply)                            \
3461 _(proxy_arp_add_del_reply)                              \
3462 _(proxy_arp_intfc_enable_disable_reply)                 \
3463 _(mpls_add_del_encap_reply)                             \
3464 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3465 _(sw_interface_set_unnumbered_reply)                    \
3466 _(ip_neighbor_add_del_reply)                            \
3467 _(reset_vrf_reply)                                      \
3468 _(oam_add_del_reply)                                    \
3469 _(reset_fib_reply)                                      \
3470 _(dhcp_proxy_config_reply)                              \
3471 _(dhcp_proxy_config_2_reply)                            \
3472 _(dhcp_proxy_set_vss_reply)                             \
3473 _(dhcp_client_config_reply)                             \
3474 _(set_ip_flow_hash_reply)                               \
3475 _(sw_interface_ip6_enable_disable_reply)                \
3476 _(sw_interface_ip6_set_link_local_address_reply)        \
3477 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3478 _(sw_interface_ip6nd_ra_config_reply)                   \
3479 _(set_arp_neighbor_limit_reply)                         \
3480 _(l2_patch_add_del_reply)                               \
3481 _(sr_tunnel_add_del_reply)                              \
3482 _(sr_policy_add_del_reply)                              \
3483 _(sr_multicast_map_add_del_reply)                       \
3484 _(classify_add_del_session_reply)                       \
3485 _(classify_set_interface_ip_table_reply)                \
3486 _(classify_set_interface_l2_tables_reply)               \
3487 _(l2tpv3_set_tunnel_cookies_reply)                      \
3488 _(l2tpv3_interface_enable_disable_reply)                \
3489 _(l2tpv3_set_lookup_key_reply)                          \
3490 _(l2_fib_clear_table_reply)                             \
3491 _(l2_interface_efp_filter_reply)                        \
3492 _(l2_interface_vlan_tag_rewrite_reply)                  \
3493 _(modify_vhost_user_if_reply)                           \
3494 _(delete_vhost_user_if_reply)                           \
3495 _(want_ip4_arp_events_reply)                            \
3496 _(want_ip6_nd_events_reply)                             \
3497 _(input_acl_set_interface_reply)                        \
3498 _(ipsec_spd_add_del_reply)                              \
3499 _(ipsec_interface_add_del_spd_reply)                    \
3500 _(ipsec_spd_add_del_entry_reply)                        \
3501 _(ipsec_sad_add_del_entry_reply)                        \
3502 _(ipsec_sa_set_key_reply)                               \
3503 _(ikev2_profile_add_del_reply)                          \
3504 _(ikev2_profile_set_auth_reply)                         \
3505 _(ikev2_profile_set_id_reply)                           \
3506 _(ikev2_profile_set_ts_reply)                           \
3507 _(ikev2_set_local_key_reply)                            \
3508 _(delete_loopback_reply)                                \
3509 _(bd_ip_mac_add_del_reply)                              \
3510 _(map_del_domain_reply)                                 \
3511 _(map_add_del_rule_reply)                               \
3512 _(want_interface_events_reply)                          \
3513 _(want_stats_reply)                                     \
3514 _(cop_interface_enable_disable_reply)                   \
3515 _(cop_whitelist_enable_disable_reply)                   \
3516 _(sw_interface_clear_stats_reply)                       \
3517 _(ioam_enable_reply)                              \
3518 _(ioam_disable_reply)                              \
3519 _(lisp_add_del_locator_reply)                           \
3520 _(lisp_add_del_local_eid_reply)                         \
3521 _(lisp_add_del_remote_mapping_reply)                    \
3522 _(lisp_add_del_adjacency_reply)                         \
3523 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3524 _(lisp_add_del_map_resolver_reply)                      \
3525 _(lisp_gpe_enable_disable_reply)                        \
3526 _(lisp_gpe_add_del_iface_reply)                         \
3527 _(lisp_enable_disable_reply)                            \
3528 _(lisp_pitr_set_locator_set_reply)                      \
3529 _(lisp_map_request_mode_reply)                          \
3530 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3531 _(lisp_eid_table_add_del_map_reply)                     \
3532 _(vxlan_gpe_add_del_tunnel_reply)                       \
3533 _(af_packet_delete_reply)                               \
3534 _(policer_classify_set_interface_reply)                 \
3535 _(netmap_create_reply)                                  \
3536 _(netmap_delete_reply)                                  \
3537 _(set_ipfix_exporter_reply)                             \
3538 _(set_ipfix_classify_stream_reply)                      \
3539 _(ipfix_classify_table_add_del_reply)                   \
3540 _(flow_classify_set_interface_reply)                    \
3541 _(sw_interface_span_enable_disable_reply)               \
3542 _(pg_capture_reply)                                     \
3543 _(pg_enable_disable_reply)                              \
3544 _(ip_source_and_port_range_check_add_del_reply)         \
3545 _(ip_source_and_port_range_check_interface_add_del_reply)\
3546 _(delete_subif_reply)                                   \
3547 _(l2_interface_pbb_tag_rewrite_reply)                   \
3548 _(punt_reply)                                           \
3549 _(feature_enable_disable_reply)
3550
3551 #define _(n)                                    \
3552     static void vl_api_##n##_t_handler          \
3553     (vl_api_##n##_t * mp)                       \
3554     {                                           \
3555         vat_main_t * vam = &vat_main;           \
3556         i32 retval = ntohl(mp->retval);         \
3557         if (vam->async_mode) {                  \
3558             vam->async_errors += (retval < 0);  \
3559         } else {                                \
3560             vam->retval = retval;               \
3561             vam->result_ready = 1;              \
3562         }                                       \
3563     }
3564 foreach_standard_reply_retval_handler;
3565 #undef _
3566
3567 #define _(n)                                    \
3568     static void vl_api_##n##_t_handler_json     \
3569     (vl_api_##n##_t * mp)                       \
3570     {                                           \
3571         vat_main_t * vam = &vat_main;           \
3572         vat_json_node_t node;                   \
3573         vat_json_init_object(&node);            \
3574         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3575         vat_json_print(vam->ofp, &node);        \
3576         vam->retval = ntohl(mp->retval);        \
3577         vam->result_ready = 1;                  \
3578     }
3579 foreach_standard_reply_retval_handler;
3580 #undef _
3581
3582 /*
3583  * Table of message reply handlers, must include boilerplate handlers
3584  * we just generated
3585  */
3586
3587 #define foreach_vpe_api_reply_msg                                       \
3588 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3589 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3590 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3591 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3592 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3593 _(CLI_REPLY, cli_reply)                                                 \
3594 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3595 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3596   sw_interface_add_del_address_reply)                                   \
3597 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3598 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3599 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3600 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3601   sw_interface_set_l2_xconnect_reply)                                   \
3602 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3603   sw_interface_set_l2_bridge_reply)                                     \
3604 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3605   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3606 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3607   sw_interface_set_dpdk_hqos_subport_reply)                             \
3608 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3609   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3610 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3611 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3612 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3613 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3614 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3615 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3616 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3617 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3618 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3619 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3620 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3621 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3622 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3623 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3624 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3625   proxy_arp_intfc_enable_disable_reply)                                 \
3626 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3627 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3628   mpls_ethernet_add_del_tunnel_reply)                                   \
3629 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3630   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3631 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3632   sw_interface_set_unnumbered_reply)                                    \
3633 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3634 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3635 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3636 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3637 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3638 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3639 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3640 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3641 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3642 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3643 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3644 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3645   sw_interface_ip6_enable_disable_reply)                                \
3646 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3647   sw_interface_ip6_set_link_local_address_reply)                        \
3648 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3649   sw_interface_ip6nd_ra_prefix_reply)                                   \
3650 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3651   sw_interface_ip6nd_ra_config_reply)                                   \
3652 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3653 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3654 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3655 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3656 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3657 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3658 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3659 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3660 classify_set_interface_ip_table_reply)                                  \
3661 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3662   classify_set_interface_l2_tables_reply)                               \
3663 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3664 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3665 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3666 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3667 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3668   l2tpv3_interface_enable_disable_reply)                                \
3669 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3670 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3671 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3672 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3673 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3674 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3675 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3676 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3677 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3678 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3679 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3680 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3681 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3682 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3683 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3684 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3685 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3686 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3687 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3688 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3689 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3690 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3691 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3692 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3693 _(IP_DETAILS, ip_details)                                               \
3694 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3695 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3696 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3697 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3698 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3699 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3700 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3701 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3702 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3703 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3704 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3705 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3706 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3707 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3708 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3709 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3710 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3711 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3712 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3713 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3714 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3715 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3716 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3717 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3718 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3719 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3720 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3721 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3722 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3723 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3724 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3725 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3726 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3727 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3728 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3729 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3730 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3731 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3732 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3733 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3734 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3735 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3736 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3737 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3738 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3739 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3740 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3741 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3742 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3743 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3744 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3745 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3746 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3747   lisp_add_del_map_request_itr_rlocs_reply)                             \
3748 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3749   lisp_get_map_request_itr_rlocs_reply)                                 \
3750 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3751 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3752 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3753 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3754 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3755 _(POLICER_DETAILS, policer_details)                                     \
3756 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3757 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3758 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3759 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3760 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3761 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3762 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3763 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3764 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3765 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3766 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3767 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3768 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3769 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3770 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3771 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3772 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3773 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3774 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3775 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3776 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3777 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3778 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3779 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3780 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3781 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3782  ip_source_and_port_range_check_add_del_reply)                          \
3783 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3784  ip_source_and_port_range_check_interface_add_del_reply)                \
3785 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3786 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3787 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3788 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3789 _(PUNT_REPLY, punt_reply)                                               \
3790 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3791 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3792 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)
3793
3794 /* M: construct, but don't yet send a message */
3795
3796 #define M(T,t)                                  \
3797 do {                                            \
3798     vam->result_ready = 0;                      \
3799     mp = vl_msg_api_alloc(sizeof(*mp));         \
3800     memset (mp, 0, sizeof (*mp));               \
3801     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3802     mp->client_index = vam->my_client_index;    \
3803 } while(0);
3804
3805 #define M2(T,t,n)                               \
3806 do {                                            \
3807     vam->result_ready = 0;                      \
3808     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3809     memset (mp, 0, sizeof (*mp));               \
3810     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3811     mp->client_index = vam->my_client_index;    \
3812 } while(0);
3813
3814
3815 /* S: send a message */
3816 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3817
3818 /* W: wait for results, with timeout */
3819 #define W                                       \
3820 do {                                            \
3821     timeout = vat_time_now (vam) + 1.0;         \
3822                                                 \
3823     while (vat_time_now (vam) < timeout) {      \
3824         if (vam->result_ready == 1) {           \
3825             return (vam->retval);               \
3826         }                                       \
3827     }                                           \
3828     return -99;                                 \
3829 } while(0);
3830
3831 /* W2: wait for results, with timeout */
3832 #define W2(body)                                \
3833 do {                                            \
3834     timeout = vat_time_now (vam) + 1.0;         \
3835                                                 \
3836     while (vat_time_now (vam) < timeout) {      \
3837         if (vam->result_ready == 1) {           \
3838           (body);                               \
3839           return (vam->retval);                 \
3840         }                                       \
3841     }                                           \
3842     return -99;                                 \
3843 } while(0);
3844
3845 typedef struct
3846 {
3847   u8 *name;
3848   u32 value;
3849 } name_sort_t;
3850
3851
3852 #define STR_VTR_OP_CASE(op)     \
3853     case L2_VTR_ ## op:         \
3854         return "" # op;
3855
3856 static const char *
3857 str_vtr_op (u32 vtr_op)
3858 {
3859   switch (vtr_op)
3860     {
3861       STR_VTR_OP_CASE (DISABLED);
3862       STR_VTR_OP_CASE (PUSH_1);
3863       STR_VTR_OP_CASE (PUSH_2);
3864       STR_VTR_OP_CASE (POP_1);
3865       STR_VTR_OP_CASE (POP_2);
3866       STR_VTR_OP_CASE (TRANSLATE_1_1);
3867       STR_VTR_OP_CASE (TRANSLATE_1_2);
3868       STR_VTR_OP_CASE (TRANSLATE_2_1);
3869       STR_VTR_OP_CASE (TRANSLATE_2_2);
3870     }
3871
3872   return "UNKNOWN";
3873 }
3874
3875 static int
3876 dump_sub_interface_table (vat_main_t * vam)
3877 {
3878   const sw_interface_subif_t *sub = NULL;
3879
3880   if (vam->json_output)
3881     {
3882       clib_warning
3883         ("JSON output supported only for VPE API calls and dump_stats_table");
3884       return -99;
3885     }
3886
3887   fformat (vam->ofp,
3888            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3889            "Interface", "sw_if_index",
3890            "sub id", "dot1ad", "tags", "outer id",
3891            "inner id", "exact", "default", "outer any", "inner any");
3892
3893   vec_foreach (sub, vam->sw_if_subif_table)
3894   {
3895     fformat (vam->ofp,
3896              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3897              sub->interface_name,
3898              sub->sw_if_index,
3899              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3900              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3901              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3902              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3903     if (sub->vtr_op != L2_VTR_DISABLED)
3904       {
3905         fformat (vam->ofp,
3906                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3907                  "tag1: %d tag2: %d ]\n",
3908                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3909                  sub->vtr_tag1, sub->vtr_tag2);
3910       }
3911   }
3912
3913   return 0;
3914 }
3915
3916 static int
3917 name_sort_cmp (void *a1, void *a2)
3918 {
3919   name_sort_t *n1 = a1;
3920   name_sort_t *n2 = a2;
3921
3922   return strcmp ((char *) n1->name, (char *) n2->name);
3923 }
3924
3925 static int
3926 dump_interface_table (vat_main_t * vam)
3927 {
3928   hash_pair_t *p;
3929   name_sort_t *nses = 0, *ns;
3930
3931   if (vam->json_output)
3932     {
3933       clib_warning
3934         ("JSON output supported only for VPE API calls and dump_stats_table");
3935       return -99;
3936     }
3937
3938   /* *INDENT-OFF* */
3939   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3940   ({
3941     vec_add2 (nses, ns, 1);
3942     ns->name = (u8 *)(p->key);
3943     ns->value = (u32) p->value[0];
3944   }));
3945   /* *INDENT-ON* */
3946
3947   vec_sort_with_function (nses, name_sort_cmp);
3948
3949   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3950   vec_foreach (ns, nses)
3951   {
3952     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3953   }
3954   vec_free (nses);
3955   return 0;
3956 }
3957
3958 static int
3959 dump_ip_table (vat_main_t * vam, int is_ipv6)
3960 {
3961   const ip_details_t *det = NULL;
3962   const ip_address_details_t *address = NULL;
3963   u32 i = ~0;
3964
3965   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3966
3967   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3968   {
3969     i++;
3970     if (!det->present)
3971       {
3972         continue;
3973       }
3974     fformat (vam->ofp, "%-12d\n", i);
3975     fformat (vam->ofp,
3976              "            %-30s%-13s\n", "Address", "Prefix length");
3977     if (!det->addr)
3978       {
3979         continue;
3980       }
3981     vec_foreach (address, det->addr)
3982     {
3983       fformat (vam->ofp,
3984                "            %-30U%-13d\n",
3985                is_ipv6 ? format_ip6_address : format_ip4_address,
3986                address->ip, address->prefix_length);
3987     }
3988   }
3989
3990   return 0;
3991 }
3992
3993 static int
3994 dump_ipv4_table (vat_main_t * vam)
3995 {
3996   if (vam->json_output)
3997     {
3998       clib_warning
3999         ("JSON output supported only for VPE API calls and dump_stats_table");
4000       return -99;
4001     }
4002
4003   return dump_ip_table (vam, 0);
4004 }
4005
4006 static int
4007 dump_ipv6_table (vat_main_t * vam)
4008 {
4009   if (vam->json_output)
4010     {
4011       clib_warning
4012         ("JSON output supported only for VPE API calls and dump_stats_table");
4013       return -99;
4014     }
4015
4016   return dump_ip_table (vam, 1);
4017 }
4018
4019 static char *
4020 counter_type_to_str (u8 counter_type, u8 is_combined)
4021 {
4022   if (!is_combined)
4023     {
4024       switch (counter_type)
4025         {
4026         case VNET_INTERFACE_COUNTER_DROP:
4027           return "drop";
4028         case VNET_INTERFACE_COUNTER_PUNT:
4029           return "punt";
4030         case VNET_INTERFACE_COUNTER_IP4:
4031           return "ip4";
4032         case VNET_INTERFACE_COUNTER_IP6:
4033           return "ip6";
4034         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4035           return "rx-no-buf";
4036         case VNET_INTERFACE_COUNTER_RX_MISS:
4037           return "rx-miss";
4038         case VNET_INTERFACE_COUNTER_RX_ERROR:
4039           return "rx-error";
4040         case VNET_INTERFACE_COUNTER_TX_ERROR:
4041           return "tx-error";
4042         default:
4043           return "INVALID-COUNTER-TYPE";
4044         }
4045     }
4046   else
4047     {
4048       switch (counter_type)
4049         {
4050         case VNET_INTERFACE_COUNTER_RX:
4051           return "rx";
4052         case VNET_INTERFACE_COUNTER_TX:
4053           return "tx";
4054         default:
4055           return "INVALID-COUNTER-TYPE";
4056         }
4057     }
4058 }
4059
4060 static int
4061 dump_stats_table (vat_main_t * vam)
4062 {
4063   vat_json_node_t node;
4064   vat_json_node_t *msg_array;
4065   vat_json_node_t *msg;
4066   vat_json_node_t *counter_array;
4067   vat_json_node_t *counter;
4068   interface_counter_t c;
4069   u64 packets;
4070   ip4_fib_counter_t *c4;
4071   ip6_fib_counter_t *c6;
4072   int i, j;
4073
4074   if (!vam->json_output)
4075     {
4076       clib_warning ("dump_stats_table supported only in JSON format");
4077       return -99;
4078     }
4079
4080   vat_json_init_object (&node);
4081
4082   /* interface counters */
4083   msg_array = vat_json_object_add (&node, "interface_counters");
4084   vat_json_init_array (msg_array);
4085   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4086     {
4087       msg = vat_json_array_add (msg_array);
4088       vat_json_init_object (msg);
4089       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4090                                        (u8 *) counter_type_to_str (i, 0));
4091       vat_json_object_add_int (msg, "is_combined", 0);
4092       counter_array = vat_json_object_add (msg, "data");
4093       vat_json_init_array (counter_array);
4094       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4095         {
4096           packets = vam->simple_interface_counters[i][j];
4097           vat_json_array_add_uint (counter_array, packets);
4098         }
4099     }
4100   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4101     {
4102       msg = vat_json_array_add (msg_array);
4103       vat_json_init_object (msg);
4104       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4105                                        (u8 *) counter_type_to_str (i, 1));
4106       vat_json_object_add_int (msg, "is_combined", 1);
4107       counter_array = vat_json_object_add (msg, "data");
4108       vat_json_init_array (counter_array);
4109       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4110         {
4111           c = vam->combined_interface_counters[i][j];
4112           counter = vat_json_array_add (counter_array);
4113           vat_json_init_object (counter);
4114           vat_json_object_add_uint (counter, "packets", c.packets);
4115           vat_json_object_add_uint (counter, "bytes", c.bytes);
4116         }
4117     }
4118
4119   /* ip4 fib counters */
4120   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4121   vat_json_init_array (msg_array);
4122   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4123     {
4124       msg = vat_json_array_add (msg_array);
4125       vat_json_init_object (msg);
4126       vat_json_object_add_uint (msg, "vrf_id",
4127                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4128       counter_array = vat_json_object_add (msg, "c");
4129       vat_json_init_array (counter_array);
4130       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4131         {
4132           counter = vat_json_array_add (counter_array);
4133           vat_json_init_object (counter);
4134           c4 = &vam->ip4_fib_counters[i][j];
4135           vat_json_object_add_ip4 (counter, "address", c4->address);
4136           vat_json_object_add_uint (counter, "address_length",
4137                                     c4->address_length);
4138           vat_json_object_add_uint (counter, "packets", c4->packets);
4139           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4140         }
4141     }
4142
4143   /* ip6 fib counters */
4144   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4145   vat_json_init_array (msg_array);
4146   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4147     {
4148       msg = vat_json_array_add (msg_array);
4149       vat_json_init_object (msg);
4150       vat_json_object_add_uint (msg, "vrf_id",
4151                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4152       counter_array = vat_json_object_add (msg, "c");
4153       vat_json_init_array (counter_array);
4154       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4155         {
4156           counter = vat_json_array_add (counter_array);
4157           vat_json_init_object (counter);
4158           c6 = &vam->ip6_fib_counters[i][j];
4159           vat_json_object_add_ip6 (counter, "address", c6->address);
4160           vat_json_object_add_uint (counter, "address_length",
4161                                     c6->address_length);
4162           vat_json_object_add_uint (counter, "packets", c6->packets);
4163           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4164         }
4165     }
4166
4167   vat_json_print (vam->ofp, &node);
4168   vat_json_free (&node);
4169
4170   return 0;
4171 }
4172
4173 int
4174 exec (vat_main_t * vam)
4175 {
4176   api_main_t *am = &api_main;
4177   vl_api_cli_request_t *mp;
4178   f64 timeout;
4179   void *oldheap;
4180   u8 *cmd = 0;
4181   unformat_input_t *i = vam->input;
4182
4183   if (vec_len (i->buffer) == 0)
4184     return -1;
4185
4186   if (vam->exec_mode == 0 && unformat (i, "mode"))
4187     {
4188       vam->exec_mode = 1;
4189       return 0;
4190     }
4191   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4192     {
4193       vam->exec_mode = 0;
4194       return 0;
4195     }
4196
4197
4198   M (CLI_REQUEST, cli_request);
4199
4200   /*
4201    * Copy cmd into shared memory.
4202    * In order for the CLI command to work, it
4203    * must be a vector ending in \n, not a C-string ending
4204    * in \n\0.
4205    */
4206   pthread_mutex_lock (&am->vlib_rp->mutex);
4207   oldheap = svm_push_data_heap (am->vlib_rp);
4208
4209   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4210   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4211
4212   svm_pop_heap (oldheap);
4213   pthread_mutex_unlock (&am->vlib_rp->mutex);
4214
4215   mp->cmd_in_shmem = (u64) cmd;
4216   S;
4217   timeout = vat_time_now (vam) + 10.0;
4218
4219   while (vat_time_now (vam) < timeout)
4220     {
4221       if (vam->result_ready == 1)
4222         {
4223           u8 *free_me;
4224           if (vam->shmem_result != NULL)
4225             fformat (vam->ofp, "%s", vam->shmem_result);
4226           pthread_mutex_lock (&am->vlib_rp->mutex);
4227           oldheap = svm_push_data_heap (am->vlib_rp);
4228
4229           free_me = (u8 *) vam->shmem_result;
4230           vec_free (free_me);
4231
4232           svm_pop_heap (oldheap);
4233           pthread_mutex_unlock (&am->vlib_rp->mutex);
4234           return 0;
4235         }
4236     }
4237   return -99;
4238 }
4239
4240 /*
4241  * Future replacement of exec() that passes CLI buffers directly in
4242  * the API messages instead of an additional shared memory area.
4243  */
4244 static int
4245 exec_inband (vat_main_t * vam)
4246 {
4247   vl_api_cli_inband_t *mp;
4248   f64 timeout;
4249   unformat_input_t *i = vam->input;
4250
4251   if (vec_len (i->buffer) == 0)
4252     return -1;
4253
4254   if (vam->exec_mode == 0 && unformat (i, "mode"))
4255     {
4256       vam->exec_mode = 1;
4257       return 0;
4258     }
4259   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4260     {
4261       vam->exec_mode = 0;
4262       return 0;
4263     }
4264
4265   /*
4266    * In order for the CLI command to work, it
4267    * must be a vector ending in \n, not a C-string ending
4268    * in \n\0.
4269    */
4270   u32 len = vec_len (vam->input->buffer);
4271   M2 (CLI_INBAND, cli_inband, len);
4272   clib_memcpy (mp->cmd, vam->input->buffer, len);
4273   mp->length = htonl (len);
4274
4275   S;
4276   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4277 }
4278
4279 static int
4280 api_create_loopback (vat_main_t * vam)
4281 {
4282   unformat_input_t *i = vam->input;
4283   vl_api_create_loopback_t *mp;
4284   f64 timeout;
4285   u8 mac_address[6];
4286   u8 mac_set = 0;
4287
4288   memset (mac_address, 0, sizeof (mac_address));
4289
4290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4291     {
4292       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4293         mac_set = 1;
4294       else
4295         break;
4296     }
4297
4298   /* Construct the API message */
4299   M (CREATE_LOOPBACK, create_loopback);
4300   if (mac_set)
4301     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4302
4303   S;
4304   W;
4305 }
4306
4307 static int
4308 api_delete_loopback (vat_main_t * vam)
4309 {
4310   unformat_input_t *i = vam->input;
4311   vl_api_delete_loopback_t *mp;
4312   f64 timeout;
4313   u32 sw_if_index = ~0;
4314
4315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4316     {
4317       if (unformat (i, "sw_if_index %d", &sw_if_index))
4318         ;
4319       else
4320         break;
4321     }
4322
4323   if (sw_if_index == ~0)
4324     {
4325       errmsg ("missing sw_if_index\n");
4326       return -99;
4327     }
4328
4329   /* Construct the API message */
4330   M (DELETE_LOOPBACK, delete_loopback);
4331   mp->sw_if_index = ntohl (sw_if_index);
4332
4333   S;
4334   W;
4335 }
4336
4337 static int
4338 api_want_stats (vat_main_t * vam)
4339 {
4340   unformat_input_t *i = vam->input;
4341   vl_api_want_stats_t *mp;
4342   f64 timeout;
4343   int enable = -1;
4344
4345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4346     {
4347       if (unformat (i, "enable"))
4348         enable = 1;
4349       else if (unformat (i, "disable"))
4350         enable = 0;
4351       else
4352         break;
4353     }
4354
4355   if (enable == -1)
4356     {
4357       errmsg ("missing enable|disable\n");
4358       return -99;
4359     }
4360
4361   M (WANT_STATS, want_stats);
4362   mp->enable_disable = enable;
4363
4364   S;
4365   W;
4366 }
4367
4368 static int
4369 api_want_interface_events (vat_main_t * vam)
4370 {
4371   unformat_input_t *i = vam->input;
4372   vl_api_want_interface_events_t *mp;
4373   f64 timeout;
4374   int enable = -1;
4375
4376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4377     {
4378       if (unformat (i, "enable"))
4379         enable = 1;
4380       else if (unformat (i, "disable"))
4381         enable = 0;
4382       else
4383         break;
4384     }
4385
4386   if (enable == -1)
4387     {
4388       errmsg ("missing enable|disable\n");
4389       return -99;
4390     }
4391
4392   M (WANT_INTERFACE_EVENTS, want_interface_events);
4393   mp->enable_disable = enable;
4394
4395   vam->interface_event_display = enable;
4396
4397   S;
4398   W;
4399 }
4400
4401
4402 /* Note: non-static, called once to set up the initial intfc table */
4403 int
4404 api_sw_interface_dump (vat_main_t * vam)
4405 {
4406   vl_api_sw_interface_dump_t *mp;
4407   f64 timeout;
4408   hash_pair_t *p;
4409   name_sort_t *nses = 0, *ns;
4410   sw_interface_subif_t *sub = NULL;
4411
4412   /* Toss the old name table */
4413   /* *INDENT-OFF* */
4414   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4415   ({
4416     vec_add2 (nses, ns, 1);
4417     ns->name = (u8 *)(p->key);
4418     ns->value = (u32) p->value[0];
4419   }));
4420   /* *INDENT-ON* */
4421
4422   hash_free (vam->sw_if_index_by_interface_name);
4423
4424   vec_foreach (ns, nses) vec_free (ns->name);
4425
4426   vec_free (nses);
4427
4428   vec_foreach (sub, vam->sw_if_subif_table)
4429   {
4430     vec_free (sub->interface_name);
4431   }
4432   vec_free (vam->sw_if_subif_table);
4433
4434   /* recreate the interface name hash table */
4435   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4436
4437   /* Get list of ethernets */
4438   M (SW_INTERFACE_DUMP, sw_interface_dump);
4439   mp->name_filter_valid = 1;
4440   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4441   S;
4442
4443   /* and local / loopback interfaces */
4444   M (SW_INTERFACE_DUMP, sw_interface_dump);
4445   mp->name_filter_valid = 1;
4446   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4447   S;
4448
4449   /* and packet-generator interfaces */
4450   M (SW_INTERFACE_DUMP, sw_interface_dump);
4451   mp->name_filter_valid = 1;
4452   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4453   S;
4454
4455   /* and vxlan-gpe tunnel interfaces */
4456   M (SW_INTERFACE_DUMP, sw_interface_dump);
4457   mp->name_filter_valid = 1;
4458   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4459            sizeof (mp->name_filter) - 1);
4460   S;
4461
4462   /* and vxlan tunnel interfaces */
4463   M (SW_INTERFACE_DUMP, sw_interface_dump);
4464   mp->name_filter_valid = 1;
4465   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4466   S;
4467
4468   /* and host (af_packet) interfaces */
4469   M (SW_INTERFACE_DUMP, sw_interface_dump);
4470   mp->name_filter_valid = 1;
4471   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4472   S;
4473
4474   /* and l2tpv3 tunnel interfaces */
4475   M (SW_INTERFACE_DUMP, sw_interface_dump);
4476   mp->name_filter_valid = 1;
4477   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4478            sizeof (mp->name_filter) - 1);
4479   S;
4480
4481   /* and GRE tunnel interfaces */
4482   M (SW_INTERFACE_DUMP, sw_interface_dump);
4483   mp->name_filter_valid = 1;
4484   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4485   S;
4486
4487   /* and LISP-GPE interfaces */
4488   M (SW_INTERFACE_DUMP, sw_interface_dump);
4489   mp->name_filter_valid = 1;
4490   strncpy ((char *) mp->name_filter, "lisp_gpe",
4491            sizeof (mp->name_filter) - 1);
4492   S;
4493
4494   /* and IPSEC tunnel interfaces */
4495   M (SW_INTERFACE_DUMP, sw_interface_dump);
4496   mp->name_filter_valid = 1;
4497   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4498   S;
4499
4500   /* Use a control ping for synchronization */
4501   {
4502     vl_api_control_ping_t *mp;
4503     M (CONTROL_PING, control_ping);
4504     S;
4505   }
4506   W;
4507 }
4508
4509 static int
4510 api_sw_interface_set_flags (vat_main_t * vam)
4511 {
4512   unformat_input_t *i = vam->input;
4513   vl_api_sw_interface_set_flags_t *mp;
4514   f64 timeout;
4515   u32 sw_if_index;
4516   u8 sw_if_index_set = 0;
4517   u8 admin_up = 0, link_up = 0;
4518
4519   /* Parse args required to build the message */
4520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4521     {
4522       if (unformat (i, "admin-up"))
4523         admin_up = 1;
4524       else if (unformat (i, "admin-down"))
4525         admin_up = 0;
4526       else if (unformat (i, "link-up"))
4527         link_up = 1;
4528       else if (unformat (i, "link-down"))
4529         link_up = 0;
4530       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4531         sw_if_index_set = 1;
4532       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4533         sw_if_index_set = 1;
4534       else
4535         break;
4536     }
4537
4538   if (sw_if_index_set == 0)
4539     {
4540       errmsg ("missing interface name or sw_if_index\n");
4541       return -99;
4542     }
4543
4544   /* Construct the API message */
4545   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4546   mp->sw_if_index = ntohl (sw_if_index);
4547   mp->admin_up_down = admin_up;
4548   mp->link_up_down = link_up;
4549
4550   /* send it... */
4551   S;
4552
4553   /* Wait for a reply, return the good/bad news... */
4554   W;
4555 }
4556
4557 static int
4558 api_sw_interface_clear_stats (vat_main_t * vam)
4559 {
4560   unformat_input_t *i = vam->input;
4561   vl_api_sw_interface_clear_stats_t *mp;
4562   f64 timeout;
4563   u32 sw_if_index;
4564   u8 sw_if_index_set = 0;
4565
4566   /* Parse args required to build the message */
4567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4568     {
4569       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4570         sw_if_index_set = 1;
4571       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4572         sw_if_index_set = 1;
4573       else
4574         break;
4575     }
4576
4577   /* Construct the API message */
4578   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4579
4580   if (sw_if_index_set == 1)
4581     mp->sw_if_index = ntohl (sw_if_index);
4582   else
4583     mp->sw_if_index = ~0;
4584
4585   /* send it... */
4586   S;
4587
4588   /* Wait for a reply, return the good/bad news... */
4589   W;
4590 }
4591
4592 static int
4593 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4594 {
4595   unformat_input_t *i = vam->input;
4596   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4597   f64 timeout;
4598   u32 sw_if_index;
4599   u8 sw_if_index_set = 0;
4600   u32 subport;
4601   u8 subport_set = 0;
4602   u32 pipe;
4603   u8 pipe_set = 0;
4604   u32 profile;
4605   u8 profile_set = 0;
4606
4607   /* Parse args required to build the message */
4608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4609     {
4610       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4611         sw_if_index_set = 1;
4612       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4613         sw_if_index_set = 1;
4614       else if (unformat (i, "subport %u", &subport))
4615         subport_set = 1;
4616       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4617         sw_if_index_set = 1;
4618       else if (unformat (i, "pipe %u", &pipe))
4619         pipe_set = 1;
4620       else if (unformat (i, "profile %u", &profile))
4621         profile_set = 1;
4622       else
4623         break;
4624     }
4625
4626   if (sw_if_index_set == 0)
4627     {
4628       errmsg ("missing interface name or sw_if_index\n");
4629       return -99;
4630     }
4631
4632   if (subport_set == 0)
4633     {
4634       errmsg ("missing subport \n");
4635       return -99;
4636     }
4637
4638   if (pipe_set == 0)
4639     {
4640       errmsg ("missing pipe\n");
4641       return -99;
4642     }
4643
4644   if (profile_set == 0)
4645     {
4646       errmsg ("missing profile\n");
4647       return -99;
4648     }
4649
4650   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4651
4652   mp->sw_if_index = ntohl (sw_if_index);
4653   mp->subport = ntohl (subport);
4654   mp->pipe = ntohl (pipe);
4655   mp->profile = ntohl (profile);
4656
4657
4658   S;
4659   W;
4660   /* NOTREACHED */
4661   return 0;
4662 }
4663
4664 static int
4665 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4666 {
4667   unformat_input_t *i = vam->input;
4668   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4669   f64 timeout;
4670   u32 sw_if_index;
4671   u8 sw_if_index_set = 0;
4672   u32 subport;
4673   u8 subport_set = 0;
4674   u32 tb_rate = 1250000000;     /* 10GbE */
4675   u32 tb_size = 1000000;
4676   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4677   u32 tc_period = 10;
4678
4679   /* Parse args required to build the message */
4680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4681     {
4682       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4683         sw_if_index_set = 1;
4684       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4685         sw_if_index_set = 1;
4686       else if (unformat (i, "subport %u", &subport))
4687         subport_set = 1;
4688       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4689         sw_if_index_set = 1;
4690       else if (unformat (i, "rate %u", &tb_rate))
4691         {
4692           u32 tc_id;
4693
4694           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4695                tc_id++)
4696             tc_rate[tc_id] = tb_rate;
4697         }
4698       else if (unformat (i, "bktsize %u", &tb_size))
4699         ;
4700       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4701         ;
4702       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4703         ;
4704       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4705         ;
4706       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4707         ;
4708       else if (unformat (i, "period %u", &tc_period))
4709         ;
4710       else
4711         break;
4712     }
4713
4714   if (sw_if_index_set == 0)
4715     {
4716       errmsg ("missing interface name or sw_if_index\n");
4717       return -99;
4718     }
4719
4720   if (subport_set == 0)
4721     {
4722       errmsg ("missing subport \n");
4723       return -99;
4724     }
4725
4726   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4727
4728   mp->sw_if_index = ntohl (sw_if_index);
4729   mp->subport = ntohl (subport);
4730   mp->tb_rate = ntohl (tb_rate);
4731   mp->tb_size = ntohl (tb_size);
4732   mp->tc_rate[0] = ntohl (tc_rate[0]);
4733   mp->tc_rate[1] = ntohl (tc_rate[1]);
4734   mp->tc_rate[2] = ntohl (tc_rate[2]);
4735   mp->tc_rate[3] = ntohl (tc_rate[3]);
4736   mp->tc_period = ntohl (tc_period);
4737
4738   S;
4739   W;
4740   /* NOTREACHED */
4741   return 0;
4742 }
4743
4744 static int
4745 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4746 {
4747   unformat_input_t *i = vam->input;
4748   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4749   f64 timeout;
4750   u32 sw_if_index;
4751   u8 sw_if_index_set = 0;
4752   u8 entry_set = 0;
4753   u8 tc_set = 0;
4754   u8 queue_set = 0;
4755   u32 entry, tc, queue;
4756
4757   /* Parse args required to build the message */
4758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4759     {
4760       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4761         sw_if_index_set = 1;
4762       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4763         sw_if_index_set = 1;
4764       else if (unformat (i, "entry %d", &entry))
4765         entry_set = 1;
4766       else if (unformat (i, "tc %d", &tc))
4767         tc_set = 1;
4768       else if (unformat (i, "queue %d", &queue))
4769         queue_set = 1;
4770       else
4771         break;
4772     }
4773
4774   if (sw_if_index_set == 0)
4775     {
4776       errmsg ("missing interface name or sw_if_index\n");
4777       return -99;
4778     }
4779
4780   if (entry_set == 0)
4781     {
4782       errmsg ("missing entry \n");
4783       return -99;
4784     }
4785
4786   if (tc_set == 0)
4787     {
4788       errmsg ("missing traffic class \n");
4789       return -99;
4790     }
4791
4792   if (queue_set == 0)
4793     {
4794       errmsg ("missing queue \n");
4795       return -99;
4796     }
4797
4798   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4799
4800   mp->sw_if_index = ntohl (sw_if_index);
4801   mp->entry = ntohl (entry);
4802   mp->tc = ntohl (tc);
4803   mp->queue = ntohl (queue);
4804
4805   S;
4806   W;
4807   /* NOTREACHED */
4808   return 0;
4809 }
4810
4811 static int
4812 api_sw_interface_add_del_address (vat_main_t * vam)
4813 {
4814   unformat_input_t *i = vam->input;
4815   vl_api_sw_interface_add_del_address_t *mp;
4816   f64 timeout;
4817   u32 sw_if_index;
4818   u8 sw_if_index_set = 0;
4819   u8 is_add = 1, del_all = 0;
4820   u32 address_length = 0;
4821   u8 v4_address_set = 0;
4822   u8 v6_address_set = 0;
4823   ip4_address_t v4address;
4824   ip6_address_t v6address;
4825
4826   /* Parse args required to build the message */
4827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4828     {
4829       if (unformat (i, "del-all"))
4830         del_all = 1;
4831       else if (unformat (i, "del"))
4832         is_add = 0;
4833       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4834         sw_if_index_set = 1;
4835       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4836         sw_if_index_set = 1;
4837       else if (unformat (i, "%U/%d",
4838                          unformat_ip4_address, &v4address, &address_length))
4839         v4_address_set = 1;
4840       else if (unformat (i, "%U/%d",
4841                          unformat_ip6_address, &v6address, &address_length))
4842         v6_address_set = 1;
4843       else
4844         break;
4845     }
4846
4847   if (sw_if_index_set == 0)
4848     {
4849       errmsg ("missing interface name or sw_if_index\n");
4850       return -99;
4851     }
4852   if (v4_address_set && v6_address_set)
4853     {
4854       errmsg ("both v4 and v6 addresses set\n");
4855       return -99;
4856     }
4857   if (!v4_address_set && !v6_address_set && !del_all)
4858     {
4859       errmsg ("no addresses set\n");
4860       return -99;
4861     }
4862
4863   /* Construct the API message */
4864   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4865
4866   mp->sw_if_index = ntohl (sw_if_index);
4867   mp->is_add = is_add;
4868   mp->del_all = del_all;
4869   if (v6_address_set)
4870     {
4871       mp->is_ipv6 = 1;
4872       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4873     }
4874   else
4875     {
4876       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4877     }
4878   mp->address_length = address_length;
4879
4880   /* send it... */
4881   S;
4882
4883   /* Wait for a reply, return good/bad news  */
4884   W;
4885 }
4886
4887 static int
4888 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4889 {
4890   unformat_input_t *i = vam->input;
4891   vl_api_sw_interface_set_mpls_enable_t *mp;
4892   f64 timeout;
4893   u32 sw_if_index;
4894   u8 sw_if_index_set = 0;
4895   u8 enable = 1;
4896
4897   /* Parse args required to build the message */
4898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4899     {
4900       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4901         sw_if_index_set = 1;
4902       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4903         sw_if_index_set = 1;
4904       else if (unformat (i, "disable"))
4905         enable = 0;
4906       else if (unformat (i, "dis"))
4907         enable = 0;
4908       else
4909         break;
4910     }
4911
4912   if (sw_if_index_set == 0)
4913     {
4914       errmsg ("missing interface name or sw_if_index\n");
4915       return -99;
4916     }
4917
4918   /* Construct the API message */
4919   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
4920
4921   mp->sw_if_index = ntohl (sw_if_index);
4922   mp->enable = enable;
4923
4924   /* send it... */
4925   S;
4926
4927   /* Wait for a reply... */
4928   W;
4929 }
4930
4931 static int
4932 api_sw_interface_set_table (vat_main_t * vam)
4933 {
4934   unformat_input_t *i = vam->input;
4935   vl_api_sw_interface_set_table_t *mp;
4936   f64 timeout;
4937   u32 sw_if_index, vrf_id = 0;
4938   u8 sw_if_index_set = 0;
4939   u8 is_ipv6 = 0;
4940
4941   /* Parse args required to build the message */
4942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4943     {
4944       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4945         sw_if_index_set = 1;
4946       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4947         sw_if_index_set = 1;
4948       else if (unformat (i, "vrf %d", &vrf_id))
4949         ;
4950       else if (unformat (i, "ipv6"))
4951         is_ipv6 = 1;
4952       else
4953         break;
4954     }
4955
4956   if (sw_if_index_set == 0)
4957     {
4958       errmsg ("missing interface name or sw_if_index\n");
4959       return -99;
4960     }
4961
4962   /* Construct the API message */
4963   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4964
4965   mp->sw_if_index = ntohl (sw_if_index);
4966   mp->is_ipv6 = is_ipv6;
4967   mp->vrf_id = ntohl (vrf_id);
4968
4969   /* send it... */
4970   S;
4971
4972   /* Wait for a reply... */
4973   W;
4974 }
4975
4976 static int
4977 api_sw_interface_set_vpath (vat_main_t * vam)
4978 {
4979   unformat_input_t *i = vam->input;
4980   vl_api_sw_interface_set_vpath_t *mp;
4981   f64 timeout;
4982   u32 sw_if_index = 0;
4983   u8 sw_if_index_set = 0;
4984   u8 is_enable = 0;
4985
4986   /* Parse args required to build the message */
4987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4988     {
4989       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4990         sw_if_index_set = 1;
4991       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4992         sw_if_index_set = 1;
4993       else if (unformat (i, "enable"))
4994         is_enable = 1;
4995       else if (unformat (i, "disable"))
4996         is_enable = 0;
4997       else
4998         break;
4999     }
5000
5001   if (sw_if_index_set == 0)
5002     {
5003       errmsg ("missing interface name or sw_if_index\n");
5004       return -99;
5005     }
5006
5007   /* Construct the API message */
5008   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5009
5010   mp->sw_if_index = ntohl (sw_if_index);
5011   mp->enable = is_enable;
5012
5013   /* send it... */
5014   S;
5015
5016   /* Wait for a reply... */
5017   W;
5018 }
5019
5020 static int
5021 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5022 {
5023   unformat_input_t *i = vam->input;
5024   vl_api_sw_interface_set_l2_xconnect_t *mp;
5025   f64 timeout;
5026   u32 rx_sw_if_index;
5027   u8 rx_sw_if_index_set = 0;
5028   u32 tx_sw_if_index;
5029   u8 tx_sw_if_index_set = 0;
5030   u8 enable = 1;
5031
5032   /* Parse args required to build the message */
5033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5034     {
5035       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5036         rx_sw_if_index_set = 1;
5037       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5038         tx_sw_if_index_set = 1;
5039       else if (unformat (i, "rx"))
5040         {
5041           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5042             {
5043               if (unformat (i, "%U", unformat_sw_if_index, vam,
5044                             &rx_sw_if_index))
5045                 rx_sw_if_index_set = 1;
5046             }
5047           else
5048             break;
5049         }
5050       else if (unformat (i, "tx"))
5051         {
5052           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5053             {
5054               if (unformat (i, "%U", unformat_sw_if_index, vam,
5055                             &tx_sw_if_index))
5056                 tx_sw_if_index_set = 1;
5057             }
5058           else
5059             break;
5060         }
5061       else if (unformat (i, "enable"))
5062         enable = 1;
5063       else if (unformat (i, "disable"))
5064         enable = 0;
5065       else
5066         break;
5067     }
5068
5069   if (rx_sw_if_index_set == 0)
5070     {
5071       errmsg ("missing rx interface name or rx_sw_if_index\n");
5072       return -99;
5073     }
5074
5075   if (enable && (tx_sw_if_index_set == 0))
5076     {
5077       errmsg ("missing tx interface name or tx_sw_if_index\n");
5078       return -99;
5079     }
5080
5081   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5082
5083   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5084   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5085   mp->enable = enable;
5086
5087   S;
5088   W;
5089   /* NOTREACHED */
5090   return 0;
5091 }
5092
5093 static int
5094 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5095 {
5096   unformat_input_t *i = vam->input;
5097   vl_api_sw_interface_set_l2_bridge_t *mp;
5098   f64 timeout;
5099   u32 rx_sw_if_index;
5100   u8 rx_sw_if_index_set = 0;
5101   u32 bd_id;
5102   u8 bd_id_set = 0;
5103   u8 bvi = 0;
5104   u32 shg = 0;
5105   u8 enable = 1;
5106
5107   /* Parse args required to build the message */
5108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5109     {
5110       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5111         rx_sw_if_index_set = 1;
5112       else if (unformat (i, "bd_id %d", &bd_id))
5113         bd_id_set = 1;
5114       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5115         rx_sw_if_index_set = 1;
5116       else if (unformat (i, "shg %d", &shg))
5117         ;
5118       else if (unformat (i, "bvi"))
5119         bvi = 1;
5120       else if (unformat (i, "enable"))
5121         enable = 1;
5122       else if (unformat (i, "disable"))
5123         enable = 0;
5124       else
5125         break;
5126     }
5127
5128   if (rx_sw_if_index_set == 0)
5129     {
5130       errmsg ("missing rx interface name or sw_if_index\n");
5131       return -99;
5132     }
5133
5134   if (enable && (bd_id_set == 0))
5135     {
5136       errmsg ("missing bridge domain\n");
5137       return -99;
5138     }
5139
5140   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5141
5142   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5143   mp->bd_id = ntohl (bd_id);
5144   mp->shg = (u8) shg;
5145   mp->bvi = bvi;
5146   mp->enable = enable;
5147
5148   S;
5149   W;
5150   /* NOTREACHED */
5151   return 0;
5152 }
5153
5154 static int
5155 api_bridge_domain_dump (vat_main_t * vam)
5156 {
5157   unformat_input_t *i = vam->input;
5158   vl_api_bridge_domain_dump_t *mp;
5159   f64 timeout;
5160   u32 bd_id = ~0;
5161
5162   /* Parse args required to build the message */
5163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5164     {
5165       if (unformat (i, "bd_id %d", &bd_id))
5166         ;
5167       else
5168         break;
5169     }
5170
5171   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5172   mp->bd_id = ntohl (bd_id);
5173   S;
5174
5175   /* Use a control ping for synchronization */
5176   {
5177     vl_api_control_ping_t *mp;
5178     M (CONTROL_PING, control_ping);
5179     S;
5180   }
5181
5182   W;
5183   /* NOTREACHED */
5184   return 0;
5185 }
5186
5187 static int
5188 api_bridge_domain_add_del (vat_main_t * vam)
5189 {
5190   unformat_input_t *i = vam->input;
5191   vl_api_bridge_domain_add_del_t *mp;
5192   f64 timeout;
5193   u32 bd_id = ~0;
5194   u8 is_add = 1;
5195   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5196
5197   /* Parse args required to build the message */
5198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5199     {
5200       if (unformat (i, "bd_id %d", &bd_id))
5201         ;
5202       else if (unformat (i, "flood %d", &flood))
5203         ;
5204       else if (unformat (i, "uu-flood %d", &uu_flood))
5205         ;
5206       else if (unformat (i, "forward %d", &forward))
5207         ;
5208       else if (unformat (i, "learn %d", &learn))
5209         ;
5210       else if (unformat (i, "arp-term %d", &arp_term))
5211         ;
5212       else if (unformat (i, "del"))
5213         {
5214           is_add = 0;
5215           flood = uu_flood = forward = learn = 0;
5216         }
5217       else
5218         break;
5219     }
5220
5221   if (bd_id == ~0)
5222     {
5223       errmsg ("missing bridge domain\n");
5224       return -99;
5225     }
5226
5227   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5228
5229   mp->bd_id = ntohl (bd_id);
5230   mp->flood = flood;
5231   mp->uu_flood = uu_flood;
5232   mp->forward = forward;
5233   mp->learn = learn;
5234   mp->arp_term = arp_term;
5235   mp->is_add = is_add;
5236
5237   S;
5238   W;
5239   /* NOTREACHED */
5240   return 0;
5241 }
5242
5243 static int
5244 api_l2fib_add_del (vat_main_t * vam)
5245 {
5246   unformat_input_t *i = vam->input;
5247   vl_api_l2fib_add_del_t *mp;
5248   f64 timeout;
5249   u64 mac = 0;
5250   u8 mac_set = 0;
5251   u32 bd_id;
5252   u8 bd_id_set = 0;
5253   u32 sw_if_index;
5254   u8 sw_if_index_set = 0;
5255   u8 is_add = 1;
5256   u8 static_mac = 0;
5257   u8 filter_mac = 0;
5258   u8 bvi_mac = 0;
5259   int count = 1;
5260   f64 before = 0;
5261   int j;
5262
5263   /* Parse args required to build the message */
5264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5265     {
5266       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5267         mac_set = 1;
5268       else if (unformat (i, "bd_id %d", &bd_id))
5269         bd_id_set = 1;
5270       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5271         sw_if_index_set = 1;
5272       else if (unformat (i, "sw_if"))
5273         {
5274           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5275             {
5276               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5277                 sw_if_index_set = 1;
5278             }
5279           else
5280             break;
5281         }
5282       else if (unformat (i, "static"))
5283         static_mac = 1;
5284       else if (unformat (i, "filter"))
5285         {
5286           filter_mac = 1;
5287           static_mac = 1;
5288         }
5289       else if (unformat (i, "bvi"))
5290         {
5291           bvi_mac = 1;
5292           static_mac = 1;
5293         }
5294       else if (unformat (i, "del"))
5295         is_add = 0;
5296       else if (unformat (i, "count %d", &count))
5297         ;
5298       else
5299         break;
5300     }
5301
5302   if (mac_set == 0)
5303     {
5304       errmsg ("missing mac address\n");
5305       return -99;
5306     }
5307
5308   if (bd_id_set == 0)
5309     {
5310       errmsg ("missing bridge domain\n");
5311       return -99;
5312     }
5313
5314   if (is_add && (sw_if_index_set == 0))
5315     {
5316       errmsg ("missing interface name or sw_if_index\n");
5317       return -99;
5318     }
5319
5320   if (count > 1)
5321     {
5322       /* Turn on async mode */
5323       vam->async_mode = 1;
5324       vam->async_errors = 0;
5325       before = vat_time_now (vam);
5326     }
5327
5328   for (j = 0; j < count; j++)
5329     {
5330       M (L2FIB_ADD_DEL, l2fib_add_del);
5331
5332       mp->mac = mac;
5333       mp->bd_id = ntohl (bd_id);
5334       mp->is_add = is_add;
5335
5336       if (is_add)
5337         {
5338           mp->sw_if_index = ntohl (sw_if_index);
5339           mp->static_mac = static_mac;
5340           mp->filter_mac = filter_mac;
5341           mp->bvi_mac = bvi_mac;
5342         }
5343       increment_mac_address (&mac);
5344       /* send it... */
5345       S;
5346     }
5347
5348   if (count > 1)
5349     {
5350       vl_api_control_ping_t *mp;
5351       f64 after;
5352
5353       /* Shut off async mode */
5354       vam->async_mode = 0;
5355
5356       M (CONTROL_PING, control_ping);
5357       S;
5358
5359       timeout = vat_time_now (vam) + 1.0;
5360       while (vat_time_now (vam) < timeout)
5361         if (vam->result_ready == 1)
5362           goto out;
5363       vam->retval = -99;
5364
5365     out:
5366       if (vam->retval == -99)
5367         errmsg ("timeout\n");
5368
5369       if (vam->async_errors > 0)
5370         {
5371           errmsg ("%d asynchronous errors\n", vam->async_errors);
5372           vam->retval = -98;
5373         }
5374       vam->async_errors = 0;
5375       after = vat_time_now (vam);
5376
5377       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5378                count, after - before, count / (after - before));
5379     }
5380   else
5381     {
5382       /* Wait for a reply... */
5383       W;
5384     }
5385   /* Return the good/bad news */
5386   return (vam->retval);
5387 }
5388
5389 static int
5390 api_l2_flags (vat_main_t * vam)
5391 {
5392   unformat_input_t *i = vam->input;
5393   vl_api_l2_flags_t *mp;
5394   f64 timeout;
5395   u32 sw_if_index;
5396   u32 feature_bitmap = 0;
5397   u8 sw_if_index_set = 0;
5398
5399   /* Parse args required to build the message */
5400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5401     {
5402       if (unformat (i, "sw_if_index %d", &sw_if_index))
5403         sw_if_index_set = 1;
5404       else if (unformat (i, "sw_if"))
5405         {
5406           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5407             {
5408               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5409                 sw_if_index_set = 1;
5410             }
5411           else
5412             break;
5413         }
5414       else if (unformat (i, "learn"))
5415         feature_bitmap |= L2INPUT_FEAT_LEARN;
5416       else if (unformat (i, "forward"))
5417         feature_bitmap |= L2INPUT_FEAT_FWD;
5418       else if (unformat (i, "flood"))
5419         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5420       else if (unformat (i, "uu-flood"))
5421         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5422       else
5423         break;
5424     }
5425
5426   if (sw_if_index_set == 0)
5427     {
5428       errmsg ("missing interface name or sw_if_index\n");
5429       return -99;
5430     }
5431
5432   M (L2_FLAGS, l2_flags);
5433
5434   mp->sw_if_index = ntohl (sw_if_index);
5435   mp->feature_bitmap = ntohl (feature_bitmap);
5436
5437   S;
5438   W;
5439   /* NOTREACHED */
5440   return 0;
5441 }
5442
5443 static int
5444 api_bridge_flags (vat_main_t * vam)
5445 {
5446   unformat_input_t *i = vam->input;
5447   vl_api_bridge_flags_t *mp;
5448   f64 timeout;
5449   u32 bd_id;
5450   u8 bd_id_set = 0;
5451   u8 is_set = 1;
5452   u32 flags = 0;
5453
5454   /* Parse args required to build the message */
5455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5456     {
5457       if (unformat (i, "bd_id %d", &bd_id))
5458         bd_id_set = 1;
5459       else if (unformat (i, "learn"))
5460         flags |= L2_LEARN;
5461       else if (unformat (i, "forward"))
5462         flags |= L2_FWD;
5463       else if (unformat (i, "flood"))
5464         flags |= L2_FLOOD;
5465       else if (unformat (i, "uu-flood"))
5466         flags |= L2_UU_FLOOD;
5467       else if (unformat (i, "arp-term"))
5468         flags |= L2_ARP_TERM;
5469       else if (unformat (i, "off"))
5470         is_set = 0;
5471       else if (unformat (i, "disable"))
5472         is_set = 0;
5473       else
5474         break;
5475     }
5476
5477   if (bd_id_set == 0)
5478     {
5479       errmsg ("missing bridge domain\n");
5480       return -99;
5481     }
5482
5483   M (BRIDGE_FLAGS, bridge_flags);
5484
5485   mp->bd_id = ntohl (bd_id);
5486   mp->feature_bitmap = ntohl (flags);
5487   mp->is_set = is_set;
5488
5489   S;
5490   W;
5491   /* NOTREACHED */
5492   return 0;
5493 }
5494
5495 static int
5496 api_bd_ip_mac_add_del (vat_main_t * vam)
5497 {
5498   unformat_input_t *i = vam->input;
5499   vl_api_bd_ip_mac_add_del_t *mp;
5500   f64 timeout;
5501   u32 bd_id;
5502   u8 is_ipv6 = 0;
5503   u8 is_add = 1;
5504   u8 bd_id_set = 0;
5505   u8 ip_set = 0;
5506   u8 mac_set = 0;
5507   ip4_address_t v4addr;
5508   ip6_address_t v6addr;
5509   u8 macaddr[6];
5510
5511
5512   /* Parse args required to build the message */
5513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5514     {
5515       if (unformat (i, "bd_id %d", &bd_id))
5516         {
5517           bd_id_set++;
5518         }
5519       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5520         {
5521           ip_set++;
5522         }
5523       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5524         {
5525           ip_set++;
5526           is_ipv6++;
5527         }
5528       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5529         {
5530           mac_set++;
5531         }
5532       else if (unformat (i, "del"))
5533         is_add = 0;
5534       else
5535         break;
5536     }
5537
5538   if (bd_id_set == 0)
5539     {
5540       errmsg ("missing bridge domain\n");
5541       return -99;
5542     }
5543   else if (ip_set == 0)
5544     {
5545       errmsg ("missing IP address\n");
5546       return -99;
5547     }
5548   else if (mac_set == 0)
5549     {
5550       errmsg ("missing MAC address\n");
5551       return -99;
5552     }
5553
5554   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5555
5556   mp->bd_id = ntohl (bd_id);
5557   mp->is_ipv6 = is_ipv6;
5558   mp->is_add = is_add;
5559   if (is_ipv6)
5560     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5561   else
5562     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5563   clib_memcpy (mp->mac_address, macaddr, 6);
5564   S;
5565   W;
5566   /* NOTREACHED */
5567   return 0;
5568 }
5569
5570 static int
5571 api_tap_connect (vat_main_t * vam)
5572 {
5573   unformat_input_t *i = vam->input;
5574   vl_api_tap_connect_t *mp;
5575   f64 timeout;
5576   u8 mac_address[6];
5577   u8 random_mac = 1;
5578   u8 name_set = 0;
5579   u8 *tap_name;
5580
5581   memset (mac_address, 0, sizeof (mac_address));
5582
5583   /* Parse args required to build the message */
5584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5585     {
5586       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5587         {
5588           random_mac = 0;
5589         }
5590       else if (unformat (i, "random-mac"))
5591         random_mac = 1;
5592       else if (unformat (i, "tapname %s", &tap_name))
5593         name_set = 1;
5594       else
5595         break;
5596     }
5597
5598   if (name_set == 0)
5599     {
5600       errmsg ("missing tap name\n");
5601       return -99;
5602     }
5603   if (vec_len (tap_name) > 63)
5604     {
5605       errmsg ("tap name too long\n");
5606     }
5607   vec_add1 (tap_name, 0);
5608
5609   /* Construct the API message */
5610   M (TAP_CONNECT, tap_connect);
5611
5612   mp->use_random_mac = random_mac;
5613   clib_memcpy (mp->mac_address, mac_address, 6);
5614   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5615   vec_free (tap_name);
5616
5617   /* send it... */
5618   S;
5619
5620   /* Wait for a reply... */
5621   W;
5622 }
5623
5624 static int
5625 api_tap_modify (vat_main_t * vam)
5626 {
5627   unformat_input_t *i = vam->input;
5628   vl_api_tap_modify_t *mp;
5629   f64 timeout;
5630   u8 mac_address[6];
5631   u8 random_mac = 1;
5632   u8 name_set = 0;
5633   u8 *tap_name;
5634   u32 sw_if_index = ~0;
5635   u8 sw_if_index_set = 0;
5636
5637   memset (mac_address, 0, sizeof (mac_address));
5638
5639   /* Parse args required to build the message */
5640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5641     {
5642       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5643         sw_if_index_set = 1;
5644       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5645         sw_if_index_set = 1;
5646       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5647         {
5648           random_mac = 0;
5649         }
5650       else if (unformat (i, "random-mac"))
5651         random_mac = 1;
5652       else if (unformat (i, "tapname %s", &tap_name))
5653         name_set = 1;
5654       else
5655         break;
5656     }
5657
5658   if (sw_if_index_set == 0)
5659     {
5660       errmsg ("missing vpp interface name");
5661       return -99;
5662     }
5663   if (name_set == 0)
5664     {
5665       errmsg ("missing tap name\n");
5666       return -99;
5667     }
5668   if (vec_len (tap_name) > 63)
5669     {
5670       errmsg ("tap name too long\n");
5671     }
5672   vec_add1 (tap_name, 0);
5673
5674   /* Construct the API message */
5675   M (TAP_MODIFY, tap_modify);
5676
5677   mp->use_random_mac = random_mac;
5678   mp->sw_if_index = ntohl (sw_if_index);
5679   clib_memcpy (mp->mac_address, mac_address, 6);
5680   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5681   vec_free (tap_name);
5682
5683   /* send it... */
5684   S;
5685
5686   /* Wait for a reply... */
5687   W;
5688 }
5689
5690 static int
5691 api_tap_delete (vat_main_t * vam)
5692 {
5693   unformat_input_t *i = vam->input;
5694   vl_api_tap_delete_t *mp;
5695   f64 timeout;
5696   u32 sw_if_index = ~0;
5697   u8 sw_if_index_set = 0;
5698
5699   /* Parse args required to build the message */
5700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5701     {
5702       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5703         sw_if_index_set = 1;
5704       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5705         sw_if_index_set = 1;
5706       else
5707         break;
5708     }
5709
5710   if (sw_if_index_set == 0)
5711     {
5712       errmsg ("missing vpp interface name");
5713       return -99;
5714     }
5715
5716   /* Construct the API message */
5717   M (TAP_DELETE, tap_delete);
5718
5719   mp->sw_if_index = ntohl (sw_if_index);
5720
5721   /* send it... */
5722   S;
5723
5724   /* Wait for a reply... */
5725   W;
5726 }
5727
5728 static int
5729 api_ip_add_del_route (vat_main_t * vam)
5730 {
5731   unformat_input_t *i = vam->input;
5732   vl_api_ip_add_del_route_t *mp;
5733   f64 timeout;
5734   u32 sw_if_index = ~0, vrf_id = 0;
5735   u8 sw_if_index_set = 0;
5736   u8 is_ipv6 = 0;
5737   u8 is_local = 0, is_drop = 0;
5738   u8 is_unreach = 0, is_prohibit = 0;
5739   u8 create_vrf_if_needed = 0;
5740   u8 is_add = 1;
5741   u32 next_hop_weight = 1;
5742   u8 not_last = 0;
5743   u8 is_multipath = 0;
5744   u8 address_set = 0;
5745   u8 address_length_set = 0;
5746   u32 next_hop_table_id = 0;
5747   u32 resolve_attempts = 0;
5748   u32 dst_address_length = 0;
5749   u8 next_hop_set = 0;
5750   ip4_address_t v4_dst_address, v4_next_hop_address;
5751   ip6_address_t v6_dst_address, v6_next_hop_address;
5752   int count = 1;
5753   int j;
5754   f64 before = 0;
5755   u32 random_add_del = 0;
5756   u32 *random_vector = 0;
5757   uword *random_hash;
5758   u32 random_seed = 0xdeaddabe;
5759   u32 classify_table_index = ~0;
5760   u8 is_classify = 0;
5761   u8 resolve_host = 0, resolve_attached = 0;
5762   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5763
5764   /* Parse args required to build the message */
5765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5766     {
5767       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5768         sw_if_index_set = 1;
5769       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5770         sw_if_index_set = 1;
5771       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5772         {
5773           address_set = 1;
5774           is_ipv6 = 0;
5775         }
5776       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5777         {
5778           address_set = 1;
5779           is_ipv6 = 1;
5780         }
5781       else if (unformat (i, "/%d", &dst_address_length))
5782         {
5783           address_length_set = 1;
5784         }
5785
5786       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5787                                          &v4_next_hop_address))
5788         {
5789           next_hop_set = 1;
5790         }
5791       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5792                                          &v6_next_hop_address))
5793         {
5794           next_hop_set = 1;
5795         }
5796       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5797         ;
5798       else if (unformat (i, "weight %d", &next_hop_weight))
5799         ;
5800       else if (unformat (i, "drop"))
5801         {
5802           is_drop = 1;
5803         }
5804       else if (unformat (i, "null-send-unreach"))
5805         {
5806           is_unreach = 1;
5807         }
5808       else if (unformat (i, "null-send-prohibit"))
5809         {
5810           is_prohibit = 1;
5811         }
5812       else if (unformat (i, "local"))
5813         {
5814           is_local = 1;
5815         }
5816       else if (unformat (i, "classify %d", &classify_table_index))
5817         {
5818           is_classify = 1;
5819         }
5820       else if (unformat (i, "del"))
5821         is_add = 0;
5822       else if (unformat (i, "add"))
5823         is_add = 1;
5824       else if (unformat (i, "not-last"))
5825         not_last = 1;
5826       else if (unformat (i, "resolve-via-host"))
5827         resolve_host = 1;
5828       else if (unformat (i, "resolve-via-attached"))
5829         resolve_attached = 1;
5830       else if (unformat (i, "multipath"))
5831         is_multipath = 1;
5832       else if (unformat (i, "vrf %d", &vrf_id))
5833         ;
5834       else if (unformat (i, "create-vrf"))
5835         create_vrf_if_needed = 1;
5836       else if (unformat (i, "count %d", &count))
5837         ;
5838       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
5839         ;
5840       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
5841         ;
5842       else if (unformat (i, "out-label %d", &next_hop_out_label))
5843         ;
5844       else if (unformat (i, "random"))
5845         random_add_del = 1;
5846       else if (unformat (i, "seed %d", &random_seed))
5847         ;
5848       else
5849         {
5850           clib_warning ("parse error '%U'", format_unformat_error, i);
5851           return -99;
5852         }
5853     }
5854
5855   if (resolve_attempts > 0 && sw_if_index_set == 0)
5856     {
5857       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5858       return -99;
5859     }
5860
5861   if (!next_hop_set && !is_drop && !is_local &&
5862       !is_classify && !is_unreach && !is_prohibit)
5863     {
5864       errmsg
5865         ("next hop / local / drop / unreach / prohibit / classify not set\n");
5866       return -99;
5867     }
5868
5869   if (address_set == 0)
5870     {
5871       errmsg ("missing addresses\n");
5872       return -99;
5873     }
5874
5875   if (address_length_set == 0)
5876     {
5877       errmsg ("missing address length\n");
5878       return -99;
5879     }
5880
5881   /* Generate a pile of unique, random routes */
5882   if (random_add_del)
5883     {
5884       u32 this_random_address;
5885       random_hash = hash_create (count, sizeof (uword));
5886
5887       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5888       for (j = 0; j <= count; j++)
5889         {
5890           do
5891             {
5892               this_random_address = random_u32 (&random_seed);
5893               this_random_address =
5894                 clib_host_to_net_u32 (this_random_address);
5895             }
5896           while (hash_get (random_hash, this_random_address));
5897           vec_add1 (random_vector, this_random_address);
5898           hash_set (random_hash, this_random_address, 1);
5899         }
5900       hash_free (random_hash);
5901       v4_dst_address.as_u32 = random_vector[0];
5902     }
5903
5904   if (count > 1)
5905     {
5906       /* Turn on async mode */
5907       vam->async_mode = 1;
5908       vam->async_errors = 0;
5909       before = vat_time_now (vam);
5910     }
5911
5912   for (j = 0; j < count; j++)
5913     {
5914       /* Construct the API message */
5915       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5916
5917       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5918       mp->table_id = ntohl (vrf_id);
5919       if (resolve_attempts > 0)
5920         {
5921           mp->resolve_attempts = ntohl (resolve_attempts);
5922           mp->resolve_if_needed = 1;
5923         }
5924       mp->create_vrf_if_needed = create_vrf_if_needed;
5925
5926       mp->is_add = is_add;
5927       mp->is_drop = is_drop;
5928       mp->is_unreach = is_unreach;
5929       mp->is_prohibit = is_prohibit;
5930       mp->is_ipv6 = is_ipv6;
5931       mp->is_local = is_local;
5932       mp->is_classify = is_classify;
5933       mp->is_multipath = is_multipath;
5934       mp->is_resolve_host = resolve_host;
5935       mp->is_resolve_attached = resolve_attached;
5936       mp->not_last = not_last;
5937       mp->next_hop_weight = next_hop_weight;
5938       mp->dst_address_length = dst_address_length;
5939       mp->next_hop_table_id = ntohl (next_hop_table_id);
5940       mp->classify_table_index = ntohl (classify_table_index);
5941       mp->next_hop_out_label = ntohl (next_hop_out_label);
5942
5943       if (is_ipv6)
5944         {
5945           clib_memcpy (mp->dst_address, &v6_dst_address,
5946                        sizeof (v6_dst_address));
5947           if (next_hop_set)
5948             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5949                          sizeof (v6_next_hop_address));
5950           increment_v6_address (&v6_dst_address);
5951         }
5952       else
5953         {
5954           clib_memcpy (mp->dst_address, &v4_dst_address,
5955                        sizeof (v4_dst_address));
5956           if (next_hop_set)
5957             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5958                          sizeof (v4_next_hop_address));
5959           if (random_add_del)
5960             v4_dst_address.as_u32 = random_vector[j + 1];
5961           else
5962             increment_v4_address (&v4_dst_address);
5963         }
5964       /* send it... */
5965       S;
5966       /* If we receive SIGTERM, stop now... */
5967       if (vam->do_exit)
5968         break;
5969     }
5970
5971   /* When testing multiple add/del ops, use a control-ping to sync */
5972   if (count > 1)
5973     {
5974       vl_api_control_ping_t *mp;
5975       f64 after;
5976
5977       /* Shut off async mode */
5978       vam->async_mode = 0;
5979
5980       M (CONTROL_PING, control_ping);
5981       S;
5982
5983       timeout = vat_time_now (vam) + 1.0;
5984       while (vat_time_now (vam) < timeout)
5985         if (vam->result_ready == 1)
5986           goto out;
5987       vam->retval = -99;
5988
5989     out:
5990       if (vam->retval == -99)
5991         errmsg ("timeout\n");
5992
5993       if (vam->async_errors > 0)
5994         {
5995           errmsg ("%d asynchronous errors\n", vam->async_errors);
5996           vam->retval = -98;
5997         }
5998       vam->async_errors = 0;
5999       after = vat_time_now (vam);
6000
6001       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6002       if (j > 0)
6003         count = j;
6004
6005       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6006                count, after - before, count / (after - before));
6007     }
6008   else
6009     {
6010       /* Wait for a reply... */
6011       W;
6012     }
6013
6014   /* Return the good/bad news */
6015   return (vam->retval);
6016 }
6017
6018 static int
6019 api_mpls_route_add_del (vat_main_t * vam)
6020 {
6021   unformat_input_t *i = vam->input;
6022   vl_api_mpls_route_add_del_t *mp;
6023   f64 timeout;
6024   u32 sw_if_index = ~0, table_id = 0;
6025   u8 create_table_if_needed = 0;
6026   u8 is_add = 1;
6027   u32 next_hop_weight = 1;
6028   u8 is_multipath = 0;
6029   u32 next_hop_table_id = 0;
6030   u8 next_hop_set = 0;
6031   ip4_address_t v4_next_hop_address = {
6032     .as_u32 = 0,
6033   };
6034   ip6_address_t v6_next_hop_address = { {0} };
6035   int count = 1;
6036   int j;
6037   f64 before = 0;
6038   u32 classify_table_index = ~0;
6039   u8 is_classify = 0;
6040   u8 resolve_host = 0, resolve_attached = 0;
6041   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6042   mpls_label_t local_label = MPLS_LABEL_INVALID;
6043   u8 is_eos = 1;
6044   u8 next_hop_proto_is_ip4 = 1;
6045
6046   /* Parse args required to build the message */
6047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6048     {
6049       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6050         ;
6051       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6052         ;
6053       else if (unformat (i, "%d", &local_label))
6054         ;
6055       else if (unformat (i, "eos"))
6056         is_eos = 1;
6057       else if (unformat (i, "non-eos"))
6058         is_eos = 0;
6059       else if (unformat (i, "via %U", unformat_ip4_address,
6060                          &v4_next_hop_address))
6061         {
6062           next_hop_set = 1;
6063           next_hop_proto_is_ip4 = 1;
6064         }
6065       else if (unformat (i, "via %U", unformat_ip6_address,
6066                          &v6_next_hop_address))
6067         {
6068           next_hop_set = 1;
6069           next_hop_proto_is_ip4 = 0;
6070         }
6071       else if (unformat (i, "weight %d", &next_hop_weight))
6072         ;
6073       else if (unformat (i, "create-table"))
6074         create_table_if_needed = 1;
6075       else if (unformat (i, "classify %d", &classify_table_index))
6076         {
6077           is_classify = 1;
6078         }
6079       else if (unformat (i, "del"))
6080         is_add = 0;
6081       else if (unformat (i, "add"))
6082         is_add = 1;
6083       else if (unformat (i, "resolve-via-host"))
6084         resolve_host = 1;
6085       else if (unformat (i, "resolve-via-attached"))
6086         resolve_attached = 1;
6087       else if (unformat (i, "multipath"))
6088         is_multipath = 1;
6089       else if (unformat (i, "count %d", &count))
6090         ;
6091       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6092         {
6093           next_hop_set = 1;
6094           next_hop_proto_is_ip4 = 1;
6095         }
6096       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6097         {
6098           next_hop_set = 1;
6099           next_hop_proto_is_ip4 = 0;
6100         }
6101       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6102         ;
6103       else if (unformat (i, "out-label %d", &next_hop_out_label))
6104         ;
6105       else
6106         {
6107           clib_warning ("parse error '%U'", format_unformat_error, i);
6108           return -99;
6109         }
6110     }
6111
6112   if (!next_hop_set && !is_classify)
6113     {
6114       errmsg ("next hop / classify not set\n");
6115       return -99;
6116     }
6117
6118   if (MPLS_LABEL_INVALID == local_label)
6119     {
6120       errmsg ("missing label\n");
6121       return -99;
6122     }
6123
6124   if (count > 1)
6125     {
6126       /* Turn on async mode */
6127       vam->async_mode = 1;
6128       vam->async_errors = 0;
6129       before = vat_time_now (vam);
6130     }
6131
6132   for (j = 0; j < count; j++)
6133     {
6134       /* Construct the API message */
6135       M (MPLS_ROUTE_ADD_DEL, mpls_route_add_del);
6136
6137       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6138       mp->mr_table_id = ntohl (table_id);
6139       mp->mr_create_table_if_needed = create_table_if_needed;
6140
6141       mp->mr_is_add = is_add;
6142       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6143       mp->mr_is_classify = is_classify;
6144       mp->mr_is_multipath = is_multipath;
6145       mp->mr_is_resolve_host = resolve_host;
6146       mp->mr_is_resolve_attached = resolve_attached;
6147       mp->mr_next_hop_weight = next_hop_weight;
6148       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6149       mp->mr_classify_table_index = ntohl (classify_table_index);
6150       mp->mr_next_hop_out_label = ntohl (next_hop_out_label);
6151       mp->mr_label = ntohl (local_label);
6152       mp->mr_eos = is_eos;
6153
6154       if (next_hop_set)
6155         {
6156           if (next_hop_proto_is_ip4)
6157             {
6158               clib_memcpy (mp->mr_next_hop,
6159                            &v4_next_hop_address,
6160                            sizeof (v4_next_hop_address));
6161             }
6162           else
6163             {
6164               clib_memcpy (mp->mr_next_hop,
6165                            &v6_next_hop_address,
6166                            sizeof (v6_next_hop_address));
6167             }
6168         }
6169       local_label++;
6170
6171       /* send it... */
6172       S;
6173       /* If we receive SIGTERM, stop now... */
6174       if (vam->do_exit)
6175         break;
6176     }
6177
6178   /* When testing multiple add/del ops, use a control-ping to sync */
6179   if (count > 1)
6180     {
6181       vl_api_control_ping_t *mp;
6182       f64 after;
6183
6184       /* Shut off async mode */
6185       vam->async_mode = 0;
6186
6187       M (CONTROL_PING, control_ping);
6188       S;
6189
6190       timeout = vat_time_now (vam) + 1.0;
6191       while (vat_time_now (vam) < timeout)
6192         if (vam->result_ready == 1)
6193           goto out;
6194       vam->retval = -99;
6195
6196     out:
6197       if (vam->retval == -99)
6198         errmsg ("timeout\n");
6199
6200       if (vam->async_errors > 0)
6201         {
6202           errmsg ("%d asynchronous errors\n", vam->async_errors);
6203           vam->retval = -98;
6204         }
6205       vam->async_errors = 0;
6206       after = vat_time_now (vam);
6207
6208       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6209       if (j > 0)
6210         count = j;
6211
6212       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6213                count, after - before, count / (after - before));
6214     }
6215   else
6216     {
6217       /* Wait for a reply... */
6218       W;
6219     }
6220
6221   /* Return the good/bad news */
6222   return (vam->retval);
6223 }
6224
6225 static int
6226 api_mpls_ip_bind_unbind (vat_main_t * vam)
6227 {
6228   unformat_input_t *i = vam->input;
6229   vl_api_mpls_ip_bind_unbind_t *mp;
6230   f64 timeout;
6231   u32 ip_table_id = 0;
6232   u8 create_table_if_needed = 0;
6233   u8 is_bind = 1;
6234   u8 is_ip4 = 1;
6235   ip4_address_t v4_address;
6236   ip6_address_t v6_address;
6237   u32 address_length;
6238   u8 address_set = 0;
6239   mpls_label_t local_label = MPLS_LABEL_INVALID;
6240
6241   /* Parse args required to build the message */
6242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6243     {
6244       if (unformat (i, "%U/%d", unformat_ip4_address,
6245                     &v4_address, &address_length))
6246         {
6247           is_ip4 = 1;
6248           address_set = 1;
6249         }
6250       else if (unformat (i, "%U/%d", unformat_ip6_address,
6251                          &v6_address, &address_length))
6252         {
6253           is_ip4 = 0;
6254           address_set = 1;
6255         }
6256       else if (unformat (i, "%d", &local_label))
6257         ;
6258       else if (unformat (i, "create-table"))
6259         create_table_if_needed = 1;
6260       else if (unformat (i, "table-id %d", &ip_table_id))
6261         ;
6262       else if (unformat (i, "unbind"))
6263         is_bind = 0;
6264       else if (unformat (i, "bind"))
6265         is_bind = 1;
6266       else
6267         {
6268           clib_warning ("parse error '%U'", format_unformat_error, i);
6269           return -99;
6270         }
6271     }
6272
6273   if (!address_set)
6274     {
6275       errmsg ("IP addres not set\n");
6276       return -99;
6277     }
6278
6279   if (MPLS_LABEL_INVALID == local_label)
6280     {
6281       errmsg ("missing label\n");
6282       return -99;
6283     }
6284
6285   /* Construct the API message */
6286   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6287
6288   mp->mb_create_table_if_needed = create_table_if_needed;
6289   mp->mb_is_bind = is_bind;
6290   mp->mb_is_ip4 = is_ip4;
6291   mp->mb_ip_table_id = ntohl (ip_table_id);
6292   mp->mb_mpls_table_id = 0;
6293   mp->mb_label = ntohl (local_label);
6294   mp->mb_address_length = address_length;
6295
6296   if (is_ip4)
6297     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6298   else
6299     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6300
6301   /* send it... */
6302   S;
6303
6304   /* Wait for a reply... */
6305   W;
6306 }
6307
6308 static int
6309 api_proxy_arp_add_del (vat_main_t * vam)
6310 {
6311   unformat_input_t *i = vam->input;
6312   vl_api_proxy_arp_add_del_t *mp;
6313   f64 timeout;
6314   u32 vrf_id = 0;
6315   u8 is_add = 1;
6316   ip4_address_t lo, hi;
6317   u8 range_set = 0;
6318
6319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6320     {
6321       if (unformat (i, "vrf %d", &vrf_id))
6322         ;
6323       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6324                          unformat_ip4_address, &hi))
6325         range_set = 1;
6326       else if (unformat (i, "del"))
6327         is_add = 0;
6328       else
6329         {
6330           clib_warning ("parse error '%U'", format_unformat_error, i);
6331           return -99;
6332         }
6333     }
6334
6335   if (range_set == 0)
6336     {
6337       errmsg ("address range not set\n");
6338       return -99;
6339     }
6340
6341   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6342
6343   mp->vrf_id = ntohl (vrf_id);
6344   mp->is_add = is_add;
6345   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6346   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6347
6348   S;
6349   W;
6350   /* NOTREACHED */
6351   return 0;
6352 }
6353
6354 static int
6355 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6356 {
6357   unformat_input_t *i = vam->input;
6358   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6359   f64 timeout;
6360   u32 sw_if_index;
6361   u8 enable = 1;
6362   u8 sw_if_index_set = 0;
6363
6364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6365     {
6366       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6367         sw_if_index_set = 1;
6368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6369         sw_if_index_set = 1;
6370       else if (unformat (i, "enable"))
6371         enable = 1;
6372       else if (unformat (i, "disable"))
6373         enable = 0;
6374       else
6375         {
6376           clib_warning ("parse error '%U'", format_unformat_error, i);
6377           return -99;
6378         }
6379     }
6380
6381   if (sw_if_index_set == 0)
6382     {
6383       errmsg ("missing interface name or sw_if_index\n");
6384       return -99;
6385     }
6386
6387   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6388
6389   mp->sw_if_index = ntohl (sw_if_index);
6390   mp->enable_disable = enable;
6391
6392   S;
6393   W;
6394   /* NOTREACHED */
6395   return 0;
6396 }
6397
6398 static int
6399 api_mpls_add_del_encap (vat_main_t * vam)
6400 {
6401   unformat_input_t *i = vam->input;
6402   vl_api_mpls_add_del_encap_t *mp;
6403   f64 timeout;
6404   u32 vrf_id = 0;
6405   u32 *labels = 0;
6406   u32 label;
6407   ip4_address_t dst_address;
6408   u8 is_add = 1;
6409
6410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6411     {
6412       if (unformat (i, "vrf %d", &vrf_id))
6413         ;
6414       else if (unformat (i, "label %d", &label))
6415         vec_add1 (labels, ntohl (label));
6416       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6417         ;
6418       else if (unformat (i, "del"))
6419         is_add = 0;
6420       else
6421         {
6422           clib_warning ("parse error '%U'", format_unformat_error, i);
6423           return -99;
6424         }
6425     }
6426
6427   if (vec_len (labels) == 0)
6428     {
6429       errmsg ("missing encap label stack\n");
6430       return -99;
6431     }
6432
6433   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6434       sizeof (u32) * vec_len (labels));
6435
6436   mp->vrf_id = ntohl (vrf_id);
6437   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6438   mp->is_add = is_add;
6439   mp->nlabels = vec_len (labels);
6440   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6441
6442   vec_free (labels);
6443
6444   S;
6445   W;
6446   /* NOTREACHED */
6447   return 0;
6448 }
6449
6450 static int
6451 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6452 {
6453   unformat_input_t *i = vam->input;
6454   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6455   f64 timeout;
6456   u32 inner_vrf_id = 0;
6457   ip4_address_t intfc_address;
6458   u8 dst_mac_address[6];
6459   int dst_set = 1;
6460   u32 tmp;
6461   u8 intfc_address_length = 0;
6462   u8 is_add = 1;
6463   u8 l2_only = 0;
6464   u32 tx_sw_if_index;
6465   int tx_sw_if_index_set = 0;
6466
6467   /* Shut up coverity */
6468   memset (dst_mac_address, 0, sizeof (dst_mac_address));
6469
6470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6471     {
6472       if (unformat (i, "vrf %d", &inner_vrf_id))
6473         ;
6474       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6475                          &intfc_address, &tmp))
6476         intfc_address_length = tmp;
6477       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6478         tx_sw_if_index_set = 1;
6479       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6480         tx_sw_if_index_set = 1;
6481       else if (unformat (i, "dst %U", unformat_ethernet_address,
6482                          dst_mac_address))
6483         dst_set = 1;
6484       else if (unformat (i, "l2-only"))
6485         l2_only = 1;
6486       else if (unformat (i, "del"))
6487         is_add = 0;
6488       else
6489         {
6490           clib_warning ("parse error '%U'", format_unformat_error, i);
6491           return -99;
6492         }
6493     }
6494
6495   if (!dst_set)
6496     {
6497       errmsg ("dst (mac address) not set\n");
6498       return -99;
6499     }
6500   if (!tx_sw_if_index_set)
6501     {
6502       errmsg ("tx-intfc not set\n");
6503       return -99;
6504     }
6505
6506   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6507
6508   mp->vrf_id = ntohl (inner_vrf_id);
6509   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6510   mp->adj_address_length = intfc_address_length;
6511   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6512                sizeof (dst_mac_address));
6513   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6514   mp->l2_only = l2_only;
6515   mp->is_add = is_add;
6516
6517   S;
6518   W;
6519   /* NOTREACHED */
6520   return 0;
6521 }
6522
6523 static int
6524 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6525 {
6526   unformat_input_t *i = vam->input;
6527   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6528   f64 timeout;
6529   u32 inner_vrf_id = 0;
6530   u32 outer_vrf_id = 0;
6531   ip4_address_t adj_address;
6532   int adj_address_set = 0;
6533   ip4_address_t next_hop_address;
6534   int next_hop_address_set = 0;
6535   u32 tmp;
6536   u8 adj_address_length = 0;
6537   u8 l2_only = 0;
6538   u8 is_add = 1;
6539   u32 resolve_attempts = 5;
6540   u8 resolve_if_needed = 1;
6541
6542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6543     {
6544       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6545         ;
6546       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6547         ;
6548       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6549                          &adj_address, &tmp))
6550         {
6551           adj_address_length = tmp;
6552           adj_address_set = 1;
6553         }
6554       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6555                          &next_hop_address))
6556         next_hop_address_set = 1;
6557       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6558         ;
6559       else if (unformat (i, "resolve-if-needed %d", &tmp))
6560         resolve_if_needed = tmp;
6561       else if (unformat (i, "l2-only"))
6562         l2_only = 1;
6563       else if (unformat (i, "del"))
6564         is_add = 0;
6565       else
6566         {
6567           clib_warning ("parse error '%U'", format_unformat_error, i);
6568           return -99;
6569         }
6570     }
6571
6572   if (!adj_address_set)
6573     {
6574       errmsg ("adjacency address/mask not set\n");
6575       return -99;
6576     }
6577   if (!next_hop_address_set)
6578     {
6579       errmsg ("ip4 next hop address (in outer fib) not set\n");
6580       return -99;
6581     }
6582
6583   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6584
6585   mp->inner_vrf_id = ntohl (inner_vrf_id);
6586   mp->outer_vrf_id = ntohl (outer_vrf_id);
6587   mp->resolve_attempts = ntohl (resolve_attempts);
6588   mp->resolve_if_needed = resolve_if_needed;
6589   mp->is_add = is_add;
6590   mp->l2_only = l2_only;
6591   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6592   mp->adj_address_length = adj_address_length;
6593   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6594                sizeof (next_hop_address));
6595
6596   S;
6597   W;
6598   /* NOTREACHED */
6599   return 0;
6600 }
6601
6602 static int
6603 api_sw_interface_set_unnumbered (vat_main_t * vam)
6604 {
6605   unformat_input_t *i = vam->input;
6606   vl_api_sw_interface_set_unnumbered_t *mp;
6607   f64 timeout;
6608   u32 sw_if_index;
6609   u32 unnum_sw_index = ~0;
6610   u8 is_add = 1;
6611   u8 sw_if_index_set = 0;
6612
6613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6614     {
6615       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6616         sw_if_index_set = 1;
6617       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6618         sw_if_index_set = 1;
6619       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6620         ;
6621       else if (unformat (i, "del"))
6622         is_add = 0;
6623       else
6624         {
6625           clib_warning ("parse error '%U'", format_unformat_error, i);
6626           return -99;
6627         }
6628     }
6629
6630   if (sw_if_index_set == 0)
6631     {
6632       errmsg ("missing interface name or sw_if_index\n");
6633       return -99;
6634     }
6635
6636   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6637
6638   mp->sw_if_index = ntohl (sw_if_index);
6639   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6640   mp->is_add = is_add;
6641
6642   S;
6643   W;
6644   /* NOTREACHED */
6645   return 0;
6646 }
6647
6648 static int
6649 api_ip_neighbor_add_del (vat_main_t * vam)
6650 {
6651   unformat_input_t *i = vam->input;
6652   vl_api_ip_neighbor_add_del_t *mp;
6653   f64 timeout;
6654   u32 sw_if_index;
6655   u8 sw_if_index_set = 0;
6656   u32 vrf_id = 0;
6657   u8 is_add = 1;
6658   u8 is_static = 0;
6659   u8 mac_address[6];
6660   u8 mac_set = 0;
6661   u8 v4_address_set = 0;
6662   u8 v6_address_set = 0;
6663   ip4_address_t v4address;
6664   ip6_address_t v6address;
6665
6666   memset (mac_address, 0, sizeof (mac_address));
6667
6668   /* Parse args required to build the message */
6669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6670     {
6671       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6672         {
6673           mac_set = 1;
6674         }
6675       else if (unformat (i, "del"))
6676         is_add = 0;
6677       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6678         sw_if_index_set = 1;
6679       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6680         sw_if_index_set = 1;
6681       else if (unformat (i, "is_static"))
6682         is_static = 1;
6683       else if (unformat (i, "vrf %d", &vrf_id))
6684         ;
6685       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6686         v4_address_set = 1;
6687       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6688         v6_address_set = 1;
6689       else
6690         {
6691           clib_warning ("parse error '%U'", format_unformat_error, i);
6692           return -99;
6693         }
6694     }
6695
6696   if (sw_if_index_set == 0)
6697     {
6698       errmsg ("missing interface name or sw_if_index\n");
6699       return -99;
6700     }
6701   if (v4_address_set && v6_address_set)
6702     {
6703       errmsg ("both v4 and v6 addresses set\n");
6704       return -99;
6705     }
6706   if (!v4_address_set && !v6_address_set)
6707     {
6708       errmsg ("no address set\n");
6709       return -99;
6710     }
6711
6712   /* Construct the API message */
6713   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6714
6715   mp->sw_if_index = ntohl (sw_if_index);
6716   mp->is_add = is_add;
6717   mp->vrf_id = ntohl (vrf_id);
6718   mp->is_static = is_static;
6719   if (mac_set)
6720     clib_memcpy (mp->mac_address, mac_address, 6);
6721   if (v6_address_set)
6722     {
6723       mp->is_ipv6 = 1;
6724       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6725     }
6726   else
6727     {
6728       /* mp->is_ipv6 = 0; via memset in M macro above */
6729       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6730     }
6731
6732   /* send it... */
6733   S;
6734
6735   /* Wait for a reply, return good/bad news  */
6736   W;
6737
6738   /* NOTREACHED */
6739   return 0;
6740 }
6741
6742 static int
6743 api_reset_vrf (vat_main_t * vam)
6744 {
6745   unformat_input_t *i = vam->input;
6746   vl_api_reset_vrf_t *mp;
6747   f64 timeout;
6748   u32 vrf_id = 0;
6749   u8 is_ipv6 = 0;
6750   u8 vrf_id_set = 0;
6751
6752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6753     {
6754       if (unformat (i, "vrf %d", &vrf_id))
6755         vrf_id_set = 1;
6756       else if (unformat (i, "ipv6"))
6757         is_ipv6 = 1;
6758       else
6759         {
6760           clib_warning ("parse error '%U'", format_unformat_error, i);
6761           return -99;
6762         }
6763     }
6764
6765   if (vrf_id_set == 0)
6766     {
6767       errmsg ("missing vrf id\n");
6768       return -99;
6769     }
6770
6771   M (RESET_VRF, reset_vrf);
6772
6773   mp->vrf_id = ntohl (vrf_id);
6774   mp->is_ipv6 = is_ipv6;
6775
6776   S;
6777   W;
6778   /* NOTREACHED */
6779   return 0;
6780 }
6781
6782 static int
6783 api_create_vlan_subif (vat_main_t * vam)
6784 {
6785   unformat_input_t *i = vam->input;
6786   vl_api_create_vlan_subif_t *mp;
6787   f64 timeout;
6788   u32 sw_if_index;
6789   u8 sw_if_index_set = 0;
6790   u32 vlan_id;
6791   u8 vlan_id_set = 0;
6792
6793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6794     {
6795       if (unformat (i, "sw_if_index %d", &sw_if_index))
6796         sw_if_index_set = 1;
6797       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6798         sw_if_index_set = 1;
6799       else if (unformat (i, "vlan %d", &vlan_id))
6800         vlan_id_set = 1;
6801       else
6802         {
6803           clib_warning ("parse error '%U'", format_unformat_error, i);
6804           return -99;
6805         }
6806     }
6807
6808   if (sw_if_index_set == 0)
6809     {
6810       errmsg ("missing interface name or sw_if_index\n");
6811       return -99;
6812     }
6813
6814   if (vlan_id_set == 0)
6815     {
6816       errmsg ("missing vlan_id\n");
6817       return -99;
6818     }
6819   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6820
6821   mp->sw_if_index = ntohl (sw_if_index);
6822   mp->vlan_id = ntohl (vlan_id);
6823
6824   S;
6825   W;
6826   /* NOTREACHED */
6827   return 0;
6828 }
6829
6830 #define foreach_create_subif_bit                \
6831 _(no_tags)                                      \
6832 _(one_tag)                                      \
6833 _(two_tags)                                     \
6834 _(dot1ad)                                       \
6835 _(exact_match)                                  \
6836 _(default_sub)                                  \
6837 _(outer_vlan_id_any)                            \
6838 _(inner_vlan_id_any)
6839
6840 static int
6841 api_create_subif (vat_main_t * vam)
6842 {
6843   unformat_input_t *i = vam->input;
6844   vl_api_create_subif_t *mp;
6845   f64 timeout;
6846   u32 sw_if_index;
6847   u8 sw_if_index_set = 0;
6848   u32 sub_id;
6849   u8 sub_id_set = 0;
6850   u32 no_tags = 0;
6851   u32 one_tag = 0;
6852   u32 two_tags = 0;
6853   u32 dot1ad = 0;
6854   u32 exact_match = 0;
6855   u32 default_sub = 0;
6856   u32 outer_vlan_id_any = 0;
6857   u32 inner_vlan_id_any = 0;
6858   u32 tmp;
6859   u16 outer_vlan_id = 0;
6860   u16 inner_vlan_id = 0;
6861
6862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6863     {
6864       if (unformat (i, "sw_if_index %d", &sw_if_index))
6865         sw_if_index_set = 1;
6866       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6867         sw_if_index_set = 1;
6868       else if (unformat (i, "sub_id %d", &sub_id))
6869         sub_id_set = 1;
6870       else if (unformat (i, "outer_vlan_id %d", &tmp))
6871         outer_vlan_id = tmp;
6872       else if (unformat (i, "inner_vlan_id %d", &tmp))
6873         inner_vlan_id = tmp;
6874
6875 #define _(a) else if (unformat (i, #a)) a = 1 ;
6876       foreach_create_subif_bit
6877 #undef _
6878         else
6879         {
6880           clib_warning ("parse error '%U'", format_unformat_error, i);
6881           return -99;
6882         }
6883     }
6884
6885   if (sw_if_index_set == 0)
6886     {
6887       errmsg ("missing interface name or sw_if_index\n");
6888       return -99;
6889     }
6890
6891   if (sub_id_set == 0)
6892     {
6893       errmsg ("missing sub_id\n");
6894       return -99;
6895     }
6896   M (CREATE_SUBIF, create_subif);
6897
6898   mp->sw_if_index = ntohl (sw_if_index);
6899   mp->sub_id = ntohl (sub_id);
6900
6901 #define _(a) mp->a = a;
6902   foreach_create_subif_bit;
6903 #undef _
6904
6905   mp->outer_vlan_id = ntohs (outer_vlan_id);
6906   mp->inner_vlan_id = ntohs (inner_vlan_id);
6907
6908   S;
6909   W;
6910   /* NOTREACHED */
6911   return 0;
6912 }
6913
6914 static int
6915 api_oam_add_del (vat_main_t * vam)
6916 {
6917   unformat_input_t *i = vam->input;
6918   vl_api_oam_add_del_t *mp;
6919   f64 timeout;
6920   u32 vrf_id = 0;
6921   u8 is_add = 1;
6922   ip4_address_t src, dst;
6923   u8 src_set = 0;
6924   u8 dst_set = 0;
6925
6926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6927     {
6928       if (unformat (i, "vrf %d", &vrf_id))
6929         ;
6930       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6931         src_set = 1;
6932       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6933         dst_set = 1;
6934       else if (unformat (i, "del"))
6935         is_add = 0;
6936       else
6937         {
6938           clib_warning ("parse error '%U'", format_unformat_error, i);
6939           return -99;
6940         }
6941     }
6942
6943   if (src_set == 0)
6944     {
6945       errmsg ("missing src addr\n");
6946       return -99;
6947     }
6948
6949   if (dst_set == 0)
6950     {
6951       errmsg ("missing dst addr\n");
6952       return -99;
6953     }
6954
6955   M (OAM_ADD_DEL, oam_add_del);
6956
6957   mp->vrf_id = ntohl (vrf_id);
6958   mp->is_add = is_add;
6959   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6960   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6961
6962   S;
6963   W;
6964   /* NOTREACHED */
6965   return 0;
6966 }
6967
6968 static int
6969 api_reset_fib (vat_main_t * vam)
6970 {
6971   unformat_input_t *i = vam->input;
6972   vl_api_reset_fib_t *mp;
6973   f64 timeout;
6974   u32 vrf_id = 0;
6975   u8 is_ipv6 = 0;
6976   u8 vrf_id_set = 0;
6977
6978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6979     {
6980       if (unformat (i, "vrf %d", &vrf_id))
6981         vrf_id_set = 1;
6982       else if (unformat (i, "ipv6"))
6983         is_ipv6 = 1;
6984       else
6985         {
6986           clib_warning ("parse error '%U'", format_unformat_error, i);
6987           return -99;
6988         }
6989     }
6990
6991   if (vrf_id_set == 0)
6992     {
6993       errmsg ("missing vrf id\n");
6994       return -99;
6995     }
6996
6997   M (RESET_FIB, reset_fib);
6998
6999   mp->vrf_id = ntohl (vrf_id);
7000   mp->is_ipv6 = is_ipv6;
7001
7002   S;
7003   W;
7004   /* NOTREACHED */
7005   return 0;
7006 }
7007
7008 static int
7009 api_dhcp_proxy_config (vat_main_t * vam)
7010 {
7011   unformat_input_t *i = vam->input;
7012   vl_api_dhcp_proxy_config_t *mp;
7013   f64 timeout;
7014   u32 vrf_id = 0;
7015   u8 is_add = 1;
7016   u8 insert_cid = 1;
7017   u8 v4_address_set = 0;
7018   u8 v6_address_set = 0;
7019   ip4_address_t v4address;
7020   ip6_address_t v6address;
7021   u8 v4_src_address_set = 0;
7022   u8 v6_src_address_set = 0;
7023   ip4_address_t v4srcaddress;
7024   ip6_address_t v6srcaddress;
7025
7026   /* Parse args required to build the message */
7027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7028     {
7029       if (unformat (i, "del"))
7030         is_add = 0;
7031       else if (unformat (i, "vrf %d", &vrf_id))
7032         ;
7033       else if (unformat (i, "insert-cid %d", &insert_cid))
7034         ;
7035       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7036         v4_address_set = 1;
7037       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7038         v6_address_set = 1;
7039       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7040         v4_src_address_set = 1;
7041       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7042         v6_src_address_set = 1;
7043       else
7044         break;
7045     }
7046
7047   if (v4_address_set && v6_address_set)
7048     {
7049       errmsg ("both v4 and v6 server addresses set\n");
7050       return -99;
7051     }
7052   if (!v4_address_set && !v6_address_set)
7053     {
7054       errmsg ("no server addresses set\n");
7055       return -99;
7056     }
7057
7058   if (v4_src_address_set && v6_src_address_set)
7059     {
7060       errmsg ("both v4 and v6  src addresses set\n");
7061       return -99;
7062     }
7063   if (!v4_src_address_set && !v6_src_address_set)
7064     {
7065       errmsg ("no src addresses set\n");
7066       return -99;
7067     }
7068
7069   if (!(v4_src_address_set && v4_address_set) &&
7070       !(v6_src_address_set && v6_address_set))
7071     {
7072       errmsg ("no matching server and src addresses set\n");
7073       return -99;
7074     }
7075
7076   /* Construct the API message */
7077   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7078
7079   mp->insert_circuit_id = insert_cid;
7080   mp->is_add = is_add;
7081   mp->vrf_id = ntohl (vrf_id);
7082   if (v6_address_set)
7083     {
7084       mp->is_ipv6 = 1;
7085       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7086       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7087     }
7088   else
7089     {
7090       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7091       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7092     }
7093
7094   /* send it... */
7095   S;
7096
7097   /* Wait for a reply, return good/bad news  */
7098   W;
7099   /* NOTREACHED */
7100   return 0;
7101 }
7102
7103 static int
7104 api_dhcp_proxy_config_2 (vat_main_t * vam)
7105 {
7106   unformat_input_t *i = vam->input;
7107   vl_api_dhcp_proxy_config_2_t *mp;
7108   f64 timeout;
7109   u32 rx_vrf_id = 0;
7110   u32 server_vrf_id = 0;
7111   u8 is_add = 1;
7112   u8 insert_cid = 1;
7113   u8 v4_address_set = 0;
7114   u8 v6_address_set = 0;
7115   ip4_address_t v4address;
7116   ip6_address_t v6address;
7117   u8 v4_src_address_set = 0;
7118   u8 v6_src_address_set = 0;
7119   ip4_address_t v4srcaddress;
7120   ip6_address_t v6srcaddress;
7121
7122   /* Parse args required to build the message */
7123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7124     {
7125       if (unformat (i, "del"))
7126         is_add = 0;
7127       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7128         ;
7129       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7130         ;
7131       else if (unformat (i, "insert-cid %d", &insert_cid))
7132         ;
7133       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7134         v4_address_set = 1;
7135       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7136         v6_address_set = 1;
7137       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7138         v4_src_address_set = 1;
7139       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7140         v6_src_address_set = 1;
7141       else
7142         break;
7143     }
7144
7145   if (v4_address_set && v6_address_set)
7146     {
7147       errmsg ("both v4 and v6 server addresses set\n");
7148       return -99;
7149     }
7150   if (!v4_address_set && !v6_address_set)
7151     {
7152       errmsg ("no server addresses set\n");
7153       return -99;
7154     }
7155
7156   if (v4_src_address_set && v6_src_address_set)
7157     {
7158       errmsg ("both v4 and v6  src addresses set\n");
7159       return -99;
7160     }
7161   if (!v4_src_address_set && !v6_src_address_set)
7162     {
7163       errmsg ("no src addresses set\n");
7164       return -99;
7165     }
7166
7167   if (!(v4_src_address_set && v4_address_set) &&
7168       !(v6_src_address_set && v6_address_set))
7169     {
7170       errmsg ("no matching server and src addresses set\n");
7171       return -99;
7172     }
7173
7174   /* Construct the API message */
7175   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7176
7177   mp->insert_circuit_id = insert_cid;
7178   mp->is_add = is_add;
7179   mp->rx_vrf_id = ntohl (rx_vrf_id);
7180   mp->server_vrf_id = ntohl (server_vrf_id);
7181   if (v6_address_set)
7182     {
7183       mp->is_ipv6 = 1;
7184       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7185       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7186     }
7187   else
7188     {
7189       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7190       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7191     }
7192
7193   /* send it... */
7194   S;
7195
7196   /* Wait for a reply, return good/bad news  */
7197   W;
7198   /* NOTREACHED */
7199   return 0;
7200 }
7201
7202 static int
7203 api_dhcp_proxy_set_vss (vat_main_t * vam)
7204 {
7205   unformat_input_t *i = vam->input;
7206   vl_api_dhcp_proxy_set_vss_t *mp;
7207   f64 timeout;
7208   u8 is_ipv6 = 0;
7209   u8 is_add = 1;
7210   u32 tbl_id;
7211   u8 tbl_id_set = 0;
7212   u32 oui;
7213   u8 oui_set = 0;
7214   u32 fib_id;
7215   u8 fib_id_set = 0;
7216
7217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7218     {
7219       if (unformat (i, "tbl_id %d", &tbl_id))
7220         tbl_id_set = 1;
7221       if (unformat (i, "fib_id %d", &fib_id))
7222         fib_id_set = 1;
7223       if (unformat (i, "oui %d", &oui))
7224         oui_set = 1;
7225       else if (unformat (i, "ipv6"))
7226         is_ipv6 = 1;
7227       else if (unformat (i, "del"))
7228         is_add = 0;
7229       else
7230         {
7231           clib_warning ("parse error '%U'", format_unformat_error, i);
7232           return -99;
7233         }
7234     }
7235
7236   if (tbl_id_set == 0)
7237     {
7238       errmsg ("missing tbl id\n");
7239       return -99;
7240     }
7241
7242   if (fib_id_set == 0)
7243     {
7244       errmsg ("missing fib id\n");
7245       return -99;
7246     }
7247   if (oui_set == 0)
7248     {
7249       errmsg ("missing oui\n");
7250       return -99;
7251     }
7252
7253   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7254   mp->tbl_id = ntohl (tbl_id);
7255   mp->fib_id = ntohl (fib_id);
7256   mp->oui = ntohl (oui);
7257   mp->is_ipv6 = is_ipv6;
7258   mp->is_add = is_add;
7259
7260   S;
7261   W;
7262   /* NOTREACHED */
7263   return 0;
7264 }
7265
7266 static int
7267 api_dhcp_client_config (vat_main_t * vam)
7268 {
7269   unformat_input_t *i = vam->input;
7270   vl_api_dhcp_client_config_t *mp;
7271   f64 timeout;
7272   u32 sw_if_index;
7273   u8 sw_if_index_set = 0;
7274   u8 is_add = 1;
7275   u8 *hostname = 0;
7276   u8 disable_event = 0;
7277
7278   /* Parse args required to build the message */
7279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7280     {
7281       if (unformat (i, "del"))
7282         is_add = 0;
7283       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7284         sw_if_index_set = 1;
7285       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7286         sw_if_index_set = 1;
7287       else if (unformat (i, "hostname %s", &hostname))
7288         ;
7289       else if (unformat (i, "disable_event"))
7290         disable_event = 1;
7291       else
7292         break;
7293     }
7294
7295   if (sw_if_index_set == 0)
7296     {
7297       errmsg ("missing interface name or sw_if_index\n");
7298       return -99;
7299     }
7300
7301   if (vec_len (hostname) > 63)
7302     {
7303       errmsg ("hostname too long\n");
7304     }
7305   vec_add1 (hostname, 0);
7306
7307   /* Construct the API message */
7308   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7309
7310   mp->sw_if_index = ntohl (sw_if_index);
7311   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7312   vec_free (hostname);
7313   mp->is_add = is_add;
7314   mp->want_dhcp_event = disable_event ? 0 : 1;
7315   mp->pid = getpid ();
7316
7317   /* send it... */
7318   S;
7319
7320   /* Wait for a reply, return good/bad news  */
7321   W;
7322   /* NOTREACHED */
7323   return 0;
7324 }
7325
7326 static int
7327 api_set_ip_flow_hash (vat_main_t * vam)
7328 {
7329   unformat_input_t *i = vam->input;
7330   vl_api_set_ip_flow_hash_t *mp;
7331   f64 timeout;
7332   u32 vrf_id = 0;
7333   u8 is_ipv6 = 0;
7334   u8 vrf_id_set = 0;
7335   u8 src = 0;
7336   u8 dst = 0;
7337   u8 sport = 0;
7338   u8 dport = 0;
7339   u8 proto = 0;
7340   u8 reverse = 0;
7341
7342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7343     {
7344       if (unformat (i, "vrf %d", &vrf_id))
7345         vrf_id_set = 1;
7346       else if (unformat (i, "ipv6"))
7347         is_ipv6 = 1;
7348       else if (unformat (i, "src"))
7349         src = 1;
7350       else if (unformat (i, "dst"))
7351         dst = 1;
7352       else if (unformat (i, "sport"))
7353         sport = 1;
7354       else if (unformat (i, "dport"))
7355         dport = 1;
7356       else if (unformat (i, "proto"))
7357         proto = 1;
7358       else if (unformat (i, "reverse"))
7359         reverse = 1;
7360
7361       else
7362         {
7363           clib_warning ("parse error '%U'", format_unformat_error, i);
7364           return -99;
7365         }
7366     }
7367
7368   if (vrf_id_set == 0)
7369     {
7370       errmsg ("missing vrf id\n");
7371       return -99;
7372     }
7373
7374   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7375   mp->src = src;
7376   mp->dst = dst;
7377   mp->sport = sport;
7378   mp->dport = dport;
7379   mp->proto = proto;
7380   mp->reverse = reverse;
7381   mp->vrf_id = ntohl (vrf_id);
7382   mp->is_ipv6 = is_ipv6;
7383
7384   S;
7385   W;
7386   /* NOTREACHED */
7387   return 0;
7388 }
7389
7390 static int
7391 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7392 {
7393   unformat_input_t *i = vam->input;
7394   vl_api_sw_interface_ip6_enable_disable_t *mp;
7395   f64 timeout;
7396   u32 sw_if_index;
7397   u8 sw_if_index_set = 0;
7398   u8 enable = 0;
7399
7400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7401     {
7402       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7403         sw_if_index_set = 1;
7404       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7405         sw_if_index_set = 1;
7406       else if (unformat (i, "enable"))
7407         enable = 1;
7408       else if (unformat (i, "disable"))
7409         enable = 0;
7410       else
7411         {
7412           clib_warning ("parse error '%U'", format_unformat_error, i);
7413           return -99;
7414         }
7415     }
7416
7417   if (sw_if_index_set == 0)
7418     {
7419       errmsg ("missing interface name or sw_if_index\n");
7420       return -99;
7421     }
7422
7423   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7424
7425   mp->sw_if_index = ntohl (sw_if_index);
7426   mp->enable = enable;
7427
7428   S;
7429   W;
7430   /* NOTREACHED */
7431   return 0;
7432 }
7433
7434 static int
7435 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7436 {
7437   unformat_input_t *i = vam->input;
7438   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7439   f64 timeout;
7440   u32 sw_if_index;
7441   u8 sw_if_index_set = 0;
7442   u32 address_length = 0;
7443   u8 v6_address_set = 0;
7444   ip6_address_t v6address;
7445
7446   /* Parse args required to build the message */
7447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7448     {
7449       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7450         sw_if_index_set = 1;
7451       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7452         sw_if_index_set = 1;
7453       else if (unformat (i, "%U/%d",
7454                          unformat_ip6_address, &v6address, &address_length))
7455         v6_address_set = 1;
7456       else
7457         break;
7458     }
7459
7460   if (sw_if_index_set == 0)
7461     {
7462       errmsg ("missing interface name or sw_if_index\n");
7463       return -99;
7464     }
7465   if (!v6_address_set)
7466     {
7467       errmsg ("no address set\n");
7468       return -99;
7469     }
7470
7471   /* Construct the API message */
7472   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7473      sw_interface_ip6_set_link_local_address);
7474
7475   mp->sw_if_index = ntohl (sw_if_index);
7476   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7477   mp->address_length = address_length;
7478
7479   /* send it... */
7480   S;
7481
7482   /* Wait for a reply, return good/bad news  */
7483   W;
7484
7485   /* NOTREACHED */
7486   return 0;
7487 }
7488
7489
7490 static int
7491 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7492 {
7493   unformat_input_t *i = vam->input;
7494   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7495   f64 timeout;
7496   u32 sw_if_index;
7497   u8 sw_if_index_set = 0;
7498   u32 address_length = 0;
7499   u8 v6_address_set = 0;
7500   ip6_address_t v6address;
7501   u8 use_default = 0;
7502   u8 no_advertise = 0;
7503   u8 off_link = 0;
7504   u8 no_autoconfig = 0;
7505   u8 no_onlink = 0;
7506   u8 is_no = 0;
7507   u32 val_lifetime = 0;
7508   u32 pref_lifetime = 0;
7509
7510   /* Parse args required to build the message */
7511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7512     {
7513       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7514         sw_if_index_set = 1;
7515       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7516         sw_if_index_set = 1;
7517       else if (unformat (i, "%U/%d",
7518                          unformat_ip6_address, &v6address, &address_length))
7519         v6_address_set = 1;
7520       else if (unformat (i, "val_life %d", &val_lifetime))
7521         ;
7522       else if (unformat (i, "pref_life %d", &pref_lifetime))
7523         ;
7524       else if (unformat (i, "def"))
7525         use_default = 1;
7526       else if (unformat (i, "noadv"))
7527         no_advertise = 1;
7528       else if (unformat (i, "offl"))
7529         off_link = 1;
7530       else if (unformat (i, "noauto"))
7531         no_autoconfig = 1;
7532       else if (unformat (i, "nolink"))
7533         no_onlink = 1;
7534       else if (unformat (i, "isno"))
7535         is_no = 1;
7536       else
7537         {
7538           clib_warning ("parse error '%U'", format_unformat_error, i);
7539           return -99;
7540         }
7541     }
7542
7543   if (sw_if_index_set == 0)
7544     {
7545       errmsg ("missing interface name or sw_if_index\n");
7546       return -99;
7547     }
7548   if (!v6_address_set)
7549     {
7550       errmsg ("no address set\n");
7551       return -99;
7552     }
7553
7554   /* Construct the API message */
7555   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7556
7557   mp->sw_if_index = ntohl (sw_if_index);
7558   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7559   mp->address_length = address_length;
7560   mp->use_default = use_default;
7561   mp->no_advertise = no_advertise;
7562   mp->off_link = off_link;
7563   mp->no_autoconfig = no_autoconfig;
7564   mp->no_onlink = no_onlink;
7565   mp->is_no = is_no;
7566   mp->val_lifetime = ntohl (val_lifetime);
7567   mp->pref_lifetime = ntohl (pref_lifetime);
7568
7569   /* send it... */
7570   S;
7571
7572   /* Wait for a reply, return good/bad news  */
7573   W;
7574
7575   /* NOTREACHED */
7576   return 0;
7577 }
7578
7579 static int
7580 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7581 {
7582   unformat_input_t *i = vam->input;
7583   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7584   f64 timeout;
7585   u32 sw_if_index;
7586   u8 sw_if_index_set = 0;
7587   u8 suppress = 0;
7588   u8 managed = 0;
7589   u8 other = 0;
7590   u8 ll_option = 0;
7591   u8 send_unicast = 0;
7592   u8 cease = 0;
7593   u8 is_no = 0;
7594   u8 default_router = 0;
7595   u32 max_interval = 0;
7596   u32 min_interval = 0;
7597   u32 lifetime = 0;
7598   u32 initial_count = 0;
7599   u32 initial_interval = 0;
7600
7601
7602   /* Parse args required to build the message */
7603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7604     {
7605       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7606         sw_if_index_set = 1;
7607       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7608         sw_if_index_set = 1;
7609       else if (unformat (i, "maxint %d", &max_interval))
7610         ;
7611       else if (unformat (i, "minint %d", &min_interval))
7612         ;
7613       else if (unformat (i, "life %d", &lifetime))
7614         ;
7615       else if (unformat (i, "count %d", &initial_count))
7616         ;
7617       else if (unformat (i, "interval %d", &initial_interval))
7618         ;
7619       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7620         suppress = 1;
7621       else if (unformat (i, "managed"))
7622         managed = 1;
7623       else if (unformat (i, "other"))
7624         other = 1;
7625       else if (unformat (i, "ll"))
7626         ll_option = 1;
7627       else if (unformat (i, "send"))
7628         send_unicast = 1;
7629       else if (unformat (i, "cease"))
7630         cease = 1;
7631       else if (unformat (i, "isno"))
7632         is_no = 1;
7633       else if (unformat (i, "def"))
7634         default_router = 1;
7635       else
7636         {
7637           clib_warning ("parse error '%U'", format_unformat_error, i);
7638           return -99;
7639         }
7640     }
7641
7642   if (sw_if_index_set == 0)
7643     {
7644       errmsg ("missing interface name or sw_if_index\n");
7645       return -99;
7646     }
7647
7648   /* Construct the API message */
7649   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7650
7651   mp->sw_if_index = ntohl (sw_if_index);
7652   mp->max_interval = ntohl (max_interval);
7653   mp->min_interval = ntohl (min_interval);
7654   mp->lifetime = ntohl (lifetime);
7655   mp->initial_count = ntohl (initial_count);
7656   mp->initial_interval = ntohl (initial_interval);
7657   mp->suppress = suppress;
7658   mp->managed = managed;
7659   mp->other = other;
7660   mp->ll_option = ll_option;
7661   mp->send_unicast = send_unicast;
7662   mp->cease = cease;
7663   mp->is_no = is_no;
7664   mp->default_router = default_router;
7665
7666   /* send it... */
7667   S;
7668
7669   /* Wait for a reply, return good/bad news  */
7670   W;
7671
7672   /* NOTREACHED */
7673   return 0;
7674 }
7675
7676 static int
7677 api_set_arp_neighbor_limit (vat_main_t * vam)
7678 {
7679   unformat_input_t *i = vam->input;
7680   vl_api_set_arp_neighbor_limit_t *mp;
7681   f64 timeout;
7682   u32 arp_nbr_limit;
7683   u8 limit_set = 0;
7684   u8 is_ipv6 = 0;
7685
7686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7687     {
7688       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7689         limit_set = 1;
7690       else if (unformat (i, "ipv6"))
7691         is_ipv6 = 1;
7692       else
7693         {
7694           clib_warning ("parse error '%U'", format_unformat_error, i);
7695           return -99;
7696         }
7697     }
7698
7699   if (limit_set == 0)
7700     {
7701       errmsg ("missing limit value\n");
7702       return -99;
7703     }
7704
7705   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7706
7707   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7708   mp->is_ipv6 = is_ipv6;
7709
7710   S;
7711   W;
7712   /* NOTREACHED */
7713   return 0;
7714 }
7715
7716 static int
7717 api_l2_patch_add_del (vat_main_t * vam)
7718 {
7719   unformat_input_t *i = vam->input;
7720   vl_api_l2_patch_add_del_t *mp;
7721   f64 timeout;
7722   u32 rx_sw_if_index;
7723   u8 rx_sw_if_index_set = 0;
7724   u32 tx_sw_if_index;
7725   u8 tx_sw_if_index_set = 0;
7726   u8 is_add = 1;
7727
7728   /* Parse args required to build the message */
7729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7730     {
7731       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7732         rx_sw_if_index_set = 1;
7733       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7734         tx_sw_if_index_set = 1;
7735       else if (unformat (i, "rx"))
7736         {
7737           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7738             {
7739               if (unformat (i, "%U", unformat_sw_if_index, vam,
7740                             &rx_sw_if_index))
7741                 rx_sw_if_index_set = 1;
7742             }
7743           else
7744             break;
7745         }
7746       else if (unformat (i, "tx"))
7747         {
7748           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7749             {
7750               if (unformat (i, "%U", unformat_sw_if_index, vam,
7751                             &tx_sw_if_index))
7752                 tx_sw_if_index_set = 1;
7753             }
7754           else
7755             break;
7756         }
7757       else if (unformat (i, "del"))
7758         is_add = 0;
7759       else
7760         break;
7761     }
7762
7763   if (rx_sw_if_index_set == 0)
7764     {
7765       errmsg ("missing rx interface name or rx_sw_if_index\n");
7766       return -99;
7767     }
7768
7769   if (tx_sw_if_index_set == 0)
7770     {
7771       errmsg ("missing tx interface name or tx_sw_if_index\n");
7772       return -99;
7773     }
7774
7775   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7776
7777   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7778   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7779   mp->is_add = is_add;
7780
7781   S;
7782   W;
7783   /* NOTREACHED */
7784   return 0;
7785 }
7786
7787 static int
7788 api_ioam_enable (vat_main_t * vam)
7789 {
7790   unformat_input_t *input = vam->input;
7791   vl_api_ioam_enable_t *mp;
7792   f64 timeout;
7793   u32 id = 0;
7794   int has_trace_option = 0;
7795   int has_pot_option = 0;
7796   int has_seqno_option = 0;
7797   int has_analyse_option = 0;
7798
7799   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7800     {
7801       if (unformat (input, "trace"))
7802         has_trace_option = 1;
7803       else if (unformat (input, "pot"))
7804         has_pot_option = 1;
7805       else if (unformat (input, "seqno"))
7806         has_seqno_option = 1;
7807       else if (unformat (input, "analyse"))
7808         has_analyse_option = 1;
7809       else
7810         break;
7811     }
7812   M (IOAM_ENABLE, ioam_enable);
7813   mp->id = htons (id);
7814   mp->seqno = has_seqno_option;
7815   mp->analyse = has_analyse_option;
7816   mp->pot_enable = has_pot_option;
7817   mp->trace_enable = has_trace_option;
7818
7819   S;
7820   W;
7821
7822   return (0);
7823
7824 }
7825
7826
7827 static int
7828 api_ioam_disable (vat_main_t * vam)
7829 {
7830   vl_api_ioam_disable_t *mp;
7831   f64 timeout;
7832
7833   M (IOAM_DISABLE, ioam_disable);
7834   S;
7835   W;
7836   return 0;
7837 }
7838
7839 static int
7840 api_sr_tunnel_add_del (vat_main_t * vam)
7841 {
7842   unformat_input_t *i = vam->input;
7843   vl_api_sr_tunnel_add_del_t *mp;
7844   f64 timeout;
7845   int is_del = 0;
7846   int pl_index;
7847   ip6_address_t src_address;
7848   int src_address_set = 0;
7849   ip6_address_t dst_address;
7850   u32 dst_mask_width;
7851   int dst_address_set = 0;
7852   u16 flags = 0;
7853   u32 rx_table_id = 0;
7854   u32 tx_table_id = 0;
7855   ip6_address_t *segments = 0;
7856   ip6_address_t *this_seg;
7857   ip6_address_t *tags = 0;
7858   ip6_address_t *this_tag;
7859   ip6_address_t next_address, tag;
7860   u8 *name = 0;
7861   u8 *policy_name = 0;
7862
7863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7864     {
7865       if (unformat (i, "del"))
7866         is_del = 1;
7867       else if (unformat (i, "name %s", &name))
7868         ;
7869       else if (unformat (i, "policy %s", &policy_name))
7870         ;
7871       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7872         ;
7873       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7874         ;
7875       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7876         src_address_set = 1;
7877       else if (unformat (i, "dst %U/%d",
7878                          unformat_ip6_address, &dst_address, &dst_mask_width))
7879         dst_address_set = 1;
7880       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7881         {
7882           vec_add2 (segments, this_seg, 1);
7883           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7884                        sizeof (*this_seg));
7885         }
7886       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7887         {
7888           vec_add2 (tags, this_tag, 1);
7889           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7890         }
7891       else if (unformat (i, "clean"))
7892         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7893       else if (unformat (i, "protected"))
7894         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7895       else if (unformat (i, "InPE %d", &pl_index))
7896         {
7897           if (pl_index <= 0 || pl_index > 4)
7898             {
7899             pl_index_range_error:
7900               errmsg ("pl index %d out of range\n", pl_index);
7901               return -99;
7902             }
7903           flags |=
7904             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7905         }
7906       else if (unformat (i, "EgPE %d", &pl_index))
7907         {
7908           if (pl_index <= 0 || pl_index > 4)
7909             goto pl_index_range_error;
7910           flags |=
7911             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7912         }
7913       else if (unformat (i, "OrgSrc %d", &pl_index))
7914         {
7915           if (pl_index <= 0 || pl_index > 4)
7916             goto pl_index_range_error;
7917           flags |=
7918             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7919         }
7920       else
7921         break;
7922     }
7923
7924   if (!src_address_set)
7925     {
7926       errmsg ("src address required\n");
7927       return -99;
7928     }
7929
7930   if (!dst_address_set)
7931     {
7932       errmsg ("dst address required\n");
7933       return -99;
7934     }
7935
7936   if (!segments)
7937     {
7938       errmsg ("at least one sr segment required\n");
7939       return -99;
7940     }
7941
7942   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7943       vec_len (segments) * sizeof (ip6_address_t)
7944       + vec_len (tags) * sizeof (ip6_address_t));
7945
7946   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7947   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7948   mp->dst_mask_width = dst_mask_width;
7949   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7950   mp->n_segments = vec_len (segments);
7951   mp->n_tags = vec_len (tags);
7952   mp->is_add = is_del == 0;
7953   clib_memcpy (mp->segs_and_tags, segments,
7954                vec_len (segments) * sizeof (ip6_address_t));
7955   clib_memcpy (mp->segs_and_tags +
7956                vec_len (segments) * sizeof (ip6_address_t), tags,
7957                vec_len (tags) * sizeof (ip6_address_t));
7958
7959   mp->outer_vrf_id = ntohl (rx_table_id);
7960   mp->inner_vrf_id = ntohl (tx_table_id);
7961   memcpy (mp->name, name, vec_len (name));
7962   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7963
7964   vec_free (segments);
7965   vec_free (tags);
7966
7967   S;
7968   W;
7969   /* NOTREACHED */
7970 }
7971
7972 static int
7973 api_sr_policy_add_del (vat_main_t * vam)
7974 {
7975   unformat_input_t *input = vam->input;
7976   vl_api_sr_policy_add_del_t *mp;
7977   f64 timeout;
7978   int is_del = 0;
7979   u8 *name = 0;
7980   u8 *tunnel_name = 0;
7981   u8 **tunnel_names = 0;
7982
7983   int name_set = 0;
7984   int tunnel_set = 0;
7985   int j = 0;
7986   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7987   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7988
7989   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7990     {
7991       if (unformat (input, "del"))
7992         is_del = 1;
7993       else if (unformat (input, "name %s", &name))
7994         name_set = 1;
7995       else if (unformat (input, "tunnel %s", &tunnel_name))
7996         {
7997           if (tunnel_name)
7998             {
7999               vec_add1 (tunnel_names, tunnel_name);
8000               /* For serializer:
8001                  - length = #bytes to store in serial vector
8002                  - +1 = byte to store that length
8003                */
8004               tunnel_names_length += (vec_len (tunnel_name) + 1);
8005               tunnel_set = 1;
8006               tunnel_name = 0;
8007             }
8008         }
8009       else
8010         break;
8011     }
8012
8013   if (!name_set)
8014     {
8015       errmsg ("policy name required\n");
8016       return -99;
8017     }
8018
8019   if ((!tunnel_set) && (!is_del))
8020     {
8021       errmsg ("tunnel name required\n");
8022       return -99;
8023     }
8024
8025   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8026
8027
8028
8029   mp->is_add = !is_del;
8030
8031   memcpy (mp->name, name, vec_len (name));
8032   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8033   u8 *serial_orig = 0;
8034   vec_validate (serial_orig, tunnel_names_length);
8035   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8036   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8037
8038   for (j = 0; j < vec_len (tunnel_names); j++)
8039     {
8040       tun_name_len = vec_len (tunnel_names[j]);
8041       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8042       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8043       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8044       serial_orig += tun_name_len;      // Advance past the copy
8045     }
8046   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8047
8048   vec_free (tunnel_names);
8049   vec_free (tunnel_name);
8050
8051   S;
8052   W;
8053   /* NOTREACHED */
8054 }
8055
8056 static int
8057 api_sr_multicast_map_add_del (vat_main_t * vam)
8058 {
8059   unformat_input_t *input = vam->input;
8060   vl_api_sr_multicast_map_add_del_t *mp;
8061   f64 timeout;
8062   int is_del = 0;
8063   ip6_address_t multicast_address;
8064   u8 *policy_name = 0;
8065   int multicast_address_set = 0;
8066
8067   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8068     {
8069       if (unformat (input, "del"))
8070         is_del = 1;
8071       else
8072         if (unformat
8073             (input, "address %U", unformat_ip6_address, &multicast_address))
8074         multicast_address_set = 1;
8075       else if (unformat (input, "sr-policy %s", &policy_name))
8076         ;
8077       else
8078         break;
8079     }
8080
8081   if (!is_del && !policy_name)
8082     {
8083       errmsg ("sr-policy name required\n");
8084       return -99;
8085     }
8086
8087
8088   if (!multicast_address_set)
8089     {
8090       errmsg ("address required\n");
8091       return -99;
8092     }
8093
8094   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8095
8096   mp->is_add = !is_del;
8097   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8098   clib_memcpy (mp->multicast_address, &multicast_address,
8099                sizeof (mp->multicast_address));
8100
8101
8102   vec_free (policy_name);
8103
8104   S;
8105   W;
8106   /* NOTREACHED */
8107 }
8108
8109
8110 #define foreach_tcp_proto_field                 \
8111 _(src_port)                                     \
8112 _(dst_port)
8113
8114 #define foreach_udp_proto_field                 \
8115 _(src_port)                                     \
8116 _(dst_port)
8117
8118 #define foreach_ip4_proto_field                 \
8119 _(src_address)                                  \
8120 _(dst_address)                                  \
8121 _(tos)                                          \
8122 _(length)                                       \
8123 _(fragment_id)                                  \
8124 _(ttl)                                          \
8125 _(protocol)                                     \
8126 _(checksum)
8127
8128 uword
8129 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8130 {
8131   u8 **maskp = va_arg (*args, u8 **);
8132   u8 *mask = 0;
8133   u8 found_something = 0;
8134   tcp_header_t *tcp;
8135
8136 #define _(a) u8 a=0;
8137   foreach_tcp_proto_field;
8138 #undef _
8139
8140   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8141     {
8142       if (0);
8143 #define _(a) else if (unformat (input, #a)) a=1;
8144       foreach_tcp_proto_field
8145 #undef _
8146         else
8147         break;
8148     }
8149
8150 #define _(a) found_something += a;
8151   foreach_tcp_proto_field;
8152 #undef _
8153
8154   if (found_something == 0)
8155     return 0;
8156
8157   vec_validate (mask, sizeof (*tcp) - 1);
8158
8159   tcp = (tcp_header_t *) mask;
8160
8161 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8162   foreach_tcp_proto_field;
8163 #undef _
8164
8165   *maskp = mask;
8166   return 1;
8167 }
8168
8169 uword
8170 unformat_udp_mask (unformat_input_t * input, va_list * args)
8171 {
8172   u8 **maskp = va_arg (*args, u8 **);
8173   u8 *mask = 0;
8174   u8 found_something = 0;
8175   udp_header_t *udp;
8176
8177 #define _(a) u8 a=0;
8178   foreach_udp_proto_field;
8179 #undef _
8180
8181   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8182     {
8183       if (0);
8184 #define _(a) else if (unformat (input, #a)) a=1;
8185       foreach_udp_proto_field
8186 #undef _
8187         else
8188         break;
8189     }
8190
8191 #define _(a) found_something += a;
8192   foreach_udp_proto_field;
8193 #undef _
8194
8195   if (found_something == 0)
8196     return 0;
8197
8198   vec_validate (mask, sizeof (*udp) - 1);
8199
8200   udp = (udp_header_t *) mask;
8201
8202 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8203   foreach_udp_proto_field;
8204 #undef _
8205
8206   *maskp = mask;
8207   return 1;
8208 }
8209
8210 typedef struct
8211 {
8212   u16 src_port, dst_port;
8213 } tcpudp_header_t;
8214
8215 uword
8216 unformat_l4_mask (unformat_input_t * input, va_list * args)
8217 {
8218   u8 **maskp = va_arg (*args, u8 **);
8219   u16 src_port = 0, dst_port = 0;
8220   tcpudp_header_t *tcpudp;
8221
8222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8223     {
8224       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8225         return 1;
8226       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8227         return 1;
8228       else if (unformat (input, "src_port"))
8229         src_port = 0xFFFF;
8230       else if (unformat (input, "dst_port"))
8231         dst_port = 0xFFFF;
8232       else
8233         return 0;
8234     }
8235
8236   if (!src_port && !dst_port)
8237     return 0;
8238
8239   u8 *mask = 0;
8240   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8241
8242   tcpudp = (tcpudp_header_t *) mask;
8243   tcpudp->src_port = src_port;
8244   tcpudp->dst_port = dst_port;
8245
8246   *maskp = mask;
8247
8248   return 1;
8249 }
8250
8251 uword
8252 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8253 {
8254   u8 **maskp = va_arg (*args, u8 **);
8255   u8 *mask = 0;
8256   u8 found_something = 0;
8257   ip4_header_t *ip;
8258
8259 #define _(a) u8 a=0;
8260   foreach_ip4_proto_field;
8261 #undef _
8262   u8 version = 0;
8263   u8 hdr_length = 0;
8264
8265
8266   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8267     {
8268       if (unformat (input, "version"))
8269         version = 1;
8270       else if (unformat (input, "hdr_length"))
8271         hdr_length = 1;
8272       else if (unformat (input, "src"))
8273         src_address = 1;
8274       else if (unformat (input, "dst"))
8275         dst_address = 1;
8276       else if (unformat (input, "proto"))
8277         protocol = 1;
8278
8279 #define _(a) else if (unformat (input, #a)) a=1;
8280       foreach_ip4_proto_field
8281 #undef _
8282         else
8283         break;
8284     }
8285
8286 #define _(a) found_something += a;
8287   foreach_ip4_proto_field;
8288 #undef _
8289
8290   if (found_something == 0)
8291     return 0;
8292
8293   vec_validate (mask, sizeof (*ip) - 1);
8294
8295   ip = (ip4_header_t *) mask;
8296
8297 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8298   foreach_ip4_proto_field;
8299 #undef _
8300
8301   ip->ip_version_and_header_length = 0;
8302
8303   if (version)
8304     ip->ip_version_and_header_length |= 0xF0;
8305
8306   if (hdr_length)
8307     ip->ip_version_and_header_length |= 0x0F;
8308
8309   *maskp = mask;
8310   return 1;
8311 }
8312
8313 #define foreach_ip6_proto_field                 \
8314 _(src_address)                                  \
8315 _(dst_address)                                  \
8316 _(payload_length)                               \
8317 _(hop_limit)                                    \
8318 _(protocol)
8319
8320 uword
8321 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8322 {
8323   u8 **maskp = va_arg (*args, u8 **);
8324   u8 *mask = 0;
8325   u8 found_something = 0;
8326   ip6_header_t *ip;
8327   u32 ip_version_traffic_class_and_flow_label;
8328
8329 #define _(a) u8 a=0;
8330   foreach_ip6_proto_field;
8331 #undef _
8332   u8 version = 0;
8333   u8 traffic_class = 0;
8334   u8 flow_label = 0;
8335
8336   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8337     {
8338       if (unformat (input, "version"))
8339         version = 1;
8340       else if (unformat (input, "traffic-class"))
8341         traffic_class = 1;
8342       else if (unformat (input, "flow-label"))
8343         flow_label = 1;
8344       else if (unformat (input, "src"))
8345         src_address = 1;
8346       else if (unformat (input, "dst"))
8347         dst_address = 1;
8348       else if (unformat (input, "proto"))
8349         protocol = 1;
8350
8351 #define _(a) else if (unformat (input, #a)) a=1;
8352       foreach_ip6_proto_field
8353 #undef _
8354         else
8355         break;
8356     }
8357
8358 #define _(a) found_something += a;
8359   foreach_ip6_proto_field;
8360 #undef _
8361
8362   if (found_something == 0)
8363     return 0;
8364
8365   vec_validate (mask, sizeof (*ip) - 1);
8366
8367   ip = (ip6_header_t *) mask;
8368
8369 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8370   foreach_ip6_proto_field;
8371 #undef _
8372
8373   ip_version_traffic_class_and_flow_label = 0;
8374
8375   if (version)
8376     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8377
8378   if (traffic_class)
8379     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8380
8381   if (flow_label)
8382     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8383
8384   ip->ip_version_traffic_class_and_flow_label =
8385     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8386
8387   *maskp = mask;
8388   return 1;
8389 }
8390
8391 uword
8392 unformat_l3_mask (unformat_input_t * input, va_list * args)
8393 {
8394   u8 **maskp = va_arg (*args, u8 **);
8395
8396   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8397     {
8398       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8399         return 1;
8400       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8401         return 1;
8402       else
8403         break;
8404     }
8405   return 0;
8406 }
8407
8408 uword
8409 unformat_l2_mask (unformat_input_t * input, va_list * args)
8410 {
8411   u8 **maskp = va_arg (*args, u8 **);
8412   u8 *mask = 0;
8413   u8 src = 0;
8414   u8 dst = 0;
8415   u8 proto = 0;
8416   u8 tag1 = 0;
8417   u8 tag2 = 0;
8418   u8 ignore_tag1 = 0;
8419   u8 ignore_tag2 = 0;
8420   u8 cos1 = 0;
8421   u8 cos2 = 0;
8422   u8 dot1q = 0;
8423   u8 dot1ad = 0;
8424   int len = 14;
8425
8426   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8427     {
8428       if (unformat (input, "src"))
8429         src = 1;
8430       else if (unformat (input, "dst"))
8431         dst = 1;
8432       else if (unformat (input, "proto"))
8433         proto = 1;
8434       else if (unformat (input, "tag1"))
8435         tag1 = 1;
8436       else if (unformat (input, "tag2"))
8437         tag2 = 1;
8438       else if (unformat (input, "ignore-tag1"))
8439         ignore_tag1 = 1;
8440       else if (unformat (input, "ignore-tag2"))
8441         ignore_tag2 = 1;
8442       else if (unformat (input, "cos1"))
8443         cos1 = 1;
8444       else if (unformat (input, "cos2"))
8445         cos2 = 1;
8446       else if (unformat (input, "dot1q"))
8447         dot1q = 1;
8448       else if (unformat (input, "dot1ad"))
8449         dot1ad = 1;
8450       else
8451         break;
8452     }
8453   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8454        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8455     return 0;
8456
8457   if (tag1 || ignore_tag1 || cos1 || dot1q)
8458     len = 18;
8459   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8460     len = 22;
8461
8462   vec_validate (mask, len - 1);
8463
8464   if (dst)
8465     memset (mask, 0xff, 6);
8466
8467   if (src)
8468     memset (mask + 6, 0xff, 6);
8469
8470   if (tag2 || dot1ad)
8471     {
8472       /* inner vlan tag */
8473       if (tag2)
8474         {
8475           mask[19] = 0xff;
8476           mask[18] = 0x0f;
8477         }
8478       if (cos2)
8479         mask[18] |= 0xe0;
8480       if (proto)
8481         mask[21] = mask[20] = 0xff;
8482       if (tag1)
8483         {
8484           mask[15] = 0xff;
8485           mask[14] = 0x0f;
8486         }
8487       if (cos1)
8488         mask[14] |= 0xe0;
8489       *maskp = mask;
8490       return 1;
8491     }
8492   if (tag1 | dot1q)
8493     {
8494       if (tag1)
8495         {
8496           mask[15] = 0xff;
8497           mask[14] = 0x0f;
8498         }
8499       if (cos1)
8500         mask[14] |= 0xe0;
8501       if (proto)
8502         mask[16] = mask[17] = 0xff;
8503
8504       *maskp = mask;
8505       return 1;
8506     }
8507   if (cos2)
8508     mask[18] |= 0xe0;
8509   if (cos1)
8510     mask[14] |= 0xe0;
8511   if (proto)
8512     mask[12] = mask[13] = 0xff;
8513
8514   *maskp = mask;
8515   return 1;
8516 }
8517
8518 uword
8519 unformat_classify_mask (unformat_input_t * input, va_list * args)
8520 {
8521   u8 **maskp = va_arg (*args, u8 **);
8522   u32 *skipp = va_arg (*args, u32 *);
8523   u32 *matchp = va_arg (*args, u32 *);
8524   u32 match;
8525   u8 *mask = 0;
8526   u8 *l2 = 0;
8527   u8 *l3 = 0;
8528   u8 *l4 = 0;
8529   int i;
8530
8531   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8532     {
8533       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8534         ;
8535       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8536         ;
8537       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8538         ;
8539       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8540         ;
8541       else
8542         break;
8543     }
8544
8545   if (l4 && !l3)
8546     {
8547       vec_free (mask);
8548       vec_free (l2);
8549       vec_free (l4);
8550       return 0;
8551     }
8552
8553   if (mask || l2 || l3 || l4)
8554     {
8555       if (l2 || l3 || l4)
8556         {
8557           /* "With a free Ethernet header in every package" */
8558           if (l2 == 0)
8559             vec_validate (l2, 13);
8560           mask = l2;
8561           if (vec_len (l3))
8562             {
8563               vec_append (mask, l3);
8564               vec_free (l3);
8565             }
8566           if (vec_len (l4))
8567             {
8568               vec_append (mask, l4);
8569               vec_free (l4);
8570             }
8571         }
8572
8573       /* Scan forward looking for the first significant mask octet */
8574       for (i = 0; i < vec_len (mask); i++)
8575         if (mask[i])
8576           break;
8577
8578       /* compute (skip, match) params */
8579       *skipp = i / sizeof (u32x4);
8580       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8581
8582       /* Pad mask to an even multiple of the vector size */
8583       while (vec_len (mask) % sizeof (u32x4))
8584         vec_add1 (mask, 0);
8585
8586       match = vec_len (mask) / sizeof (u32x4);
8587
8588       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8589         {
8590           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8591           if (*tmp || *(tmp + 1))
8592             break;
8593           match--;
8594         }
8595       if (match == 0)
8596         clib_warning ("BUG: match 0");
8597
8598       _vec_len (mask) = match * sizeof (u32x4);
8599
8600       *matchp = match;
8601       *maskp = mask;
8602
8603       return 1;
8604     }
8605
8606   return 0;
8607 }
8608
8609 #define foreach_l2_next                         \
8610 _(drop, DROP)                                   \
8611 _(ethernet, ETHERNET_INPUT)                     \
8612 _(ip4, IP4_INPUT)                               \
8613 _(ip6, IP6_INPUT)
8614
8615 uword
8616 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8617 {
8618   u32 *miss_next_indexp = va_arg (*args, u32 *);
8619   u32 next_index = 0;
8620   u32 tmp;
8621
8622 #define _(n,N) \
8623   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8624   foreach_l2_next;
8625 #undef _
8626
8627   if (unformat (input, "%d", &tmp))
8628     {
8629       next_index = tmp;
8630       goto out;
8631     }
8632
8633   return 0;
8634
8635 out:
8636   *miss_next_indexp = next_index;
8637   return 1;
8638 }
8639
8640 #define foreach_ip_next                         \
8641 _(drop, DROP)                                   \
8642 _(local, LOCAL)                                 \
8643 _(rewrite, REWRITE)
8644
8645 uword
8646 unformat_ip_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 = IP_LOOKUP_NEXT_##N; goto out;}
8654   foreach_ip_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_acl_next                        \
8671 _(deny, DENY)
8672
8673 uword
8674 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8675 {
8676   u32 *miss_next_indexp = va_arg (*args, u32 *);
8677   u32 next_index = 0;
8678   u32 tmp;
8679
8680 #define _(n,N) \
8681   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8682   foreach_acl_next;
8683 #undef _
8684
8685   if (unformat (input, "permit"))
8686     {
8687       next_index = ~0;
8688       goto out;
8689     }
8690   else if (unformat (input, "%d", &tmp))
8691     {
8692       next_index = tmp;
8693       goto out;
8694     }
8695
8696   return 0;
8697
8698 out:
8699   *miss_next_indexp = next_index;
8700   return 1;
8701 }
8702
8703 uword
8704 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8705 {
8706   u32 *r = va_arg (*args, u32 *);
8707
8708   if (unformat (input, "conform-color"))
8709     *r = POLICE_CONFORM;
8710   else if (unformat (input, "exceed-color"))
8711     *r = POLICE_EXCEED;
8712   else
8713     return 0;
8714
8715   return 1;
8716 }
8717
8718 static int
8719 api_classify_add_del_table (vat_main_t * vam)
8720 {
8721   unformat_input_t *i = vam->input;
8722   vl_api_classify_add_del_table_t *mp;
8723
8724   u32 nbuckets = 2;
8725   u32 skip = ~0;
8726   u32 match = ~0;
8727   int is_add = 1;
8728   u32 table_index = ~0;
8729   u32 next_table_index = ~0;
8730   u32 miss_next_index = ~0;
8731   u32 memory_size = 32 << 20;
8732   u8 *mask = 0;
8733   f64 timeout;
8734   u32 current_data_flag = 0;
8735   int current_data_offset = 0;
8736
8737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8738     {
8739       if (unformat (i, "del"))
8740         is_add = 0;
8741       else if (unformat (i, "buckets %d", &nbuckets))
8742         ;
8743       else if (unformat (i, "memory_size %d", &memory_size))
8744         ;
8745       else if (unformat (i, "skip %d", &skip))
8746         ;
8747       else if (unformat (i, "match %d", &match))
8748         ;
8749       else if (unformat (i, "table %d", &table_index))
8750         ;
8751       else if (unformat (i, "mask %U", unformat_classify_mask,
8752                          &mask, &skip, &match))
8753         ;
8754       else if (unformat (i, "next-table %d", &next_table_index))
8755         ;
8756       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8757                          &miss_next_index))
8758         ;
8759       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8760                          &miss_next_index))
8761         ;
8762       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8763                          &miss_next_index))
8764         ;
8765       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8766         ;
8767       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8768         ;
8769       else
8770         break;
8771     }
8772
8773   if (is_add && mask == 0)
8774     {
8775       errmsg ("Mask required\n");
8776       return -99;
8777     }
8778
8779   if (is_add && skip == ~0)
8780     {
8781       errmsg ("skip count required\n");
8782       return -99;
8783     }
8784
8785   if (is_add && match == ~0)
8786     {
8787       errmsg ("match count required\n");
8788       return -99;
8789     }
8790
8791   if (!is_add && table_index == ~0)
8792     {
8793       errmsg ("table index required for delete\n");
8794       return -99;
8795     }
8796
8797   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8798
8799   mp->is_add = is_add;
8800   mp->table_index = ntohl (table_index);
8801   mp->nbuckets = ntohl (nbuckets);
8802   mp->memory_size = ntohl (memory_size);
8803   mp->skip_n_vectors = ntohl (skip);
8804   mp->match_n_vectors = ntohl (match);
8805   mp->next_table_index = ntohl (next_table_index);
8806   mp->miss_next_index = ntohl (miss_next_index);
8807   mp->current_data_flag = ntohl (current_data_flag);
8808   mp->current_data_offset = ntohl (current_data_offset);
8809   clib_memcpy (mp->mask, mask, vec_len (mask));
8810
8811   vec_free (mask);
8812
8813   S;
8814   W;
8815   /* NOTREACHED */
8816 }
8817
8818 uword
8819 unformat_l4_match (unformat_input_t * input, va_list * args)
8820 {
8821   u8 **matchp = va_arg (*args, u8 **);
8822
8823   u8 *proto_header = 0;
8824   int src_port = 0;
8825   int dst_port = 0;
8826
8827   tcpudp_header_t h;
8828
8829   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8830     {
8831       if (unformat (input, "src_port %d", &src_port))
8832         ;
8833       else if (unformat (input, "dst_port %d", &dst_port))
8834         ;
8835       else
8836         return 0;
8837     }
8838
8839   h.src_port = clib_host_to_net_u16 (src_port);
8840   h.dst_port = clib_host_to_net_u16 (dst_port);
8841   vec_validate (proto_header, sizeof (h) - 1);
8842   memcpy (proto_header, &h, sizeof (h));
8843
8844   *matchp = proto_header;
8845
8846   return 1;
8847 }
8848
8849 uword
8850 unformat_ip4_match (unformat_input_t * input, va_list * args)
8851 {
8852   u8 **matchp = va_arg (*args, u8 **);
8853   u8 *match = 0;
8854   ip4_header_t *ip;
8855   int version = 0;
8856   u32 version_val;
8857   int hdr_length = 0;
8858   u32 hdr_length_val;
8859   int src = 0, dst = 0;
8860   ip4_address_t src_val, dst_val;
8861   int proto = 0;
8862   u32 proto_val;
8863   int tos = 0;
8864   u32 tos_val;
8865   int length = 0;
8866   u32 length_val;
8867   int fragment_id = 0;
8868   u32 fragment_id_val;
8869   int ttl = 0;
8870   int ttl_val;
8871   int checksum = 0;
8872   u32 checksum_val;
8873
8874   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8875     {
8876       if (unformat (input, "version %d", &version_val))
8877         version = 1;
8878       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8879         hdr_length = 1;
8880       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8881         src = 1;
8882       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8883         dst = 1;
8884       else if (unformat (input, "proto %d", &proto_val))
8885         proto = 1;
8886       else if (unformat (input, "tos %d", &tos_val))
8887         tos = 1;
8888       else if (unformat (input, "length %d", &length_val))
8889         length = 1;
8890       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8891         fragment_id = 1;
8892       else if (unformat (input, "ttl %d", &ttl_val))
8893         ttl = 1;
8894       else if (unformat (input, "checksum %d", &checksum_val))
8895         checksum = 1;
8896       else
8897         break;
8898     }
8899
8900   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8901       + ttl + checksum == 0)
8902     return 0;
8903
8904   /*
8905    * Aligned because we use the real comparison functions
8906    */
8907   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8908
8909   ip = (ip4_header_t *) match;
8910
8911   /* These are realistically matched in practice */
8912   if (src)
8913     ip->src_address.as_u32 = src_val.as_u32;
8914
8915   if (dst)
8916     ip->dst_address.as_u32 = dst_val.as_u32;
8917
8918   if (proto)
8919     ip->protocol = proto_val;
8920
8921
8922   /* These are not, but they're included for completeness */
8923   if (version)
8924     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8925
8926   if (hdr_length)
8927     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8928
8929   if (tos)
8930     ip->tos = tos_val;
8931
8932   if (length)
8933     ip->length = clib_host_to_net_u16 (length_val);
8934
8935   if (ttl)
8936     ip->ttl = ttl_val;
8937
8938   if (checksum)
8939     ip->checksum = clib_host_to_net_u16 (checksum_val);
8940
8941   *matchp = match;
8942   return 1;
8943 }
8944
8945 uword
8946 unformat_ip6_match (unformat_input_t * input, va_list * args)
8947 {
8948   u8 **matchp = va_arg (*args, u8 **);
8949   u8 *match = 0;
8950   ip6_header_t *ip;
8951   int version = 0;
8952   u32 version_val;
8953   u8 traffic_class = 0;
8954   u32 traffic_class_val = 0;
8955   u8 flow_label = 0;
8956   u8 flow_label_val;
8957   int src = 0, dst = 0;
8958   ip6_address_t src_val, dst_val;
8959   int proto = 0;
8960   u32 proto_val;
8961   int payload_length = 0;
8962   u32 payload_length_val;
8963   int hop_limit = 0;
8964   int hop_limit_val;
8965   u32 ip_version_traffic_class_and_flow_label;
8966
8967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8968     {
8969       if (unformat (input, "version %d", &version_val))
8970         version = 1;
8971       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8972         traffic_class = 1;
8973       else if (unformat (input, "flow_label %d", &flow_label_val))
8974         flow_label = 1;
8975       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8976         src = 1;
8977       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8978         dst = 1;
8979       else if (unformat (input, "proto %d", &proto_val))
8980         proto = 1;
8981       else if (unformat (input, "payload_length %d", &payload_length_val))
8982         payload_length = 1;
8983       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8984         hop_limit = 1;
8985       else
8986         break;
8987     }
8988
8989   if (version + traffic_class + flow_label + src + dst + proto +
8990       payload_length + hop_limit == 0)
8991     return 0;
8992
8993   /*
8994    * Aligned because we use the real comparison functions
8995    */
8996   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8997
8998   ip = (ip6_header_t *) match;
8999
9000   if (src)
9001     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9002
9003   if (dst)
9004     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9005
9006   if (proto)
9007     ip->protocol = proto_val;
9008
9009   ip_version_traffic_class_and_flow_label = 0;
9010
9011   if (version)
9012     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9013
9014   if (traffic_class)
9015     ip_version_traffic_class_and_flow_label |=
9016       (traffic_class_val & 0xFF) << 20;
9017
9018   if (flow_label)
9019     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9020
9021   ip->ip_version_traffic_class_and_flow_label =
9022     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9023
9024   if (payload_length)
9025     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9026
9027   if (hop_limit)
9028     ip->hop_limit = hop_limit_val;
9029
9030   *matchp = match;
9031   return 1;
9032 }
9033
9034 uword
9035 unformat_l3_match (unformat_input_t * input, va_list * args)
9036 {
9037   u8 **matchp = va_arg (*args, u8 **);
9038
9039   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9040     {
9041       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9042         return 1;
9043       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9044         return 1;
9045       else
9046         break;
9047     }
9048   return 0;
9049 }
9050
9051 uword
9052 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9053 {
9054   u8 *tagp = va_arg (*args, u8 *);
9055   u32 tag;
9056
9057   if (unformat (input, "%d", &tag))
9058     {
9059       tagp[0] = (tag >> 8) & 0x0F;
9060       tagp[1] = tag & 0xFF;
9061       return 1;
9062     }
9063
9064   return 0;
9065 }
9066
9067 uword
9068 unformat_l2_match (unformat_input_t * input, va_list * args)
9069 {
9070   u8 **matchp = va_arg (*args, u8 **);
9071   u8 *match = 0;
9072   u8 src = 0;
9073   u8 src_val[6];
9074   u8 dst = 0;
9075   u8 dst_val[6];
9076   u8 proto = 0;
9077   u16 proto_val;
9078   u8 tag1 = 0;
9079   u8 tag1_val[2];
9080   u8 tag2 = 0;
9081   u8 tag2_val[2];
9082   int len = 14;
9083   u8 ignore_tag1 = 0;
9084   u8 ignore_tag2 = 0;
9085   u8 cos1 = 0;
9086   u8 cos2 = 0;
9087   u32 cos1_val = 0;
9088   u32 cos2_val = 0;
9089
9090   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9091     {
9092       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9093         src = 1;
9094       else
9095         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9096         dst = 1;
9097       else if (unformat (input, "proto %U",
9098                          unformat_ethernet_type_host_byte_order, &proto_val))
9099         proto = 1;
9100       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9101         tag1 = 1;
9102       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9103         tag2 = 1;
9104       else if (unformat (input, "ignore-tag1"))
9105         ignore_tag1 = 1;
9106       else if (unformat (input, "ignore-tag2"))
9107         ignore_tag2 = 1;
9108       else if (unformat (input, "cos1 %d", &cos1_val))
9109         cos1 = 1;
9110       else if (unformat (input, "cos2 %d", &cos2_val))
9111         cos2 = 1;
9112       else
9113         break;
9114     }
9115   if ((src + dst + proto + tag1 + tag2 +
9116        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9117     return 0;
9118
9119   if (tag1 || ignore_tag1 || cos1)
9120     len = 18;
9121   if (tag2 || ignore_tag2 || cos2)
9122     len = 22;
9123
9124   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9125
9126   if (dst)
9127     clib_memcpy (match, dst_val, 6);
9128
9129   if (src)
9130     clib_memcpy (match + 6, src_val, 6);
9131
9132   if (tag2)
9133     {
9134       /* inner vlan tag */
9135       match[19] = tag2_val[1];
9136       match[18] = tag2_val[0];
9137       if (cos2)
9138         match[18] |= (cos2_val & 0x7) << 5;
9139       if (proto)
9140         {
9141           match[21] = proto_val & 0xff;
9142           match[20] = proto_val >> 8;
9143         }
9144       if (tag1)
9145         {
9146           match[15] = tag1_val[1];
9147           match[14] = tag1_val[0];
9148         }
9149       if (cos1)
9150         match[14] |= (cos1_val & 0x7) << 5;
9151       *matchp = match;
9152       return 1;
9153     }
9154   if (tag1)
9155     {
9156       match[15] = tag1_val[1];
9157       match[14] = tag1_val[0];
9158       if (proto)
9159         {
9160           match[17] = proto_val & 0xff;
9161           match[16] = proto_val >> 8;
9162         }
9163       if (cos1)
9164         match[14] |= (cos1_val & 0x7) << 5;
9165
9166       *matchp = match;
9167       return 1;
9168     }
9169   if (cos2)
9170     match[18] |= (cos2_val & 0x7) << 5;
9171   if (cos1)
9172     match[14] |= (cos1_val & 0x7) << 5;
9173   if (proto)
9174     {
9175       match[13] = proto_val & 0xff;
9176       match[12] = proto_val >> 8;
9177     }
9178
9179   *matchp = match;
9180   return 1;
9181 }
9182
9183
9184 uword
9185 unformat_classify_match (unformat_input_t * input, va_list * args)
9186 {
9187   u8 **matchp = va_arg (*args, u8 **);
9188   u32 skip_n_vectors = va_arg (*args, u32);
9189   u32 match_n_vectors = va_arg (*args, u32);
9190
9191   u8 *match = 0;
9192   u8 *l2 = 0;
9193   u8 *l3 = 0;
9194   u8 *l4 = 0;
9195
9196   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9197     {
9198       if (unformat (input, "hex %U", unformat_hex_string, &match))
9199         ;
9200       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9201         ;
9202       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9203         ;
9204       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9205         ;
9206       else
9207         break;
9208     }
9209
9210   if (l4 && !l3)
9211     {
9212       vec_free (match);
9213       vec_free (l2);
9214       vec_free (l4);
9215       return 0;
9216     }
9217
9218   if (match || l2 || l3 || l4)
9219     {
9220       if (l2 || l3 || l4)
9221         {
9222           /* "Win a free Ethernet header in every packet" */
9223           if (l2 == 0)
9224             vec_validate_aligned (l2, 13, sizeof (u32x4));
9225           match = l2;
9226           if (vec_len (l3))
9227             {
9228               vec_append_aligned (match, l3, sizeof (u32x4));
9229               vec_free (l3);
9230             }
9231           if (vec_len (l4))
9232             {
9233               vec_append_aligned (match, l4, sizeof (u32x4));
9234               vec_free (l4);
9235             }
9236         }
9237
9238       /* Make sure the vector is big enough even if key is all 0's */
9239       vec_validate_aligned
9240         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9241          sizeof (u32x4));
9242
9243       /* Set size, include skipped vectors */
9244       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9245
9246       *matchp = match;
9247
9248       return 1;
9249     }
9250
9251   return 0;
9252 }
9253
9254 static int
9255 api_classify_add_del_session (vat_main_t * vam)
9256 {
9257   unformat_input_t *i = vam->input;
9258   vl_api_classify_add_del_session_t *mp;
9259   int is_add = 1;
9260   u32 table_index = ~0;
9261   u32 hit_next_index = ~0;
9262   u32 opaque_index = ~0;
9263   u8 *match = 0;
9264   i32 advance = 0;
9265   f64 timeout;
9266   u32 skip_n_vectors = 0;
9267   u32 match_n_vectors = 0;
9268   u32 action = 0;
9269   u32 metadata = 0;
9270
9271   /*
9272    * Warning: you have to supply skip_n and match_n
9273    * because the API client cant simply look at the classify
9274    * table object.
9275    */
9276
9277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9278     {
9279       if (unformat (i, "del"))
9280         is_add = 0;
9281       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9282                          &hit_next_index))
9283         ;
9284       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9285                          &hit_next_index))
9286         ;
9287       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9288                          &hit_next_index))
9289         ;
9290       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9291         ;
9292       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9293         ;
9294       else if (unformat (i, "opaque-index %d", &opaque_index))
9295         ;
9296       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9297         ;
9298       else if (unformat (i, "match_n %d", &match_n_vectors))
9299         ;
9300       else if (unformat (i, "match %U", unformat_classify_match,
9301                          &match, skip_n_vectors, match_n_vectors))
9302         ;
9303       else if (unformat (i, "advance %d", &advance))
9304         ;
9305       else if (unformat (i, "table-index %d", &table_index))
9306         ;
9307       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9308         action = 1;
9309       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9310         action = 2;
9311       else if (unformat (i, "action %d", &action))
9312         ;
9313       else if (unformat (i, "metadata %d", &metadata))
9314         ;
9315       else
9316         break;
9317     }
9318
9319   if (table_index == ~0)
9320     {
9321       errmsg ("Table index required\n");
9322       return -99;
9323     }
9324
9325   if (is_add && match == 0)
9326     {
9327       errmsg ("Match value required\n");
9328       return -99;
9329     }
9330
9331   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9332
9333   mp->is_add = is_add;
9334   mp->table_index = ntohl (table_index);
9335   mp->hit_next_index = ntohl (hit_next_index);
9336   mp->opaque_index = ntohl (opaque_index);
9337   mp->advance = ntohl (advance);
9338   mp->action = action;
9339   mp->metadata = ntohl (metadata);
9340   clib_memcpy (mp->match, match, vec_len (match));
9341   vec_free (match);
9342
9343   S;
9344   W;
9345   /* NOTREACHED */
9346 }
9347
9348 static int
9349 api_classify_set_interface_ip_table (vat_main_t * vam)
9350 {
9351   unformat_input_t *i = vam->input;
9352   vl_api_classify_set_interface_ip_table_t *mp;
9353   f64 timeout;
9354   u32 sw_if_index;
9355   int sw_if_index_set;
9356   u32 table_index = ~0;
9357   u8 is_ipv6 = 0;
9358
9359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9360     {
9361       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9362         sw_if_index_set = 1;
9363       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9364         sw_if_index_set = 1;
9365       else if (unformat (i, "table %d", &table_index))
9366         ;
9367       else
9368         {
9369           clib_warning ("parse error '%U'", format_unformat_error, i);
9370           return -99;
9371         }
9372     }
9373
9374   if (sw_if_index_set == 0)
9375     {
9376       errmsg ("missing interface name or sw_if_index\n");
9377       return -99;
9378     }
9379
9380
9381   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9382
9383   mp->sw_if_index = ntohl (sw_if_index);
9384   mp->table_index = ntohl (table_index);
9385   mp->is_ipv6 = is_ipv6;
9386
9387   S;
9388   W;
9389   /* NOTREACHED */
9390   return 0;
9391 }
9392
9393 static int
9394 api_classify_set_interface_l2_tables (vat_main_t * vam)
9395 {
9396   unformat_input_t *i = vam->input;
9397   vl_api_classify_set_interface_l2_tables_t *mp;
9398   f64 timeout;
9399   u32 sw_if_index;
9400   int sw_if_index_set;
9401   u32 ip4_table_index = ~0;
9402   u32 ip6_table_index = ~0;
9403   u32 other_table_index = ~0;
9404   u32 is_input = 1;
9405
9406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9407     {
9408       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9409         sw_if_index_set = 1;
9410       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9411         sw_if_index_set = 1;
9412       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9413         ;
9414       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9415         ;
9416       else if (unformat (i, "other-table %d", &other_table_index))
9417         ;
9418       else if (unformat (i, "is-input %d", &is_input))
9419         ;
9420       else
9421         {
9422           clib_warning ("parse error '%U'", format_unformat_error, i);
9423           return -99;
9424         }
9425     }
9426
9427   if (sw_if_index_set == 0)
9428     {
9429       errmsg ("missing interface name or sw_if_index\n");
9430       return -99;
9431     }
9432
9433
9434   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9435
9436   mp->sw_if_index = ntohl (sw_if_index);
9437   mp->ip4_table_index = ntohl (ip4_table_index);
9438   mp->ip6_table_index = ntohl (ip6_table_index);
9439   mp->other_table_index = ntohl (other_table_index);
9440   mp->is_input = (u8) is_input;
9441
9442   S;
9443   W;
9444   /* NOTREACHED */
9445   return 0;
9446 }
9447
9448 static int
9449 api_set_ipfix_exporter (vat_main_t * vam)
9450 {
9451   unformat_input_t *i = vam->input;
9452   vl_api_set_ipfix_exporter_t *mp;
9453   ip4_address_t collector_address;
9454   u8 collector_address_set = 0;
9455   u32 collector_port = ~0;
9456   ip4_address_t src_address;
9457   u8 src_address_set = 0;
9458   u32 vrf_id = ~0;
9459   u32 path_mtu = ~0;
9460   u32 template_interval = ~0;
9461   u8 udp_checksum = 0;
9462   f64 timeout;
9463
9464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9465     {
9466       if (unformat (i, "collector_address %U", unformat_ip4_address,
9467                     &collector_address))
9468         collector_address_set = 1;
9469       else if (unformat (i, "collector_port %d", &collector_port))
9470         ;
9471       else if (unformat (i, "src_address %U", unformat_ip4_address,
9472                          &src_address))
9473         src_address_set = 1;
9474       else if (unformat (i, "vrf_id %d", &vrf_id))
9475         ;
9476       else if (unformat (i, "path_mtu %d", &path_mtu))
9477         ;
9478       else if (unformat (i, "template_interval %d", &template_interval))
9479         ;
9480       else if (unformat (i, "udp_checksum"))
9481         udp_checksum = 1;
9482       else
9483         break;
9484     }
9485
9486   if (collector_address_set == 0)
9487     {
9488       errmsg ("collector_address required\n");
9489       return -99;
9490     }
9491
9492   if (src_address_set == 0)
9493     {
9494       errmsg ("src_address required\n");
9495       return -99;
9496     }
9497
9498   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9499
9500   memcpy (mp->collector_address, collector_address.data,
9501           sizeof (collector_address.data));
9502   mp->collector_port = htons ((u16) collector_port);
9503   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9504   mp->vrf_id = htonl (vrf_id);
9505   mp->path_mtu = htonl (path_mtu);
9506   mp->template_interval = htonl (template_interval);
9507   mp->udp_checksum = udp_checksum;
9508
9509   S;
9510   W;
9511   /* NOTREACHED */
9512 }
9513
9514 static int
9515 api_set_ipfix_classify_stream (vat_main_t * vam)
9516 {
9517   unformat_input_t *i = vam->input;
9518   vl_api_set_ipfix_classify_stream_t *mp;
9519   u32 domain_id = 0;
9520   u32 src_port = UDP_DST_PORT_ipfix;
9521   f64 timeout;
9522
9523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9524     {
9525       if (unformat (i, "domain %d", &domain_id))
9526         ;
9527       else if (unformat (i, "src_port %d", &src_port))
9528         ;
9529       else
9530         {
9531           errmsg ("unknown input `%U'", format_unformat_error, i);
9532           return -99;
9533         }
9534     }
9535
9536   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9537
9538   mp->domain_id = htonl (domain_id);
9539   mp->src_port = htons ((u16) src_port);
9540
9541   S;
9542   W;
9543   /* NOTREACHED */
9544 }
9545
9546 static int
9547 api_ipfix_classify_table_add_del (vat_main_t * vam)
9548 {
9549   unformat_input_t *i = vam->input;
9550   vl_api_ipfix_classify_table_add_del_t *mp;
9551   int is_add = -1;
9552   u32 classify_table_index = ~0;
9553   u8 ip_version = 0;
9554   u8 transport_protocol = 255;
9555   f64 timeout;
9556
9557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9558     {
9559       if (unformat (i, "add"))
9560         is_add = 1;
9561       else if (unformat (i, "del"))
9562         is_add = 0;
9563       else if (unformat (i, "table %d", &classify_table_index))
9564         ;
9565       else if (unformat (i, "ip4"))
9566         ip_version = 4;
9567       else if (unformat (i, "ip6"))
9568         ip_version = 6;
9569       else if (unformat (i, "tcp"))
9570         transport_protocol = 6;
9571       else if (unformat (i, "udp"))
9572         transport_protocol = 17;
9573       else
9574         {
9575           errmsg ("unknown input `%U'", format_unformat_error, i);
9576           return -99;
9577         }
9578     }
9579
9580   if (is_add == -1)
9581     {
9582       errmsg ("expecting: add|del");
9583       return -99;
9584     }
9585   if (classify_table_index == ~0)
9586     {
9587       errmsg ("classifier table not specified");
9588       return -99;
9589     }
9590   if (ip_version == 0)
9591     {
9592       errmsg ("IP version not specified");
9593       return -99;
9594     }
9595
9596   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9597
9598   mp->is_add = is_add;
9599   mp->table_id = htonl (classify_table_index);
9600   mp->ip_version = ip_version;
9601   mp->transport_protocol = transport_protocol;
9602
9603   S;
9604   W;
9605   /* NOTREACHED */
9606 }
9607
9608 static int
9609 api_get_node_index (vat_main_t * vam)
9610 {
9611   unformat_input_t *i = vam->input;
9612   vl_api_get_node_index_t *mp;
9613   f64 timeout;
9614   u8 *name = 0;
9615
9616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9617     {
9618       if (unformat (i, "node %s", &name))
9619         ;
9620       else
9621         break;
9622     }
9623   if (name == 0)
9624     {
9625       errmsg ("node name required\n");
9626       return -99;
9627     }
9628   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9629     {
9630       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9631       return -99;
9632     }
9633
9634   M (GET_NODE_INDEX, get_node_index);
9635   clib_memcpy (mp->node_name, name, vec_len (name));
9636   vec_free (name);
9637
9638   S;
9639   W;
9640   /* NOTREACHED */
9641   return 0;
9642 }
9643
9644 static int
9645 api_get_next_index (vat_main_t * vam)
9646 {
9647   unformat_input_t *i = vam->input;
9648   vl_api_get_next_index_t *mp;
9649   f64 timeout;
9650   u8 *node_name = 0, *next_node_name = 0;
9651
9652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9653     {
9654       if (unformat (i, "node-name %s", &node_name))
9655         ;
9656       else if (unformat (i, "next-node-name %s", &next_node_name))
9657         break;
9658     }
9659
9660   if (node_name == 0)
9661     {
9662       errmsg ("node name required\n");
9663       return -99;
9664     }
9665   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9666     {
9667       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9668       return -99;
9669     }
9670
9671   if (next_node_name == 0)
9672     {
9673       errmsg ("next node name required\n");
9674       return -99;
9675     }
9676   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9677     {
9678       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9679       return -99;
9680     }
9681
9682   M (GET_NEXT_INDEX, get_next_index);
9683   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9684   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9685   vec_free (node_name);
9686   vec_free (next_node_name);
9687
9688   S;
9689   W;
9690   /* NOTREACHED */
9691   return 0;
9692 }
9693
9694 static int
9695 api_add_node_next (vat_main_t * vam)
9696 {
9697   unformat_input_t *i = vam->input;
9698   vl_api_add_node_next_t *mp;
9699   f64 timeout;
9700   u8 *name = 0;
9701   u8 *next = 0;
9702
9703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9704     {
9705       if (unformat (i, "node %s", &name))
9706         ;
9707       else if (unformat (i, "next %s", &next))
9708         ;
9709       else
9710         break;
9711     }
9712   if (name == 0)
9713     {
9714       errmsg ("node name required\n");
9715       return -99;
9716     }
9717   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9718     {
9719       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9720       return -99;
9721     }
9722   if (next == 0)
9723     {
9724       errmsg ("next node required\n");
9725       return -99;
9726     }
9727   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9728     {
9729       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9730       return -99;
9731     }
9732
9733   M (ADD_NODE_NEXT, add_node_next);
9734   clib_memcpy (mp->node_name, name, vec_len (name));
9735   clib_memcpy (mp->next_name, next, vec_len (next));
9736   vec_free (name);
9737   vec_free (next);
9738
9739   S;
9740   W;
9741   /* NOTREACHED */
9742   return 0;
9743 }
9744
9745 static int
9746 api_l2tpv3_create_tunnel (vat_main_t * vam)
9747 {
9748   unformat_input_t *i = vam->input;
9749   ip6_address_t client_address, our_address;
9750   int client_address_set = 0;
9751   int our_address_set = 0;
9752   u32 local_session_id = 0;
9753   u32 remote_session_id = 0;
9754   u64 local_cookie = 0;
9755   u64 remote_cookie = 0;
9756   u8 l2_sublayer_present = 0;
9757   vl_api_l2tpv3_create_tunnel_t *mp;
9758   f64 timeout;
9759
9760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9761     {
9762       if (unformat (i, "client_address %U", unformat_ip6_address,
9763                     &client_address))
9764         client_address_set = 1;
9765       else if (unformat (i, "our_address %U", unformat_ip6_address,
9766                          &our_address))
9767         our_address_set = 1;
9768       else if (unformat (i, "local_session_id %d", &local_session_id))
9769         ;
9770       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9771         ;
9772       else if (unformat (i, "local_cookie %lld", &local_cookie))
9773         ;
9774       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9775         ;
9776       else if (unformat (i, "l2-sublayer-present"))
9777         l2_sublayer_present = 1;
9778       else
9779         break;
9780     }
9781
9782   if (client_address_set == 0)
9783     {
9784       errmsg ("client_address required\n");
9785       return -99;
9786     }
9787
9788   if (our_address_set == 0)
9789     {
9790       errmsg ("our_address required\n");
9791       return -99;
9792     }
9793
9794   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9795
9796   clib_memcpy (mp->client_address, client_address.as_u8,
9797                sizeof (mp->client_address));
9798
9799   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9800
9801   mp->local_session_id = ntohl (local_session_id);
9802   mp->remote_session_id = ntohl (remote_session_id);
9803   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9804   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9805   mp->l2_sublayer_present = l2_sublayer_present;
9806   mp->is_ipv6 = 1;
9807
9808   S;
9809   W;
9810   /* NOTREACHED */
9811   return 0;
9812 }
9813
9814 static int
9815 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9816 {
9817   unformat_input_t *i = vam->input;
9818   u32 sw_if_index;
9819   u8 sw_if_index_set = 0;
9820   u64 new_local_cookie = 0;
9821   u64 new_remote_cookie = 0;
9822   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9823   f64 timeout;
9824
9825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9826     {
9827       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9828         sw_if_index_set = 1;
9829       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9830         sw_if_index_set = 1;
9831       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9832         ;
9833       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9834         ;
9835       else
9836         break;
9837     }
9838
9839   if (sw_if_index_set == 0)
9840     {
9841       errmsg ("missing interface name or sw_if_index\n");
9842       return -99;
9843     }
9844
9845   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9846
9847   mp->sw_if_index = ntohl (sw_if_index);
9848   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9849   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9850
9851   S;
9852   W;
9853   /* NOTREACHED */
9854   return 0;
9855 }
9856
9857 static int
9858 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9859 {
9860   unformat_input_t *i = vam->input;
9861   vl_api_l2tpv3_interface_enable_disable_t *mp;
9862   f64 timeout;
9863   u32 sw_if_index;
9864   u8 sw_if_index_set = 0;
9865   u8 enable_disable = 1;
9866
9867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9868     {
9869       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9870         sw_if_index_set = 1;
9871       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9872         sw_if_index_set = 1;
9873       else if (unformat (i, "enable"))
9874         enable_disable = 1;
9875       else if (unformat (i, "disable"))
9876         enable_disable = 0;
9877       else
9878         break;
9879     }
9880
9881   if (sw_if_index_set == 0)
9882     {
9883       errmsg ("missing interface name or sw_if_index\n");
9884       return -99;
9885     }
9886
9887   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9888
9889   mp->sw_if_index = ntohl (sw_if_index);
9890   mp->enable_disable = enable_disable;
9891
9892   S;
9893   W;
9894   /* NOTREACHED */
9895   return 0;
9896 }
9897
9898 static int
9899 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9900 {
9901   unformat_input_t *i = vam->input;
9902   vl_api_l2tpv3_set_lookup_key_t *mp;
9903   f64 timeout;
9904   u8 key = ~0;
9905
9906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9907     {
9908       if (unformat (i, "lookup_v6_src"))
9909         key = L2T_LOOKUP_SRC_ADDRESS;
9910       else if (unformat (i, "lookup_v6_dst"))
9911         key = L2T_LOOKUP_DST_ADDRESS;
9912       else if (unformat (i, "lookup_session_id"))
9913         key = L2T_LOOKUP_SESSION_ID;
9914       else
9915         break;
9916     }
9917
9918   if (key == (u8) ~ 0)
9919     {
9920       errmsg ("l2tp session lookup key unset\n");
9921       return -99;
9922     }
9923
9924   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9925
9926   mp->key = key;
9927
9928   S;
9929   W;
9930   /* NOTREACHED */
9931   return 0;
9932 }
9933
9934 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9935   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9936 {
9937   vat_main_t *vam = &vat_main;
9938
9939   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9940            format_ip6_address, mp->our_address,
9941            format_ip6_address, mp->client_address,
9942            clib_net_to_host_u32 (mp->sw_if_index));
9943
9944   fformat (vam->ofp,
9945            "   local cookies %016llx %016llx remote cookie %016llx\n",
9946            clib_net_to_host_u64 (mp->local_cookie[0]),
9947            clib_net_to_host_u64 (mp->local_cookie[1]),
9948            clib_net_to_host_u64 (mp->remote_cookie));
9949
9950   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9951            clib_net_to_host_u32 (mp->local_session_id),
9952            clib_net_to_host_u32 (mp->remote_session_id));
9953
9954   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9955            mp->l2_sublayer_present ? "preset" : "absent");
9956
9957 }
9958
9959 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9960   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9961 {
9962   vat_main_t *vam = &vat_main;
9963   vat_json_node_t *node = NULL;
9964   struct in6_addr addr;
9965
9966   if (VAT_JSON_ARRAY != vam->json_tree.type)
9967     {
9968       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9969       vat_json_init_array (&vam->json_tree);
9970     }
9971   node = vat_json_array_add (&vam->json_tree);
9972
9973   vat_json_init_object (node);
9974
9975   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9976   vat_json_object_add_ip6 (node, "our_address", addr);
9977   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9978   vat_json_object_add_ip6 (node, "client_address", addr);
9979
9980   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9981   vat_json_init_array (lc);
9982   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9983   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9984   vat_json_object_add_uint (node, "remote_cookie",
9985                             clib_net_to_host_u64 (mp->remote_cookie));
9986
9987   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9988   vat_json_object_add_uint (node, "local_session_id",
9989                             clib_net_to_host_u32 (mp->local_session_id));
9990   vat_json_object_add_uint (node, "remote_session_id",
9991                             clib_net_to_host_u32 (mp->remote_session_id));
9992   vat_json_object_add_string_copy (node, "l2_sublayer",
9993                                    mp->l2_sublayer_present ? (u8 *) "present"
9994                                    : (u8 *) "absent");
9995 }
9996
9997 static int
9998 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9999 {
10000   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10001   f64 timeout;
10002
10003   /* Get list of l2tpv3-tunnel interfaces */
10004   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10005   S;
10006
10007   /* Use a control ping for synchronization */
10008   {
10009     vl_api_control_ping_t *mp;
10010     M (CONTROL_PING, control_ping);
10011     S;
10012   }
10013   W;
10014 }
10015
10016
10017 static void vl_api_sw_interface_tap_details_t_handler
10018   (vl_api_sw_interface_tap_details_t * mp)
10019 {
10020   vat_main_t *vam = &vat_main;
10021
10022   fformat (vam->ofp, "%-16s %d\n",
10023            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10024 }
10025
10026 static void vl_api_sw_interface_tap_details_t_handler_json
10027   (vl_api_sw_interface_tap_details_t * mp)
10028 {
10029   vat_main_t *vam = &vat_main;
10030   vat_json_node_t *node = NULL;
10031
10032   if (VAT_JSON_ARRAY != vam->json_tree.type)
10033     {
10034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10035       vat_json_init_array (&vam->json_tree);
10036     }
10037   node = vat_json_array_add (&vam->json_tree);
10038
10039   vat_json_init_object (node);
10040   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10041   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10042 }
10043
10044 static int
10045 api_sw_interface_tap_dump (vat_main_t * vam)
10046 {
10047   vl_api_sw_interface_tap_dump_t *mp;
10048   f64 timeout;
10049
10050   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10051   /* Get list of tap interfaces */
10052   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10053   S;
10054
10055   /* Use a control ping for synchronization */
10056   {
10057     vl_api_control_ping_t *mp;
10058     M (CONTROL_PING, control_ping);
10059     S;
10060   }
10061   W;
10062 }
10063
10064 static uword unformat_vxlan_decap_next
10065   (unformat_input_t * input, va_list * args)
10066 {
10067   u32 *result = va_arg (*args, u32 *);
10068   u32 tmp;
10069
10070   if (unformat (input, "l2"))
10071     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10072   else if (unformat (input, "%d", &tmp))
10073     *result = tmp;
10074   else
10075     return 0;
10076   return 1;
10077 }
10078
10079 static int
10080 api_vxlan_add_del_tunnel (vat_main_t * vam)
10081 {
10082   unformat_input_t *line_input = vam->input;
10083   vl_api_vxlan_add_del_tunnel_t *mp;
10084   f64 timeout;
10085   ip46_address_t src, dst;
10086   u8 is_add = 1;
10087   u8 ipv4_set = 0, ipv6_set = 0;
10088   u8 src_set = 0;
10089   u8 dst_set = 0;
10090   u8 grp_set = 0;
10091   u32 mcast_sw_if_index = ~0;
10092   u32 encap_vrf_id = 0;
10093   u32 decap_next_index = ~0;
10094   u32 vni = 0;
10095
10096   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10097   memset (&src, 0, sizeof src);
10098   memset (&dst, 0, sizeof dst);
10099
10100   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10101     {
10102       if (unformat (line_input, "del"))
10103         is_add = 0;
10104       else
10105         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10106         {
10107           ipv4_set = 1;
10108           src_set = 1;
10109         }
10110       else
10111         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10112         {
10113           ipv4_set = 1;
10114           dst_set = 1;
10115         }
10116       else
10117         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10118         {
10119           ipv6_set = 1;
10120           src_set = 1;
10121         }
10122       else
10123         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10124         {
10125           ipv6_set = 1;
10126           dst_set = 1;
10127         }
10128       else if (unformat (line_input, "group %U %U",
10129                          unformat_ip4_address, &dst.ip4,
10130                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10131         {
10132           grp_set = dst_set = 1;
10133           ipv4_set = 1;
10134         }
10135       else if (unformat (line_input, "group %U",
10136                          unformat_ip4_address, &dst.ip4))
10137         {
10138           grp_set = dst_set = 1;
10139           ipv4_set = 1;
10140         }
10141       else if (unformat (line_input, "group %U %U",
10142                          unformat_ip6_address, &dst.ip6,
10143                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10144         {
10145           grp_set = dst_set = 1;
10146           ipv6_set = 1;
10147         }
10148       else if (unformat (line_input, "group %U",
10149                          unformat_ip6_address, &dst.ip6))
10150         {
10151           grp_set = dst_set = 1;
10152           ipv6_set = 1;
10153         }
10154       else
10155         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10156         ;
10157       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10158         ;
10159       else if (unformat (line_input, "decap-next %U",
10160                          unformat_vxlan_decap_next, &decap_next_index))
10161         ;
10162       else if (unformat (line_input, "vni %d", &vni))
10163         ;
10164       else
10165         {
10166           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10167           return -99;
10168         }
10169     }
10170
10171   if (src_set == 0)
10172     {
10173       errmsg ("tunnel src address not specified\n");
10174       return -99;
10175     }
10176   if (dst_set == 0)
10177     {
10178       errmsg ("tunnel dst address not specified\n");
10179       return -99;
10180     }
10181
10182   if (grp_set && !ip46_address_is_multicast (&dst))
10183     {
10184       errmsg ("tunnel group address not multicast\n");
10185       return -99;
10186     }
10187   if (grp_set && mcast_sw_if_index == ~0)
10188     {
10189       errmsg ("tunnel nonexistent multicast device\n");
10190       return -99;
10191     }
10192
10193
10194   if (ipv4_set && ipv6_set)
10195     {
10196       errmsg ("both IPv4 and IPv6 addresses specified");
10197       return -99;
10198     }
10199
10200   if ((vni == 0) || (vni >> 24))
10201     {
10202       errmsg ("vni not specified or out of range\n");
10203       return -99;
10204     }
10205
10206   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10207
10208   if (ipv6_set)
10209     {
10210       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10211       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10212     }
10213   else
10214     {
10215       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10216       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10217     }
10218   mp->encap_vrf_id = ntohl (encap_vrf_id);
10219   mp->decap_next_index = ntohl (decap_next_index);
10220   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10221   mp->vni = ntohl (vni);
10222   mp->is_add = is_add;
10223   mp->is_ipv6 = ipv6_set;
10224
10225   S;
10226   W;
10227   /* NOTREACHED */
10228   return 0;
10229 }
10230
10231 static void vl_api_vxlan_tunnel_details_t_handler
10232   (vl_api_vxlan_tunnel_details_t * mp)
10233 {
10234   vat_main_t *vam = &vat_main;
10235   ip46_address_t src, dst;
10236
10237   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10238   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10239
10240   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d\n",
10241            ntohl (mp->sw_if_index),
10242            format_ip46_address, &src, IP46_TYPE_ANY,
10243            format_ip46_address, &dst, IP46_TYPE_ANY,
10244            ntohl (mp->encap_vrf_id),
10245            ntohl (mp->decap_next_index), ntohl (mp->vni),
10246            ntohl (mp->mcast_sw_if_index));
10247 }
10248
10249 static void vl_api_vxlan_tunnel_details_t_handler_json
10250   (vl_api_vxlan_tunnel_details_t * mp)
10251 {
10252   vat_main_t *vam = &vat_main;
10253   vat_json_node_t *node = NULL;
10254
10255   if (VAT_JSON_ARRAY != vam->json_tree.type)
10256     {
10257       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10258       vat_json_init_array (&vam->json_tree);
10259     }
10260   node = vat_json_array_add (&vam->json_tree);
10261
10262   vat_json_init_object (node);
10263   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10264   if (mp->is_ipv6)
10265     {
10266       struct in6_addr ip6;
10267
10268       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10269       vat_json_object_add_ip6 (node, "src_address", ip6);
10270       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10271       vat_json_object_add_ip6 (node, "dst_address", ip6);
10272     }
10273   else
10274     {
10275       struct in_addr ip4;
10276
10277       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10278       vat_json_object_add_ip4 (node, "src_address", ip4);
10279       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10280       vat_json_object_add_ip4 (node, "dst_address", ip4);
10281     }
10282   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10283   vat_json_object_add_uint (node, "decap_next_index",
10284                             ntohl (mp->decap_next_index));
10285   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10286   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10287   vat_json_object_add_uint (node, "mcast_sw_if_index",
10288                             ntohl (mp->mcast_sw_if_index));
10289 }
10290
10291 static int
10292 api_vxlan_tunnel_dump (vat_main_t * vam)
10293 {
10294   unformat_input_t *i = vam->input;
10295   vl_api_vxlan_tunnel_dump_t *mp;
10296   f64 timeout;
10297   u32 sw_if_index;
10298   u8 sw_if_index_set = 0;
10299
10300   /* Parse args required to build the message */
10301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10302     {
10303       if (unformat (i, "sw_if_index %d", &sw_if_index))
10304         sw_if_index_set = 1;
10305       else
10306         break;
10307     }
10308
10309   if (sw_if_index_set == 0)
10310     {
10311       sw_if_index = ~0;
10312     }
10313
10314   if (!vam->json_output)
10315     {
10316       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s\n",
10317                "sw_if_index", "src_address", "dst_address",
10318                "encap_vrf_id", "decap_next_index", "vni",
10319                "mcast_sw_if_index");
10320     }
10321
10322   /* Get list of vxlan-tunnel interfaces */
10323   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10324
10325   mp->sw_if_index = htonl (sw_if_index);
10326
10327   S;
10328
10329   /* Use a control ping for synchronization */
10330   {
10331     vl_api_control_ping_t *mp;
10332     M (CONTROL_PING, control_ping);
10333     S;
10334   }
10335   W;
10336 }
10337
10338 static int
10339 api_gre_add_del_tunnel (vat_main_t * vam)
10340 {
10341   unformat_input_t *line_input = vam->input;
10342   vl_api_gre_add_del_tunnel_t *mp;
10343   f64 timeout;
10344   ip4_address_t src4, dst4;
10345   u8 is_add = 1;
10346   u8 teb = 0;
10347   u8 src_set = 0;
10348   u8 dst_set = 0;
10349   u32 outer_fib_id = 0;
10350
10351   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10352     {
10353       if (unformat (line_input, "del"))
10354         is_add = 0;
10355       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10356         src_set = 1;
10357       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10358         dst_set = 1;
10359       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10360         ;
10361       else if (unformat (line_input, "teb"))
10362         teb = 1;
10363       else
10364         {
10365           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10366           return -99;
10367         }
10368     }
10369
10370   if (src_set == 0)
10371     {
10372       errmsg ("tunnel src address not specified\n");
10373       return -99;
10374     }
10375   if (dst_set == 0)
10376     {
10377       errmsg ("tunnel dst address not specified\n");
10378       return -99;
10379     }
10380
10381
10382   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10383
10384   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10385   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10386   mp->outer_fib_id = ntohl (outer_fib_id);
10387   mp->is_add = is_add;
10388   mp->teb = teb;
10389
10390   S;
10391   W;
10392   /* NOTREACHED */
10393   return 0;
10394 }
10395
10396 static void vl_api_gre_tunnel_details_t_handler
10397   (vl_api_gre_tunnel_details_t * mp)
10398 {
10399   vat_main_t *vam = &vat_main;
10400
10401   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10402            ntohl (mp->sw_if_index),
10403            format_ip4_address, &mp->src_address,
10404            format_ip4_address, &mp->dst_address,
10405            mp->teb, ntohl (mp->outer_fib_id));
10406 }
10407
10408 static void vl_api_gre_tunnel_details_t_handler_json
10409   (vl_api_gre_tunnel_details_t * mp)
10410 {
10411   vat_main_t *vam = &vat_main;
10412   vat_json_node_t *node = NULL;
10413   struct in_addr ip4;
10414
10415   if (VAT_JSON_ARRAY != vam->json_tree.type)
10416     {
10417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10418       vat_json_init_array (&vam->json_tree);
10419     }
10420   node = vat_json_array_add (&vam->json_tree);
10421
10422   vat_json_init_object (node);
10423   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10424   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10425   vat_json_object_add_ip4 (node, "src_address", ip4);
10426   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10427   vat_json_object_add_ip4 (node, "dst_address", ip4);
10428   vat_json_object_add_uint (node, "teb", mp->teb);
10429   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10430 }
10431
10432 static int
10433 api_gre_tunnel_dump (vat_main_t * vam)
10434 {
10435   unformat_input_t *i = vam->input;
10436   vl_api_gre_tunnel_dump_t *mp;
10437   f64 timeout;
10438   u32 sw_if_index;
10439   u8 sw_if_index_set = 0;
10440
10441   /* Parse args required to build the message */
10442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10443     {
10444       if (unformat (i, "sw_if_index %d", &sw_if_index))
10445         sw_if_index_set = 1;
10446       else
10447         break;
10448     }
10449
10450   if (sw_if_index_set == 0)
10451     {
10452       sw_if_index = ~0;
10453     }
10454
10455   if (!vam->json_output)
10456     {
10457       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10458                "sw_if_index", "src_address", "dst_address", "teb",
10459                "outer_fib_id");
10460     }
10461
10462   /* Get list of gre-tunnel interfaces */
10463   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10464
10465   mp->sw_if_index = htonl (sw_if_index);
10466
10467   S;
10468
10469   /* Use a control ping for synchronization */
10470   {
10471     vl_api_control_ping_t *mp;
10472     M (CONTROL_PING, control_ping);
10473     S;
10474   }
10475   W;
10476 }
10477
10478 static int
10479 api_l2_fib_clear_table (vat_main_t * vam)
10480 {
10481 //  unformat_input_t * i = vam->input;
10482   vl_api_l2_fib_clear_table_t *mp;
10483   f64 timeout;
10484
10485   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10486
10487   S;
10488   W;
10489   /* NOTREACHED */
10490   return 0;
10491 }
10492
10493 static int
10494 api_l2_interface_efp_filter (vat_main_t * vam)
10495 {
10496   unformat_input_t *i = vam->input;
10497   vl_api_l2_interface_efp_filter_t *mp;
10498   f64 timeout;
10499   u32 sw_if_index;
10500   u8 enable = 1;
10501   u8 sw_if_index_set = 0;
10502
10503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10504     {
10505       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10506         sw_if_index_set = 1;
10507       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10508         sw_if_index_set = 1;
10509       else if (unformat (i, "enable"))
10510         enable = 1;
10511       else if (unformat (i, "disable"))
10512         enable = 0;
10513       else
10514         {
10515           clib_warning ("parse error '%U'", format_unformat_error, i);
10516           return -99;
10517         }
10518     }
10519
10520   if (sw_if_index_set == 0)
10521     {
10522       errmsg ("missing sw_if_index\n");
10523       return -99;
10524     }
10525
10526   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10527
10528   mp->sw_if_index = ntohl (sw_if_index);
10529   mp->enable_disable = enable;
10530
10531   S;
10532   W;
10533   /* NOTREACHED */
10534   return 0;
10535 }
10536
10537 #define foreach_vtr_op                          \
10538 _("disable",  L2_VTR_DISABLED)                  \
10539 _("push-1",  L2_VTR_PUSH_1)                     \
10540 _("push-2",  L2_VTR_PUSH_2)                     \
10541 _("pop-1",  L2_VTR_POP_1)                       \
10542 _("pop-2",  L2_VTR_POP_2)                       \
10543 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10544 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10545 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10546 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10547
10548 static int
10549 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10550 {
10551   unformat_input_t *i = vam->input;
10552   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10553   f64 timeout;
10554   u32 sw_if_index;
10555   u8 sw_if_index_set = 0;
10556   u8 vtr_op_set = 0;
10557   u32 vtr_op = 0;
10558   u32 push_dot1q = 1;
10559   u32 tag1 = ~0;
10560   u32 tag2 = ~0;
10561
10562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10563     {
10564       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10565         sw_if_index_set = 1;
10566       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10567         sw_if_index_set = 1;
10568       else if (unformat (i, "vtr_op %d", &vtr_op))
10569         vtr_op_set = 1;
10570 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10571       foreach_vtr_op
10572 #undef _
10573         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10574         ;
10575       else if (unformat (i, "tag1 %d", &tag1))
10576         ;
10577       else if (unformat (i, "tag2 %d", &tag2))
10578         ;
10579       else
10580         {
10581           clib_warning ("parse error '%U'", format_unformat_error, i);
10582           return -99;
10583         }
10584     }
10585
10586   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10587     {
10588       errmsg ("missing vtr operation or sw_if_index\n");
10589       return -99;
10590     }
10591
10592   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10593     mp->sw_if_index = ntohl (sw_if_index);
10594   mp->vtr_op = ntohl (vtr_op);
10595   mp->push_dot1q = ntohl (push_dot1q);
10596   mp->tag1 = ntohl (tag1);
10597   mp->tag2 = ntohl (tag2);
10598
10599   S;
10600   W;
10601   /* NOTREACHED */
10602   return 0;
10603 }
10604
10605 static int
10606 api_create_vhost_user_if (vat_main_t * vam)
10607 {
10608   unformat_input_t *i = vam->input;
10609   vl_api_create_vhost_user_if_t *mp;
10610   f64 timeout;
10611   u8 *file_name;
10612   u8 is_server = 0;
10613   u8 file_name_set = 0;
10614   u32 custom_dev_instance = ~0;
10615   u8 hwaddr[6];
10616   u8 use_custom_mac = 0;
10617
10618   /* Shut up coverity */
10619   memset (hwaddr, 0, sizeof (hwaddr));
10620
10621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10622     {
10623       if (unformat (i, "socket %s", &file_name))
10624         {
10625           file_name_set = 1;
10626         }
10627       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10628         ;
10629       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10630         use_custom_mac = 1;
10631       else if (unformat (i, "server"))
10632         is_server = 1;
10633       else
10634         break;
10635     }
10636
10637   if (file_name_set == 0)
10638     {
10639       errmsg ("missing socket file name\n");
10640       return -99;
10641     }
10642
10643   if (vec_len (file_name) > 255)
10644     {
10645       errmsg ("socket file name too long\n");
10646       return -99;
10647     }
10648   vec_add1 (file_name, 0);
10649
10650   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10651
10652   mp->is_server = is_server;
10653   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10654   vec_free (file_name);
10655   if (custom_dev_instance != ~0)
10656     {
10657       mp->renumber = 1;
10658       mp->custom_dev_instance = ntohl (custom_dev_instance);
10659     }
10660   mp->use_custom_mac = use_custom_mac;
10661   clib_memcpy (mp->mac_address, hwaddr, 6);
10662
10663   S;
10664   W;
10665   /* NOTREACHED */
10666   return 0;
10667 }
10668
10669 static int
10670 api_modify_vhost_user_if (vat_main_t * vam)
10671 {
10672   unformat_input_t *i = vam->input;
10673   vl_api_modify_vhost_user_if_t *mp;
10674   f64 timeout;
10675   u8 *file_name;
10676   u8 is_server = 0;
10677   u8 file_name_set = 0;
10678   u32 custom_dev_instance = ~0;
10679   u8 sw_if_index_set = 0;
10680   u32 sw_if_index = (u32) ~ 0;
10681
10682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10683     {
10684       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10685         sw_if_index_set = 1;
10686       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10687         sw_if_index_set = 1;
10688       else if (unformat (i, "socket %s", &file_name))
10689         {
10690           file_name_set = 1;
10691         }
10692       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10693         ;
10694       else if (unformat (i, "server"))
10695         is_server = 1;
10696       else
10697         break;
10698     }
10699
10700   if (sw_if_index_set == 0)
10701     {
10702       errmsg ("missing sw_if_index or interface name\n");
10703       return -99;
10704     }
10705
10706   if (file_name_set == 0)
10707     {
10708       errmsg ("missing socket file name\n");
10709       return -99;
10710     }
10711
10712   if (vec_len (file_name) > 255)
10713     {
10714       errmsg ("socket file name too long\n");
10715       return -99;
10716     }
10717   vec_add1 (file_name, 0);
10718
10719   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10720
10721   mp->sw_if_index = ntohl (sw_if_index);
10722   mp->is_server = is_server;
10723   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10724   vec_free (file_name);
10725   if (custom_dev_instance != ~0)
10726     {
10727       mp->renumber = 1;
10728       mp->custom_dev_instance = ntohl (custom_dev_instance);
10729     }
10730
10731   S;
10732   W;
10733   /* NOTREACHED */
10734   return 0;
10735 }
10736
10737 static int
10738 api_delete_vhost_user_if (vat_main_t * vam)
10739 {
10740   unformat_input_t *i = vam->input;
10741   vl_api_delete_vhost_user_if_t *mp;
10742   f64 timeout;
10743   u32 sw_if_index = ~0;
10744   u8 sw_if_index_set = 0;
10745
10746   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10747     {
10748       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10749         sw_if_index_set = 1;
10750       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10751         sw_if_index_set = 1;
10752       else
10753         break;
10754     }
10755
10756   if (sw_if_index_set == 0)
10757     {
10758       errmsg ("missing sw_if_index or interface name\n");
10759       return -99;
10760     }
10761
10762
10763   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10764
10765   mp->sw_if_index = ntohl (sw_if_index);
10766
10767   S;
10768   W;
10769   /* NOTREACHED */
10770   return 0;
10771 }
10772
10773 static void vl_api_sw_interface_vhost_user_details_t_handler
10774   (vl_api_sw_interface_vhost_user_details_t * mp)
10775 {
10776   vat_main_t *vam = &vat_main;
10777
10778   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10779            (char *) mp->interface_name,
10780            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10781            clib_net_to_host_u64 (mp->features), mp->is_server,
10782            ntohl (mp->num_regions), (char *) mp->sock_filename);
10783   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10784 }
10785
10786 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10787   (vl_api_sw_interface_vhost_user_details_t * mp)
10788 {
10789   vat_main_t *vam = &vat_main;
10790   vat_json_node_t *node = NULL;
10791
10792   if (VAT_JSON_ARRAY != vam->json_tree.type)
10793     {
10794       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10795       vat_json_init_array (&vam->json_tree);
10796     }
10797   node = vat_json_array_add (&vam->json_tree);
10798
10799   vat_json_init_object (node);
10800   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10801   vat_json_object_add_string_copy (node, "interface_name",
10802                                    mp->interface_name);
10803   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10804                             ntohl (mp->virtio_net_hdr_sz));
10805   vat_json_object_add_uint (node, "features",
10806                             clib_net_to_host_u64 (mp->features));
10807   vat_json_object_add_uint (node, "is_server", mp->is_server);
10808   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10809   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10810   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10811 }
10812
10813 static int
10814 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10815 {
10816   vl_api_sw_interface_vhost_user_dump_t *mp;
10817   f64 timeout;
10818   fformat (vam->ofp,
10819            "Interface name           idx hdr_sz features server regions filename\n");
10820
10821   /* Get list of vhost-user interfaces */
10822   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10823   S;
10824
10825   /* Use a control ping for synchronization */
10826   {
10827     vl_api_control_ping_t *mp;
10828     M (CONTROL_PING, control_ping);
10829     S;
10830   }
10831   W;
10832 }
10833
10834 static int
10835 api_show_version (vat_main_t * vam)
10836 {
10837   vl_api_show_version_t *mp;
10838   f64 timeout;
10839
10840   M (SHOW_VERSION, show_version);
10841
10842   S;
10843   W;
10844   /* NOTREACHED */
10845   return 0;
10846 }
10847
10848
10849 static int
10850 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10851 {
10852   unformat_input_t *line_input = vam->input;
10853   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10854   f64 timeout;
10855   ip4_address_t local4, remote4;
10856   ip6_address_t local6, remote6;
10857   u8 is_add = 1;
10858   u8 ipv4_set = 0, ipv6_set = 0;
10859   u8 local_set = 0;
10860   u8 remote_set = 0;
10861   u32 encap_vrf_id = 0;
10862   u32 decap_vrf_id = 0;
10863   u8 protocol = ~0;
10864   u32 vni;
10865   u8 vni_set = 0;
10866
10867   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10868     {
10869       if (unformat (line_input, "del"))
10870         is_add = 0;
10871       else if (unformat (line_input, "local %U",
10872                          unformat_ip4_address, &local4))
10873         {
10874           local_set = 1;
10875           ipv4_set = 1;
10876         }
10877       else if (unformat (line_input, "remote %U",
10878                          unformat_ip4_address, &remote4))
10879         {
10880           remote_set = 1;
10881           ipv4_set = 1;
10882         }
10883       else if (unformat (line_input, "local %U",
10884                          unformat_ip6_address, &local6))
10885         {
10886           local_set = 1;
10887           ipv6_set = 1;
10888         }
10889       else if (unformat (line_input, "remote %U",
10890                          unformat_ip6_address, &remote6))
10891         {
10892           remote_set = 1;
10893           ipv6_set = 1;
10894         }
10895       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10896         ;
10897       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10898         ;
10899       else if (unformat (line_input, "vni %d", &vni))
10900         vni_set = 1;
10901       else if (unformat (line_input, "next-ip4"))
10902         protocol = 1;
10903       else if (unformat (line_input, "next-ip6"))
10904         protocol = 2;
10905       else if (unformat (line_input, "next-ethernet"))
10906         protocol = 3;
10907       else if (unformat (line_input, "next-nsh"))
10908         protocol = 4;
10909       else
10910         {
10911           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10912           return -99;
10913         }
10914     }
10915
10916   if (local_set == 0)
10917     {
10918       errmsg ("tunnel local address not specified\n");
10919       return -99;
10920     }
10921   if (remote_set == 0)
10922     {
10923       errmsg ("tunnel remote address not specified\n");
10924       return -99;
10925     }
10926   if (ipv4_set && ipv6_set)
10927     {
10928       errmsg ("both IPv4 and IPv6 addresses specified");
10929       return -99;
10930     }
10931
10932   if (vni_set == 0)
10933     {
10934       errmsg ("vni not specified\n");
10935       return -99;
10936     }
10937
10938   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10939
10940
10941   if (ipv6_set)
10942     {
10943       clib_memcpy (&mp->local, &local6, sizeof (local6));
10944       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10945     }
10946   else
10947     {
10948       clib_memcpy (&mp->local, &local4, sizeof (local4));
10949       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10950     }
10951
10952   mp->encap_vrf_id = ntohl (encap_vrf_id);
10953   mp->decap_vrf_id = ntohl (decap_vrf_id);
10954   mp->protocol = ntohl (protocol);
10955   mp->vni = ntohl (vni);
10956   mp->is_add = is_add;
10957   mp->is_ipv6 = ipv6_set;
10958
10959   S;
10960   W;
10961   /* NOTREACHED */
10962   return 0;
10963 }
10964
10965 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10966   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10967 {
10968   vat_main_t *vam = &vat_main;
10969
10970   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10971            ntohl (mp->sw_if_index),
10972            format_ip46_address, &(mp->local[0]),
10973            format_ip46_address, &(mp->remote[0]),
10974            ntohl (mp->vni),
10975            ntohl (mp->protocol),
10976            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10977 }
10978
10979 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10980   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10981 {
10982   vat_main_t *vam = &vat_main;
10983   vat_json_node_t *node = NULL;
10984   struct in_addr ip4;
10985   struct in6_addr ip6;
10986
10987   if (VAT_JSON_ARRAY != vam->json_tree.type)
10988     {
10989       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10990       vat_json_init_array (&vam->json_tree);
10991     }
10992   node = vat_json_array_add (&vam->json_tree);
10993
10994   vat_json_init_object (node);
10995   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10996   if (mp->is_ipv6)
10997     {
10998       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10999       vat_json_object_add_ip6 (node, "local", ip6);
11000       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11001       vat_json_object_add_ip6 (node, "remote", ip6);
11002     }
11003   else
11004     {
11005       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11006       vat_json_object_add_ip4 (node, "local", ip4);
11007       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11008       vat_json_object_add_ip4 (node, "remote", ip4);
11009     }
11010   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11011   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11012   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11013   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11014   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11015 }
11016
11017 static int
11018 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11019 {
11020   unformat_input_t *i = vam->input;
11021   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11022   f64 timeout;
11023   u32 sw_if_index;
11024   u8 sw_if_index_set = 0;
11025
11026   /* Parse args required to build the message */
11027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11028     {
11029       if (unformat (i, "sw_if_index %d", &sw_if_index))
11030         sw_if_index_set = 1;
11031       else
11032         break;
11033     }
11034
11035   if (sw_if_index_set == 0)
11036     {
11037       sw_if_index = ~0;
11038     }
11039
11040   if (!vam->json_output)
11041     {
11042       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
11043                "sw_if_index", "local", "remote", "vni",
11044                "protocol", "encap_vrf_id", "decap_vrf_id");
11045     }
11046
11047   /* Get list of vxlan-tunnel interfaces */
11048   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11049
11050   mp->sw_if_index = htonl (sw_if_index);
11051
11052   S;
11053
11054   /* Use a control ping for synchronization */
11055   {
11056     vl_api_control_ping_t *mp;
11057     M (CONTROL_PING, control_ping);
11058     S;
11059   }
11060   W;
11061 }
11062
11063 u8 *
11064 format_l2_fib_mac_address (u8 * s, va_list * args)
11065 {
11066   u8 *a = va_arg (*args, u8 *);
11067
11068   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11069                  a[2], a[3], a[4], a[5], a[6], a[7]);
11070 }
11071
11072 static void vl_api_l2_fib_table_entry_t_handler
11073   (vl_api_l2_fib_table_entry_t * mp)
11074 {
11075   vat_main_t *vam = &vat_main;
11076
11077   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11078            "       %d       %d     %d\n",
11079            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11080            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11081            mp->bvi_mac);
11082 }
11083
11084 static void vl_api_l2_fib_table_entry_t_handler_json
11085   (vl_api_l2_fib_table_entry_t * mp)
11086 {
11087   vat_main_t *vam = &vat_main;
11088   vat_json_node_t *node = NULL;
11089
11090   if (VAT_JSON_ARRAY != vam->json_tree.type)
11091     {
11092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11093       vat_json_init_array (&vam->json_tree);
11094     }
11095   node = vat_json_array_add (&vam->json_tree);
11096
11097   vat_json_init_object (node);
11098   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11099   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11100   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11101   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11102   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11103   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11104 }
11105
11106 static int
11107 api_l2_fib_table_dump (vat_main_t * vam)
11108 {
11109   unformat_input_t *i = vam->input;
11110   vl_api_l2_fib_table_dump_t *mp;
11111   f64 timeout;
11112   u32 bd_id;
11113   u8 bd_id_set = 0;
11114
11115   /* Parse args required to build the message */
11116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11117     {
11118       if (unformat (i, "bd_id %d", &bd_id))
11119         bd_id_set = 1;
11120       else
11121         break;
11122     }
11123
11124   if (bd_id_set == 0)
11125     {
11126       errmsg ("missing bridge domain\n");
11127       return -99;
11128     }
11129
11130   fformat (vam->ofp,
11131            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11132
11133   /* Get list of l2 fib entries */
11134   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11135
11136   mp->bd_id = ntohl (bd_id);
11137   S;
11138
11139   /* Use a control ping for synchronization */
11140   {
11141     vl_api_control_ping_t *mp;
11142     M (CONTROL_PING, control_ping);
11143     S;
11144   }
11145   W;
11146 }
11147
11148
11149 static int
11150 api_interface_name_renumber (vat_main_t * vam)
11151 {
11152   unformat_input_t *line_input = vam->input;
11153   vl_api_interface_name_renumber_t *mp;
11154   u32 sw_if_index = ~0;
11155   f64 timeout;
11156   u32 new_show_dev_instance = ~0;
11157
11158   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11159     {
11160       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11161                     &sw_if_index))
11162         ;
11163       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11164         ;
11165       else if (unformat (line_input, "new_show_dev_instance %d",
11166                          &new_show_dev_instance))
11167         ;
11168       else
11169         break;
11170     }
11171
11172   if (sw_if_index == ~0)
11173     {
11174       errmsg ("missing interface name or sw_if_index\n");
11175       return -99;
11176     }
11177
11178   if (new_show_dev_instance == ~0)
11179     {
11180       errmsg ("missing new_show_dev_instance\n");
11181       return -99;
11182     }
11183
11184   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11185
11186   mp->sw_if_index = ntohl (sw_if_index);
11187   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11188
11189   S;
11190   W;
11191 }
11192
11193 static int
11194 api_want_ip4_arp_events (vat_main_t * vam)
11195 {
11196   unformat_input_t *line_input = vam->input;
11197   vl_api_want_ip4_arp_events_t *mp;
11198   f64 timeout;
11199   ip4_address_t address;
11200   int address_set = 0;
11201   u32 enable_disable = 1;
11202
11203   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11204     {
11205       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11206         address_set = 1;
11207       else if (unformat (line_input, "del"))
11208         enable_disable = 0;
11209       else
11210         break;
11211     }
11212
11213   if (address_set == 0)
11214     {
11215       errmsg ("missing addresses\n");
11216       return -99;
11217     }
11218
11219   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11220   mp->enable_disable = enable_disable;
11221   mp->pid = getpid ();
11222   mp->address = address.as_u32;
11223
11224   S;
11225   W;
11226 }
11227
11228 static int
11229 api_want_ip6_nd_events (vat_main_t * vam)
11230 {
11231   unformat_input_t *line_input = vam->input;
11232   vl_api_want_ip6_nd_events_t *mp;
11233   f64 timeout;
11234   ip6_address_t address;
11235   int address_set = 0;
11236   u32 enable_disable = 1;
11237
11238   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11239     {
11240       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11241         address_set = 1;
11242       else if (unformat (line_input, "del"))
11243         enable_disable = 0;
11244       else
11245         break;
11246     }
11247
11248   if (address_set == 0)
11249     {
11250       errmsg ("missing addresses\n");
11251       return -99;
11252     }
11253
11254   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11255   mp->enable_disable = enable_disable;
11256   mp->pid = getpid ();
11257   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11258
11259   S;
11260   W;
11261 }
11262
11263 static int
11264 api_input_acl_set_interface (vat_main_t * vam)
11265 {
11266   unformat_input_t *i = vam->input;
11267   vl_api_input_acl_set_interface_t *mp;
11268   f64 timeout;
11269   u32 sw_if_index;
11270   int sw_if_index_set;
11271   u32 ip4_table_index = ~0;
11272   u32 ip6_table_index = ~0;
11273   u32 l2_table_index = ~0;
11274   u8 is_add = 1;
11275
11276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11277     {
11278       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11279         sw_if_index_set = 1;
11280       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11281         sw_if_index_set = 1;
11282       else if (unformat (i, "del"))
11283         is_add = 0;
11284       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11285         ;
11286       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11287         ;
11288       else if (unformat (i, "l2-table %d", &l2_table_index))
11289         ;
11290       else
11291         {
11292           clib_warning ("parse error '%U'", format_unformat_error, i);
11293           return -99;
11294         }
11295     }
11296
11297   if (sw_if_index_set == 0)
11298     {
11299       errmsg ("missing interface name or sw_if_index\n");
11300       return -99;
11301     }
11302
11303   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11304
11305   mp->sw_if_index = ntohl (sw_if_index);
11306   mp->ip4_table_index = ntohl (ip4_table_index);
11307   mp->ip6_table_index = ntohl (ip6_table_index);
11308   mp->l2_table_index = ntohl (l2_table_index);
11309   mp->is_add = is_add;
11310
11311   S;
11312   W;
11313   /* NOTREACHED */
11314   return 0;
11315 }
11316
11317 static int
11318 api_ip_address_dump (vat_main_t * vam)
11319 {
11320   unformat_input_t *i = vam->input;
11321   vl_api_ip_address_dump_t *mp;
11322   u32 sw_if_index = ~0;
11323   u8 sw_if_index_set = 0;
11324   u8 ipv4_set = 0;
11325   u8 ipv6_set = 0;
11326   f64 timeout;
11327
11328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11329     {
11330       if (unformat (i, "sw_if_index %d", &sw_if_index))
11331         sw_if_index_set = 1;
11332       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11333         sw_if_index_set = 1;
11334       else if (unformat (i, "ipv4"))
11335         ipv4_set = 1;
11336       else if (unformat (i, "ipv6"))
11337         ipv6_set = 1;
11338       else
11339         break;
11340     }
11341
11342   if (ipv4_set && ipv6_set)
11343     {
11344       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11345       return -99;
11346     }
11347
11348   if ((!ipv4_set) && (!ipv6_set))
11349     {
11350       errmsg ("no ipv4 nor ipv6 flag set\n");
11351       return -99;
11352     }
11353
11354   if (sw_if_index_set == 0)
11355     {
11356       errmsg ("missing interface name or sw_if_index\n");
11357       return -99;
11358     }
11359
11360   vam->current_sw_if_index = sw_if_index;
11361   vam->is_ipv6 = ipv6_set;
11362
11363   M (IP_ADDRESS_DUMP, ip_address_dump);
11364   mp->sw_if_index = ntohl (sw_if_index);
11365   mp->is_ipv6 = ipv6_set;
11366   S;
11367
11368   /* Use a control ping for synchronization */
11369   {
11370     vl_api_control_ping_t *mp;
11371     M (CONTROL_PING, control_ping);
11372     S;
11373   }
11374   W;
11375 }
11376
11377 static int
11378 api_ip_dump (vat_main_t * vam)
11379 {
11380   vl_api_ip_dump_t *mp;
11381   unformat_input_t *in = vam->input;
11382   int ipv4_set = 0;
11383   int ipv6_set = 0;
11384   int is_ipv6;
11385   f64 timeout;
11386   int i;
11387
11388   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11389     {
11390       if (unformat (in, "ipv4"))
11391         ipv4_set = 1;
11392       else if (unformat (in, "ipv6"))
11393         ipv6_set = 1;
11394       else
11395         break;
11396     }
11397
11398   if (ipv4_set && ipv6_set)
11399     {
11400       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11401       return -99;
11402     }
11403
11404   if ((!ipv4_set) && (!ipv6_set))
11405     {
11406       errmsg ("no ipv4 nor ipv6 flag set\n");
11407       return -99;
11408     }
11409
11410   is_ipv6 = ipv6_set;
11411   vam->is_ipv6 = is_ipv6;
11412
11413   /* free old data */
11414   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11415     {
11416       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11417     }
11418   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11419
11420   M (IP_DUMP, ip_dump);
11421   mp->is_ipv6 = ipv6_set;
11422   S;
11423
11424   /* Use a control ping for synchronization */
11425   {
11426     vl_api_control_ping_t *mp;
11427     M (CONTROL_PING, control_ping);
11428     S;
11429   }
11430   W;
11431 }
11432
11433 static int
11434 api_ipsec_spd_add_del (vat_main_t * vam)
11435 {
11436   unformat_input_t *i = vam->input;
11437   vl_api_ipsec_spd_add_del_t *mp;
11438   f64 timeout;
11439   u32 spd_id = ~0;
11440   u8 is_add = 1;
11441
11442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11443     {
11444       if (unformat (i, "spd_id %d", &spd_id))
11445         ;
11446       else if (unformat (i, "del"))
11447         is_add = 0;
11448       else
11449         {
11450           clib_warning ("parse error '%U'", format_unformat_error, i);
11451           return -99;
11452         }
11453     }
11454   if (spd_id == ~0)
11455     {
11456       errmsg ("spd_id must be set\n");
11457       return -99;
11458     }
11459
11460   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11461
11462   mp->spd_id = ntohl (spd_id);
11463   mp->is_add = is_add;
11464
11465   S;
11466   W;
11467   /* NOTREACHED */
11468   return 0;
11469 }
11470
11471 static int
11472 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11473 {
11474   unformat_input_t *i = vam->input;
11475   vl_api_ipsec_interface_add_del_spd_t *mp;
11476   f64 timeout;
11477   u32 sw_if_index;
11478   u8 sw_if_index_set = 0;
11479   u32 spd_id = (u32) ~ 0;
11480   u8 is_add = 1;
11481
11482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11483     {
11484       if (unformat (i, "del"))
11485         is_add = 0;
11486       else if (unformat (i, "spd_id %d", &spd_id))
11487         ;
11488       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11489         sw_if_index_set = 1;
11490       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11491         sw_if_index_set = 1;
11492       else
11493         {
11494           clib_warning ("parse error '%U'", format_unformat_error, i);
11495           return -99;
11496         }
11497
11498     }
11499
11500   if (spd_id == (u32) ~ 0)
11501     {
11502       errmsg ("spd_id must be set\n");
11503       return -99;
11504     }
11505
11506   if (sw_if_index_set == 0)
11507     {
11508       errmsg ("missing interface name or sw_if_index\n");
11509       return -99;
11510     }
11511
11512   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11513
11514   mp->spd_id = ntohl (spd_id);
11515   mp->sw_if_index = ntohl (sw_if_index);
11516   mp->is_add = is_add;
11517
11518   S;
11519   W;
11520   /* NOTREACHED */
11521   return 0;
11522 }
11523
11524 static int
11525 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11526 {
11527   unformat_input_t *i = vam->input;
11528   vl_api_ipsec_spd_add_del_entry_t *mp;
11529   f64 timeout;
11530   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11531   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11532   i32 priority = 0;
11533   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11534   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11535   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11536   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11537
11538   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11539   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11540   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11541   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11542   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11543   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11544
11545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11546     {
11547       if (unformat (i, "del"))
11548         is_add = 0;
11549       if (unformat (i, "outbound"))
11550         is_outbound = 1;
11551       if (unformat (i, "inbound"))
11552         is_outbound = 0;
11553       else if (unformat (i, "spd_id %d", &spd_id))
11554         ;
11555       else if (unformat (i, "sa_id %d", &sa_id))
11556         ;
11557       else if (unformat (i, "priority %d", &priority))
11558         ;
11559       else if (unformat (i, "protocol %d", &protocol))
11560         ;
11561       else if (unformat (i, "lport_start %d", &lport_start))
11562         ;
11563       else if (unformat (i, "lport_stop %d", &lport_stop))
11564         ;
11565       else if (unformat (i, "rport_start %d", &rport_start))
11566         ;
11567       else if (unformat (i, "rport_stop %d", &rport_stop))
11568         ;
11569       else
11570         if (unformat
11571             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11572         {
11573           is_ipv6 = 0;
11574           is_ip_any = 0;
11575         }
11576       else
11577         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11578         {
11579           is_ipv6 = 0;
11580           is_ip_any = 0;
11581         }
11582       else
11583         if (unformat
11584             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11585         {
11586           is_ipv6 = 0;
11587           is_ip_any = 0;
11588         }
11589       else
11590         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11591         {
11592           is_ipv6 = 0;
11593           is_ip_any = 0;
11594         }
11595       else
11596         if (unformat
11597             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11598         {
11599           is_ipv6 = 1;
11600           is_ip_any = 0;
11601         }
11602       else
11603         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11604         {
11605           is_ipv6 = 1;
11606           is_ip_any = 0;
11607         }
11608       else
11609         if (unformat
11610             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11611         {
11612           is_ipv6 = 1;
11613           is_ip_any = 0;
11614         }
11615       else
11616         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11617         {
11618           is_ipv6 = 1;
11619           is_ip_any = 0;
11620         }
11621       else
11622         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11623         {
11624           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11625             {
11626               clib_warning ("unsupported action: 'resolve'");
11627               return -99;
11628             }
11629         }
11630       else
11631         {
11632           clib_warning ("parse error '%U'", format_unformat_error, i);
11633           return -99;
11634         }
11635
11636     }
11637
11638   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11639
11640   mp->spd_id = ntohl (spd_id);
11641   mp->priority = ntohl (priority);
11642   mp->is_outbound = is_outbound;
11643
11644   mp->is_ipv6 = is_ipv6;
11645   if (is_ipv6 || is_ip_any)
11646     {
11647       clib_memcpy (mp->remote_address_start, &raddr6_start,
11648                    sizeof (ip6_address_t));
11649       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11650                    sizeof (ip6_address_t));
11651       clib_memcpy (mp->local_address_start, &laddr6_start,
11652                    sizeof (ip6_address_t));
11653       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11654                    sizeof (ip6_address_t));
11655     }
11656   else
11657     {
11658       clib_memcpy (mp->remote_address_start, &raddr4_start,
11659                    sizeof (ip4_address_t));
11660       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11661                    sizeof (ip4_address_t));
11662       clib_memcpy (mp->local_address_start, &laddr4_start,
11663                    sizeof (ip4_address_t));
11664       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11665                    sizeof (ip4_address_t));
11666     }
11667   mp->protocol = (u8) protocol;
11668   mp->local_port_start = ntohs ((u16) lport_start);
11669   mp->local_port_stop = ntohs ((u16) lport_stop);
11670   mp->remote_port_start = ntohs ((u16) rport_start);
11671   mp->remote_port_stop = ntohs ((u16) rport_stop);
11672   mp->policy = (u8) policy;
11673   mp->sa_id = ntohl (sa_id);
11674   mp->is_add = is_add;
11675   mp->is_ip_any = is_ip_any;
11676   S;
11677   W;
11678   /* NOTREACHED */
11679   return 0;
11680 }
11681
11682 static int
11683 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11684 {
11685   unformat_input_t *i = vam->input;
11686   vl_api_ipsec_sad_add_del_entry_t *mp;
11687   f64 timeout;
11688   u32 sad_id = 0, spi = 0;
11689   u8 *ck = 0, *ik = 0;
11690   u8 is_add = 1;
11691
11692   u8 protocol = IPSEC_PROTOCOL_AH;
11693   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11694   u32 crypto_alg = 0, integ_alg = 0;
11695   ip4_address_t tun_src4;
11696   ip4_address_t tun_dst4;
11697   ip6_address_t tun_src6;
11698   ip6_address_t tun_dst6;
11699
11700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11701     {
11702       if (unformat (i, "del"))
11703         is_add = 0;
11704       else if (unformat (i, "sad_id %d", &sad_id))
11705         ;
11706       else if (unformat (i, "spi %d", &spi))
11707         ;
11708       else if (unformat (i, "esp"))
11709         protocol = IPSEC_PROTOCOL_ESP;
11710       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11711         {
11712           is_tunnel = 1;
11713           is_tunnel_ipv6 = 0;
11714         }
11715       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11716         {
11717           is_tunnel = 1;
11718           is_tunnel_ipv6 = 0;
11719         }
11720       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11721         {
11722           is_tunnel = 1;
11723           is_tunnel_ipv6 = 1;
11724         }
11725       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11726         {
11727           is_tunnel = 1;
11728           is_tunnel_ipv6 = 1;
11729         }
11730       else
11731         if (unformat
11732             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11733         {
11734           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11735               crypto_alg >= IPSEC_CRYPTO_N_ALG)
11736             {
11737               clib_warning ("unsupported crypto-alg: '%U'",
11738                             format_ipsec_crypto_alg, crypto_alg);
11739               return -99;
11740             }
11741         }
11742       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11743         ;
11744       else
11745         if (unformat
11746             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11747         {
11748 #if DPDK_CRYPTO==1
11749           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
11750 #else
11751           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11752 #endif
11753               integ_alg >= IPSEC_INTEG_N_ALG)
11754             {
11755               clib_warning ("unsupported integ-alg: '%U'",
11756                             format_ipsec_integ_alg, integ_alg);
11757               return -99;
11758             }
11759         }
11760       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11761         ;
11762       else
11763         {
11764           clib_warning ("parse error '%U'", format_unformat_error, i);
11765           return -99;
11766         }
11767
11768     }
11769
11770 #if DPDK_CRYPTO==1
11771   /*Special cases, aes-gcm-128 encryption */
11772   if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
11773     {
11774       if (integ_alg != IPSEC_INTEG_ALG_NONE
11775           && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
11776         {
11777           clib_warning
11778             ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
11779           return -99;
11780         }
11781       else                      /*set integ-alg internally to aes-gcm-128 */
11782         integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
11783     }
11784   else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
11785     {
11786       clib_warning ("unsupported integ-alg: aes-gcm-128");
11787       return -99;
11788     }
11789   else if (integ_alg == IPSEC_INTEG_ALG_NONE)
11790     {
11791       clib_warning ("unsupported integ-alg: none");
11792       return -99;
11793     }
11794 #endif
11795
11796
11797   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11798
11799   mp->sad_id = ntohl (sad_id);
11800   mp->is_add = is_add;
11801   mp->protocol = protocol;
11802   mp->spi = ntohl (spi);
11803   mp->is_tunnel = is_tunnel;
11804   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11805   mp->crypto_algorithm = crypto_alg;
11806   mp->integrity_algorithm = integ_alg;
11807   mp->crypto_key_length = vec_len (ck);
11808   mp->integrity_key_length = vec_len (ik);
11809
11810   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11811     mp->crypto_key_length = sizeof (mp->crypto_key);
11812
11813   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11814     mp->integrity_key_length = sizeof (mp->integrity_key);
11815
11816   if (ck)
11817     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11818   if (ik)
11819     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11820
11821   if (is_tunnel)
11822     {
11823       if (is_tunnel_ipv6)
11824         {
11825           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11826                        sizeof (ip6_address_t));
11827           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11828                        sizeof (ip6_address_t));
11829         }
11830       else
11831         {
11832           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11833                        sizeof (ip4_address_t));
11834           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11835                        sizeof (ip4_address_t));
11836         }
11837     }
11838
11839   S;
11840   W;
11841   /* NOTREACHED */
11842   return 0;
11843 }
11844
11845 static int
11846 api_ipsec_sa_set_key (vat_main_t * vam)
11847 {
11848   unformat_input_t *i = vam->input;
11849   vl_api_ipsec_sa_set_key_t *mp;
11850   f64 timeout;
11851   u32 sa_id;
11852   u8 *ck = 0, *ik = 0;
11853
11854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11855     {
11856       if (unformat (i, "sa_id %d", &sa_id))
11857         ;
11858       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11859         ;
11860       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11861         ;
11862       else
11863         {
11864           clib_warning ("parse error '%U'", format_unformat_error, i);
11865           return -99;
11866         }
11867     }
11868
11869   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11870
11871   mp->sa_id = ntohl (sa_id);
11872   mp->crypto_key_length = vec_len (ck);
11873   mp->integrity_key_length = vec_len (ik);
11874
11875   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11876     mp->crypto_key_length = sizeof (mp->crypto_key);
11877
11878   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11879     mp->integrity_key_length = sizeof (mp->integrity_key);
11880
11881   if (ck)
11882     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11883   if (ik)
11884     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11885
11886   S;
11887   W;
11888   /* NOTREACHED */
11889   return 0;
11890 }
11891
11892 static int
11893 api_ikev2_profile_add_del (vat_main_t * vam)
11894 {
11895   unformat_input_t *i = vam->input;
11896   vl_api_ikev2_profile_add_del_t *mp;
11897   f64 timeout;
11898   u8 is_add = 1;
11899   u8 *name = 0;
11900
11901   const char *valid_chars = "a-zA-Z0-9_";
11902
11903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11904     {
11905       if (unformat (i, "del"))
11906         is_add = 0;
11907       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11908         vec_add1 (name, 0);
11909       else
11910         {
11911           errmsg ("parse error '%U'", format_unformat_error, i);
11912           return -99;
11913         }
11914     }
11915
11916   if (!vec_len (name))
11917     {
11918       errmsg ("profile name must be specified");
11919       return -99;
11920     }
11921
11922   if (vec_len (name) > 64)
11923     {
11924       errmsg ("profile name too long");
11925       return -99;
11926     }
11927
11928   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11929
11930   clib_memcpy (mp->name, name, vec_len (name));
11931   mp->is_add = is_add;
11932   vec_free (name);
11933
11934   S;
11935   W;
11936   /* NOTREACHED */
11937   return 0;
11938 }
11939
11940 static int
11941 api_ikev2_profile_set_auth (vat_main_t * vam)
11942 {
11943   unformat_input_t *i = vam->input;
11944   vl_api_ikev2_profile_set_auth_t *mp;
11945   f64 timeout;
11946   u8 *name = 0;
11947   u8 *data = 0;
11948   u32 auth_method = 0;
11949   u8 is_hex = 0;
11950
11951   const char *valid_chars = "a-zA-Z0-9_";
11952
11953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11954     {
11955       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11956         vec_add1 (name, 0);
11957       else if (unformat (i, "auth_method %U",
11958                          unformat_ikev2_auth_method, &auth_method))
11959         ;
11960       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11961         is_hex = 1;
11962       else if (unformat (i, "auth_data %v", &data))
11963         ;
11964       else
11965         {
11966           errmsg ("parse error '%U'", format_unformat_error, i);
11967           return -99;
11968         }
11969     }
11970
11971   if (!vec_len (name))
11972     {
11973       errmsg ("profile name must be specified");
11974       return -99;
11975     }
11976
11977   if (vec_len (name) > 64)
11978     {
11979       errmsg ("profile name too long");
11980       return -99;
11981     }
11982
11983   if (!vec_len (data))
11984     {
11985       errmsg ("auth_data must be specified");
11986       return -99;
11987     }
11988
11989   if (!auth_method)
11990     {
11991       errmsg ("auth_method must be specified");
11992       return -99;
11993     }
11994
11995   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11996
11997   mp->is_hex = is_hex;
11998   mp->auth_method = (u8) auth_method;
11999   mp->data_len = vec_len (data);
12000   clib_memcpy (mp->name, name, vec_len (name));
12001   clib_memcpy (mp->data, data, vec_len (data));
12002   vec_free (name);
12003   vec_free (data);
12004
12005   S;
12006   W;
12007   /* NOTREACHED */
12008   return 0;
12009 }
12010
12011 static int
12012 api_ikev2_profile_set_id (vat_main_t * vam)
12013 {
12014   unformat_input_t *i = vam->input;
12015   vl_api_ikev2_profile_set_id_t *mp;
12016   f64 timeout;
12017   u8 *name = 0;
12018   u8 *data = 0;
12019   u8 is_local = 0;
12020   u32 id_type = 0;
12021   ip4_address_t ip4;
12022
12023   const char *valid_chars = "a-zA-Z0-9_";
12024
12025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12026     {
12027       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12028         vec_add1 (name, 0);
12029       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12030         ;
12031       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12032         {
12033           data = vec_new (u8, 4);
12034           clib_memcpy (data, ip4.as_u8, 4);
12035         }
12036       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12037         ;
12038       else if (unformat (i, "id_data %v", &data))
12039         ;
12040       else if (unformat (i, "local"))
12041         is_local = 1;
12042       else if (unformat (i, "remote"))
12043         is_local = 0;
12044       else
12045         {
12046           errmsg ("parse error '%U'", format_unformat_error, i);
12047           return -99;
12048         }
12049     }
12050
12051   if (!vec_len (name))
12052     {
12053       errmsg ("profile name must be specified");
12054       return -99;
12055     }
12056
12057   if (vec_len (name) > 64)
12058     {
12059       errmsg ("profile name too long");
12060       return -99;
12061     }
12062
12063   if (!vec_len (data))
12064     {
12065       errmsg ("id_data must be specified");
12066       return -99;
12067     }
12068
12069   if (!id_type)
12070     {
12071       errmsg ("id_type must be specified");
12072       return -99;
12073     }
12074
12075   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12076
12077   mp->is_local = is_local;
12078   mp->id_type = (u8) id_type;
12079   mp->data_len = vec_len (data);
12080   clib_memcpy (mp->name, name, vec_len (name));
12081   clib_memcpy (mp->data, data, vec_len (data));
12082   vec_free (name);
12083   vec_free (data);
12084
12085   S;
12086   W;
12087   /* NOTREACHED */
12088   return 0;
12089 }
12090
12091 static int
12092 api_ikev2_profile_set_ts (vat_main_t * vam)
12093 {
12094   unformat_input_t *i = vam->input;
12095   vl_api_ikev2_profile_set_ts_t *mp;
12096   f64 timeout;
12097   u8 *name = 0;
12098   u8 is_local = 0;
12099   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12100   ip4_address_t start_addr, end_addr;
12101
12102   const char *valid_chars = "a-zA-Z0-9_";
12103
12104   start_addr.as_u32 = 0;
12105   end_addr.as_u32 = (u32) ~ 0;
12106
12107   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12108     {
12109       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12110         vec_add1 (name, 0);
12111       else if (unformat (i, "protocol %d", &proto))
12112         ;
12113       else if (unformat (i, "start_port %d", &start_port))
12114         ;
12115       else if (unformat (i, "end_port %d", &end_port))
12116         ;
12117       else
12118         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12119         ;
12120       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12121         ;
12122       else if (unformat (i, "local"))
12123         is_local = 1;
12124       else if (unformat (i, "remote"))
12125         is_local = 0;
12126       else
12127         {
12128           errmsg ("parse error '%U'", format_unformat_error, i);
12129           return -99;
12130         }
12131     }
12132
12133   if (!vec_len (name))
12134     {
12135       errmsg ("profile name must be specified");
12136       return -99;
12137     }
12138
12139   if (vec_len (name) > 64)
12140     {
12141       errmsg ("profile name too long");
12142       return -99;
12143     }
12144
12145   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12146
12147   mp->is_local = is_local;
12148   mp->proto = (u8) proto;
12149   mp->start_port = (u16) start_port;
12150   mp->end_port = (u16) end_port;
12151   mp->start_addr = start_addr.as_u32;
12152   mp->end_addr = end_addr.as_u32;
12153   clib_memcpy (mp->name, name, vec_len (name));
12154   vec_free (name);
12155
12156   S;
12157   W;
12158   /* NOTREACHED */
12159   return 0;
12160 }
12161
12162 static int
12163 api_ikev2_set_local_key (vat_main_t * vam)
12164 {
12165   unformat_input_t *i = vam->input;
12166   vl_api_ikev2_set_local_key_t *mp;
12167   f64 timeout;
12168   u8 *file = 0;
12169
12170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12171     {
12172       if (unformat (i, "file %v", &file))
12173         vec_add1 (file, 0);
12174       else
12175         {
12176           errmsg ("parse error '%U'", format_unformat_error, i);
12177           return -99;
12178         }
12179     }
12180
12181   if (!vec_len (file))
12182     {
12183       errmsg ("RSA key file must be specified");
12184       return -99;
12185     }
12186
12187   if (vec_len (file) > 256)
12188     {
12189       errmsg ("file name too long");
12190       return -99;
12191     }
12192
12193   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12194
12195   clib_memcpy (mp->key_file, file, vec_len (file));
12196   vec_free (file);
12197
12198   S;
12199   W;
12200   /* NOTREACHED */
12201   return 0;
12202 }
12203
12204 /*
12205  * MAP
12206  */
12207 static int
12208 api_map_add_domain (vat_main_t * vam)
12209 {
12210   unformat_input_t *i = vam->input;
12211   vl_api_map_add_domain_t *mp;
12212   f64 timeout;
12213
12214   ip4_address_t ip4_prefix;
12215   ip6_address_t ip6_prefix;
12216   ip6_address_t ip6_src;
12217   u32 num_m_args = 0;
12218   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12219     0, psid_length = 0;
12220   u8 is_translation = 0;
12221   u32 mtu = 0;
12222   u32 ip6_src_len = 128;
12223
12224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12225     {
12226       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12227                     &ip4_prefix, &ip4_prefix_len))
12228         num_m_args++;
12229       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12230                          &ip6_prefix, &ip6_prefix_len))
12231         num_m_args++;
12232       else
12233         if (unformat
12234             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12235              &ip6_src_len))
12236         num_m_args++;
12237       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12238         num_m_args++;
12239       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12240         num_m_args++;
12241       else if (unformat (i, "psid-offset %d", &psid_offset))
12242         num_m_args++;
12243       else if (unformat (i, "psid-len %d", &psid_length))
12244         num_m_args++;
12245       else if (unformat (i, "mtu %d", &mtu))
12246         num_m_args++;
12247       else if (unformat (i, "map-t"))
12248         is_translation = 1;
12249       else
12250         {
12251           clib_warning ("parse error '%U'", format_unformat_error, i);
12252           return -99;
12253         }
12254     }
12255
12256   if (num_m_args < 3)
12257     {
12258       errmsg ("mandatory argument(s) missing\n");
12259       return -99;
12260     }
12261
12262   /* Construct the API message */
12263   M (MAP_ADD_DOMAIN, map_add_domain);
12264
12265   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12266   mp->ip4_prefix_len = ip4_prefix_len;
12267
12268   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12269   mp->ip6_prefix_len = ip6_prefix_len;
12270
12271   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12272   mp->ip6_src_prefix_len = ip6_src_len;
12273
12274   mp->ea_bits_len = ea_bits_len;
12275   mp->psid_offset = psid_offset;
12276   mp->psid_length = psid_length;
12277   mp->is_translation = is_translation;
12278   mp->mtu = htons (mtu);
12279
12280   /* send it... */
12281   S;
12282
12283   /* Wait for a reply, return good/bad news  */
12284   W;
12285 }
12286
12287 static int
12288 api_map_del_domain (vat_main_t * vam)
12289 {
12290   unformat_input_t *i = vam->input;
12291   vl_api_map_del_domain_t *mp;
12292   f64 timeout;
12293
12294   u32 num_m_args = 0;
12295   u32 index;
12296
12297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12298     {
12299       if (unformat (i, "index %d", &index))
12300         num_m_args++;
12301       else
12302         {
12303           clib_warning ("parse error '%U'", format_unformat_error, i);
12304           return -99;
12305         }
12306     }
12307
12308   if (num_m_args != 1)
12309     {
12310       errmsg ("mandatory argument(s) missing\n");
12311       return -99;
12312     }
12313
12314   /* Construct the API message */
12315   M (MAP_DEL_DOMAIN, map_del_domain);
12316
12317   mp->index = ntohl (index);
12318
12319   /* send it... */
12320   S;
12321
12322   /* Wait for a reply, return good/bad news  */
12323   W;
12324 }
12325
12326 static int
12327 api_map_add_del_rule (vat_main_t * vam)
12328 {
12329   unformat_input_t *i = vam->input;
12330   vl_api_map_add_del_rule_t *mp;
12331   f64 timeout;
12332   u8 is_add = 1;
12333   ip6_address_t ip6_dst;
12334   u32 num_m_args = 0, index, psid = 0;
12335
12336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12337     {
12338       if (unformat (i, "index %d", &index))
12339         num_m_args++;
12340       else if (unformat (i, "psid %d", &psid))
12341         num_m_args++;
12342       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12343         num_m_args++;
12344       else if (unformat (i, "del"))
12345         {
12346           is_add = 0;
12347         }
12348       else
12349         {
12350           clib_warning ("parse error '%U'", format_unformat_error, i);
12351           return -99;
12352         }
12353     }
12354
12355   /* Construct the API message */
12356   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12357
12358   mp->index = ntohl (index);
12359   mp->is_add = is_add;
12360   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12361   mp->psid = ntohs (psid);
12362
12363   /* send it... */
12364   S;
12365
12366   /* Wait for a reply, return good/bad news  */
12367   W;
12368 }
12369
12370 static int
12371 api_map_domain_dump (vat_main_t * vam)
12372 {
12373   vl_api_map_domain_dump_t *mp;
12374   f64 timeout;
12375
12376   /* Construct the API message */
12377   M (MAP_DOMAIN_DUMP, map_domain_dump);
12378
12379   /* send it... */
12380   S;
12381
12382   /* Use a control ping for synchronization */
12383   {
12384     vl_api_control_ping_t *mp;
12385     M (CONTROL_PING, control_ping);
12386     S;
12387   }
12388   W;
12389 }
12390
12391 static int
12392 api_map_rule_dump (vat_main_t * vam)
12393 {
12394   unformat_input_t *i = vam->input;
12395   vl_api_map_rule_dump_t *mp;
12396   f64 timeout;
12397   u32 domain_index = ~0;
12398
12399   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12400     {
12401       if (unformat (i, "index %u", &domain_index))
12402         ;
12403       else
12404         break;
12405     }
12406
12407   if (domain_index == ~0)
12408     {
12409       clib_warning ("parse error: domain index expected");
12410       return -99;
12411     }
12412
12413   /* Construct the API message */
12414   M (MAP_RULE_DUMP, map_rule_dump);
12415
12416   mp->domain_index = htonl (domain_index);
12417
12418   /* send it... */
12419   S;
12420
12421   /* Use a control ping for synchronization */
12422   {
12423     vl_api_control_ping_t *mp;
12424     M (CONTROL_PING, control_ping);
12425     S;
12426   }
12427   W;
12428 }
12429
12430 static void vl_api_map_add_domain_reply_t_handler
12431   (vl_api_map_add_domain_reply_t * mp)
12432 {
12433   vat_main_t *vam = &vat_main;
12434   i32 retval = ntohl (mp->retval);
12435
12436   if (vam->async_mode)
12437     {
12438       vam->async_errors += (retval < 0);
12439     }
12440   else
12441     {
12442       vam->retval = retval;
12443       vam->result_ready = 1;
12444     }
12445 }
12446
12447 static void vl_api_map_add_domain_reply_t_handler_json
12448   (vl_api_map_add_domain_reply_t * mp)
12449 {
12450   vat_main_t *vam = &vat_main;
12451   vat_json_node_t node;
12452
12453   vat_json_init_object (&node);
12454   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12455   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12456
12457   vat_json_print (vam->ofp, &node);
12458   vat_json_free (&node);
12459
12460   vam->retval = ntohl (mp->retval);
12461   vam->result_ready = 1;
12462 }
12463
12464 static int
12465 api_get_first_msg_id (vat_main_t * vam)
12466 {
12467   vl_api_get_first_msg_id_t *mp;
12468   f64 timeout;
12469   unformat_input_t *i = vam->input;
12470   u8 *name;
12471   u8 name_set = 0;
12472
12473   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12474     {
12475       if (unformat (i, "client %s", &name))
12476         name_set = 1;
12477       else
12478         break;
12479     }
12480
12481   if (name_set == 0)
12482     {
12483       errmsg ("missing client name\n");
12484       return -99;
12485     }
12486   vec_add1 (name, 0);
12487
12488   if (vec_len (name) > 63)
12489     {
12490       errmsg ("client name too long\n");
12491       return -99;
12492     }
12493
12494   M (GET_FIRST_MSG_ID, get_first_msg_id);
12495   clib_memcpy (mp->name, name, vec_len (name));
12496   S;
12497   W;
12498   /* NOTREACHED */
12499   return 0;
12500 }
12501
12502 static int
12503 api_cop_interface_enable_disable (vat_main_t * vam)
12504 {
12505   unformat_input_t *line_input = vam->input;
12506   vl_api_cop_interface_enable_disable_t *mp;
12507   f64 timeout;
12508   u32 sw_if_index = ~0;
12509   u8 enable_disable = 1;
12510
12511   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12512     {
12513       if (unformat (line_input, "disable"))
12514         enable_disable = 0;
12515       if (unformat (line_input, "enable"))
12516         enable_disable = 1;
12517       else if (unformat (line_input, "%U", unformat_sw_if_index,
12518                          vam, &sw_if_index))
12519         ;
12520       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12521         ;
12522       else
12523         break;
12524     }
12525
12526   if (sw_if_index == ~0)
12527     {
12528       errmsg ("missing interface name or sw_if_index\n");
12529       return -99;
12530     }
12531
12532   /* Construct the API message */
12533   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12534   mp->sw_if_index = ntohl (sw_if_index);
12535   mp->enable_disable = enable_disable;
12536
12537   /* send it... */
12538   S;
12539   /* Wait for the reply */
12540   W;
12541 }
12542
12543 static int
12544 api_cop_whitelist_enable_disable (vat_main_t * vam)
12545 {
12546   unformat_input_t *line_input = vam->input;
12547   vl_api_cop_whitelist_enable_disable_t *mp;
12548   f64 timeout;
12549   u32 sw_if_index = ~0;
12550   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12551   u32 fib_id = 0;
12552
12553   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12554     {
12555       if (unformat (line_input, "ip4"))
12556         ip4 = 1;
12557       else if (unformat (line_input, "ip6"))
12558         ip6 = 1;
12559       else if (unformat (line_input, "default"))
12560         default_cop = 1;
12561       else if (unformat (line_input, "%U", unformat_sw_if_index,
12562                          vam, &sw_if_index))
12563         ;
12564       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12565         ;
12566       else if (unformat (line_input, "fib-id %d", &fib_id))
12567         ;
12568       else
12569         break;
12570     }
12571
12572   if (sw_if_index == ~0)
12573     {
12574       errmsg ("missing interface name or sw_if_index\n");
12575       return -99;
12576     }
12577
12578   /* Construct the API message */
12579   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12580   mp->sw_if_index = ntohl (sw_if_index);
12581   mp->fib_id = ntohl (fib_id);
12582   mp->ip4 = ip4;
12583   mp->ip6 = ip6;
12584   mp->default_cop = default_cop;
12585
12586   /* send it... */
12587   S;
12588   /* Wait for the reply */
12589   W;
12590 }
12591
12592 static int
12593 api_get_node_graph (vat_main_t * vam)
12594 {
12595   vl_api_get_node_graph_t *mp;
12596   f64 timeout;
12597
12598   M (GET_NODE_GRAPH, get_node_graph);
12599
12600   /* send it... */
12601   S;
12602   /* Wait for the reply */
12603   W;
12604 }
12605
12606 /* *INDENT-OFF* */
12607 /** Used for parsing LISP eids */
12608 typedef CLIB_PACKED(struct{
12609   u8 addr[16];   /**< eid address */
12610   u32 len;       /**< prefix length if IP */
12611   u8 type;      /**< type of eid */
12612 }) lisp_eid_vat_t;
12613 /* *INDENT-ON* */
12614
12615 static uword
12616 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12617 {
12618   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12619
12620   memset (a, 0, sizeof (a[0]));
12621
12622   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12623     {
12624       a->type = 0;              /* ipv4 type */
12625     }
12626   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12627     {
12628       a->type = 1;              /* ipv6 type */
12629     }
12630   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12631     {
12632       a->type = 2;              /* mac type */
12633     }
12634   else
12635     {
12636       return 0;
12637     }
12638
12639   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12640     {
12641       return 0;
12642     }
12643
12644   return 1;
12645 }
12646
12647 static int
12648 lisp_eid_size_vat (u8 type)
12649 {
12650   switch (type)
12651     {
12652     case 0:
12653       return 4;
12654     case 1:
12655       return 16;
12656     case 2:
12657       return 6;
12658     }
12659   return 0;
12660 }
12661
12662 static void
12663 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12664 {
12665   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12666 }
12667
12668 /* *INDENT-OFF* */
12669 /** Used for transferring locators via VPP API */
12670 typedef CLIB_PACKED(struct
12671 {
12672   u32 sw_if_index; /**< locator sw_if_index */
12673   u8 priority; /**< locator priority */
12674   u8 weight;   /**< locator weight */
12675 }) ls_locator_t;
12676 /* *INDENT-ON* */
12677
12678 static int
12679 api_lisp_add_del_locator_set (vat_main_t * vam)
12680 {
12681   unformat_input_t *input = vam->input;
12682   vl_api_lisp_add_del_locator_set_t *mp;
12683   f64 timeout = ~0;
12684   u8 is_add = 1;
12685   u8 *locator_set_name = NULL;
12686   u8 locator_set_name_set = 0;
12687   ls_locator_t locator, *locators = 0;
12688   u32 sw_if_index, priority, weight;
12689   u32 data_len = 0;
12690
12691   /* Parse args required to build the message */
12692   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12693     {
12694       if (unformat (input, "del"))
12695         {
12696           is_add = 0;
12697         }
12698       else if (unformat (input, "locator-set %s", &locator_set_name))
12699         {
12700           locator_set_name_set = 1;
12701         }
12702       else if (unformat (input, "sw_if_index %u p %u w %u",
12703                          &sw_if_index, &priority, &weight))
12704         {
12705           locator.sw_if_index = htonl (sw_if_index);
12706           locator.priority = priority;
12707           locator.weight = weight;
12708           vec_add1 (locators, locator);
12709         }
12710       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12711                          vam, &sw_if_index, &priority, &weight))
12712         {
12713           locator.sw_if_index = htonl (sw_if_index);
12714           locator.priority = priority;
12715           locator.weight = weight;
12716           vec_add1 (locators, locator);
12717         }
12718       else
12719         break;
12720     }
12721
12722   if (locator_set_name_set == 0)
12723     {
12724       errmsg ("missing locator-set name");
12725       vec_free (locators);
12726       return -99;
12727     }
12728
12729   if (vec_len (locator_set_name) > 64)
12730     {
12731       errmsg ("locator-set name too long\n");
12732       vec_free (locator_set_name);
12733       vec_free (locators);
12734       return -99;
12735     }
12736   vec_add1 (locator_set_name, 0);
12737
12738   data_len = sizeof (ls_locator_t) * vec_len (locators);
12739
12740   /* Construct the API message */
12741   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12742
12743   mp->is_add = is_add;
12744   clib_memcpy (mp->locator_set_name, locator_set_name,
12745                vec_len (locator_set_name));
12746   vec_free (locator_set_name);
12747
12748   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12749   if (locators)
12750     clib_memcpy (mp->locators, locators, data_len);
12751   vec_free (locators);
12752
12753   /* send it... */
12754   S;
12755
12756   /* Wait for a reply... */
12757   W;
12758
12759   /* NOTREACHED */
12760   return 0;
12761 }
12762
12763 static int
12764 api_lisp_add_del_locator (vat_main_t * vam)
12765 {
12766   unformat_input_t *input = vam->input;
12767   vl_api_lisp_add_del_locator_t *mp;
12768   f64 timeout = ~0;
12769   u32 tmp_if_index = ~0;
12770   u32 sw_if_index = ~0;
12771   u8 sw_if_index_set = 0;
12772   u8 sw_if_index_if_name_set = 0;
12773   u32 priority = ~0;
12774   u8 priority_set = 0;
12775   u32 weight = ~0;
12776   u8 weight_set = 0;
12777   u8 is_add = 1;
12778   u8 *locator_set_name = NULL;
12779   u8 locator_set_name_set = 0;
12780
12781   /* Parse args required to build the message */
12782   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12783     {
12784       if (unformat (input, "del"))
12785         {
12786           is_add = 0;
12787         }
12788       else if (unformat (input, "locator-set %s", &locator_set_name))
12789         {
12790           locator_set_name_set = 1;
12791         }
12792       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12793                          &tmp_if_index))
12794         {
12795           sw_if_index_if_name_set = 1;
12796           sw_if_index = tmp_if_index;
12797         }
12798       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12799         {
12800           sw_if_index_set = 1;
12801           sw_if_index = tmp_if_index;
12802         }
12803       else if (unformat (input, "p %d", &priority))
12804         {
12805           priority_set = 1;
12806         }
12807       else if (unformat (input, "w %d", &weight))
12808         {
12809           weight_set = 1;
12810         }
12811       else
12812         break;
12813     }
12814
12815   if (locator_set_name_set == 0)
12816     {
12817       errmsg ("missing locator-set name");
12818       return -99;
12819     }
12820
12821   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12822     {
12823       errmsg ("missing sw_if_index");
12824       vec_free (locator_set_name);
12825       return -99;
12826     }
12827
12828   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12829     {
12830       errmsg ("cannot use both params interface name and sw_if_index");
12831       vec_free (locator_set_name);
12832       return -99;
12833     }
12834
12835   if (priority_set == 0)
12836     {
12837       errmsg ("missing locator-set priority\n");
12838       vec_free (locator_set_name);
12839       return -99;
12840     }
12841
12842   if (weight_set == 0)
12843     {
12844       errmsg ("missing locator-set weight\n");
12845       vec_free (locator_set_name);
12846       return -99;
12847     }
12848
12849   if (vec_len (locator_set_name) > 64)
12850     {
12851       errmsg ("locator-set name too long\n");
12852       vec_free (locator_set_name);
12853       return -99;
12854     }
12855   vec_add1 (locator_set_name, 0);
12856
12857   /* Construct the API message */
12858   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12859
12860   mp->is_add = is_add;
12861   mp->sw_if_index = ntohl (sw_if_index);
12862   mp->priority = priority;
12863   mp->weight = weight;
12864   clib_memcpy (mp->locator_set_name, locator_set_name,
12865                vec_len (locator_set_name));
12866   vec_free (locator_set_name);
12867
12868   /* send it... */
12869   S;
12870
12871   /* Wait for a reply... */
12872   W;
12873
12874   /* NOTREACHED */
12875   return 0;
12876 }
12877
12878 static int
12879 api_lisp_add_del_local_eid (vat_main_t * vam)
12880 {
12881   unformat_input_t *input = vam->input;
12882   vl_api_lisp_add_del_local_eid_t *mp;
12883   f64 timeout = ~0;
12884   u8 is_add = 1;
12885   u8 eid_set = 0;
12886   lisp_eid_vat_t _eid, *eid = &_eid;
12887   u8 *locator_set_name = 0;
12888   u8 locator_set_name_set = 0;
12889   u32 vni = 0;
12890
12891   /* Parse args required to build the message */
12892   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12893     {
12894       if (unformat (input, "del"))
12895         {
12896           is_add = 0;
12897         }
12898       else if (unformat (input, "vni %d", &vni))
12899         {
12900           ;
12901         }
12902       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12903         {
12904           eid_set = 1;
12905         }
12906       else if (unformat (input, "locator-set %s", &locator_set_name))
12907         {
12908           locator_set_name_set = 1;
12909         }
12910       else
12911         break;
12912     }
12913
12914   if (locator_set_name_set == 0)
12915     {
12916       errmsg ("missing locator-set name\n");
12917       return -99;
12918     }
12919
12920   if (0 == eid_set)
12921     {
12922       errmsg ("EID address not set!");
12923       vec_free (locator_set_name);
12924       return -99;
12925     }
12926
12927   if (vec_len (locator_set_name) > 64)
12928     {
12929       errmsg ("locator-set name too long\n");
12930       vec_free (locator_set_name);
12931       return -99;
12932     }
12933   vec_add1 (locator_set_name, 0);
12934
12935   /* Construct the API message */
12936   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12937
12938   mp->is_add = is_add;
12939   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12940   mp->eid_type = eid->type;
12941   mp->prefix_len = eid->len;
12942   mp->vni = clib_host_to_net_u32 (vni);
12943   clib_memcpy (mp->locator_set_name, locator_set_name,
12944                vec_len (locator_set_name));
12945
12946   vec_free (locator_set_name);
12947
12948   /* send it... */
12949   S;
12950
12951   /* Wait for a reply... */
12952   W;
12953
12954   /* NOTREACHED */
12955   return 0;
12956 }
12957
12958 /* *INDENT-OFF* */
12959 /** Used for transferring locators via VPP API */
12960 typedef CLIB_PACKED(struct
12961 {
12962   u8 is_ip4; /**< is locator an IPv4 address? */
12963   u8 priority; /**< locator priority */
12964   u8 weight;   /**< locator weight */
12965   u8 addr[16]; /**< IPv4/IPv6 address */
12966 }) rloc_t;
12967 /* *INDENT-ON* */
12968
12969 static int
12970 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12971 {
12972   unformat_input_t *input = vam->input;
12973   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12974   f64 timeout = ~0;
12975   u8 is_add = 1;
12976   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12977   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12978   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12979   u32 action = ~0, p, w;
12980   ip4_address_t rmt_rloc4, lcl_rloc4;
12981   ip6_address_t rmt_rloc6, lcl_rloc6;
12982   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12983
12984   memset (&rloc, 0, sizeof (rloc));
12985
12986   /* Parse args required to build the message */
12987   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12988     {
12989       if (unformat (input, "del"))
12990         {
12991           is_add = 0;
12992         }
12993       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12994         {
12995           rmt_eid_set = 1;
12996         }
12997       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12998         {
12999           lcl_eid_set = 1;
13000         }
13001       else if (unformat (input, "p %d w %d", &p, &w))
13002         {
13003           if (!curr_rloc)
13004             {
13005               errmsg ("No RLOC configured for setting priority/weight!");
13006               return -99;
13007             }
13008           curr_rloc->priority = p;
13009           curr_rloc->weight = w;
13010         }
13011       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13012                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13013         {
13014           rloc.is_ip4 = 1;
13015
13016           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13017           rloc.priority = rloc.weight = 0;
13018           vec_add1 (lcl_locs, rloc);
13019
13020           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13021           vec_add1 (rmt_locs, rloc);
13022           /* priority and weight saved in rmt loc */
13023           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13024         }
13025       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13026                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13027         {
13028           rloc.is_ip4 = 0;
13029           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13030           rloc.priority = rloc.weight = 0;
13031           vec_add1 (lcl_locs, rloc);
13032
13033           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13034           vec_add1 (rmt_locs, rloc);
13035           /* priority and weight saved in rmt loc */
13036           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13037         }
13038       else if (unformat (input, "action %d", &action))
13039         {
13040           ;
13041         }
13042       else
13043         {
13044           clib_warning ("parse error '%U'", format_unformat_error, input);
13045           return -99;
13046         }
13047     }
13048
13049   if (!rmt_eid_set)
13050     {
13051       errmsg ("remote eid addresses not set\n");
13052       return -99;
13053     }
13054
13055   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13056     {
13057       errmsg ("eid types don't match\n");
13058       return -99;
13059     }
13060
13061   if (0 == rmt_locs && (u32) ~ 0 == action)
13062     {
13063       errmsg ("action not set for negative mapping\n");
13064       return -99;
13065     }
13066
13067   /* Construct the API message */
13068   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13069
13070   mp->is_add = is_add;
13071   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13072   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13073   mp->eid_type = rmt_eid->type;
13074   mp->rmt_len = rmt_eid->len;
13075   mp->lcl_len = lcl_eid->len;
13076   mp->action = action;
13077
13078   if (0 != rmt_locs && 0 != lcl_locs)
13079     {
13080       mp->loc_num = vec_len (rmt_locs);
13081       clib_memcpy (mp->lcl_locs, lcl_locs,
13082                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13083       clib_memcpy (mp->rmt_locs, rmt_locs,
13084                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13085     }
13086   vec_free (lcl_locs);
13087   vec_free (rmt_locs);
13088
13089   /* send it... */
13090   S;
13091
13092   /* Wait for a reply... */
13093   W;
13094
13095   /* NOTREACHED */
13096   return 0;
13097 }
13098
13099 static int
13100 api_lisp_add_del_map_resolver (vat_main_t * vam)
13101 {
13102   unformat_input_t *input = vam->input;
13103   vl_api_lisp_add_del_map_resolver_t *mp;
13104   f64 timeout = ~0;
13105   u8 is_add = 1;
13106   u8 ipv4_set = 0;
13107   u8 ipv6_set = 0;
13108   ip4_address_t ipv4;
13109   ip6_address_t ipv6;
13110
13111   /* Parse args required to build the message */
13112   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13113     {
13114       if (unformat (input, "del"))
13115         {
13116           is_add = 0;
13117         }
13118       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13119         {
13120           ipv4_set = 1;
13121         }
13122       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13123         {
13124           ipv6_set = 1;
13125         }
13126       else
13127         break;
13128     }
13129
13130   if (ipv4_set && ipv6_set)
13131     {
13132       errmsg ("both eid v4 and v6 addresses set\n");
13133       return -99;
13134     }
13135
13136   if (!ipv4_set && !ipv6_set)
13137     {
13138       errmsg ("eid addresses not set\n");
13139       return -99;
13140     }
13141
13142   /* Construct the API message */
13143   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13144
13145   mp->is_add = is_add;
13146   if (ipv6_set)
13147     {
13148       mp->is_ipv6 = 1;
13149       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13150     }
13151   else
13152     {
13153       mp->is_ipv6 = 0;
13154       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13155     }
13156
13157   /* send it... */
13158   S;
13159
13160   /* Wait for a reply... */
13161   W;
13162
13163   /* NOTREACHED */
13164   return 0;
13165 }
13166
13167 static int
13168 api_lisp_gpe_enable_disable (vat_main_t * vam)
13169 {
13170   unformat_input_t *input = vam->input;
13171   vl_api_lisp_gpe_enable_disable_t *mp;
13172   f64 timeout = ~0;
13173   u8 is_set = 0;
13174   u8 is_en = 1;
13175
13176   /* Parse args required to build the message */
13177   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13178     {
13179       if (unformat (input, "enable"))
13180         {
13181           is_set = 1;
13182           is_en = 1;
13183         }
13184       else if (unformat (input, "disable"))
13185         {
13186           is_set = 1;
13187           is_en = 0;
13188         }
13189       else
13190         break;
13191     }
13192
13193   if (is_set == 0)
13194     {
13195       errmsg ("Value not set\n");
13196       return -99;
13197     }
13198
13199   /* Construct the API message */
13200   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13201
13202   mp->is_en = is_en;
13203
13204   /* send it... */
13205   S;
13206
13207   /* Wait for a reply... */
13208   W;
13209
13210   /* NOTREACHED */
13211   return 0;
13212 }
13213
13214 static int
13215 api_lisp_enable_disable (vat_main_t * vam)
13216 {
13217   unformat_input_t *input = vam->input;
13218   vl_api_lisp_enable_disable_t *mp;
13219   f64 timeout = ~0;
13220   u8 is_set = 0;
13221   u8 is_en = 0;
13222
13223   /* Parse args required to build the message */
13224   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13225     {
13226       if (unformat (input, "enable"))
13227         {
13228           is_set = 1;
13229           is_en = 1;
13230         }
13231       else if (unformat (input, "disable"))
13232         {
13233           is_set = 1;
13234         }
13235       else
13236         break;
13237     }
13238
13239   if (!is_set)
13240     {
13241       errmsg ("Value not set\n");
13242       return -99;
13243     }
13244
13245   /* Construct the API message */
13246   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13247
13248   mp->is_en = is_en;
13249
13250   /* send it... */
13251   S;
13252
13253   /* Wait for a reply... */
13254   W;
13255
13256   /* NOTREACHED */
13257   return 0;
13258 }
13259
13260 static int
13261 api_show_lisp_map_request_mode (vat_main_t * vam)
13262 {
13263   f64 timeout = ~0;
13264   vl_api_show_lisp_map_request_mode_t *mp;
13265
13266   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13267
13268   /* send */
13269   S;
13270
13271   /* wait for reply */
13272   W;
13273
13274   return 0;
13275 }
13276
13277 static int
13278 api_lisp_map_request_mode (vat_main_t * vam)
13279 {
13280   f64 timeout = ~0;
13281   unformat_input_t *input = vam->input;
13282   vl_api_lisp_map_request_mode_t *mp;
13283   u8 mode = 0;
13284
13285   /* Parse args required to build the message */
13286   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13287     {
13288       if (unformat (input, "dst-only"))
13289         mode = 0;
13290       else if (unformat (input, "src-dst"))
13291         mode = 1;
13292       else
13293         {
13294           errmsg ("parse error '%U'", format_unformat_error, input);
13295           return -99;
13296         }
13297     }
13298
13299   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13300
13301   mp->mode = mode;
13302
13303   /* send */
13304   S;
13305
13306   /* wait for reply */
13307   W;
13308
13309   /* notreached */
13310   return 0;
13311 }
13312
13313 /**
13314  * Enable/disable LISP proxy ITR.
13315  *
13316  * @param vam vpp API test context
13317  * @return return code
13318  */
13319 static int
13320 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13321 {
13322   f64 timeout = ~0;
13323   u8 ls_name_set = 0;
13324   unformat_input_t *input = vam->input;
13325   vl_api_lisp_pitr_set_locator_set_t *mp;
13326   u8 is_add = 1;
13327   u8 *ls_name = 0;
13328
13329   /* Parse args required to build the message */
13330   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13331     {
13332       if (unformat (input, "del"))
13333         is_add = 0;
13334       else if (unformat (input, "locator-set %s", &ls_name))
13335         ls_name_set = 1;
13336       else
13337         {
13338           errmsg ("parse error '%U'", format_unformat_error, input);
13339           return -99;
13340         }
13341     }
13342
13343   if (!ls_name_set)
13344     {
13345       errmsg ("locator-set name not set!");
13346       return -99;
13347     }
13348
13349   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13350
13351   mp->is_add = is_add;
13352   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13353   vec_free (ls_name);
13354
13355   /* send */
13356   S;
13357
13358   /* wait for reply */
13359   W;
13360
13361   /* notreached */
13362   return 0;
13363 }
13364
13365 static int
13366 api_show_lisp_pitr (vat_main_t * vam)
13367 {
13368   vl_api_show_lisp_pitr_t *mp;
13369   f64 timeout = ~0;
13370
13371   if (!vam->json_output)
13372     {
13373       fformat (vam->ofp, "%=20s\n", "lisp status:");
13374     }
13375
13376   M (SHOW_LISP_PITR, show_lisp_pitr);
13377   /* send it... */
13378   S;
13379
13380   /* Wait for a reply... */
13381   W;
13382
13383   /* NOTREACHED */
13384   return 0;
13385 }
13386
13387 /**
13388  * Add/delete mapping between vni and vrf
13389  */
13390 static int
13391 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13392 {
13393   f64 timeout = ~0;
13394   unformat_input_t *input = vam->input;
13395   vl_api_lisp_eid_table_add_del_map_t *mp;
13396   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13397   u32 vni, vrf, bd_index;
13398
13399   /* Parse args required to build the message */
13400   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13401     {
13402       if (unformat (input, "del"))
13403         is_add = 0;
13404       else if (unformat (input, "vrf %d", &vrf))
13405         vrf_set = 1;
13406       else if (unformat (input, "bd_index %d", &bd_index))
13407         bd_index_set = 1;
13408       else if (unformat (input, "vni %d", &vni))
13409         vni_set = 1;
13410       else
13411         break;
13412     }
13413
13414   if (!vni_set || (!vrf_set && !bd_index_set))
13415     {
13416       errmsg ("missing arguments!");
13417       return -99;
13418     }
13419
13420   if (vrf_set && bd_index_set)
13421     {
13422       errmsg ("error: both vrf and bd entered!");
13423       return -99;
13424     }
13425
13426   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13427
13428   mp->is_add = is_add;
13429   mp->vni = htonl (vni);
13430   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13431   mp->is_l2 = bd_index_set;
13432
13433   /* send */
13434   S;
13435
13436   /* wait for reply */
13437   W;
13438
13439   /* notreached */
13440   return 0;
13441 }
13442
13443 uword
13444 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13445 {
13446   u32 *action = va_arg (*args, u32 *);
13447   u8 *s = 0;
13448
13449   if (unformat (input, "%s", &s))
13450     {
13451       if (!strcmp ((char *) s, "no-action"))
13452         action[0] = 0;
13453       else if (!strcmp ((char *) s, "natively-forward"))
13454         action[0] = 1;
13455       else if (!strcmp ((char *) s, "send-map-request"))
13456         action[0] = 2;
13457       else if (!strcmp ((char *) s, "drop"))
13458         action[0] = 3;
13459       else
13460         {
13461           clib_warning ("invalid action: '%s'", s);
13462           action[0] = 3;
13463         }
13464     }
13465   else
13466     return 0;
13467
13468   vec_free (s);
13469   return 1;
13470 }
13471
13472 /**
13473  * Add/del remote mapping to/from LISP control plane
13474  *
13475  * @param vam vpp API test context
13476  * @return return code
13477  */
13478 static int
13479 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13480 {
13481   unformat_input_t *input = vam->input;
13482   vl_api_lisp_add_del_remote_mapping_t *mp;
13483   f64 timeout = ~0;
13484   u32 vni = 0;
13485   lisp_eid_vat_t _eid, *eid = &_eid;
13486   lisp_eid_vat_t _seid, *seid = &_seid;
13487   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13488   u32 action = ~0, p, w, data_len;
13489   ip4_address_t rloc4;
13490   ip6_address_t rloc6;
13491   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13492
13493   memset (&rloc, 0, sizeof (rloc));
13494
13495   /* Parse args required to build the message */
13496   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13497     {
13498       if (unformat (input, "del-all"))
13499         {
13500           del_all = 1;
13501         }
13502       else if (unformat (input, "del"))
13503         {
13504           is_add = 0;
13505         }
13506       else if (unformat (input, "add"))
13507         {
13508           is_add = 1;
13509         }
13510       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13511         {
13512           eid_set = 1;
13513         }
13514       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13515         {
13516           seid_set = 1;
13517         }
13518       else if (unformat (input, "vni %d", &vni))
13519         {
13520           ;
13521         }
13522       else if (unformat (input, "p %d w %d", &p, &w))
13523         {
13524           if (!curr_rloc)
13525             {
13526               errmsg ("No RLOC configured for setting priority/weight!");
13527               return -99;
13528             }
13529           curr_rloc->priority = p;
13530           curr_rloc->weight = w;
13531         }
13532       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13533         {
13534           rloc.is_ip4 = 1;
13535           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13536           vec_add1 (rlocs, rloc);
13537           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13538         }
13539       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13540         {
13541           rloc.is_ip4 = 0;
13542           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13543           vec_add1 (rlocs, rloc);
13544           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13545         }
13546       else if (unformat (input, "action %U",
13547                          unformat_negative_mapping_action, &action))
13548         {
13549           ;
13550         }
13551       else
13552         {
13553           clib_warning ("parse error '%U'", format_unformat_error, input);
13554           return -99;
13555         }
13556     }
13557
13558   if (0 == eid_set)
13559     {
13560       errmsg ("missing params!");
13561       return -99;
13562     }
13563
13564   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13565     {
13566       errmsg ("no action set for negative map-reply!");
13567       return -99;
13568     }
13569
13570   data_len = vec_len (rlocs) * sizeof (rloc_t);
13571
13572   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13573   mp->is_add = is_add;
13574   mp->vni = htonl (vni);
13575   mp->action = (u8) action;
13576   mp->is_src_dst = seid_set;
13577   mp->eid_len = eid->len;
13578   mp->seid_len = seid->len;
13579   mp->del_all = del_all;
13580   mp->eid_type = eid->type;
13581   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13582   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13583
13584   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13585   clib_memcpy (mp->rlocs, rlocs, data_len);
13586   vec_free (rlocs);
13587
13588   /* send it... */
13589   S;
13590
13591   /* Wait for a reply... */
13592   W;
13593
13594   /* NOTREACHED */
13595   return 0;
13596 }
13597
13598 /**
13599  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13600  * forwarding entries in data-plane accordingly.
13601  *
13602  * @param vam vpp API test context
13603  * @return return code
13604  */
13605 static int
13606 api_lisp_add_del_adjacency (vat_main_t * vam)
13607 {
13608   unformat_input_t *input = vam->input;
13609   vl_api_lisp_add_del_adjacency_t *mp;
13610   f64 timeout = ~0;
13611   u32 vni = 0;
13612   ip4_address_t leid4, reid4;
13613   ip6_address_t leid6, reid6;
13614   u8 reid_mac[6] = { 0 };
13615   u8 leid_mac[6] = { 0 };
13616   u8 reid_type, leid_type;
13617   u32 leid_len = 0, reid_len = 0, len;
13618   u8 is_add = 1;
13619
13620   leid_type = reid_type = (u8) ~ 0;
13621
13622   /* Parse args required to build the message */
13623   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13624     {
13625       if (unformat (input, "del"))
13626         {
13627           is_add = 0;
13628         }
13629       else if (unformat (input, "add"))
13630         {
13631           is_add = 1;
13632         }
13633       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13634                          &reid4, &len))
13635         {
13636           reid_type = 0;        /* ipv4 */
13637           reid_len = len;
13638         }
13639       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13640                          &reid6, &len))
13641         {
13642           reid_type = 1;        /* ipv6 */
13643           reid_len = len;
13644         }
13645       else if (unformat (input, "reid %U", unformat_ethernet_address,
13646                          reid_mac))
13647         {
13648           reid_type = 2;        /* mac */
13649         }
13650       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13651                          &leid4, &len))
13652         {
13653           leid_type = 0;        /* ipv4 */
13654           leid_len = len;
13655         }
13656       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13657                          &leid6, &len))
13658         {
13659           leid_type = 1;        /* ipv6 */
13660           leid_len = len;
13661         }
13662       else if (unformat (input, "leid %U", unformat_ethernet_address,
13663                          leid_mac))
13664         {
13665           leid_type = 2;        /* mac */
13666         }
13667       else if (unformat (input, "vni %d", &vni))
13668         {
13669           ;
13670         }
13671       else
13672         {
13673           errmsg ("parse error '%U'", format_unformat_error, input);
13674           return -99;
13675         }
13676     }
13677
13678   if ((u8) ~ 0 == reid_type)
13679     {
13680       errmsg ("missing params!");
13681       return -99;
13682     }
13683
13684   if (leid_type != reid_type)
13685     {
13686       errmsg ("remote and local EIDs are of different types!");
13687       return -99;
13688     }
13689
13690   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13691   mp->is_add = is_add;
13692   mp->vni = htonl (vni);
13693   mp->leid_len = leid_len;
13694   mp->reid_len = reid_len;
13695   mp->eid_type = reid_type;
13696
13697   switch (mp->eid_type)
13698     {
13699     case 0:
13700       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13701       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13702       break;
13703     case 1:
13704       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13705       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13706       break;
13707     case 2:
13708       clib_memcpy (mp->leid, leid_mac, 6);
13709       clib_memcpy (mp->reid, reid_mac, 6);
13710       break;
13711     default:
13712       errmsg ("unknown EID type %d!", mp->eid_type);
13713       return 0;
13714     }
13715
13716   /* send it... */
13717   S;
13718
13719   /* Wait for a reply... */
13720   W;
13721
13722   /* NOTREACHED */
13723   return 0;
13724 }
13725
13726 static int
13727 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13728 {
13729   unformat_input_t *input = vam->input;
13730   vl_api_lisp_gpe_add_del_iface_t *mp;
13731   f64 timeout = ~0;
13732   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13733   u32 dp_table = 0, vni = 0;
13734
13735   /* Parse args required to build the message */
13736   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13737     {
13738       if (unformat (input, "up"))
13739         {
13740           action_set = 1;
13741           is_add = 1;
13742         }
13743       else if (unformat (input, "down"))
13744         {
13745           action_set = 1;
13746           is_add = 0;
13747         }
13748       else if (unformat (input, "table_id %d", &dp_table))
13749         {
13750           dp_table_set = 1;
13751         }
13752       else if (unformat (input, "bd_id %d", &dp_table))
13753         {
13754           dp_table_set = 1;
13755           is_l2 = 1;
13756         }
13757       else if (unformat (input, "vni %d", &vni))
13758         {
13759           vni_set = 1;
13760         }
13761       else
13762         break;
13763     }
13764
13765   if (action_set == 0)
13766     {
13767       errmsg ("Action not set\n");
13768       return -99;
13769     }
13770   if (dp_table_set == 0 || vni_set == 0)
13771     {
13772       errmsg ("vni and dp_table must be set\n");
13773       return -99;
13774     }
13775
13776   /* Construct the API message */
13777   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13778
13779   mp->is_add = is_add;
13780   mp->dp_table = dp_table;
13781   mp->is_l2 = is_l2;
13782   mp->vni = vni;
13783
13784   /* send it... */
13785   S;
13786
13787   /* Wait for a reply... */
13788   W;
13789
13790   /* NOTREACHED */
13791   return 0;
13792 }
13793
13794 /**
13795  * Add/del map request itr rlocs from LISP control plane and updates
13796  *
13797  * @param vam vpp API test context
13798  * @return return code
13799  */
13800 static int
13801 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13802 {
13803   unformat_input_t *input = vam->input;
13804   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13805   f64 timeout = ~0;
13806   u8 *locator_set_name = 0;
13807   u8 locator_set_name_set = 0;
13808   u8 is_add = 1;
13809
13810   /* Parse args required to build the message */
13811   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13812     {
13813       if (unformat (input, "del"))
13814         {
13815           is_add = 0;
13816         }
13817       else if (unformat (input, "%_%v%_", &locator_set_name))
13818         {
13819           locator_set_name_set = 1;
13820         }
13821       else
13822         {
13823           clib_warning ("parse error '%U'", format_unformat_error, input);
13824           return -99;
13825         }
13826     }
13827
13828   if (is_add && !locator_set_name_set)
13829     {
13830       errmsg ("itr-rloc is not set!");
13831       return -99;
13832     }
13833
13834   if (is_add && vec_len (locator_set_name) > 64)
13835     {
13836       errmsg ("itr-rloc locator-set name too long\n");
13837       vec_free (locator_set_name);
13838       return -99;
13839     }
13840
13841   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13842   mp->is_add = is_add;
13843   if (is_add)
13844     {
13845       clib_memcpy (mp->locator_set_name, locator_set_name,
13846                    vec_len (locator_set_name));
13847     }
13848   else
13849     {
13850       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13851     }
13852   vec_free (locator_set_name);
13853
13854   /* send it... */
13855   S;
13856
13857   /* Wait for a reply... */
13858   W;
13859
13860   /* NOTREACHED */
13861   return 0;
13862 }
13863
13864 static int
13865 api_lisp_locator_dump (vat_main_t * vam)
13866 {
13867   unformat_input_t *input = vam->input;
13868   vl_api_lisp_locator_dump_t *mp;
13869   f64 timeout = ~0;
13870   u8 is_index_set = 0, is_name_set = 0;
13871   u8 *ls_name = 0;
13872   u32 ls_index = ~0;
13873
13874   /* Parse args required to build the message */
13875   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13876     {
13877       if (unformat (input, "ls_name %_%v%_", &ls_name))
13878         {
13879           is_name_set = 1;
13880         }
13881       else if (unformat (input, "ls_index %d", &ls_index))
13882         {
13883           is_index_set = 1;
13884         }
13885       else
13886         {
13887           errmsg ("parse error '%U'", format_unformat_error, input);
13888           return -99;
13889         }
13890     }
13891
13892   if (!is_index_set && !is_name_set)
13893     {
13894       errmsg ("error: expected one of index or name!\n");
13895       return -99;
13896     }
13897
13898   if (is_index_set && is_name_set)
13899     {
13900       errmsg ("error: only one param expected!\n");
13901       return -99;
13902     }
13903
13904   if (vec_len (ls_name) > 62)
13905     {
13906       errmsg ("error: locator set name too long!");
13907       return -99;
13908     }
13909
13910   if (!vam->json_output)
13911     {
13912       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13913                "weight");
13914     }
13915
13916   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13917   mp->is_index_set = is_index_set;
13918
13919   if (is_index_set)
13920     mp->ls_index = clib_host_to_net_u32 (ls_index);
13921   else
13922     {
13923       vec_add1 (ls_name, 0);
13924       strncpy ((char *) mp->ls_name, (char *) ls_name,
13925                sizeof (mp->ls_name) - 1);
13926     }
13927
13928   /* send it... */
13929   S;
13930
13931   /* Use a control ping for synchronization */
13932   {
13933     vl_api_control_ping_t *mp;
13934     M (CONTROL_PING, control_ping);
13935     S;
13936   }
13937   /* Wait for a reply... */
13938   W;
13939
13940   /* NOTREACHED */
13941   return 0;
13942 }
13943
13944 static int
13945 api_lisp_locator_set_dump (vat_main_t * vam)
13946 {
13947   vl_api_lisp_locator_set_dump_t *mp;
13948   unformat_input_t *input = vam->input;
13949   f64 timeout = ~0;
13950   u8 filter = 0;
13951
13952   /* Parse args required to build the message */
13953   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13954     {
13955       if (unformat (input, "local"))
13956         {
13957           filter = 1;
13958         }
13959       else if (unformat (input, "remote"))
13960         {
13961           filter = 2;
13962         }
13963       else
13964         {
13965           errmsg ("parse error '%U'", format_unformat_error, input);
13966           return -99;
13967         }
13968     }
13969
13970   if (!vam->json_output)
13971     {
13972       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13973     }
13974
13975   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13976
13977   mp->filter = filter;
13978
13979   /* send it... */
13980   S;
13981
13982   /* Use a control ping for synchronization */
13983   {
13984     vl_api_control_ping_t *mp;
13985     M (CONTROL_PING, control_ping);
13986     S;
13987   }
13988   /* Wait for a reply... */
13989   W;
13990
13991   /* NOTREACHED */
13992   return 0;
13993 }
13994
13995 static int
13996 api_lisp_eid_table_map_dump (vat_main_t * vam)
13997 {
13998   u8 is_l2 = 0;
13999   u8 mode_set = 0;
14000   unformat_input_t *input = vam->input;
14001   vl_api_lisp_eid_table_map_dump_t *mp;
14002   f64 timeout = ~0;
14003
14004   /* Parse args required to build the message */
14005   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14006     {
14007       if (unformat (input, "l2"))
14008         {
14009           is_l2 = 1;
14010           mode_set = 1;
14011         }
14012       else if (unformat (input, "l3"))
14013         {
14014           is_l2 = 0;
14015           mode_set = 1;
14016         }
14017       else
14018         {
14019           errmsg ("parse error '%U'", format_unformat_error, input);
14020           return -99;
14021         }
14022     }
14023
14024   if (!mode_set)
14025     {
14026       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
14027       return -99;
14028     }
14029
14030   if (!vam->json_output)
14031     {
14032       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
14033     }
14034
14035   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14036   mp->is_l2 = is_l2;
14037
14038   /* send it... */
14039   S;
14040
14041   /* Use a control ping for synchronization */
14042   {
14043     vl_api_control_ping_t *mp;
14044     M (CONTROL_PING, control_ping);
14045     S;
14046   }
14047   /* Wait for a reply... */
14048   W;
14049
14050   /* NOTREACHED */
14051   return 0;
14052 }
14053
14054 static int
14055 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14056 {
14057   vl_api_lisp_eid_table_vni_dump_t *mp;
14058   f64 timeout = ~0;
14059
14060   if (!vam->json_output)
14061     {
14062       fformat (vam->ofp, "VNI\n");
14063     }
14064
14065   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14066
14067   /* send it... */
14068   S;
14069
14070   /* Use a control ping for synchronization */
14071   {
14072     vl_api_control_ping_t *mp;
14073     M (CONTROL_PING, control_ping);
14074     S;
14075   }
14076   /* Wait for a reply... */
14077   W;
14078
14079   /* NOTREACHED */
14080   return 0;
14081 }
14082
14083 static int
14084 api_lisp_eid_table_dump (vat_main_t * vam)
14085 {
14086   unformat_input_t *i = vam->input;
14087   vl_api_lisp_eid_table_dump_t *mp;
14088   f64 timeout = ~0;
14089   struct in_addr ip4;
14090   struct in6_addr ip6;
14091   u8 mac[6];
14092   u8 eid_type = ~0, eid_set = 0;
14093   u32 prefix_length = ~0, t, vni = 0;
14094   u8 filter = 0;
14095
14096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14097     {
14098       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14099         {
14100           eid_set = 1;
14101           eid_type = 0;
14102           prefix_length = t;
14103         }
14104       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14105         {
14106           eid_set = 1;
14107           eid_type = 1;
14108           prefix_length = t;
14109         }
14110       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14111         {
14112           eid_set = 1;
14113           eid_type = 2;
14114         }
14115       else if (unformat (i, "vni %d", &t))
14116         {
14117           vni = t;
14118         }
14119       else if (unformat (i, "local"))
14120         {
14121           filter = 1;
14122         }
14123       else if (unformat (i, "remote"))
14124         {
14125           filter = 2;
14126         }
14127       else
14128         {
14129           errmsg ("parse error '%U'", format_unformat_error, i);
14130           return -99;
14131         }
14132     }
14133
14134   if (!vam->json_output)
14135     {
14136       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
14137                "ls_index", "ttl", "authoritative");
14138     }
14139
14140   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14141
14142   mp->filter = filter;
14143   if (eid_set)
14144     {
14145       mp->eid_set = 1;
14146       mp->vni = htonl (vni);
14147       mp->eid_type = eid_type;
14148       switch (eid_type)
14149         {
14150         case 0:
14151           mp->prefix_length = prefix_length;
14152           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14153           break;
14154         case 1:
14155           mp->prefix_length = prefix_length;
14156           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14157           break;
14158         case 2:
14159           clib_memcpy (mp->eid, mac, sizeof (mac));
14160           break;
14161         default:
14162           errmsg ("unknown EID type %d!", eid_type);
14163           return -99;
14164         }
14165     }
14166
14167   /* send it... */
14168   S;
14169
14170   /* Use a control ping for synchronization */
14171   {
14172     vl_api_control_ping_t *mp;
14173     M (CONTROL_PING, control_ping);
14174     S;
14175   }
14176
14177   /* Wait for a reply... */
14178   W;
14179
14180   /* NOTREACHED */
14181   return 0;
14182 }
14183
14184 static int
14185 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14186 {
14187   vl_api_lisp_gpe_tunnel_dump_t *mp;
14188   f64 timeout = ~0;
14189
14190   if (!vam->json_output)
14191     {
14192       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14193                "%=16s%=16s%=16s%=16s%=16s\n",
14194                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14195                "Decap next", "Lisp version", "Flags", "Next protocol",
14196                "ver_res", "res", "iid");
14197     }
14198
14199   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14200   /* send it... */
14201   S;
14202
14203   /* Use a control ping for synchronization */
14204   {
14205     vl_api_control_ping_t *mp;
14206     M (CONTROL_PING, control_ping);
14207     S;
14208   }
14209   /* Wait for a reply... */
14210   W;
14211
14212   /* NOTREACHED */
14213   return 0;
14214 }
14215
14216 static int
14217 api_lisp_adjacencies_get (vat_main_t * vam)
14218 {
14219   unformat_input_t *i = vam->input;
14220   vl_api_lisp_adjacencies_get_t *mp;
14221   f64 timeout = ~0;
14222   u8 vni_set = 0;
14223   u32 vni = ~0;
14224
14225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14226     {
14227       if (unformat (i, "vni %d", &vni))
14228         {
14229           vni_set = 1;
14230         }
14231       else
14232         {
14233           errmsg ("parse error '%U'\n", format_unformat_error, i);
14234           return -99;
14235         }
14236     }
14237
14238   if (!vni_set)
14239     {
14240       errmsg ("vni not set!\n");
14241       return -99;
14242     }
14243
14244   if (!vam->json_output)
14245     {
14246       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14247     }
14248
14249   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14250   mp->vni = clib_host_to_net_u32 (vni);
14251
14252   /* send it... */
14253   S;
14254
14255   /* Wait for a reply... */
14256   W;
14257
14258   /* NOTREACHED */
14259   return 0;
14260 }
14261
14262 static int
14263 api_lisp_map_resolver_dump (vat_main_t * vam)
14264 {
14265   vl_api_lisp_map_resolver_dump_t *mp;
14266   f64 timeout = ~0;
14267
14268   if (!vam->json_output)
14269     {
14270       fformat (vam->ofp, "%=20s\n", "Map resolver");
14271     }
14272
14273   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14274   /* send it... */
14275   S;
14276
14277   /* Use a control ping for synchronization */
14278   {
14279     vl_api_control_ping_t *mp;
14280     M (CONTROL_PING, control_ping);
14281     S;
14282   }
14283   /* Wait for a reply... */
14284   W;
14285
14286   /* NOTREACHED */
14287   return 0;
14288 }
14289
14290 static int
14291 api_show_lisp_status (vat_main_t * vam)
14292 {
14293   vl_api_show_lisp_status_t *mp;
14294   f64 timeout = ~0;
14295
14296   if (!vam->json_output)
14297     {
14298       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14299     }
14300
14301   M (SHOW_LISP_STATUS, show_lisp_status);
14302   /* send it... */
14303   S;
14304   /* Wait for a reply... */
14305   W;
14306
14307   /* NOTREACHED */
14308   return 0;
14309 }
14310
14311 static int
14312 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14313 {
14314   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14315   f64 timeout = ~0;
14316
14317   if (!vam->json_output)
14318     {
14319       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14320     }
14321
14322   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14323   /* send it... */
14324   S;
14325   /* Wait for a reply... */
14326   W;
14327
14328   /* NOTREACHED */
14329   return 0;
14330 }
14331
14332 static int
14333 api_af_packet_create (vat_main_t * vam)
14334 {
14335   unformat_input_t *i = vam->input;
14336   vl_api_af_packet_create_t *mp;
14337   f64 timeout;
14338   u8 *host_if_name = 0;
14339   u8 hw_addr[6];
14340   u8 random_hw_addr = 1;
14341
14342   memset (hw_addr, 0, sizeof (hw_addr));
14343
14344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14345     {
14346       if (unformat (i, "name %s", &host_if_name))
14347         vec_add1 (host_if_name, 0);
14348       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14349         random_hw_addr = 0;
14350       else
14351         break;
14352     }
14353
14354   if (!vec_len (host_if_name))
14355     {
14356       errmsg ("host-interface name must be specified");
14357       return -99;
14358     }
14359
14360   if (vec_len (host_if_name) > 64)
14361     {
14362       errmsg ("host-interface name too long");
14363       return -99;
14364     }
14365
14366   M (AF_PACKET_CREATE, af_packet_create);
14367
14368   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14369   clib_memcpy (mp->hw_addr, hw_addr, 6);
14370   mp->use_random_hw_addr = random_hw_addr;
14371   vec_free (host_if_name);
14372
14373   S;
14374   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14375   /* NOTREACHED */
14376   return 0;
14377 }
14378
14379 static int
14380 api_af_packet_delete (vat_main_t * vam)
14381 {
14382   unformat_input_t *i = vam->input;
14383   vl_api_af_packet_delete_t *mp;
14384   f64 timeout;
14385   u8 *host_if_name = 0;
14386
14387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14388     {
14389       if (unformat (i, "name %s", &host_if_name))
14390         vec_add1 (host_if_name, 0);
14391       else
14392         break;
14393     }
14394
14395   if (!vec_len (host_if_name))
14396     {
14397       errmsg ("host-interface name must be specified");
14398       return -99;
14399     }
14400
14401   if (vec_len (host_if_name) > 64)
14402     {
14403       errmsg ("host-interface name too long");
14404       return -99;
14405     }
14406
14407   M (AF_PACKET_DELETE, af_packet_delete);
14408
14409   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14410   vec_free (host_if_name);
14411
14412   S;
14413   W;
14414   /* NOTREACHED */
14415   return 0;
14416 }
14417
14418 static int
14419 api_policer_add_del (vat_main_t * vam)
14420 {
14421   unformat_input_t *i = vam->input;
14422   vl_api_policer_add_del_t *mp;
14423   f64 timeout;
14424   u8 is_add = 1;
14425   u8 *name = 0;
14426   u32 cir = 0;
14427   u32 eir = 0;
14428   u64 cb = 0;
14429   u64 eb = 0;
14430   u8 rate_type = 0;
14431   u8 round_type = 0;
14432   u8 type = 0;
14433   u8 color_aware = 0;
14434   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14435
14436   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14437   conform_action.dscp = 0;
14438   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14439   exceed_action.dscp = 0;
14440   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14441   violate_action.dscp = 0;
14442
14443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14444     {
14445       if (unformat (i, "del"))
14446         is_add = 0;
14447       else if (unformat (i, "name %s", &name))
14448         vec_add1 (name, 0);
14449       else if (unformat (i, "cir %u", &cir))
14450         ;
14451       else if (unformat (i, "eir %u", &eir))
14452         ;
14453       else if (unformat (i, "cb %u", &cb))
14454         ;
14455       else if (unformat (i, "eb %u", &eb))
14456         ;
14457       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14458                          &rate_type))
14459         ;
14460       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14461                          &round_type))
14462         ;
14463       else if (unformat (i, "type %U", unformat_policer_type, &type))
14464         ;
14465       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14466                          &conform_action))
14467         ;
14468       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14469                          &exceed_action))
14470         ;
14471       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14472                          &violate_action))
14473         ;
14474       else if (unformat (i, "color-aware"))
14475         color_aware = 1;
14476       else
14477         break;
14478     }
14479
14480   if (!vec_len (name))
14481     {
14482       errmsg ("policer name must be specified");
14483       return -99;
14484     }
14485
14486   if (vec_len (name) > 64)
14487     {
14488       errmsg ("policer name too long");
14489       return -99;
14490     }
14491
14492   M (POLICER_ADD_DEL, policer_add_del);
14493
14494   clib_memcpy (mp->name, name, vec_len (name));
14495   vec_free (name);
14496   mp->is_add = is_add;
14497   mp->cir = cir;
14498   mp->eir = eir;
14499   mp->cb = cb;
14500   mp->eb = eb;
14501   mp->rate_type = rate_type;
14502   mp->round_type = round_type;
14503   mp->type = type;
14504   mp->conform_action_type = conform_action.action_type;
14505   mp->conform_dscp = conform_action.dscp;
14506   mp->exceed_action_type = exceed_action.action_type;
14507   mp->exceed_dscp = exceed_action.dscp;
14508   mp->violate_action_type = violate_action.action_type;
14509   mp->violate_dscp = violate_action.dscp;
14510   mp->color_aware = color_aware;
14511
14512   S;
14513   W;
14514   /* NOTREACHED */
14515   return 0;
14516 }
14517
14518 static int
14519 api_policer_dump (vat_main_t * vam)
14520 {
14521   unformat_input_t *i = vam->input;
14522   vl_api_policer_dump_t *mp;
14523   f64 timeout = ~0;
14524   u8 *match_name = 0;
14525   u8 match_name_valid = 0;
14526
14527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14528     {
14529       if (unformat (i, "name %s", &match_name))
14530         {
14531           vec_add1 (match_name, 0);
14532           match_name_valid = 1;
14533         }
14534       else
14535         break;
14536     }
14537
14538   M (POLICER_DUMP, policer_dump);
14539   mp->match_name_valid = match_name_valid;
14540   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14541   vec_free (match_name);
14542   /* send it... */
14543   S;
14544
14545   /* Use a control ping for synchronization */
14546   {
14547     vl_api_control_ping_t *mp;
14548     M (CONTROL_PING, control_ping);
14549     S;
14550   }
14551   /* Wait for a reply... */
14552   W;
14553
14554   /* NOTREACHED */
14555   return 0;
14556 }
14557
14558 static int
14559 api_policer_classify_set_interface (vat_main_t * vam)
14560 {
14561   unformat_input_t *i = vam->input;
14562   vl_api_policer_classify_set_interface_t *mp;
14563   f64 timeout;
14564   u32 sw_if_index;
14565   int sw_if_index_set;
14566   u32 ip4_table_index = ~0;
14567   u32 ip6_table_index = ~0;
14568   u32 l2_table_index = ~0;
14569   u8 is_add = 1;
14570
14571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14572     {
14573       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14574         sw_if_index_set = 1;
14575       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14576         sw_if_index_set = 1;
14577       else if (unformat (i, "del"))
14578         is_add = 0;
14579       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14580         ;
14581       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14582         ;
14583       else if (unformat (i, "l2-table %d", &l2_table_index))
14584         ;
14585       else
14586         {
14587           clib_warning ("parse error '%U'", format_unformat_error, i);
14588           return -99;
14589         }
14590     }
14591
14592   if (sw_if_index_set == 0)
14593     {
14594       errmsg ("missing interface name or sw_if_index\n");
14595       return -99;
14596     }
14597
14598   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14599
14600   mp->sw_if_index = ntohl (sw_if_index);
14601   mp->ip4_table_index = ntohl (ip4_table_index);
14602   mp->ip6_table_index = ntohl (ip6_table_index);
14603   mp->l2_table_index = ntohl (l2_table_index);
14604   mp->is_add = is_add;
14605
14606   S;
14607   W;
14608   /* NOTREACHED */
14609   return 0;
14610 }
14611
14612 static int
14613 api_policer_classify_dump (vat_main_t * vam)
14614 {
14615   unformat_input_t *i = vam->input;
14616   vl_api_policer_classify_dump_t *mp;
14617   f64 timeout = ~0;
14618   u8 type = POLICER_CLASSIFY_N_TABLES;
14619
14620   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14621     ;
14622   else
14623     {
14624       errmsg ("classify table type must be specified\n");
14625       return -99;
14626     }
14627
14628   if (!vam->json_output)
14629     {
14630       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14631     }
14632
14633   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14634   mp->type = type;
14635   /* send it... */
14636   S;
14637
14638   /* Use a control ping for synchronization */
14639   {
14640     vl_api_control_ping_t *mp;
14641     M (CONTROL_PING, control_ping);
14642     S;
14643   }
14644   /* Wait for a reply... */
14645   W;
14646
14647   /* NOTREACHED */
14648   return 0;
14649 }
14650
14651 static int
14652 api_netmap_create (vat_main_t * vam)
14653 {
14654   unformat_input_t *i = vam->input;
14655   vl_api_netmap_create_t *mp;
14656   f64 timeout;
14657   u8 *if_name = 0;
14658   u8 hw_addr[6];
14659   u8 random_hw_addr = 1;
14660   u8 is_pipe = 0;
14661   u8 is_master = 0;
14662
14663   memset (hw_addr, 0, sizeof (hw_addr));
14664
14665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14666     {
14667       if (unformat (i, "name %s", &if_name))
14668         vec_add1 (if_name, 0);
14669       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14670         random_hw_addr = 0;
14671       else if (unformat (i, "pipe"))
14672         is_pipe = 1;
14673       else if (unformat (i, "master"))
14674         is_master = 1;
14675       else if (unformat (i, "slave"))
14676         is_master = 0;
14677       else
14678         break;
14679     }
14680
14681   if (!vec_len (if_name))
14682     {
14683       errmsg ("interface name must be specified");
14684       return -99;
14685     }
14686
14687   if (vec_len (if_name) > 64)
14688     {
14689       errmsg ("interface name too long");
14690       return -99;
14691     }
14692
14693   M (NETMAP_CREATE, netmap_create);
14694
14695   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14696   clib_memcpy (mp->hw_addr, hw_addr, 6);
14697   mp->use_random_hw_addr = random_hw_addr;
14698   mp->is_pipe = is_pipe;
14699   mp->is_master = is_master;
14700   vec_free (if_name);
14701
14702   S;
14703   W;
14704   /* NOTREACHED */
14705   return 0;
14706 }
14707
14708 static int
14709 api_netmap_delete (vat_main_t * vam)
14710 {
14711   unformat_input_t *i = vam->input;
14712   vl_api_netmap_delete_t *mp;
14713   f64 timeout;
14714   u8 *if_name = 0;
14715
14716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14717     {
14718       if (unformat (i, "name %s", &if_name))
14719         vec_add1 (if_name, 0);
14720       else
14721         break;
14722     }
14723
14724   if (!vec_len (if_name))
14725     {
14726       errmsg ("interface name must be specified");
14727       return -99;
14728     }
14729
14730   if (vec_len (if_name) > 64)
14731     {
14732       errmsg ("interface name too long");
14733       return -99;
14734     }
14735
14736   M (NETMAP_DELETE, netmap_delete);
14737
14738   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14739   vec_free (if_name);
14740
14741   S;
14742   W;
14743   /* NOTREACHED */
14744   return 0;
14745 }
14746
14747 static void vl_api_mpls_eth_tunnel_details_t_handler
14748   (vl_api_mpls_eth_tunnel_details_t * mp)
14749 {
14750   vat_main_t *vam = &vat_main;
14751   i32 i;
14752   i32 len = ntohl (mp->nlabels);
14753
14754   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14755            ntohl (mp->tunnel_index),
14756            format_ethernet_address, &mp->tunnel_dst_mac,
14757            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14758   for (i = 0; i < len; i++)
14759     {
14760       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14761     }
14762   fformat (vam->ofp, "\n");
14763   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14764            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14765 }
14766
14767 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14768   (vl_api_mpls_eth_tunnel_details_t * mp)
14769 {
14770   vat_main_t *vam = &vat_main;
14771   vat_json_node_t *node = NULL;
14772   struct in_addr ip4;
14773   i32 i;
14774   i32 len = ntohl (mp->nlabels);
14775
14776   if (VAT_JSON_ARRAY != vam->json_tree.type)
14777     {
14778       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14779       vat_json_init_array (&vam->json_tree);
14780     }
14781   node = vat_json_array_add (&vam->json_tree);
14782
14783   vat_json_init_object (node);
14784   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14785   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14786   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14787   vat_json_object_add_uint (node, "inner_fib_index",
14788                             ntohl (mp->inner_fib_index));
14789   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14790   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14791   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14792   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14793   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14794                                    format (0, "%U", format_ethernet_address,
14795                                            &mp->tunnel_dst_mac));
14796   vat_json_object_add_uint (node, "tx_sw_if_index",
14797                             ntohl (mp->tx_sw_if_index));
14798   vat_json_object_add_uint (node, "label_count", len);
14799   for (i = 0; i < len; i++)
14800     {
14801       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14802     }
14803 }
14804
14805 static int
14806 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14807 {
14808   vl_api_mpls_eth_tunnel_dump_t *mp;
14809   f64 timeout;
14810   i32 index = -1;
14811
14812   /* Parse args required to build the message */
14813   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14814     {
14815       if (!unformat (vam->input, "tunnel_index %d", &index))
14816         {
14817           index = -1;
14818           break;
14819         }
14820     }
14821
14822   fformat (vam->ofp, "  tunnel_index %d\n", index);
14823
14824   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14825   mp->tunnel_index = htonl (index);
14826   S;
14827
14828   /* Use a control ping for synchronization */
14829   {
14830     vl_api_control_ping_t *mp;
14831     M (CONTROL_PING, control_ping);
14832     S;
14833   }
14834   W;
14835 }
14836
14837 static void vl_api_mpls_fib_encap_details_t_handler
14838   (vl_api_mpls_fib_encap_details_t * mp)
14839 {
14840   vat_main_t *vam = &vat_main;
14841   i32 i;
14842   i32 len = ntohl (mp->nlabels);
14843
14844   fformat (vam->ofp, "table %d, dest %U, label ",
14845            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14846   for (i = 0; i < len; i++)
14847     {
14848       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14849     }
14850   fformat (vam->ofp, "\n");
14851 }
14852
14853 static void vl_api_mpls_fib_encap_details_t_handler_json
14854   (vl_api_mpls_fib_encap_details_t * mp)
14855 {
14856   vat_main_t *vam = &vat_main;
14857   vat_json_node_t *node = NULL;
14858   i32 i;
14859   i32 len = ntohl (mp->nlabels);
14860   struct in_addr ip4;
14861
14862   if (VAT_JSON_ARRAY != vam->json_tree.type)
14863     {
14864       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14865       vat_json_init_array (&vam->json_tree);
14866     }
14867   node = vat_json_array_add (&vam->json_tree);
14868
14869   vat_json_init_object (node);
14870   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14871   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14872   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14873   vat_json_object_add_ip4 (node, "dest", ip4);
14874   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14875   vat_json_object_add_uint (node, "label_count", len);
14876   for (i = 0; i < len; i++)
14877     {
14878       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14879     }
14880 }
14881
14882 static int
14883 api_mpls_fib_encap_dump (vat_main_t * vam)
14884 {
14885   vl_api_mpls_fib_encap_dump_t *mp;
14886   f64 timeout;
14887
14888   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14889   S;
14890
14891   /* Use a control ping for synchronization */
14892   {
14893     vl_api_control_ping_t *mp;
14894     M (CONTROL_PING, control_ping);
14895     S;
14896   }
14897   W;
14898 }
14899
14900 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
14901 #define vl_api_mpls_fib_details_t_print vl_noop_handler
14902
14903 static void
14904 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
14905 {
14906   vat_main_t *vam = &vat_main;
14907   int count = ntohl (mp->count);
14908   vl_api_fib_path_t *fp;
14909   int i;
14910
14911   fformat (vam->ofp,
14912            "table-id %d, label %u, ess_bit %u\n",
14913            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
14914   fp = mp->path;
14915   for (i = 0; i < count; i++)
14916     {
14917       if (fp->afi == IP46_TYPE_IP6)
14918         fformat (vam->ofp,
14919                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14920                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14921                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14922                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14923                  format_ip6_address, fp->next_hop);
14924       else if (fp->afi == IP46_TYPE_IP4)
14925         fformat (vam->ofp,
14926                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14927                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14928                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14929                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14930                  format_ip4_address, fp->next_hop);
14931       fp++;
14932     }
14933 }
14934
14935 static void vl_api_mpls_fib_details_t_handler_json
14936   (vl_api_mpls_fib_details_t * mp)
14937 {
14938   vat_main_t *vam = &vat_main;
14939   int count = ntohl (mp->count);
14940   vat_json_node_t *node = NULL;
14941   struct in_addr ip4;
14942   struct in6_addr ip6;
14943   vl_api_fib_path_t *fp;
14944   int i;
14945
14946   if (VAT_JSON_ARRAY != vam->json_tree.type)
14947     {
14948       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14949       vat_json_init_array (&vam->json_tree);
14950     }
14951   node = vat_json_array_add (&vam->json_tree);
14952
14953   vat_json_init_object (node);
14954   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14955   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
14956   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14957   vat_json_object_add_uint (node, "path_count", count);
14958   fp = mp->path;
14959   for (i = 0; i < count; i++)
14960     {
14961       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
14962       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
14963       vat_json_object_add_uint (node, "is_local", fp->is_local);
14964       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
14965       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
14966       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
14967       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
14968       if (fp->afi == IP46_TYPE_IP4)
14969         {
14970           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
14971           vat_json_object_add_ip4 (node, "next_hop", ip4);
14972         }
14973       else if (fp->afi == IP46_TYPE_IP6)
14974         {
14975           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
14976           vat_json_object_add_ip6 (node, "next_hop", ip6);
14977         }
14978     }
14979 }
14980
14981 static int
14982 api_mpls_fib_dump (vat_main_t * vam)
14983 {
14984   vl_api_mpls_fib_dump_t *mp;
14985   f64 timeout;
14986
14987   M (MPLS_FIB_DUMP, mpls_fib_dump);
14988   S;
14989
14990   /* Use a control ping for synchronization */
14991   {
14992     vl_api_control_ping_t *mp;
14993     M (CONTROL_PING, control_ping);
14994     S;
14995   }
14996   W;
14997 }
14998
14999 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15000 #define vl_api_ip_fib_details_t_print vl_noop_handler
15001
15002 static void
15003 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15004 {
15005   vat_main_t *vam = &vat_main;
15006   int count = ntohl (mp->count);
15007   vl_api_fib_path_t *fp;
15008   int i;
15009
15010   fformat (vam->ofp,
15011            "table-id %d, prefix %U/%d\n",
15012            ntohl (mp->table_id), format_ip4_address, mp->address,
15013            mp->address_length);
15014   fp = mp->path;
15015   for (i = 0; i < count; i++)
15016     {
15017       if (fp->afi == IP46_TYPE_IP6)
15018         fformat (vam->ofp,
15019                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15020                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15021                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15022                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15023                  format_ip6_address, fp->next_hop);
15024       else if (fp->afi == IP46_TYPE_IP4)
15025         fformat (vam->ofp,
15026                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15027                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15028                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15029                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15030                  format_ip4_address, fp->next_hop);
15031       fp++;
15032     }
15033 }
15034
15035 static void vl_api_ip_fib_details_t_handler_json
15036   (vl_api_ip_fib_details_t * mp)
15037 {
15038   vat_main_t *vam = &vat_main;
15039   int count = ntohl (mp->count);
15040   vat_json_node_t *node = NULL;
15041   struct in_addr ip4;
15042   struct in6_addr ip6;
15043   vl_api_fib_path_t *fp;
15044   int i;
15045
15046   if (VAT_JSON_ARRAY != vam->json_tree.type)
15047     {
15048       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15049       vat_json_init_array (&vam->json_tree);
15050     }
15051   node = vat_json_array_add (&vam->json_tree);
15052
15053   vat_json_init_object (node);
15054   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15055   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15056   vat_json_object_add_ip4 (node, "prefix", ip4);
15057   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15058   vat_json_object_add_uint (node, "path_count", count);
15059   fp = mp->path;
15060   for (i = 0; i < count; i++)
15061     {
15062       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15063       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15064       vat_json_object_add_uint (node, "is_local", fp->is_local);
15065       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15066       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15067       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15068       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15069       if (fp->afi == IP46_TYPE_IP4)
15070         {
15071           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15072           vat_json_object_add_ip4 (node, "next_hop", ip4);
15073         }
15074       else if (fp->afi == IP46_TYPE_IP6)
15075         {
15076           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15077           vat_json_object_add_ip6 (node, "next_hop", ip6);
15078         }
15079     }
15080 }
15081
15082 static int
15083 api_ip_fib_dump (vat_main_t * vam)
15084 {
15085   vl_api_ip_fib_dump_t *mp;
15086   f64 timeout;
15087
15088   M (IP_FIB_DUMP, ip_fib_dump);
15089   S;
15090
15091   /* Use a control ping for synchronization */
15092   {
15093     vl_api_control_ping_t *mp;
15094     M (CONTROL_PING, control_ping);
15095     S;
15096   }
15097   W;
15098 }
15099
15100 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15101 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15102
15103 static void
15104 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15105 {
15106   vat_main_t *vam = &vat_main;
15107   int count = ntohl (mp->count);
15108   vl_api_fib_path_t *fp;
15109   int i;
15110
15111   fformat (vam->ofp,
15112            "table-id %d, prefix %U/%d\n",
15113            ntohl (mp->table_id), format_ip6_address, mp->address,
15114            mp->address_length);
15115   fp = mp->path;
15116   for (i = 0; i < count; i++)
15117     {
15118       if (fp->afi == IP46_TYPE_IP6)
15119         fformat (vam->ofp,
15120                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15121                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15122                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15123                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15124                  format_ip6_address, fp->next_hop);
15125       else if (fp->afi == IP46_TYPE_IP4)
15126         fformat (vam->ofp,
15127                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15128                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15129                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15130                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15131                  format_ip4_address, fp->next_hop);
15132       fp++;
15133     }
15134 }
15135
15136 static void vl_api_ip6_fib_details_t_handler_json
15137   (vl_api_ip6_fib_details_t * mp)
15138 {
15139   vat_main_t *vam = &vat_main;
15140   int count = ntohl (mp->count);
15141   vat_json_node_t *node = NULL;
15142   struct in_addr ip4;
15143   struct in6_addr ip6;
15144   vl_api_fib_path_t *fp;
15145   int i;
15146
15147   if (VAT_JSON_ARRAY != vam->json_tree.type)
15148     {
15149       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15150       vat_json_init_array (&vam->json_tree);
15151     }
15152   node = vat_json_array_add (&vam->json_tree);
15153
15154   vat_json_init_object (node);
15155   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15156   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15157   vat_json_object_add_ip6 (node, "prefix", ip6);
15158   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15159   vat_json_object_add_uint (node, "path_count", count);
15160   fp = mp->path;
15161   for (i = 0; i < count; i++)
15162     {
15163       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15164       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15165       vat_json_object_add_uint (node, "is_local", fp->is_local);
15166       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15167       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15168       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15169       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15170       if (fp->afi == IP46_TYPE_IP4)
15171         {
15172           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15173           vat_json_object_add_ip4 (node, "next_hop", ip4);
15174         }
15175       else if (fp->afi == IP46_TYPE_IP6)
15176         {
15177           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15178           vat_json_object_add_ip6 (node, "next_hop", ip6);
15179         }
15180     }
15181 }
15182
15183 static int
15184 api_ip6_fib_dump (vat_main_t * vam)
15185 {
15186   vl_api_ip6_fib_dump_t *mp;
15187   f64 timeout;
15188
15189   M (IP6_FIB_DUMP, ip6_fib_dump);
15190   S;
15191
15192   /* Use a control ping for synchronization */
15193   {
15194     vl_api_control_ping_t *mp;
15195     M (CONTROL_PING, control_ping);
15196     S;
15197   }
15198   W;
15199 }
15200
15201 int
15202 api_classify_table_ids (vat_main_t * vam)
15203 {
15204   vl_api_classify_table_ids_t *mp;
15205   f64 timeout;
15206
15207   /* Construct the API message */
15208   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15209   mp->context = 0;
15210
15211   S;
15212   W;
15213   /* NOTREACHED */
15214   return 0;
15215 }
15216
15217 int
15218 api_classify_table_by_interface (vat_main_t * vam)
15219 {
15220   unformat_input_t *input = vam->input;
15221   vl_api_classify_table_by_interface_t *mp;
15222   f64 timeout;
15223
15224   u32 sw_if_index = ~0;
15225   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15226     {
15227       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15228         ;
15229       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15230         ;
15231       else
15232         break;
15233     }
15234   if (sw_if_index == ~0)
15235     {
15236       errmsg ("missing interface name or sw_if_index\n");
15237       return -99;
15238     }
15239
15240   /* Construct the API message */
15241   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15242   mp->context = 0;
15243   mp->sw_if_index = ntohl (sw_if_index);
15244
15245   S;
15246   W;
15247   /* NOTREACHED */
15248   return 0;
15249 }
15250
15251 int
15252 api_classify_table_info (vat_main_t * vam)
15253 {
15254   unformat_input_t *input = vam->input;
15255   vl_api_classify_table_info_t *mp;
15256   f64 timeout;
15257
15258   u32 table_id = ~0;
15259   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15260     {
15261       if (unformat (input, "table_id %d", &table_id))
15262         ;
15263       else
15264         break;
15265     }
15266   if (table_id == ~0)
15267     {
15268       errmsg ("missing table id\n");
15269       return -99;
15270     }
15271
15272   /* Construct the API message */
15273   M (CLASSIFY_TABLE_INFO, classify_table_info);
15274   mp->context = 0;
15275   mp->table_id = ntohl (table_id);
15276
15277   S;
15278   W;
15279   /* NOTREACHED */
15280   return 0;
15281 }
15282
15283 int
15284 api_classify_session_dump (vat_main_t * vam)
15285 {
15286   unformat_input_t *input = vam->input;
15287   vl_api_classify_session_dump_t *mp;
15288   f64 timeout;
15289
15290   u32 table_id = ~0;
15291   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15292     {
15293       if (unformat (input, "table_id %d", &table_id))
15294         ;
15295       else
15296         break;
15297     }
15298   if (table_id == ~0)
15299     {
15300       errmsg ("missing table id\n");
15301       return -99;
15302     }
15303
15304   /* Construct the API message */
15305   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15306   mp->context = 0;
15307   mp->table_id = ntohl (table_id);
15308   S;
15309
15310   /* Use a control ping for synchronization */
15311   {
15312     vl_api_control_ping_t *mp;
15313     M (CONTROL_PING, control_ping);
15314     S;
15315   }
15316   W;
15317   /* NOTREACHED */
15318   return 0;
15319 }
15320
15321 static void
15322 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15323 {
15324   vat_main_t *vam = &vat_main;
15325
15326   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15327            "src_address %U, vrf_id %d, path_mtu %u, "
15328            "template_interval %u, udp_checksum %d\n",
15329            format_ip4_address, mp->collector_address,
15330            ntohs (mp->collector_port),
15331            format_ip4_address, mp->src_address,
15332            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15333            ntohl (mp->template_interval), mp->udp_checksum);
15334
15335   vam->retval = 0;
15336   vam->result_ready = 1;
15337 }
15338
15339 static void
15340   vl_api_ipfix_exporter_details_t_handler_json
15341   (vl_api_ipfix_exporter_details_t * mp)
15342 {
15343   vat_main_t *vam = &vat_main;
15344   vat_json_node_t node;
15345   struct in_addr collector_address;
15346   struct in_addr src_address;
15347
15348   vat_json_init_object (&node);
15349   clib_memcpy (&collector_address, &mp->collector_address,
15350                sizeof (collector_address));
15351   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15352   vat_json_object_add_uint (&node, "collector_port",
15353                             ntohs (mp->collector_port));
15354   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15355   vat_json_object_add_ip4 (&node, "src_address", src_address);
15356   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15357   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15358   vat_json_object_add_uint (&node, "template_interval",
15359                             ntohl (mp->template_interval));
15360   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15361
15362   vat_json_print (vam->ofp, &node);
15363   vat_json_free (&node);
15364   vam->retval = 0;
15365   vam->result_ready = 1;
15366 }
15367
15368 int
15369 api_ipfix_exporter_dump (vat_main_t * vam)
15370 {
15371   vl_api_ipfix_exporter_dump_t *mp;
15372   f64 timeout;
15373
15374   /* Construct the API message */
15375   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15376   mp->context = 0;
15377
15378   S;
15379   W;
15380   /* NOTREACHED */
15381   return 0;
15382 }
15383
15384 static int
15385 api_ipfix_classify_stream_dump (vat_main_t * vam)
15386 {
15387   vl_api_ipfix_classify_stream_dump_t *mp;
15388   f64 timeout;
15389
15390   /* Construct the API message */
15391   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15392   mp->context = 0;
15393
15394   S;
15395   W;
15396   /* NOTREACHED */
15397   return 0;
15398 }
15399
15400 static void
15401   vl_api_ipfix_classify_stream_details_t_handler
15402   (vl_api_ipfix_classify_stream_details_t * mp)
15403 {
15404   vat_main_t *vam = &vat_main;
15405   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15406            ntohl (mp->domain_id), ntohs (mp->src_port));
15407   vam->retval = 0;
15408   vam->result_ready = 1;
15409 }
15410
15411 static void
15412   vl_api_ipfix_classify_stream_details_t_handler_json
15413   (vl_api_ipfix_classify_stream_details_t * mp)
15414 {
15415   vat_main_t *vam = &vat_main;
15416   vat_json_node_t node;
15417
15418   vat_json_init_object (&node);
15419   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15420   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15421
15422   vat_json_print (vam->ofp, &node);
15423   vat_json_free (&node);
15424   vam->retval = 0;
15425   vam->result_ready = 1;
15426 }
15427
15428 static int
15429 api_ipfix_classify_table_dump (vat_main_t * vam)
15430 {
15431   vl_api_ipfix_classify_table_dump_t *mp;
15432   f64 timeout;
15433
15434   if (!vam->json_output)
15435     {
15436       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15437                "transport_protocol");
15438     }
15439
15440   /* Construct the API message */
15441   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15442
15443   /* send it... */
15444   S;
15445
15446   /* Use a control ping for synchronization */
15447   {
15448     vl_api_control_ping_t *mp;
15449     M (CONTROL_PING, control_ping);
15450     S;
15451   }
15452   W;
15453 }
15454
15455 static void
15456   vl_api_ipfix_classify_table_details_t_handler
15457   (vl_api_ipfix_classify_table_details_t * mp)
15458 {
15459   vat_main_t *vam = &vat_main;
15460   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15461            mp->transport_protocol);
15462 }
15463
15464 static void
15465   vl_api_ipfix_classify_table_details_t_handler_json
15466   (vl_api_ipfix_classify_table_details_t * mp)
15467 {
15468   vat_json_node_t *node = NULL;
15469   vat_main_t *vam = &vat_main;
15470
15471   if (VAT_JSON_ARRAY != vam->json_tree.type)
15472     {
15473       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15474       vat_json_init_array (&vam->json_tree);
15475     }
15476
15477   node = vat_json_array_add (&vam->json_tree);
15478   vat_json_init_object (node);
15479
15480   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15481   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15482   vat_json_object_add_uint (node, "transport_protocol",
15483                             mp->transport_protocol);
15484 }
15485
15486 static int
15487 api_sw_interface_span_enable_disable (vat_main_t * vam)
15488 {
15489   unformat_input_t *i = vam->input;
15490   vl_api_sw_interface_span_enable_disable_t *mp;
15491   f64 timeout;
15492   u32 src_sw_if_index = ~0;
15493   u32 dst_sw_if_index = ~0;
15494   u8 enable = 1;
15495
15496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15497     {
15498       if (unformat (i, "src %U", unformat_sw_if_index, vam, &src_sw_if_index))
15499         ;
15500       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15501         ;
15502       else
15503         if (unformat
15504             (i, "dst %U", unformat_sw_if_index, vam, &dst_sw_if_index))
15505         ;
15506       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15507         ;
15508       else if (unformat (i, "disable"))
15509         enable = 0;
15510       else
15511         break;
15512     }
15513
15514   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15515
15516   mp->sw_if_index_from = htonl (src_sw_if_index);
15517   mp->sw_if_index_to = htonl (dst_sw_if_index);
15518   mp->enable = enable;
15519
15520   S;
15521   W;
15522   /* NOTREACHED */
15523   return 0;
15524 }
15525
15526 static void
15527 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
15528                                             * mp)
15529 {
15530   vat_main_t *vam = &vat_main;
15531
15532   fformat (vam->ofp, "%u => %u\n",
15533            ntohl (mp->sw_if_index_from), ntohl (mp->sw_if_index_to));
15534 }
15535
15536 static void
15537   vl_api_sw_interface_span_details_t_handler_json
15538   (vl_api_sw_interface_span_details_t * mp)
15539 {
15540   vat_main_t *vam = &vat_main;
15541   vat_json_node_t *node = NULL;
15542
15543   if (VAT_JSON_ARRAY != vam->json_tree.type)
15544     {
15545       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15546       vat_json_init_array (&vam->json_tree);
15547     }
15548   node = vat_json_array_add (&vam->json_tree);
15549
15550   vat_json_init_object (node);
15551   vat_json_object_add_uint (node, "src-if-index",
15552                             ntohl (mp->sw_if_index_from));
15553   vat_json_object_add_uint (node, "dst-if-index", ntohl (mp->sw_if_index_to));
15554 }
15555
15556 static int
15557 api_sw_interface_span_dump (vat_main_t * vam)
15558 {
15559   vl_api_sw_interface_span_dump_t *mp;
15560   f64 timeout;
15561
15562   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
15563   S;
15564
15565   /* Use a control ping for synchronization */
15566   {
15567     vl_api_control_ping_t *mp;
15568     M (CONTROL_PING, control_ping);
15569     S;
15570   }
15571   W;
15572 }
15573
15574 int
15575 api_pg_create_interface (vat_main_t * vam)
15576 {
15577   unformat_input_t *input = vam->input;
15578   vl_api_pg_create_interface_t *mp;
15579   f64 timeout;
15580
15581   u32 if_id = ~0;
15582   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15583     {
15584       if (unformat (input, "if_id %d", &if_id))
15585         ;
15586       else
15587         break;
15588     }
15589   if (if_id == ~0)
15590     {
15591       errmsg ("missing pg interface index\n");
15592       return -99;
15593     }
15594
15595   /* Construct the API message */
15596   M (PG_CREATE_INTERFACE, pg_create_interface);
15597   mp->context = 0;
15598   mp->interface_id = ntohl (if_id);
15599
15600   S;
15601   W;
15602   /* NOTREACHED */
15603   return 0;
15604 }
15605
15606 int
15607 api_pg_capture (vat_main_t * vam)
15608 {
15609   unformat_input_t *input = vam->input;
15610   vl_api_pg_capture_t *mp;
15611   f64 timeout;
15612
15613   u32 if_id = ~0;
15614   u8 enable = 1;
15615   u32 count = 1;
15616   u8 pcap_file_set = 0;
15617   u8 *pcap_file = 0;
15618   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15619     {
15620       if (unformat (input, "if_id %d", &if_id))
15621         ;
15622       else if (unformat (input, "pcap %s", &pcap_file))
15623         pcap_file_set = 1;
15624       else if (unformat (input, "count %d", &count))
15625         ;
15626       else if (unformat (input, "disable"))
15627         enable = 0;
15628       else
15629         break;
15630     }
15631   if (if_id == ~0)
15632     {
15633       errmsg ("missing pg interface index\n");
15634       return -99;
15635     }
15636   if (pcap_file_set > 0)
15637     {
15638       if (vec_len (pcap_file) > 255)
15639         {
15640           errmsg ("pcap file name is too long\n");
15641           return -99;
15642         }
15643     }
15644
15645   u32 name_len = vec_len (pcap_file);
15646   /* Construct the API message */
15647   M (PG_CAPTURE, pg_capture);
15648   mp->context = 0;
15649   mp->interface_id = ntohl (if_id);
15650   mp->is_enabled = enable;
15651   mp->count = ntohl (count);
15652   mp->pcap_name_length = ntohl (name_len);
15653   if (pcap_file_set != 0)
15654     {
15655       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15656     }
15657   vec_free (pcap_file);
15658
15659   S;
15660   W;
15661   /* NOTREACHED */
15662   return 0;
15663 }
15664
15665 int
15666 api_pg_enable_disable (vat_main_t * vam)
15667 {
15668   unformat_input_t *input = vam->input;
15669   vl_api_pg_enable_disable_t *mp;
15670   f64 timeout;
15671
15672   u8 enable = 1;
15673   u8 stream_name_set = 0;
15674   u8 *stream_name = 0;
15675   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15676     {
15677       if (unformat (input, "stream %s", &stream_name))
15678         stream_name_set = 1;
15679       else if (unformat (input, "disable"))
15680         enable = 0;
15681       else
15682         break;
15683     }
15684
15685   if (stream_name_set > 0)
15686     {
15687       if (vec_len (stream_name) > 255)
15688         {
15689           errmsg ("stream name too long\n");
15690           return -99;
15691         }
15692     }
15693
15694   u32 name_len = vec_len (stream_name);
15695   /* Construct the API message */
15696   M (PG_ENABLE_DISABLE, pg_enable_disable);
15697   mp->context = 0;
15698   mp->is_enabled = enable;
15699   if (stream_name_set != 0)
15700     {
15701       mp->stream_name_length = ntohl (name_len);
15702       clib_memcpy (mp->stream_name, stream_name, name_len);
15703     }
15704   vec_free (stream_name);
15705
15706   S;
15707   W;
15708   /* NOTREACHED */
15709   return 0;
15710 }
15711
15712 int
15713 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15714 {
15715   unformat_input_t *input = vam->input;
15716   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15717   f64 timeout;
15718
15719   u16 *low_ports = 0;
15720   u16 *high_ports = 0;
15721   u16 this_low;
15722   u16 this_hi;
15723   ip4_address_t ip4_addr;
15724   ip6_address_t ip6_addr;
15725   u32 length;
15726   u32 tmp, tmp2;
15727   u8 prefix_set = 0;
15728   u32 vrf_id = ~0;
15729   u8 is_add = 1;
15730   u8 is_ipv6 = 0;
15731
15732   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15733     {
15734       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15735         {
15736           prefix_set = 1;
15737         }
15738       else
15739         if (unformat
15740             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15741         {
15742           prefix_set = 1;
15743           is_ipv6 = 1;
15744         }
15745       else if (unformat (input, "vrf %d", &vrf_id))
15746         ;
15747       else if (unformat (input, "del"))
15748         is_add = 0;
15749       else if (unformat (input, "port %d", &tmp))
15750         {
15751           if (tmp == 0 || tmp > 65535)
15752             {
15753               errmsg ("port %d out of range", tmp);
15754               return -99;
15755             }
15756           this_low = tmp;
15757           this_hi = this_low + 1;
15758           vec_add1 (low_ports, this_low);
15759           vec_add1 (high_ports, this_hi);
15760         }
15761       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15762         {
15763           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15764             {
15765               errmsg ("incorrect range parameters\n");
15766               return -99;
15767             }
15768           this_low = tmp;
15769           /* Note: in debug CLI +1 is added to high before
15770              passing to real fn that does "the work"
15771              (ip_source_and_port_range_check_add_del).
15772              This fn is a wrapper around the binary API fn a
15773              control plane will call, which expects this increment
15774              to have occurred. Hence letting the binary API control
15775              plane fn do the increment for consistency between VAT
15776              and other control planes.
15777            */
15778           this_hi = tmp2;
15779           vec_add1 (low_ports, this_low);
15780           vec_add1 (high_ports, this_hi);
15781         }
15782       else
15783         break;
15784     }
15785
15786   if (prefix_set == 0)
15787     {
15788       errmsg ("<address>/<mask> not specified\n");
15789       return -99;
15790     }
15791
15792   if (vrf_id == ~0)
15793     {
15794       errmsg ("VRF ID required, not specified\n");
15795       return -99;
15796     }
15797
15798   if (vrf_id == 0)
15799     {
15800       errmsg
15801         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15802       return -99;
15803     }
15804
15805   if (vec_len (low_ports) == 0)
15806     {
15807       errmsg ("At least one port or port range required\n");
15808       return -99;
15809     }
15810
15811   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15812      ip_source_and_port_range_check_add_del);
15813
15814   mp->is_add = is_add;
15815
15816   if (is_ipv6)
15817     {
15818       mp->is_ipv6 = 1;
15819       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15820     }
15821   else
15822     {
15823       mp->is_ipv6 = 0;
15824       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15825     }
15826
15827   mp->mask_length = length;
15828   mp->number_of_ranges = vec_len (low_ports);
15829
15830   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15831   vec_free (low_ports);
15832
15833   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15834   vec_free (high_ports);
15835
15836   mp->vrf_id = ntohl (vrf_id);
15837
15838   S;
15839   W;
15840   /* NOTREACHED */
15841   return 0;
15842 }
15843
15844 int
15845 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15846 {
15847   unformat_input_t *input = vam->input;
15848   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15849   f64 timeout;
15850   u32 sw_if_index = ~0;
15851   int vrf_set = 0;
15852   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15853   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15854   u8 is_add = 1;
15855
15856   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15857     {
15858       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15859         ;
15860       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15861         ;
15862       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15863         vrf_set = 1;
15864       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15865         vrf_set = 1;
15866       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15867         vrf_set = 1;
15868       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15869         vrf_set = 1;
15870       else if (unformat (input, "del"))
15871         is_add = 0;
15872       else
15873         break;
15874     }
15875
15876   if (sw_if_index == ~0)
15877     {
15878       errmsg ("Interface required but not specified\n");
15879       return -99;
15880     }
15881
15882   if (vrf_set == 0)
15883     {
15884       errmsg ("VRF ID required but not specified\n");
15885       return -99;
15886     }
15887
15888   if (tcp_out_vrf_id == 0
15889       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15890     {
15891       errmsg
15892         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15893       return -99;
15894     }
15895
15896   /* Construct the API message */
15897   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15898      ip_source_and_port_range_check_interface_add_del);
15899
15900   mp->sw_if_index = ntohl (sw_if_index);
15901   mp->is_add = is_add;
15902   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15903   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15904   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15905   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15906
15907   /* send it... */
15908   S;
15909
15910   /* Wait for a reply... */
15911   W;
15912 }
15913
15914 static int
15915 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15916 {
15917   unformat_input_t *i = vam->input;
15918   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15919   f64 timeout;
15920   u32 local_sa_id = 0;
15921   u32 remote_sa_id = 0;
15922   ip4_address_t src_address;
15923   ip4_address_t dst_address;
15924   u8 is_add = 1;
15925
15926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15927     {
15928       if (unformat (i, "local_sa %d", &local_sa_id))
15929         ;
15930       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15931         ;
15932       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15933         ;
15934       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15935         ;
15936       else if (unformat (i, "del"))
15937         is_add = 0;
15938       else
15939         {
15940           clib_warning ("parse error '%U'", format_unformat_error, i);
15941           return -99;
15942         }
15943     }
15944
15945   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15946
15947   mp->local_sa_id = ntohl (local_sa_id);
15948   mp->remote_sa_id = ntohl (remote_sa_id);
15949   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15950   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15951   mp->is_add = is_add;
15952
15953   S;
15954   W;
15955   /* NOTREACHED */
15956   return 0;
15957 }
15958
15959 static int
15960 api_punt (vat_main_t * vam)
15961 {
15962   unformat_input_t *i = vam->input;
15963   vl_api_punt_t *mp;
15964   f64 timeout;
15965   u32 ipv = ~0;
15966   u32 protocol = ~0;
15967   u32 port = ~0;
15968   int is_add = 1;
15969
15970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15971     {
15972       if (unformat (i, "ip %d", &ipv))
15973         ;
15974       else if (unformat (i, "protocol %d", &protocol))
15975         ;
15976       else if (unformat (i, "port %d", &port))
15977         ;
15978       else if (unformat (i, "del"))
15979         is_add = 0;
15980       else
15981         {
15982           clib_warning ("parse error '%U'", format_unformat_error, i);
15983           return -99;
15984         }
15985     }
15986
15987   M (PUNT, punt);
15988
15989   mp->is_add = (u8) is_add;
15990   mp->ipv = (u8) ipv;
15991   mp->l4_protocol = (u8) protocol;
15992   mp->l4_port = htons ((u16) port);
15993
15994   S;
15995   W;
15996   /* NOTREACHED */
15997   return 0;
15998 }
15999
16000 static void vl_api_ipsec_gre_tunnel_details_t_handler
16001   (vl_api_ipsec_gre_tunnel_details_t * mp)
16002 {
16003   vat_main_t *vam = &vat_main;
16004
16005   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
16006            ntohl (mp->sw_if_index),
16007            format_ip4_address, &mp->src_address,
16008            format_ip4_address, &mp->dst_address,
16009            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16010 }
16011
16012 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16013   (vl_api_ipsec_gre_tunnel_details_t * mp)
16014 {
16015   vat_main_t *vam = &vat_main;
16016   vat_json_node_t *node = NULL;
16017   struct in_addr ip4;
16018
16019   if (VAT_JSON_ARRAY != vam->json_tree.type)
16020     {
16021       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16022       vat_json_init_array (&vam->json_tree);
16023     }
16024   node = vat_json_array_add (&vam->json_tree);
16025
16026   vat_json_init_object (node);
16027   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16028   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16029   vat_json_object_add_ip4 (node, "src_address", ip4);
16030   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16031   vat_json_object_add_ip4 (node, "dst_address", ip4);
16032   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16033   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16034 }
16035
16036 static int
16037 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16038 {
16039   unformat_input_t *i = vam->input;
16040   vl_api_ipsec_gre_tunnel_dump_t *mp;
16041   f64 timeout;
16042   u32 sw_if_index;
16043   u8 sw_if_index_set = 0;
16044
16045   /* Parse args required to build the message */
16046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16047     {
16048       if (unformat (i, "sw_if_index %d", &sw_if_index))
16049         sw_if_index_set = 1;
16050       else
16051         break;
16052     }
16053
16054   if (sw_if_index_set == 0)
16055     {
16056       sw_if_index = ~0;
16057     }
16058
16059   if (!vam->json_output)
16060     {
16061       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
16062                "sw_if_index", "src_address", "dst_address",
16063                "local_sa_id", "remote_sa_id");
16064     }
16065
16066   /* Get list of gre-tunnel interfaces */
16067   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16068
16069   mp->sw_if_index = htonl (sw_if_index);
16070
16071   S;
16072
16073   /* Use a control ping for synchronization */
16074   {
16075     vl_api_control_ping_t *mp;
16076     M (CONTROL_PING, control_ping);
16077     S;
16078   }
16079   W;
16080 }
16081
16082 static int
16083 api_delete_subif (vat_main_t * vam)
16084 {
16085   unformat_input_t *i = vam->input;
16086   vl_api_delete_subif_t *mp;
16087   f64 timeout;
16088   u32 sw_if_index = ~0;
16089
16090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16091     {
16092       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16093         ;
16094       if (unformat (i, "sw_if_index %d", &sw_if_index))
16095         ;
16096       else
16097         break;
16098     }
16099
16100   if (sw_if_index == ~0)
16101     {
16102       errmsg ("missing sw_if_index\n");
16103       return -99;
16104     }
16105
16106   /* Construct the API message */
16107   M (DELETE_SUBIF, delete_subif);
16108   mp->sw_if_index = ntohl (sw_if_index);
16109
16110   S;
16111   W;
16112 }
16113
16114 #define foreach_pbb_vtr_op      \
16115 _("disable",  L2_VTR_DISABLED)  \
16116 _("pop",  L2_VTR_POP_2)         \
16117 _("push",  L2_VTR_PUSH_2)
16118
16119 static int
16120 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16121 {
16122   unformat_input_t *i = vam->input;
16123   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16124   f64 timeout;
16125   u32 sw_if_index = ~0, vtr_op = ~0;
16126   u16 outer_tag = ~0;
16127   u8 dmac[6], smac[6];
16128   u8 dmac_set = 0, smac_set = 0;
16129   u16 vlanid = 0;
16130   u32 sid = ~0;
16131   u32 tmp;
16132
16133   /* Shut up coverity */
16134   memset (dmac, 0, sizeof (dmac));
16135   memset (smac, 0, sizeof (smac));
16136
16137   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16138     {
16139       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16140         ;
16141       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16142         ;
16143       else if (unformat (i, "vtr_op %d", &vtr_op))
16144         ;
16145 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16146       foreach_pbb_vtr_op
16147 #undef _
16148         else if (unformat (i, "translate_pbb_stag"))
16149         {
16150           if (unformat (i, "%d", &tmp))
16151             {
16152               vtr_op = L2_VTR_TRANSLATE_2_1;
16153               outer_tag = tmp;
16154             }
16155           else
16156             {
16157               errmsg
16158                 ("translate_pbb_stag operation requires outer tag definition\n");
16159               return -99;
16160             }
16161         }
16162       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16163         dmac_set++;
16164       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16165         smac_set++;
16166       else if (unformat (i, "sid %d", &sid))
16167         ;
16168       else if (unformat (i, "vlanid %d", &tmp))
16169         vlanid = tmp;
16170       else
16171         {
16172           clib_warning ("parse error '%U'", format_unformat_error, i);
16173           return -99;
16174         }
16175     }
16176
16177   if ((sw_if_index == ~0) || (vtr_op == ~0))
16178     {
16179       errmsg ("missing sw_if_index or vtr operation\n");
16180       return -99;
16181     }
16182   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16183       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16184     {
16185       errmsg
16186         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
16187       return -99;
16188     }
16189
16190   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16191   mp->sw_if_index = ntohl (sw_if_index);
16192   mp->vtr_op = ntohl (vtr_op);
16193   mp->outer_tag = ntohs (outer_tag);
16194   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16195   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16196   mp->b_vlanid = ntohs (vlanid);
16197   mp->i_sid = ntohl (sid);
16198
16199   S;
16200   W;
16201   /* NOTREACHED */
16202   return 0;
16203 }
16204
16205 static int
16206 api_flow_classify_set_interface (vat_main_t * vam)
16207 {
16208   unformat_input_t *i = vam->input;
16209   vl_api_flow_classify_set_interface_t *mp;
16210   f64 timeout;
16211   u32 sw_if_index;
16212   int sw_if_index_set;
16213   u32 ip4_table_index = ~0;
16214   u32 ip6_table_index = ~0;
16215   u8 is_add = 1;
16216
16217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16218     {
16219       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16220         sw_if_index_set = 1;
16221       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16222         sw_if_index_set = 1;
16223       else if (unformat (i, "del"))
16224         is_add = 0;
16225       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16226         ;
16227       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16228         ;
16229       else
16230         {
16231           clib_warning ("parse error '%U'", format_unformat_error, i);
16232           return -99;
16233         }
16234     }
16235
16236   if (sw_if_index_set == 0)
16237     {
16238       errmsg ("missing interface name or sw_if_index\n");
16239       return -99;
16240     }
16241
16242   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16243
16244   mp->sw_if_index = ntohl (sw_if_index);
16245   mp->ip4_table_index = ntohl (ip4_table_index);
16246   mp->ip6_table_index = ntohl (ip6_table_index);
16247   mp->is_add = is_add;
16248
16249   S;
16250   W;
16251   /* NOTREACHED */
16252   return 0;
16253 }
16254
16255 static int
16256 api_flow_classify_dump (vat_main_t * vam)
16257 {
16258   unformat_input_t *i = vam->input;
16259   vl_api_flow_classify_dump_t *mp;
16260   f64 timeout = ~0;
16261   u8 type = FLOW_CLASSIFY_N_TABLES;
16262
16263   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16264     ;
16265   else
16266     {
16267       errmsg ("classify table type must be specified\n");
16268       return -99;
16269     }
16270
16271   if (!vam->json_output)
16272     {
16273       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
16274     }
16275
16276   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16277   mp->type = type;
16278   /* send it... */
16279   S;
16280
16281   /* Use a control ping for synchronization */
16282   {
16283     vl_api_control_ping_t *mp;
16284     M (CONTROL_PING, control_ping);
16285     S;
16286   }
16287   /* Wait for a reply... */
16288   W;
16289
16290   /* NOTREACHED */
16291   return 0;
16292 }
16293
16294 static int
16295 api_feature_enable_disable (vat_main_t * vam)
16296 {
16297   unformat_input_t *i = vam->input;
16298   vl_api_feature_enable_disable_t *mp;
16299   f64 timeout;
16300   u8 *arc_name = 0;
16301   u8 *feature_name = 0;
16302   u32 sw_if_index = ~0;
16303   u8 enable = 1;
16304
16305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16306     {
16307       if (unformat (i, "arc_name %s", &arc_name))
16308         ;
16309       else if (unformat (i, "feature_name %s", &feature_name))
16310         ;
16311       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16312         ;
16313       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16314         ;
16315       else if (unformat (i, "disable"))
16316         enable = 0;
16317       else
16318         break;
16319     }
16320
16321   if (arc_name == 0)
16322     {
16323       errmsg ("missing arc name\n");
16324       return -99;
16325     }
16326   if (vec_len (arc_name) > 63)
16327     {
16328       errmsg ("arc name too long\n");
16329     }
16330
16331   if (feature_name == 0)
16332     {
16333       errmsg ("missing feature name\n");
16334       return -99;
16335     }
16336   if (vec_len (feature_name) > 63)
16337     {
16338       errmsg ("feature name too long\n");
16339     }
16340
16341   if (sw_if_index == ~0)
16342     {
16343       errmsg ("missing interface name or sw_if_index\n");
16344       return -99;
16345     }
16346
16347   /* Construct the API message */
16348   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16349   mp->sw_if_index = ntohl (sw_if_index);
16350   mp->enable = enable;
16351   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16352   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16353   vec_free (arc_name);
16354   vec_free (feature_name);
16355
16356   S;
16357   W;
16358 }
16359
16360 static int
16361 q_or_quit (vat_main_t * vam)
16362 {
16363   longjmp (vam->jump_buf, 1);
16364   return 0;                     /* not so much */
16365 }
16366
16367 static int
16368 q (vat_main_t * vam)
16369 {
16370   return q_or_quit (vam);
16371 }
16372
16373 static int
16374 quit (vat_main_t * vam)
16375 {
16376   return q_or_quit (vam);
16377 }
16378
16379 static int
16380 comment (vat_main_t * vam)
16381 {
16382   return 0;
16383 }
16384
16385 static int
16386 cmd_cmp (void *a1, void *a2)
16387 {
16388   u8 **c1 = a1;
16389   u8 **c2 = a2;
16390
16391   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
16392 }
16393
16394 static int
16395 help (vat_main_t * vam)
16396 {
16397   u8 **cmds = 0;
16398   u8 *name = 0;
16399   hash_pair_t *p;
16400   unformat_input_t *i = vam->input;
16401   int j;
16402
16403   if (unformat (i, "%s", &name))
16404     {
16405       uword *hs;
16406
16407       vec_add1 (name, 0);
16408
16409       hs = hash_get_mem (vam->help_by_name, name);
16410       if (hs)
16411         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
16412       else
16413         fformat (vam->ofp, "No such msg / command '%s'\n", name);
16414       vec_free (name);
16415       return 0;
16416     }
16417
16418   fformat (vam->ofp, "Help is available for the following:\n");
16419
16420     /* *INDENT-OFF* */
16421     hash_foreach_pair (p, vam->function_by_name,
16422     ({
16423       vec_add1 (cmds, (u8 *)(p->key));
16424     }));
16425     /* *INDENT-ON* */
16426
16427   vec_sort_with_function (cmds, cmd_cmp);
16428
16429   for (j = 0; j < vec_len (cmds); j++)
16430     fformat (vam->ofp, "%s\n", cmds[j]);
16431
16432   vec_free (cmds);
16433   return 0;
16434 }
16435
16436 static int
16437 set (vat_main_t * vam)
16438 {
16439   u8 *name = 0, *value = 0;
16440   unformat_input_t *i = vam->input;
16441
16442   if (unformat (i, "%s", &name))
16443     {
16444       /* The input buffer is a vector, not a string. */
16445       value = vec_dup (i->buffer);
16446       vec_delete (value, i->index, 0);
16447       /* Almost certainly has a trailing newline */
16448       if (value[vec_len (value) - 1] == '\n')
16449         value[vec_len (value) - 1] = 0;
16450       /* Make sure it's a proper string, one way or the other */
16451       vec_add1 (value, 0);
16452       (void) clib_macro_set_value (&vam->macro_main,
16453                                    (char *) name, (char *) value);
16454     }
16455   else
16456     errmsg ("usage: set <name> <value>\n");
16457
16458   vec_free (name);
16459   vec_free (value);
16460   return 0;
16461 }
16462
16463 static int
16464 unset (vat_main_t * vam)
16465 {
16466   u8 *name = 0;
16467
16468   if (unformat (vam->input, "%s", &name))
16469     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
16470       errmsg ("unset: %s wasn't set\n", name);
16471   vec_free (name);
16472   return 0;
16473 }
16474
16475 typedef struct
16476 {
16477   u8 *name;
16478   u8 *value;
16479 } macro_sort_t;
16480
16481
16482 static int
16483 macro_sort_cmp (void *a1, void *a2)
16484 {
16485   macro_sort_t *s1 = a1;
16486   macro_sort_t *s2 = a2;
16487
16488   return strcmp ((char *) (s1->name), (char *) (s2->name));
16489 }
16490
16491 static int
16492 dump_macro_table (vat_main_t * vam)
16493 {
16494   macro_sort_t *sort_me = 0, *sm;
16495   int i;
16496   hash_pair_t *p;
16497
16498     /* *INDENT-OFF* */
16499     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
16500     ({
16501       vec_add2 (sort_me, sm, 1);
16502       sm->name = (u8 *)(p->key);
16503       sm->value = (u8 *) (p->value[0]);
16504     }));
16505     /* *INDENT-ON* */
16506
16507   vec_sort_with_function (sort_me, macro_sort_cmp);
16508
16509   if (vec_len (sort_me))
16510     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
16511   else
16512     fformat (vam->ofp, "The macro table is empty...\n");
16513
16514   for (i = 0; i < vec_len (sort_me); i++)
16515     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
16516   return 0;
16517 }
16518
16519 static int
16520 dump_node_table (vat_main_t * vam)
16521 {
16522   int i, j;
16523   vlib_node_t *node, *next_node;
16524
16525   if (vec_len (vam->graph_nodes) == 0)
16526     {
16527       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16528       return 0;
16529     }
16530
16531   for (i = 0; i < vec_len (vam->graph_nodes); i++)
16532     {
16533       node = vam->graph_nodes[i];
16534       fformat (vam->ofp, "[%d] %s\n", i, node->name);
16535       for (j = 0; j < vec_len (node->next_nodes); j++)
16536         {
16537           if (node->next_nodes[j] != ~0)
16538             {
16539               next_node = vam->graph_nodes[node->next_nodes[j]];
16540               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16541             }
16542         }
16543     }
16544   return 0;
16545 }
16546
16547 static int
16548 value_sort_cmp (void *a1, void *a2)
16549 {
16550   name_sort_t *n1 = a1;
16551   name_sort_t *n2 = a2;
16552
16553   if (n1->value < n2->value)
16554     return -1;
16555   if (n1->value > n2->value)
16556     return 1;
16557   return 0;
16558 }
16559
16560
16561 static int
16562 dump_msg_api_table (vat_main_t * vam)
16563 {
16564   api_main_t *am = &api_main;
16565   name_sort_t *nses = 0, *ns;
16566   hash_pair_t *hp;
16567   int i;
16568
16569   /* *INDENT-OFF* */
16570   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
16571   ({
16572     vec_add2 (nses, ns, 1);
16573     ns->name = (u8 *)(hp->key);
16574     ns->value = (u32) hp->value[0];
16575   }));
16576   /* *INDENT-ON* */
16577
16578   vec_sort_with_function (nses, value_sort_cmp);
16579
16580   for (i = 0; i < vec_len (nses); i++)
16581     fformat (vam->ofp, " [%d]: %s\n", nses[i].value, nses[i].name);
16582   vec_free (nses);
16583   return 0;
16584 }
16585
16586 static int
16587 get_msg_id (vat_main_t * vam)
16588 {
16589   u8 *name_and_crc;
16590   u32 message_index;
16591
16592   if (unformat (vam->input, "%s", &name_and_crc))
16593     {
16594       message_index = vl_api_get_msg_index (name_and_crc);
16595       if (message_index == ~0)
16596         {
16597           fformat (vam->ofp, " '%s' not found\n", name_and_crc);
16598           return 0;
16599         }
16600       fformat (vam->ofp, " '%s' has message index %d\n",
16601                name_and_crc, message_index);
16602       return 0;
16603     }
16604   errmsg ("name_and_crc required...\n");
16605   return 0;
16606 }
16607
16608 static int
16609 search_node_table (vat_main_t * vam)
16610 {
16611   unformat_input_t *line_input = vam->input;
16612   u8 *node_to_find;
16613   int j;
16614   vlib_node_t *node, *next_node;
16615   uword *p;
16616
16617   if (vam->graph_node_index_by_name == 0)
16618     {
16619       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16620       return 0;
16621     }
16622
16623   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16624     {
16625       if (unformat (line_input, "%s", &node_to_find))
16626         {
16627           vec_add1 (node_to_find, 0);
16628           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
16629           if (p == 0)
16630             {
16631               fformat (vam->ofp, "%s not found...\n", node_to_find);
16632               goto out;
16633             }
16634           node = vam->graph_nodes[p[0]];
16635           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
16636           for (j = 0; j < vec_len (node->next_nodes); j++)
16637             {
16638               if (node->next_nodes[j] != ~0)
16639                 {
16640                   next_node = vam->graph_nodes[node->next_nodes[j]];
16641                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16642                 }
16643             }
16644         }
16645
16646       else
16647         {
16648           clib_warning ("parse error '%U'", format_unformat_error,
16649                         line_input);
16650           return -99;
16651         }
16652
16653     out:
16654       vec_free (node_to_find);
16655
16656     }
16657
16658   return 0;
16659 }
16660
16661
16662 static int
16663 script (vat_main_t * vam)
16664 {
16665   u8 *s = 0;
16666   char *save_current_file;
16667   unformat_input_t save_input;
16668   jmp_buf save_jump_buf;
16669   u32 save_line_number;
16670
16671   FILE *new_fp, *save_ifp;
16672
16673   if (unformat (vam->input, "%s", &s))
16674     {
16675       new_fp = fopen ((char *) s, "r");
16676       if (new_fp == 0)
16677         {
16678           errmsg ("Couldn't open script file %s\n", s);
16679           vec_free (s);
16680           return -99;
16681         }
16682     }
16683   else
16684     {
16685       errmsg ("Missing script name\n");
16686       return -99;
16687     }
16688
16689   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
16690   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
16691   save_ifp = vam->ifp;
16692   save_line_number = vam->input_line_number;
16693   save_current_file = (char *) vam->current_file;
16694
16695   vam->input_line_number = 0;
16696   vam->ifp = new_fp;
16697   vam->current_file = s;
16698   do_one_file (vam);
16699
16700   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
16701   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
16702   vam->ifp = save_ifp;
16703   vam->input_line_number = save_line_number;
16704   vam->current_file = (u8 *) save_current_file;
16705   vec_free (s);
16706
16707   return 0;
16708 }
16709
16710 static int
16711 echo (vat_main_t * vam)
16712 {
16713   fformat (vam->ofp, "%v", vam->input->buffer);
16714   return 0;
16715 }
16716
16717 /* List of API message constructors, CLI names map to api_xxx */
16718 #define foreach_vpe_api_msg                                             \
16719 _(create_loopback,"[mac <mac-addr>]")                                   \
16720 _(sw_interface_dump,"")                                                 \
16721 _(sw_interface_set_flags,                                               \
16722   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
16723 _(sw_interface_add_del_address,                                         \
16724   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
16725 _(sw_interface_set_table,                                               \
16726   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
16727 _(sw_interface_set_mpls_enable,                                                \
16728   "<intfc> | sw_if_index [disable | dis]")                                \
16729 _(sw_interface_set_vpath,                                               \
16730   "<intfc> | sw_if_index <id> enable | disable")                        \
16731 _(sw_interface_set_l2_xconnect,                                         \
16732   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16733   "enable | disable")                                                   \
16734 _(sw_interface_set_l2_bridge,                                           \
16735   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16736   "[shg <split-horizon-group>] [bvi]\n"                                 \
16737   "enable | disable")                                                   \
16738 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16739   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16740   "profile <profile-id>\n")                                             \
16741 _(sw_interface_set_dpdk_hqos_subport,                                   \
16742   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16743   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16744 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16745   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16746 _(bridge_domain_add_del,                                                \
16747   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16748 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16749 _(l2fib_add_del,                                                        \
16750   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16751 _(l2_flags,                                                             \
16752   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16753 _(bridge_flags,                                                         \
16754   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16755 _(tap_connect,                                                          \
16756   "tapname <name> mac <mac-addr> | random-mac")                         \
16757 _(tap_modify,                                                           \
16758   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16759 _(tap_delete,                                                           \
16760   "<vpp-if-name> | sw_if_index <id>")                                   \
16761 _(sw_interface_tap_dump, "")                                            \
16762 _(ip_add_del_route,                                                     \
16763   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
16764   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16765   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16766   "[multipath] [count <n>]")                                            \
16767 _(mpls_route_add_del,                                                   \
16768   "<label> <eos> via <addr> [table-id <n>]\n"                           \
16769   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16770   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16771   "[multipath] [count <n>]")                                            \
16772 _(mpls_ip_bind_unbind,                                                  \
16773   "<label> <addr/len>")                                                 \
16774 _(proxy_arp_add_del,                                                    \
16775   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16776 _(proxy_arp_intfc_enable_disable,                                       \
16777   "<intfc> | sw_if_index <id> enable | disable")                        \
16778 _(mpls_add_del_encap,                                                   \
16779   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
16780 _(sw_interface_set_unnumbered,                                          \
16781   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16782 _(ip_neighbor_add_del,                                                  \
16783   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16784   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16785 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16786 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16787 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16788   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16789   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16790   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16791 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16792 _(reset_fib, "vrf <n> [ipv6]")                                          \
16793 _(dhcp_proxy_config,                                                    \
16794   "svr <v46-address> src <v46-address>\n"                               \
16795    "insert-cid <n> [del]")                                              \
16796 _(dhcp_proxy_config_2,                                                  \
16797   "svr <v46-address> src <v46-address>\n"                               \
16798    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16799 _(dhcp_proxy_set_vss,                                                   \
16800   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16801 _(dhcp_client_config,                                                   \
16802   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16803 _(set_ip_flow_hash,                                                     \
16804   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16805 _(sw_interface_ip6_enable_disable,                                      \
16806   "<intfc> | sw_if_index <id> enable | disable")                        \
16807 _(sw_interface_ip6_set_link_local_address,                              \
16808   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16809 _(sw_interface_ip6nd_ra_prefix,                                         \
16810   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16811   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16812   "[nolink] [isno]")                                                    \
16813 _(sw_interface_ip6nd_ra_config,                                         \
16814   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16815   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16816   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16817 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16818 _(l2_patch_add_del,                                                     \
16819   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16820   "enable | disable")                                                   \
16821 _(mpls_ethernet_add_del_tunnel,                                         \
16822   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
16823   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
16824 _(mpls_ethernet_add_del_tunnel_2,                                       \
16825   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
16826   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
16827 _(sr_tunnel_add_del,                                                    \
16828   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16829   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16830   "[policy <policy_name>]")                                             \
16831 _(sr_policy_add_del,                                                    \
16832   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16833 _(sr_multicast_map_add_del,                                             \
16834   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16835 _(classify_add_del_table,                                               \
16836   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16837   " [del] mask <mask-value>\n"                                          \
16838   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
16839   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
16840 _(classify_add_del_session,                                             \
16841   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16842   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16843   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
16844   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
16845 _(classify_set_interface_ip_table,                                      \
16846   "<intfc> | sw_if_index <nn> table <nn>")                              \
16847 _(classify_set_interface_l2_tables,                                     \
16848   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16849   "  [other-table <nn>]")                                               \
16850 _(get_node_index, "node <node-name")                                    \
16851 _(add_node_next, "node <node-name> next <next-node-name>")              \
16852 _(l2tpv3_create_tunnel,                                                 \
16853   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16854   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16855   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16856 _(l2tpv3_set_tunnel_cookies,                                            \
16857   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16858   "[new_remote_cookie <nn>]\n")                                         \
16859 _(l2tpv3_interface_enable_disable,                                      \
16860   "<intfc> | sw_if_index <nn> enable | disable")                        \
16861 _(l2tpv3_set_lookup_key,                                                \
16862   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16863 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16864 _(vxlan_add_del_tunnel,                                                 \
16865   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
16866   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
16867   "vni <vni> [encap-vrf-id <nn>] [decap-next l2|ip4|ip6] [del]")        \
16868 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16869 _(gre_add_del_tunnel,                                                   \
16870   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16871 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16872 _(l2_fib_clear_table, "")                                               \
16873 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16874 _(l2_interface_vlan_tag_rewrite,                                        \
16875   "<intfc> | sw_if_index <nn> \n"                                       \
16876   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
16877   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
16878 _(create_vhost_user_if,                                                 \
16879         "socket <filename> [server] [renumber <dev_instance>] "         \
16880         "[mac <mac_address>]")                                          \
16881 _(modify_vhost_user_if,                                                 \
16882         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
16883         "[server] [renumber <dev_instance>]")                           \
16884 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
16885 _(sw_interface_vhost_user_dump, "")                                     \
16886 _(show_version, "")                                                     \
16887 _(vxlan_gpe_add_del_tunnel,                                             \
16888   "local <addr> remote <addr> vni <nn>\n"                               \
16889     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
16890   "[next-ethernet] [next-nsh]\n")                                       \
16891 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
16892 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
16893 _(interface_name_renumber,                                              \
16894   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
16895 _(input_acl_set_interface,                                              \
16896   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16897   "  [l2-table <nn>] [del]")                                            \
16898 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
16899 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
16900 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
16901 _(ip_dump, "ipv4 | ipv6")                                               \
16902 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
16903 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
16904   "  spid_id <n> ")                                                     \
16905 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
16906   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
16907   "  integ_alg <alg> integ_key <hex>")                                  \
16908 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
16909   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
16910   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
16911   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
16912 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
16913 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
16914 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
16915   "(auth_data 0x<data> | auth_data <data>)")                            \
16916 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
16917   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
16918 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16919   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16920   "(local|remote)")                                                     \
16921 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16922 _(delete_loopback,"sw_if_index <nn>")                                   \
16923 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16924 _(map_add_domain,                                                       \
16925   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16926   "ip6-src <ip6addr> "                                                  \
16927   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16928 _(map_del_domain, "index <n>")                                          \
16929 _(map_add_del_rule,                                                     \
16930   "index <n> psid <n> dst <ip6addr> [del]")                             \
16931 _(map_domain_dump, "")                                                  \
16932 _(map_rule_dump, "index <map-domain>")                                  \
16933 _(want_interface_events,  "enable|disable")                             \
16934 _(want_stats,"enable|disable")                                          \
16935 _(get_first_msg_id, "client <name>")                                    \
16936 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16937 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16938   "fib-id <nn> [ip4][ip6][default]")                                    \
16939 _(get_node_graph, " ")                                                  \
16940 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16941 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16942 _(ioam_disable, "")                                                \
16943 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16944                             " sw_if_index <sw_if_index> p <priority> "  \
16945                             "w <weight>] [del]")                        \
16946 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16947                         "iface <intf> | sw_if_index <sw_if_index> "     \
16948                         "p <priority> w <weight> [del]")                \
16949 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16950                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16951                           "locator-set <locator_name> [del]")           \
16952 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16953   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16954 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16955 _(lisp_gpe_enable_disable, "enable|disable")                            \
16956 _(lisp_enable_disable, "enable|disable")                                \
16957 _(lisp_gpe_add_del_iface, "up|down")                                    \
16958 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
16959                                "[seid <seid>] "                         \
16960                                "rloc <locator> p <prio> "               \
16961                                "w <weight> [rloc <loc> ... ] "          \
16962                                "action <action> [del-all]")             \
16963 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
16964                           "<local-eid>")                                \
16965 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16966 _(lisp_map_request_mode, "src-dst|dst-only")                            \
16967 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16968 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16969 _(lisp_locator_set_dump, "[local | remote]")                            \
16970 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
16971 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16972                        "[local] | [remote]")                            \
16973 _(lisp_eid_table_vni_dump, "")                                          \
16974 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16975 _(lisp_gpe_tunnel_dump, "")                                             \
16976 _(lisp_map_resolver_dump, "")                                           \
16977 _(lisp_adjacencies_get, "vni <vni>")                                    \
16978 _(show_lisp_status, "")                                                 \
16979 _(lisp_get_map_request_itr_rlocs, "")                                   \
16980 _(show_lisp_pitr, "")                                                   \
16981 _(show_lisp_map_request_mode, "")                                       \
16982 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16983 _(af_packet_delete, "name <host interface name>")                       \
16984 _(policer_add_del, "name <policer name> <params> [del]")                \
16985 _(policer_dump, "[name <policer name>]")                                \
16986 _(policer_classify_set_interface,                                       \
16987   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16988   "  [l2-table <nn>] [del]")                                            \
16989 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16990 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16991     "[master|slave]")                                                   \
16992 _(netmap_delete, "name <interface name>")                               \
16993 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16994 _(mpls_fib_encap_dump, "")                                              \
16995 _(mpls_fib_dump, "")                                                    \
16996 _(classify_table_ids, "")                                               \
16997 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16998 _(classify_table_info, "table_id <nn>")                                 \
16999 _(classify_session_dump, "table_id <nn>")                               \
17000 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
17001     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
17002     "[template_interval <nn>] [udp_checksum]")                          \
17003 _(ipfix_exporter_dump, "")                                              \
17004 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17005 _(ipfix_classify_stream_dump, "")                                       \
17006 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
17007 _(ipfix_classify_table_dump, "")                                        \
17008 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [[dst <intfc> | dst_sw_if_index <id>] | disable]") \
17009 _(sw_interface_span_dump, "")                                           \
17010 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17011 _(pg_create_interface, "if_id <nn>")                                    \
17012 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17013 _(pg_enable_disable, "[stream <id>] disable")                           \
17014 _(ip_source_and_port_range_check_add_del,                               \
17015   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17016 _(ip_source_and_port_range_check_interface_add_del,                     \
17017   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17018   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17019 _(ipsec_gre_add_del_tunnel,                                             \
17020   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17021 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17022 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17023 _(l2_interface_pbb_tag_rewrite,                                         \
17024   "<intfc> | sw_if_index <nn> \n"                                       \
17025   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17026   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17027 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17028 _(flow_classify_set_interface,                                          \
17029   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17030 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17031 _(ip_fib_dump, "")                                                      \
17032 _(ip6_fib_dump, "")                                                     \
17033 _(feature_enable_disable, "arc_name <arc_name> "                        \
17034   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")
17035
17036 /* List of command functions, CLI names map directly to functions */
17037 #define foreach_cli_function                                    \
17038 _(comment, "usage: comment <ignore-rest-of-line>")              \
17039 _(dump_interface_table, "usage: dump_interface_table")          \
17040 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17041 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17042 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17043 _(dump_stats_table, "usage: dump_stats_table")                  \
17044 _(dump_macro_table, "usage: dump_macro_table ")                 \
17045 _(dump_node_table, "usage: dump_node_table")                    \
17046 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17047 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17048 _(echo, "usage: echo <message>")                                \
17049 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17050 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17051 _(help, "usage: help")                                          \
17052 _(q, "usage: quit")                                             \
17053 _(quit, "usage: quit")                                          \
17054 _(search_node_table, "usage: search_node_table <name>...")      \
17055 _(set, "usage: set <variable-name> <value>")                    \
17056 _(script, "usage: script <file-name>")                          \
17057 _(unset, "usage: unset <variable-name>")
17058
17059 #define _(N,n)                                  \
17060     static void vl_api_##n##_t_handler_uni      \
17061     (vl_api_##n##_t * mp)                       \
17062     {                                           \
17063         vat_main_t * vam = &vat_main;           \
17064         if (vam->json_output) {                 \
17065             vl_api_##n##_t_handler_json(mp);    \
17066         } else {                                \
17067             vl_api_##n##_t_handler(mp);         \
17068         }                                       \
17069     }
17070 foreach_vpe_api_reply_msg;
17071 #undef _
17072
17073 void
17074 vat_api_hookup (vat_main_t * vam)
17075 {
17076 #define _(N,n)                                                  \
17077     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17078                            vl_api_##n##_t_handler_uni,          \
17079                            vl_noop_handler,                     \
17080                            vl_api_##n##_t_endian,               \
17081                            vl_api_##n##_t_print,                \
17082                            sizeof(vl_api_##n##_t), 1);
17083   foreach_vpe_api_reply_msg;
17084 #undef _
17085
17086   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17087
17088   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17089
17090   vam->function_by_name = hash_create_string (0, sizeof (uword));
17091
17092   vam->help_by_name = hash_create_string (0, sizeof (uword));
17093
17094   /* API messages we can send */
17095 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17096   foreach_vpe_api_msg;
17097 #undef _
17098
17099   /* Help strings */
17100 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17101   foreach_vpe_api_msg;
17102 #undef _
17103
17104   /* CLI functions */
17105 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17106   foreach_cli_function;
17107 #undef _
17108
17109   /* Help strings */
17110 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17111   foreach_cli_function;
17112 #undef _
17113 }
17114
17115 #undef vl_api_version
17116 #define vl_api_version(n,v) static u32 memory_api_version = v;
17117 #include <vlibmemory/vl_memory_api_h.h>
17118 #undef vl_api_version
17119
17120 #undef vl_api_version
17121 #define vl_api_version(n,v) static u32 vnet_interface_api_version = v;
17122 #include <vnet/interface.api.h>
17123 #undef vl_api_version
17124
17125 #undef vl_api_version
17126 #define vl_api_version(n,v) static u32 vpp_api_version = v;
17127 #include <vpp-api/vpe.api.h>
17128 #undef vl_api_version
17129
17130 static u32 *api_versions[] = {
17131   &memory_api_version,
17132   &vnet_interface_api_version,
17133   &vpp_api_version,
17134 };
17135
17136 void
17137 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
17138 {
17139   int i;
17140
17141   ASSERT (ARRAY_LEN (mp->api_versions) >= ARRAY_LEN (api_versions));
17142
17143   /*
17144    * Send the API signatures. This bit of code must
17145    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
17146    */
17147
17148   for (i = 0; i < ARRAY_LEN (api_versions); i++)
17149     mp->api_versions[i] = clib_host_to_net_u32 (*api_versions[i]);
17150 }
17151
17152 /*
17153  * fd.io coding-style-patch-verification: ON
17154  *
17155  * Local Variables:
17156  * eval: (c-set-style "gnu")
17157  * End:
17158  */