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