Add a 64-byte interface "tag" for vhost and tap interfaces
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248   u32 *r = va_arg (*args, u32 *);
249
250   if (0);
251 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
252   foreach_ipsec_policy_action
253 #undef _
254     else
255     return 0;
256   return 1;
257 }
258
259 uword
260 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
261 {
262   u32 *r = va_arg (*args, u32 *);
263
264   if (0);
265 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
266   foreach_ipsec_crypto_alg
267 #undef _
268     else
269     return 0;
270   return 1;
271 }
272
273 u8 *
274 format_ipsec_crypto_alg (u8 * s, va_list * args)
275 {
276   u32 i = va_arg (*args, u32);
277   u8 *t = 0;
278
279   switch (i)
280     {
281 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
282       foreach_ipsec_crypto_alg
283 #undef _
284     default:
285       return format (s, "unknown");
286     }
287   return format (s, "%s", t);
288 }
289
290 uword
291 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
292 {
293   u32 *r = va_arg (*args, u32 *);
294
295   if (0);
296 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
297   foreach_ipsec_integ_alg
298 #undef _
299     else
300     return 0;
301   return 1;
302 }
303
304 u8 *
305 format_ipsec_integ_alg (u8 * s, va_list * args)
306 {
307   u32 i = va_arg (*args, u32);
308   u8 *t = 0;
309
310   switch (i)
311     {
312 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
313       foreach_ipsec_integ_alg
314 #undef _
315     default:
316       return format (s, "unknown");
317     }
318   return format (s, "%s", t);
319 }
320
321 uword
322 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
323 {
324   u32 *r = va_arg (*args, u32 *);
325
326   if (0);
327 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
328   foreach_ikev2_auth_method
329 #undef _
330     else
331     return 0;
332   return 1;
333 }
334
335 uword
336 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
337 {
338   u32 *r = va_arg (*args, u32 *);
339
340   if (0);
341 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
342   foreach_ikev2_id_type
343 #undef _
344     else
345     return 0;
346   return 1;
347 }
348
349 uword
350 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
351 {
352   u8 *r = va_arg (*args, u8 *);
353
354   if (unformat (input, "kbps"))
355     *r = SSE2_QOS_RATE_KBPS;
356   else if (unformat (input, "pps"))
357     *r = SSE2_QOS_RATE_PPS;
358   else
359     return 0;
360   return 1;
361 }
362
363 uword
364 unformat_policer_round_type (unformat_input_t * input, va_list * args)
365 {
366   u8 *r = va_arg (*args, u8 *);
367
368   if (unformat (input, "closest"))
369     *r = SSE2_QOS_ROUND_TO_CLOSEST;
370   else if (unformat (input, "up"))
371     *r = SSE2_QOS_ROUND_TO_UP;
372   else if (unformat (input, "down"))
373     *r = SSE2_QOS_ROUND_TO_DOWN;
374   else
375     return 0;
376   return 1;
377 }
378
379 uword
380 unformat_policer_type (unformat_input_t * input, va_list * args)
381 {
382   u8 *r = va_arg (*args, u8 *);
383
384   if (unformat (input, "1r2c"))
385     *r = SSE2_QOS_POLICER_TYPE_1R2C;
386   else if (unformat (input, "1r3c"))
387     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
388   else if (unformat (input, "2r3c-2698"))
389     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
390   else if (unformat (input, "2r3c-4115"))
391     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
392   else if (unformat (input, "2r3c-mef5cf1"))
393     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
394   else
395     return 0;
396   return 1;
397 }
398
399 uword
400 unformat_dscp (unformat_input_t * input, va_list * va)
401 {
402   u8 *r = va_arg (*va, u8 *);
403
404   if (0);
405 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
406   foreach_vnet_dscp
407 #undef _
408     else
409     return 0;
410   return 1;
411 }
412
413 uword
414 unformat_policer_action_type (unformat_input_t * input, va_list * va)
415 {
416   sse2_qos_pol_action_params_st *a
417     = va_arg (*va, sse2_qos_pol_action_params_st *);
418
419   if (unformat (input, "drop"))
420     a->action_type = SSE2_QOS_ACTION_DROP;
421   else if (unformat (input, "transmit"))
422     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
423   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
424     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
425   else
426     return 0;
427   return 1;
428 }
429
430 uword
431 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
432 {
433   u32 *r = va_arg (*va, u32 *);
434   u32 tid;
435
436   if (unformat (input, "ip4"))
437     tid = POLICER_CLASSIFY_TABLE_IP4;
438   else if (unformat (input, "ip6"))
439     tid = POLICER_CLASSIFY_TABLE_IP6;
440   else if (unformat (input, "l2"))
441     tid = POLICER_CLASSIFY_TABLE_L2;
442   else
443     return 0;
444
445   *r = tid;
446   return 1;
447 }
448
449 uword
450 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
451 {
452   u32 *r = va_arg (*va, u32 *);
453   u32 tid;
454
455   if (unformat (input, "ip4"))
456     tid = FLOW_CLASSIFY_TABLE_IP4;
457   else if (unformat (input, "ip6"))
458     tid = FLOW_CLASSIFY_TABLE_IP6;
459   else
460     return 0;
461
462   *r = tid;
463   return 1;
464 }
465
466 u8 *
467 format_ip4_address (u8 * s, va_list * args)
468 {
469   u8 *a = va_arg (*args, u8 *);
470   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
471 }
472
473 u8 *
474 format_ip6_address (u8 * s, va_list * args)
475 {
476   ip6_address_t *a = va_arg (*args, ip6_address_t *);
477   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
478
479   i_max_n_zero = ARRAY_LEN (a->as_u16);
480   max_n_zeros = 0;
481   i_first_zero = i_max_n_zero;
482   n_zeros = 0;
483   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
484     {
485       u32 is_zero = a->as_u16[i] == 0;
486       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
487         {
488           i_first_zero = i;
489           n_zeros = 0;
490         }
491       n_zeros += is_zero;
492       if ((!is_zero && n_zeros > max_n_zeros)
493           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
494         {
495           i_max_n_zero = i_first_zero;
496           max_n_zeros = n_zeros;
497           i_first_zero = ARRAY_LEN (a->as_u16);
498           n_zeros = 0;
499         }
500     }
501
502   last_double_colon = 0;
503   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
504     {
505       if (i == i_max_n_zero && max_n_zeros > 1)
506         {
507           s = format (s, "::");
508           i += max_n_zeros - 1;
509           last_double_colon = 1;
510         }
511       else
512         {
513           s = format (s, "%s%x",
514                       (last_double_colon || i == 0) ? "" : ":",
515                       clib_net_to_host_u16 (a->as_u16[i]));
516           last_double_colon = 0;
517         }
518     }
519
520   return s;
521 }
522
523 /* Format an IP46 address. */
524 u8 *
525 format_ip46_address (u8 * s, va_list * args)
526 {
527   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
528   ip46_type_t type = va_arg (*args, ip46_type_t);
529   int is_ip4 = 1;
530
531   switch (type)
532     {
533     case IP46_TYPE_ANY:
534       is_ip4 = ip46_address_is_ip4 (ip46);
535       break;
536     case IP46_TYPE_IP4:
537       is_ip4 = 1;
538       break;
539     case IP46_TYPE_IP6:
540       is_ip4 = 0;
541       break;
542     }
543
544   return is_ip4 ?
545     format (s, "%U", format_ip4_address, &ip46->ip4) :
546     format (s, "%U", format_ip6_address, &ip46->ip6);
547 }
548
549 u8 *
550 format_ethernet_address (u8 * s, va_list * args)
551 {
552   u8 *a = va_arg (*args, u8 *);
553
554   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
555                  a[0], a[1], a[2], a[3], a[4], a[5]);
556 }
557
558 void
559 increment_v4_address (ip4_address_t * a)
560 {
561   u32 v;
562
563   v = ntohl (a->as_u32) + 1;
564   a->as_u32 = ntohl (v);
565 }
566
567 void
568 increment_v6_address (ip6_address_t * a)
569 {
570   u64 v0, v1;
571
572   v0 = clib_net_to_host_u64 (a->as_u64[0]);
573   v1 = clib_net_to_host_u64 (a->as_u64[1]);
574
575   v1 += 1;
576   if (v1 == 0)
577     v0 += 1;
578   a->as_u64[0] = clib_net_to_host_u64 (v0);
579   a->as_u64[1] = clib_net_to_host_u64 (v1);
580 }
581
582 void
583 increment_mac_address (u64 * mac)
584 {
585   u64 tmp = *mac;
586
587   tmp = clib_net_to_host_u64 (tmp);
588   tmp += 1 << 16;               /* skip unused (least significant) octets */
589   tmp = clib_host_to_net_u64 (tmp);
590   *mac = tmp;
591 }
592
593 static void vl_api_create_loopback_reply_t_handler
594   (vl_api_create_loopback_reply_t * mp)
595 {
596   vat_main_t *vam = &vat_main;
597   i32 retval = ntohl (mp->retval);
598
599   vam->retval = retval;
600   vam->regenerate_interface_table = 1;
601   vam->sw_if_index = ntohl (mp->sw_if_index);
602   vam->result_ready = 1;
603 }
604
605 static void vl_api_create_loopback_reply_t_handler_json
606   (vl_api_create_loopback_reply_t * mp)
607 {
608   vat_main_t *vam = &vat_main;
609   vat_json_node_t node;
610
611   vat_json_init_object (&node);
612   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
613   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
614
615   vat_json_print (vam->ofp, &node);
616   vat_json_free (&node);
617   vam->retval = ntohl (mp->retval);
618   vam->result_ready = 1;
619 }
620
621 static void vl_api_af_packet_create_reply_t_handler
622   (vl_api_af_packet_create_reply_t * mp)
623 {
624   vat_main_t *vam = &vat_main;
625   i32 retval = ntohl (mp->retval);
626
627   vam->retval = retval;
628   vam->regenerate_interface_table = 1;
629   vam->sw_if_index = ntohl (mp->sw_if_index);
630   vam->result_ready = 1;
631 }
632
633 static void vl_api_af_packet_create_reply_t_handler_json
634   (vl_api_af_packet_create_reply_t * mp)
635 {
636   vat_main_t *vam = &vat_main;
637   vat_json_node_t node;
638
639   vat_json_init_object (&node);
640   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
641   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
642
643   vat_json_print (vam->ofp, &node);
644   vat_json_free (&node);
645
646   vam->retval = ntohl (mp->retval);
647   vam->result_ready = 1;
648 }
649
650 static void vl_api_create_vlan_subif_reply_t_handler
651   (vl_api_create_vlan_subif_reply_t * mp)
652 {
653   vat_main_t *vam = &vat_main;
654   i32 retval = ntohl (mp->retval);
655
656   vam->retval = retval;
657   vam->regenerate_interface_table = 1;
658   vam->sw_if_index = ntohl (mp->sw_if_index);
659   vam->result_ready = 1;
660 }
661
662 static void vl_api_create_vlan_subif_reply_t_handler_json
663   (vl_api_create_vlan_subif_reply_t * mp)
664 {
665   vat_main_t *vam = &vat_main;
666   vat_json_node_t node;
667
668   vat_json_init_object (&node);
669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
670   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
671
672   vat_json_print (vam->ofp, &node);
673   vat_json_free (&node);
674
675   vam->retval = ntohl (mp->retval);
676   vam->result_ready = 1;
677 }
678
679 static void vl_api_create_subif_reply_t_handler
680   (vl_api_create_subif_reply_t * mp)
681 {
682   vat_main_t *vam = &vat_main;
683   i32 retval = ntohl (mp->retval);
684
685   vam->retval = retval;
686   vam->regenerate_interface_table = 1;
687   vam->sw_if_index = ntohl (mp->sw_if_index);
688   vam->result_ready = 1;
689 }
690
691 static void vl_api_create_subif_reply_t_handler_json
692   (vl_api_create_subif_reply_t * mp)
693 {
694   vat_main_t *vam = &vat_main;
695   vat_json_node_t node;
696
697   vat_json_init_object (&node);
698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
699   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
700
701   vat_json_print (vam->ofp, &node);
702   vat_json_free (&node);
703
704   vam->retval = ntohl (mp->retval);
705   vam->result_ready = 1;
706 }
707
708 static void vl_api_interface_name_renumber_reply_t_handler
709   (vl_api_interface_name_renumber_reply_t * mp)
710 {
711   vat_main_t *vam = &vat_main;
712   i32 retval = ntohl (mp->retval);
713
714   vam->retval = retval;
715   vam->regenerate_interface_table = 1;
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler_json
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   vat_json_node_t node;
724
725   vat_json_init_object (&node);
726   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
727
728   vat_json_print (vam->ofp, &node);
729   vat_json_free (&node);
730
731   vam->retval = ntohl (mp->retval);
732   vam->result_ready = 1;
733 }
734
735 /*
736  * Special-case: build the interface table, maintain
737  * the next loopback sw_if_index vbl.
738  */
739 static void vl_api_sw_interface_details_t_handler
740   (vl_api_sw_interface_details_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   u8 *s = format (0, "%s%c", mp->interface_name, 0);
744
745   hash_set_mem (vam->sw_if_index_by_interface_name, s,
746                 ntohl (mp->sw_if_index));
747
748   /* In sub interface case, fill the sub interface table entry */
749   if (mp->sw_if_index != mp->sup_sw_if_index)
750     {
751       sw_interface_subif_t *sub = NULL;
752
753       vec_add2 (vam->sw_if_subif_table, sub, 1);
754
755       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
756       strncpy ((char *) sub->interface_name, (char *) s,
757                vec_len (sub->interface_name));
758       sub->sw_if_index = ntohl (mp->sw_if_index);
759       sub->sub_id = ntohl (mp->sub_id);
760
761       sub->sub_dot1ad = mp->sub_dot1ad;
762       sub->sub_number_of_tags = mp->sub_number_of_tags;
763       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
764       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
765       sub->sub_exact_match = mp->sub_exact_match;
766       sub->sub_default = mp->sub_default;
767       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
768       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
769
770       /* vlan tag rewrite */
771       sub->vtr_op = ntohl (mp->vtr_op);
772       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
773       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
774       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
775     }
776 }
777
778 static void vl_api_sw_interface_details_t_handler_json
779   (vl_api_sw_interface_details_t * mp)
780 {
781   vat_main_t *vam = &vat_main;
782   vat_json_node_t *node = NULL;
783
784   if (VAT_JSON_ARRAY != vam->json_tree.type)
785     {
786       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
787       vat_json_init_array (&vam->json_tree);
788     }
789   node = vat_json_array_add (&vam->json_tree);
790
791   vat_json_init_object (node);
792   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
793   vat_json_object_add_uint (node, "sup_sw_if_index",
794                             ntohl (mp->sup_sw_if_index));
795   vat_json_object_add_uint (node, "l2_address_length",
796                             ntohl (mp->l2_address_length));
797   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
798                              sizeof (mp->l2_address));
799   vat_json_object_add_string_copy (node, "interface_name",
800                                    mp->interface_name);
801   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
802   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
803   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
804   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
805   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
806   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
807   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
808   vat_json_object_add_uint (node, "sub_number_of_tags",
809                             mp->sub_number_of_tags);
810   vat_json_object_add_uint (node, "sub_outer_vlan_id",
811                             ntohs (mp->sub_outer_vlan_id));
812   vat_json_object_add_uint (node, "sub_inner_vlan_id",
813                             ntohs (mp->sub_inner_vlan_id));
814   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
815   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
816   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
817                             mp->sub_outer_vlan_id_any);
818   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
819                             mp->sub_inner_vlan_id_any);
820   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
821   vat_json_object_add_uint (node, "vtr_push_dot1q",
822                             ntohl (mp->vtr_push_dot1q));
823   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
824   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
825 }
826
827 static void vl_api_sw_interface_set_flags_t_handler
828   (vl_api_sw_interface_set_flags_t * mp)
829 {
830   vat_main_t *vam = &vat_main;
831   if (vam->interface_event_display)
832     errmsg ("interface flags: sw_if_index %d %s %s\n",
833             ntohl (mp->sw_if_index),
834             mp->admin_up_down ? "admin-up" : "admin-down",
835             mp->link_up_down ? "link-up" : "link-down");
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler_json
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   /* JSON output not supported */
842 }
843
844 static void
845 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
846 {
847   vat_main_t *vam = &vat_main;
848   i32 retval = ntohl (mp->retval);
849
850   vam->retval = retval;
851   vam->shmem_result = (u8 *) mp->reply_in_shmem;
852   vam->result_ready = 1;
853 }
854
855 static void
856 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   vat_json_node_t node;
860   api_main_t *am = &api_main;
861   void *oldheap;
862   u8 *reply;
863
864   vat_json_init_object (&node);
865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
866   vat_json_object_add_uint (&node, "reply_in_shmem",
867                             ntohl (mp->reply_in_shmem));
868   /* Toss the shared-memory original... */
869   pthread_mutex_lock (&am->vlib_rp->mutex);
870   oldheap = svm_push_data_heap (am->vlib_rp);
871
872   reply = (u8 *) (mp->reply_in_shmem);
873   vec_free (reply);
874
875   svm_pop_heap (oldheap);
876   pthread_mutex_unlock (&am->vlib_rp->mutex);
877
878   vat_json_print (vam->ofp, &node);
879   vat_json_free (&node);
880
881   vam->retval = ntohl (mp->retval);
882   vam->result_ready = 1;
883 }
884
885 static void
886 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   i32 retval = ntohl (mp->retval);
890
891   vam->retval = retval;
892   vam->cmd_reply = mp->reply;
893   vam->result_ready = 1;
894 }
895
896 static void
897 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   vat_json_node_t node;
901
902   vat_json_init_object (&node);
903   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
904   vat_json_object_add_string_copy (&node, "reply", mp->reply);
905
906   vat_json_print (vam->ofp, &node);
907   vat_json_free (&node);
908
909   vam->retval = ntohl (mp->retval);
910   vam->result_ready = 1;
911 }
912
913 static void vl_api_classify_add_del_table_reply_t_handler
914   (vl_api_classify_add_del_table_reply_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   i32 retval = ntohl (mp->retval);
918   if (vam->async_mode)
919     {
920       vam->async_errors += (retval < 0);
921     }
922   else
923     {
924       vam->retval = retval;
925       if (retval == 0 &&
926           ((mp->new_table_index != 0xFFFFFFFF) ||
927            (mp->skip_n_vectors != 0xFFFFFFFF) ||
928            (mp->match_n_vectors != 0xFFFFFFFF)))
929         /*
930          * Note: this is just barely thread-safe, depends on
931          * the main thread spinning waiting for an answer...
932          */
933         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
934                 ntohl (mp->new_table_index),
935                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
936       vam->result_ready = 1;
937     }
938 }
939
940 static void vl_api_classify_add_del_table_reply_t_handler_json
941   (vl_api_classify_add_del_table_reply_t * mp)
942 {
943   vat_main_t *vam = &vat_main;
944   vat_json_node_t node;
945
946   vat_json_init_object (&node);
947   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
948   vat_json_object_add_uint (&node, "new_table_index",
949                             ntohl (mp->new_table_index));
950   vat_json_object_add_uint (&node, "skip_n_vectors",
951                             ntohl (mp->skip_n_vectors));
952   vat_json_object_add_uint (&node, "match_n_vectors",
953                             ntohl (mp->match_n_vectors));
954
955   vat_json_print (vam->ofp, &node);
956   vat_json_free (&node);
957
958   vam->retval = ntohl (mp->retval);
959   vam->result_ready = 1;
960 }
961
962 static void vl_api_get_node_index_reply_t_handler
963   (vl_api_get_node_index_reply_t * mp)
964 {
965   vat_main_t *vam = &vat_main;
966   i32 retval = ntohl (mp->retval);
967   if (vam->async_mode)
968     {
969       vam->async_errors += (retval < 0);
970     }
971   else
972     {
973       vam->retval = retval;
974       if (retval == 0)
975         errmsg ("node index %d\n", ntohl (mp->node_index));
976       vam->result_ready = 1;
977     }
978 }
979
980 static void vl_api_get_node_index_reply_t_handler_json
981   (vl_api_get_node_index_reply_t * mp)
982 {
983   vat_main_t *vam = &vat_main;
984   vat_json_node_t node;
985
986   vat_json_init_object (&node);
987   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
988   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
989
990   vat_json_print (vam->ofp, &node);
991   vat_json_free (&node);
992
993   vam->retval = ntohl (mp->retval);
994   vam->result_ready = 1;
995 }
996
997 static void vl_api_get_next_index_reply_t_handler
998   (vl_api_get_next_index_reply_t * mp)
999 {
1000   vat_main_t *vam = &vat_main;
1001   i32 retval = ntohl (mp->retval);
1002   if (vam->async_mode)
1003     {
1004       vam->async_errors += (retval < 0);
1005     }
1006   else
1007     {
1008       vam->retval = retval;
1009       if (retval == 0)
1010         errmsg ("next node index %d\n", ntohl (mp->next_index));
1011       vam->result_ready = 1;
1012     }
1013 }
1014
1015 static void vl_api_get_next_index_reply_t_handler_json
1016   (vl_api_get_next_index_reply_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   vat_json_node_t node;
1020
1021   vat_json_init_object (&node);
1022   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1023   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1024
1025   vat_json_print (vam->ofp, &node);
1026   vat_json_free (&node);
1027
1028   vam->retval = ntohl (mp->retval);
1029   vam->result_ready = 1;
1030 }
1031
1032 static void vl_api_add_node_next_reply_t_handler
1033   (vl_api_add_node_next_reply_t * mp)
1034 {
1035   vat_main_t *vam = &vat_main;
1036   i32 retval = ntohl (mp->retval);
1037   if (vam->async_mode)
1038     {
1039       vam->async_errors += (retval < 0);
1040     }
1041   else
1042     {
1043       vam->retval = retval;
1044       if (retval == 0)
1045         errmsg ("next index %d\n", ntohl (mp->next_index));
1046       vam->result_ready = 1;
1047     }
1048 }
1049
1050 static void vl_api_add_node_next_reply_t_handler_json
1051   (vl_api_add_node_next_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   vat_json_node_t node;
1055
1056   vat_json_init_object (&node);
1057   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1058   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1059
1060   vat_json_print (vam->ofp, &node);
1061   vat_json_free (&node);
1062
1063   vam->retval = ntohl (mp->retval);
1064   vam->result_ready = 1;
1065 }
1066
1067 static void vl_api_show_version_reply_t_handler
1068   (vl_api_show_version_reply_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   i32 retval = ntohl (mp->retval);
1072
1073   if (retval >= 0)
1074     {
1075       errmsg ("        program: %s\n", mp->program);
1076       errmsg ("        version: %s\n", mp->version);
1077       errmsg ("     build date: %s\n", mp->build_date);
1078       errmsg ("build directory: %s\n", mp->build_directory);
1079     }
1080   vam->retval = retval;
1081   vam->result_ready = 1;
1082 }
1083
1084 static void vl_api_show_version_reply_t_handler_json
1085   (vl_api_show_version_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   vat_json_node_t node;
1089
1090   vat_json_init_object (&node);
1091   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1092   vat_json_object_add_string_copy (&node, "program", mp->program);
1093   vat_json_object_add_string_copy (&node, "version", mp->version);
1094   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1095   vat_json_object_add_string_copy (&node, "build_directory",
1096                                    mp->build_directory);
1097
1098   vat_json_print (vam->ofp, &node);
1099   vat_json_free (&node);
1100
1101   vam->retval = ntohl (mp->retval);
1102   vam->result_ready = 1;
1103 }
1104
1105 static void
1106 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1107 {
1108   vat_main_t *vam = &vat_main;
1109   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1110           mp->mac_ip ? "mac/ip binding" : "address resolution",
1111           format_ip4_address, &mp->address,
1112           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1113 }
1114
1115 static void
1116 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1117 {
1118   /* JSON output not supported */
1119 }
1120
1121 static void
1122 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1123 {
1124   vat_main_t *vam = &vat_main;
1125   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1126           mp->mac_ip ? "mac/ip binding" : "address resolution",
1127           format_ip6_address, mp->address,
1128           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1129 }
1130
1131 static void
1132 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1133 {
1134   /* JSON output not supported */
1135 }
1136
1137 /*
1138  * Special-case: build the bridge domain table, maintain
1139  * the next bd id vbl.
1140  */
1141 static void vl_api_bridge_domain_details_t_handler
1142   (vl_api_bridge_domain_details_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1146
1147   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1148            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1149
1150   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1151            ntohl (mp->bd_id), mp->learn, mp->forward,
1152            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1153
1154   if (n_sw_ifs)
1155     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1156              "Interface Name");
1157 }
1158
1159 static void vl_api_bridge_domain_details_t_handler_json
1160   (vl_api_bridge_domain_details_t * mp)
1161 {
1162   vat_main_t *vam = &vat_main;
1163   vat_json_node_t *node, *array = NULL;
1164
1165   if (VAT_JSON_ARRAY != vam->json_tree.type)
1166     {
1167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1168       vat_json_init_array (&vam->json_tree);
1169     }
1170   node = vat_json_array_add (&vam->json_tree);
1171
1172   vat_json_init_object (node);
1173   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1174   vat_json_object_add_uint (node, "flood", mp->flood);
1175   vat_json_object_add_uint (node, "forward", mp->forward);
1176   vat_json_object_add_uint (node, "learn", mp->learn);
1177   vat_json_object_add_uint (node, "bvi_sw_if_index",
1178                             ntohl (mp->bvi_sw_if_index));
1179   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1180   array = vat_json_object_add (node, "sw_if");
1181   vat_json_init_array (array);
1182 }
1183
1184 /*
1185  * Special-case: build the bridge domain sw if table.
1186  */
1187 static void vl_api_bridge_domain_sw_if_details_t_handler
1188   (vl_api_bridge_domain_sw_if_details_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   hash_pair_t *p;
1192   u8 *sw_if_name = 0;
1193   u32 sw_if_index;
1194
1195   sw_if_index = ntohl (mp->sw_if_index);
1196   /* *INDENT-OFF* */
1197   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1198   ({
1199     if ((u32) p->value[0] == sw_if_index)
1200       {
1201         sw_if_name = (u8 *)(p->key);
1202         break;
1203       }
1204   }));
1205   /* *INDENT-ON* */
1206
1207   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1208            mp->shg, sw_if_name ? (char *) sw_if_name :
1209            "sw_if_index not found!");
1210 }
1211
1212 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1213   (vl_api_bridge_domain_sw_if_details_t * mp)
1214 {
1215   vat_main_t *vam = &vat_main;
1216   vat_json_node_t *node = NULL;
1217   uword last_index = 0;
1218
1219   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1220   ASSERT (vec_len (vam->json_tree.array) >= 1);
1221   last_index = vec_len (vam->json_tree.array) - 1;
1222   node = &vam->json_tree.array[last_index];
1223   node = vat_json_object_get_element (node, "sw_if");
1224   ASSERT (NULL != node);
1225   node = vat_json_array_add (node);
1226
1227   vat_json_init_object (node);
1228   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1230   vat_json_object_add_uint (node, "shg", mp->shg);
1231 }
1232
1233 static void vl_api_control_ping_reply_t_handler
1234   (vl_api_control_ping_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   i32 retval = ntohl (mp->retval);
1238   if (vam->async_mode)
1239     {
1240       vam->async_errors += (retval < 0);
1241     }
1242   else
1243     {
1244       vam->retval = retval;
1245       vam->result_ready = 1;
1246     }
1247 }
1248
1249 static void vl_api_control_ping_reply_t_handler_json
1250   (vl_api_control_ping_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254
1255   if (VAT_JSON_NONE != vam->json_tree.type)
1256     {
1257       vat_json_print (vam->ofp, &vam->json_tree);
1258       vat_json_free (&vam->json_tree);
1259       vam->json_tree.type = VAT_JSON_NONE;
1260     }
1261   else
1262     {
1263       /* just print [] */
1264       vat_json_init_array (&vam->json_tree);
1265       vat_json_print (vam->ofp, &vam->json_tree);
1266       vam->json_tree.type = VAT_JSON_NONE;
1267     }
1268
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void
1274 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278   if (vam->async_mode)
1279     {
1280       vam->async_errors += (retval < 0);
1281     }
1282   else
1283     {
1284       vam->retval = retval;
1285       vam->result_ready = 1;
1286     }
1287 }
1288
1289 static void vl_api_l2_flags_reply_t_handler_json
1290   (vl_api_l2_flags_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   vat_json_node_t node;
1294
1295   vat_json_init_object (&node);
1296   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1297   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1298                             ntohl (mp->resulting_feature_bitmap));
1299
1300   vat_json_print (vam->ofp, &node);
1301   vat_json_free (&node);
1302
1303   vam->retval = ntohl (mp->retval);
1304   vam->result_ready = 1;
1305 }
1306
1307 static void vl_api_bridge_flags_reply_t_handler
1308   (vl_api_bridge_flags_reply_t * mp)
1309 {
1310   vat_main_t *vam = &vat_main;
1311   i32 retval = ntohl (mp->retval);
1312   if (vam->async_mode)
1313     {
1314       vam->async_errors += (retval < 0);
1315     }
1316   else
1317     {
1318       vam->retval = retval;
1319       vam->result_ready = 1;
1320     }
1321 }
1322
1323 static void vl_api_bridge_flags_reply_t_handler_json
1324   (vl_api_bridge_flags_reply_t * mp)
1325 {
1326   vat_main_t *vam = &vat_main;
1327   vat_json_node_t node;
1328
1329   vat_json_init_object (&node);
1330   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1331   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1332                             ntohl (mp->resulting_feature_bitmap));
1333
1334   vat_json_print (vam->ofp, &node);
1335   vat_json_free (&node);
1336
1337   vam->retval = ntohl (mp->retval);
1338   vam->result_ready = 1;
1339 }
1340
1341 static void vl_api_tap_connect_reply_t_handler
1342   (vl_api_tap_connect_reply_t * mp)
1343 {
1344   vat_main_t *vam = &vat_main;
1345   i32 retval = ntohl (mp->retval);
1346   if (vam->async_mode)
1347     {
1348       vam->async_errors += (retval < 0);
1349     }
1350   else
1351     {
1352       vam->retval = retval;
1353       vam->sw_if_index = ntohl (mp->sw_if_index);
1354       vam->result_ready = 1;
1355     }
1356
1357 }
1358
1359 static void vl_api_tap_connect_reply_t_handler_json
1360   (vl_api_tap_connect_reply_t * mp)
1361 {
1362   vat_main_t *vam = &vat_main;
1363   vat_json_node_t node;
1364
1365   vat_json_init_object (&node);
1366   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1367   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1368
1369   vat_json_print (vam->ofp, &node);
1370   vat_json_free (&node);
1371
1372   vam->retval = ntohl (mp->retval);
1373   vam->result_ready = 1;
1374
1375 }
1376
1377 static void
1378 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1379 {
1380   vat_main_t *vam = &vat_main;
1381   i32 retval = ntohl (mp->retval);
1382   if (vam->async_mode)
1383     {
1384       vam->async_errors += (retval < 0);
1385     }
1386   else
1387     {
1388       vam->retval = retval;
1389       vam->sw_if_index = ntohl (mp->sw_if_index);
1390       vam->result_ready = 1;
1391     }
1392 }
1393
1394 static void vl_api_tap_modify_reply_t_handler_json
1395   (vl_api_tap_modify_reply_t * mp)
1396 {
1397   vat_main_t *vam = &vat_main;
1398   vat_json_node_t node;
1399
1400   vat_json_init_object (&node);
1401   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1402   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1403
1404   vat_json_print (vam->ofp, &node);
1405   vat_json_free (&node);
1406
1407   vam->retval = ntohl (mp->retval);
1408   vam->result_ready = 1;
1409 }
1410
1411 static void
1412 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1413 {
1414   vat_main_t *vam = &vat_main;
1415   i32 retval = ntohl (mp->retval);
1416   if (vam->async_mode)
1417     {
1418       vam->async_errors += (retval < 0);
1419     }
1420   else
1421     {
1422       vam->retval = retval;
1423       vam->result_ready = 1;
1424     }
1425 }
1426
1427 static void vl_api_tap_delete_reply_t_handler_json
1428   (vl_api_tap_delete_reply_t * mp)
1429 {
1430   vat_main_t *vam = &vat_main;
1431   vat_json_node_t node;
1432
1433   vat_json_init_object (&node);
1434   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1435
1436   vat_json_print (vam->ofp, &node);
1437   vat_json_free (&node);
1438
1439   vam->retval = ntohl (mp->retval);
1440   vam->result_ready = 1;
1441 }
1442
1443 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1444   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   i32 retval = ntohl (mp->retval);
1448   if (vam->async_mode)
1449     {
1450       vam->async_errors += (retval < 0);
1451     }
1452   else
1453     {
1454       vam->retval = retval;
1455       vam->result_ready = 1;
1456     }
1457 }
1458
1459 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1460   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   vat_json_node_t node;
1464
1465   vat_json_init_object (&node);
1466   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1467   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1468                             ntohl (mp->tunnel_sw_if_index));
1469
1470   vat_json_print (vam->ofp, &node);
1471   vat_json_free (&node);
1472
1473   vam->retval = ntohl (mp->retval);
1474   vam->result_ready = 1;
1475 }
1476
1477 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1478   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1479 {
1480   vat_main_t *vam = &vat_main;
1481   i32 retval = ntohl (mp->retval);
1482   if (vam->async_mode)
1483     {
1484       vam->async_errors += (retval < 0);
1485     }
1486   else
1487     {
1488       vam->retval = retval;
1489       vam->sw_if_index = ntohl (mp->sw_if_index);
1490       vam->result_ready = 1;
1491     }
1492 }
1493
1494 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1495   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   vat_json_node_t node;
1499
1500   vat_json_init_object (&node);
1501   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1502   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1503
1504   vat_json_print (vam->ofp, &node);
1505   vat_json_free (&node);
1506
1507   vam->retval = ntohl (mp->retval);
1508   vam->result_ready = 1;
1509 }
1510
1511
1512 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1513   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1514 {
1515   vat_main_t *vam = &vat_main;
1516   i32 retval = ntohl (mp->retval);
1517   if (vam->async_mode)
1518     {
1519       vam->async_errors += (retval < 0);
1520     }
1521   else
1522     {
1523       vam->retval = retval;
1524       vam->result_ready = 1;
1525     }
1526 }
1527
1528 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1529   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1530 {
1531   vat_main_t *vam = &vat_main;
1532   vat_json_node_t node;
1533
1534   vat_json_init_object (&node);
1535   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1536   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1537
1538   vat_json_print (vam->ofp, &node);
1539   vat_json_free (&node);
1540
1541   vam->retval = ntohl (mp->retval);
1542   vam->result_ready = 1;
1543 }
1544
1545 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1546   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   i32 retval = ntohl (mp->retval);
1550   if (vam->async_mode)
1551     {
1552       vam->async_errors += (retval < 0);
1553     }
1554   else
1555     {
1556       vam->retval = retval;
1557       vam->sw_if_index = ntohl (mp->sw_if_index);
1558       vam->result_ready = 1;
1559     }
1560 }
1561
1562 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1563   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1564 {
1565   vat_main_t *vam = &vat_main;
1566   vat_json_node_t node;
1567
1568   vat_json_init_object (&node);
1569   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1570   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1571
1572   vat_json_print (vam->ofp, &node);
1573   vat_json_free (&node);
1574
1575   vam->retval = ntohl (mp->retval);
1576   vam->result_ready = 1;
1577 }
1578
1579 static void vl_api_gre_add_del_tunnel_reply_t_handler
1580   (vl_api_gre_add_del_tunnel_reply_t * mp)
1581 {
1582   vat_main_t *vam = &vat_main;
1583   i32 retval = ntohl (mp->retval);
1584   if (vam->async_mode)
1585     {
1586       vam->async_errors += (retval < 0);
1587     }
1588   else
1589     {
1590       vam->retval = retval;
1591       vam->sw_if_index = ntohl (mp->sw_if_index);
1592       vam->result_ready = 1;
1593     }
1594 }
1595
1596 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1597   (vl_api_gre_add_del_tunnel_reply_t * mp)
1598 {
1599   vat_main_t *vam = &vat_main;
1600   vat_json_node_t node;
1601
1602   vat_json_init_object (&node);
1603   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1604   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1605
1606   vat_json_print (vam->ofp, &node);
1607   vat_json_free (&node);
1608
1609   vam->retval = ntohl (mp->retval);
1610   vam->result_ready = 1;
1611 }
1612
1613 static void vl_api_create_vhost_user_if_reply_t_handler
1614   (vl_api_create_vhost_user_if_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   i32 retval = ntohl (mp->retval);
1618   if (vam->async_mode)
1619     {
1620       vam->async_errors += (retval < 0);
1621     }
1622   else
1623     {
1624       vam->retval = retval;
1625       vam->sw_if_index = ntohl (mp->sw_if_index);
1626       vam->result_ready = 1;
1627     }
1628 }
1629
1630 static void vl_api_create_vhost_user_if_reply_t_handler_json
1631   (vl_api_create_vhost_user_if_reply_t * mp)
1632 {
1633   vat_main_t *vam = &vat_main;
1634   vat_json_node_t node;
1635
1636   vat_json_init_object (&node);
1637   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1638   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1639
1640   vat_json_print (vam->ofp, &node);
1641   vat_json_free (&node);
1642
1643   vam->retval = ntohl (mp->retval);
1644   vam->result_ready = 1;
1645 }
1646
1647 static void vl_api_ip_address_details_t_handler
1648   (vl_api_ip_address_details_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   static ip_address_details_t empty_ip_address_details = { {0} };
1652   ip_address_details_t *address = NULL;
1653   ip_details_t *current_ip_details = NULL;
1654   ip_details_t *details = NULL;
1655
1656   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1657
1658   if (!details || vam->current_sw_if_index >= vec_len (details)
1659       || !details[vam->current_sw_if_index].present)
1660     {
1661       errmsg ("ip address details arrived but not stored\n");
1662       errmsg ("ip_dump should be called first\n");
1663       return;
1664     }
1665
1666   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1667
1668 #define addresses (current_ip_details->addr)
1669
1670   vec_validate_init_empty (addresses, vec_len (addresses),
1671                            empty_ip_address_details);
1672
1673   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1674
1675   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1676   address->prefix_length = mp->prefix_length;
1677 #undef addresses
1678 }
1679
1680 static void vl_api_ip_address_details_t_handler_json
1681   (vl_api_ip_address_details_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t *node = NULL;
1685   struct in6_addr ip6;
1686   struct in_addr ip4;
1687
1688   if (VAT_JSON_ARRAY != vam->json_tree.type)
1689     {
1690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1691       vat_json_init_array (&vam->json_tree);
1692     }
1693   node = vat_json_array_add (&vam->json_tree);
1694
1695   vat_json_init_object (node);
1696   if (vam->is_ipv6)
1697     {
1698       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1699       vat_json_object_add_ip6 (node, "ip", ip6);
1700     }
1701   else
1702     {
1703       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1704       vat_json_object_add_ip4 (node, "ip", ip4);
1705     }
1706   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1707 }
1708
1709 static void
1710 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   static ip_details_t empty_ip_details = { 0 };
1714   ip_details_t *ip = NULL;
1715   u32 sw_if_index = ~0;
1716
1717   sw_if_index = ntohl (mp->sw_if_index);
1718
1719   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1720                            sw_if_index, empty_ip_details);
1721
1722   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1723                          sw_if_index);
1724
1725   ip->present = 1;
1726 }
1727
1728 static void
1729 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732
1733   if (VAT_JSON_ARRAY != vam->json_tree.type)
1734     {
1735       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1736       vat_json_init_array (&vam->json_tree);
1737     }
1738   vat_json_array_add_uint (&vam->json_tree,
1739                            clib_net_to_host_u32 (mp->sw_if_index));
1740 }
1741
1742 static void vl_api_map_domain_details_t_handler_json
1743   (vl_api_map_domain_details_t * mp)
1744 {
1745   vat_json_node_t *node = NULL;
1746   vat_main_t *vam = &vat_main;
1747   struct in6_addr ip6;
1748   struct in_addr ip4;
1749
1750   if (VAT_JSON_ARRAY != vam->json_tree.type)
1751     {
1752       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1753       vat_json_init_array (&vam->json_tree);
1754     }
1755
1756   node = vat_json_array_add (&vam->json_tree);
1757   vat_json_init_object (node);
1758
1759   vat_json_object_add_uint (node, "domain_index",
1760                             clib_net_to_host_u32 (mp->domain_index));
1761   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1762   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1763   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1764   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1765   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1766   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1767   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1768   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1769   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1770   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1771   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1772   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1773   vat_json_object_add_uint (node, "flags", mp->flags);
1774   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1775   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1776 }
1777
1778 static void vl_api_map_domain_details_t_handler
1779   (vl_api_map_domain_details_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782
1783   if (mp->is_translation)
1784     {
1785       fformat (vam->ofp,
1786                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1787                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1788                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1789                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1790                clib_net_to_host_u32 (mp->domain_index));
1791     }
1792   else
1793     {
1794       fformat (vam->ofp,
1795                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1796                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1797                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1798                format_ip6_address, mp->ip6_src,
1799                clib_net_to_host_u32 (mp->domain_index));
1800     }
1801   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1802            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1803            mp->is_translation ? "map-t" : "");
1804 }
1805
1806 static void vl_api_map_rule_details_t_handler_json
1807   (vl_api_map_rule_details_t * mp)
1808 {
1809   struct in6_addr ip6;
1810   vat_json_node_t *node = NULL;
1811   vat_main_t *vam = &vat_main;
1812
1813   if (VAT_JSON_ARRAY != vam->json_tree.type)
1814     {
1815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1816       vat_json_init_array (&vam->json_tree);
1817     }
1818
1819   node = vat_json_array_add (&vam->json_tree);
1820   vat_json_init_object (node);
1821
1822   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1823   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1824   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1825 }
1826
1827 static void
1828 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1829 {
1830   vat_main_t *vam = &vat_main;
1831   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1832            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1833 }
1834
1835 static void
1836 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1837 {
1838   vat_main_t *vam = &vat_main;
1839   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1840           "router_addr %U host_mac %U\n",
1841           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1842           format_ip4_address, &mp->host_address,
1843           format_ip4_address, &mp->router_address,
1844           format_ethernet_address, mp->host_mac);
1845 }
1846
1847 static void vl_api_dhcp_compl_event_t_handler_json
1848   (vl_api_dhcp_compl_event_t * mp)
1849 {
1850   /* JSON output not supported */
1851 }
1852
1853 static void
1854 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1855                               u32 counter)
1856 {
1857   vat_main_t *vam = &vat_main;
1858   static u64 default_counter = 0;
1859
1860   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1861                            NULL);
1862   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1863                            sw_if_index, default_counter);
1864   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1865 }
1866
1867 static void
1868 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1869                                 interface_counter_t counter)
1870 {
1871   vat_main_t *vam = &vat_main;
1872   static interface_counter_t default_counter = { 0, };
1873
1874   vec_validate_init_empty (vam->combined_interface_counters,
1875                            vnet_counter_type, NULL);
1876   vec_validate_init_empty (vam->combined_interface_counters
1877                            [vnet_counter_type], sw_if_index, default_counter);
1878   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1879 }
1880
1881 static void vl_api_vnet_interface_counters_t_handler
1882   (vl_api_vnet_interface_counters_t * mp)
1883 {
1884   /* not supported */
1885 }
1886
1887 static void vl_api_vnet_interface_counters_t_handler_json
1888   (vl_api_vnet_interface_counters_t * mp)
1889 {
1890   interface_counter_t counter;
1891   vlib_counter_t *v;
1892   u64 *v_packets;
1893   u64 packets;
1894   u32 count;
1895   u32 first_sw_if_index;
1896   int i;
1897
1898   count = ntohl (mp->count);
1899   first_sw_if_index = ntohl (mp->first_sw_if_index);
1900
1901   if (!mp->is_combined)
1902     {
1903       v_packets = (u64 *) & mp->data;
1904       for (i = 0; i < count; i++)
1905         {
1906           packets =
1907             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1908           set_simple_interface_counter (mp->vnet_counter_type,
1909                                         first_sw_if_index + i, packets);
1910           v_packets++;
1911         }
1912     }
1913   else
1914     {
1915       v = (vlib_counter_t *) & mp->data;
1916       for (i = 0; i < count; i++)
1917         {
1918           counter.packets =
1919             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1920           counter.bytes =
1921             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1922           set_combined_interface_counter (mp->vnet_counter_type,
1923                                           first_sw_if_index + i, counter);
1924           v++;
1925         }
1926     }
1927 }
1928
1929 static u32
1930 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1931 {
1932   vat_main_t *vam = &vat_main;
1933   u32 i;
1934
1935   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1936     {
1937       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1938         {
1939           return i;
1940         }
1941     }
1942   return ~0;
1943 }
1944
1945 static u32
1946 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1947 {
1948   vat_main_t *vam = &vat_main;
1949   u32 i;
1950
1951   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1952     {
1953       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1954         {
1955           return i;
1956         }
1957     }
1958   return ~0;
1959 }
1960
1961 static void vl_api_vnet_ip4_fib_counters_t_handler
1962   (vl_api_vnet_ip4_fib_counters_t * mp)
1963 {
1964   /* not supported */
1965 }
1966
1967 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1968   (vl_api_vnet_ip4_fib_counters_t * mp)
1969 {
1970   vat_main_t *vam = &vat_main;
1971   vl_api_ip4_fib_counter_t *v;
1972   ip4_fib_counter_t *counter;
1973   struct in_addr ip4;
1974   u32 vrf_id;
1975   u32 vrf_index;
1976   u32 count;
1977   int i;
1978
1979   vrf_id = ntohl (mp->vrf_id);
1980   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
1981   if (~0 == vrf_index)
1982     {
1983       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
1984       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1985       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1986       vec_validate (vam->ip4_fib_counters, vrf_index);
1987       vam->ip4_fib_counters[vrf_index] = NULL;
1988     }
1989
1990   vec_free (vam->ip4_fib_counters[vrf_index]);
1991   v = (vl_api_ip4_fib_counter_t *) & mp->c;
1992   count = ntohl (mp->count);
1993   for (i = 0; i < count; i++)
1994     {
1995       vec_validate (vam->ip4_fib_counters[vrf_index], i);
1996       counter = &vam->ip4_fib_counters[vrf_index][i];
1997       clib_memcpy (&ip4, &v->address, sizeof (ip4));
1998       counter->address = ip4;
1999       counter->address_length = v->address_length;
2000       counter->packets = clib_net_to_host_u64 (v->packets);
2001       counter->bytes = clib_net_to_host_u64 (v->bytes);
2002       v++;
2003     }
2004 }
2005
2006 static void vl_api_vnet_ip6_fib_counters_t_handler
2007   (vl_api_vnet_ip6_fib_counters_t * mp)
2008 {
2009   /* not supported */
2010 }
2011
2012 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2013   (vl_api_vnet_ip6_fib_counters_t * mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016   vl_api_ip6_fib_counter_t *v;
2017   ip6_fib_counter_t *counter;
2018   struct in6_addr ip6;
2019   u32 vrf_id;
2020   u32 vrf_index;
2021   u32 count;
2022   int i;
2023
2024   vrf_id = ntohl (mp->vrf_id);
2025   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2026   if (~0 == vrf_index)
2027     {
2028       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2029       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2030       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2031       vec_validate (vam->ip6_fib_counters, vrf_index);
2032       vam->ip6_fib_counters[vrf_index] = NULL;
2033     }
2034
2035   vec_free (vam->ip6_fib_counters[vrf_index]);
2036   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2037   count = ntohl (mp->count);
2038   for (i = 0; i < count; i++)
2039     {
2040       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2041       counter = &vam->ip6_fib_counters[vrf_index][i];
2042       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2043       counter->address = ip6;
2044       counter->address_length = v->address_length;
2045       counter->packets = clib_net_to_host_u64 (v->packets);
2046       counter->bytes = clib_net_to_host_u64 (v->bytes);
2047       v++;
2048     }
2049 }
2050
2051 static void vl_api_get_first_msg_id_reply_t_handler
2052   (vl_api_get_first_msg_id_reply_t * mp)
2053 {
2054   vat_main_t *vam = &vat_main;
2055   i32 retval = ntohl (mp->retval);
2056
2057   if (vam->async_mode)
2058     {
2059       vam->async_errors += (retval < 0);
2060     }
2061   else
2062     {
2063       vam->retval = retval;
2064       vam->result_ready = 1;
2065     }
2066   if (retval >= 0)
2067     {
2068       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2069     }
2070 }
2071
2072 static void vl_api_get_first_msg_id_reply_t_handler_json
2073   (vl_api_get_first_msg_id_reply_t * mp)
2074 {
2075   vat_main_t *vam = &vat_main;
2076   vat_json_node_t node;
2077
2078   vat_json_init_object (&node);
2079   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2080   vat_json_object_add_uint (&node, "first_msg_id",
2081                             (uint) ntohs (mp->first_msg_id));
2082
2083   vat_json_print (vam->ofp, &node);
2084   vat_json_free (&node);
2085
2086   vam->retval = ntohl (mp->retval);
2087   vam->result_ready = 1;
2088 }
2089
2090 static void vl_api_get_node_graph_reply_t_handler
2091   (vl_api_get_node_graph_reply_t * mp)
2092 {
2093   vat_main_t *vam = &vat_main;
2094   api_main_t *am = &api_main;
2095   i32 retval = ntohl (mp->retval);
2096   u8 *pvt_copy, *reply;
2097   void *oldheap;
2098   vlib_node_t *node;
2099   int i;
2100
2101   if (vam->async_mode)
2102     {
2103       vam->async_errors += (retval < 0);
2104     }
2105   else
2106     {
2107       vam->retval = retval;
2108       vam->result_ready = 1;
2109     }
2110
2111   /* "Should never happen..." */
2112   if (retval != 0)
2113     return;
2114
2115   reply = (u8 *) (mp->reply_in_shmem);
2116   pvt_copy = vec_dup (reply);
2117
2118   /* Toss the shared-memory original... */
2119   pthread_mutex_lock (&am->vlib_rp->mutex);
2120   oldheap = svm_push_data_heap (am->vlib_rp);
2121
2122   vec_free (reply);
2123
2124   svm_pop_heap (oldheap);
2125   pthread_mutex_unlock (&am->vlib_rp->mutex);
2126
2127   if (vam->graph_nodes)
2128     {
2129       hash_free (vam->graph_node_index_by_name);
2130
2131       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2132         {
2133           node = vam->graph_nodes[i];
2134           vec_free (node->name);
2135           vec_free (node->next_nodes);
2136           vec_free (node);
2137         }
2138       vec_free (vam->graph_nodes);
2139     }
2140
2141   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2142   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2143   vec_free (pvt_copy);
2144
2145   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2146     {
2147       node = vam->graph_nodes[i];
2148       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2149     }
2150 }
2151
2152 static void vl_api_get_node_graph_reply_t_handler_json
2153   (vl_api_get_node_graph_reply_t * mp)
2154 {
2155   vat_main_t *vam = &vat_main;
2156   api_main_t *am = &api_main;
2157   void *oldheap;
2158   vat_json_node_t node;
2159   u8 *reply;
2160
2161   /* $$$$ make this real? */
2162   vat_json_init_object (&node);
2163   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2164   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2165
2166   reply = (u8 *) (mp->reply_in_shmem);
2167
2168   /* Toss the shared-memory original... */
2169   pthread_mutex_lock (&am->vlib_rp->mutex);
2170   oldheap = svm_push_data_heap (am->vlib_rp);
2171
2172   vec_free (reply);
2173
2174   svm_pop_heap (oldheap);
2175   pthread_mutex_unlock (&am->vlib_rp->mutex);
2176
2177   vat_json_print (vam->ofp, &node);
2178   vat_json_free (&node);
2179
2180   vam->retval = ntohl (mp->retval);
2181   vam->result_ready = 1;
2182 }
2183
2184 static void
2185 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2186 {
2187   vat_main_t *vam = &vat_main;
2188   u8 *s = 0;
2189
2190   if (mp->local)
2191     {
2192       s = format (s, "%=16d%=16d%=16d\n",
2193                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2194     }
2195   else
2196     {
2197       s = format (s, "%=16U%=16d%=16d\n",
2198                   mp->is_ipv6 ? format_ip6_address :
2199                   format_ip4_address,
2200                   mp->ip_address, mp->priority, mp->weight);
2201     }
2202
2203   fformat (vam->ofp, "%v", s);
2204   vec_free (s);
2205 }
2206
2207 static void
2208 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2209                                             mp)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   vat_json_node_t *node = NULL;
2213   struct in6_addr ip6;
2214   struct in_addr ip4;
2215
2216   if (VAT_JSON_ARRAY != vam->json_tree.type)
2217     {
2218       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2219       vat_json_init_array (&vam->json_tree);
2220     }
2221   node = vat_json_array_add (&vam->json_tree);
2222   vat_json_init_object (node);
2223
2224   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2225   vat_json_object_add_uint (node, "priority", mp->priority);
2226   vat_json_object_add_uint (node, "weight", mp->weight);
2227
2228   if (mp->local)
2229     vat_json_object_add_uint (node, "sw_if_index",
2230                               clib_net_to_host_u32 (mp->sw_if_index));
2231   else
2232     {
2233       if (mp->is_ipv6)
2234         {
2235           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2236           vat_json_object_add_ip6 (node, "address", ip6);
2237         }
2238       else
2239         {
2240           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2241           vat_json_object_add_ip4 (node, "address", ip4);
2242         }
2243     }
2244 }
2245
2246 static void
2247 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2248                                            mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   u8 *ls_name = 0;
2252
2253   ls_name = format (0, "%s", mp->ls_name);
2254
2255   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2256            ls_name);
2257   vec_free (ls_name);
2258 }
2259
2260 static void
2261   vl_api_lisp_locator_set_details_t_handler_json
2262   (vl_api_lisp_locator_set_details_t * mp)
2263 {
2264   vat_main_t *vam = &vat_main;
2265   vat_json_node_t *node = 0;
2266   u8 *ls_name = 0;
2267
2268   ls_name = format (0, "%s", mp->ls_name);
2269   vec_add1 (ls_name, 0);
2270
2271   if (VAT_JSON_ARRAY != vam->json_tree.type)
2272     {
2273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2274       vat_json_init_array (&vam->json_tree);
2275     }
2276   node = vat_json_array_add (&vam->json_tree);
2277
2278   vat_json_init_object (node);
2279   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2280   vat_json_object_add_uint (node, "ls_index",
2281                             clib_net_to_host_u32 (mp->ls_index));
2282   vec_free (ls_name);
2283 }
2284
2285 static u8 *
2286 format_lisp_flat_eid (u8 * s, va_list * args)
2287 {
2288   u32 type = va_arg (*args, u32);
2289   u8 *eid = va_arg (*args, u8 *);
2290   u32 eid_len = va_arg (*args, u32);
2291
2292   switch (type)
2293     {
2294     case 0:
2295       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2296     case 1:
2297       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2298     case 2:
2299       return format (s, "%U", format_ethernet_address, eid);
2300     }
2301   return 0;
2302 }
2303
2304 static u8 *
2305 format_lisp_eid_vat (u8 * s, va_list * args)
2306 {
2307   u32 type = va_arg (*args, u32);
2308   u8 *eid = va_arg (*args, u8 *);
2309   u32 eid_len = va_arg (*args, u32);
2310   u8 *seid = va_arg (*args, u8 *);
2311   u32 seid_len = va_arg (*args, u32);
2312   u32 is_src_dst = va_arg (*args, u32);
2313
2314   if (is_src_dst)
2315     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2316
2317   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2318
2319   return s;
2320 }
2321
2322 static void
2323 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2324 {
2325   vat_main_t *vam = &vat_main;
2326   u8 *s = 0, *eid = 0;
2327
2328   if (~0 == mp->locator_set_index)
2329     s = format (0, "action: %d", mp->action);
2330   else
2331     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2332
2333   eid = format (0, "%U", format_lisp_eid_vat,
2334                 mp->eid_type,
2335                 mp->eid,
2336                 mp->eid_prefix_len,
2337                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2338   vec_add1 (eid, 0);
2339
2340   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2341            clib_net_to_host_u32 (mp->vni),
2342            eid,
2343            mp->is_local ? "local" : "remote",
2344            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2345   vec_free (s);
2346   vec_free (eid);
2347 }
2348
2349 static void
2350 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2351                                               * mp)
2352 {
2353   vat_main_t *vam = &vat_main;
2354   vat_json_node_t *node = 0;
2355   u8 *eid = 0;
2356
2357   if (VAT_JSON_ARRAY != vam->json_tree.type)
2358     {
2359       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2360       vat_json_init_array (&vam->json_tree);
2361     }
2362   node = vat_json_array_add (&vam->json_tree);
2363
2364   vat_json_init_object (node);
2365   if (~0 == mp->locator_set_index)
2366     vat_json_object_add_uint (node, "action", mp->action);
2367   else
2368     vat_json_object_add_uint (node, "locator_set_index",
2369                               clib_net_to_host_u32 (mp->locator_set_index));
2370
2371   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2372   eid = format (0, "%U", format_lisp_eid_vat,
2373                 mp->eid_type,
2374                 mp->eid,
2375                 mp->eid_prefix_len,
2376                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2377   vec_add1 (eid, 0);
2378   vat_json_object_add_string_copy (node, "eid", eid);
2379   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2380   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2381   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2382   vec_free (eid);
2383 }
2384
2385 static void
2386   vl_api_lisp_eid_table_map_details_t_handler
2387   (vl_api_lisp_eid_table_map_details_t * mp)
2388 {
2389   vat_main_t *vam = &vat_main;
2390
2391   u8 *line = format (0, "%=10d%=10d",
2392                      clib_net_to_host_u32 (mp->vni),
2393                      clib_net_to_host_u32 (mp->dp_table));
2394   fformat (vam->ofp, "%v\n", line);
2395   vec_free (line);
2396 }
2397
2398 static void
2399   vl_api_lisp_eid_table_map_details_t_handler_json
2400   (vl_api_lisp_eid_table_map_details_t * mp)
2401 {
2402   vat_main_t *vam = &vat_main;
2403   vat_json_node_t *node = NULL;
2404
2405   if (VAT_JSON_ARRAY != vam->json_tree.type)
2406     {
2407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2408       vat_json_init_array (&vam->json_tree);
2409     }
2410   node = vat_json_array_add (&vam->json_tree);
2411   vat_json_init_object (node);
2412   vat_json_object_add_uint (node, "dp_table",
2413                             clib_net_to_host_u32 (mp->dp_table));
2414   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2415 }
2416
2417 static void
2418   vl_api_lisp_eid_table_vni_details_t_handler
2419   (vl_api_lisp_eid_table_vni_details_t * mp)
2420 {
2421   vat_main_t *vam = &vat_main;
2422
2423   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2424   fformat (vam->ofp, "%v\n", line);
2425   vec_free (line);
2426 }
2427
2428 static void
2429   vl_api_lisp_eid_table_vni_details_t_handler_json
2430   (vl_api_lisp_eid_table_vni_details_t * mp)
2431 {
2432   vat_main_t *vam = &vat_main;
2433   vat_json_node_t *node = NULL;
2434
2435   if (VAT_JSON_ARRAY != vam->json_tree.type)
2436     {
2437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2438       vat_json_init_array (&vam->json_tree);
2439     }
2440   node = vat_json_array_add (&vam->json_tree);
2441   vat_json_init_object (node);
2442   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2443 }
2444
2445 static u8 *
2446 format_decap_next (u8 * s, va_list * args)
2447 {
2448   u32 next_index = va_arg (*args, u32);
2449
2450   switch (next_index)
2451     {
2452     case LISP_GPE_INPUT_NEXT_DROP:
2453       return format (s, "drop");
2454     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2455       return format (s, "ip4");
2456     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2457       return format (s, "ip6");
2458     default:
2459       return format (s, "unknown %d", next_index);
2460     }
2461   return s;
2462 }
2463
2464 static void
2465 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2466                                           mp)
2467 {
2468   vat_main_t *vam = &vat_main;
2469   u8 *iid_str;
2470   u8 *flag_str = NULL;
2471
2472   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2473
2474 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2475   foreach_lisp_gpe_flag_bit;
2476 #undef _
2477
2478   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2479            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2480            mp->tunnels,
2481            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2482            mp->source_ip,
2483            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2484            mp->destination_ip,
2485            ntohl (mp->encap_fib_id),
2486            ntohl (mp->decap_fib_id),
2487            format_decap_next, ntohl (mp->dcap_next),
2488            mp->ver_res >> 6,
2489            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2490
2491   vec_free (iid_str);
2492 }
2493
2494 static void
2495   vl_api_lisp_gpe_tunnel_details_t_handler_json
2496   (vl_api_lisp_gpe_tunnel_details_t * mp)
2497 {
2498   vat_main_t *vam = &vat_main;
2499   vat_json_node_t *node = NULL;
2500   struct in6_addr ip6;
2501   struct in_addr ip4;
2502   u8 *next_decap_str;
2503
2504   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2505
2506   if (VAT_JSON_ARRAY != vam->json_tree.type)
2507     {
2508       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2509       vat_json_init_array (&vam->json_tree);
2510     }
2511   node = vat_json_array_add (&vam->json_tree);
2512
2513   vat_json_init_object (node);
2514   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2515   if (mp->is_ipv6)
2516     {
2517       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2518       vat_json_object_add_ip6 (node, "source address", ip6);
2519       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2520       vat_json_object_add_ip6 (node, "destination address", ip6);
2521     }
2522   else
2523     {
2524       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2525       vat_json_object_add_ip4 (node, "source address", ip4);
2526       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2527       vat_json_object_add_ip4 (node, "destination address", ip4);
2528     }
2529   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2530   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2531   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2532   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2533   vat_json_object_add_uint (node, "flags", mp->flags);
2534   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2535   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2536   vat_json_object_add_uint (node, "res", mp->res);
2537   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2538
2539   vec_free (next_decap_str);
2540 }
2541
2542 static void
2543   vl_api_lisp_adjacencies_get_reply_t_handler
2544   (vl_api_lisp_adjacencies_get_reply_t * mp)
2545 {
2546   vat_main_t *vam = &vat_main;
2547   u32 i, n;
2548   int retval = clib_net_to_host_u32 (mp->retval);
2549   vl_api_lisp_adjacency_t *a;
2550
2551   if (retval)
2552     goto end;
2553
2554   n = clib_net_to_host_u32 (mp->count);
2555
2556   for (i = 0; i < n; i++)
2557     {
2558       a = &mp->adjacencies[i];
2559       fformat (vam->ofp, "%U %40U\n",
2560                format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2561                format_lisp_flat_eid, a->eid_type, a->reid,
2562                a->reid_prefix_len);
2563     }
2564
2565 end:
2566   vam->retval = retval;
2567   vam->result_ready = 1;
2568 }
2569
2570 static void
2571   vl_api_lisp_adjacencies_get_reply_t_handler_json
2572   (vl_api_lisp_adjacencies_get_reply_t * mp)
2573 {
2574   u8 *s = 0;
2575   vat_main_t *vam = &vat_main;
2576   vat_json_node_t *e = 0, root;
2577   u32 i, n;
2578   int retval = clib_net_to_host_u32 (mp->retval);
2579   vl_api_lisp_adjacency_t *a;
2580
2581   if (retval)
2582     goto end;
2583
2584   n = clib_net_to_host_u32 (mp->count);
2585   vat_json_init_array (&root);
2586
2587   for (i = 0; i < n; i++)
2588     {
2589       e = vat_json_array_add (&root);
2590       a = &mp->adjacencies[i];
2591
2592       vat_json_init_object (e);
2593       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2594                   a->leid_prefix_len);
2595       vec_add1 (s, 0);
2596       vat_json_object_add_string_copy (e, "leid", s);
2597       vec_free (s);
2598
2599       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2600                   a->reid_prefix_len);
2601       vec_add1 (s, 0);
2602       vat_json_object_add_string_copy (e, "reid", s);
2603       vec_free (s);
2604     }
2605
2606   vat_json_print (vam->ofp, &root);
2607   vat_json_free (&root);
2608
2609 end:
2610   vam->retval = retval;
2611   vam->result_ready = 1;
2612 }
2613
2614 static void
2615 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2616                                             * mp)
2617 {
2618   vat_main_t *vam = &vat_main;
2619
2620   fformat (vam->ofp, "%=20U\n",
2621            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2622            mp->ip_address);
2623 }
2624
2625 static void
2626   vl_api_lisp_map_resolver_details_t_handler_json
2627   (vl_api_lisp_map_resolver_details_t * mp)
2628 {
2629   vat_main_t *vam = &vat_main;
2630   vat_json_node_t *node = NULL;
2631   struct in6_addr ip6;
2632   struct in_addr ip4;
2633
2634   if (VAT_JSON_ARRAY != vam->json_tree.type)
2635     {
2636       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2637       vat_json_init_array (&vam->json_tree);
2638     }
2639   node = vat_json_array_add (&vam->json_tree);
2640
2641   vat_json_init_object (node);
2642   if (mp->is_ipv6)
2643     {
2644       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2645       vat_json_object_add_ip6 (node, "map resolver", ip6);
2646     }
2647   else
2648     {
2649       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2650       vat_json_object_add_ip4 (node, "map resolver", ip4);
2651     }
2652 }
2653
2654 static void
2655   vl_api_show_lisp_status_reply_t_handler
2656   (vl_api_show_lisp_status_reply_t * mp)
2657 {
2658   vat_main_t *vam = &vat_main;
2659   i32 retval = ntohl (mp->retval);
2660
2661   if (0 <= retval)
2662     {
2663       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2664                mp->feature_status ? "enabled" : "disabled",
2665                mp->gpe_status ? "enabled" : "disabled");
2666     }
2667
2668   vam->retval = retval;
2669   vam->result_ready = 1;
2670 }
2671
2672 static void
2673   vl_api_show_lisp_status_reply_t_handler_json
2674   (vl_api_show_lisp_status_reply_t * mp)
2675 {
2676   vat_main_t *vam = &vat_main;
2677   vat_json_node_t node;
2678   u8 *gpe_status = NULL;
2679   u8 *feature_status = NULL;
2680
2681   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2682   feature_status = format (0, "%s",
2683                            mp->feature_status ? "enabled" : "disabled");
2684   vec_add1 (gpe_status, 0);
2685   vec_add1 (feature_status, 0);
2686
2687   vat_json_init_object (&node);
2688   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2689   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2690
2691   vec_free (gpe_status);
2692   vec_free (feature_status);
2693
2694   vat_json_print (vam->ofp, &node);
2695   vat_json_free (&node);
2696
2697   vam->retval = ntohl (mp->retval);
2698   vam->result_ready = 1;
2699 }
2700
2701 static void
2702   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2703   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2704 {
2705   vat_main_t *vam = &vat_main;
2706   i32 retval = ntohl (mp->retval);
2707
2708   if (retval >= 0)
2709     {
2710       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2711     }
2712
2713   vam->retval = retval;
2714   vam->result_ready = 1;
2715 }
2716
2717 static void
2718   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2719   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2720 {
2721   vat_main_t *vam = &vat_main;
2722   vat_json_node_t *node = NULL;
2723
2724   if (VAT_JSON_ARRAY != vam->json_tree.type)
2725     {
2726       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2727       vat_json_init_array (&vam->json_tree);
2728     }
2729   node = vat_json_array_add (&vam->json_tree);
2730
2731   vat_json_init_object (node);
2732   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2733
2734   vat_json_print (vam->ofp, node);
2735   vat_json_free (node);
2736
2737   vam->retval = ntohl (mp->retval);
2738   vam->result_ready = 1;
2739 }
2740
2741 static u8 *
2742 format_lisp_map_request_mode (u8 * s, va_list * args)
2743 {
2744   u32 mode = va_arg (*args, u32);
2745
2746   switch (mode)
2747     {
2748     case 0:
2749       return format (0, "dst-only");
2750     case 1:
2751       return format (0, "src-dst");
2752     }
2753   return 0;
2754 }
2755
2756 static void
2757   vl_api_show_lisp_map_request_mode_reply_t_handler
2758   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2759 {
2760   vat_main_t *vam = &vat_main;
2761   i32 retval = ntohl (mp->retval);
2762
2763   if (0 <= retval)
2764     {
2765       u32 mode = mp->mode;
2766       fformat (vam->ofp, "map_request_mode: %U\n",
2767                format_lisp_map_request_mode, mode);
2768     }
2769
2770   vam->retval = retval;
2771   vam->result_ready = 1;
2772 }
2773
2774 static void
2775   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2776   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2777 {
2778   vat_main_t *vam = &vat_main;
2779   vat_json_node_t node;
2780   u8 *s = 0;
2781   u32 mode;
2782
2783   mode = mp->mode;
2784   s = format (0, "%U", format_lisp_map_request_mode, mode);
2785   vec_add1 (s, 0);
2786
2787   vat_json_init_object (&node);
2788   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2789   vat_json_print (vam->ofp, &node);
2790   vat_json_free (&node);
2791
2792   vec_free (s);
2793   vam->retval = ntohl (mp->retval);
2794   vam->result_ready = 1;
2795 }
2796
2797 static void
2798 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2799 {
2800   vat_main_t *vam = &vat_main;
2801   i32 retval = ntohl (mp->retval);
2802
2803   if (0 <= retval)
2804     {
2805       fformat (vam->ofp, "%-20s%-16s\n",
2806                mp->status ? "enabled" : "disabled",
2807                mp->status ? (char *) mp->locator_set_name : "");
2808     }
2809
2810   vam->retval = retval;
2811   vam->result_ready = 1;
2812 }
2813
2814 static void
2815 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2816                                             mp)
2817 {
2818   vat_main_t *vam = &vat_main;
2819   vat_json_node_t node;
2820   u8 *status = 0;
2821
2822   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2823   vec_add1 (status, 0);
2824
2825   vat_json_init_object (&node);
2826   vat_json_object_add_string_copy (&node, "status", status);
2827   if (mp->status)
2828     {
2829       vat_json_object_add_string_copy (&node, "locator_set",
2830                                        mp->locator_set_name);
2831     }
2832
2833   vec_free (status);
2834
2835   vat_json_print (vam->ofp, &node);
2836   vat_json_free (&node);
2837
2838   vam->retval = ntohl (mp->retval);
2839   vam->result_ready = 1;
2840 }
2841
2842 static u8 *
2843 format_policer_type (u8 * s, va_list * va)
2844 {
2845   u32 i = va_arg (*va, u32);
2846
2847   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2848     s = format (s, "1r2c");
2849   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2850     s = format (s, "1r3c");
2851   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2852     s = format (s, "2r3c-2698");
2853   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2854     s = format (s, "2r3c-4115");
2855   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2856     s = format (s, "2r3c-mef5cf1");
2857   else
2858     s = format (s, "ILLEGAL");
2859   return s;
2860 }
2861
2862 static u8 *
2863 format_policer_rate_type (u8 * s, va_list * va)
2864 {
2865   u32 i = va_arg (*va, u32);
2866
2867   if (i == SSE2_QOS_RATE_KBPS)
2868     s = format (s, "kbps");
2869   else if (i == SSE2_QOS_RATE_PPS)
2870     s = format (s, "pps");
2871   else
2872     s = format (s, "ILLEGAL");
2873   return s;
2874 }
2875
2876 static u8 *
2877 format_policer_round_type (u8 * s, va_list * va)
2878 {
2879   u32 i = va_arg (*va, u32);
2880
2881   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2882     s = format (s, "closest");
2883   else if (i == SSE2_QOS_ROUND_TO_UP)
2884     s = format (s, "up");
2885   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2886     s = format (s, "down");
2887   else
2888     s = format (s, "ILLEGAL");
2889   return s;
2890 }
2891
2892 static u8 *
2893 format_policer_action_type (u8 * s, va_list * va)
2894 {
2895   u32 i = va_arg (*va, u32);
2896
2897   if (i == SSE2_QOS_ACTION_DROP)
2898     s = format (s, "drop");
2899   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2900     s = format (s, "transmit");
2901   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2902     s = format (s, "mark-and-transmit");
2903   else
2904     s = format (s, "ILLEGAL");
2905   return s;
2906 }
2907
2908 static u8 *
2909 format_dscp (u8 * s, va_list * va)
2910 {
2911   u32 i = va_arg (*va, u32);
2912   char *t = 0;
2913
2914   switch (i)
2915     {
2916 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2917       foreach_vnet_dscp
2918 #undef _
2919     default:
2920       return format (s, "ILLEGAL");
2921     }
2922   s = format (s, "%s", t);
2923   return s;
2924 }
2925
2926 static void
2927 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2928 {
2929   vat_main_t *vam = &vat_main;
2930   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2931
2932   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2933     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2934   else
2935     conform_dscp_str = format (0, "");
2936
2937   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2938     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2939   else
2940     exceed_dscp_str = format (0, "");
2941
2942   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2943     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2944   else
2945     violate_dscp_str = format (0, "");
2946
2947   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2948            "rate type %U, round type %U, %s rate, %s color-aware, "
2949            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2950            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2951            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2952            mp->name,
2953            format_policer_type, mp->type,
2954            ntohl (mp->cir),
2955            ntohl (mp->eir),
2956            clib_net_to_host_u64 (mp->cb),
2957            clib_net_to_host_u64 (mp->eb),
2958            format_policer_rate_type, mp->rate_type,
2959            format_policer_round_type, mp->round_type,
2960            mp->single_rate ? "single" : "dual",
2961            mp->color_aware ? "is" : "not",
2962            ntohl (mp->cir_tokens_per_period),
2963            ntohl (mp->pir_tokens_per_period),
2964            ntohl (mp->scale),
2965            ntohl (mp->current_limit),
2966            ntohl (mp->current_bucket),
2967            ntohl (mp->extended_limit),
2968            ntohl (mp->extended_bucket),
2969            clib_net_to_host_u64 (mp->last_update_time),
2970            format_policer_action_type, mp->conform_action_type,
2971            conform_dscp_str,
2972            format_policer_action_type, mp->exceed_action_type,
2973            exceed_dscp_str,
2974            format_policer_action_type, mp->violate_action_type,
2975            violate_dscp_str);
2976
2977   vec_free (conform_dscp_str);
2978   vec_free (exceed_dscp_str);
2979   vec_free (violate_dscp_str);
2980 }
2981
2982 static void vl_api_policer_details_t_handler_json
2983   (vl_api_policer_details_t * mp)
2984 {
2985   vat_main_t *vam = &vat_main;
2986   vat_json_node_t *node;
2987   u8 *rate_type_str, *round_type_str, *type_str;
2988   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2989
2990   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2991   round_type_str =
2992     format (0, "%U", format_policer_round_type, mp->round_type);
2993   type_str = format (0, "%U", format_policer_type, mp->type);
2994   conform_action_str = format (0, "%U", format_policer_action_type,
2995                                mp->conform_action_type);
2996   exceed_action_str = format (0, "%U", format_policer_action_type,
2997                               mp->exceed_action_type);
2998   violate_action_str = format (0, "%U", format_policer_action_type,
2999                                mp->violate_action_type);
3000
3001   if (VAT_JSON_ARRAY != vam->json_tree.type)
3002     {
3003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3004       vat_json_init_array (&vam->json_tree);
3005     }
3006   node = vat_json_array_add (&vam->json_tree);
3007
3008   vat_json_init_object (node);
3009   vat_json_object_add_string_copy (node, "name", mp->name);
3010   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3011   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3012   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3013   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3014   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3015   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3016   vat_json_object_add_string_copy (node, "type", type_str);
3017   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3018   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3019   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3020   vat_json_object_add_uint (node, "cir_tokens_per_period",
3021                             ntohl (mp->cir_tokens_per_period));
3022   vat_json_object_add_uint (node, "eir_tokens_per_period",
3023                             ntohl (mp->pir_tokens_per_period));
3024   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3025   vat_json_object_add_uint (node, "current_bucket",
3026                             ntohl (mp->current_bucket));
3027   vat_json_object_add_uint (node, "extended_limit",
3028                             ntohl (mp->extended_limit));
3029   vat_json_object_add_uint (node, "extended_bucket",
3030                             ntohl (mp->extended_bucket));
3031   vat_json_object_add_uint (node, "last_update_time",
3032                             ntohl (mp->last_update_time));
3033   vat_json_object_add_string_copy (node, "conform_action",
3034                                    conform_action_str);
3035   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3036     {
3037       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3038       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3039       vec_free (dscp_str);
3040     }
3041   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3042   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3043     {
3044       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3045       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3046       vec_free (dscp_str);
3047     }
3048   vat_json_object_add_string_copy (node, "violate_action",
3049                                    violate_action_str);
3050   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3051     {
3052       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3053       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3054       vec_free (dscp_str);
3055     }
3056
3057   vec_free (rate_type_str);
3058   vec_free (round_type_str);
3059   vec_free (type_str);
3060   vec_free (conform_action_str);
3061   vec_free (exceed_action_str);
3062   vec_free (violate_action_str);
3063 }
3064
3065 static void
3066 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3067                                            mp)
3068 {
3069   vat_main_t *vam = &vat_main;
3070   int i, count = ntohl (mp->count);
3071
3072   if (count > 0)
3073     fformat (vam->ofp, "classify table ids (%d) : ", count);
3074   for (i = 0; i < count; i++)
3075     {
3076       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3077       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3078     }
3079   vam->retval = ntohl (mp->retval);
3080   vam->result_ready = 1;
3081 }
3082
3083 static void
3084   vl_api_classify_table_ids_reply_t_handler_json
3085   (vl_api_classify_table_ids_reply_t * mp)
3086 {
3087   vat_main_t *vam = &vat_main;
3088   int i, count = ntohl (mp->count);
3089
3090   if (count > 0)
3091     {
3092       vat_json_node_t node;
3093
3094       vat_json_init_object (&node);
3095       for (i = 0; i < count; i++)
3096         {
3097           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3098         }
3099       vat_json_print (vam->ofp, &node);
3100       vat_json_free (&node);
3101     }
3102   vam->retval = ntohl (mp->retval);
3103   vam->result_ready = 1;
3104 }
3105
3106 static void
3107   vl_api_classify_table_by_interface_reply_t_handler
3108   (vl_api_classify_table_by_interface_reply_t * mp)
3109 {
3110   vat_main_t *vam = &vat_main;
3111   u32 table_id;
3112
3113   table_id = ntohl (mp->l2_table_id);
3114   if (table_id != ~0)
3115     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3116   else
3117     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3118   table_id = ntohl (mp->ip4_table_id);
3119   if (table_id != ~0)
3120     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3121   else
3122     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3123   table_id = ntohl (mp->ip6_table_id);
3124   if (table_id != ~0)
3125     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3126   else
3127     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3128   vam->retval = ntohl (mp->retval);
3129   vam->result_ready = 1;
3130 }
3131
3132 static void
3133   vl_api_classify_table_by_interface_reply_t_handler_json
3134   (vl_api_classify_table_by_interface_reply_t * mp)
3135 {
3136   vat_main_t *vam = &vat_main;
3137   vat_json_node_t node;
3138
3139   vat_json_init_object (&node);
3140
3141   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3142   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3143   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3144
3145   vat_json_print (vam->ofp, &node);
3146   vat_json_free (&node);
3147
3148   vam->retval = ntohl (mp->retval);
3149   vam->result_ready = 1;
3150 }
3151
3152 static void vl_api_policer_add_del_reply_t_handler
3153   (vl_api_policer_add_del_reply_t * mp)
3154 {
3155   vat_main_t *vam = &vat_main;
3156   i32 retval = ntohl (mp->retval);
3157   if (vam->async_mode)
3158     {
3159       vam->async_errors += (retval < 0);
3160     }
3161   else
3162     {
3163       vam->retval = retval;
3164       vam->result_ready = 1;
3165       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3166         /*
3167          * Note: this is just barely thread-safe, depends on
3168          * the main thread spinning waiting for an answer...
3169          */
3170         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3171     }
3172 }
3173
3174 static void vl_api_policer_add_del_reply_t_handler_json
3175   (vl_api_policer_add_del_reply_t * mp)
3176 {
3177   vat_main_t *vam = &vat_main;
3178   vat_json_node_t node;
3179
3180   vat_json_init_object (&node);
3181   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3182   vat_json_object_add_uint (&node, "policer_index",
3183                             ntohl (mp->policer_index));
3184
3185   vat_json_print (vam->ofp, &node);
3186   vat_json_free (&node);
3187
3188   vam->retval = ntohl (mp->retval);
3189   vam->result_ready = 1;
3190 }
3191
3192 /* Format hex dump. */
3193 u8 *
3194 format_hex_bytes (u8 * s, va_list * va)
3195 {
3196   u8 *bytes = va_arg (*va, u8 *);
3197   int n_bytes = va_arg (*va, int);
3198   uword i;
3199
3200   /* Print short or long form depending on byte count. */
3201   uword short_form = n_bytes <= 32;
3202   uword indent = format_get_indent (s);
3203
3204   if (n_bytes == 0)
3205     return s;
3206
3207   for (i = 0; i < n_bytes; i++)
3208     {
3209       if (!short_form && (i % 32) == 0)
3210         s = format (s, "%08x: ", i);
3211       s = format (s, "%02x", bytes[i]);
3212       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3213         s = format (s, "\n%U", format_white_space, indent);
3214     }
3215
3216   return s;
3217 }
3218
3219 static void
3220 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3221                                             * mp)
3222 {
3223   vat_main_t *vam = &vat_main;
3224   i32 retval = ntohl (mp->retval);
3225   if (retval == 0)
3226     {
3227       fformat (vam->ofp, "classify table info :\n");
3228       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3229                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3230                ntohl (mp->miss_next_index));
3231       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3232                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3233                ntohl (mp->match_n_vectors));
3234       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3235                ntohl (mp->mask_length));
3236     }
3237   vam->retval = retval;
3238   vam->result_ready = 1;
3239 }
3240
3241 static void
3242   vl_api_classify_table_info_reply_t_handler_json
3243   (vl_api_classify_table_info_reply_t * mp)
3244 {
3245   vat_main_t *vam = &vat_main;
3246   vat_json_node_t node;
3247
3248   i32 retval = ntohl (mp->retval);
3249   if (retval == 0)
3250     {
3251       vat_json_init_object (&node);
3252
3253       vat_json_object_add_int (&node, "sessions",
3254                                ntohl (mp->active_sessions));
3255       vat_json_object_add_int (&node, "nexttbl",
3256                                ntohl (mp->next_table_index));
3257       vat_json_object_add_int (&node, "nextnode",
3258                                ntohl (mp->miss_next_index));
3259       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3260       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3261       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3262       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3263                       ntohl (mp->mask_length), 0);
3264       vat_json_object_add_string_copy (&node, "mask", s);
3265
3266       vat_json_print (vam->ofp, &node);
3267       vat_json_free (&node);
3268     }
3269   vam->retval = ntohl (mp->retval);
3270   vam->result_ready = 1;
3271 }
3272
3273 static void
3274 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3275                                            mp)
3276 {
3277   vat_main_t *vam = &vat_main;
3278
3279   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3280            ntohl (mp->hit_next_index), ntohl (mp->advance),
3281            ntohl (mp->opaque_index));
3282   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3283            ntohl (mp->match_length));
3284 }
3285
3286 static void
3287   vl_api_classify_session_details_t_handler_json
3288   (vl_api_classify_session_details_t * mp)
3289 {
3290   vat_main_t *vam = &vat_main;
3291   vat_json_node_t *node = NULL;
3292
3293   if (VAT_JSON_ARRAY != vam->json_tree.type)
3294     {
3295       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3296       vat_json_init_array (&vam->json_tree);
3297     }
3298   node = vat_json_array_add (&vam->json_tree);
3299
3300   vat_json_init_object (node);
3301   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3302   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3303   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3304   u8 *s =
3305     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3306             0);
3307   vat_json_object_add_string_copy (node, "match", s);
3308 }
3309
3310 static void vl_api_pg_create_interface_reply_t_handler
3311   (vl_api_pg_create_interface_reply_t * mp)
3312 {
3313   vat_main_t *vam = &vat_main;
3314
3315   vam->retval = ntohl (mp->retval);
3316   vam->result_ready = 1;
3317 }
3318
3319 static void vl_api_pg_create_interface_reply_t_handler_json
3320   (vl_api_pg_create_interface_reply_t * mp)
3321 {
3322   vat_main_t *vam = &vat_main;
3323   vat_json_node_t node;
3324
3325   i32 retval = ntohl (mp->retval);
3326   if (retval == 0)
3327     {
3328       vat_json_init_object (&node);
3329
3330       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3331
3332       vat_json_print (vam->ofp, &node);
3333       vat_json_free (&node);
3334     }
3335   vam->retval = ntohl (mp->retval);
3336   vam->result_ready = 1;
3337 }
3338
3339 static void vl_api_policer_classify_details_t_handler
3340   (vl_api_policer_classify_details_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343
3344   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3345            ntohl (mp->table_index));
3346 }
3347
3348 static void vl_api_policer_classify_details_t_handler_json
3349   (vl_api_policer_classify_details_t * mp)
3350 {
3351   vat_main_t *vam = &vat_main;
3352   vat_json_node_t *node;
3353
3354   if (VAT_JSON_ARRAY != vam->json_tree.type)
3355     {
3356       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3357       vat_json_init_array (&vam->json_tree);
3358     }
3359   node = vat_json_array_add (&vam->json_tree);
3360
3361   vat_json_init_object (node);
3362   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3363   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3364 }
3365
3366 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3367   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3368 {
3369   vat_main_t *vam = &vat_main;
3370   i32 retval = ntohl (mp->retval);
3371   if (vam->async_mode)
3372     {
3373       vam->async_errors += (retval < 0);
3374     }
3375   else
3376     {
3377       vam->retval = retval;
3378       vam->sw_if_index = ntohl (mp->sw_if_index);
3379       vam->result_ready = 1;
3380     }
3381 }
3382
3383 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3384   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3385 {
3386   vat_main_t *vam = &vat_main;
3387   vat_json_node_t node;
3388
3389   vat_json_init_object (&node);
3390   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3391   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3392
3393   vat_json_print (vam->ofp, &node);
3394   vat_json_free (&node);
3395
3396   vam->retval = ntohl (mp->retval);
3397   vam->result_ready = 1;
3398 }
3399
3400 static void vl_api_flow_classify_details_t_handler
3401   (vl_api_flow_classify_details_t * mp)
3402 {
3403   vat_main_t *vam = &vat_main;
3404
3405   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3406            ntohl (mp->table_index));
3407 }
3408
3409 static void vl_api_flow_classify_details_t_handler_json
3410   (vl_api_flow_classify_details_t * mp)
3411 {
3412   vat_main_t *vam = &vat_main;
3413   vat_json_node_t *node;
3414
3415   if (VAT_JSON_ARRAY != vam->json_tree.type)
3416     {
3417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3418       vat_json_init_array (&vam->json_tree);
3419     }
3420   node = vat_json_array_add (&vam->json_tree);
3421
3422   vat_json_init_object (node);
3423   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3424   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3425 }
3426
3427
3428
3429 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3430 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3431 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3432 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3433 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3434 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3435
3436 /*
3437  * Generate boilerplate reply handlers, which
3438  * dig the return value out of the xxx_reply_t API message,
3439  * stick it into vam->retval, and set vam->result_ready
3440  *
3441  * Could also do this by pointing N message decode slots at
3442  * a single function, but that could break in subtle ways.
3443  */
3444
3445 #define foreach_standard_reply_retval_handler           \
3446 _(sw_interface_set_flags_reply)                         \
3447 _(sw_interface_add_del_address_reply)                   \
3448 _(sw_interface_set_table_reply)                         \
3449 _(sw_interface_set_mpls_enable_reply)                   \
3450 _(sw_interface_set_vpath_reply)                         \
3451 _(sw_interface_set_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 _(mpls_add_del_encap_reply)                             \
3465 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3466 _(sw_interface_set_unnumbered_reply)                    \
3467 _(ip_neighbor_add_del_reply)                            \
3468 _(reset_vrf_reply)                                      \
3469 _(oam_add_del_reply)                                    \
3470 _(reset_fib_reply)                                      \
3471 _(dhcp_proxy_config_reply)                              \
3472 _(dhcp_proxy_config_2_reply)                            \
3473 _(dhcp_proxy_set_vss_reply)                             \
3474 _(dhcp_client_config_reply)                             \
3475 _(set_ip_flow_hash_reply)                               \
3476 _(sw_interface_ip6_enable_disable_reply)                \
3477 _(sw_interface_ip6_set_link_local_address_reply)        \
3478 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3479 _(sw_interface_ip6nd_ra_config_reply)                   \
3480 _(set_arp_neighbor_limit_reply)                         \
3481 _(l2_patch_add_del_reply)                               \
3482 _(sr_tunnel_add_del_reply)                              \
3483 _(sr_policy_add_del_reply)                              \
3484 _(sr_multicast_map_add_del_reply)                       \
3485 _(classify_add_del_session_reply)                       \
3486 _(classify_set_interface_ip_table_reply)                \
3487 _(classify_set_interface_l2_tables_reply)               \
3488 _(l2tpv3_set_tunnel_cookies_reply)                      \
3489 _(l2tpv3_interface_enable_disable_reply)                \
3490 _(l2tpv3_set_lookup_key_reply)                          \
3491 _(l2_fib_clear_table_reply)                             \
3492 _(l2_interface_efp_filter_reply)                        \
3493 _(l2_interface_vlan_tag_rewrite_reply)                  \
3494 _(modify_vhost_user_if_reply)                           \
3495 _(delete_vhost_user_if_reply)                           \
3496 _(want_ip4_arp_events_reply)                            \
3497 _(want_ip6_nd_events_reply)                             \
3498 _(input_acl_set_interface_reply)                        \
3499 _(ipsec_spd_add_del_reply)                              \
3500 _(ipsec_interface_add_del_spd_reply)                    \
3501 _(ipsec_spd_add_del_entry_reply)                        \
3502 _(ipsec_sad_add_del_entry_reply)                        \
3503 _(ipsec_sa_set_key_reply)                               \
3504 _(ikev2_profile_add_del_reply)                          \
3505 _(ikev2_profile_set_auth_reply)                         \
3506 _(ikev2_profile_set_id_reply)                           \
3507 _(ikev2_profile_set_ts_reply)                           \
3508 _(ikev2_set_local_key_reply)                            \
3509 _(delete_loopback_reply)                                \
3510 _(bd_ip_mac_add_del_reply)                              \
3511 _(map_del_domain_reply)                                 \
3512 _(map_add_del_rule_reply)                               \
3513 _(want_interface_events_reply)                          \
3514 _(want_stats_reply)                                     \
3515 _(cop_interface_enable_disable_reply)                   \
3516 _(cop_whitelist_enable_disable_reply)                   \
3517 _(sw_interface_clear_stats_reply)                       \
3518 _(ioam_enable_reply)                              \
3519 _(ioam_disable_reply)                              \
3520 _(lisp_add_del_locator_reply)                           \
3521 _(lisp_add_del_local_eid_reply)                         \
3522 _(lisp_add_del_remote_mapping_reply)                    \
3523 _(lisp_add_del_adjacency_reply)                         \
3524 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3525 _(lisp_add_del_map_resolver_reply)                      \
3526 _(lisp_gpe_enable_disable_reply)                        \
3527 _(lisp_gpe_add_del_iface_reply)                         \
3528 _(lisp_enable_disable_reply)                            \
3529 _(lisp_pitr_set_locator_set_reply)                      \
3530 _(lisp_map_request_mode_reply)                          \
3531 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3532 _(lisp_eid_table_add_del_map_reply)                     \
3533 _(vxlan_gpe_add_del_tunnel_reply)                       \
3534 _(af_packet_delete_reply)                               \
3535 _(policer_classify_set_interface_reply)                 \
3536 _(netmap_create_reply)                                  \
3537 _(netmap_delete_reply)                                  \
3538 _(set_ipfix_exporter_reply)                             \
3539 _(set_ipfix_classify_stream_reply)                      \
3540 _(ipfix_classify_table_add_del_reply)                   \
3541 _(flow_classify_set_interface_reply)                    \
3542 _(sw_interface_span_enable_disable_reply)               \
3543 _(pg_capture_reply)                                     \
3544 _(pg_enable_disable_reply)                              \
3545 _(ip_source_and_port_range_check_add_del_reply)         \
3546 _(ip_source_and_port_range_check_interface_add_del_reply)\
3547 _(delete_subif_reply)                                   \
3548 _(l2_interface_pbb_tag_rewrite_reply)                   \
3549 _(punt_reply)                                           \
3550 _(feature_enable_disable_reply)                         \
3551 _(sw_interface_tag_add_del_reply)
3552
3553 #define _(n)                                    \
3554     static void vl_api_##n##_t_handler          \
3555     (vl_api_##n##_t * mp)                       \
3556     {                                           \
3557         vat_main_t * vam = &vat_main;           \
3558         i32 retval = ntohl(mp->retval);         \
3559         if (vam->async_mode) {                  \
3560             vam->async_errors += (retval < 0);  \
3561         } else {                                \
3562             vam->retval = retval;               \
3563             vam->result_ready = 1;              \
3564         }                                       \
3565     }
3566 foreach_standard_reply_retval_handler;
3567 #undef _
3568
3569 #define _(n)                                    \
3570     static void vl_api_##n##_t_handler_json     \
3571     (vl_api_##n##_t * mp)                       \
3572     {                                           \
3573         vat_main_t * vam = &vat_main;           \
3574         vat_json_node_t node;                   \
3575         vat_json_init_object(&node);            \
3576         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3577         vat_json_print(vam->ofp, &node);        \
3578         vam->retval = ntohl(mp->retval);        \
3579         vam->result_ready = 1;                  \
3580     }
3581 foreach_standard_reply_retval_handler;
3582 #undef _
3583
3584 /*
3585  * Table of message reply handlers, must include boilerplate handlers
3586  * we just generated
3587  */
3588
3589 #define foreach_vpe_api_reply_msg                                       \
3590 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3591 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3592 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3593 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3594 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3595 _(CLI_REPLY, cli_reply)                                                 \
3596 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3597 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3598   sw_interface_add_del_address_reply)                                   \
3599 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3600 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3601 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3602 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3603 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3604   sw_interface_set_l2_xconnect_reply)                                   \
3605 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3606   sw_interface_set_l2_bridge_reply)                                     \
3607 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3608   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3609 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3610   sw_interface_set_dpdk_hqos_subport_reply)                             \
3611 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3612   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3613 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3614 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3615 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3616 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3617 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3618 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3619 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3620 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3621 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3622 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3623 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3624 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3625 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3626 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3627 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3628   proxy_arp_intfc_enable_disable_reply)                                 \
3629 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3630 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3631   mpls_ethernet_add_del_tunnel_reply)                                   \
3632 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3633   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3634 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3635   sw_interface_set_unnumbered_reply)                                    \
3636 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3637 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3638 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3639 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3640 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3641 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3642 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3643 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3644 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3645 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3646 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3647 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3648   sw_interface_ip6_enable_disable_reply)                                \
3649 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3650   sw_interface_ip6_set_link_local_address_reply)                        \
3651 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3652   sw_interface_ip6nd_ra_prefix_reply)                                   \
3653 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3654   sw_interface_ip6nd_ra_config_reply)                                   \
3655 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3656 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3657 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3658 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3659 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3660 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3661 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3662 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3663 classify_set_interface_ip_table_reply)                                  \
3664 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3665   classify_set_interface_l2_tables_reply)                               \
3666 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3667 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3668 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3669 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3670 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3671   l2tpv3_interface_enable_disable_reply)                                \
3672 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3673 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3674 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3675 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3676 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3677 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3678 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3679 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3680 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3681 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3682 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3683 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3684 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3685 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3686 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3687 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3688 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3689 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3690 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3691 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3692 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3693 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3694 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3695 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3696 _(IP_DETAILS, ip_details)                                               \
3697 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3698 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3699 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3700 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3701 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3702 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3703 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3704 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3705 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3706 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3707 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3708 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3709 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3710 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3711 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3712 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3713 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3714 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3715 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3716 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3717 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3718 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3719 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3720 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3721 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3722 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3723 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3724 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3725 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3726 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3727 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3728 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3729 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3730 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3731 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3732 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3733 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3734 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3735 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3736 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3737 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3738 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3739 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3740 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3741 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3742 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3743 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3744 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3745 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3746 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3747 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3748 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3749 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3750   lisp_add_del_map_request_itr_rlocs_reply)                             \
3751 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3752   lisp_get_map_request_itr_rlocs_reply)                                 \
3753 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3754 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3755 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3756 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3757 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3758 _(POLICER_DETAILS, policer_details)                                     \
3759 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3760 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3761 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3762 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3763 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3764 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3765 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3766 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3767 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3768 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3769 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3770 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3771 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3772 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3773 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3774 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3775 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3776 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3777 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3778 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3779 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3780 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3781 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3782 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3783 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3784 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3785  ip_source_and_port_range_check_add_del_reply)                          \
3786 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3787  ip_source_and_port_range_check_interface_add_del_reply)                \
3788 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3789 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3790 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3791 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3792 _(PUNT_REPLY, punt_reply)                                               \
3793 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3794 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3795 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
3796 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)
3797
3798 /* M: construct, but don't yet send a message */
3799
3800 #define M(T,t)                                  \
3801 do {                                            \
3802     vam->result_ready = 0;                      \
3803     mp = vl_msg_api_alloc(sizeof(*mp));         \
3804     memset (mp, 0, sizeof (*mp));               \
3805     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3806     mp->client_index = vam->my_client_index;    \
3807 } while(0);
3808
3809 #define M2(T,t,n)                               \
3810 do {                                            \
3811     vam->result_ready = 0;                      \
3812     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3813     memset (mp, 0, sizeof (*mp));               \
3814     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3815     mp->client_index = vam->my_client_index;    \
3816 } while(0);
3817
3818
3819 /* S: send a message */
3820 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3821
3822 /* W: wait for results, with timeout */
3823 #define W                                       \
3824 do {                                            \
3825     timeout = vat_time_now (vam) + 1.0;         \
3826                                                 \
3827     while (vat_time_now (vam) < timeout) {      \
3828         if (vam->result_ready == 1) {           \
3829             return (vam->retval);               \
3830         }                                       \
3831     }                                           \
3832     return -99;                                 \
3833 } while(0);
3834
3835 /* W2: wait for results, with timeout */
3836 #define W2(body)                                \
3837 do {                                            \
3838     timeout = vat_time_now (vam) + 1.0;         \
3839                                                 \
3840     while (vat_time_now (vam) < timeout) {      \
3841         if (vam->result_ready == 1) {           \
3842           (body);                               \
3843           return (vam->retval);                 \
3844         }                                       \
3845     }                                           \
3846     return -99;                                 \
3847 } while(0);
3848
3849 typedef struct
3850 {
3851   u8 *name;
3852   u32 value;
3853 } name_sort_t;
3854
3855
3856 #define STR_VTR_OP_CASE(op)     \
3857     case L2_VTR_ ## op:         \
3858         return "" # op;
3859
3860 static const char *
3861 str_vtr_op (u32 vtr_op)
3862 {
3863   switch (vtr_op)
3864     {
3865       STR_VTR_OP_CASE (DISABLED);
3866       STR_VTR_OP_CASE (PUSH_1);
3867       STR_VTR_OP_CASE (PUSH_2);
3868       STR_VTR_OP_CASE (POP_1);
3869       STR_VTR_OP_CASE (POP_2);
3870       STR_VTR_OP_CASE (TRANSLATE_1_1);
3871       STR_VTR_OP_CASE (TRANSLATE_1_2);
3872       STR_VTR_OP_CASE (TRANSLATE_2_1);
3873       STR_VTR_OP_CASE (TRANSLATE_2_2);
3874     }
3875
3876   return "UNKNOWN";
3877 }
3878
3879 static int
3880 dump_sub_interface_table (vat_main_t * vam)
3881 {
3882   const sw_interface_subif_t *sub = NULL;
3883
3884   if (vam->json_output)
3885     {
3886       clib_warning
3887         ("JSON output supported only for VPE API calls and dump_stats_table");
3888       return -99;
3889     }
3890
3891   fformat (vam->ofp,
3892            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3893            "Interface", "sw_if_index",
3894            "sub id", "dot1ad", "tags", "outer id",
3895            "inner id", "exact", "default", "outer any", "inner any");
3896
3897   vec_foreach (sub, vam->sw_if_subif_table)
3898   {
3899     fformat (vam->ofp,
3900              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3901              sub->interface_name,
3902              sub->sw_if_index,
3903              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3904              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3905              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3906              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3907     if (sub->vtr_op != L2_VTR_DISABLED)
3908       {
3909         fformat (vam->ofp,
3910                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3911                  "tag1: %d tag2: %d ]\n",
3912                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3913                  sub->vtr_tag1, sub->vtr_tag2);
3914       }
3915   }
3916
3917   return 0;
3918 }
3919
3920 static int
3921 name_sort_cmp (void *a1, void *a2)
3922 {
3923   name_sort_t *n1 = a1;
3924   name_sort_t *n2 = a2;
3925
3926   return strcmp ((char *) n1->name, (char *) n2->name);
3927 }
3928
3929 static int
3930 dump_interface_table (vat_main_t * vam)
3931 {
3932   hash_pair_t *p;
3933   name_sort_t *nses = 0, *ns;
3934
3935   if (vam->json_output)
3936     {
3937       clib_warning
3938         ("JSON output supported only for VPE API calls and dump_stats_table");
3939       return -99;
3940     }
3941
3942   /* *INDENT-OFF* */
3943   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3944   ({
3945     vec_add2 (nses, ns, 1);
3946     ns->name = (u8 *)(p->key);
3947     ns->value = (u32) p->value[0];
3948   }));
3949   /* *INDENT-ON* */
3950
3951   vec_sort_with_function (nses, name_sort_cmp);
3952
3953   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3954   vec_foreach (ns, nses)
3955   {
3956     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3957   }
3958   vec_free (nses);
3959   return 0;
3960 }
3961
3962 static int
3963 dump_ip_table (vat_main_t * vam, int is_ipv6)
3964 {
3965   const ip_details_t *det = NULL;
3966   const ip_address_details_t *address = NULL;
3967   u32 i = ~0;
3968
3969   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3970
3971   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3972   {
3973     i++;
3974     if (!det->present)
3975       {
3976         continue;
3977       }
3978     fformat (vam->ofp, "%-12d\n", i);
3979     fformat (vam->ofp,
3980              "            %-30s%-13s\n", "Address", "Prefix length");
3981     if (!det->addr)
3982       {
3983         continue;
3984       }
3985     vec_foreach (address, det->addr)
3986     {
3987       fformat (vam->ofp,
3988                "            %-30U%-13d\n",
3989                is_ipv6 ? format_ip6_address : format_ip4_address,
3990                address->ip, address->prefix_length);
3991     }
3992   }
3993
3994   return 0;
3995 }
3996
3997 static int
3998 dump_ipv4_table (vat_main_t * vam)
3999 {
4000   if (vam->json_output)
4001     {
4002       clib_warning
4003         ("JSON output supported only for VPE API calls and dump_stats_table");
4004       return -99;
4005     }
4006
4007   return dump_ip_table (vam, 0);
4008 }
4009
4010 static int
4011 dump_ipv6_table (vat_main_t * vam)
4012 {
4013   if (vam->json_output)
4014     {
4015       clib_warning
4016         ("JSON output supported only for VPE API calls and dump_stats_table");
4017       return -99;
4018     }
4019
4020   return dump_ip_table (vam, 1);
4021 }
4022
4023 static char *
4024 counter_type_to_str (u8 counter_type, u8 is_combined)
4025 {
4026   if (!is_combined)
4027     {
4028       switch (counter_type)
4029         {
4030         case VNET_INTERFACE_COUNTER_DROP:
4031           return "drop";
4032         case VNET_INTERFACE_COUNTER_PUNT:
4033           return "punt";
4034         case VNET_INTERFACE_COUNTER_IP4:
4035           return "ip4";
4036         case VNET_INTERFACE_COUNTER_IP6:
4037           return "ip6";
4038         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4039           return "rx-no-buf";
4040         case VNET_INTERFACE_COUNTER_RX_MISS:
4041           return "rx-miss";
4042         case VNET_INTERFACE_COUNTER_RX_ERROR:
4043           return "rx-error";
4044         case VNET_INTERFACE_COUNTER_TX_ERROR:
4045           return "tx-error";
4046         default:
4047           return "INVALID-COUNTER-TYPE";
4048         }
4049     }
4050   else
4051     {
4052       switch (counter_type)
4053         {
4054         case VNET_INTERFACE_COUNTER_RX:
4055           return "rx";
4056         case VNET_INTERFACE_COUNTER_TX:
4057           return "tx";
4058         default:
4059           return "INVALID-COUNTER-TYPE";
4060         }
4061     }
4062 }
4063
4064 static int
4065 dump_stats_table (vat_main_t * vam)
4066 {
4067   vat_json_node_t node;
4068   vat_json_node_t *msg_array;
4069   vat_json_node_t *msg;
4070   vat_json_node_t *counter_array;
4071   vat_json_node_t *counter;
4072   interface_counter_t c;
4073   u64 packets;
4074   ip4_fib_counter_t *c4;
4075   ip6_fib_counter_t *c6;
4076   int i, j;
4077
4078   if (!vam->json_output)
4079     {
4080       clib_warning ("dump_stats_table supported only in JSON format");
4081       return -99;
4082     }
4083
4084   vat_json_init_object (&node);
4085
4086   /* interface counters */
4087   msg_array = vat_json_object_add (&node, "interface_counters");
4088   vat_json_init_array (msg_array);
4089   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4090     {
4091       msg = vat_json_array_add (msg_array);
4092       vat_json_init_object (msg);
4093       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4094                                        (u8 *) counter_type_to_str (i, 0));
4095       vat_json_object_add_int (msg, "is_combined", 0);
4096       counter_array = vat_json_object_add (msg, "data");
4097       vat_json_init_array (counter_array);
4098       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4099         {
4100           packets = vam->simple_interface_counters[i][j];
4101           vat_json_array_add_uint (counter_array, packets);
4102         }
4103     }
4104   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4105     {
4106       msg = vat_json_array_add (msg_array);
4107       vat_json_init_object (msg);
4108       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4109                                        (u8 *) counter_type_to_str (i, 1));
4110       vat_json_object_add_int (msg, "is_combined", 1);
4111       counter_array = vat_json_object_add (msg, "data");
4112       vat_json_init_array (counter_array);
4113       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4114         {
4115           c = vam->combined_interface_counters[i][j];
4116           counter = vat_json_array_add (counter_array);
4117           vat_json_init_object (counter);
4118           vat_json_object_add_uint (counter, "packets", c.packets);
4119           vat_json_object_add_uint (counter, "bytes", c.bytes);
4120         }
4121     }
4122
4123   /* ip4 fib counters */
4124   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4125   vat_json_init_array (msg_array);
4126   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4127     {
4128       msg = vat_json_array_add (msg_array);
4129       vat_json_init_object (msg);
4130       vat_json_object_add_uint (msg, "vrf_id",
4131                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4132       counter_array = vat_json_object_add (msg, "c");
4133       vat_json_init_array (counter_array);
4134       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4135         {
4136           counter = vat_json_array_add (counter_array);
4137           vat_json_init_object (counter);
4138           c4 = &vam->ip4_fib_counters[i][j];
4139           vat_json_object_add_ip4 (counter, "address", c4->address);
4140           vat_json_object_add_uint (counter, "address_length",
4141                                     c4->address_length);
4142           vat_json_object_add_uint (counter, "packets", c4->packets);
4143           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4144         }
4145     }
4146
4147   /* ip6 fib counters */
4148   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4149   vat_json_init_array (msg_array);
4150   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4151     {
4152       msg = vat_json_array_add (msg_array);
4153       vat_json_init_object (msg);
4154       vat_json_object_add_uint (msg, "vrf_id",
4155                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4156       counter_array = vat_json_object_add (msg, "c");
4157       vat_json_init_array (counter_array);
4158       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4159         {
4160           counter = vat_json_array_add (counter_array);
4161           vat_json_init_object (counter);
4162           c6 = &vam->ip6_fib_counters[i][j];
4163           vat_json_object_add_ip6 (counter, "address", c6->address);
4164           vat_json_object_add_uint (counter, "address_length",
4165                                     c6->address_length);
4166           vat_json_object_add_uint (counter, "packets", c6->packets);
4167           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4168         }
4169     }
4170
4171   vat_json_print (vam->ofp, &node);
4172   vat_json_free (&node);
4173
4174   return 0;
4175 }
4176
4177 int
4178 exec (vat_main_t * vam)
4179 {
4180   api_main_t *am = &api_main;
4181   vl_api_cli_request_t *mp;
4182   f64 timeout;
4183   void *oldheap;
4184   u8 *cmd = 0;
4185   unformat_input_t *i = vam->input;
4186
4187   if (vec_len (i->buffer) == 0)
4188     return -1;
4189
4190   if (vam->exec_mode == 0 && unformat (i, "mode"))
4191     {
4192       vam->exec_mode = 1;
4193       return 0;
4194     }
4195   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4196     {
4197       vam->exec_mode = 0;
4198       return 0;
4199     }
4200
4201
4202   M (CLI_REQUEST, cli_request);
4203
4204   /*
4205    * Copy cmd into shared memory.
4206    * In order for the CLI command to work, it
4207    * must be a vector ending in \n, not a C-string ending
4208    * in \n\0.
4209    */
4210   pthread_mutex_lock (&am->vlib_rp->mutex);
4211   oldheap = svm_push_data_heap (am->vlib_rp);
4212
4213   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4214   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4215
4216   svm_pop_heap (oldheap);
4217   pthread_mutex_unlock (&am->vlib_rp->mutex);
4218
4219   mp->cmd_in_shmem = (u64) cmd;
4220   S;
4221   timeout = vat_time_now (vam) + 10.0;
4222
4223   while (vat_time_now (vam) < timeout)
4224     {
4225       if (vam->result_ready == 1)
4226         {
4227           u8 *free_me;
4228           if (vam->shmem_result != NULL)
4229             fformat (vam->ofp, "%s", vam->shmem_result);
4230           pthread_mutex_lock (&am->vlib_rp->mutex);
4231           oldheap = svm_push_data_heap (am->vlib_rp);
4232
4233           free_me = (u8 *) vam->shmem_result;
4234           vec_free (free_me);
4235
4236           svm_pop_heap (oldheap);
4237           pthread_mutex_unlock (&am->vlib_rp->mutex);
4238           return 0;
4239         }
4240     }
4241   return -99;
4242 }
4243
4244 /*
4245  * Future replacement of exec() that passes CLI buffers directly in
4246  * the API messages instead of an additional shared memory area.
4247  */
4248 static int
4249 exec_inband (vat_main_t * vam)
4250 {
4251   vl_api_cli_inband_t *mp;
4252   f64 timeout;
4253   unformat_input_t *i = vam->input;
4254
4255   if (vec_len (i->buffer) == 0)
4256     return -1;
4257
4258   if (vam->exec_mode == 0 && unformat (i, "mode"))
4259     {
4260       vam->exec_mode = 1;
4261       return 0;
4262     }
4263   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4264     {
4265       vam->exec_mode = 0;
4266       return 0;
4267     }
4268
4269   /*
4270    * In order for the CLI command to work, it
4271    * must be a vector ending in \n, not a C-string ending
4272    * in \n\0.
4273    */
4274   u32 len = vec_len (vam->input->buffer);
4275   M2 (CLI_INBAND, cli_inband, len);
4276   clib_memcpy (mp->cmd, vam->input->buffer, len);
4277   mp->length = htonl (len);
4278
4279   S;
4280   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4281 }
4282
4283 static int
4284 api_create_loopback (vat_main_t * vam)
4285 {
4286   unformat_input_t *i = vam->input;
4287   vl_api_create_loopback_t *mp;
4288   f64 timeout;
4289   u8 mac_address[6];
4290   u8 mac_set = 0;
4291
4292   memset (mac_address, 0, sizeof (mac_address));
4293
4294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4295     {
4296       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4297         mac_set = 1;
4298       else
4299         break;
4300     }
4301
4302   /* Construct the API message */
4303   M (CREATE_LOOPBACK, create_loopback);
4304   if (mac_set)
4305     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4306
4307   S;
4308   W;
4309 }
4310
4311 static int
4312 api_delete_loopback (vat_main_t * vam)
4313 {
4314   unformat_input_t *i = vam->input;
4315   vl_api_delete_loopback_t *mp;
4316   f64 timeout;
4317   u32 sw_if_index = ~0;
4318
4319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4320     {
4321       if (unformat (i, "sw_if_index %d", &sw_if_index))
4322         ;
4323       else
4324         break;
4325     }
4326
4327   if (sw_if_index == ~0)
4328     {
4329       errmsg ("missing sw_if_index\n");
4330       return -99;
4331     }
4332
4333   /* Construct the API message */
4334   M (DELETE_LOOPBACK, delete_loopback);
4335   mp->sw_if_index = ntohl (sw_if_index);
4336
4337   S;
4338   W;
4339 }
4340
4341 static int
4342 api_want_stats (vat_main_t * vam)
4343 {
4344   unformat_input_t *i = vam->input;
4345   vl_api_want_stats_t *mp;
4346   f64 timeout;
4347   int enable = -1;
4348
4349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4350     {
4351       if (unformat (i, "enable"))
4352         enable = 1;
4353       else if (unformat (i, "disable"))
4354         enable = 0;
4355       else
4356         break;
4357     }
4358
4359   if (enable == -1)
4360     {
4361       errmsg ("missing enable|disable\n");
4362       return -99;
4363     }
4364
4365   M (WANT_STATS, want_stats);
4366   mp->enable_disable = enable;
4367
4368   S;
4369   W;
4370 }
4371
4372 static int
4373 api_want_interface_events (vat_main_t * vam)
4374 {
4375   unformat_input_t *i = vam->input;
4376   vl_api_want_interface_events_t *mp;
4377   f64 timeout;
4378   int enable = -1;
4379
4380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4381     {
4382       if (unformat (i, "enable"))
4383         enable = 1;
4384       else if (unformat (i, "disable"))
4385         enable = 0;
4386       else
4387         break;
4388     }
4389
4390   if (enable == -1)
4391     {
4392       errmsg ("missing enable|disable\n");
4393       return -99;
4394     }
4395
4396   M (WANT_INTERFACE_EVENTS, want_interface_events);
4397   mp->enable_disable = enable;
4398
4399   vam->interface_event_display = enable;
4400
4401   S;
4402   W;
4403 }
4404
4405
4406 /* Note: non-static, called once to set up the initial intfc table */
4407 int
4408 api_sw_interface_dump (vat_main_t * vam)
4409 {
4410   vl_api_sw_interface_dump_t *mp;
4411   f64 timeout;
4412   hash_pair_t *p;
4413   name_sort_t *nses = 0, *ns;
4414   sw_interface_subif_t *sub = NULL;
4415
4416   /* Toss the old name table */
4417   /* *INDENT-OFF* */
4418   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4419   ({
4420     vec_add2 (nses, ns, 1);
4421     ns->name = (u8 *)(p->key);
4422     ns->value = (u32) p->value[0];
4423   }));
4424   /* *INDENT-ON* */
4425
4426   hash_free (vam->sw_if_index_by_interface_name);
4427
4428   vec_foreach (ns, nses) vec_free (ns->name);
4429
4430   vec_free (nses);
4431
4432   vec_foreach (sub, vam->sw_if_subif_table)
4433   {
4434     vec_free (sub->interface_name);
4435   }
4436   vec_free (vam->sw_if_subif_table);
4437
4438   /* recreate the interface name hash table */
4439   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4440
4441   /* Get list of ethernets */
4442   M (SW_INTERFACE_DUMP, sw_interface_dump);
4443   mp->name_filter_valid = 1;
4444   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4445   S;
4446
4447   /* and local / loopback interfaces */
4448   M (SW_INTERFACE_DUMP, sw_interface_dump);
4449   mp->name_filter_valid = 1;
4450   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4451   S;
4452
4453   /* and packet-generator interfaces */
4454   M (SW_INTERFACE_DUMP, sw_interface_dump);
4455   mp->name_filter_valid = 1;
4456   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4457   S;
4458
4459   /* and vxlan-gpe tunnel interfaces */
4460   M (SW_INTERFACE_DUMP, sw_interface_dump);
4461   mp->name_filter_valid = 1;
4462   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4463            sizeof (mp->name_filter) - 1);
4464   S;
4465
4466   /* and vxlan tunnel interfaces */
4467   M (SW_INTERFACE_DUMP, sw_interface_dump);
4468   mp->name_filter_valid = 1;
4469   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4470   S;
4471
4472   /* and host (af_packet) interfaces */
4473   M (SW_INTERFACE_DUMP, sw_interface_dump);
4474   mp->name_filter_valid = 1;
4475   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4476   S;
4477
4478   /* and l2tpv3 tunnel interfaces */
4479   M (SW_INTERFACE_DUMP, sw_interface_dump);
4480   mp->name_filter_valid = 1;
4481   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4482            sizeof (mp->name_filter) - 1);
4483   S;
4484
4485   /* and GRE tunnel interfaces */
4486   M (SW_INTERFACE_DUMP, sw_interface_dump);
4487   mp->name_filter_valid = 1;
4488   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4489   S;
4490
4491   /* and LISP-GPE interfaces */
4492   M (SW_INTERFACE_DUMP, sw_interface_dump);
4493   mp->name_filter_valid = 1;
4494   strncpy ((char *) mp->name_filter, "lisp_gpe",
4495            sizeof (mp->name_filter) - 1);
4496   S;
4497
4498   /* and IPSEC tunnel interfaces */
4499   M (SW_INTERFACE_DUMP, sw_interface_dump);
4500   mp->name_filter_valid = 1;
4501   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4502   S;
4503
4504   /* Use a control ping for synchronization */
4505   {
4506     vl_api_control_ping_t *mp;
4507     M (CONTROL_PING, control_ping);
4508     S;
4509   }
4510   W;
4511 }
4512
4513 static int
4514 api_sw_interface_set_flags (vat_main_t * vam)
4515 {
4516   unformat_input_t *i = vam->input;
4517   vl_api_sw_interface_set_flags_t *mp;
4518   f64 timeout;
4519   u32 sw_if_index;
4520   u8 sw_if_index_set = 0;
4521   u8 admin_up = 0, link_up = 0;
4522
4523   /* Parse args required to build the message */
4524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4525     {
4526       if (unformat (i, "admin-up"))
4527         admin_up = 1;
4528       else if (unformat (i, "admin-down"))
4529         admin_up = 0;
4530       else if (unformat (i, "link-up"))
4531         link_up = 1;
4532       else if (unformat (i, "link-down"))
4533         link_up = 0;
4534       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4535         sw_if_index_set = 1;
4536       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4537         sw_if_index_set = 1;
4538       else
4539         break;
4540     }
4541
4542   if (sw_if_index_set == 0)
4543     {
4544       errmsg ("missing interface name or sw_if_index\n");
4545       return -99;
4546     }
4547
4548   /* Construct the API message */
4549   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4550   mp->sw_if_index = ntohl (sw_if_index);
4551   mp->admin_up_down = admin_up;
4552   mp->link_up_down = link_up;
4553
4554   /* send it... */
4555   S;
4556
4557   /* Wait for a reply, return the good/bad news... */
4558   W;
4559 }
4560
4561 static int
4562 api_sw_interface_clear_stats (vat_main_t * vam)
4563 {
4564   unformat_input_t *i = vam->input;
4565   vl_api_sw_interface_clear_stats_t *mp;
4566   f64 timeout;
4567   u32 sw_if_index;
4568   u8 sw_if_index_set = 0;
4569
4570   /* Parse args required to build the message */
4571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4572     {
4573       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4574         sw_if_index_set = 1;
4575       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4576         sw_if_index_set = 1;
4577       else
4578         break;
4579     }
4580
4581   /* Construct the API message */
4582   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4583
4584   if (sw_if_index_set == 1)
4585     mp->sw_if_index = ntohl (sw_if_index);
4586   else
4587     mp->sw_if_index = ~0;
4588
4589   /* send it... */
4590   S;
4591
4592   /* Wait for a reply, return the good/bad news... */
4593   W;
4594 }
4595
4596 static int
4597 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4598 {
4599   unformat_input_t *i = vam->input;
4600   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4601   f64 timeout;
4602   u32 sw_if_index;
4603   u8 sw_if_index_set = 0;
4604   u32 subport;
4605   u8 subport_set = 0;
4606   u32 pipe;
4607   u8 pipe_set = 0;
4608   u32 profile;
4609   u8 profile_set = 0;
4610
4611   /* Parse args required to build the message */
4612   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4613     {
4614       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4615         sw_if_index_set = 1;
4616       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4617         sw_if_index_set = 1;
4618       else if (unformat (i, "subport %u", &subport))
4619         subport_set = 1;
4620       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4621         sw_if_index_set = 1;
4622       else if (unformat (i, "pipe %u", &pipe))
4623         pipe_set = 1;
4624       else if (unformat (i, "profile %u", &profile))
4625         profile_set = 1;
4626       else
4627         break;
4628     }
4629
4630   if (sw_if_index_set == 0)
4631     {
4632       errmsg ("missing interface name or sw_if_index\n");
4633       return -99;
4634     }
4635
4636   if (subport_set == 0)
4637     {
4638       errmsg ("missing subport \n");
4639       return -99;
4640     }
4641
4642   if (pipe_set == 0)
4643     {
4644       errmsg ("missing pipe\n");
4645       return -99;
4646     }
4647
4648   if (profile_set == 0)
4649     {
4650       errmsg ("missing profile\n");
4651       return -99;
4652     }
4653
4654   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4655
4656   mp->sw_if_index = ntohl (sw_if_index);
4657   mp->subport = ntohl (subport);
4658   mp->pipe = ntohl (pipe);
4659   mp->profile = ntohl (profile);
4660
4661
4662   S;
4663   W;
4664   /* NOTREACHED */
4665   return 0;
4666 }
4667
4668 static int
4669 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4670 {
4671   unformat_input_t *i = vam->input;
4672   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4673   f64 timeout;
4674   u32 sw_if_index;
4675   u8 sw_if_index_set = 0;
4676   u32 subport;
4677   u8 subport_set = 0;
4678   u32 tb_rate = 1250000000;     /* 10GbE */
4679   u32 tb_size = 1000000;
4680   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4681   u32 tc_period = 10;
4682
4683   /* Parse args required to build the message */
4684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4685     {
4686       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4687         sw_if_index_set = 1;
4688       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4689         sw_if_index_set = 1;
4690       else if (unformat (i, "subport %u", &subport))
4691         subport_set = 1;
4692       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4693         sw_if_index_set = 1;
4694       else if (unformat (i, "rate %u", &tb_rate))
4695         {
4696           u32 tc_id;
4697
4698           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4699                tc_id++)
4700             tc_rate[tc_id] = tb_rate;
4701         }
4702       else if (unformat (i, "bktsize %u", &tb_size))
4703         ;
4704       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4705         ;
4706       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4707         ;
4708       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4709         ;
4710       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4711         ;
4712       else if (unformat (i, "period %u", &tc_period))
4713         ;
4714       else
4715         break;
4716     }
4717
4718   if (sw_if_index_set == 0)
4719     {
4720       errmsg ("missing interface name or sw_if_index\n");
4721       return -99;
4722     }
4723
4724   if (subport_set == 0)
4725     {
4726       errmsg ("missing subport \n");
4727       return -99;
4728     }
4729
4730   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4731
4732   mp->sw_if_index = ntohl (sw_if_index);
4733   mp->subport = ntohl (subport);
4734   mp->tb_rate = ntohl (tb_rate);
4735   mp->tb_size = ntohl (tb_size);
4736   mp->tc_rate[0] = ntohl (tc_rate[0]);
4737   mp->tc_rate[1] = ntohl (tc_rate[1]);
4738   mp->tc_rate[2] = ntohl (tc_rate[2]);
4739   mp->tc_rate[3] = ntohl (tc_rate[3]);
4740   mp->tc_period = ntohl (tc_period);
4741
4742   S;
4743   W;
4744   /* NOTREACHED */
4745   return 0;
4746 }
4747
4748 static int
4749 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4750 {
4751   unformat_input_t *i = vam->input;
4752   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4753   f64 timeout;
4754   u32 sw_if_index;
4755   u8 sw_if_index_set = 0;
4756   u8 entry_set = 0;
4757   u8 tc_set = 0;
4758   u8 queue_set = 0;
4759   u32 entry, tc, queue;
4760
4761   /* Parse args required to build the message */
4762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4763     {
4764       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4765         sw_if_index_set = 1;
4766       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4767         sw_if_index_set = 1;
4768       else if (unformat (i, "entry %d", &entry))
4769         entry_set = 1;
4770       else if (unformat (i, "tc %d", &tc))
4771         tc_set = 1;
4772       else if (unformat (i, "queue %d", &queue))
4773         queue_set = 1;
4774       else
4775         break;
4776     }
4777
4778   if (sw_if_index_set == 0)
4779     {
4780       errmsg ("missing interface name or sw_if_index\n");
4781       return -99;
4782     }
4783
4784   if (entry_set == 0)
4785     {
4786       errmsg ("missing entry \n");
4787       return -99;
4788     }
4789
4790   if (tc_set == 0)
4791     {
4792       errmsg ("missing traffic class \n");
4793       return -99;
4794     }
4795
4796   if (queue_set == 0)
4797     {
4798       errmsg ("missing queue \n");
4799       return -99;
4800     }
4801
4802   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4803
4804   mp->sw_if_index = ntohl (sw_if_index);
4805   mp->entry = ntohl (entry);
4806   mp->tc = ntohl (tc);
4807   mp->queue = ntohl (queue);
4808
4809   S;
4810   W;
4811   /* NOTREACHED */
4812   return 0;
4813 }
4814
4815 static int
4816 api_sw_interface_add_del_address (vat_main_t * vam)
4817 {
4818   unformat_input_t *i = vam->input;
4819   vl_api_sw_interface_add_del_address_t *mp;
4820   f64 timeout;
4821   u32 sw_if_index;
4822   u8 sw_if_index_set = 0;
4823   u8 is_add = 1, del_all = 0;
4824   u32 address_length = 0;
4825   u8 v4_address_set = 0;
4826   u8 v6_address_set = 0;
4827   ip4_address_t v4address;
4828   ip6_address_t v6address;
4829
4830   /* Parse args required to build the message */
4831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4832     {
4833       if (unformat (i, "del-all"))
4834         del_all = 1;
4835       else if (unformat (i, "del"))
4836         is_add = 0;
4837       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4838         sw_if_index_set = 1;
4839       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4840         sw_if_index_set = 1;
4841       else if (unformat (i, "%U/%d",
4842                          unformat_ip4_address, &v4address, &address_length))
4843         v4_address_set = 1;
4844       else if (unformat (i, "%U/%d",
4845                          unformat_ip6_address, &v6address, &address_length))
4846         v6_address_set = 1;
4847       else
4848         break;
4849     }
4850
4851   if (sw_if_index_set == 0)
4852     {
4853       errmsg ("missing interface name or sw_if_index\n");
4854       return -99;
4855     }
4856   if (v4_address_set && v6_address_set)
4857     {
4858       errmsg ("both v4 and v6 addresses set\n");
4859       return -99;
4860     }
4861   if (!v4_address_set && !v6_address_set && !del_all)
4862     {
4863       errmsg ("no addresses set\n");
4864       return -99;
4865     }
4866
4867   /* Construct the API message */
4868   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4869
4870   mp->sw_if_index = ntohl (sw_if_index);
4871   mp->is_add = is_add;
4872   mp->del_all = del_all;
4873   if (v6_address_set)
4874     {
4875       mp->is_ipv6 = 1;
4876       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4877     }
4878   else
4879     {
4880       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4881     }
4882   mp->address_length = address_length;
4883
4884   /* send it... */
4885   S;
4886
4887   /* Wait for a reply, return good/bad news  */
4888   W;
4889 }
4890
4891 static int
4892 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4893 {
4894   unformat_input_t *i = vam->input;
4895   vl_api_sw_interface_set_mpls_enable_t *mp;
4896   f64 timeout;
4897   u32 sw_if_index;
4898   u8 sw_if_index_set = 0;
4899   u8 enable = 1;
4900
4901   /* Parse args required to build the message */
4902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4903     {
4904       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4905         sw_if_index_set = 1;
4906       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4907         sw_if_index_set = 1;
4908       else if (unformat (i, "disable"))
4909         enable = 0;
4910       else if (unformat (i, "dis"))
4911         enable = 0;
4912       else
4913         break;
4914     }
4915
4916   if (sw_if_index_set == 0)
4917     {
4918       errmsg ("missing interface name or sw_if_index\n");
4919       return -99;
4920     }
4921
4922   /* Construct the API message */
4923   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
4924
4925   mp->sw_if_index = ntohl (sw_if_index);
4926   mp->enable = enable;
4927
4928   /* send it... */
4929   S;
4930
4931   /* Wait for a reply... */
4932   W;
4933 }
4934
4935 static int
4936 api_sw_interface_set_table (vat_main_t * vam)
4937 {
4938   unformat_input_t *i = vam->input;
4939   vl_api_sw_interface_set_table_t *mp;
4940   f64 timeout;
4941   u32 sw_if_index, vrf_id = 0;
4942   u8 sw_if_index_set = 0;
4943   u8 is_ipv6 = 0;
4944
4945   /* Parse args required to build the message */
4946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4947     {
4948       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4949         sw_if_index_set = 1;
4950       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4951         sw_if_index_set = 1;
4952       else if (unformat (i, "vrf %d", &vrf_id))
4953         ;
4954       else if (unformat (i, "ipv6"))
4955         is_ipv6 = 1;
4956       else
4957         break;
4958     }
4959
4960   if (sw_if_index_set == 0)
4961     {
4962       errmsg ("missing interface name or sw_if_index\n");
4963       return -99;
4964     }
4965
4966   /* Construct the API message */
4967   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4968
4969   mp->sw_if_index = ntohl (sw_if_index);
4970   mp->is_ipv6 = is_ipv6;
4971   mp->vrf_id = ntohl (vrf_id);
4972
4973   /* send it... */
4974   S;
4975
4976   /* Wait for a reply... */
4977   W;
4978 }
4979
4980 static int
4981 api_sw_interface_set_vpath (vat_main_t * vam)
4982 {
4983   unformat_input_t *i = vam->input;
4984   vl_api_sw_interface_set_vpath_t *mp;
4985   f64 timeout;
4986   u32 sw_if_index = 0;
4987   u8 sw_if_index_set = 0;
4988   u8 is_enable = 0;
4989
4990   /* Parse args required to build the message */
4991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4992     {
4993       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4994         sw_if_index_set = 1;
4995       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4996         sw_if_index_set = 1;
4997       else if (unformat (i, "enable"))
4998         is_enable = 1;
4999       else if (unformat (i, "disable"))
5000         is_enable = 0;
5001       else
5002         break;
5003     }
5004
5005   if (sw_if_index_set == 0)
5006     {
5007       errmsg ("missing interface name or sw_if_index\n");
5008       return -99;
5009     }
5010
5011   /* Construct the API message */
5012   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5013
5014   mp->sw_if_index = ntohl (sw_if_index);
5015   mp->enable = is_enable;
5016
5017   /* send it... */
5018   S;
5019
5020   /* Wait for a reply... */
5021   W;
5022 }
5023
5024 static int
5025 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5026 {
5027   unformat_input_t *i = vam->input;
5028   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5029   f64 timeout;
5030   u32 sw_if_index = 0;
5031   u8 sw_if_index_set = 0;
5032   u8 is_enable = 0;
5033   u8 is_ipv6 = 0;
5034
5035   /* Parse args required to build the message */
5036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5037     {
5038       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5039         sw_if_index_set = 1;
5040       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5041         sw_if_index_set = 1;
5042       else if (unformat (i, "enable"))
5043         is_enable = 1;
5044       else if (unformat (i, "disable"))
5045         is_enable = 0;
5046       else if (unformat (i, "ip4"))
5047         is_ipv6 = 0;
5048       else if (unformat (i, "ip6"))
5049         is_ipv6 = 1;
5050       else
5051         break;
5052     }
5053
5054   if (sw_if_index_set == 0)
5055     {
5056       errmsg ("missing interface name or sw_if_index\n");
5057       return -99;
5058     }
5059
5060   /* Construct the API message */
5061   M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5062
5063   mp->sw_if_index = ntohl (sw_if_index);
5064   mp->enable = is_enable;
5065   mp->is_ipv6 = is_ipv6;
5066
5067   /* send it... */
5068   S;
5069
5070   /* Wait for a reply... */
5071   W;
5072 }
5073
5074 static int
5075 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5076 {
5077   unformat_input_t *i = vam->input;
5078   vl_api_sw_interface_set_l2_xconnect_t *mp;
5079   f64 timeout;
5080   u32 rx_sw_if_index;
5081   u8 rx_sw_if_index_set = 0;
5082   u32 tx_sw_if_index;
5083   u8 tx_sw_if_index_set = 0;
5084   u8 enable = 1;
5085
5086   /* Parse args required to build the message */
5087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5088     {
5089       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5090         rx_sw_if_index_set = 1;
5091       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5092         tx_sw_if_index_set = 1;
5093       else if (unformat (i, "rx"))
5094         {
5095           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5096             {
5097               if (unformat (i, "%U", unformat_sw_if_index, vam,
5098                             &rx_sw_if_index))
5099                 rx_sw_if_index_set = 1;
5100             }
5101           else
5102             break;
5103         }
5104       else if (unformat (i, "tx"))
5105         {
5106           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5107             {
5108               if (unformat (i, "%U", unformat_sw_if_index, vam,
5109                             &tx_sw_if_index))
5110                 tx_sw_if_index_set = 1;
5111             }
5112           else
5113             break;
5114         }
5115       else if (unformat (i, "enable"))
5116         enable = 1;
5117       else if (unformat (i, "disable"))
5118         enable = 0;
5119       else
5120         break;
5121     }
5122
5123   if (rx_sw_if_index_set == 0)
5124     {
5125       errmsg ("missing rx interface name or rx_sw_if_index\n");
5126       return -99;
5127     }
5128
5129   if (enable && (tx_sw_if_index_set == 0))
5130     {
5131       errmsg ("missing tx interface name or tx_sw_if_index\n");
5132       return -99;
5133     }
5134
5135   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5136
5137   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5138   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5139   mp->enable = enable;
5140
5141   S;
5142   W;
5143   /* NOTREACHED */
5144   return 0;
5145 }
5146
5147 static int
5148 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5149 {
5150   unformat_input_t *i = vam->input;
5151   vl_api_sw_interface_set_l2_bridge_t *mp;
5152   f64 timeout;
5153   u32 rx_sw_if_index;
5154   u8 rx_sw_if_index_set = 0;
5155   u32 bd_id;
5156   u8 bd_id_set = 0;
5157   u8 bvi = 0;
5158   u32 shg = 0;
5159   u8 enable = 1;
5160
5161   /* Parse args required to build the message */
5162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5163     {
5164       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5165         rx_sw_if_index_set = 1;
5166       else if (unformat (i, "bd_id %d", &bd_id))
5167         bd_id_set = 1;
5168       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5169         rx_sw_if_index_set = 1;
5170       else if (unformat (i, "shg %d", &shg))
5171         ;
5172       else if (unformat (i, "bvi"))
5173         bvi = 1;
5174       else if (unformat (i, "enable"))
5175         enable = 1;
5176       else if (unformat (i, "disable"))
5177         enable = 0;
5178       else
5179         break;
5180     }
5181
5182   if (rx_sw_if_index_set == 0)
5183     {
5184       errmsg ("missing rx interface name or sw_if_index\n");
5185       return -99;
5186     }
5187
5188   if (enable && (bd_id_set == 0))
5189     {
5190       errmsg ("missing bridge domain\n");
5191       return -99;
5192     }
5193
5194   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5195
5196   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5197   mp->bd_id = ntohl (bd_id);
5198   mp->shg = (u8) shg;
5199   mp->bvi = bvi;
5200   mp->enable = enable;
5201
5202   S;
5203   W;
5204   /* NOTREACHED */
5205   return 0;
5206 }
5207
5208 static int
5209 api_bridge_domain_dump (vat_main_t * vam)
5210 {
5211   unformat_input_t *i = vam->input;
5212   vl_api_bridge_domain_dump_t *mp;
5213   f64 timeout;
5214   u32 bd_id = ~0;
5215
5216   /* Parse args required to build the message */
5217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5218     {
5219       if (unformat (i, "bd_id %d", &bd_id))
5220         ;
5221       else
5222         break;
5223     }
5224
5225   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5226   mp->bd_id = ntohl (bd_id);
5227   S;
5228
5229   /* Use a control ping for synchronization */
5230   {
5231     vl_api_control_ping_t *mp;
5232     M (CONTROL_PING, control_ping);
5233     S;
5234   }
5235
5236   W;
5237   /* NOTREACHED */
5238   return 0;
5239 }
5240
5241 static int
5242 api_bridge_domain_add_del (vat_main_t * vam)
5243 {
5244   unformat_input_t *i = vam->input;
5245   vl_api_bridge_domain_add_del_t *mp;
5246   f64 timeout;
5247   u32 bd_id = ~0;
5248   u8 is_add = 1;
5249   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5250
5251   /* Parse args required to build the message */
5252   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5253     {
5254       if (unformat (i, "bd_id %d", &bd_id))
5255         ;
5256       else if (unformat (i, "flood %d", &flood))
5257         ;
5258       else if (unformat (i, "uu-flood %d", &uu_flood))
5259         ;
5260       else if (unformat (i, "forward %d", &forward))
5261         ;
5262       else if (unformat (i, "learn %d", &learn))
5263         ;
5264       else if (unformat (i, "arp-term %d", &arp_term))
5265         ;
5266       else if (unformat (i, "del"))
5267         {
5268           is_add = 0;
5269           flood = uu_flood = forward = learn = 0;
5270         }
5271       else
5272         break;
5273     }
5274
5275   if (bd_id == ~0)
5276     {
5277       errmsg ("missing bridge domain\n");
5278       return -99;
5279     }
5280
5281   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5282
5283   mp->bd_id = ntohl (bd_id);
5284   mp->flood = flood;
5285   mp->uu_flood = uu_flood;
5286   mp->forward = forward;
5287   mp->learn = learn;
5288   mp->arp_term = arp_term;
5289   mp->is_add = is_add;
5290
5291   S;
5292   W;
5293   /* NOTREACHED */
5294   return 0;
5295 }
5296
5297 static int
5298 api_l2fib_add_del (vat_main_t * vam)
5299 {
5300   unformat_input_t *i = vam->input;
5301   vl_api_l2fib_add_del_t *mp;
5302   f64 timeout;
5303   u64 mac = 0;
5304   u8 mac_set = 0;
5305   u32 bd_id;
5306   u8 bd_id_set = 0;
5307   u32 sw_if_index;
5308   u8 sw_if_index_set = 0;
5309   u8 is_add = 1;
5310   u8 static_mac = 0;
5311   u8 filter_mac = 0;
5312   u8 bvi_mac = 0;
5313   int count = 1;
5314   f64 before = 0;
5315   int j;
5316
5317   /* Parse args required to build the message */
5318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5319     {
5320       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5321         mac_set = 1;
5322       else if (unformat (i, "bd_id %d", &bd_id))
5323         bd_id_set = 1;
5324       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5325         sw_if_index_set = 1;
5326       else if (unformat (i, "sw_if"))
5327         {
5328           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5329             {
5330               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5331                 sw_if_index_set = 1;
5332             }
5333           else
5334             break;
5335         }
5336       else if (unformat (i, "static"))
5337         static_mac = 1;
5338       else if (unformat (i, "filter"))
5339         {
5340           filter_mac = 1;
5341           static_mac = 1;
5342         }
5343       else if (unformat (i, "bvi"))
5344         {
5345           bvi_mac = 1;
5346           static_mac = 1;
5347         }
5348       else if (unformat (i, "del"))
5349         is_add = 0;
5350       else if (unformat (i, "count %d", &count))
5351         ;
5352       else
5353         break;
5354     }
5355
5356   if (mac_set == 0)
5357     {
5358       errmsg ("missing mac address\n");
5359       return -99;
5360     }
5361
5362   if (bd_id_set == 0)
5363     {
5364       errmsg ("missing bridge domain\n");
5365       return -99;
5366     }
5367
5368   if (is_add && (sw_if_index_set == 0))
5369     {
5370       errmsg ("missing interface name or sw_if_index\n");
5371       return -99;
5372     }
5373
5374   if (count > 1)
5375     {
5376       /* Turn on async mode */
5377       vam->async_mode = 1;
5378       vam->async_errors = 0;
5379       before = vat_time_now (vam);
5380     }
5381
5382   for (j = 0; j < count; j++)
5383     {
5384       M (L2FIB_ADD_DEL, l2fib_add_del);
5385
5386       mp->mac = mac;
5387       mp->bd_id = ntohl (bd_id);
5388       mp->is_add = is_add;
5389
5390       if (is_add)
5391         {
5392           mp->sw_if_index = ntohl (sw_if_index);
5393           mp->static_mac = static_mac;
5394           mp->filter_mac = filter_mac;
5395           mp->bvi_mac = bvi_mac;
5396         }
5397       increment_mac_address (&mac);
5398       /* send it... */
5399       S;
5400     }
5401
5402   if (count > 1)
5403     {
5404       vl_api_control_ping_t *mp;
5405       f64 after;
5406
5407       /* Shut off async mode */
5408       vam->async_mode = 0;
5409
5410       M (CONTROL_PING, control_ping);
5411       S;
5412
5413       timeout = vat_time_now (vam) + 1.0;
5414       while (vat_time_now (vam) < timeout)
5415         if (vam->result_ready == 1)
5416           goto out;
5417       vam->retval = -99;
5418
5419     out:
5420       if (vam->retval == -99)
5421         errmsg ("timeout\n");
5422
5423       if (vam->async_errors > 0)
5424         {
5425           errmsg ("%d asynchronous errors\n", vam->async_errors);
5426           vam->retval = -98;
5427         }
5428       vam->async_errors = 0;
5429       after = vat_time_now (vam);
5430
5431       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5432                count, after - before, count / (after - before));
5433     }
5434   else
5435     {
5436       /* Wait for a reply... */
5437       W;
5438     }
5439   /* Return the good/bad news */
5440   return (vam->retval);
5441 }
5442
5443 static int
5444 api_l2_flags (vat_main_t * vam)
5445 {
5446   unformat_input_t *i = vam->input;
5447   vl_api_l2_flags_t *mp;
5448   f64 timeout;
5449   u32 sw_if_index;
5450   u32 feature_bitmap = 0;
5451   u8 sw_if_index_set = 0;
5452
5453   /* Parse args required to build the message */
5454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5455     {
5456       if (unformat (i, "sw_if_index %d", &sw_if_index))
5457         sw_if_index_set = 1;
5458       else if (unformat (i, "sw_if"))
5459         {
5460           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5461             {
5462               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5463                 sw_if_index_set = 1;
5464             }
5465           else
5466             break;
5467         }
5468       else if (unformat (i, "learn"))
5469         feature_bitmap |= L2INPUT_FEAT_LEARN;
5470       else if (unformat (i, "forward"))
5471         feature_bitmap |= L2INPUT_FEAT_FWD;
5472       else if (unformat (i, "flood"))
5473         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5474       else if (unformat (i, "uu-flood"))
5475         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5476       else
5477         break;
5478     }
5479
5480   if (sw_if_index_set == 0)
5481     {
5482       errmsg ("missing interface name or sw_if_index\n");
5483       return -99;
5484     }
5485
5486   M (L2_FLAGS, l2_flags);
5487
5488   mp->sw_if_index = ntohl (sw_if_index);
5489   mp->feature_bitmap = ntohl (feature_bitmap);
5490
5491   S;
5492   W;
5493   /* NOTREACHED */
5494   return 0;
5495 }
5496
5497 static int
5498 api_bridge_flags (vat_main_t * vam)
5499 {
5500   unformat_input_t *i = vam->input;
5501   vl_api_bridge_flags_t *mp;
5502   f64 timeout;
5503   u32 bd_id;
5504   u8 bd_id_set = 0;
5505   u8 is_set = 1;
5506   u32 flags = 0;
5507
5508   /* Parse args required to build the message */
5509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5510     {
5511       if (unformat (i, "bd_id %d", &bd_id))
5512         bd_id_set = 1;
5513       else if (unformat (i, "learn"))
5514         flags |= L2_LEARN;
5515       else if (unformat (i, "forward"))
5516         flags |= L2_FWD;
5517       else if (unformat (i, "flood"))
5518         flags |= L2_FLOOD;
5519       else if (unformat (i, "uu-flood"))
5520         flags |= L2_UU_FLOOD;
5521       else if (unformat (i, "arp-term"))
5522         flags |= L2_ARP_TERM;
5523       else if (unformat (i, "off"))
5524         is_set = 0;
5525       else if (unformat (i, "disable"))
5526         is_set = 0;
5527       else
5528         break;
5529     }
5530
5531   if (bd_id_set == 0)
5532     {
5533       errmsg ("missing bridge domain\n");
5534       return -99;
5535     }
5536
5537   M (BRIDGE_FLAGS, bridge_flags);
5538
5539   mp->bd_id = ntohl (bd_id);
5540   mp->feature_bitmap = ntohl (flags);
5541   mp->is_set = is_set;
5542
5543   S;
5544   W;
5545   /* NOTREACHED */
5546   return 0;
5547 }
5548
5549 static int
5550 api_bd_ip_mac_add_del (vat_main_t * vam)
5551 {
5552   unformat_input_t *i = vam->input;
5553   vl_api_bd_ip_mac_add_del_t *mp;
5554   f64 timeout;
5555   u32 bd_id;
5556   u8 is_ipv6 = 0;
5557   u8 is_add = 1;
5558   u8 bd_id_set = 0;
5559   u8 ip_set = 0;
5560   u8 mac_set = 0;
5561   ip4_address_t v4addr;
5562   ip6_address_t v6addr;
5563   u8 macaddr[6];
5564
5565
5566   /* Parse args required to build the message */
5567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5568     {
5569       if (unformat (i, "bd_id %d", &bd_id))
5570         {
5571           bd_id_set++;
5572         }
5573       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5574         {
5575           ip_set++;
5576         }
5577       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5578         {
5579           ip_set++;
5580           is_ipv6++;
5581         }
5582       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5583         {
5584           mac_set++;
5585         }
5586       else if (unformat (i, "del"))
5587         is_add = 0;
5588       else
5589         break;
5590     }
5591
5592   if (bd_id_set == 0)
5593     {
5594       errmsg ("missing bridge domain\n");
5595       return -99;
5596     }
5597   else if (ip_set == 0)
5598     {
5599       errmsg ("missing IP address\n");
5600       return -99;
5601     }
5602   else if (mac_set == 0)
5603     {
5604       errmsg ("missing MAC address\n");
5605       return -99;
5606     }
5607
5608   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5609
5610   mp->bd_id = ntohl (bd_id);
5611   mp->is_ipv6 = is_ipv6;
5612   mp->is_add = is_add;
5613   if (is_ipv6)
5614     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5615   else
5616     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5617   clib_memcpy (mp->mac_address, macaddr, 6);
5618   S;
5619   W;
5620   /* NOTREACHED */
5621   return 0;
5622 }
5623
5624 static int
5625 api_tap_connect (vat_main_t * vam)
5626 {
5627   unformat_input_t *i = vam->input;
5628   vl_api_tap_connect_t *mp;
5629   f64 timeout;
5630   u8 mac_address[6];
5631   u8 random_mac = 1;
5632   u8 name_set = 0;
5633   u8 *tap_name;
5634   u8 *tag = 0;
5635
5636   memset (mac_address, 0, sizeof (mac_address));
5637
5638   /* Parse args required to build the message */
5639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5640     {
5641       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5642         {
5643           random_mac = 0;
5644         }
5645       else if (unformat (i, "random-mac"))
5646         random_mac = 1;
5647       else if (unformat (i, "tapname %s", &tap_name))
5648         name_set = 1;
5649       else if (unformat (i, "tag %s", &tag));
5650       else
5651         break;
5652     }
5653
5654   if (name_set == 0)
5655     {
5656       errmsg ("missing tap name\n");
5657       return -99;
5658     }
5659   if (vec_len (tap_name) > 63)
5660     {
5661       errmsg ("tap name too long\n");
5662       return -99;
5663     }
5664   vec_add1 (tap_name, 0);
5665
5666   if (vec_len (tag) > 63)
5667     {
5668       errmsg ("tag too long\n");
5669       return -99;
5670     }
5671   vec_add1 (tag, 0);
5672
5673   /* Construct the API message */
5674   M (TAP_CONNECT, tap_connect);
5675
5676   mp->use_random_mac = random_mac;
5677   clib_memcpy (mp->mac_address, mac_address, 6);
5678   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5679   if (tag)
5680     clib_memcpy (mp->tag, tag, vec_len (tag));
5681
5682   vec_free (tap_name);
5683   vec_free (tag);
5684
5685   /* send it... */
5686   S;
5687
5688   /* Wait for a reply... */
5689   W;
5690 }
5691
5692 static int
5693 api_tap_modify (vat_main_t * vam)
5694 {
5695   unformat_input_t *i = vam->input;
5696   vl_api_tap_modify_t *mp;
5697   f64 timeout;
5698   u8 mac_address[6];
5699   u8 random_mac = 1;
5700   u8 name_set = 0;
5701   u8 *tap_name;
5702   u32 sw_if_index = ~0;
5703   u8 sw_if_index_set = 0;
5704
5705   memset (mac_address, 0, sizeof (mac_address));
5706
5707   /* Parse args required to build the message */
5708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5709     {
5710       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5711         sw_if_index_set = 1;
5712       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5713         sw_if_index_set = 1;
5714       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5715         {
5716           random_mac = 0;
5717         }
5718       else if (unformat (i, "random-mac"))
5719         random_mac = 1;
5720       else if (unformat (i, "tapname %s", &tap_name))
5721         name_set = 1;
5722       else
5723         break;
5724     }
5725
5726   if (sw_if_index_set == 0)
5727     {
5728       errmsg ("missing vpp interface name");
5729       return -99;
5730     }
5731   if (name_set == 0)
5732     {
5733       errmsg ("missing tap name\n");
5734       return -99;
5735     }
5736   if (vec_len (tap_name) > 63)
5737     {
5738       errmsg ("tap name too long\n");
5739     }
5740   vec_add1 (tap_name, 0);
5741
5742   /* Construct the API message */
5743   M (TAP_MODIFY, tap_modify);
5744
5745   mp->use_random_mac = random_mac;
5746   mp->sw_if_index = ntohl (sw_if_index);
5747   clib_memcpy (mp->mac_address, mac_address, 6);
5748   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5749   vec_free (tap_name);
5750
5751   /* send it... */
5752   S;
5753
5754   /* Wait for a reply... */
5755   W;
5756 }
5757
5758 static int
5759 api_tap_delete (vat_main_t * vam)
5760 {
5761   unformat_input_t *i = vam->input;
5762   vl_api_tap_delete_t *mp;
5763   f64 timeout;
5764   u32 sw_if_index = ~0;
5765   u8 sw_if_index_set = 0;
5766
5767   /* Parse args required to build the message */
5768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5769     {
5770       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5771         sw_if_index_set = 1;
5772       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5773         sw_if_index_set = 1;
5774       else
5775         break;
5776     }
5777
5778   if (sw_if_index_set == 0)
5779     {
5780       errmsg ("missing vpp interface name");
5781       return -99;
5782     }
5783
5784   /* Construct the API message */
5785   M (TAP_DELETE, tap_delete);
5786
5787   mp->sw_if_index = ntohl (sw_if_index);
5788
5789   /* send it... */
5790   S;
5791
5792   /* Wait for a reply... */
5793   W;
5794 }
5795
5796 static int
5797 api_ip_add_del_route (vat_main_t * vam)
5798 {
5799   unformat_input_t *i = vam->input;
5800   vl_api_ip_add_del_route_t *mp;
5801   f64 timeout;
5802   u32 sw_if_index = ~0, vrf_id = 0;
5803   u8 sw_if_index_set = 0;
5804   u8 is_ipv6 = 0;
5805   u8 is_local = 0, is_drop = 0;
5806   u8 is_unreach = 0, is_prohibit = 0;
5807   u8 create_vrf_if_needed = 0;
5808   u8 is_add = 1;
5809   u32 next_hop_weight = 1;
5810   u8 not_last = 0;
5811   u8 is_multipath = 0;
5812   u8 address_set = 0;
5813   u8 address_length_set = 0;
5814   u32 next_hop_table_id = 0;
5815   u32 resolve_attempts = 0;
5816   u32 dst_address_length = 0;
5817   u8 next_hop_set = 0;
5818   ip4_address_t v4_dst_address, v4_next_hop_address;
5819   ip6_address_t v6_dst_address, v6_next_hop_address;
5820   int count = 1;
5821   int j;
5822   f64 before = 0;
5823   u32 random_add_del = 0;
5824   u32 *random_vector = 0;
5825   uword *random_hash;
5826   u32 random_seed = 0xdeaddabe;
5827   u32 classify_table_index = ~0;
5828   u8 is_classify = 0;
5829   u8 resolve_host = 0, resolve_attached = 0;
5830   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5831
5832   /* Parse args required to build the message */
5833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5834     {
5835       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5836         sw_if_index_set = 1;
5837       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5838         sw_if_index_set = 1;
5839       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5840         {
5841           address_set = 1;
5842           is_ipv6 = 0;
5843         }
5844       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5845         {
5846           address_set = 1;
5847           is_ipv6 = 1;
5848         }
5849       else if (unformat (i, "/%d", &dst_address_length))
5850         {
5851           address_length_set = 1;
5852         }
5853
5854       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5855                                          &v4_next_hop_address))
5856         {
5857           next_hop_set = 1;
5858         }
5859       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5860                                          &v6_next_hop_address))
5861         {
5862           next_hop_set = 1;
5863         }
5864       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5865         ;
5866       else if (unformat (i, "weight %d", &next_hop_weight))
5867         ;
5868       else if (unformat (i, "drop"))
5869         {
5870           is_drop = 1;
5871         }
5872       else if (unformat (i, "null-send-unreach"))
5873         {
5874           is_unreach = 1;
5875         }
5876       else if (unformat (i, "null-send-prohibit"))
5877         {
5878           is_prohibit = 1;
5879         }
5880       else if (unformat (i, "local"))
5881         {
5882           is_local = 1;
5883         }
5884       else if (unformat (i, "classify %d", &classify_table_index))
5885         {
5886           is_classify = 1;
5887         }
5888       else if (unformat (i, "del"))
5889         is_add = 0;
5890       else if (unformat (i, "add"))
5891         is_add = 1;
5892       else if (unformat (i, "not-last"))
5893         not_last = 1;
5894       else if (unformat (i, "resolve-via-host"))
5895         resolve_host = 1;
5896       else if (unformat (i, "resolve-via-attached"))
5897         resolve_attached = 1;
5898       else if (unformat (i, "multipath"))
5899         is_multipath = 1;
5900       else if (unformat (i, "vrf %d", &vrf_id))
5901         ;
5902       else if (unformat (i, "create-vrf"))
5903         create_vrf_if_needed = 1;
5904       else if (unformat (i, "count %d", &count))
5905         ;
5906       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
5907         ;
5908       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
5909         ;
5910       else if (unformat (i, "out-label %d", &next_hop_out_label))
5911         ;
5912       else if (unformat (i, "random"))
5913         random_add_del = 1;
5914       else if (unformat (i, "seed %d", &random_seed))
5915         ;
5916       else
5917         {
5918           clib_warning ("parse error '%U'", format_unformat_error, i);
5919           return -99;
5920         }
5921     }
5922
5923   if (resolve_attempts > 0 && sw_if_index_set == 0)
5924     {
5925       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5926       return -99;
5927     }
5928
5929   if (!next_hop_set && !is_drop && !is_local &&
5930       !is_classify && !is_unreach && !is_prohibit)
5931     {
5932       errmsg
5933         ("next hop / local / drop / unreach / prohibit / classify not set\n");
5934       return -99;
5935     }
5936
5937   if (address_set == 0)
5938     {
5939       errmsg ("missing addresses\n");
5940       return -99;
5941     }
5942
5943   if (address_length_set == 0)
5944     {
5945       errmsg ("missing address length\n");
5946       return -99;
5947     }
5948
5949   /* Generate a pile of unique, random routes */
5950   if (random_add_del)
5951     {
5952       u32 this_random_address;
5953       random_hash = hash_create (count, sizeof (uword));
5954
5955       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5956       for (j = 0; j <= count; j++)
5957         {
5958           do
5959             {
5960               this_random_address = random_u32 (&random_seed);
5961               this_random_address =
5962                 clib_host_to_net_u32 (this_random_address);
5963             }
5964           while (hash_get (random_hash, this_random_address));
5965           vec_add1 (random_vector, this_random_address);
5966           hash_set (random_hash, this_random_address, 1);
5967         }
5968       hash_free (random_hash);
5969       v4_dst_address.as_u32 = random_vector[0];
5970     }
5971
5972   if (count > 1)
5973     {
5974       /* Turn on async mode */
5975       vam->async_mode = 1;
5976       vam->async_errors = 0;
5977       before = vat_time_now (vam);
5978     }
5979
5980   for (j = 0; j < count; j++)
5981     {
5982       /* Construct the API message */
5983       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5984
5985       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5986       mp->table_id = ntohl (vrf_id);
5987       if (resolve_attempts > 0)
5988         {
5989           mp->resolve_attempts = ntohl (resolve_attempts);
5990           mp->resolve_if_needed = 1;
5991         }
5992       mp->create_vrf_if_needed = create_vrf_if_needed;
5993
5994       mp->is_add = is_add;
5995       mp->is_drop = is_drop;
5996       mp->is_unreach = is_unreach;
5997       mp->is_prohibit = is_prohibit;
5998       mp->is_ipv6 = is_ipv6;
5999       mp->is_local = is_local;
6000       mp->is_classify = is_classify;
6001       mp->is_multipath = is_multipath;
6002       mp->is_resolve_host = resolve_host;
6003       mp->is_resolve_attached = resolve_attached;
6004       mp->not_last = not_last;
6005       mp->next_hop_weight = next_hop_weight;
6006       mp->dst_address_length = dst_address_length;
6007       mp->next_hop_table_id = ntohl (next_hop_table_id);
6008       mp->classify_table_index = ntohl (classify_table_index);
6009       mp->next_hop_out_label = ntohl (next_hop_out_label);
6010
6011       if (is_ipv6)
6012         {
6013           clib_memcpy (mp->dst_address, &v6_dst_address,
6014                        sizeof (v6_dst_address));
6015           if (next_hop_set)
6016             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6017                          sizeof (v6_next_hop_address));
6018           increment_v6_address (&v6_dst_address);
6019         }
6020       else
6021         {
6022           clib_memcpy (mp->dst_address, &v4_dst_address,
6023                        sizeof (v4_dst_address));
6024           if (next_hop_set)
6025             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6026                          sizeof (v4_next_hop_address));
6027           if (random_add_del)
6028             v4_dst_address.as_u32 = random_vector[j + 1];
6029           else
6030             increment_v4_address (&v4_dst_address);
6031         }
6032       /* send it... */
6033       S;
6034       /* If we receive SIGTERM, stop now... */
6035       if (vam->do_exit)
6036         break;
6037     }
6038
6039   /* When testing multiple add/del ops, use a control-ping to sync */
6040   if (count > 1)
6041     {
6042       vl_api_control_ping_t *mp;
6043       f64 after;
6044
6045       /* Shut off async mode */
6046       vam->async_mode = 0;
6047
6048       M (CONTROL_PING, control_ping);
6049       S;
6050
6051       timeout = vat_time_now (vam) + 1.0;
6052       while (vat_time_now (vam) < timeout)
6053         if (vam->result_ready == 1)
6054           goto out;
6055       vam->retval = -99;
6056
6057     out:
6058       if (vam->retval == -99)
6059         errmsg ("timeout\n");
6060
6061       if (vam->async_errors > 0)
6062         {
6063           errmsg ("%d asynchronous errors\n", vam->async_errors);
6064           vam->retval = -98;
6065         }
6066       vam->async_errors = 0;
6067       after = vat_time_now (vam);
6068
6069       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6070       if (j > 0)
6071         count = j;
6072
6073       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6074                count, after - before, count / (after - before));
6075     }
6076   else
6077     {
6078       /* Wait for a reply... */
6079       W;
6080     }
6081
6082   /* Return the good/bad news */
6083   return (vam->retval);
6084 }
6085
6086 static int
6087 api_mpls_route_add_del (vat_main_t * vam)
6088 {
6089   unformat_input_t *i = vam->input;
6090   vl_api_mpls_route_add_del_t *mp;
6091   f64 timeout;
6092   u32 sw_if_index = ~0, table_id = 0;
6093   u8 create_table_if_needed = 0;
6094   u8 is_add = 1;
6095   u32 next_hop_weight = 1;
6096   u8 is_multipath = 0;
6097   u32 next_hop_table_id = 0;
6098   u8 next_hop_set = 0;
6099   ip4_address_t v4_next_hop_address = {
6100     .as_u32 = 0,
6101   };
6102   ip6_address_t v6_next_hop_address = { {0} };
6103   int count = 1;
6104   int j;
6105   f64 before = 0;
6106   u32 classify_table_index = ~0;
6107   u8 is_classify = 0;
6108   u8 resolve_host = 0, resolve_attached = 0;
6109   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6110   mpls_label_t local_label = MPLS_LABEL_INVALID;
6111   u8 is_eos = 1;
6112   u8 next_hop_proto_is_ip4 = 1;
6113
6114   /* Parse args required to build the message */
6115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6116     {
6117       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6118         ;
6119       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6120         ;
6121       else if (unformat (i, "%d", &local_label))
6122         ;
6123       else if (unformat (i, "eos"))
6124         is_eos = 1;
6125       else if (unformat (i, "non-eos"))
6126         is_eos = 0;
6127       else if (unformat (i, "via %U", unformat_ip4_address,
6128                          &v4_next_hop_address))
6129         {
6130           next_hop_set = 1;
6131           next_hop_proto_is_ip4 = 1;
6132         }
6133       else if (unformat (i, "via %U", unformat_ip6_address,
6134                          &v6_next_hop_address))
6135         {
6136           next_hop_set = 1;
6137           next_hop_proto_is_ip4 = 0;
6138         }
6139       else if (unformat (i, "weight %d", &next_hop_weight))
6140         ;
6141       else if (unformat (i, "create-table"))
6142         create_table_if_needed = 1;
6143       else if (unformat (i, "classify %d", &classify_table_index))
6144         {
6145           is_classify = 1;
6146         }
6147       else if (unformat (i, "del"))
6148         is_add = 0;
6149       else if (unformat (i, "add"))
6150         is_add = 1;
6151       else if (unformat (i, "resolve-via-host"))
6152         resolve_host = 1;
6153       else if (unformat (i, "resolve-via-attached"))
6154         resolve_attached = 1;
6155       else if (unformat (i, "multipath"))
6156         is_multipath = 1;
6157       else if (unformat (i, "count %d", &count))
6158         ;
6159       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6160         {
6161           next_hop_set = 1;
6162           next_hop_proto_is_ip4 = 1;
6163         }
6164       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6165         {
6166           next_hop_set = 1;
6167           next_hop_proto_is_ip4 = 0;
6168         }
6169       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6170         ;
6171       else if (unformat (i, "out-label %d", &next_hop_out_label))
6172         ;
6173       else
6174         {
6175           clib_warning ("parse error '%U'", format_unformat_error, i);
6176           return -99;
6177         }
6178     }
6179
6180   if (!next_hop_set && !is_classify)
6181     {
6182       errmsg ("next hop / classify not set\n");
6183       return -99;
6184     }
6185
6186   if (MPLS_LABEL_INVALID == local_label)
6187     {
6188       errmsg ("missing label\n");
6189       return -99;
6190     }
6191
6192   if (count > 1)
6193     {
6194       /* Turn on async mode */
6195       vam->async_mode = 1;
6196       vam->async_errors = 0;
6197       before = vat_time_now (vam);
6198     }
6199
6200   for (j = 0; j < count; j++)
6201     {
6202       /* Construct the API message */
6203       M (MPLS_ROUTE_ADD_DEL, mpls_route_add_del);
6204
6205       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6206       mp->mr_table_id = ntohl (table_id);
6207       mp->mr_create_table_if_needed = create_table_if_needed;
6208
6209       mp->mr_is_add = is_add;
6210       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6211       mp->mr_is_classify = is_classify;
6212       mp->mr_is_multipath = is_multipath;
6213       mp->mr_is_resolve_host = resolve_host;
6214       mp->mr_is_resolve_attached = resolve_attached;
6215       mp->mr_next_hop_weight = next_hop_weight;
6216       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6217       mp->mr_classify_table_index = ntohl (classify_table_index);
6218       mp->mr_next_hop_out_label = ntohl (next_hop_out_label);
6219       mp->mr_label = ntohl (local_label);
6220       mp->mr_eos = is_eos;
6221
6222       if (next_hop_set)
6223         {
6224           if (next_hop_proto_is_ip4)
6225             {
6226               clib_memcpy (mp->mr_next_hop,
6227                            &v4_next_hop_address,
6228                            sizeof (v4_next_hop_address));
6229             }
6230           else
6231             {
6232               clib_memcpy (mp->mr_next_hop,
6233                            &v6_next_hop_address,
6234                            sizeof (v6_next_hop_address));
6235             }
6236         }
6237       local_label++;
6238
6239       /* send it... */
6240       S;
6241       /* If we receive SIGTERM, stop now... */
6242       if (vam->do_exit)
6243         break;
6244     }
6245
6246   /* When testing multiple add/del ops, use a control-ping to sync */
6247   if (count > 1)
6248     {
6249       vl_api_control_ping_t *mp;
6250       f64 after;
6251
6252       /* Shut off async mode */
6253       vam->async_mode = 0;
6254
6255       M (CONTROL_PING, control_ping);
6256       S;
6257
6258       timeout = vat_time_now (vam) + 1.0;
6259       while (vat_time_now (vam) < timeout)
6260         if (vam->result_ready == 1)
6261           goto out;
6262       vam->retval = -99;
6263
6264     out:
6265       if (vam->retval == -99)
6266         errmsg ("timeout\n");
6267
6268       if (vam->async_errors > 0)
6269         {
6270           errmsg ("%d asynchronous errors\n", vam->async_errors);
6271           vam->retval = -98;
6272         }
6273       vam->async_errors = 0;
6274       after = vat_time_now (vam);
6275
6276       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6277       if (j > 0)
6278         count = j;
6279
6280       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6281                count, after - before, count / (after - before));
6282     }
6283   else
6284     {
6285       /* Wait for a reply... */
6286       W;
6287     }
6288
6289   /* Return the good/bad news */
6290   return (vam->retval);
6291 }
6292
6293 static int
6294 api_mpls_ip_bind_unbind (vat_main_t * vam)
6295 {
6296   unformat_input_t *i = vam->input;
6297   vl_api_mpls_ip_bind_unbind_t *mp;
6298   f64 timeout;
6299   u32 ip_table_id = 0;
6300   u8 create_table_if_needed = 0;
6301   u8 is_bind = 1;
6302   u8 is_ip4 = 1;
6303   ip4_address_t v4_address;
6304   ip6_address_t v6_address;
6305   u32 address_length;
6306   u8 address_set = 0;
6307   mpls_label_t local_label = MPLS_LABEL_INVALID;
6308
6309   /* Parse args required to build the message */
6310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6311     {
6312       if (unformat (i, "%U/%d", unformat_ip4_address,
6313                     &v4_address, &address_length))
6314         {
6315           is_ip4 = 1;
6316           address_set = 1;
6317         }
6318       else if (unformat (i, "%U/%d", unformat_ip6_address,
6319                          &v6_address, &address_length))
6320         {
6321           is_ip4 = 0;
6322           address_set = 1;
6323         }
6324       else if (unformat (i, "%d", &local_label))
6325         ;
6326       else if (unformat (i, "create-table"))
6327         create_table_if_needed = 1;
6328       else if (unformat (i, "table-id %d", &ip_table_id))
6329         ;
6330       else if (unformat (i, "unbind"))
6331         is_bind = 0;
6332       else if (unformat (i, "bind"))
6333         is_bind = 1;
6334       else
6335         {
6336           clib_warning ("parse error '%U'", format_unformat_error, i);
6337           return -99;
6338         }
6339     }
6340
6341   if (!address_set)
6342     {
6343       errmsg ("IP addres not set\n");
6344       return -99;
6345     }
6346
6347   if (MPLS_LABEL_INVALID == local_label)
6348     {
6349       errmsg ("missing label\n");
6350       return -99;
6351     }
6352
6353   /* Construct the API message */
6354   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6355
6356   mp->mb_create_table_if_needed = create_table_if_needed;
6357   mp->mb_is_bind = is_bind;
6358   mp->mb_is_ip4 = is_ip4;
6359   mp->mb_ip_table_id = ntohl (ip_table_id);
6360   mp->mb_mpls_table_id = 0;
6361   mp->mb_label = ntohl (local_label);
6362   mp->mb_address_length = address_length;
6363
6364   if (is_ip4)
6365     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6366   else
6367     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6368
6369   /* send it... */
6370   S;
6371
6372   /* Wait for a reply... */
6373   W;
6374 }
6375
6376 static int
6377 api_proxy_arp_add_del (vat_main_t * vam)
6378 {
6379   unformat_input_t *i = vam->input;
6380   vl_api_proxy_arp_add_del_t *mp;
6381   f64 timeout;
6382   u32 vrf_id = 0;
6383   u8 is_add = 1;
6384   ip4_address_t lo, hi;
6385   u8 range_set = 0;
6386
6387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6388     {
6389       if (unformat (i, "vrf %d", &vrf_id))
6390         ;
6391       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6392                          unformat_ip4_address, &hi))
6393         range_set = 1;
6394       else if (unformat (i, "del"))
6395         is_add = 0;
6396       else
6397         {
6398           clib_warning ("parse error '%U'", format_unformat_error, i);
6399           return -99;
6400         }
6401     }
6402
6403   if (range_set == 0)
6404     {
6405       errmsg ("address range not set\n");
6406       return -99;
6407     }
6408
6409   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6410
6411   mp->vrf_id = ntohl (vrf_id);
6412   mp->is_add = is_add;
6413   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6414   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6415
6416   S;
6417   W;
6418   /* NOTREACHED */
6419   return 0;
6420 }
6421
6422 static int
6423 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6424 {
6425   unformat_input_t *i = vam->input;
6426   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6427   f64 timeout;
6428   u32 sw_if_index;
6429   u8 enable = 1;
6430   u8 sw_if_index_set = 0;
6431
6432   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6433     {
6434       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6435         sw_if_index_set = 1;
6436       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6437         sw_if_index_set = 1;
6438       else if (unformat (i, "enable"))
6439         enable = 1;
6440       else if (unformat (i, "disable"))
6441         enable = 0;
6442       else
6443         {
6444           clib_warning ("parse error '%U'", format_unformat_error, i);
6445           return -99;
6446         }
6447     }
6448
6449   if (sw_if_index_set == 0)
6450     {
6451       errmsg ("missing interface name or sw_if_index\n");
6452       return -99;
6453     }
6454
6455   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6456
6457   mp->sw_if_index = ntohl (sw_if_index);
6458   mp->enable_disable = enable;
6459
6460   S;
6461   W;
6462   /* NOTREACHED */
6463   return 0;
6464 }
6465
6466 static int
6467 api_mpls_add_del_encap (vat_main_t * vam)
6468 {
6469   unformat_input_t *i = vam->input;
6470   vl_api_mpls_add_del_encap_t *mp;
6471   f64 timeout;
6472   u32 vrf_id = 0;
6473   u32 *labels = 0;
6474   u32 label;
6475   ip4_address_t dst_address;
6476   u8 is_add = 1;
6477
6478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6479     {
6480       if (unformat (i, "vrf %d", &vrf_id))
6481         ;
6482       else if (unformat (i, "label %d", &label))
6483         vec_add1 (labels, ntohl (label));
6484       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6485         ;
6486       else if (unformat (i, "del"))
6487         is_add = 0;
6488       else
6489         {
6490           clib_warning ("parse error '%U'", format_unformat_error, i);
6491           return -99;
6492         }
6493     }
6494
6495   if (vec_len (labels) == 0)
6496     {
6497       errmsg ("missing encap label stack\n");
6498       return -99;
6499     }
6500
6501   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6502       sizeof (u32) * vec_len (labels));
6503
6504   mp->vrf_id = ntohl (vrf_id);
6505   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6506   mp->is_add = is_add;
6507   mp->nlabels = vec_len (labels);
6508   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6509
6510   vec_free (labels);
6511
6512   S;
6513   W;
6514   /* NOTREACHED */
6515   return 0;
6516 }
6517
6518 static int
6519 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6520 {
6521   unformat_input_t *i = vam->input;
6522   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6523   f64 timeout;
6524   u32 inner_vrf_id = 0;
6525   ip4_address_t intfc_address;
6526   u8 dst_mac_address[6];
6527   int dst_set = 1;
6528   u32 tmp;
6529   u8 intfc_address_length = 0;
6530   u8 is_add = 1;
6531   u8 l2_only = 0;
6532   u32 tx_sw_if_index;
6533   int tx_sw_if_index_set = 0;
6534
6535   /* Shut up coverity */
6536   memset (dst_mac_address, 0, sizeof (dst_mac_address));
6537
6538   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6539     {
6540       if (unformat (i, "vrf %d", &inner_vrf_id))
6541         ;
6542       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6543                          &intfc_address, &tmp))
6544         intfc_address_length = tmp;
6545       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6546         tx_sw_if_index_set = 1;
6547       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6548         tx_sw_if_index_set = 1;
6549       else if (unformat (i, "dst %U", unformat_ethernet_address,
6550                          dst_mac_address))
6551         dst_set = 1;
6552       else if (unformat (i, "l2-only"))
6553         l2_only = 1;
6554       else if (unformat (i, "del"))
6555         is_add = 0;
6556       else
6557         {
6558           clib_warning ("parse error '%U'", format_unformat_error, i);
6559           return -99;
6560         }
6561     }
6562
6563   if (!dst_set)
6564     {
6565       errmsg ("dst (mac address) not set\n");
6566       return -99;
6567     }
6568   if (!tx_sw_if_index_set)
6569     {
6570       errmsg ("tx-intfc not set\n");
6571       return -99;
6572     }
6573
6574   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6575
6576   mp->vrf_id = ntohl (inner_vrf_id);
6577   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6578   mp->adj_address_length = intfc_address_length;
6579   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6580                sizeof (dst_mac_address));
6581   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6582   mp->l2_only = l2_only;
6583   mp->is_add = is_add;
6584
6585   S;
6586   W;
6587   /* NOTREACHED */
6588   return 0;
6589 }
6590
6591 static int
6592 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6593 {
6594   unformat_input_t *i = vam->input;
6595   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6596   f64 timeout;
6597   u32 inner_vrf_id = 0;
6598   u32 outer_vrf_id = 0;
6599   ip4_address_t adj_address;
6600   int adj_address_set = 0;
6601   ip4_address_t next_hop_address;
6602   int next_hop_address_set = 0;
6603   u32 tmp;
6604   u8 adj_address_length = 0;
6605   u8 l2_only = 0;
6606   u8 is_add = 1;
6607   u32 resolve_attempts = 5;
6608   u8 resolve_if_needed = 1;
6609
6610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6611     {
6612       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6613         ;
6614       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6615         ;
6616       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6617                          &adj_address, &tmp))
6618         {
6619           adj_address_length = tmp;
6620           adj_address_set = 1;
6621         }
6622       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6623                          &next_hop_address))
6624         next_hop_address_set = 1;
6625       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6626         ;
6627       else if (unformat (i, "resolve-if-needed %d", &tmp))
6628         resolve_if_needed = tmp;
6629       else if (unformat (i, "l2-only"))
6630         l2_only = 1;
6631       else if (unformat (i, "del"))
6632         is_add = 0;
6633       else
6634         {
6635           clib_warning ("parse error '%U'", format_unformat_error, i);
6636           return -99;
6637         }
6638     }
6639
6640   if (!adj_address_set)
6641     {
6642       errmsg ("adjacency address/mask not set\n");
6643       return -99;
6644     }
6645   if (!next_hop_address_set)
6646     {
6647       errmsg ("ip4 next hop address (in outer fib) not set\n");
6648       return -99;
6649     }
6650
6651   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6652
6653   mp->inner_vrf_id = ntohl (inner_vrf_id);
6654   mp->outer_vrf_id = ntohl (outer_vrf_id);
6655   mp->resolve_attempts = ntohl (resolve_attempts);
6656   mp->resolve_if_needed = resolve_if_needed;
6657   mp->is_add = is_add;
6658   mp->l2_only = l2_only;
6659   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6660   mp->adj_address_length = adj_address_length;
6661   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6662                sizeof (next_hop_address));
6663
6664   S;
6665   W;
6666   /* NOTREACHED */
6667   return 0;
6668 }
6669
6670 static int
6671 api_sw_interface_set_unnumbered (vat_main_t * vam)
6672 {
6673   unformat_input_t *i = vam->input;
6674   vl_api_sw_interface_set_unnumbered_t *mp;
6675   f64 timeout;
6676   u32 sw_if_index;
6677   u32 unnum_sw_index = ~0;
6678   u8 is_add = 1;
6679   u8 sw_if_index_set = 0;
6680
6681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6682     {
6683       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6684         sw_if_index_set = 1;
6685       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6686         sw_if_index_set = 1;
6687       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6688         ;
6689       else if (unformat (i, "del"))
6690         is_add = 0;
6691       else
6692         {
6693           clib_warning ("parse error '%U'", format_unformat_error, i);
6694           return -99;
6695         }
6696     }
6697
6698   if (sw_if_index_set == 0)
6699     {
6700       errmsg ("missing interface name or sw_if_index\n");
6701       return -99;
6702     }
6703
6704   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6705
6706   mp->sw_if_index = ntohl (sw_if_index);
6707   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6708   mp->is_add = is_add;
6709
6710   S;
6711   W;
6712   /* NOTREACHED */
6713   return 0;
6714 }
6715
6716 static int
6717 api_ip_neighbor_add_del (vat_main_t * vam)
6718 {
6719   unformat_input_t *i = vam->input;
6720   vl_api_ip_neighbor_add_del_t *mp;
6721   f64 timeout;
6722   u32 sw_if_index;
6723   u8 sw_if_index_set = 0;
6724   u32 vrf_id = 0;
6725   u8 is_add = 1;
6726   u8 is_static = 0;
6727   u8 mac_address[6];
6728   u8 mac_set = 0;
6729   u8 v4_address_set = 0;
6730   u8 v6_address_set = 0;
6731   ip4_address_t v4address;
6732   ip6_address_t v6address;
6733
6734   memset (mac_address, 0, sizeof (mac_address));
6735
6736   /* Parse args required to build the message */
6737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6738     {
6739       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6740         {
6741           mac_set = 1;
6742         }
6743       else if (unformat (i, "del"))
6744         is_add = 0;
6745       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6746         sw_if_index_set = 1;
6747       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6748         sw_if_index_set = 1;
6749       else if (unformat (i, "is_static"))
6750         is_static = 1;
6751       else if (unformat (i, "vrf %d", &vrf_id))
6752         ;
6753       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6754         v4_address_set = 1;
6755       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6756         v6_address_set = 1;
6757       else
6758         {
6759           clib_warning ("parse error '%U'", format_unformat_error, i);
6760           return -99;
6761         }
6762     }
6763
6764   if (sw_if_index_set == 0)
6765     {
6766       errmsg ("missing interface name or sw_if_index\n");
6767       return -99;
6768     }
6769   if (v4_address_set && v6_address_set)
6770     {
6771       errmsg ("both v4 and v6 addresses set\n");
6772       return -99;
6773     }
6774   if (!v4_address_set && !v6_address_set)
6775     {
6776       errmsg ("no address set\n");
6777       return -99;
6778     }
6779
6780   /* Construct the API message */
6781   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6782
6783   mp->sw_if_index = ntohl (sw_if_index);
6784   mp->is_add = is_add;
6785   mp->vrf_id = ntohl (vrf_id);
6786   mp->is_static = is_static;
6787   if (mac_set)
6788     clib_memcpy (mp->mac_address, mac_address, 6);
6789   if (v6_address_set)
6790     {
6791       mp->is_ipv6 = 1;
6792       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6793     }
6794   else
6795     {
6796       /* mp->is_ipv6 = 0; via memset in M macro above */
6797       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6798     }
6799
6800   /* send it... */
6801   S;
6802
6803   /* Wait for a reply, return good/bad news  */
6804   W;
6805
6806   /* NOTREACHED */
6807   return 0;
6808 }
6809
6810 static int
6811 api_reset_vrf (vat_main_t * vam)
6812 {
6813   unformat_input_t *i = vam->input;
6814   vl_api_reset_vrf_t *mp;
6815   f64 timeout;
6816   u32 vrf_id = 0;
6817   u8 is_ipv6 = 0;
6818   u8 vrf_id_set = 0;
6819
6820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6821     {
6822       if (unformat (i, "vrf %d", &vrf_id))
6823         vrf_id_set = 1;
6824       else if (unformat (i, "ipv6"))
6825         is_ipv6 = 1;
6826       else
6827         {
6828           clib_warning ("parse error '%U'", format_unformat_error, i);
6829           return -99;
6830         }
6831     }
6832
6833   if (vrf_id_set == 0)
6834     {
6835       errmsg ("missing vrf id\n");
6836       return -99;
6837     }
6838
6839   M (RESET_VRF, reset_vrf);
6840
6841   mp->vrf_id = ntohl (vrf_id);
6842   mp->is_ipv6 = is_ipv6;
6843
6844   S;
6845   W;
6846   /* NOTREACHED */
6847   return 0;
6848 }
6849
6850 static int
6851 api_create_vlan_subif (vat_main_t * vam)
6852 {
6853   unformat_input_t *i = vam->input;
6854   vl_api_create_vlan_subif_t *mp;
6855   f64 timeout;
6856   u32 sw_if_index;
6857   u8 sw_if_index_set = 0;
6858   u32 vlan_id;
6859   u8 vlan_id_set = 0;
6860
6861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6862     {
6863       if (unformat (i, "sw_if_index %d", &sw_if_index))
6864         sw_if_index_set = 1;
6865       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6866         sw_if_index_set = 1;
6867       else if (unformat (i, "vlan %d", &vlan_id))
6868         vlan_id_set = 1;
6869       else
6870         {
6871           clib_warning ("parse error '%U'", format_unformat_error, i);
6872           return -99;
6873         }
6874     }
6875
6876   if (sw_if_index_set == 0)
6877     {
6878       errmsg ("missing interface name or sw_if_index\n");
6879       return -99;
6880     }
6881
6882   if (vlan_id_set == 0)
6883     {
6884       errmsg ("missing vlan_id\n");
6885       return -99;
6886     }
6887   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6888
6889   mp->sw_if_index = ntohl (sw_if_index);
6890   mp->vlan_id = ntohl (vlan_id);
6891
6892   S;
6893   W;
6894   /* NOTREACHED */
6895   return 0;
6896 }
6897
6898 #define foreach_create_subif_bit                \
6899 _(no_tags)                                      \
6900 _(one_tag)                                      \
6901 _(two_tags)                                     \
6902 _(dot1ad)                                       \
6903 _(exact_match)                                  \
6904 _(default_sub)                                  \
6905 _(outer_vlan_id_any)                            \
6906 _(inner_vlan_id_any)
6907
6908 static int
6909 api_create_subif (vat_main_t * vam)
6910 {
6911   unformat_input_t *i = vam->input;
6912   vl_api_create_subif_t *mp;
6913   f64 timeout;
6914   u32 sw_if_index;
6915   u8 sw_if_index_set = 0;
6916   u32 sub_id;
6917   u8 sub_id_set = 0;
6918   u32 no_tags = 0;
6919   u32 one_tag = 0;
6920   u32 two_tags = 0;
6921   u32 dot1ad = 0;
6922   u32 exact_match = 0;
6923   u32 default_sub = 0;
6924   u32 outer_vlan_id_any = 0;
6925   u32 inner_vlan_id_any = 0;
6926   u32 tmp;
6927   u16 outer_vlan_id = 0;
6928   u16 inner_vlan_id = 0;
6929
6930   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6931     {
6932       if (unformat (i, "sw_if_index %d", &sw_if_index))
6933         sw_if_index_set = 1;
6934       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6935         sw_if_index_set = 1;
6936       else if (unformat (i, "sub_id %d", &sub_id))
6937         sub_id_set = 1;
6938       else if (unformat (i, "outer_vlan_id %d", &tmp))
6939         outer_vlan_id = tmp;
6940       else if (unformat (i, "inner_vlan_id %d", &tmp))
6941         inner_vlan_id = tmp;
6942
6943 #define _(a) else if (unformat (i, #a)) a = 1 ;
6944       foreach_create_subif_bit
6945 #undef _
6946         else
6947         {
6948           clib_warning ("parse error '%U'", format_unformat_error, i);
6949           return -99;
6950         }
6951     }
6952
6953   if (sw_if_index_set == 0)
6954     {
6955       errmsg ("missing interface name or sw_if_index\n");
6956       return -99;
6957     }
6958
6959   if (sub_id_set == 0)
6960     {
6961       errmsg ("missing sub_id\n");
6962       return -99;
6963     }
6964   M (CREATE_SUBIF, create_subif);
6965
6966   mp->sw_if_index = ntohl (sw_if_index);
6967   mp->sub_id = ntohl (sub_id);
6968
6969 #define _(a) mp->a = a;
6970   foreach_create_subif_bit;
6971 #undef _
6972
6973   mp->outer_vlan_id = ntohs (outer_vlan_id);
6974   mp->inner_vlan_id = ntohs (inner_vlan_id);
6975
6976   S;
6977   W;
6978   /* NOTREACHED */
6979   return 0;
6980 }
6981
6982 static int
6983 api_oam_add_del (vat_main_t * vam)
6984 {
6985   unformat_input_t *i = vam->input;
6986   vl_api_oam_add_del_t *mp;
6987   f64 timeout;
6988   u32 vrf_id = 0;
6989   u8 is_add = 1;
6990   ip4_address_t src, dst;
6991   u8 src_set = 0;
6992   u8 dst_set = 0;
6993
6994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6995     {
6996       if (unformat (i, "vrf %d", &vrf_id))
6997         ;
6998       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6999         src_set = 1;
7000       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7001         dst_set = 1;
7002       else if (unformat (i, "del"))
7003         is_add = 0;
7004       else
7005         {
7006           clib_warning ("parse error '%U'", format_unformat_error, i);
7007           return -99;
7008         }
7009     }
7010
7011   if (src_set == 0)
7012     {
7013       errmsg ("missing src addr\n");
7014       return -99;
7015     }
7016
7017   if (dst_set == 0)
7018     {
7019       errmsg ("missing dst addr\n");
7020       return -99;
7021     }
7022
7023   M (OAM_ADD_DEL, oam_add_del);
7024
7025   mp->vrf_id = ntohl (vrf_id);
7026   mp->is_add = is_add;
7027   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7028   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7029
7030   S;
7031   W;
7032   /* NOTREACHED */
7033   return 0;
7034 }
7035
7036 static int
7037 api_reset_fib (vat_main_t * vam)
7038 {
7039   unformat_input_t *i = vam->input;
7040   vl_api_reset_fib_t *mp;
7041   f64 timeout;
7042   u32 vrf_id = 0;
7043   u8 is_ipv6 = 0;
7044   u8 vrf_id_set = 0;
7045
7046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7047     {
7048       if (unformat (i, "vrf %d", &vrf_id))
7049         vrf_id_set = 1;
7050       else if (unformat (i, "ipv6"))
7051         is_ipv6 = 1;
7052       else
7053         {
7054           clib_warning ("parse error '%U'", format_unformat_error, i);
7055           return -99;
7056         }
7057     }
7058
7059   if (vrf_id_set == 0)
7060     {
7061       errmsg ("missing vrf id\n");
7062       return -99;
7063     }
7064
7065   M (RESET_FIB, reset_fib);
7066
7067   mp->vrf_id = ntohl (vrf_id);
7068   mp->is_ipv6 = is_ipv6;
7069
7070   S;
7071   W;
7072   /* NOTREACHED */
7073   return 0;
7074 }
7075
7076 static int
7077 api_dhcp_proxy_config (vat_main_t * vam)
7078 {
7079   unformat_input_t *i = vam->input;
7080   vl_api_dhcp_proxy_config_t *mp;
7081   f64 timeout;
7082   u32 vrf_id = 0;
7083   u8 is_add = 1;
7084   u8 insert_cid = 1;
7085   u8 v4_address_set = 0;
7086   u8 v6_address_set = 0;
7087   ip4_address_t v4address;
7088   ip6_address_t v6address;
7089   u8 v4_src_address_set = 0;
7090   u8 v6_src_address_set = 0;
7091   ip4_address_t v4srcaddress;
7092   ip6_address_t v6srcaddress;
7093
7094   /* Parse args required to build the message */
7095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7096     {
7097       if (unformat (i, "del"))
7098         is_add = 0;
7099       else if (unformat (i, "vrf %d", &vrf_id))
7100         ;
7101       else if (unformat (i, "insert-cid %d", &insert_cid))
7102         ;
7103       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7104         v4_address_set = 1;
7105       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7106         v6_address_set = 1;
7107       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7108         v4_src_address_set = 1;
7109       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7110         v6_src_address_set = 1;
7111       else
7112         break;
7113     }
7114
7115   if (v4_address_set && v6_address_set)
7116     {
7117       errmsg ("both v4 and v6 server addresses set\n");
7118       return -99;
7119     }
7120   if (!v4_address_set && !v6_address_set)
7121     {
7122       errmsg ("no server addresses set\n");
7123       return -99;
7124     }
7125
7126   if (v4_src_address_set && v6_src_address_set)
7127     {
7128       errmsg ("both v4 and v6  src addresses set\n");
7129       return -99;
7130     }
7131   if (!v4_src_address_set && !v6_src_address_set)
7132     {
7133       errmsg ("no src addresses set\n");
7134       return -99;
7135     }
7136
7137   if (!(v4_src_address_set && v4_address_set) &&
7138       !(v6_src_address_set && v6_address_set))
7139     {
7140       errmsg ("no matching server and src addresses set\n");
7141       return -99;
7142     }
7143
7144   /* Construct the API message */
7145   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7146
7147   mp->insert_circuit_id = insert_cid;
7148   mp->is_add = is_add;
7149   mp->vrf_id = ntohl (vrf_id);
7150   if (v6_address_set)
7151     {
7152       mp->is_ipv6 = 1;
7153       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7154       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7155     }
7156   else
7157     {
7158       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7159       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7160     }
7161
7162   /* send it... */
7163   S;
7164
7165   /* Wait for a reply, return good/bad news  */
7166   W;
7167   /* NOTREACHED */
7168   return 0;
7169 }
7170
7171 static int
7172 api_dhcp_proxy_config_2 (vat_main_t * vam)
7173 {
7174   unformat_input_t *i = vam->input;
7175   vl_api_dhcp_proxy_config_2_t *mp;
7176   f64 timeout;
7177   u32 rx_vrf_id = 0;
7178   u32 server_vrf_id = 0;
7179   u8 is_add = 1;
7180   u8 insert_cid = 1;
7181   u8 v4_address_set = 0;
7182   u8 v6_address_set = 0;
7183   ip4_address_t v4address;
7184   ip6_address_t v6address;
7185   u8 v4_src_address_set = 0;
7186   u8 v6_src_address_set = 0;
7187   ip4_address_t v4srcaddress;
7188   ip6_address_t v6srcaddress;
7189
7190   /* Parse args required to build the message */
7191   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7192     {
7193       if (unformat (i, "del"))
7194         is_add = 0;
7195       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7196         ;
7197       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7198         ;
7199       else if (unformat (i, "insert-cid %d", &insert_cid))
7200         ;
7201       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7202         v4_address_set = 1;
7203       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7204         v6_address_set = 1;
7205       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7206         v4_src_address_set = 1;
7207       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7208         v6_src_address_set = 1;
7209       else
7210         break;
7211     }
7212
7213   if (v4_address_set && v6_address_set)
7214     {
7215       errmsg ("both v4 and v6 server addresses set\n");
7216       return -99;
7217     }
7218   if (!v4_address_set && !v6_address_set)
7219     {
7220       errmsg ("no server addresses set\n");
7221       return -99;
7222     }
7223
7224   if (v4_src_address_set && v6_src_address_set)
7225     {
7226       errmsg ("both v4 and v6  src addresses set\n");
7227       return -99;
7228     }
7229   if (!v4_src_address_set && !v6_src_address_set)
7230     {
7231       errmsg ("no src addresses set\n");
7232       return -99;
7233     }
7234
7235   if (!(v4_src_address_set && v4_address_set) &&
7236       !(v6_src_address_set && v6_address_set))
7237     {
7238       errmsg ("no matching server and src addresses set\n");
7239       return -99;
7240     }
7241
7242   /* Construct the API message */
7243   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7244
7245   mp->insert_circuit_id = insert_cid;
7246   mp->is_add = is_add;
7247   mp->rx_vrf_id = ntohl (rx_vrf_id);
7248   mp->server_vrf_id = ntohl (server_vrf_id);
7249   if (v6_address_set)
7250     {
7251       mp->is_ipv6 = 1;
7252       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7253       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7254     }
7255   else
7256     {
7257       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7258       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7259     }
7260
7261   /* send it... */
7262   S;
7263
7264   /* Wait for a reply, return good/bad news  */
7265   W;
7266   /* NOTREACHED */
7267   return 0;
7268 }
7269
7270 static int
7271 api_dhcp_proxy_set_vss (vat_main_t * vam)
7272 {
7273   unformat_input_t *i = vam->input;
7274   vl_api_dhcp_proxy_set_vss_t *mp;
7275   f64 timeout;
7276   u8 is_ipv6 = 0;
7277   u8 is_add = 1;
7278   u32 tbl_id;
7279   u8 tbl_id_set = 0;
7280   u32 oui;
7281   u8 oui_set = 0;
7282   u32 fib_id;
7283   u8 fib_id_set = 0;
7284
7285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7286     {
7287       if (unformat (i, "tbl_id %d", &tbl_id))
7288         tbl_id_set = 1;
7289       if (unformat (i, "fib_id %d", &fib_id))
7290         fib_id_set = 1;
7291       if (unformat (i, "oui %d", &oui))
7292         oui_set = 1;
7293       else if (unformat (i, "ipv6"))
7294         is_ipv6 = 1;
7295       else if (unformat (i, "del"))
7296         is_add = 0;
7297       else
7298         {
7299           clib_warning ("parse error '%U'", format_unformat_error, i);
7300           return -99;
7301         }
7302     }
7303
7304   if (tbl_id_set == 0)
7305     {
7306       errmsg ("missing tbl id\n");
7307       return -99;
7308     }
7309
7310   if (fib_id_set == 0)
7311     {
7312       errmsg ("missing fib id\n");
7313       return -99;
7314     }
7315   if (oui_set == 0)
7316     {
7317       errmsg ("missing oui\n");
7318       return -99;
7319     }
7320
7321   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7322   mp->tbl_id = ntohl (tbl_id);
7323   mp->fib_id = ntohl (fib_id);
7324   mp->oui = ntohl (oui);
7325   mp->is_ipv6 = is_ipv6;
7326   mp->is_add = is_add;
7327
7328   S;
7329   W;
7330   /* NOTREACHED */
7331   return 0;
7332 }
7333
7334 static int
7335 api_dhcp_client_config (vat_main_t * vam)
7336 {
7337   unformat_input_t *i = vam->input;
7338   vl_api_dhcp_client_config_t *mp;
7339   f64 timeout;
7340   u32 sw_if_index;
7341   u8 sw_if_index_set = 0;
7342   u8 is_add = 1;
7343   u8 *hostname = 0;
7344   u8 disable_event = 0;
7345
7346   /* Parse args required to build the message */
7347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7348     {
7349       if (unformat (i, "del"))
7350         is_add = 0;
7351       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7352         sw_if_index_set = 1;
7353       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7354         sw_if_index_set = 1;
7355       else if (unformat (i, "hostname %s", &hostname))
7356         ;
7357       else if (unformat (i, "disable_event"))
7358         disable_event = 1;
7359       else
7360         break;
7361     }
7362
7363   if (sw_if_index_set == 0)
7364     {
7365       errmsg ("missing interface name or sw_if_index\n");
7366       return -99;
7367     }
7368
7369   if (vec_len (hostname) > 63)
7370     {
7371       errmsg ("hostname too long\n");
7372     }
7373   vec_add1 (hostname, 0);
7374
7375   /* Construct the API message */
7376   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7377
7378   mp->sw_if_index = ntohl (sw_if_index);
7379   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7380   vec_free (hostname);
7381   mp->is_add = is_add;
7382   mp->want_dhcp_event = disable_event ? 0 : 1;
7383   mp->pid = getpid ();
7384
7385   /* send it... */
7386   S;
7387
7388   /* Wait for a reply, return good/bad news  */
7389   W;
7390   /* NOTREACHED */
7391   return 0;
7392 }
7393
7394 static int
7395 api_set_ip_flow_hash (vat_main_t * vam)
7396 {
7397   unformat_input_t *i = vam->input;
7398   vl_api_set_ip_flow_hash_t *mp;
7399   f64 timeout;
7400   u32 vrf_id = 0;
7401   u8 is_ipv6 = 0;
7402   u8 vrf_id_set = 0;
7403   u8 src = 0;
7404   u8 dst = 0;
7405   u8 sport = 0;
7406   u8 dport = 0;
7407   u8 proto = 0;
7408   u8 reverse = 0;
7409
7410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7411     {
7412       if (unformat (i, "vrf %d", &vrf_id))
7413         vrf_id_set = 1;
7414       else if (unformat (i, "ipv6"))
7415         is_ipv6 = 1;
7416       else if (unformat (i, "src"))
7417         src = 1;
7418       else if (unformat (i, "dst"))
7419         dst = 1;
7420       else if (unformat (i, "sport"))
7421         sport = 1;
7422       else if (unformat (i, "dport"))
7423         dport = 1;
7424       else if (unformat (i, "proto"))
7425         proto = 1;
7426       else if (unformat (i, "reverse"))
7427         reverse = 1;
7428
7429       else
7430         {
7431           clib_warning ("parse error '%U'", format_unformat_error, i);
7432           return -99;
7433         }
7434     }
7435
7436   if (vrf_id_set == 0)
7437     {
7438       errmsg ("missing vrf id\n");
7439       return -99;
7440     }
7441
7442   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7443   mp->src = src;
7444   mp->dst = dst;
7445   mp->sport = sport;
7446   mp->dport = dport;
7447   mp->proto = proto;
7448   mp->reverse = reverse;
7449   mp->vrf_id = ntohl (vrf_id);
7450   mp->is_ipv6 = is_ipv6;
7451
7452   S;
7453   W;
7454   /* NOTREACHED */
7455   return 0;
7456 }
7457
7458 static int
7459 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7460 {
7461   unformat_input_t *i = vam->input;
7462   vl_api_sw_interface_ip6_enable_disable_t *mp;
7463   f64 timeout;
7464   u32 sw_if_index;
7465   u8 sw_if_index_set = 0;
7466   u8 enable = 0;
7467
7468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7469     {
7470       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7471         sw_if_index_set = 1;
7472       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7473         sw_if_index_set = 1;
7474       else if (unformat (i, "enable"))
7475         enable = 1;
7476       else if (unformat (i, "disable"))
7477         enable = 0;
7478       else
7479         {
7480           clib_warning ("parse error '%U'", format_unformat_error, i);
7481           return -99;
7482         }
7483     }
7484
7485   if (sw_if_index_set == 0)
7486     {
7487       errmsg ("missing interface name or sw_if_index\n");
7488       return -99;
7489     }
7490
7491   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7492
7493   mp->sw_if_index = ntohl (sw_if_index);
7494   mp->enable = enable;
7495
7496   S;
7497   W;
7498   /* NOTREACHED */
7499   return 0;
7500 }
7501
7502 static int
7503 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7504 {
7505   unformat_input_t *i = vam->input;
7506   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7507   f64 timeout;
7508   u32 sw_if_index;
7509   u8 sw_if_index_set = 0;
7510   u32 address_length = 0;
7511   u8 v6_address_set = 0;
7512   ip6_address_t v6address;
7513
7514   /* Parse args required to build the message */
7515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7516     {
7517       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7518         sw_if_index_set = 1;
7519       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7520         sw_if_index_set = 1;
7521       else if (unformat (i, "%U/%d",
7522                          unformat_ip6_address, &v6address, &address_length))
7523         v6_address_set = 1;
7524       else
7525         break;
7526     }
7527
7528   if (sw_if_index_set == 0)
7529     {
7530       errmsg ("missing interface name or sw_if_index\n");
7531       return -99;
7532     }
7533   if (!v6_address_set)
7534     {
7535       errmsg ("no address set\n");
7536       return -99;
7537     }
7538
7539   /* Construct the API message */
7540   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7541      sw_interface_ip6_set_link_local_address);
7542
7543   mp->sw_if_index = ntohl (sw_if_index);
7544   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7545   mp->address_length = address_length;
7546
7547   /* send it... */
7548   S;
7549
7550   /* Wait for a reply, return good/bad news  */
7551   W;
7552
7553   /* NOTREACHED */
7554   return 0;
7555 }
7556
7557
7558 static int
7559 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7560 {
7561   unformat_input_t *i = vam->input;
7562   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7563   f64 timeout;
7564   u32 sw_if_index;
7565   u8 sw_if_index_set = 0;
7566   u32 address_length = 0;
7567   u8 v6_address_set = 0;
7568   ip6_address_t v6address;
7569   u8 use_default = 0;
7570   u8 no_advertise = 0;
7571   u8 off_link = 0;
7572   u8 no_autoconfig = 0;
7573   u8 no_onlink = 0;
7574   u8 is_no = 0;
7575   u32 val_lifetime = 0;
7576   u32 pref_lifetime = 0;
7577
7578   /* Parse args required to build the message */
7579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7580     {
7581       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7582         sw_if_index_set = 1;
7583       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7584         sw_if_index_set = 1;
7585       else if (unformat (i, "%U/%d",
7586                          unformat_ip6_address, &v6address, &address_length))
7587         v6_address_set = 1;
7588       else if (unformat (i, "val_life %d", &val_lifetime))
7589         ;
7590       else if (unformat (i, "pref_life %d", &pref_lifetime))
7591         ;
7592       else if (unformat (i, "def"))
7593         use_default = 1;
7594       else if (unformat (i, "noadv"))
7595         no_advertise = 1;
7596       else if (unformat (i, "offl"))
7597         off_link = 1;
7598       else if (unformat (i, "noauto"))
7599         no_autoconfig = 1;
7600       else if (unformat (i, "nolink"))
7601         no_onlink = 1;
7602       else if (unformat (i, "isno"))
7603         is_no = 1;
7604       else
7605         {
7606           clib_warning ("parse error '%U'", format_unformat_error, i);
7607           return -99;
7608         }
7609     }
7610
7611   if (sw_if_index_set == 0)
7612     {
7613       errmsg ("missing interface name or sw_if_index\n");
7614       return -99;
7615     }
7616   if (!v6_address_set)
7617     {
7618       errmsg ("no address set\n");
7619       return -99;
7620     }
7621
7622   /* Construct the API message */
7623   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7624
7625   mp->sw_if_index = ntohl (sw_if_index);
7626   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7627   mp->address_length = address_length;
7628   mp->use_default = use_default;
7629   mp->no_advertise = no_advertise;
7630   mp->off_link = off_link;
7631   mp->no_autoconfig = no_autoconfig;
7632   mp->no_onlink = no_onlink;
7633   mp->is_no = is_no;
7634   mp->val_lifetime = ntohl (val_lifetime);
7635   mp->pref_lifetime = ntohl (pref_lifetime);
7636
7637   /* send it... */
7638   S;
7639
7640   /* Wait for a reply, return good/bad news  */
7641   W;
7642
7643   /* NOTREACHED */
7644   return 0;
7645 }
7646
7647 static int
7648 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7649 {
7650   unformat_input_t *i = vam->input;
7651   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7652   f64 timeout;
7653   u32 sw_if_index;
7654   u8 sw_if_index_set = 0;
7655   u8 suppress = 0;
7656   u8 managed = 0;
7657   u8 other = 0;
7658   u8 ll_option = 0;
7659   u8 send_unicast = 0;
7660   u8 cease = 0;
7661   u8 is_no = 0;
7662   u8 default_router = 0;
7663   u32 max_interval = 0;
7664   u32 min_interval = 0;
7665   u32 lifetime = 0;
7666   u32 initial_count = 0;
7667   u32 initial_interval = 0;
7668
7669
7670   /* Parse args required to build the message */
7671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7672     {
7673       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7674         sw_if_index_set = 1;
7675       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7676         sw_if_index_set = 1;
7677       else if (unformat (i, "maxint %d", &max_interval))
7678         ;
7679       else if (unformat (i, "minint %d", &min_interval))
7680         ;
7681       else if (unformat (i, "life %d", &lifetime))
7682         ;
7683       else if (unformat (i, "count %d", &initial_count))
7684         ;
7685       else if (unformat (i, "interval %d", &initial_interval))
7686         ;
7687       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7688         suppress = 1;
7689       else if (unformat (i, "managed"))
7690         managed = 1;
7691       else if (unformat (i, "other"))
7692         other = 1;
7693       else if (unformat (i, "ll"))
7694         ll_option = 1;
7695       else if (unformat (i, "send"))
7696         send_unicast = 1;
7697       else if (unformat (i, "cease"))
7698         cease = 1;
7699       else if (unformat (i, "isno"))
7700         is_no = 1;
7701       else if (unformat (i, "def"))
7702         default_router = 1;
7703       else
7704         {
7705           clib_warning ("parse error '%U'", format_unformat_error, i);
7706           return -99;
7707         }
7708     }
7709
7710   if (sw_if_index_set == 0)
7711     {
7712       errmsg ("missing interface name or sw_if_index\n");
7713       return -99;
7714     }
7715
7716   /* Construct the API message */
7717   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7718
7719   mp->sw_if_index = ntohl (sw_if_index);
7720   mp->max_interval = ntohl (max_interval);
7721   mp->min_interval = ntohl (min_interval);
7722   mp->lifetime = ntohl (lifetime);
7723   mp->initial_count = ntohl (initial_count);
7724   mp->initial_interval = ntohl (initial_interval);
7725   mp->suppress = suppress;
7726   mp->managed = managed;
7727   mp->other = other;
7728   mp->ll_option = ll_option;
7729   mp->send_unicast = send_unicast;
7730   mp->cease = cease;
7731   mp->is_no = is_no;
7732   mp->default_router = default_router;
7733
7734   /* send it... */
7735   S;
7736
7737   /* Wait for a reply, return good/bad news  */
7738   W;
7739
7740   /* NOTREACHED */
7741   return 0;
7742 }
7743
7744 static int
7745 api_set_arp_neighbor_limit (vat_main_t * vam)
7746 {
7747   unformat_input_t *i = vam->input;
7748   vl_api_set_arp_neighbor_limit_t *mp;
7749   f64 timeout;
7750   u32 arp_nbr_limit;
7751   u8 limit_set = 0;
7752   u8 is_ipv6 = 0;
7753
7754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7755     {
7756       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7757         limit_set = 1;
7758       else if (unformat (i, "ipv6"))
7759         is_ipv6 = 1;
7760       else
7761         {
7762           clib_warning ("parse error '%U'", format_unformat_error, i);
7763           return -99;
7764         }
7765     }
7766
7767   if (limit_set == 0)
7768     {
7769       errmsg ("missing limit value\n");
7770       return -99;
7771     }
7772
7773   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7774
7775   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7776   mp->is_ipv6 = is_ipv6;
7777
7778   S;
7779   W;
7780   /* NOTREACHED */
7781   return 0;
7782 }
7783
7784 static int
7785 api_l2_patch_add_del (vat_main_t * vam)
7786 {
7787   unformat_input_t *i = vam->input;
7788   vl_api_l2_patch_add_del_t *mp;
7789   f64 timeout;
7790   u32 rx_sw_if_index;
7791   u8 rx_sw_if_index_set = 0;
7792   u32 tx_sw_if_index;
7793   u8 tx_sw_if_index_set = 0;
7794   u8 is_add = 1;
7795
7796   /* Parse args required to build the message */
7797   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7798     {
7799       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7800         rx_sw_if_index_set = 1;
7801       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7802         tx_sw_if_index_set = 1;
7803       else if (unformat (i, "rx"))
7804         {
7805           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7806             {
7807               if (unformat (i, "%U", unformat_sw_if_index, vam,
7808                             &rx_sw_if_index))
7809                 rx_sw_if_index_set = 1;
7810             }
7811           else
7812             break;
7813         }
7814       else if (unformat (i, "tx"))
7815         {
7816           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7817             {
7818               if (unformat (i, "%U", unformat_sw_if_index, vam,
7819                             &tx_sw_if_index))
7820                 tx_sw_if_index_set = 1;
7821             }
7822           else
7823             break;
7824         }
7825       else if (unformat (i, "del"))
7826         is_add = 0;
7827       else
7828         break;
7829     }
7830
7831   if (rx_sw_if_index_set == 0)
7832     {
7833       errmsg ("missing rx interface name or rx_sw_if_index\n");
7834       return -99;
7835     }
7836
7837   if (tx_sw_if_index_set == 0)
7838     {
7839       errmsg ("missing tx interface name or tx_sw_if_index\n");
7840       return -99;
7841     }
7842
7843   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7844
7845   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7846   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7847   mp->is_add = is_add;
7848
7849   S;
7850   W;
7851   /* NOTREACHED */
7852   return 0;
7853 }
7854
7855 static int
7856 api_ioam_enable (vat_main_t * vam)
7857 {
7858   unformat_input_t *input = vam->input;
7859   vl_api_ioam_enable_t *mp;
7860   f64 timeout;
7861   u32 id = 0;
7862   int has_trace_option = 0;
7863   int has_pot_option = 0;
7864   int has_seqno_option = 0;
7865   int has_analyse_option = 0;
7866
7867   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7868     {
7869       if (unformat (input, "trace"))
7870         has_trace_option = 1;
7871       else if (unformat (input, "pot"))
7872         has_pot_option = 1;
7873       else if (unformat (input, "seqno"))
7874         has_seqno_option = 1;
7875       else if (unformat (input, "analyse"))
7876         has_analyse_option = 1;
7877       else
7878         break;
7879     }
7880   M (IOAM_ENABLE, ioam_enable);
7881   mp->id = htons (id);
7882   mp->seqno = has_seqno_option;
7883   mp->analyse = has_analyse_option;
7884   mp->pot_enable = has_pot_option;
7885   mp->trace_enable = has_trace_option;
7886
7887   S;
7888   W;
7889
7890   return (0);
7891
7892 }
7893
7894
7895 static int
7896 api_ioam_disable (vat_main_t * vam)
7897 {
7898   vl_api_ioam_disable_t *mp;
7899   f64 timeout;
7900
7901   M (IOAM_DISABLE, ioam_disable);
7902   S;
7903   W;
7904   return 0;
7905 }
7906
7907 static int
7908 api_sr_tunnel_add_del (vat_main_t * vam)
7909 {
7910   unformat_input_t *i = vam->input;
7911   vl_api_sr_tunnel_add_del_t *mp;
7912   f64 timeout;
7913   int is_del = 0;
7914   int pl_index;
7915   ip6_address_t src_address;
7916   int src_address_set = 0;
7917   ip6_address_t dst_address;
7918   u32 dst_mask_width;
7919   int dst_address_set = 0;
7920   u16 flags = 0;
7921   u32 rx_table_id = 0;
7922   u32 tx_table_id = 0;
7923   ip6_address_t *segments = 0;
7924   ip6_address_t *this_seg;
7925   ip6_address_t *tags = 0;
7926   ip6_address_t *this_tag;
7927   ip6_address_t next_address, tag;
7928   u8 *name = 0;
7929   u8 *policy_name = 0;
7930
7931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7932     {
7933       if (unformat (i, "del"))
7934         is_del = 1;
7935       else if (unformat (i, "name %s", &name))
7936         ;
7937       else if (unformat (i, "policy %s", &policy_name))
7938         ;
7939       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7940         ;
7941       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7942         ;
7943       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7944         src_address_set = 1;
7945       else if (unformat (i, "dst %U/%d",
7946                          unformat_ip6_address, &dst_address, &dst_mask_width))
7947         dst_address_set = 1;
7948       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7949         {
7950           vec_add2 (segments, this_seg, 1);
7951           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7952                        sizeof (*this_seg));
7953         }
7954       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7955         {
7956           vec_add2 (tags, this_tag, 1);
7957           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7958         }
7959       else if (unformat (i, "clean"))
7960         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7961       else if (unformat (i, "protected"))
7962         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7963       else if (unformat (i, "InPE %d", &pl_index))
7964         {
7965           if (pl_index <= 0 || pl_index > 4)
7966             {
7967             pl_index_range_error:
7968               errmsg ("pl index %d out of range\n", pl_index);
7969               return -99;
7970             }
7971           flags |=
7972             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7973         }
7974       else if (unformat (i, "EgPE %d", &pl_index))
7975         {
7976           if (pl_index <= 0 || pl_index > 4)
7977             goto pl_index_range_error;
7978           flags |=
7979             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7980         }
7981       else if (unformat (i, "OrgSrc %d", &pl_index))
7982         {
7983           if (pl_index <= 0 || pl_index > 4)
7984             goto pl_index_range_error;
7985           flags |=
7986             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7987         }
7988       else
7989         break;
7990     }
7991
7992   if (!src_address_set)
7993     {
7994       errmsg ("src address required\n");
7995       return -99;
7996     }
7997
7998   if (!dst_address_set)
7999     {
8000       errmsg ("dst address required\n");
8001       return -99;
8002     }
8003
8004   if (!segments)
8005     {
8006       errmsg ("at least one sr segment required\n");
8007       return -99;
8008     }
8009
8010   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
8011       vec_len (segments) * sizeof (ip6_address_t)
8012       + vec_len (tags) * sizeof (ip6_address_t));
8013
8014   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8015   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8016   mp->dst_mask_width = dst_mask_width;
8017   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8018   mp->n_segments = vec_len (segments);
8019   mp->n_tags = vec_len (tags);
8020   mp->is_add = is_del == 0;
8021   clib_memcpy (mp->segs_and_tags, segments,
8022                vec_len (segments) * sizeof (ip6_address_t));
8023   clib_memcpy (mp->segs_and_tags +
8024                vec_len (segments) * sizeof (ip6_address_t), tags,
8025                vec_len (tags) * sizeof (ip6_address_t));
8026
8027   mp->outer_vrf_id = ntohl (rx_table_id);
8028   mp->inner_vrf_id = ntohl (tx_table_id);
8029   memcpy (mp->name, name, vec_len (name));
8030   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8031
8032   vec_free (segments);
8033   vec_free (tags);
8034
8035   S;
8036   W;
8037   /* NOTREACHED */
8038 }
8039
8040 static int
8041 api_sr_policy_add_del (vat_main_t * vam)
8042 {
8043   unformat_input_t *input = vam->input;
8044   vl_api_sr_policy_add_del_t *mp;
8045   f64 timeout;
8046   int is_del = 0;
8047   u8 *name = 0;
8048   u8 *tunnel_name = 0;
8049   u8 **tunnel_names = 0;
8050
8051   int name_set = 0;
8052   int tunnel_set = 0;
8053   int j = 0;
8054   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8055   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8056
8057   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8058     {
8059       if (unformat (input, "del"))
8060         is_del = 1;
8061       else if (unformat (input, "name %s", &name))
8062         name_set = 1;
8063       else if (unformat (input, "tunnel %s", &tunnel_name))
8064         {
8065           if (tunnel_name)
8066             {
8067               vec_add1 (tunnel_names, tunnel_name);
8068               /* For serializer:
8069                  - length = #bytes to store in serial vector
8070                  - +1 = byte to store that length
8071                */
8072               tunnel_names_length += (vec_len (tunnel_name) + 1);
8073               tunnel_set = 1;
8074               tunnel_name = 0;
8075             }
8076         }
8077       else
8078         break;
8079     }
8080
8081   if (!name_set)
8082     {
8083       errmsg ("policy name required\n");
8084       return -99;
8085     }
8086
8087   if ((!tunnel_set) && (!is_del))
8088     {
8089       errmsg ("tunnel name required\n");
8090       return -99;
8091     }
8092
8093   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8094
8095
8096
8097   mp->is_add = !is_del;
8098
8099   memcpy (mp->name, name, vec_len (name));
8100   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8101   u8 *serial_orig = 0;
8102   vec_validate (serial_orig, tunnel_names_length);
8103   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8104   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8105
8106   for (j = 0; j < vec_len (tunnel_names); j++)
8107     {
8108       tun_name_len = vec_len (tunnel_names[j]);
8109       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8110       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8111       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8112       serial_orig += tun_name_len;      // Advance past the copy
8113     }
8114   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8115
8116   vec_free (tunnel_names);
8117   vec_free (tunnel_name);
8118
8119   S;
8120   W;
8121   /* NOTREACHED */
8122 }
8123
8124 static int
8125 api_sr_multicast_map_add_del (vat_main_t * vam)
8126 {
8127   unformat_input_t *input = vam->input;
8128   vl_api_sr_multicast_map_add_del_t *mp;
8129   f64 timeout;
8130   int is_del = 0;
8131   ip6_address_t multicast_address;
8132   u8 *policy_name = 0;
8133   int multicast_address_set = 0;
8134
8135   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8136     {
8137       if (unformat (input, "del"))
8138         is_del = 1;
8139       else
8140         if (unformat
8141             (input, "address %U", unformat_ip6_address, &multicast_address))
8142         multicast_address_set = 1;
8143       else if (unformat (input, "sr-policy %s", &policy_name))
8144         ;
8145       else
8146         break;
8147     }
8148
8149   if (!is_del && !policy_name)
8150     {
8151       errmsg ("sr-policy name required\n");
8152       return -99;
8153     }
8154
8155
8156   if (!multicast_address_set)
8157     {
8158       errmsg ("address required\n");
8159       return -99;
8160     }
8161
8162   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8163
8164   mp->is_add = !is_del;
8165   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8166   clib_memcpy (mp->multicast_address, &multicast_address,
8167                sizeof (mp->multicast_address));
8168
8169
8170   vec_free (policy_name);
8171
8172   S;
8173   W;
8174   /* NOTREACHED */
8175 }
8176
8177
8178 #define foreach_tcp_proto_field                 \
8179 _(src_port)                                     \
8180 _(dst_port)
8181
8182 #define foreach_udp_proto_field                 \
8183 _(src_port)                                     \
8184 _(dst_port)
8185
8186 #define foreach_ip4_proto_field                 \
8187 _(src_address)                                  \
8188 _(dst_address)                                  \
8189 _(tos)                                          \
8190 _(length)                                       \
8191 _(fragment_id)                                  \
8192 _(ttl)                                          \
8193 _(protocol)                                     \
8194 _(checksum)
8195
8196 uword
8197 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8198 {
8199   u8 **maskp = va_arg (*args, u8 **);
8200   u8 *mask = 0;
8201   u8 found_something = 0;
8202   tcp_header_t *tcp;
8203
8204 #define _(a) u8 a=0;
8205   foreach_tcp_proto_field;
8206 #undef _
8207
8208   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8209     {
8210       if (0);
8211 #define _(a) else if (unformat (input, #a)) a=1;
8212       foreach_tcp_proto_field
8213 #undef _
8214         else
8215         break;
8216     }
8217
8218 #define _(a) found_something += a;
8219   foreach_tcp_proto_field;
8220 #undef _
8221
8222   if (found_something == 0)
8223     return 0;
8224
8225   vec_validate (mask, sizeof (*tcp) - 1);
8226
8227   tcp = (tcp_header_t *) mask;
8228
8229 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8230   foreach_tcp_proto_field;
8231 #undef _
8232
8233   *maskp = mask;
8234   return 1;
8235 }
8236
8237 uword
8238 unformat_udp_mask (unformat_input_t * input, va_list * args)
8239 {
8240   u8 **maskp = va_arg (*args, u8 **);
8241   u8 *mask = 0;
8242   u8 found_something = 0;
8243   udp_header_t *udp;
8244
8245 #define _(a) u8 a=0;
8246   foreach_udp_proto_field;
8247 #undef _
8248
8249   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8250     {
8251       if (0);
8252 #define _(a) else if (unformat (input, #a)) a=1;
8253       foreach_udp_proto_field
8254 #undef _
8255         else
8256         break;
8257     }
8258
8259 #define _(a) found_something += a;
8260   foreach_udp_proto_field;
8261 #undef _
8262
8263   if (found_something == 0)
8264     return 0;
8265
8266   vec_validate (mask, sizeof (*udp) - 1);
8267
8268   udp = (udp_header_t *) mask;
8269
8270 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8271   foreach_udp_proto_field;
8272 #undef _
8273
8274   *maskp = mask;
8275   return 1;
8276 }
8277
8278 typedef struct
8279 {
8280   u16 src_port, dst_port;
8281 } tcpudp_header_t;
8282
8283 uword
8284 unformat_l4_mask (unformat_input_t * input, va_list * args)
8285 {
8286   u8 **maskp = va_arg (*args, u8 **);
8287   u16 src_port = 0, dst_port = 0;
8288   tcpudp_header_t *tcpudp;
8289
8290   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8291     {
8292       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8293         return 1;
8294       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8295         return 1;
8296       else if (unformat (input, "src_port"))
8297         src_port = 0xFFFF;
8298       else if (unformat (input, "dst_port"))
8299         dst_port = 0xFFFF;
8300       else
8301         return 0;
8302     }
8303
8304   if (!src_port && !dst_port)
8305     return 0;
8306
8307   u8 *mask = 0;
8308   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8309
8310   tcpudp = (tcpudp_header_t *) mask;
8311   tcpudp->src_port = src_port;
8312   tcpudp->dst_port = dst_port;
8313
8314   *maskp = mask;
8315
8316   return 1;
8317 }
8318
8319 uword
8320 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8321 {
8322   u8 **maskp = va_arg (*args, u8 **);
8323   u8 *mask = 0;
8324   u8 found_something = 0;
8325   ip4_header_t *ip;
8326
8327 #define _(a) u8 a=0;
8328   foreach_ip4_proto_field;
8329 #undef _
8330   u8 version = 0;
8331   u8 hdr_length = 0;
8332
8333
8334   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8335     {
8336       if (unformat (input, "version"))
8337         version = 1;
8338       else if (unformat (input, "hdr_length"))
8339         hdr_length = 1;
8340       else if (unformat (input, "src"))
8341         src_address = 1;
8342       else if (unformat (input, "dst"))
8343         dst_address = 1;
8344       else if (unformat (input, "proto"))
8345         protocol = 1;
8346
8347 #define _(a) else if (unformat (input, #a)) a=1;
8348       foreach_ip4_proto_field
8349 #undef _
8350         else
8351         break;
8352     }
8353
8354 #define _(a) found_something += a;
8355   foreach_ip4_proto_field;
8356 #undef _
8357
8358   if (found_something == 0)
8359     return 0;
8360
8361   vec_validate (mask, sizeof (*ip) - 1);
8362
8363   ip = (ip4_header_t *) mask;
8364
8365 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8366   foreach_ip4_proto_field;
8367 #undef _
8368
8369   ip->ip_version_and_header_length = 0;
8370
8371   if (version)
8372     ip->ip_version_and_header_length |= 0xF0;
8373
8374   if (hdr_length)
8375     ip->ip_version_and_header_length |= 0x0F;
8376
8377   *maskp = mask;
8378   return 1;
8379 }
8380
8381 #define foreach_ip6_proto_field                 \
8382 _(src_address)                                  \
8383 _(dst_address)                                  \
8384 _(payload_length)                               \
8385 _(hop_limit)                                    \
8386 _(protocol)
8387
8388 uword
8389 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8390 {
8391   u8 **maskp = va_arg (*args, u8 **);
8392   u8 *mask = 0;
8393   u8 found_something = 0;
8394   ip6_header_t *ip;
8395   u32 ip_version_traffic_class_and_flow_label;
8396
8397 #define _(a) u8 a=0;
8398   foreach_ip6_proto_field;
8399 #undef _
8400   u8 version = 0;
8401   u8 traffic_class = 0;
8402   u8 flow_label = 0;
8403
8404   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8405     {
8406       if (unformat (input, "version"))
8407         version = 1;
8408       else if (unformat (input, "traffic-class"))
8409         traffic_class = 1;
8410       else if (unformat (input, "flow-label"))
8411         flow_label = 1;
8412       else if (unformat (input, "src"))
8413         src_address = 1;
8414       else if (unformat (input, "dst"))
8415         dst_address = 1;
8416       else if (unformat (input, "proto"))
8417         protocol = 1;
8418
8419 #define _(a) else if (unformat (input, #a)) a=1;
8420       foreach_ip6_proto_field
8421 #undef _
8422         else
8423         break;
8424     }
8425
8426 #define _(a) found_something += a;
8427   foreach_ip6_proto_field;
8428 #undef _
8429
8430   if (found_something == 0)
8431     return 0;
8432
8433   vec_validate (mask, sizeof (*ip) - 1);
8434
8435   ip = (ip6_header_t *) mask;
8436
8437 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8438   foreach_ip6_proto_field;
8439 #undef _
8440
8441   ip_version_traffic_class_and_flow_label = 0;
8442
8443   if (version)
8444     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8445
8446   if (traffic_class)
8447     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8448
8449   if (flow_label)
8450     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8451
8452   ip->ip_version_traffic_class_and_flow_label =
8453     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8454
8455   *maskp = mask;
8456   return 1;
8457 }
8458
8459 uword
8460 unformat_l3_mask (unformat_input_t * input, va_list * args)
8461 {
8462   u8 **maskp = va_arg (*args, u8 **);
8463
8464   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8465     {
8466       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8467         return 1;
8468       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8469         return 1;
8470       else
8471         break;
8472     }
8473   return 0;
8474 }
8475
8476 uword
8477 unformat_l2_mask (unformat_input_t * input, va_list * args)
8478 {
8479   u8 **maskp = va_arg (*args, u8 **);
8480   u8 *mask = 0;
8481   u8 src = 0;
8482   u8 dst = 0;
8483   u8 proto = 0;
8484   u8 tag1 = 0;
8485   u8 tag2 = 0;
8486   u8 ignore_tag1 = 0;
8487   u8 ignore_tag2 = 0;
8488   u8 cos1 = 0;
8489   u8 cos2 = 0;
8490   u8 dot1q = 0;
8491   u8 dot1ad = 0;
8492   int len = 14;
8493
8494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8495     {
8496       if (unformat (input, "src"))
8497         src = 1;
8498       else if (unformat (input, "dst"))
8499         dst = 1;
8500       else if (unformat (input, "proto"))
8501         proto = 1;
8502       else if (unformat (input, "tag1"))
8503         tag1 = 1;
8504       else if (unformat (input, "tag2"))
8505         tag2 = 1;
8506       else if (unformat (input, "ignore-tag1"))
8507         ignore_tag1 = 1;
8508       else if (unformat (input, "ignore-tag2"))
8509         ignore_tag2 = 1;
8510       else if (unformat (input, "cos1"))
8511         cos1 = 1;
8512       else if (unformat (input, "cos2"))
8513         cos2 = 1;
8514       else if (unformat (input, "dot1q"))
8515         dot1q = 1;
8516       else if (unformat (input, "dot1ad"))
8517         dot1ad = 1;
8518       else
8519         break;
8520     }
8521   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8522        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8523     return 0;
8524
8525   if (tag1 || ignore_tag1 || cos1 || dot1q)
8526     len = 18;
8527   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8528     len = 22;
8529
8530   vec_validate (mask, len - 1);
8531
8532   if (dst)
8533     memset (mask, 0xff, 6);
8534
8535   if (src)
8536     memset (mask + 6, 0xff, 6);
8537
8538   if (tag2 || dot1ad)
8539     {
8540       /* inner vlan tag */
8541       if (tag2)
8542         {
8543           mask[19] = 0xff;
8544           mask[18] = 0x0f;
8545         }
8546       if (cos2)
8547         mask[18] |= 0xe0;
8548       if (proto)
8549         mask[21] = mask[20] = 0xff;
8550       if (tag1)
8551         {
8552           mask[15] = 0xff;
8553           mask[14] = 0x0f;
8554         }
8555       if (cos1)
8556         mask[14] |= 0xe0;
8557       *maskp = mask;
8558       return 1;
8559     }
8560   if (tag1 | dot1q)
8561     {
8562       if (tag1)
8563         {
8564           mask[15] = 0xff;
8565           mask[14] = 0x0f;
8566         }
8567       if (cos1)
8568         mask[14] |= 0xe0;
8569       if (proto)
8570         mask[16] = mask[17] = 0xff;
8571
8572       *maskp = mask;
8573       return 1;
8574     }
8575   if (cos2)
8576     mask[18] |= 0xe0;
8577   if (cos1)
8578     mask[14] |= 0xe0;
8579   if (proto)
8580     mask[12] = mask[13] = 0xff;
8581
8582   *maskp = mask;
8583   return 1;
8584 }
8585
8586 uword
8587 unformat_classify_mask (unformat_input_t * input, va_list * args)
8588 {
8589   u8 **maskp = va_arg (*args, u8 **);
8590   u32 *skipp = va_arg (*args, u32 *);
8591   u32 *matchp = va_arg (*args, u32 *);
8592   u32 match;
8593   u8 *mask = 0;
8594   u8 *l2 = 0;
8595   u8 *l3 = 0;
8596   u8 *l4 = 0;
8597   int i;
8598
8599   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8600     {
8601       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8602         ;
8603       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8604         ;
8605       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8606         ;
8607       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8608         ;
8609       else
8610         break;
8611     }
8612
8613   if (l4 && !l3)
8614     {
8615       vec_free (mask);
8616       vec_free (l2);
8617       vec_free (l4);
8618       return 0;
8619     }
8620
8621   if (mask || l2 || l3 || l4)
8622     {
8623       if (l2 || l3 || l4)
8624         {
8625           /* "With a free Ethernet header in every package" */
8626           if (l2 == 0)
8627             vec_validate (l2, 13);
8628           mask = l2;
8629           if (vec_len (l3))
8630             {
8631               vec_append (mask, l3);
8632               vec_free (l3);
8633             }
8634           if (vec_len (l4))
8635             {
8636               vec_append (mask, l4);
8637               vec_free (l4);
8638             }
8639         }
8640
8641       /* Scan forward looking for the first significant mask octet */
8642       for (i = 0; i < vec_len (mask); i++)
8643         if (mask[i])
8644           break;
8645
8646       /* compute (skip, match) params */
8647       *skipp = i / sizeof (u32x4);
8648       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8649
8650       /* Pad mask to an even multiple of the vector size */
8651       while (vec_len (mask) % sizeof (u32x4))
8652         vec_add1 (mask, 0);
8653
8654       match = vec_len (mask) / sizeof (u32x4);
8655
8656       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8657         {
8658           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8659           if (*tmp || *(tmp + 1))
8660             break;
8661           match--;
8662         }
8663       if (match == 0)
8664         clib_warning ("BUG: match 0");
8665
8666       _vec_len (mask) = match * sizeof (u32x4);
8667
8668       *matchp = match;
8669       *maskp = mask;
8670
8671       return 1;
8672     }
8673
8674   return 0;
8675 }
8676
8677 #define foreach_l2_next                         \
8678 _(drop, DROP)                                   \
8679 _(ethernet, ETHERNET_INPUT)                     \
8680 _(ip4, IP4_INPUT)                               \
8681 _(ip6, IP6_INPUT)
8682
8683 uword
8684 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8685 {
8686   u32 *miss_next_indexp = va_arg (*args, u32 *);
8687   u32 next_index = 0;
8688   u32 tmp;
8689
8690 #define _(n,N) \
8691   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8692   foreach_l2_next;
8693 #undef _
8694
8695   if (unformat (input, "%d", &tmp))
8696     {
8697       next_index = tmp;
8698       goto out;
8699     }
8700
8701   return 0;
8702
8703 out:
8704   *miss_next_indexp = next_index;
8705   return 1;
8706 }
8707
8708 #define foreach_ip_next                         \
8709 _(drop, DROP)                                   \
8710 _(local, LOCAL)                                 \
8711 _(rewrite, REWRITE)
8712
8713 uword
8714 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8715 {
8716   u32 *miss_next_indexp = va_arg (*args, u32 *);
8717   u32 next_index = 0;
8718   u32 tmp;
8719
8720 #define _(n,N) \
8721   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8722   foreach_ip_next;
8723 #undef _
8724
8725   if (unformat (input, "%d", &tmp))
8726     {
8727       next_index = tmp;
8728       goto out;
8729     }
8730
8731   return 0;
8732
8733 out:
8734   *miss_next_indexp = next_index;
8735   return 1;
8736 }
8737
8738 #define foreach_acl_next                        \
8739 _(deny, DENY)
8740
8741 uword
8742 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8743 {
8744   u32 *miss_next_indexp = va_arg (*args, u32 *);
8745   u32 next_index = 0;
8746   u32 tmp;
8747
8748 #define _(n,N) \
8749   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8750   foreach_acl_next;
8751 #undef _
8752
8753   if (unformat (input, "permit"))
8754     {
8755       next_index = ~0;
8756       goto out;
8757     }
8758   else if (unformat (input, "%d", &tmp))
8759     {
8760       next_index = tmp;
8761       goto out;
8762     }
8763
8764   return 0;
8765
8766 out:
8767   *miss_next_indexp = next_index;
8768   return 1;
8769 }
8770
8771 uword
8772 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8773 {
8774   u32 *r = va_arg (*args, u32 *);
8775
8776   if (unformat (input, "conform-color"))
8777     *r = POLICE_CONFORM;
8778   else if (unformat (input, "exceed-color"))
8779     *r = POLICE_EXCEED;
8780   else
8781     return 0;
8782
8783   return 1;
8784 }
8785
8786 static int
8787 api_classify_add_del_table (vat_main_t * vam)
8788 {
8789   unformat_input_t *i = vam->input;
8790   vl_api_classify_add_del_table_t *mp;
8791
8792   u32 nbuckets = 2;
8793   u32 skip = ~0;
8794   u32 match = ~0;
8795   int is_add = 1;
8796   u32 table_index = ~0;
8797   u32 next_table_index = ~0;
8798   u32 miss_next_index = ~0;
8799   u32 memory_size = 32 << 20;
8800   u8 *mask = 0;
8801   f64 timeout;
8802   u32 current_data_flag = 0;
8803   int current_data_offset = 0;
8804
8805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8806     {
8807       if (unformat (i, "del"))
8808         is_add = 0;
8809       else if (unformat (i, "buckets %d", &nbuckets))
8810         ;
8811       else if (unformat (i, "memory_size %d", &memory_size))
8812         ;
8813       else if (unformat (i, "skip %d", &skip))
8814         ;
8815       else if (unformat (i, "match %d", &match))
8816         ;
8817       else if (unformat (i, "table %d", &table_index))
8818         ;
8819       else if (unformat (i, "mask %U", unformat_classify_mask,
8820                          &mask, &skip, &match))
8821         ;
8822       else if (unformat (i, "next-table %d", &next_table_index))
8823         ;
8824       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8825                          &miss_next_index))
8826         ;
8827       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8828                          &miss_next_index))
8829         ;
8830       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8831                          &miss_next_index))
8832         ;
8833       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8834         ;
8835       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8836         ;
8837       else
8838         break;
8839     }
8840
8841   if (is_add && mask == 0)
8842     {
8843       errmsg ("Mask required\n");
8844       return -99;
8845     }
8846
8847   if (is_add && skip == ~0)
8848     {
8849       errmsg ("skip count required\n");
8850       return -99;
8851     }
8852
8853   if (is_add && match == ~0)
8854     {
8855       errmsg ("match count required\n");
8856       return -99;
8857     }
8858
8859   if (!is_add && table_index == ~0)
8860     {
8861       errmsg ("table index required for delete\n");
8862       return -99;
8863     }
8864
8865   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8866
8867   mp->is_add = is_add;
8868   mp->table_index = ntohl (table_index);
8869   mp->nbuckets = ntohl (nbuckets);
8870   mp->memory_size = ntohl (memory_size);
8871   mp->skip_n_vectors = ntohl (skip);
8872   mp->match_n_vectors = ntohl (match);
8873   mp->next_table_index = ntohl (next_table_index);
8874   mp->miss_next_index = ntohl (miss_next_index);
8875   mp->current_data_flag = ntohl (current_data_flag);
8876   mp->current_data_offset = ntohl (current_data_offset);
8877   clib_memcpy (mp->mask, mask, vec_len (mask));
8878
8879   vec_free (mask);
8880
8881   S;
8882   W;
8883   /* NOTREACHED */
8884 }
8885
8886 uword
8887 unformat_l4_match (unformat_input_t * input, va_list * args)
8888 {
8889   u8 **matchp = va_arg (*args, u8 **);
8890
8891   u8 *proto_header = 0;
8892   int src_port = 0;
8893   int dst_port = 0;
8894
8895   tcpudp_header_t h;
8896
8897   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8898     {
8899       if (unformat (input, "src_port %d", &src_port))
8900         ;
8901       else if (unformat (input, "dst_port %d", &dst_port))
8902         ;
8903       else
8904         return 0;
8905     }
8906
8907   h.src_port = clib_host_to_net_u16 (src_port);
8908   h.dst_port = clib_host_to_net_u16 (dst_port);
8909   vec_validate (proto_header, sizeof (h) - 1);
8910   memcpy (proto_header, &h, sizeof (h));
8911
8912   *matchp = proto_header;
8913
8914   return 1;
8915 }
8916
8917 uword
8918 unformat_ip4_match (unformat_input_t * input, va_list * args)
8919 {
8920   u8 **matchp = va_arg (*args, u8 **);
8921   u8 *match = 0;
8922   ip4_header_t *ip;
8923   int version = 0;
8924   u32 version_val;
8925   int hdr_length = 0;
8926   u32 hdr_length_val;
8927   int src = 0, dst = 0;
8928   ip4_address_t src_val, dst_val;
8929   int proto = 0;
8930   u32 proto_val;
8931   int tos = 0;
8932   u32 tos_val;
8933   int length = 0;
8934   u32 length_val;
8935   int fragment_id = 0;
8936   u32 fragment_id_val;
8937   int ttl = 0;
8938   int ttl_val;
8939   int checksum = 0;
8940   u32 checksum_val;
8941
8942   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8943     {
8944       if (unformat (input, "version %d", &version_val))
8945         version = 1;
8946       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8947         hdr_length = 1;
8948       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8949         src = 1;
8950       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8951         dst = 1;
8952       else if (unformat (input, "proto %d", &proto_val))
8953         proto = 1;
8954       else if (unformat (input, "tos %d", &tos_val))
8955         tos = 1;
8956       else if (unformat (input, "length %d", &length_val))
8957         length = 1;
8958       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8959         fragment_id = 1;
8960       else if (unformat (input, "ttl %d", &ttl_val))
8961         ttl = 1;
8962       else if (unformat (input, "checksum %d", &checksum_val))
8963         checksum = 1;
8964       else
8965         break;
8966     }
8967
8968   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8969       + ttl + checksum == 0)
8970     return 0;
8971
8972   /*
8973    * Aligned because we use the real comparison functions
8974    */
8975   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8976
8977   ip = (ip4_header_t *) match;
8978
8979   /* These are realistically matched in practice */
8980   if (src)
8981     ip->src_address.as_u32 = src_val.as_u32;
8982
8983   if (dst)
8984     ip->dst_address.as_u32 = dst_val.as_u32;
8985
8986   if (proto)
8987     ip->protocol = proto_val;
8988
8989
8990   /* These are not, but they're included for completeness */
8991   if (version)
8992     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8993
8994   if (hdr_length)
8995     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8996
8997   if (tos)
8998     ip->tos = tos_val;
8999
9000   if (length)
9001     ip->length = clib_host_to_net_u16 (length_val);
9002
9003   if (ttl)
9004     ip->ttl = ttl_val;
9005
9006   if (checksum)
9007     ip->checksum = clib_host_to_net_u16 (checksum_val);
9008
9009   *matchp = match;
9010   return 1;
9011 }
9012
9013 uword
9014 unformat_ip6_match (unformat_input_t * input, va_list * args)
9015 {
9016   u8 **matchp = va_arg (*args, u8 **);
9017   u8 *match = 0;
9018   ip6_header_t *ip;
9019   int version = 0;
9020   u32 version_val;
9021   u8 traffic_class = 0;
9022   u32 traffic_class_val = 0;
9023   u8 flow_label = 0;
9024   u8 flow_label_val;
9025   int src = 0, dst = 0;
9026   ip6_address_t src_val, dst_val;
9027   int proto = 0;
9028   u32 proto_val;
9029   int payload_length = 0;
9030   u32 payload_length_val;
9031   int hop_limit = 0;
9032   int hop_limit_val;
9033   u32 ip_version_traffic_class_and_flow_label;
9034
9035   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9036     {
9037       if (unformat (input, "version %d", &version_val))
9038         version = 1;
9039       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9040         traffic_class = 1;
9041       else if (unformat (input, "flow_label %d", &flow_label_val))
9042         flow_label = 1;
9043       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9044         src = 1;
9045       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9046         dst = 1;
9047       else if (unformat (input, "proto %d", &proto_val))
9048         proto = 1;
9049       else if (unformat (input, "payload_length %d", &payload_length_val))
9050         payload_length = 1;
9051       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9052         hop_limit = 1;
9053       else
9054         break;
9055     }
9056
9057   if (version + traffic_class + flow_label + src + dst + proto +
9058       payload_length + hop_limit == 0)
9059     return 0;
9060
9061   /*
9062    * Aligned because we use the real comparison functions
9063    */
9064   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9065
9066   ip = (ip6_header_t *) match;
9067
9068   if (src)
9069     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9070
9071   if (dst)
9072     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9073
9074   if (proto)
9075     ip->protocol = proto_val;
9076
9077   ip_version_traffic_class_and_flow_label = 0;
9078
9079   if (version)
9080     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9081
9082   if (traffic_class)
9083     ip_version_traffic_class_and_flow_label |=
9084       (traffic_class_val & 0xFF) << 20;
9085
9086   if (flow_label)
9087     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9088
9089   ip->ip_version_traffic_class_and_flow_label =
9090     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9091
9092   if (payload_length)
9093     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9094
9095   if (hop_limit)
9096     ip->hop_limit = hop_limit_val;
9097
9098   *matchp = match;
9099   return 1;
9100 }
9101
9102 uword
9103 unformat_l3_match (unformat_input_t * input, va_list * args)
9104 {
9105   u8 **matchp = va_arg (*args, u8 **);
9106
9107   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9108     {
9109       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9110         return 1;
9111       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9112         return 1;
9113       else
9114         break;
9115     }
9116   return 0;
9117 }
9118
9119 uword
9120 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9121 {
9122   u8 *tagp = va_arg (*args, u8 *);
9123   u32 tag;
9124
9125   if (unformat (input, "%d", &tag))
9126     {
9127       tagp[0] = (tag >> 8) & 0x0F;
9128       tagp[1] = tag & 0xFF;
9129       return 1;
9130     }
9131
9132   return 0;
9133 }
9134
9135 uword
9136 unformat_l2_match (unformat_input_t * input, va_list * args)
9137 {
9138   u8 **matchp = va_arg (*args, u8 **);
9139   u8 *match = 0;
9140   u8 src = 0;
9141   u8 src_val[6];
9142   u8 dst = 0;
9143   u8 dst_val[6];
9144   u8 proto = 0;
9145   u16 proto_val;
9146   u8 tag1 = 0;
9147   u8 tag1_val[2];
9148   u8 tag2 = 0;
9149   u8 tag2_val[2];
9150   int len = 14;
9151   u8 ignore_tag1 = 0;
9152   u8 ignore_tag2 = 0;
9153   u8 cos1 = 0;
9154   u8 cos2 = 0;
9155   u32 cos1_val = 0;
9156   u32 cos2_val = 0;
9157
9158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9159     {
9160       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9161         src = 1;
9162       else
9163         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9164         dst = 1;
9165       else if (unformat (input, "proto %U",
9166                          unformat_ethernet_type_host_byte_order, &proto_val))
9167         proto = 1;
9168       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9169         tag1 = 1;
9170       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9171         tag2 = 1;
9172       else if (unformat (input, "ignore-tag1"))
9173         ignore_tag1 = 1;
9174       else if (unformat (input, "ignore-tag2"))
9175         ignore_tag2 = 1;
9176       else if (unformat (input, "cos1 %d", &cos1_val))
9177         cos1 = 1;
9178       else if (unformat (input, "cos2 %d", &cos2_val))
9179         cos2 = 1;
9180       else
9181         break;
9182     }
9183   if ((src + dst + proto + tag1 + tag2 +
9184        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9185     return 0;
9186
9187   if (tag1 || ignore_tag1 || cos1)
9188     len = 18;
9189   if (tag2 || ignore_tag2 || cos2)
9190     len = 22;
9191
9192   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9193
9194   if (dst)
9195     clib_memcpy (match, dst_val, 6);
9196
9197   if (src)
9198     clib_memcpy (match + 6, src_val, 6);
9199
9200   if (tag2)
9201     {
9202       /* inner vlan tag */
9203       match[19] = tag2_val[1];
9204       match[18] = tag2_val[0];
9205       if (cos2)
9206         match[18] |= (cos2_val & 0x7) << 5;
9207       if (proto)
9208         {
9209           match[21] = proto_val & 0xff;
9210           match[20] = proto_val >> 8;
9211         }
9212       if (tag1)
9213         {
9214           match[15] = tag1_val[1];
9215           match[14] = tag1_val[0];
9216         }
9217       if (cos1)
9218         match[14] |= (cos1_val & 0x7) << 5;
9219       *matchp = match;
9220       return 1;
9221     }
9222   if (tag1)
9223     {
9224       match[15] = tag1_val[1];
9225       match[14] = tag1_val[0];
9226       if (proto)
9227         {
9228           match[17] = proto_val & 0xff;
9229           match[16] = proto_val >> 8;
9230         }
9231       if (cos1)
9232         match[14] |= (cos1_val & 0x7) << 5;
9233
9234       *matchp = match;
9235       return 1;
9236     }
9237   if (cos2)
9238     match[18] |= (cos2_val & 0x7) << 5;
9239   if (cos1)
9240     match[14] |= (cos1_val & 0x7) << 5;
9241   if (proto)
9242     {
9243       match[13] = proto_val & 0xff;
9244       match[12] = proto_val >> 8;
9245     }
9246
9247   *matchp = match;
9248   return 1;
9249 }
9250
9251
9252 uword
9253 unformat_classify_match (unformat_input_t * input, va_list * args)
9254 {
9255   u8 **matchp = va_arg (*args, u8 **);
9256   u32 skip_n_vectors = va_arg (*args, u32);
9257   u32 match_n_vectors = va_arg (*args, u32);
9258
9259   u8 *match = 0;
9260   u8 *l2 = 0;
9261   u8 *l3 = 0;
9262   u8 *l4 = 0;
9263
9264   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9265     {
9266       if (unformat (input, "hex %U", unformat_hex_string, &match))
9267         ;
9268       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9269         ;
9270       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9271         ;
9272       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9273         ;
9274       else
9275         break;
9276     }
9277
9278   if (l4 && !l3)
9279     {
9280       vec_free (match);
9281       vec_free (l2);
9282       vec_free (l4);
9283       return 0;
9284     }
9285
9286   if (match || l2 || l3 || l4)
9287     {
9288       if (l2 || l3 || l4)
9289         {
9290           /* "Win a free Ethernet header in every packet" */
9291           if (l2 == 0)
9292             vec_validate_aligned (l2, 13, sizeof (u32x4));
9293           match = l2;
9294           if (vec_len (l3))
9295             {
9296               vec_append_aligned (match, l3, sizeof (u32x4));
9297               vec_free (l3);
9298             }
9299           if (vec_len (l4))
9300             {
9301               vec_append_aligned (match, l4, sizeof (u32x4));
9302               vec_free (l4);
9303             }
9304         }
9305
9306       /* Make sure the vector is big enough even if key is all 0's */
9307       vec_validate_aligned
9308         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9309          sizeof (u32x4));
9310
9311       /* Set size, include skipped vectors */
9312       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9313
9314       *matchp = match;
9315
9316       return 1;
9317     }
9318
9319   return 0;
9320 }
9321
9322 static int
9323 api_classify_add_del_session (vat_main_t * vam)
9324 {
9325   unformat_input_t *i = vam->input;
9326   vl_api_classify_add_del_session_t *mp;
9327   int is_add = 1;
9328   u32 table_index = ~0;
9329   u32 hit_next_index = ~0;
9330   u32 opaque_index = ~0;
9331   u8 *match = 0;
9332   i32 advance = 0;
9333   f64 timeout;
9334   u32 skip_n_vectors = 0;
9335   u32 match_n_vectors = 0;
9336   u32 action = 0;
9337   u32 metadata = 0;
9338
9339   /*
9340    * Warning: you have to supply skip_n and match_n
9341    * because the API client cant simply look at the classify
9342    * table object.
9343    */
9344
9345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9346     {
9347       if (unformat (i, "del"))
9348         is_add = 0;
9349       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9350                          &hit_next_index))
9351         ;
9352       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9353                          &hit_next_index))
9354         ;
9355       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9356                          &hit_next_index))
9357         ;
9358       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9359         ;
9360       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9361         ;
9362       else if (unformat (i, "opaque-index %d", &opaque_index))
9363         ;
9364       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9365         ;
9366       else if (unformat (i, "match_n %d", &match_n_vectors))
9367         ;
9368       else if (unformat (i, "match %U", unformat_classify_match,
9369                          &match, skip_n_vectors, match_n_vectors))
9370         ;
9371       else if (unformat (i, "advance %d", &advance))
9372         ;
9373       else if (unformat (i, "table-index %d", &table_index))
9374         ;
9375       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9376         action = 1;
9377       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9378         action = 2;
9379       else if (unformat (i, "action %d", &action))
9380         ;
9381       else if (unformat (i, "metadata %d", &metadata))
9382         ;
9383       else
9384         break;
9385     }
9386
9387   if (table_index == ~0)
9388     {
9389       errmsg ("Table index required\n");
9390       return -99;
9391     }
9392
9393   if (is_add && match == 0)
9394     {
9395       errmsg ("Match value required\n");
9396       return -99;
9397     }
9398
9399   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9400
9401   mp->is_add = is_add;
9402   mp->table_index = ntohl (table_index);
9403   mp->hit_next_index = ntohl (hit_next_index);
9404   mp->opaque_index = ntohl (opaque_index);
9405   mp->advance = ntohl (advance);
9406   mp->action = action;
9407   mp->metadata = ntohl (metadata);
9408   clib_memcpy (mp->match, match, vec_len (match));
9409   vec_free (match);
9410
9411   S;
9412   W;
9413   /* NOTREACHED */
9414 }
9415
9416 static int
9417 api_classify_set_interface_ip_table (vat_main_t * vam)
9418 {
9419   unformat_input_t *i = vam->input;
9420   vl_api_classify_set_interface_ip_table_t *mp;
9421   f64 timeout;
9422   u32 sw_if_index;
9423   int sw_if_index_set;
9424   u32 table_index = ~0;
9425   u8 is_ipv6 = 0;
9426
9427   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9428     {
9429       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9430         sw_if_index_set = 1;
9431       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9432         sw_if_index_set = 1;
9433       else if (unformat (i, "table %d", &table_index))
9434         ;
9435       else
9436         {
9437           clib_warning ("parse error '%U'", format_unformat_error, i);
9438           return -99;
9439         }
9440     }
9441
9442   if (sw_if_index_set == 0)
9443     {
9444       errmsg ("missing interface name or sw_if_index\n");
9445       return -99;
9446     }
9447
9448
9449   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9450
9451   mp->sw_if_index = ntohl (sw_if_index);
9452   mp->table_index = ntohl (table_index);
9453   mp->is_ipv6 = is_ipv6;
9454
9455   S;
9456   W;
9457   /* NOTREACHED */
9458   return 0;
9459 }
9460
9461 static int
9462 api_classify_set_interface_l2_tables (vat_main_t * vam)
9463 {
9464   unformat_input_t *i = vam->input;
9465   vl_api_classify_set_interface_l2_tables_t *mp;
9466   f64 timeout;
9467   u32 sw_if_index;
9468   int sw_if_index_set;
9469   u32 ip4_table_index = ~0;
9470   u32 ip6_table_index = ~0;
9471   u32 other_table_index = ~0;
9472   u32 is_input = 1;
9473
9474   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9475     {
9476       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9477         sw_if_index_set = 1;
9478       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9479         sw_if_index_set = 1;
9480       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9481         ;
9482       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9483         ;
9484       else if (unformat (i, "other-table %d", &other_table_index))
9485         ;
9486       else if (unformat (i, "is-input %d", &is_input))
9487         ;
9488       else
9489         {
9490           clib_warning ("parse error '%U'", format_unformat_error, i);
9491           return -99;
9492         }
9493     }
9494
9495   if (sw_if_index_set == 0)
9496     {
9497       errmsg ("missing interface name or sw_if_index\n");
9498       return -99;
9499     }
9500
9501
9502   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9503
9504   mp->sw_if_index = ntohl (sw_if_index);
9505   mp->ip4_table_index = ntohl (ip4_table_index);
9506   mp->ip6_table_index = ntohl (ip6_table_index);
9507   mp->other_table_index = ntohl (other_table_index);
9508   mp->is_input = (u8) is_input;
9509
9510   S;
9511   W;
9512   /* NOTREACHED */
9513   return 0;
9514 }
9515
9516 static int
9517 api_set_ipfix_exporter (vat_main_t * vam)
9518 {
9519   unformat_input_t *i = vam->input;
9520   vl_api_set_ipfix_exporter_t *mp;
9521   ip4_address_t collector_address;
9522   u8 collector_address_set = 0;
9523   u32 collector_port = ~0;
9524   ip4_address_t src_address;
9525   u8 src_address_set = 0;
9526   u32 vrf_id = ~0;
9527   u32 path_mtu = ~0;
9528   u32 template_interval = ~0;
9529   u8 udp_checksum = 0;
9530   f64 timeout;
9531
9532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9533     {
9534       if (unformat (i, "collector_address %U", unformat_ip4_address,
9535                     &collector_address))
9536         collector_address_set = 1;
9537       else if (unformat (i, "collector_port %d", &collector_port))
9538         ;
9539       else if (unformat (i, "src_address %U", unformat_ip4_address,
9540                          &src_address))
9541         src_address_set = 1;
9542       else if (unformat (i, "vrf_id %d", &vrf_id))
9543         ;
9544       else if (unformat (i, "path_mtu %d", &path_mtu))
9545         ;
9546       else if (unformat (i, "template_interval %d", &template_interval))
9547         ;
9548       else if (unformat (i, "udp_checksum"))
9549         udp_checksum = 1;
9550       else
9551         break;
9552     }
9553
9554   if (collector_address_set == 0)
9555     {
9556       errmsg ("collector_address required\n");
9557       return -99;
9558     }
9559
9560   if (src_address_set == 0)
9561     {
9562       errmsg ("src_address required\n");
9563       return -99;
9564     }
9565
9566   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9567
9568   memcpy (mp->collector_address, collector_address.data,
9569           sizeof (collector_address.data));
9570   mp->collector_port = htons ((u16) collector_port);
9571   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9572   mp->vrf_id = htonl (vrf_id);
9573   mp->path_mtu = htonl (path_mtu);
9574   mp->template_interval = htonl (template_interval);
9575   mp->udp_checksum = udp_checksum;
9576
9577   S;
9578   W;
9579   /* NOTREACHED */
9580 }
9581
9582 static int
9583 api_set_ipfix_classify_stream (vat_main_t * vam)
9584 {
9585   unformat_input_t *i = vam->input;
9586   vl_api_set_ipfix_classify_stream_t *mp;
9587   u32 domain_id = 0;
9588   u32 src_port = UDP_DST_PORT_ipfix;
9589   f64 timeout;
9590
9591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9592     {
9593       if (unformat (i, "domain %d", &domain_id))
9594         ;
9595       else if (unformat (i, "src_port %d", &src_port))
9596         ;
9597       else
9598         {
9599           errmsg ("unknown input `%U'", format_unformat_error, i);
9600           return -99;
9601         }
9602     }
9603
9604   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9605
9606   mp->domain_id = htonl (domain_id);
9607   mp->src_port = htons ((u16) src_port);
9608
9609   S;
9610   W;
9611   /* NOTREACHED */
9612 }
9613
9614 static int
9615 api_ipfix_classify_table_add_del (vat_main_t * vam)
9616 {
9617   unformat_input_t *i = vam->input;
9618   vl_api_ipfix_classify_table_add_del_t *mp;
9619   int is_add = -1;
9620   u32 classify_table_index = ~0;
9621   u8 ip_version = 0;
9622   u8 transport_protocol = 255;
9623   f64 timeout;
9624
9625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9626     {
9627       if (unformat (i, "add"))
9628         is_add = 1;
9629       else if (unformat (i, "del"))
9630         is_add = 0;
9631       else if (unformat (i, "table %d", &classify_table_index))
9632         ;
9633       else if (unformat (i, "ip4"))
9634         ip_version = 4;
9635       else if (unformat (i, "ip6"))
9636         ip_version = 6;
9637       else if (unformat (i, "tcp"))
9638         transport_protocol = 6;
9639       else if (unformat (i, "udp"))
9640         transport_protocol = 17;
9641       else
9642         {
9643           errmsg ("unknown input `%U'", format_unformat_error, i);
9644           return -99;
9645         }
9646     }
9647
9648   if (is_add == -1)
9649     {
9650       errmsg ("expecting: add|del");
9651       return -99;
9652     }
9653   if (classify_table_index == ~0)
9654     {
9655       errmsg ("classifier table not specified");
9656       return -99;
9657     }
9658   if (ip_version == 0)
9659     {
9660       errmsg ("IP version not specified");
9661       return -99;
9662     }
9663
9664   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9665
9666   mp->is_add = is_add;
9667   mp->table_id = htonl (classify_table_index);
9668   mp->ip_version = ip_version;
9669   mp->transport_protocol = transport_protocol;
9670
9671   S;
9672   W;
9673   /* NOTREACHED */
9674 }
9675
9676 static int
9677 api_get_node_index (vat_main_t * vam)
9678 {
9679   unformat_input_t *i = vam->input;
9680   vl_api_get_node_index_t *mp;
9681   f64 timeout;
9682   u8 *name = 0;
9683
9684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9685     {
9686       if (unformat (i, "node %s", &name))
9687         ;
9688       else
9689         break;
9690     }
9691   if (name == 0)
9692     {
9693       errmsg ("node name required\n");
9694       return -99;
9695     }
9696   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9697     {
9698       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9699       return -99;
9700     }
9701
9702   M (GET_NODE_INDEX, get_node_index);
9703   clib_memcpy (mp->node_name, name, vec_len (name));
9704   vec_free (name);
9705
9706   S;
9707   W;
9708   /* NOTREACHED */
9709   return 0;
9710 }
9711
9712 static int
9713 api_get_next_index (vat_main_t * vam)
9714 {
9715   unformat_input_t *i = vam->input;
9716   vl_api_get_next_index_t *mp;
9717   f64 timeout;
9718   u8 *node_name = 0, *next_node_name = 0;
9719
9720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9721     {
9722       if (unformat (i, "node-name %s", &node_name))
9723         ;
9724       else if (unformat (i, "next-node-name %s", &next_node_name))
9725         break;
9726     }
9727
9728   if (node_name == 0)
9729     {
9730       errmsg ("node name required\n");
9731       return -99;
9732     }
9733   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9734     {
9735       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9736       return -99;
9737     }
9738
9739   if (next_node_name == 0)
9740     {
9741       errmsg ("next node name required\n");
9742       return -99;
9743     }
9744   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9745     {
9746       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9747       return -99;
9748     }
9749
9750   M (GET_NEXT_INDEX, get_next_index);
9751   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9752   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9753   vec_free (node_name);
9754   vec_free (next_node_name);
9755
9756   S;
9757   W;
9758   /* NOTREACHED */
9759   return 0;
9760 }
9761
9762 static int
9763 api_add_node_next (vat_main_t * vam)
9764 {
9765   unformat_input_t *i = vam->input;
9766   vl_api_add_node_next_t *mp;
9767   f64 timeout;
9768   u8 *name = 0;
9769   u8 *next = 0;
9770
9771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9772     {
9773       if (unformat (i, "node %s", &name))
9774         ;
9775       else if (unformat (i, "next %s", &next))
9776         ;
9777       else
9778         break;
9779     }
9780   if (name == 0)
9781     {
9782       errmsg ("node name required\n");
9783       return -99;
9784     }
9785   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9786     {
9787       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9788       return -99;
9789     }
9790   if (next == 0)
9791     {
9792       errmsg ("next node required\n");
9793       return -99;
9794     }
9795   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9796     {
9797       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9798       return -99;
9799     }
9800
9801   M (ADD_NODE_NEXT, add_node_next);
9802   clib_memcpy (mp->node_name, name, vec_len (name));
9803   clib_memcpy (mp->next_name, next, vec_len (next));
9804   vec_free (name);
9805   vec_free (next);
9806
9807   S;
9808   W;
9809   /* NOTREACHED */
9810   return 0;
9811 }
9812
9813 static int
9814 api_l2tpv3_create_tunnel (vat_main_t * vam)
9815 {
9816   unformat_input_t *i = vam->input;
9817   ip6_address_t client_address, our_address;
9818   int client_address_set = 0;
9819   int our_address_set = 0;
9820   u32 local_session_id = 0;
9821   u32 remote_session_id = 0;
9822   u64 local_cookie = 0;
9823   u64 remote_cookie = 0;
9824   u8 l2_sublayer_present = 0;
9825   vl_api_l2tpv3_create_tunnel_t *mp;
9826   f64 timeout;
9827
9828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9829     {
9830       if (unformat (i, "client_address %U", unformat_ip6_address,
9831                     &client_address))
9832         client_address_set = 1;
9833       else if (unformat (i, "our_address %U", unformat_ip6_address,
9834                          &our_address))
9835         our_address_set = 1;
9836       else if (unformat (i, "local_session_id %d", &local_session_id))
9837         ;
9838       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9839         ;
9840       else if (unformat (i, "local_cookie %lld", &local_cookie))
9841         ;
9842       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9843         ;
9844       else if (unformat (i, "l2-sublayer-present"))
9845         l2_sublayer_present = 1;
9846       else
9847         break;
9848     }
9849
9850   if (client_address_set == 0)
9851     {
9852       errmsg ("client_address required\n");
9853       return -99;
9854     }
9855
9856   if (our_address_set == 0)
9857     {
9858       errmsg ("our_address required\n");
9859       return -99;
9860     }
9861
9862   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9863
9864   clib_memcpy (mp->client_address, client_address.as_u8,
9865                sizeof (mp->client_address));
9866
9867   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9868
9869   mp->local_session_id = ntohl (local_session_id);
9870   mp->remote_session_id = ntohl (remote_session_id);
9871   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9872   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9873   mp->l2_sublayer_present = l2_sublayer_present;
9874   mp->is_ipv6 = 1;
9875
9876   S;
9877   W;
9878   /* NOTREACHED */
9879   return 0;
9880 }
9881
9882 static int
9883 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9884 {
9885   unformat_input_t *i = vam->input;
9886   u32 sw_if_index;
9887   u8 sw_if_index_set = 0;
9888   u64 new_local_cookie = 0;
9889   u64 new_remote_cookie = 0;
9890   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9891   f64 timeout;
9892
9893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9894     {
9895       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9896         sw_if_index_set = 1;
9897       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9898         sw_if_index_set = 1;
9899       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9900         ;
9901       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9902         ;
9903       else
9904         break;
9905     }
9906
9907   if (sw_if_index_set == 0)
9908     {
9909       errmsg ("missing interface name or sw_if_index\n");
9910       return -99;
9911     }
9912
9913   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9914
9915   mp->sw_if_index = ntohl (sw_if_index);
9916   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9917   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9918
9919   S;
9920   W;
9921   /* NOTREACHED */
9922   return 0;
9923 }
9924
9925 static int
9926 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9927 {
9928   unformat_input_t *i = vam->input;
9929   vl_api_l2tpv3_interface_enable_disable_t *mp;
9930   f64 timeout;
9931   u32 sw_if_index;
9932   u8 sw_if_index_set = 0;
9933   u8 enable_disable = 1;
9934
9935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9936     {
9937       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9938         sw_if_index_set = 1;
9939       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9940         sw_if_index_set = 1;
9941       else if (unformat (i, "enable"))
9942         enable_disable = 1;
9943       else if (unformat (i, "disable"))
9944         enable_disable = 0;
9945       else
9946         break;
9947     }
9948
9949   if (sw_if_index_set == 0)
9950     {
9951       errmsg ("missing interface name or sw_if_index\n");
9952       return -99;
9953     }
9954
9955   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9956
9957   mp->sw_if_index = ntohl (sw_if_index);
9958   mp->enable_disable = enable_disable;
9959
9960   S;
9961   W;
9962   /* NOTREACHED */
9963   return 0;
9964 }
9965
9966 static int
9967 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9968 {
9969   unformat_input_t *i = vam->input;
9970   vl_api_l2tpv3_set_lookup_key_t *mp;
9971   f64 timeout;
9972   u8 key = ~0;
9973
9974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9975     {
9976       if (unformat (i, "lookup_v6_src"))
9977         key = L2T_LOOKUP_SRC_ADDRESS;
9978       else if (unformat (i, "lookup_v6_dst"))
9979         key = L2T_LOOKUP_DST_ADDRESS;
9980       else if (unformat (i, "lookup_session_id"))
9981         key = L2T_LOOKUP_SESSION_ID;
9982       else
9983         break;
9984     }
9985
9986   if (key == (u8) ~ 0)
9987     {
9988       errmsg ("l2tp session lookup key unset\n");
9989       return -99;
9990     }
9991
9992   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9993
9994   mp->key = key;
9995
9996   S;
9997   W;
9998   /* NOTREACHED */
9999   return 0;
10000 }
10001
10002 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10003   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10004 {
10005   vat_main_t *vam = &vat_main;
10006
10007   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
10008            format_ip6_address, mp->our_address,
10009            format_ip6_address, mp->client_address,
10010            clib_net_to_host_u32 (mp->sw_if_index));
10011
10012   fformat (vam->ofp,
10013            "   local cookies %016llx %016llx remote cookie %016llx\n",
10014            clib_net_to_host_u64 (mp->local_cookie[0]),
10015            clib_net_to_host_u64 (mp->local_cookie[1]),
10016            clib_net_to_host_u64 (mp->remote_cookie));
10017
10018   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
10019            clib_net_to_host_u32 (mp->local_session_id),
10020            clib_net_to_host_u32 (mp->remote_session_id));
10021
10022   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
10023            mp->l2_sublayer_present ? "preset" : "absent");
10024
10025 }
10026
10027 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10028   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10029 {
10030   vat_main_t *vam = &vat_main;
10031   vat_json_node_t *node = NULL;
10032   struct in6_addr addr;
10033
10034   if (VAT_JSON_ARRAY != vam->json_tree.type)
10035     {
10036       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10037       vat_json_init_array (&vam->json_tree);
10038     }
10039   node = vat_json_array_add (&vam->json_tree);
10040
10041   vat_json_init_object (node);
10042
10043   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10044   vat_json_object_add_ip6 (node, "our_address", addr);
10045   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10046   vat_json_object_add_ip6 (node, "client_address", addr);
10047
10048   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10049   vat_json_init_array (lc);
10050   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10051   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10052   vat_json_object_add_uint (node, "remote_cookie",
10053                             clib_net_to_host_u64 (mp->remote_cookie));
10054
10055   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10056   vat_json_object_add_uint (node, "local_session_id",
10057                             clib_net_to_host_u32 (mp->local_session_id));
10058   vat_json_object_add_uint (node, "remote_session_id",
10059                             clib_net_to_host_u32 (mp->remote_session_id));
10060   vat_json_object_add_string_copy (node, "l2_sublayer",
10061                                    mp->l2_sublayer_present ? (u8 *) "present"
10062                                    : (u8 *) "absent");
10063 }
10064
10065 static int
10066 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10067 {
10068   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10069   f64 timeout;
10070
10071   /* Get list of l2tpv3-tunnel interfaces */
10072   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10073   S;
10074
10075   /* Use a control ping for synchronization */
10076   {
10077     vl_api_control_ping_t *mp;
10078     M (CONTROL_PING, control_ping);
10079     S;
10080   }
10081   W;
10082 }
10083
10084
10085 static void vl_api_sw_interface_tap_details_t_handler
10086   (vl_api_sw_interface_tap_details_t * mp)
10087 {
10088   vat_main_t *vam = &vat_main;
10089
10090   fformat (vam->ofp, "%-16s %d\n",
10091            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10092 }
10093
10094 static void vl_api_sw_interface_tap_details_t_handler_json
10095   (vl_api_sw_interface_tap_details_t * mp)
10096 {
10097   vat_main_t *vam = &vat_main;
10098   vat_json_node_t *node = NULL;
10099
10100   if (VAT_JSON_ARRAY != vam->json_tree.type)
10101     {
10102       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10103       vat_json_init_array (&vam->json_tree);
10104     }
10105   node = vat_json_array_add (&vam->json_tree);
10106
10107   vat_json_init_object (node);
10108   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10109   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10110 }
10111
10112 static int
10113 api_sw_interface_tap_dump (vat_main_t * vam)
10114 {
10115   vl_api_sw_interface_tap_dump_t *mp;
10116   f64 timeout;
10117
10118   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10119   /* Get list of tap interfaces */
10120   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10121   S;
10122
10123   /* Use a control ping for synchronization */
10124   {
10125     vl_api_control_ping_t *mp;
10126     M (CONTROL_PING, control_ping);
10127     S;
10128   }
10129   W;
10130 }
10131
10132 static uword unformat_vxlan_decap_next
10133   (unformat_input_t * input, va_list * args)
10134 {
10135   u32 *result = va_arg (*args, u32 *);
10136   u32 tmp;
10137
10138   if (unformat (input, "l2"))
10139     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10140   else if (unformat (input, "%d", &tmp))
10141     *result = tmp;
10142   else
10143     return 0;
10144   return 1;
10145 }
10146
10147 static int
10148 api_vxlan_add_del_tunnel (vat_main_t * vam)
10149 {
10150   unformat_input_t *line_input = vam->input;
10151   vl_api_vxlan_add_del_tunnel_t *mp;
10152   f64 timeout;
10153   ip46_address_t src, dst;
10154   u8 is_add = 1;
10155   u8 ipv4_set = 0, ipv6_set = 0;
10156   u8 src_set = 0;
10157   u8 dst_set = 0;
10158   u8 grp_set = 0;
10159   u32 mcast_sw_if_index = ~0;
10160   u32 encap_vrf_id = 0;
10161   u32 decap_next_index = ~0;
10162   u32 vni = 0;
10163
10164   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10165   memset (&src, 0, sizeof src);
10166   memset (&dst, 0, sizeof dst);
10167
10168   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10169     {
10170       if (unformat (line_input, "del"))
10171         is_add = 0;
10172       else
10173         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10174         {
10175           ipv4_set = 1;
10176           src_set = 1;
10177         }
10178       else
10179         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10180         {
10181           ipv4_set = 1;
10182           dst_set = 1;
10183         }
10184       else
10185         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10186         {
10187           ipv6_set = 1;
10188           src_set = 1;
10189         }
10190       else
10191         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10192         {
10193           ipv6_set = 1;
10194           dst_set = 1;
10195         }
10196       else if (unformat (line_input, "group %U %U",
10197                          unformat_ip4_address, &dst.ip4,
10198                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10199         {
10200           grp_set = dst_set = 1;
10201           ipv4_set = 1;
10202         }
10203       else if (unformat (line_input, "group %U",
10204                          unformat_ip4_address, &dst.ip4))
10205         {
10206           grp_set = dst_set = 1;
10207           ipv4_set = 1;
10208         }
10209       else if (unformat (line_input, "group %U %U",
10210                          unformat_ip6_address, &dst.ip6,
10211                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10212         {
10213           grp_set = dst_set = 1;
10214           ipv6_set = 1;
10215         }
10216       else if (unformat (line_input, "group %U",
10217                          unformat_ip6_address, &dst.ip6))
10218         {
10219           grp_set = dst_set = 1;
10220           ipv6_set = 1;
10221         }
10222       else
10223         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10224         ;
10225       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10226         ;
10227       else if (unformat (line_input, "decap-next %U",
10228                          unformat_vxlan_decap_next, &decap_next_index))
10229         ;
10230       else if (unformat (line_input, "vni %d", &vni))
10231         ;
10232       else
10233         {
10234           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10235           return -99;
10236         }
10237     }
10238
10239   if (src_set == 0)
10240     {
10241       errmsg ("tunnel src address not specified\n");
10242       return -99;
10243     }
10244   if (dst_set == 0)
10245     {
10246       errmsg ("tunnel dst address not specified\n");
10247       return -99;
10248     }
10249
10250   if (grp_set && !ip46_address_is_multicast (&dst))
10251     {
10252       errmsg ("tunnel group address not multicast\n");
10253       return -99;
10254     }
10255   if (grp_set && mcast_sw_if_index == ~0)
10256     {
10257       errmsg ("tunnel nonexistent multicast device\n");
10258       return -99;
10259     }
10260
10261
10262   if (ipv4_set && ipv6_set)
10263     {
10264       errmsg ("both IPv4 and IPv6 addresses specified");
10265       return -99;
10266     }
10267
10268   if ((vni == 0) || (vni >> 24))
10269     {
10270       errmsg ("vni not specified or out of range\n");
10271       return -99;
10272     }
10273
10274   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10275
10276   if (ipv6_set)
10277     {
10278       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10279       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10280     }
10281   else
10282     {
10283       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10284       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10285     }
10286   mp->encap_vrf_id = ntohl (encap_vrf_id);
10287   mp->decap_next_index = ntohl (decap_next_index);
10288   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10289   mp->vni = ntohl (vni);
10290   mp->is_add = is_add;
10291   mp->is_ipv6 = ipv6_set;
10292
10293   S;
10294   W;
10295   /* NOTREACHED */
10296   return 0;
10297 }
10298
10299 static void vl_api_vxlan_tunnel_details_t_handler
10300   (vl_api_vxlan_tunnel_details_t * mp)
10301 {
10302   vat_main_t *vam = &vat_main;
10303   ip46_address_t src, dst;
10304
10305   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10306   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10307
10308   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d\n",
10309            ntohl (mp->sw_if_index),
10310            format_ip46_address, &src, IP46_TYPE_ANY,
10311            format_ip46_address, &dst, IP46_TYPE_ANY,
10312            ntohl (mp->encap_vrf_id),
10313            ntohl (mp->decap_next_index), ntohl (mp->vni),
10314            ntohl (mp->mcast_sw_if_index));
10315 }
10316
10317 static void vl_api_vxlan_tunnel_details_t_handler_json
10318   (vl_api_vxlan_tunnel_details_t * mp)
10319 {
10320   vat_main_t *vam = &vat_main;
10321   vat_json_node_t *node = NULL;
10322
10323   if (VAT_JSON_ARRAY != vam->json_tree.type)
10324     {
10325       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10326       vat_json_init_array (&vam->json_tree);
10327     }
10328   node = vat_json_array_add (&vam->json_tree);
10329
10330   vat_json_init_object (node);
10331   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10332   if (mp->is_ipv6)
10333     {
10334       struct in6_addr ip6;
10335
10336       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10337       vat_json_object_add_ip6 (node, "src_address", ip6);
10338       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10339       vat_json_object_add_ip6 (node, "dst_address", ip6);
10340     }
10341   else
10342     {
10343       struct in_addr ip4;
10344
10345       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10346       vat_json_object_add_ip4 (node, "src_address", ip4);
10347       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10348       vat_json_object_add_ip4 (node, "dst_address", ip4);
10349     }
10350   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10351   vat_json_object_add_uint (node, "decap_next_index",
10352                             ntohl (mp->decap_next_index));
10353   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10354   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10355   vat_json_object_add_uint (node, "mcast_sw_if_index",
10356                             ntohl (mp->mcast_sw_if_index));
10357 }
10358
10359 static int
10360 api_vxlan_tunnel_dump (vat_main_t * vam)
10361 {
10362   unformat_input_t *i = vam->input;
10363   vl_api_vxlan_tunnel_dump_t *mp;
10364   f64 timeout;
10365   u32 sw_if_index;
10366   u8 sw_if_index_set = 0;
10367
10368   /* Parse args required to build the message */
10369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10370     {
10371       if (unformat (i, "sw_if_index %d", &sw_if_index))
10372         sw_if_index_set = 1;
10373       else
10374         break;
10375     }
10376
10377   if (sw_if_index_set == 0)
10378     {
10379       sw_if_index = ~0;
10380     }
10381
10382   if (!vam->json_output)
10383     {
10384       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s\n",
10385                "sw_if_index", "src_address", "dst_address",
10386                "encap_vrf_id", "decap_next_index", "vni",
10387                "mcast_sw_if_index");
10388     }
10389
10390   /* Get list of vxlan-tunnel interfaces */
10391   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10392
10393   mp->sw_if_index = htonl (sw_if_index);
10394
10395   S;
10396
10397   /* Use a control ping for synchronization */
10398   {
10399     vl_api_control_ping_t *mp;
10400     M (CONTROL_PING, control_ping);
10401     S;
10402   }
10403   W;
10404 }
10405
10406 static int
10407 api_gre_add_del_tunnel (vat_main_t * vam)
10408 {
10409   unformat_input_t *line_input = vam->input;
10410   vl_api_gre_add_del_tunnel_t *mp;
10411   f64 timeout;
10412   ip4_address_t src4, dst4;
10413   u8 is_add = 1;
10414   u8 teb = 0;
10415   u8 src_set = 0;
10416   u8 dst_set = 0;
10417   u32 outer_fib_id = 0;
10418
10419   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10420     {
10421       if (unformat (line_input, "del"))
10422         is_add = 0;
10423       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10424         src_set = 1;
10425       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10426         dst_set = 1;
10427       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10428         ;
10429       else if (unformat (line_input, "teb"))
10430         teb = 1;
10431       else
10432         {
10433           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10434           return -99;
10435         }
10436     }
10437
10438   if (src_set == 0)
10439     {
10440       errmsg ("tunnel src address not specified\n");
10441       return -99;
10442     }
10443   if (dst_set == 0)
10444     {
10445       errmsg ("tunnel dst address not specified\n");
10446       return -99;
10447     }
10448
10449
10450   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10451
10452   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10453   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10454   mp->outer_fib_id = ntohl (outer_fib_id);
10455   mp->is_add = is_add;
10456   mp->teb = teb;
10457
10458   S;
10459   W;
10460   /* NOTREACHED */
10461   return 0;
10462 }
10463
10464 static void vl_api_gre_tunnel_details_t_handler
10465   (vl_api_gre_tunnel_details_t * mp)
10466 {
10467   vat_main_t *vam = &vat_main;
10468
10469   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10470            ntohl (mp->sw_if_index),
10471            format_ip4_address, &mp->src_address,
10472            format_ip4_address, &mp->dst_address,
10473            mp->teb, ntohl (mp->outer_fib_id));
10474 }
10475
10476 static void vl_api_gre_tunnel_details_t_handler_json
10477   (vl_api_gre_tunnel_details_t * mp)
10478 {
10479   vat_main_t *vam = &vat_main;
10480   vat_json_node_t *node = NULL;
10481   struct in_addr ip4;
10482
10483   if (VAT_JSON_ARRAY != vam->json_tree.type)
10484     {
10485       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10486       vat_json_init_array (&vam->json_tree);
10487     }
10488   node = vat_json_array_add (&vam->json_tree);
10489
10490   vat_json_init_object (node);
10491   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10492   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10493   vat_json_object_add_ip4 (node, "src_address", ip4);
10494   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10495   vat_json_object_add_ip4 (node, "dst_address", ip4);
10496   vat_json_object_add_uint (node, "teb", mp->teb);
10497   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10498 }
10499
10500 static int
10501 api_gre_tunnel_dump (vat_main_t * vam)
10502 {
10503   unformat_input_t *i = vam->input;
10504   vl_api_gre_tunnel_dump_t *mp;
10505   f64 timeout;
10506   u32 sw_if_index;
10507   u8 sw_if_index_set = 0;
10508
10509   /* Parse args required to build the message */
10510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10511     {
10512       if (unformat (i, "sw_if_index %d", &sw_if_index))
10513         sw_if_index_set = 1;
10514       else
10515         break;
10516     }
10517
10518   if (sw_if_index_set == 0)
10519     {
10520       sw_if_index = ~0;
10521     }
10522
10523   if (!vam->json_output)
10524     {
10525       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10526                "sw_if_index", "src_address", "dst_address", "teb",
10527                "outer_fib_id");
10528     }
10529
10530   /* Get list of gre-tunnel interfaces */
10531   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10532
10533   mp->sw_if_index = htonl (sw_if_index);
10534
10535   S;
10536
10537   /* Use a control ping for synchronization */
10538   {
10539     vl_api_control_ping_t *mp;
10540     M (CONTROL_PING, control_ping);
10541     S;
10542   }
10543   W;
10544 }
10545
10546 static int
10547 api_l2_fib_clear_table (vat_main_t * vam)
10548 {
10549 //  unformat_input_t * i = vam->input;
10550   vl_api_l2_fib_clear_table_t *mp;
10551   f64 timeout;
10552
10553   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10554
10555   S;
10556   W;
10557   /* NOTREACHED */
10558   return 0;
10559 }
10560
10561 static int
10562 api_l2_interface_efp_filter (vat_main_t * vam)
10563 {
10564   unformat_input_t *i = vam->input;
10565   vl_api_l2_interface_efp_filter_t *mp;
10566   f64 timeout;
10567   u32 sw_if_index;
10568   u8 enable = 1;
10569   u8 sw_if_index_set = 0;
10570
10571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10572     {
10573       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10574         sw_if_index_set = 1;
10575       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10576         sw_if_index_set = 1;
10577       else if (unformat (i, "enable"))
10578         enable = 1;
10579       else if (unformat (i, "disable"))
10580         enable = 0;
10581       else
10582         {
10583           clib_warning ("parse error '%U'", format_unformat_error, i);
10584           return -99;
10585         }
10586     }
10587
10588   if (sw_if_index_set == 0)
10589     {
10590       errmsg ("missing sw_if_index\n");
10591       return -99;
10592     }
10593
10594   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10595
10596   mp->sw_if_index = ntohl (sw_if_index);
10597   mp->enable_disable = enable;
10598
10599   S;
10600   W;
10601   /* NOTREACHED */
10602   return 0;
10603 }
10604
10605 #define foreach_vtr_op                          \
10606 _("disable",  L2_VTR_DISABLED)                  \
10607 _("push-1",  L2_VTR_PUSH_1)                     \
10608 _("push-2",  L2_VTR_PUSH_2)                     \
10609 _("pop-1",  L2_VTR_POP_1)                       \
10610 _("pop-2",  L2_VTR_POP_2)                       \
10611 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10612 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10613 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10614 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10615
10616 static int
10617 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10618 {
10619   unformat_input_t *i = vam->input;
10620   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10621   f64 timeout;
10622   u32 sw_if_index;
10623   u8 sw_if_index_set = 0;
10624   u8 vtr_op_set = 0;
10625   u32 vtr_op = 0;
10626   u32 push_dot1q = 1;
10627   u32 tag1 = ~0;
10628   u32 tag2 = ~0;
10629
10630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10631     {
10632       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10633         sw_if_index_set = 1;
10634       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10635         sw_if_index_set = 1;
10636       else if (unformat (i, "vtr_op %d", &vtr_op))
10637         vtr_op_set = 1;
10638 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10639       foreach_vtr_op
10640 #undef _
10641         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10642         ;
10643       else if (unformat (i, "tag1 %d", &tag1))
10644         ;
10645       else if (unformat (i, "tag2 %d", &tag2))
10646         ;
10647       else
10648         {
10649           clib_warning ("parse error '%U'", format_unformat_error, i);
10650           return -99;
10651         }
10652     }
10653
10654   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10655     {
10656       errmsg ("missing vtr operation or sw_if_index\n");
10657       return -99;
10658     }
10659
10660   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10661     mp->sw_if_index = ntohl (sw_if_index);
10662   mp->vtr_op = ntohl (vtr_op);
10663   mp->push_dot1q = ntohl (push_dot1q);
10664   mp->tag1 = ntohl (tag1);
10665   mp->tag2 = ntohl (tag2);
10666
10667   S;
10668   W;
10669   /* NOTREACHED */
10670   return 0;
10671 }
10672
10673 static int
10674 api_create_vhost_user_if (vat_main_t * vam)
10675 {
10676   unformat_input_t *i = vam->input;
10677   vl_api_create_vhost_user_if_t *mp;
10678   f64 timeout;
10679   u8 *file_name;
10680   u8 is_server = 0;
10681   u8 file_name_set = 0;
10682   u32 custom_dev_instance = ~0;
10683   u8 hwaddr[6];
10684   u8 use_custom_mac = 0;
10685   u8 *tag = 0;
10686
10687   /* Shut up coverity */
10688   memset (hwaddr, 0, sizeof (hwaddr));
10689
10690   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10691     {
10692       if (unformat (i, "socket %s", &file_name))
10693         {
10694           file_name_set = 1;
10695         }
10696       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10697         ;
10698       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10699         use_custom_mac = 1;
10700       else if (unformat (i, "server"))
10701         is_server = 1;
10702       else if (unformat (i, "tag %s", &tag))
10703         ;
10704       else
10705         break;
10706     }
10707
10708   if (file_name_set == 0)
10709     {
10710       errmsg ("missing socket file name\n");
10711       return -99;
10712     }
10713
10714   if (vec_len (file_name) > 255)
10715     {
10716       errmsg ("socket file name too long\n");
10717       return -99;
10718     }
10719   vec_add1 (file_name, 0);
10720
10721   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10722
10723   mp->is_server = is_server;
10724   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10725   vec_free (file_name);
10726   if (custom_dev_instance != ~0)
10727     {
10728       mp->renumber = 1;
10729       mp->custom_dev_instance = ntohl (custom_dev_instance);
10730     }
10731   mp->use_custom_mac = use_custom_mac;
10732   clib_memcpy (mp->mac_address, hwaddr, 6);
10733   if (tag)
10734     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10735   vec_free (tag);
10736
10737   S;
10738   W;
10739   /* NOTREACHED */
10740   return 0;
10741 }
10742
10743 static int
10744 api_modify_vhost_user_if (vat_main_t * vam)
10745 {
10746   unformat_input_t *i = vam->input;
10747   vl_api_modify_vhost_user_if_t *mp;
10748   f64 timeout;
10749   u8 *file_name;
10750   u8 is_server = 0;
10751   u8 file_name_set = 0;
10752   u32 custom_dev_instance = ~0;
10753   u8 sw_if_index_set = 0;
10754   u32 sw_if_index = (u32) ~ 0;
10755
10756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10757     {
10758       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10759         sw_if_index_set = 1;
10760       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10761         sw_if_index_set = 1;
10762       else if (unformat (i, "socket %s", &file_name))
10763         {
10764           file_name_set = 1;
10765         }
10766       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10767         ;
10768       else if (unformat (i, "server"))
10769         is_server = 1;
10770       else
10771         break;
10772     }
10773
10774   if (sw_if_index_set == 0)
10775     {
10776       errmsg ("missing sw_if_index or interface name\n");
10777       return -99;
10778     }
10779
10780   if (file_name_set == 0)
10781     {
10782       errmsg ("missing socket file name\n");
10783       return -99;
10784     }
10785
10786   if (vec_len (file_name) > 255)
10787     {
10788       errmsg ("socket file name too long\n");
10789       return -99;
10790     }
10791   vec_add1 (file_name, 0);
10792
10793   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10794
10795   mp->sw_if_index = ntohl (sw_if_index);
10796   mp->is_server = is_server;
10797   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10798   vec_free (file_name);
10799   if (custom_dev_instance != ~0)
10800     {
10801       mp->renumber = 1;
10802       mp->custom_dev_instance = ntohl (custom_dev_instance);
10803     }
10804
10805   S;
10806   W;
10807   /* NOTREACHED */
10808   return 0;
10809 }
10810
10811 static int
10812 api_delete_vhost_user_if (vat_main_t * vam)
10813 {
10814   unformat_input_t *i = vam->input;
10815   vl_api_delete_vhost_user_if_t *mp;
10816   f64 timeout;
10817   u32 sw_if_index = ~0;
10818   u8 sw_if_index_set = 0;
10819
10820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10821     {
10822       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10823         sw_if_index_set = 1;
10824       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10825         sw_if_index_set = 1;
10826       else
10827         break;
10828     }
10829
10830   if (sw_if_index_set == 0)
10831     {
10832       errmsg ("missing sw_if_index or interface name\n");
10833       return -99;
10834     }
10835
10836
10837   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10838
10839   mp->sw_if_index = ntohl (sw_if_index);
10840
10841   S;
10842   W;
10843   /* NOTREACHED */
10844   return 0;
10845 }
10846
10847 static void vl_api_sw_interface_vhost_user_details_t_handler
10848   (vl_api_sw_interface_vhost_user_details_t * mp)
10849 {
10850   vat_main_t *vam = &vat_main;
10851
10852   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10853            (char *) mp->interface_name,
10854            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10855            clib_net_to_host_u64 (mp->features), mp->is_server,
10856            ntohl (mp->num_regions), (char *) mp->sock_filename);
10857   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10858 }
10859
10860 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10861   (vl_api_sw_interface_vhost_user_details_t * mp)
10862 {
10863   vat_main_t *vam = &vat_main;
10864   vat_json_node_t *node = NULL;
10865
10866   if (VAT_JSON_ARRAY != vam->json_tree.type)
10867     {
10868       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10869       vat_json_init_array (&vam->json_tree);
10870     }
10871   node = vat_json_array_add (&vam->json_tree);
10872
10873   vat_json_init_object (node);
10874   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10875   vat_json_object_add_string_copy (node, "interface_name",
10876                                    mp->interface_name);
10877   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10878                             ntohl (mp->virtio_net_hdr_sz));
10879   vat_json_object_add_uint (node, "features",
10880                             clib_net_to_host_u64 (mp->features));
10881   vat_json_object_add_uint (node, "is_server", mp->is_server);
10882   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10883   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10884   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10885 }
10886
10887 static int
10888 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10889 {
10890   vl_api_sw_interface_vhost_user_dump_t *mp;
10891   f64 timeout;
10892   fformat (vam->ofp,
10893            "Interface name           idx hdr_sz features server regions filename\n");
10894
10895   /* Get list of vhost-user interfaces */
10896   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10897   S;
10898
10899   /* Use a control ping for synchronization */
10900   {
10901     vl_api_control_ping_t *mp;
10902     M (CONTROL_PING, control_ping);
10903     S;
10904   }
10905   W;
10906 }
10907
10908 static int
10909 api_show_version (vat_main_t * vam)
10910 {
10911   vl_api_show_version_t *mp;
10912   f64 timeout;
10913
10914   M (SHOW_VERSION, show_version);
10915
10916   S;
10917   W;
10918   /* NOTREACHED */
10919   return 0;
10920 }
10921
10922
10923 static int
10924 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10925 {
10926   unformat_input_t *line_input = vam->input;
10927   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10928   f64 timeout;
10929   ip4_address_t local4, remote4;
10930   ip6_address_t local6, remote6;
10931   u8 is_add = 1;
10932   u8 ipv4_set = 0, ipv6_set = 0;
10933   u8 local_set = 0;
10934   u8 remote_set = 0;
10935   u32 encap_vrf_id = 0;
10936   u32 decap_vrf_id = 0;
10937   u8 protocol = ~0;
10938   u32 vni;
10939   u8 vni_set = 0;
10940
10941   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10942     {
10943       if (unformat (line_input, "del"))
10944         is_add = 0;
10945       else if (unformat (line_input, "local %U",
10946                          unformat_ip4_address, &local4))
10947         {
10948           local_set = 1;
10949           ipv4_set = 1;
10950         }
10951       else if (unformat (line_input, "remote %U",
10952                          unformat_ip4_address, &remote4))
10953         {
10954           remote_set = 1;
10955           ipv4_set = 1;
10956         }
10957       else if (unformat (line_input, "local %U",
10958                          unformat_ip6_address, &local6))
10959         {
10960           local_set = 1;
10961           ipv6_set = 1;
10962         }
10963       else if (unformat (line_input, "remote %U",
10964                          unformat_ip6_address, &remote6))
10965         {
10966           remote_set = 1;
10967           ipv6_set = 1;
10968         }
10969       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10970         ;
10971       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10972         ;
10973       else if (unformat (line_input, "vni %d", &vni))
10974         vni_set = 1;
10975       else if (unformat (line_input, "next-ip4"))
10976         protocol = 1;
10977       else if (unformat (line_input, "next-ip6"))
10978         protocol = 2;
10979       else if (unformat (line_input, "next-ethernet"))
10980         protocol = 3;
10981       else if (unformat (line_input, "next-nsh"))
10982         protocol = 4;
10983       else
10984         {
10985           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10986           return -99;
10987         }
10988     }
10989
10990   if (local_set == 0)
10991     {
10992       errmsg ("tunnel local address not specified\n");
10993       return -99;
10994     }
10995   if (remote_set == 0)
10996     {
10997       errmsg ("tunnel remote address not specified\n");
10998       return -99;
10999     }
11000   if (ipv4_set && ipv6_set)
11001     {
11002       errmsg ("both IPv4 and IPv6 addresses specified");
11003       return -99;
11004     }
11005
11006   if (vni_set == 0)
11007     {
11008       errmsg ("vni not specified\n");
11009       return -99;
11010     }
11011
11012   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
11013
11014
11015   if (ipv6_set)
11016     {
11017       clib_memcpy (&mp->local, &local6, sizeof (local6));
11018       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11019     }
11020   else
11021     {
11022       clib_memcpy (&mp->local, &local4, sizeof (local4));
11023       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11024     }
11025
11026   mp->encap_vrf_id = ntohl (encap_vrf_id);
11027   mp->decap_vrf_id = ntohl (decap_vrf_id);
11028   mp->protocol = ntohl (protocol);
11029   mp->vni = ntohl (vni);
11030   mp->is_add = is_add;
11031   mp->is_ipv6 = ipv6_set;
11032
11033   S;
11034   W;
11035   /* NOTREACHED */
11036   return 0;
11037 }
11038
11039 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11040   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11041 {
11042   vat_main_t *vam = &vat_main;
11043
11044   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
11045            ntohl (mp->sw_if_index),
11046            format_ip46_address, &(mp->local[0]),
11047            format_ip46_address, &(mp->remote[0]),
11048            ntohl (mp->vni),
11049            ntohl (mp->protocol),
11050            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11051 }
11052
11053 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11054   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11055 {
11056   vat_main_t *vam = &vat_main;
11057   vat_json_node_t *node = NULL;
11058   struct in_addr ip4;
11059   struct in6_addr ip6;
11060
11061   if (VAT_JSON_ARRAY != vam->json_tree.type)
11062     {
11063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11064       vat_json_init_array (&vam->json_tree);
11065     }
11066   node = vat_json_array_add (&vam->json_tree);
11067
11068   vat_json_init_object (node);
11069   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11070   if (mp->is_ipv6)
11071     {
11072       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11073       vat_json_object_add_ip6 (node, "local", ip6);
11074       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11075       vat_json_object_add_ip6 (node, "remote", ip6);
11076     }
11077   else
11078     {
11079       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11080       vat_json_object_add_ip4 (node, "local", ip4);
11081       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11082       vat_json_object_add_ip4 (node, "remote", ip4);
11083     }
11084   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11085   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11086   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11087   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11088   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11089 }
11090
11091 static int
11092 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11093 {
11094   unformat_input_t *i = vam->input;
11095   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11096   f64 timeout;
11097   u32 sw_if_index;
11098   u8 sw_if_index_set = 0;
11099
11100   /* Parse args required to build the message */
11101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11102     {
11103       if (unformat (i, "sw_if_index %d", &sw_if_index))
11104         sw_if_index_set = 1;
11105       else
11106         break;
11107     }
11108
11109   if (sw_if_index_set == 0)
11110     {
11111       sw_if_index = ~0;
11112     }
11113
11114   if (!vam->json_output)
11115     {
11116       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
11117                "sw_if_index", "local", "remote", "vni",
11118                "protocol", "encap_vrf_id", "decap_vrf_id");
11119     }
11120
11121   /* Get list of vxlan-tunnel interfaces */
11122   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11123
11124   mp->sw_if_index = htonl (sw_if_index);
11125
11126   S;
11127
11128   /* Use a control ping for synchronization */
11129   {
11130     vl_api_control_ping_t *mp;
11131     M (CONTROL_PING, control_ping);
11132     S;
11133   }
11134   W;
11135 }
11136
11137 u8 *
11138 format_l2_fib_mac_address (u8 * s, va_list * args)
11139 {
11140   u8 *a = va_arg (*args, u8 *);
11141
11142   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11143                  a[2], a[3], a[4], a[5], a[6], a[7]);
11144 }
11145
11146 static void vl_api_l2_fib_table_entry_t_handler
11147   (vl_api_l2_fib_table_entry_t * mp)
11148 {
11149   vat_main_t *vam = &vat_main;
11150
11151   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11152            "       %d       %d     %d\n",
11153            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11154            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11155            mp->bvi_mac);
11156 }
11157
11158 static void vl_api_l2_fib_table_entry_t_handler_json
11159   (vl_api_l2_fib_table_entry_t * mp)
11160 {
11161   vat_main_t *vam = &vat_main;
11162   vat_json_node_t *node = NULL;
11163
11164   if (VAT_JSON_ARRAY != vam->json_tree.type)
11165     {
11166       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11167       vat_json_init_array (&vam->json_tree);
11168     }
11169   node = vat_json_array_add (&vam->json_tree);
11170
11171   vat_json_init_object (node);
11172   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11173   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11174   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11175   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11176   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11177   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11178 }
11179
11180 static int
11181 api_l2_fib_table_dump (vat_main_t * vam)
11182 {
11183   unformat_input_t *i = vam->input;
11184   vl_api_l2_fib_table_dump_t *mp;
11185   f64 timeout;
11186   u32 bd_id;
11187   u8 bd_id_set = 0;
11188
11189   /* Parse args required to build the message */
11190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11191     {
11192       if (unformat (i, "bd_id %d", &bd_id))
11193         bd_id_set = 1;
11194       else
11195         break;
11196     }
11197
11198   if (bd_id_set == 0)
11199     {
11200       errmsg ("missing bridge domain\n");
11201       return -99;
11202     }
11203
11204   fformat (vam->ofp,
11205            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11206
11207   /* Get list of l2 fib entries */
11208   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11209
11210   mp->bd_id = ntohl (bd_id);
11211   S;
11212
11213   /* Use a control ping for synchronization */
11214   {
11215     vl_api_control_ping_t *mp;
11216     M (CONTROL_PING, control_ping);
11217     S;
11218   }
11219   W;
11220 }
11221
11222
11223 static int
11224 api_interface_name_renumber (vat_main_t * vam)
11225 {
11226   unformat_input_t *line_input = vam->input;
11227   vl_api_interface_name_renumber_t *mp;
11228   u32 sw_if_index = ~0;
11229   f64 timeout;
11230   u32 new_show_dev_instance = ~0;
11231
11232   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11233     {
11234       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11235                     &sw_if_index))
11236         ;
11237       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11238         ;
11239       else if (unformat (line_input, "new_show_dev_instance %d",
11240                          &new_show_dev_instance))
11241         ;
11242       else
11243         break;
11244     }
11245
11246   if (sw_if_index == ~0)
11247     {
11248       errmsg ("missing interface name or sw_if_index\n");
11249       return -99;
11250     }
11251
11252   if (new_show_dev_instance == ~0)
11253     {
11254       errmsg ("missing new_show_dev_instance\n");
11255       return -99;
11256     }
11257
11258   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11259
11260   mp->sw_if_index = ntohl (sw_if_index);
11261   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11262
11263   S;
11264   W;
11265 }
11266
11267 static int
11268 api_want_ip4_arp_events (vat_main_t * vam)
11269 {
11270   unformat_input_t *line_input = vam->input;
11271   vl_api_want_ip4_arp_events_t *mp;
11272   f64 timeout;
11273   ip4_address_t address;
11274   int address_set = 0;
11275   u32 enable_disable = 1;
11276
11277   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11278     {
11279       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11280         address_set = 1;
11281       else if (unformat (line_input, "del"))
11282         enable_disable = 0;
11283       else
11284         break;
11285     }
11286
11287   if (address_set == 0)
11288     {
11289       errmsg ("missing addresses\n");
11290       return -99;
11291     }
11292
11293   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11294   mp->enable_disable = enable_disable;
11295   mp->pid = getpid ();
11296   mp->address = address.as_u32;
11297
11298   S;
11299   W;
11300 }
11301
11302 static int
11303 api_want_ip6_nd_events (vat_main_t * vam)
11304 {
11305   unformat_input_t *line_input = vam->input;
11306   vl_api_want_ip6_nd_events_t *mp;
11307   f64 timeout;
11308   ip6_address_t address;
11309   int address_set = 0;
11310   u32 enable_disable = 1;
11311
11312   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11313     {
11314       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11315         address_set = 1;
11316       else if (unformat (line_input, "del"))
11317         enable_disable = 0;
11318       else
11319         break;
11320     }
11321
11322   if (address_set == 0)
11323     {
11324       errmsg ("missing addresses\n");
11325       return -99;
11326     }
11327
11328   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11329   mp->enable_disable = enable_disable;
11330   mp->pid = getpid ();
11331   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11332
11333   S;
11334   W;
11335 }
11336
11337 static int
11338 api_input_acl_set_interface (vat_main_t * vam)
11339 {
11340   unformat_input_t *i = vam->input;
11341   vl_api_input_acl_set_interface_t *mp;
11342   f64 timeout;
11343   u32 sw_if_index;
11344   int sw_if_index_set;
11345   u32 ip4_table_index = ~0;
11346   u32 ip6_table_index = ~0;
11347   u32 l2_table_index = ~0;
11348   u8 is_add = 1;
11349
11350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11351     {
11352       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11353         sw_if_index_set = 1;
11354       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11355         sw_if_index_set = 1;
11356       else if (unformat (i, "del"))
11357         is_add = 0;
11358       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11359         ;
11360       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11361         ;
11362       else if (unformat (i, "l2-table %d", &l2_table_index))
11363         ;
11364       else
11365         {
11366           clib_warning ("parse error '%U'", format_unformat_error, i);
11367           return -99;
11368         }
11369     }
11370
11371   if (sw_if_index_set == 0)
11372     {
11373       errmsg ("missing interface name or sw_if_index\n");
11374       return -99;
11375     }
11376
11377   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11378
11379   mp->sw_if_index = ntohl (sw_if_index);
11380   mp->ip4_table_index = ntohl (ip4_table_index);
11381   mp->ip6_table_index = ntohl (ip6_table_index);
11382   mp->l2_table_index = ntohl (l2_table_index);
11383   mp->is_add = is_add;
11384
11385   S;
11386   W;
11387   /* NOTREACHED */
11388   return 0;
11389 }
11390
11391 static int
11392 api_ip_address_dump (vat_main_t * vam)
11393 {
11394   unformat_input_t *i = vam->input;
11395   vl_api_ip_address_dump_t *mp;
11396   u32 sw_if_index = ~0;
11397   u8 sw_if_index_set = 0;
11398   u8 ipv4_set = 0;
11399   u8 ipv6_set = 0;
11400   f64 timeout;
11401
11402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11403     {
11404       if (unformat (i, "sw_if_index %d", &sw_if_index))
11405         sw_if_index_set = 1;
11406       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11407         sw_if_index_set = 1;
11408       else if (unformat (i, "ipv4"))
11409         ipv4_set = 1;
11410       else if (unformat (i, "ipv6"))
11411         ipv6_set = 1;
11412       else
11413         break;
11414     }
11415
11416   if (ipv4_set && ipv6_set)
11417     {
11418       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11419       return -99;
11420     }
11421
11422   if ((!ipv4_set) && (!ipv6_set))
11423     {
11424       errmsg ("no ipv4 nor ipv6 flag set\n");
11425       return -99;
11426     }
11427
11428   if (sw_if_index_set == 0)
11429     {
11430       errmsg ("missing interface name or sw_if_index\n");
11431       return -99;
11432     }
11433
11434   vam->current_sw_if_index = sw_if_index;
11435   vam->is_ipv6 = ipv6_set;
11436
11437   M (IP_ADDRESS_DUMP, ip_address_dump);
11438   mp->sw_if_index = ntohl (sw_if_index);
11439   mp->is_ipv6 = ipv6_set;
11440   S;
11441
11442   /* Use a control ping for synchronization */
11443   {
11444     vl_api_control_ping_t *mp;
11445     M (CONTROL_PING, control_ping);
11446     S;
11447   }
11448   W;
11449 }
11450
11451 static int
11452 api_ip_dump (vat_main_t * vam)
11453 {
11454   vl_api_ip_dump_t *mp;
11455   unformat_input_t *in = vam->input;
11456   int ipv4_set = 0;
11457   int ipv6_set = 0;
11458   int is_ipv6;
11459   f64 timeout;
11460   int i;
11461
11462   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11463     {
11464       if (unformat (in, "ipv4"))
11465         ipv4_set = 1;
11466       else if (unformat (in, "ipv6"))
11467         ipv6_set = 1;
11468       else
11469         break;
11470     }
11471
11472   if (ipv4_set && ipv6_set)
11473     {
11474       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11475       return -99;
11476     }
11477
11478   if ((!ipv4_set) && (!ipv6_set))
11479     {
11480       errmsg ("no ipv4 nor ipv6 flag set\n");
11481       return -99;
11482     }
11483
11484   is_ipv6 = ipv6_set;
11485   vam->is_ipv6 = is_ipv6;
11486
11487   /* free old data */
11488   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11489     {
11490       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11491     }
11492   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11493
11494   M (IP_DUMP, ip_dump);
11495   mp->is_ipv6 = ipv6_set;
11496   S;
11497
11498   /* Use a control ping for synchronization */
11499   {
11500     vl_api_control_ping_t *mp;
11501     M (CONTROL_PING, control_ping);
11502     S;
11503   }
11504   W;
11505 }
11506
11507 static int
11508 api_ipsec_spd_add_del (vat_main_t * vam)
11509 {
11510   unformat_input_t *i = vam->input;
11511   vl_api_ipsec_spd_add_del_t *mp;
11512   f64 timeout;
11513   u32 spd_id = ~0;
11514   u8 is_add = 1;
11515
11516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11517     {
11518       if (unformat (i, "spd_id %d", &spd_id))
11519         ;
11520       else if (unformat (i, "del"))
11521         is_add = 0;
11522       else
11523         {
11524           clib_warning ("parse error '%U'", format_unformat_error, i);
11525           return -99;
11526         }
11527     }
11528   if (spd_id == ~0)
11529     {
11530       errmsg ("spd_id must be set\n");
11531       return -99;
11532     }
11533
11534   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11535
11536   mp->spd_id = ntohl (spd_id);
11537   mp->is_add = is_add;
11538
11539   S;
11540   W;
11541   /* NOTREACHED */
11542   return 0;
11543 }
11544
11545 static int
11546 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11547 {
11548   unformat_input_t *i = vam->input;
11549   vl_api_ipsec_interface_add_del_spd_t *mp;
11550   f64 timeout;
11551   u32 sw_if_index;
11552   u8 sw_if_index_set = 0;
11553   u32 spd_id = (u32) ~ 0;
11554   u8 is_add = 1;
11555
11556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11557     {
11558       if (unformat (i, "del"))
11559         is_add = 0;
11560       else if (unformat (i, "spd_id %d", &spd_id))
11561         ;
11562       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11563         sw_if_index_set = 1;
11564       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11565         sw_if_index_set = 1;
11566       else
11567         {
11568           clib_warning ("parse error '%U'", format_unformat_error, i);
11569           return -99;
11570         }
11571
11572     }
11573
11574   if (spd_id == (u32) ~ 0)
11575     {
11576       errmsg ("spd_id must be set\n");
11577       return -99;
11578     }
11579
11580   if (sw_if_index_set == 0)
11581     {
11582       errmsg ("missing interface name or sw_if_index\n");
11583       return -99;
11584     }
11585
11586   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11587
11588   mp->spd_id = ntohl (spd_id);
11589   mp->sw_if_index = ntohl (sw_if_index);
11590   mp->is_add = is_add;
11591
11592   S;
11593   W;
11594   /* NOTREACHED */
11595   return 0;
11596 }
11597
11598 static int
11599 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11600 {
11601   unformat_input_t *i = vam->input;
11602   vl_api_ipsec_spd_add_del_entry_t *mp;
11603   f64 timeout;
11604   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11605   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11606   i32 priority = 0;
11607   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11608   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11609   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11610   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11611
11612   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11613   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11614   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11615   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11616   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11617   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11618
11619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11620     {
11621       if (unformat (i, "del"))
11622         is_add = 0;
11623       if (unformat (i, "outbound"))
11624         is_outbound = 1;
11625       if (unformat (i, "inbound"))
11626         is_outbound = 0;
11627       else if (unformat (i, "spd_id %d", &spd_id))
11628         ;
11629       else if (unformat (i, "sa_id %d", &sa_id))
11630         ;
11631       else if (unformat (i, "priority %d", &priority))
11632         ;
11633       else if (unformat (i, "protocol %d", &protocol))
11634         ;
11635       else if (unformat (i, "lport_start %d", &lport_start))
11636         ;
11637       else if (unformat (i, "lport_stop %d", &lport_stop))
11638         ;
11639       else if (unformat (i, "rport_start %d", &rport_start))
11640         ;
11641       else if (unformat (i, "rport_stop %d", &rport_stop))
11642         ;
11643       else
11644         if (unformat
11645             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11646         {
11647           is_ipv6 = 0;
11648           is_ip_any = 0;
11649         }
11650       else
11651         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11652         {
11653           is_ipv6 = 0;
11654           is_ip_any = 0;
11655         }
11656       else
11657         if (unformat
11658             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11659         {
11660           is_ipv6 = 0;
11661           is_ip_any = 0;
11662         }
11663       else
11664         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11665         {
11666           is_ipv6 = 0;
11667           is_ip_any = 0;
11668         }
11669       else
11670         if (unformat
11671             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11672         {
11673           is_ipv6 = 1;
11674           is_ip_any = 0;
11675         }
11676       else
11677         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11678         {
11679           is_ipv6 = 1;
11680           is_ip_any = 0;
11681         }
11682       else
11683         if (unformat
11684             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11685         {
11686           is_ipv6 = 1;
11687           is_ip_any = 0;
11688         }
11689       else
11690         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11691         {
11692           is_ipv6 = 1;
11693           is_ip_any = 0;
11694         }
11695       else
11696         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11697         {
11698           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11699             {
11700               clib_warning ("unsupported action: 'resolve'");
11701               return -99;
11702             }
11703         }
11704       else
11705         {
11706           clib_warning ("parse error '%U'", format_unformat_error, i);
11707           return -99;
11708         }
11709
11710     }
11711
11712   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11713
11714   mp->spd_id = ntohl (spd_id);
11715   mp->priority = ntohl (priority);
11716   mp->is_outbound = is_outbound;
11717
11718   mp->is_ipv6 = is_ipv6;
11719   if (is_ipv6 || is_ip_any)
11720     {
11721       clib_memcpy (mp->remote_address_start, &raddr6_start,
11722                    sizeof (ip6_address_t));
11723       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11724                    sizeof (ip6_address_t));
11725       clib_memcpy (mp->local_address_start, &laddr6_start,
11726                    sizeof (ip6_address_t));
11727       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11728                    sizeof (ip6_address_t));
11729     }
11730   else
11731     {
11732       clib_memcpy (mp->remote_address_start, &raddr4_start,
11733                    sizeof (ip4_address_t));
11734       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11735                    sizeof (ip4_address_t));
11736       clib_memcpy (mp->local_address_start, &laddr4_start,
11737                    sizeof (ip4_address_t));
11738       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11739                    sizeof (ip4_address_t));
11740     }
11741   mp->protocol = (u8) protocol;
11742   mp->local_port_start = ntohs ((u16) lport_start);
11743   mp->local_port_stop = ntohs ((u16) lport_stop);
11744   mp->remote_port_start = ntohs ((u16) rport_start);
11745   mp->remote_port_stop = ntohs ((u16) rport_stop);
11746   mp->policy = (u8) policy;
11747   mp->sa_id = ntohl (sa_id);
11748   mp->is_add = is_add;
11749   mp->is_ip_any = is_ip_any;
11750   S;
11751   W;
11752   /* NOTREACHED */
11753   return 0;
11754 }
11755
11756 static int
11757 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11758 {
11759   unformat_input_t *i = vam->input;
11760   vl_api_ipsec_sad_add_del_entry_t *mp;
11761   f64 timeout;
11762   u32 sad_id = 0, spi = 0;
11763   u8 *ck = 0, *ik = 0;
11764   u8 is_add = 1;
11765
11766   u8 protocol = IPSEC_PROTOCOL_AH;
11767   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11768   u32 crypto_alg = 0, integ_alg = 0;
11769   ip4_address_t tun_src4;
11770   ip4_address_t tun_dst4;
11771   ip6_address_t tun_src6;
11772   ip6_address_t tun_dst6;
11773
11774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11775     {
11776       if (unformat (i, "del"))
11777         is_add = 0;
11778       else if (unformat (i, "sad_id %d", &sad_id))
11779         ;
11780       else if (unformat (i, "spi %d", &spi))
11781         ;
11782       else if (unformat (i, "esp"))
11783         protocol = IPSEC_PROTOCOL_ESP;
11784       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11785         {
11786           is_tunnel = 1;
11787           is_tunnel_ipv6 = 0;
11788         }
11789       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11790         {
11791           is_tunnel = 1;
11792           is_tunnel_ipv6 = 0;
11793         }
11794       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11795         {
11796           is_tunnel = 1;
11797           is_tunnel_ipv6 = 1;
11798         }
11799       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11800         {
11801           is_tunnel = 1;
11802           is_tunnel_ipv6 = 1;
11803         }
11804       else
11805         if (unformat
11806             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11807         {
11808           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11809               crypto_alg >= IPSEC_CRYPTO_N_ALG)
11810             {
11811               clib_warning ("unsupported crypto-alg: '%U'",
11812                             format_ipsec_crypto_alg, crypto_alg);
11813               return -99;
11814             }
11815         }
11816       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11817         ;
11818       else
11819         if (unformat
11820             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11821         {
11822 #if DPDK_CRYPTO==1
11823           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
11824 #else
11825           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11826 #endif
11827               integ_alg >= IPSEC_INTEG_N_ALG)
11828             {
11829               clib_warning ("unsupported integ-alg: '%U'",
11830                             format_ipsec_integ_alg, integ_alg);
11831               return -99;
11832             }
11833         }
11834       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11835         ;
11836       else
11837         {
11838           clib_warning ("parse error '%U'", format_unformat_error, i);
11839           return -99;
11840         }
11841
11842     }
11843
11844 #if DPDK_CRYPTO==1
11845   /*Special cases, aes-gcm-128 encryption */
11846   if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
11847     {
11848       if (integ_alg != IPSEC_INTEG_ALG_NONE
11849           && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
11850         {
11851           clib_warning
11852             ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
11853           return -99;
11854         }
11855       else                      /*set integ-alg internally to aes-gcm-128 */
11856         integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
11857     }
11858   else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
11859     {
11860       clib_warning ("unsupported integ-alg: aes-gcm-128");
11861       return -99;
11862     }
11863   else if (integ_alg == IPSEC_INTEG_ALG_NONE)
11864     {
11865       clib_warning ("unsupported integ-alg: none");
11866       return -99;
11867     }
11868 #endif
11869
11870
11871   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11872
11873   mp->sad_id = ntohl (sad_id);
11874   mp->is_add = is_add;
11875   mp->protocol = protocol;
11876   mp->spi = ntohl (spi);
11877   mp->is_tunnel = is_tunnel;
11878   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11879   mp->crypto_algorithm = crypto_alg;
11880   mp->integrity_algorithm = integ_alg;
11881   mp->crypto_key_length = vec_len (ck);
11882   mp->integrity_key_length = vec_len (ik);
11883
11884   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11885     mp->crypto_key_length = sizeof (mp->crypto_key);
11886
11887   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11888     mp->integrity_key_length = sizeof (mp->integrity_key);
11889
11890   if (ck)
11891     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11892   if (ik)
11893     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11894
11895   if (is_tunnel)
11896     {
11897       if (is_tunnel_ipv6)
11898         {
11899           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11900                        sizeof (ip6_address_t));
11901           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11902                        sizeof (ip6_address_t));
11903         }
11904       else
11905         {
11906           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11907                        sizeof (ip4_address_t));
11908           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11909                        sizeof (ip4_address_t));
11910         }
11911     }
11912
11913   S;
11914   W;
11915   /* NOTREACHED */
11916   return 0;
11917 }
11918
11919 static int
11920 api_ipsec_sa_set_key (vat_main_t * vam)
11921 {
11922   unformat_input_t *i = vam->input;
11923   vl_api_ipsec_sa_set_key_t *mp;
11924   f64 timeout;
11925   u32 sa_id;
11926   u8 *ck = 0, *ik = 0;
11927
11928   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11929     {
11930       if (unformat (i, "sa_id %d", &sa_id))
11931         ;
11932       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11933         ;
11934       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11935         ;
11936       else
11937         {
11938           clib_warning ("parse error '%U'", format_unformat_error, i);
11939           return -99;
11940         }
11941     }
11942
11943   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11944
11945   mp->sa_id = ntohl (sa_id);
11946   mp->crypto_key_length = vec_len (ck);
11947   mp->integrity_key_length = vec_len (ik);
11948
11949   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11950     mp->crypto_key_length = sizeof (mp->crypto_key);
11951
11952   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11953     mp->integrity_key_length = sizeof (mp->integrity_key);
11954
11955   if (ck)
11956     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11957   if (ik)
11958     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11959
11960   S;
11961   W;
11962   /* NOTREACHED */
11963   return 0;
11964 }
11965
11966 static int
11967 api_ikev2_profile_add_del (vat_main_t * vam)
11968 {
11969   unformat_input_t *i = vam->input;
11970   vl_api_ikev2_profile_add_del_t *mp;
11971   f64 timeout;
11972   u8 is_add = 1;
11973   u8 *name = 0;
11974
11975   const char *valid_chars = "a-zA-Z0-9_";
11976
11977   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11978     {
11979       if (unformat (i, "del"))
11980         is_add = 0;
11981       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11982         vec_add1 (name, 0);
11983       else
11984         {
11985           errmsg ("parse error '%U'", format_unformat_error, i);
11986           return -99;
11987         }
11988     }
11989
11990   if (!vec_len (name))
11991     {
11992       errmsg ("profile name must be specified");
11993       return -99;
11994     }
11995
11996   if (vec_len (name) > 64)
11997     {
11998       errmsg ("profile name too long");
11999       return -99;
12000     }
12001
12002   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12003
12004   clib_memcpy (mp->name, name, vec_len (name));
12005   mp->is_add = is_add;
12006   vec_free (name);
12007
12008   S;
12009   W;
12010   /* NOTREACHED */
12011   return 0;
12012 }
12013
12014 static int
12015 api_ikev2_profile_set_auth (vat_main_t * vam)
12016 {
12017   unformat_input_t *i = vam->input;
12018   vl_api_ikev2_profile_set_auth_t *mp;
12019   f64 timeout;
12020   u8 *name = 0;
12021   u8 *data = 0;
12022   u32 auth_method = 0;
12023   u8 is_hex = 0;
12024
12025   const char *valid_chars = "a-zA-Z0-9_";
12026
12027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12028     {
12029       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12030         vec_add1 (name, 0);
12031       else if (unformat (i, "auth_method %U",
12032                          unformat_ikev2_auth_method, &auth_method))
12033         ;
12034       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12035         is_hex = 1;
12036       else if (unformat (i, "auth_data %v", &data))
12037         ;
12038       else
12039         {
12040           errmsg ("parse error '%U'", format_unformat_error, i);
12041           return -99;
12042         }
12043     }
12044
12045   if (!vec_len (name))
12046     {
12047       errmsg ("profile name must be specified");
12048       return -99;
12049     }
12050
12051   if (vec_len (name) > 64)
12052     {
12053       errmsg ("profile name too long");
12054       return -99;
12055     }
12056
12057   if (!vec_len (data))
12058     {
12059       errmsg ("auth_data must be specified");
12060       return -99;
12061     }
12062
12063   if (!auth_method)
12064     {
12065       errmsg ("auth_method must be specified");
12066       return -99;
12067     }
12068
12069   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12070
12071   mp->is_hex = is_hex;
12072   mp->auth_method = (u8) auth_method;
12073   mp->data_len = vec_len (data);
12074   clib_memcpy (mp->name, name, vec_len (name));
12075   clib_memcpy (mp->data, data, vec_len (data));
12076   vec_free (name);
12077   vec_free (data);
12078
12079   S;
12080   W;
12081   /* NOTREACHED */
12082   return 0;
12083 }
12084
12085 static int
12086 api_ikev2_profile_set_id (vat_main_t * vam)
12087 {
12088   unformat_input_t *i = vam->input;
12089   vl_api_ikev2_profile_set_id_t *mp;
12090   f64 timeout;
12091   u8 *name = 0;
12092   u8 *data = 0;
12093   u8 is_local = 0;
12094   u32 id_type = 0;
12095   ip4_address_t ip4;
12096
12097   const char *valid_chars = "a-zA-Z0-9_";
12098
12099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12100     {
12101       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12102         vec_add1 (name, 0);
12103       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12104         ;
12105       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12106         {
12107           data = vec_new (u8, 4);
12108           clib_memcpy (data, ip4.as_u8, 4);
12109         }
12110       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12111         ;
12112       else if (unformat (i, "id_data %v", &data))
12113         ;
12114       else if (unformat (i, "local"))
12115         is_local = 1;
12116       else if (unformat (i, "remote"))
12117         is_local = 0;
12118       else
12119         {
12120           errmsg ("parse error '%U'", format_unformat_error, i);
12121           return -99;
12122         }
12123     }
12124
12125   if (!vec_len (name))
12126     {
12127       errmsg ("profile name must be specified");
12128       return -99;
12129     }
12130
12131   if (vec_len (name) > 64)
12132     {
12133       errmsg ("profile name too long");
12134       return -99;
12135     }
12136
12137   if (!vec_len (data))
12138     {
12139       errmsg ("id_data must be specified");
12140       return -99;
12141     }
12142
12143   if (!id_type)
12144     {
12145       errmsg ("id_type must be specified");
12146       return -99;
12147     }
12148
12149   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12150
12151   mp->is_local = is_local;
12152   mp->id_type = (u8) id_type;
12153   mp->data_len = vec_len (data);
12154   clib_memcpy (mp->name, name, vec_len (name));
12155   clib_memcpy (mp->data, data, vec_len (data));
12156   vec_free (name);
12157   vec_free (data);
12158
12159   S;
12160   W;
12161   /* NOTREACHED */
12162   return 0;
12163 }
12164
12165 static int
12166 api_ikev2_profile_set_ts (vat_main_t * vam)
12167 {
12168   unformat_input_t *i = vam->input;
12169   vl_api_ikev2_profile_set_ts_t *mp;
12170   f64 timeout;
12171   u8 *name = 0;
12172   u8 is_local = 0;
12173   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12174   ip4_address_t start_addr, end_addr;
12175
12176   const char *valid_chars = "a-zA-Z0-9_";
12177
12178   start_addr.as_u32 = 0;
12179   end_addr.as_u32 = (u32) ~ 0;
12180
12181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12182     {
12183       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12184         vec_add1 (name, 0);
12185       else if (unformat (i, "protocol %d", &proto))
12186         ;
12187       else if (unformat (i, "start_port %d", &start_port))
12188         ;
12189       else if (unformat (i, "end_port %d", &end_port))
12190         ;
12191       else
12192         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12193         ;
12194       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12195         ;
12196       else if (unformat (i, "local"))
12197         is_local = 1;
12198       else if (unformat (i, "remote"))
12199         is_local = 0;
12200       else
12201         {
12202           errmsg ("parse error '%U'", format_unformat_error, i);
12203           return -99;
12204         }
12205     }
12206
12207   if (!vec_len (name))
12208     {
12209       errmsg ("profile name must be specified");
12210       return -99;
12211     }
12212
12213   if (vec_len (name) > 64)
12214     {
12215       errmsg ("profile name too long");
12216       return -99;
12217     }
12218
12219   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12220
12221   mp->is_local = is_local;
12222   mp->proto = (u8) proto;
12223   mp->start_port = (u16) start_port;
12224   mp->end_port = (u16) end_port;
12225   mp->start_addr = start_addr.as_u32;
12226   mp->end_addr = end_addr.as_u32;
12227   clib_memcpy (mp->name, name, vec_len (name));
12228   vec_free (name);
12229
12230   S;
12231   W;
12232   /* NOTREACHED */
12233   return 0;
12234 }
12235
12236 static int
12237 api_ikev2_set_local_key (vat_main_t * vam)
12238 {
12239   unformat_input_t *i = vam->input;
12240   vl_api_ikev2_set_local_key_t *mp;
12241   f64 timeout;
12242   u8 *file = 0;
12243
12244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12245     {
12246       if (unformat (i, "file %v", &file))
12247         vec_add1 (file, 0);
12248       else
12249         {
12250           errmsg ("parse error '%U'", format_unformat_error, i);
12251           return -99;
12252         }
12253     }
12254
12255   if (!vec_len (file))
12256     {
12257       errmsg ("RSA key file must be specified");
12258       return -99;
12259     }
12260
12261   if (vec_len (file) > 256)
12262     {
12263       errmsg ("file name too long");
12264       return -99;
12265     }
12266
12267   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12268
12269   clib_memcpy (mp->key_file, file, vec_len (file));
12270   vec_free (file);
12271
12272   S;
12273   W;
12274   /* NOTREACHED */
12275   return 0;
12276 }
12277
12278 /*
12279  * MAP
12280  */
12281 static int
12282 api_map_add_domain (vat_main_t * vam)
12283 {
12284   unformat_input_t *i = vam->input;
12285   vl_api_map_add_domain_t *mp;
12286   f64 timeout;
12287
12288   ip4_address_t ip4_prefix;
12289   ip6_address_t ip6_prefix;
12290   ip6_address_t ip6_src;
12291   u32 num_m_args = 0;
12292   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12293     0, psid_length = 0;
12294   u8 is_translation = 0;
12295   u32 mtu = 0;
12296   u32 ip6_src_len = 128;
12297
12298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12299     {
12300       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12301                     &ip4_prefix, &ip4_prefix_len))
12302         num_m_args++;
12303       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12304                          &ip6_prefix, &ip6_prefix_len))
12305         num_m_args++;
12306       else
12307         if (unformat
12308             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12309              &ip6_src_len))
12310         num_m_args++;
12311       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12312         num_m_args++;
12313       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12314         num_m_args++;
12315       else if (unformat (i, "psid-offset %d", &psid_offset))
12316         num_m_args++;
12317       else if (unformat (i, "psid-len %d", &psid_length))
12318         num_m_args++;
12319       else if (unformat (i, "mtu %d", &mtu))
12320         num_m_args++;
12321       else if (unformat (i, "map-t"))
12322         is_translation = 1;
12323       else
12324         {
12325           clib_warning ("parse error '%U'", format_unformat_error, i);
12326           return -99;
12327         }
12328     }
12329
12330   if (num_m_args < 3)
12331     {
12332       errmsg ("mandatory argument(s) missing\n");
12333       return -99;
12334     }
12335
12336   /* Construct the API message */
12337   M (MAP_ADD_DOMAIN, map_add_domain);
12338
12339   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12340   mp->ip4_prefix_len = ip4_prefix_len;
12341
12342   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12343   mp->ip6_prefix_len = ip6_prefix_len;
12344
12345   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12346   mp->ip6_src_prefix_len = ip6_src_len;
12347
12348   mp->ea_bits_len = ea_bits_len;
12349   mp->psid_offset = psid_offset;
12350   mp->psid_length = psid_length;
12351   mp->is_translation = is_translation;
12352   mp->mtu = htons (mtu);
12353
12354   /* send it... */
12355   S;
12356
12357   /* Wait for a reply, return good/bad news  */
12358   W;
12359 }
12360
12361 static int
12362 api_map_del_domain (vat_main_t * vam)
12363 {
12364   unformat_input_t *i = vam->input;
12365   vl_api_map_del_domain_t *mp;
12366   f64 timeout;
12367
12368   u32 num_m_args = 0;
12369   u32 index;
12370
12371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12372     {
12373       if (unformat (i, "index %d", &index))
12374         num_m_args++;
12375       else
12376         {
12377           clib_warning ("parse error '%U'", format_unformat_error, i);
12378           return -99;
12379         }
12380     }
12381
12382   if (num_m_args != 1)
12383     {
12384       errmsg ("mandatory argument(s) missing\n");
12385       return -99;
12386     }
12387
12388   /* Construct the API message */
12389   M (MAP_DEL_DOMAIN, map_del_domain);
12390
12391   mp->index = ntohl (index);
12392
12393   /* send it... */
12394   S;
12395
12396   /* Wait for a reply, return good/bad news  */
12397   W;
12398 }
12399
12400 static int
12401 api_map_add_del_rule (vat_main_t * vam)
12402 {
12403   unformat_input_t *i = vam->input;
12404   vl_api_map_add_del_rule_t *mp;
12405   f64 timeout;
12406   u8 is_add = 1;
12407   ip6_address_t ip6_dst;
12408   u32 num_m_args = 0, index, psid = 0;
12409
12410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12411     {
12412       if (unformat (i, "index %d", &index))
12413         num_m_args++;
12414       else if (unformat (i, "psid %d", &psid))
12415         num_m_args++;
12416       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12417         num_m_args++;
12418       else if (unformat (i, "del"))
12419         {
12420           is_add = 0;
12421         }
12422       else
12423         {
12424           clib_warning ("parse error '%U'", format_unformat_error, i);
12425           return -99;
12426         }
12427     }
12428
12429   /* Construct the API message */
12430   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12431
12432   mp->index = ntohl (index);
12433   mp->is_add = is_add;
12434   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12435   mp->psid = ntohs (psid);
12436
12437   /* send it... */
12438   S;
12439
12440   /* Wait for a reply, return good/bad news  */
12441   W;
12442 }
12443
12444 static int
12445 api_map_domain_dump (vat_main_t * vam)
12446 {
12447   vl_api_map_domain_dump_t *mp;
12448   f64 timeout;
12449
12450   /* Construct the API message */
12451   M (MAP_DOMAIN_DUMP, map_domain_dump);
12452
12453   /* send it... */
12454   S;
12455
12456   /* Use a control ping for synchronization */
12457   {
12458     vl_api_control_ping_t *mp;
12459     M (CONTROL_PING, control_ping);
12460     S;
12461   }
12462   W;
12463 }
12464
12465 static int
12466 api_map_rule_dump (vat_main_t * vam)
12467 {
12468   unformat_input_t *i = vam->input;
12469   vl_api_map_rule_dump_t *mp;
12470   f64 timeout;
12471   u32 domain_index = ~0;
12472
12473   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12474     {
12475       if (unformat (i, "index %u", &domain_index))
12476         ;
12477       else
12478         break;
12479     }
12480
12481   if (domain_index == ~0)
12482     {
12483       clib_warning ("parse error: domain index expected");
12484       return -99;
12485     }
12486
12487   /* Construct the API message */
12488   M (MAP_RULE_DUMP, map_rule_dump);
12489
12490   mp->domain_index = htonl (domain_index);
12491
12492   /* send it... */
12493   S;
12494
12495   /* Use a control ping for synchronization */
12496   {
12497     vl_api_control_ping_t *mp;
12498     M (CONTROL_PING, control_ping);
12499     S;
12500   }
12501   W;
12502 }
12503
12504 static void vl_api_map_add_domain_reply_t_handler
12505   (vl_api_map_add_domain_reply_t * mp)
12506 {
12507   vat_main_t *vam = &vat_main;
12508   i32 retval = ntohl (mp->retval);
12509
12510   if (vam->async_mode)
12511     {
12512       vam->async_errors += (retval < 0);
12513     }
12514   else
12515     {
12516       vam->retval = retval;
12517       vam->result_ready = 1;
12518     }
12519 }
12520
12521 static void vl_api_map_add_domain_reply_t_handler_json
12522   (vl_api_map_add_domain_reply_t * mp)
12523 {
12524   vat_main_t *vam = &vat_main;
12525   vat_json_node_t node;
12526
12527   vat_json_init_object (&node);
12528   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12529   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12530
12531   vat_json_print (vam->ofp, &node);
12532   vat_json_free (&node);
12533
12534   vam->retval = ntohl (mp->retval);
12535   vam->result_ready = 1;
12536 }
12537
12538 static int
12539 api_get_first_msg_id (vat_main_t * vam)
12540 {
12541   vl_api_get_first_msg_id_t *mp;
12542   f64 timeout;
12543   unformat_input_t *i = vam->input;
12544   u8 *name;
12545   u8 name_set = 0;
12546
12547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12548     {
12549       if (unformat (i, "client %s", &name))
12550         name_set = 1;
12551       else
12552         break;
12553     }
12554
12555   if (name_set == 0)
12556     {
12557       errmsg ("missing client name\n");
12558       return -99;
12559     }
12560   vec_add1 (name, 0);
12561
12562   if (vec_len (name) > 63)
12563     {
12564       errmsg ("client name too long\n");
12565       return -99;
12566     }
12567
12568   M (GET_FIRST_MSG_ID, get_first_msg_id);
12569   clib_memcpy (mp->name, name, vec_len (name));
12570   S;
12571   W;
12572   /* NOTREACHED */
12573   return 0;
12574 }
12575
12576 static int
12577 api_cop_interface_enable_disable (vat_main_t * vam)
12578 {
12579   unformat_input_t *line_input = vam->input;
12580   vl_api_cop_interface_enable_disable_t *mp;
12581   f64 timeout;
12582   u32 sw_if_index = ~0;
12583   u8 enable_disable = 1;
12584
12585   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12586     {
12587       if (unformat (line_input, "disable"))
12588         enable_disable = 0;
12589       if (unformat (line_input, "enable"))
12590         enable_disable = 1;
12591       else if (unformat (line_input, "%U", unformat_sw_if_index,
12592                          vam, &sw_if_index))
12593         ;
12594       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12595         ;
12596       else
12597         break;
12598     }
12599
12600   if (sw_if_index == ~0)
12601     {
12602       errmsg ("missing interface name or sw_if_index\n");
12603       return -99;
12604     }
12605
12606   /* Construct the API message */
12607   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12608   mp->sw_if_index = ntohl (sw_if_index);
12609   mp->enable_disable = enable_disable;
12610
12611   /* send it... */
12612   S;
12613   /* Wait for the reply */
12614   W;
12615 }
12616
12617 static int
12618 api_cop_whitelist_enable_disable (vat_main_t * vam)
12619 {
12620   unformat_input_t *line_input = vam->input;
12621   vl_api_cop_whitelist_enable_disable_t *mp;
12622   f64 timeout;
12623   u32 sw_if_index = ~0;
12624   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12625   u32 fib_id = 0;
12626
12627   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12628     {
12629       if (unformat (line_input, "ip4"))
12630         ip4 = 1;
12631       else if (unformat (line_input, "ip6"))
12632         ip6 = 1;
12633       else if (unformat (line_input, "default"))
12634         default_cop = 1;
12635       else if (unformat (line_input, "%U", unformat_sw_if_index,
12636                          vam, &sw_if_index))
12637         ;
12638       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12639         ;
12640       else if (unformat (line_input, "fib-id %d", &fib_id))
12641         ;
12642       else
12643         break;
12644     }
12645
12646   if (sw_if_index == ~0)
12647     {
12648       errmsg ("missing interface name or sw_if_index\n");
12649       return -99;
12650     }
12651
12652   /* Construct the API message */
12653   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12654   mp->sw_if_index = ntohl (sw_if_index);
12655   mp->fib_id = ntohl (fib_id);
12656   mp->ip4 = ip4;
12657   mp->ip6 = ip6;
12658   mp->default_cop = default_cop;
12659
12660   /* send it... */
12661   S;
12662   /* Wait for the reply */
12663   W;
12664 }
12665
12666 static int
12667 api_get_node_graph (vat_main_t * vam)
12668 {
12669   vl_api_get_node_graph_t *mp;
12670   f64 timeout;
12671
12672   M (GET_NODE_GRAPH, get_node_graph);
12673
12674   /* send it... */
12675   S;
12676   /* Wait for the reply */
12677   W;
12678 }
12679
12680 /* *INDENT-OFF* */
12681 /** Used for parsing LISP eids */
12682 typedef CLIB_PACKED(struct{
12683   u8 addr[16];   /**< eid address */
12684   u32 len;       /**< prefix length if IP */
12685   u8 type;      /**< type of eid */
12686 }) lisp_eid_vat_t;
12687 /* *INDENT-ON* */
12688
12689 static uword
12690 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12691 {
12692   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12693
12694   memset (a, 0, sizeof (a[0]));
12695
12696   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12697     {
12698       a->type = 0;              /* ipv4 type */
12699     }
12700   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12701     {
12702       a->type = 1;              /* ipv6 type */
12703     }
12704   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12705     {
12706       a->type = 2;              /* mac type */
12707     }
12708   else
12709     {
12710       return 0;
12711     }
12712
12713   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12714     {
12715       return 0;
12716     }
12717
12718   return 1;
12719 }
12720
12721 static int
12722 lisp_eid_size_vat (u8 type)
12723 {
12724   switch (type)
12725     {
12726     case 0:
12727       return 4;
12728     case 1:
12729       return 16;
12730     case 2:
12731       return 6;
12732     }
12733   return 0;
12734 }
12735
12736 static void
12737 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12738 {
12739   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12740 }
12741
12742 /* *INDENT-OFF* */
12743 /** Used for transferring locators via VPP API */
12744 typedef CLIB_PACKED(struct
12745 {
12746   u32 sw_if_index; /**< locator sw_if_index */
12747   u8 priority; /**< locator priority */
12748   u8 weight;   /**< locator weight */
12749 }) ls_locator_t;
12750 /* *INDENT-ON* */
12751
12752 static int
12753 api_lisp_add_del_locator_set (vat_main_t * vam)
12754 {
12755   unformat_input_t *input = vam->input;
12756   vl_api_lisp_add_del_locator_set_t *mp;
12757   f64 timeout = ~0;
12758   u8 is_add = 1;
12759   u8 *locator_set_name = NULL;
12760   u8 locator_set_name_set = 0;
12761   ls_locator_t locator, *locators = 0;
12762   u32 sw_if_index, priority, weight;
12763   u32 data_len = 0;
12764
12765   /* Parse args required to build the message */
12766   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12767     {
12768       if (unformat (input, "del"))
12769         {
12770           is_add = 0;
12771         }
12772       else if (unformat (input, "locator-set %s", &locator_set_name))
12773         {
12774           locator_set_name_set = 1;
12775         }
12776       else if (unformat (input, "sw_if_index %u p %u w %u",
12777                          &sw_if_index, &priority, &weight))
12778         {
12779           locator.sw_if_index = htonl (sw_if_index);
12780           locator.priority = priority;
12781           locator.weight = weight;
12782           vec_add1 (locators, locator);
12783         }
12784       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12785                          vam, &sw_if_index, &priority, &weight))
12786         {
12787           locator.sw_if_index = htonl (sw_if_index);
12788           locator.priority = priority;
12789           locator.weight = weight;
12790           vec_add1 (locators, locator);
12791         }
12792       else
12793         break;
12794     }
12795
12796   if (locator_set_name_set == 0)
12797     {
12798       errmsg ("missing locator-set name");
12799       vec_free (locators);
12800       return -99;
12801     }
12802
12803   if (vec_len (locator_set_name) > 64)
12804     {
12805       errmsg ("locator-set name too long\n");
12806       vec_free (locator_set_name);
12807       vec_free (locators);
12808       return -99;
12809     }
12810   vec_add1 (locator_set_name, 0);
12811
12812   data_len = sizeof (ls_locator_t) * vec_len (locators);
12813
12814   /* Construct the API message */
12815   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12816
12817   mp->is_add = is_add;
12818   clib_memcpy (mp->locator_set_name, locator_set_name,
12819                vec_len (locator_set_name));
12820   vec_free (locator_set_name);
12821
12822   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12823   if (locators)
12824     clib_memcpy (mp->locators, locators, data_len);
12825   vec_free (locators);
12826
12827   /* send it... */
12828   S;
12829
12830   /* Wait for a reply... */
12831   W;
12832
12833   /* NOTREACHED */
12834   return 0;
12835 }
12836
12837 static int
12838 api_lisp_add_del_locator (vat_main_t * vam)
12839 {
12840   unformat_input_t *input = vam->input;
12841   vl_api_lisp_add_del_locator_t *mp;
12842   f64 timeout = ~0;
12843   u32 tmp_if_index = ~0;
12844   u32 sw_if_index = ~0;
12845   u8 sw_if_index_set = 0;
12846   u8 sw_if_index_if_name_set = 0;
12847   u32 priority = ~0;
12848   u8 priority_set = 0;
12849   u32 weight = ~0;
12850   u8 weight_set = 0;
12851   u8 is_add = 1;
12852   u8 *locator_set_name = NULL;
12853   u8 locator_set_name_set = 0;
12854
12855   /* Parse args required to build the message */
12856   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12857     {
12858       if (unformat (input, "del"))
12859         {
12860           is_add = 0;
12861         }
12862       else if (unformat (input, "locator-set %s", &locator_set_name))
12863         {
12864           locator_set_name_set = 1;
12865         }
12866       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12867                          &tmp_if_index))
12868         {
12869           sw_if_index_if_name_set = 1;
12870           sw_if_index = tmp_if_index;
12871         }
12872       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12873         {
12874           sw_if_index_set = 1;
12875           sw_if_index = tmp_if_index;
12876         }
12877       else if (unformat (input, "p %d", &priority))
12878         {
12879           priority_set = 1;
12880         }
12881       else if (unformat (input, "w %d", &weight))
12882         {
12883           weight_set = 1;
12884         }
12885       else
12886         break;
12887     }
12888
12889   if (locator_set_name_set == 0)
12890     {
12891       errmsg ("missing locator-set name");
12892       return -99;
12893     }
12894
12895   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12896     {
12897       errmsg ("missing sw_if_index");
12898       vec_free (locator_set_name);
12899       return -99;
12900     }
12901
12902   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12903     {
12904       errmsg ("cannot use both params interface name and sw_if_index");
12905       vec_free (locator_set_name);
12906       return -99;
12907     }
12908
12909   if (priority_set == 0)
12910     {
12911       errmsg ("missing locator-set priority\n");
12912       vec_free (locator_set_name);
12913       return -99;
12914     }
12915
12916   if (weight_set == 0)
12917     {
12918       errmsg ("missing locator-set weight\n");
12919       vec_free (locator_set_name);
12920       return -99;
12921     }
12922
12923   if (vec_len (locator_set_name) > 64)
12924     {
12925       errmsg ("locator-set name too long\n");
12926       vec_free (locator_set_name);
12927       return -99;
12928     }
12929   vec_add1 (locator_set_name, 0);
12930
12931   /* Construct the API message */
12932   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12933
12934   mp->is_add = is_add;
12935   mp->sw_if_index = ntohl (sw_if_index);
12936   mp->priority = priority;
12937   mp->weight = weight;
12938   clib_memcpy (mp->locator_set_name, locator_set_name,
12939                vec_len (locator_set_name));
12940   vec_free (locator_set_name);
12941
12942   /* send it... */
12943   S;
12944
12945   /* Wait for a reply... */
12946   W;
12947
12948   /* NOTREACHED */
12949   return 0;
12950 }
12951
12952 static int
12953 api_lisp_add_del_local_eid (vat_main_t * vam)
12954 {
12955   unformat_input_t *input = vam->input;
12956   vl_api_lisp_add_del_local_eid_t *mp;
12957   f64 timeout = ~0;
12958   u8 is_add = 1;
12959   u8 eid_set = 0;
12960   lisp_eid_vat_t _eid, *eid = &_eid;
12961   u8 *locator_set_name = 0;
12962   u8 locator_set_name_set = 0;
12963   u32 vni = 0;
12964
12965   /* Parse args required to build the message */
12966   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12967     {
12968       if (unformat (input, "del"))
12969         {
12970           is_add = 0;
12971         }
12972       else if (unformat (input, "vni %d", &vni))
12973         {
12974           ;
12975         }
12976       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12977         {
12978           eid_set = 1;
12979         }
12980       else if (unformat (input, "locator-set %s", &locator_set_name))
12981         {
12982           locator_set_name_set = 1;
12983         }
12984       else
12985         break;
12986     }
12987
12988   if (locator_set_name_set == 0)
12989     {
12990       errmsg ("missing locator-set name\n");
12991       return -99;
12992     }
12993
12994   if (0 == eid_set)
12995     {
12996       errmsg ("EID address not set!");
12997       vec_free (locator_set_name);
12998       return -99;
12999     }
13000
13001   if (vec_len (locator_set_name) > 64)
13002     {
13003       errmsg ("locator-set name too long\n");
13004       vec_free (locator_set_name);
13005       return -99;
13006     }
13007   vec_add1 (locator_set_name, 0);
13008
13009   /* Construct the API message */
13010   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13011
13012   mp->is_add = is_add;
13013   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13014   mp->eid_type = eid->type;
13015   mp->prefix_len = eid->len;
13016   mp->vni = clib_host_to_net_u32 (vni);
13017   clib_memcpy (mp->locator_set_name, locator_set_name,
13018                vec_len (locator_set_name));
13019
13020   vec_free (locator_set_name);
13021
13022   /* send it... */
13023   S;
13024
13025   /* Wait for a reply... */
13026   W;
13027
13028   /* NOTREACHED */
13029   return 0;
13030 }
13031
13032 /* *INDENT-OFF* */
13033 /** Used for transferring locators via VPP API */
13034 typedef CLIB_PACKED(struct
13035 {
13036   u8 is_ip4; /**< is locator an IPv4 address? */
13037   u8 priority; /**< locator priority */
13038   u8 weight;   /**< locator weight */
13039   u8 addr[16]; /**< IPv4/IPv6 address */
13040 }) rloc_t;
13041 /* *INDENT-ON* */
13042
13043 static int
13044 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13045 {
13046   unformat_input_t *input = vam->input;
13047   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13048   f64 timeout = ~0;
13049   u8 is_add = 1;
13050   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13051   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13052   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13053   u32 action = ~0, p, w;
13054   ip4_address_t rmt_rloc4, lcl_rloc4;
13055   ip6_address_t rmt_rloc6, lcl_rloc6;
13056   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13057
13058   memset (&rloc, 0, sizeof (rloc));
13059
13060   /* Parse args required to build the message */
13061   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13062     {
13063       if (unformat (input, "del"))
13064         {
13065           is_add = 0;
13066         }
13067       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
13068         {
13069           rmt_eid_set = 1;
13070         }
13071       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
13072         {
13073           lcl_eid_set = 1;
13074         }
13075       else if (unformat (input, "p %d w %d", &p, &w))
13076         {
13077           if (!curr_rloc)
13078             {
13079               errmsg ("No RLOC configured for setting priority/weight!");
13080               return -99;
13081             }
13082           curr_rloc->priority = p;
13083           curr_rloc->weight = w;
13084         }
13085       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13086                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13087         {
13088           rloc.is_ip4 = 1;
13089
13090           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13091           rloc.priority = rloc.weight = 0;
13092           vec_add1 (lcl_locs, rloc);
13093
13094           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13095           vec_add1 (rmt_locs, rloc);
13096           /* priority and weight saved in rmt loc */
13097           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13098         }
13099       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13100                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13101         {
13102           rloc.is_ip4 = 0;
13103           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13104           rloc.priority = rloc.weight = 0;
13105           vec_add1 (lcl_locs, rloc);
13106
13107           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13108           vec_add1 (rmt_locs, rloc);
13109           /* priority and weight saved in rmt loc */
13110           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13111         }
13112       else if (unformat (input, "action %d", &action))
13113         {
13114           ;
13115         }
13116       else
13117         {
13118           clib_warning ("parse error '%U'", format_unformat_error, input);
13119           return -99;
13120         }
13121     }
13122
13123   if (!rmt_eid_set)
13124     {
13125       errmsg ("remote eid addresses not set\n");
13126       return -99;
13127     }
13128
13129   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13130     {
13131       errmsg ("eid types don't match\n");
13132       return -99;
13133     }
13134
13135   if (0 == rmt_locs && (u32) ~ 0 == action)
13136     {
13137       errmsg ("action not set for negative mapping\n");
13138       return -99;
13139     }
13140
13141   /* Construct the API message */
13142   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13143
13144   mp->is_add = is_add;
13145   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13146   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13147   mp->eid_type = rmt_eid->type;
13148   mp->rmt_len = rmt_eid->len;
13149   mp->lcl_len = lcl_eid->len;
13150   mp->action = action;
13151
13152   if (0 != rmt_locs && 0 != lcl_locs)
13153     {
13154       mp->loc_num = vec_len (rmt_locs);
13155       clib_memcpy (mp->lcl_locs, lcl_locs,
13156                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13157       clib_memcpy (mp->rmt_locs, rmt_locs,
13158                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13159     }
13160   vec_free (lcl_locs);
13161   vec_free (rmt_locs);
13162
13163   /* send it... */
13164   S;
13165
13166   /* Wait for a reply... */
13167   W;
13168
13169   /* NOTREACHED */
13170   return 0;
13171 }
13172
13173 static int
13174 api_lisp_add_del_map_resolver (vat_main_t * vam)
13175 {
13176   unformat_input_t *input = vam->input;
13177   vl_api_lisp_add_del_map_resolver_t *mp;
13178   f64 timeout = ~0;
13179   u8 is_add = 1;
13180   u8 ipv4_set = 0;
13181   u8 ipv6_set = 0;
13182   ip4_address_t ipv4;
13183   ip6_address_t ipv6;
13184
13185   /* Parse args required to build the message */
13186   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13187     {
13188       if (unformat (input, "del"))
13189         {
13190           is_add = 0;
13191         }
13192       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13193         {
13194           ipv4_set = 1;
13195         }
13196       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13197         {
13198           ipv6_set = 1;
13199         }
13200       else
13201         break;
13202     }
13203
13204   if (ipv4_set && ipv6_set)
13205     {
13206       errmsg ("both eid v4 and v6 addresses set\n");
13207       return -99;
13208     }
13209
13210   if (!ipv4_set && !ipv6_set)
13211     {
13212       errmsg ("eid addresses not set\n");
13213       return -99;
13214     }
13215
13216   /* Construct the API message */
13217   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13218
13219   mp->is_add = is_add;
13220   if (ipv6_set)
13221     {
13222       mp->is_ipv6 = 1;
13223       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13224     }
13225   else
13226     {
13227       mp->is_ipv6 = 0;
13228       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13229     }
13230
13231   /* send it... */
13232   S;
13233
13234   /* Wait for a reply... */
13235   W;
13236
13237   /* NOTREACHED */
13238   return 0;
13239 }
13240
13241 static int
13242 api_lisp_gpe_enable_disable (vat_main_t * vam)
13243 {
13244   unformat_input_t *input = vam->input;
13245   vl_api_lisp_gpe_enable_disable_t *mp;
13246   f64 timeout = ~0;
13247   u8 is_set = 0;
13248   u8 is_en = 1;
13249
13250   /* Parse args required to build the message */
13251   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13252     {
13253       if (unformat (input, "enable"))
13254         {
13255           is_set = 1;
13256           is_en = 1;
13257         }
13258       else if (unformat (input, "disable"))
13259         {
13260           is_set = 1;
13261           is_en = 0;
13262         }
13263       else
13264         break;
13265     }
13266
13267   if (is_set == 0)
13268     {
13269       errmsg ("Value not set\n");
13270       return -99;
13271     }
13272
13273   /* Construct the API message */
13274   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13275
13276   mp->is_en = is_en;
13277
13278   /* send it... */
13279   S;
13280
13281   /* Wait for a reply... */
13282   W;
13283
13284   /* NOTREACHED */
13285   return 0;
13286 }
13287
13288 static int
13289 api_lisp_enable_disable (vat_main_t * vam)
13290 {
13291   unformat_input_t *input = vam->input;
13292   vl_api_lisp_enable_disable_t *mp;
13293   f64 timeout = ~0;
13294   u8 is_set = 0;
13295   u8 is_en = 0;
13296
13297   /* Parse args required to build the message */
13298   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13299     {
13300       if (unformat (input, "enable"))
13301         {
13302           is_set = 1;
13303           is_en = 1;
13304         }
13305       else if (unformat (input, "disable"))
13306         {
13307           is_set = 1;
13308         }
13309       else
13310         break;
13311     }
13312
13313   if (!is_set)
13314     {
13315       errmsg ("Value not set\n");
13316       return -99;
13317     }
13318
13319   /* Construct the API message */
13320   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13321
13322   mp->is_en = is_en;
13323
13324   /* send it... */
13325   S;
13326
13327   /* Wait for a reply... */
13328   W;
13329
13330   /* NOTREACHED */
13331   return 0;
13332 }
13333
13334 static int
13335 api_show_lisp_map_request_mode (vat_main_t * vam)
13336 {
13337   f64 timeout = ~0;
13338   vl_api_show_lisp_map_request_mode_t *mp;
13339
13340   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13341
13342   /* send */
13343   S;
13344
13345   /* wait for reply */
13346   W;
13347
13348   return 0;
13349 }
13350
13351 static int
13352 api_lisp_map_request_mode (vat_main_t * vam)
13353 {
13354   f64 timeout = ~0;
13355   unformat_input_t *input = vam->input;
13356   vl_api_lisp_map_request_mode_t *mp;
13357   u8 mode = 0;
13358
13359   /* Parse args required to build the message */
13360   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13361     {
13362       if (unformat (input, "dst-only"))
13363         mode = 0;
13364       else if (unformat (input, "src-dst"))
13365         mode = 1;
13366       else
13367         {
13368           errmsg ("parse error '%U'", format_unformat_error, input);
13369           return -99;
13370         }
13371     }
13372
13373   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13374
13375   mp->mode = mode;
13376
13377   /* send */
13378   S;
13379
13380   /* wait for reply */
13381   W;
13382
13383   /* notreached */
13384   return 0;
13385 }
13386
13387 /**
13388  * Enable/disable LISP proxy ITR.
13389  *
13390  * @param vam vpp API test context
13391  * @return return code
13392  */
13393 static int
13394 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13395 {
13396   f64 timeout = ~0;
13397   u8 ls_name_set = 0;
13398   unformat_input_t *input = vam->input;
13399   vl_api_lisp_pitr_set_locator_set_t *mp;
13400   u8 is_add = 1;
13401   u8 *ls_name = 0;
13402
13403   /* Parse args required to build the message */
13404   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13405     {
13406       if (unformat (input, "del"))
13407         is_add = 0;
13408       else if (unformat (input, "locator-set %s", &ls_name))
13409         ls_name_set = 1;
13410       else
13411         {
13412           errmsg ("parse error '%U'", format_unformat_error, input);
13413           return -99;
13414         }
13415     }
13416
13417   if (!ls_name_set)
13418     {
13419       errmsg ("locator-set name not set!");
13420       return -99;
13421     }
13422
13423   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13424
13425   mp->is_add = is_add;
13426   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13427   vec_free (ls_name);
13428
13429   /* send */
13430   S;
13431
13432   /* wait for reply */
13433   W;
13434
13435   /* notreached */
13436   return 0;
13437 }
13438
13439 static int
13440 api_show_lisp_pitr (vat_main_t * vam)
13441 {
13442   vl_api_show_lisp_pitr_t *mp;
13443   f64 timeout = ~0;
13444
13445   if (!vam->json_output)
13446     {
13447       fformat (vam->ofp, "%=20s\n", "lisp status:");
13448     }
13449
13450   M (SHOW_LISP_PITR, show_lisp_pitr);
13451   /* send it... */
13452   S;
13453
13454   /* Wait for a reply... */
13455   W;
13456
13457   /* NOTREACHED */
13458   return 0;
13459 }
13460
13461 /**
13462  * Add/delete mapping between vni and vrf
13463  */
13464 static int
13465 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13466 {
13467   f64 timeout = ~0;
13468   unformat_input_t *input = vam->input;
13469   vl_api_lisp_eid_table_add_del_map_t *mp;
13470   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13471   u32 vni, vrf, bd_index;
13472
13473   /* Parse args required to build the message */
13474   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13475     {
13476       if (unformat (input, "del"))
13477         is_add = 0;
13478       else if (unformat (input, "vrf %d", &vrf))
13479         vrf_set = 1;
13480       else if (unformat (input, "bd_index %d", &bd_index))
13481         bd_index_set = 1;
13482       else if (unformat (input, "vni %d", &vni))
13483         vni_set = 1;
13484       else
13485         break;
13486     }
13487
13488   if (!vni_set || (!vrf_set && !bd_index_set))
13489     {
13490       errmsg ("missing arguments!");
13491       return -99;
13492     }
13493
13494   if (vrf_set && bd_index_set)
13495     {
13496       errmsg ("error: both vrf and bd entered!");
13497       return -99;
13498     }
13499
13500   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13501
13502   mp->is_add = is_add;
13503   mp->vni = htonl (vni);
13504   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13505   mp->is_l2 = bd_index_set;
13506
13507   /* send */
13508   S;
13509
13510   /* wait for reply */
13511   W;
13512
13513   /* notreached */
13514   return 0;
13515 }
13516
13517 uword
13518 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13519 {
13520   u32 *action = va_arg (*args, u32 *);
13521   u8 *s = 0;
13522
13523   if (unformat (input, "%s", &s))
13524     {
13525       if (!strcmp ((char *) s, "no-action"))
13526         action[0] = 0;
13527       else if (!strcmp ((char *) s, "natively-forward"))
13528         action[0] = 1;
13529       else if (!strcmp ((char *) s, "send-map-request"))
13530         action[0] = 2;
13531       else if (!strcmp ((char *) s, "drop"))
13532         action[0] = 3;
13533       else
13534         {
13535           clib_warning ("invalid action: '%s'", s);
13536           action[0] = 3;
13537         }
13538     }
13539   else
13540     return 0;
13541
13542   vec_free (s);
13543   return 1;
13544 }
13545
13546 /**
13547  * Add/del remote mapping to/from LISP control plane
13548  *
13549  * @param vam vpp API test context
13550  * @return return code
13551  */
13552 static int
13553 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13554 {
13555   unformat_input_t *input = vam->input;
13556   vl_api_lisp_add_del_remote_mapping_t *mp;
13557   f64 timeout = ~0;
13558   u32 vni = 0;
13559   lisp_eid_vat_t _eid, *eid = &_eid;
13560   lisp_eid_vat_t _seid, *seid = &_seid;
13561   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13562   u32 action = ~0, p, w, data_len;
13563   ip4_address_t rloc4;
13564   ip6_address_t rloc6;
13565   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13566
13567   memset (&rloc, 0, sizeof (rloc));
13568
13569   /* Parse args required to build the message */
13570   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13571     {
13572       if (unformat (input, "del-all"))
13573         {
13574           del_all = 1;
13575         }
13576       else if (unformat (input, "del"))
13577         {
13578           is_add = 0;
13579         }
13580       else if (unformat (input, "add"))
13581         {
13582           is_add = 1;
13583         }
13584       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13585         {
13586           eid_set = 1;
13587         }
13588       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13589         {
13590           seid_set = 1;
13591         }
13592       else if (unformat (input, "vni %d", &vni))
13593         {
13594           ;
13595         }
13596       else if (unformat (input, "p %d w %d", &p, &w))
13597         {
13598           if (!curr_rloc)
13599             {
13600               errmsg ("No RLOC configured for setting priority/weight!");
13601               return -99;
13602             }
13603           curr_rloc->priority = p;
13604           curr_rloc->weight = w;
13605         }
13606       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13607         {
13608           rloc.is_ip4 = 1;
13609           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13610           vec_add1 (rlocs, rloc);
13611           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13612         }
13613       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13614         {
13615           rloc.is_ip4 = 0;
13616           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13617           vec_add1 (rlocs, rloc);
13618           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13619         }
13620       else if (unformat (input, "action %U",
13621                          unformat_negative_mapping_action, &action))
13622         {
13623           ;
13624         }
13625       else
13626         {
13627           clib_warning ("parse error '%U'", format_unformat_error, input);
13628           return -99;
13629         }
13630     }
13631
13632   if (0 == eid_set)
13633     {
13634       errmsg ("missing params!");
13635       return -99;
13636     }
13637
13638   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13639     {
13640       errmsg ("no action set for negative map-reply!");
13641       return -99;
13642     }
13643
13644   data_len = vec_len (rlocs) * sizeof (rloc_t);
13645
13646   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13647   mp->is_add = is_add;
13648   mp->vni = htonl (vni);
13649   mp->action = (u8) action;
13650   mp->is_src_dst = seid_set;
13651   mp->eid_len = eid->len;
13652   mp->seid_len = seid->len;
13653   mp->del_all = del_all;
13654   mp->eid_type = eid->type;
13655   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13656   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13657
13658   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13659   clib_memcpy (mp->rlocs, rlocs, data_len);
13660   vec_free (rlocs);
13661
13662   /* send it... */
13663   S;
13664
13665   /* Wait for a reply... */
13666   W;
13667
13668   /* NOTREACHED */
13669   return 0;
13670 }
13671
13672 /**
13673  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13674  * forwarding entries in data-plane accordingly.
13675  *
13676  * @param vam vpp API test context
13677  * @return return code
13678  */
13679 static int
13680 api_lisp_add_del_adjacency (vat_main_t * vam)
13681 {
13682   unformat_input_t *input = vam->input;
13683   vl_api_lisp_add_del_adjacency_t *mp;
13684   f64 timeout = ~0;
13685   u32 vni = 0;
13686   ip4_address_t leid4, reid4;
13687   ip6_address_t leid6, reid6;
13688   u8 reid_mac[6] = { 0 };
13689   u8 leid_mac[6] = { 0 };
13690   u8 reid_type, leid_type;
13691   u32 leid_len = 0, reid_len = 0, len;
13692   u8 is_add = 1;
13693
13694   leid_type = reid_type = (u8) ~ 0;
13695
13696   /* Parse args required to build the message */
13697   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13698     {
13699       if (unformat (input, "del"))
13700         {
13701           is_add = 0;
13702         }
13703       else if (unformat (input, "add"))
13704         {
13705           is_add = 1;
13706         }
13707       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13708                          &reid4, &len))
13709         {
13710           reid_type = 0;        /* ipv4 */
13711           reid_len = len;
13712         }
13713       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13714                          &reid6, &len))
13715         {
13716           reid_type = 1;        /* ipv6 */
13717           reid_len = len;
13718         }
13719       else if (unformat (input, "reid %U", unformat_ethernet_address,
13720                          reid_mac))
13721         {
13722           reid_type = 2;        /* mac */
13723         }
13724       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13725                          &leid4, &len))
13726         {
13727           leid_type = 0;        /* ipv4 */
13728           leid_len = len;
13729         }
13730       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13731                          &leid6, &len))
13732         {
13733           leid_type = 1;        /* ipv6 */
13734           leid_len = len;
13735         }
13736       else if (unformat (input, "leid %U", unformat_ethernet_address,
13737                          leid_mac))
13738         {
13739           leid_type = 2;        /* mac */
13740         }
13741       else if (unformat (input, "vni %d", &vni))
13742         {
13743           ;
13744         }
13745       else
13746         {
13747           errmsg ("parse error '%U'", format_unformat_error, input);
13748           return -99;
13749         }
13750     }
13751
13752   if ((u8) ~ 0 == reid_type)
13753     {
13754       errmsg ("missing params!");
13755       return -99;
13756     }
13757
13758   if (leid_type != reid_type)
13759     {
13760       errmsg ("remote and local EIDs are of different types!");
13761       return -99;
13762     }
13763
13764   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13765   mp->is_add = is_add;
13766   mp->vni = htonl (vni);
13767   mp->leid_len = leid_len;
13768   mp->reid_len = reid_len;
13769   mp->eid_type = reid_type;
13770
13771   switch (mp->eid_type)
13772     {
13773     case 0:
13774       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13775       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13776       break;
13777     case 1:
13778       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13779       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13780       break;
13781     case 2:
13782       clib_memcpy (mp->leid, leid_mac, 6);
13783       clib_memcpy (mp->reid, reid_mac, 6);
13784       break;
13785     default:
13786       errmsg ("unknown EID type %d!", mp->eid_type);
13787       return 0;
13788     }
13789
13790   /* send it... */
13791   S;
13792
13793   /* Wait for a reply... */
13794   W;
13795
13796   /* NOTREACHED */
13797   return 0;
13798 }
13799
13800 static int
13801 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13802 {
13803   unformat_input_t *input = vam->input;
13804   vl_api_lisp_gpe_add_del_iface_t *mp;
13805   f64 timeout = ~0;
13806   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13807   u32 dp_table = 0, vni = 0;
13808
13809   /* Parse args required to build the message */
13810   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13811     {
13812       if (unformat (input, "up"))
13813         {
13814           action_set = 1;
13815           is_add = 1;
13816         }
13817       else if (unformat (input, "down"))
13818         {
13819           action_set = 1;
13820           is_add = 0;
13821         }
13822       else if (unformat (input, "table_id %d", &dp_table))
13823         {
13824           dp_table_set = 1;
13825         }
13826       else if (unformat (input, "bd_id %d", &dp_table))
13827         {
13828           dp_table_set = 1;
13829           is_l2 = 1;
13830         }
13831       else if (unformat (input, "vni %d", &vni))
13832         {
13833           vni_set = 1;
13834         }
13835       else
13836         break;
13837     }
13838
13839   if (action_set == 0)
13840     {
13841       errmsg ("Action not set\n");
13842       return -99;
13843     }
13844   if (dp_table_set == 0 || vni_set == 0)
13845     {
13846       errmsg ("vni and dp_table must be set\n");
13847       return -99;
13848     }
13849
13850   /* Construct the API message */
13851   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13852
13853   mp->is_add = is_add;
13854   mp->dp_table = dp_table;
13855   mp->is_l2 = is_l2;
13856   mp->vni = vni;
13857
13858   /* send it... */
13859   S;
13860
13861   /* Wait for a reply... */
13862   W;
13863
13864   /* NOTREACHED */
13865   return 0;
13866 }
13867
13868 /**
13869  * Add/del map request itr rlocs from LISP control plane and updates
13870  *
13871  * @param vam vpp API test context
13872  * @return return code
13873  */
13874 static int
13875 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13876 {
13877   unformat_input_t *input = vam->input;
13878   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13879   f64 timeout = ~0;
13880   u8 *locator_set_name = 0;
13881   u8 locator_set_name_set = 0;
13882   u8 is_add = 1;
13883
13884   /* Parse args required to build the message */
13885   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13886     {
13887       if (unformat (input, "del"))
13888         {
13889           is_add = 0;
13890         }
13891       else if (unformat (input, "%_%v%_", &locator_set_name))
13892         {
13893           locator_set_name_set = 1;
13894         }
13895       else
13896         {
13897           clib_warning ("parse error '%U'", format_unformat_error, input);
13898           return -99;
13899         }
13900     }
13901
13902   if (is_add && !locator_set_name_set)
13903     {
13904       errmsg ("itr-rloc is not set!");
13905       return -99;
13906     }
13907
13908   if (is_add && vec_len (locator_set_name) > 64)
13909     {
13910       errmsg ("itr-rloc locator-set name too long\n");
13911       vec_free (locator_set_name);
13912       return -99;
13913     }
13914
13915   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13916   mp->is_add = is_add;
13917   if (is_add)
13918     {
13919       clib_memcpy (mp->locator_set_name, locator_set_name,
13920                    vec_len (locator_set_name));
13921     }
13922   else
13923     {
13924       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13925     }
13926   vec_free (locator_set_name);
13927
13928   /* send it... */
13929   S;
13930
13931   /* Wait for a reply... */
13932   W;
13933
13934   /* NOTREACHED */
13935   return 0;
13936 }
13937
13938 static int
13939 api_lisp_locator_dump (vat_main_t * vam)
13940 {
13941   unformat_input_t *input = vam->input;
13942   vl_api_lisp_locator_dump_t *mp;
13943   f64 timeout = ~0;
13944   u8 is_index_set = 0, is_name_set = 0;
13945   u8 *ls_name = 0;
13946   u32 ls_index = ~0;
13947
13948   /* Parse args required to build the message */
13949   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13950     {
13951       if (unformat (input, "ls_name %_%v%_", &ls_name))
13952         {
13953           is_name_set = 1;
13954         }
13955       else if (unformat (input, "ls_index %d", &ls_index))
13956         {
13957           is_index_set = 1;
13958         }
13959       else
13960         {
13961           errmsg ("parse error '%U'", format_unformat_error, input);
13962           return -99;
13963         }
13964     }
13965
13966   if (!is_index_set && !is_name_set)
13967     {
13968       errmsg ("error: expected one of index or name!\n");
13969       return -99;
13970     }
13971
13972   if (is_index_set && is_name_set)
13973     {
13974       errmsg ("error: only one param expected!\n");
13975       return -99;
13976     }
13977
13978   if (vec_len (ls_name) > 62)
13979     {
13980       errmsg ("error: locator set name too long!");
13981       return -99;
13982     }
13983
13984   if (!vam->json_output)
13985     {
13986       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13987                "weight");
13988     }
13989
13990   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13991   mp->is_index_set = is_index_set;
13992
13993   if (is_index_set)
13994     mp->ls_index = clib_host_to_net_u32 (ls_index);
13995   else
13996     {
13997       vec_add1 (ls_name, 0);
13998       strncpy ((char *) mp->ls_name, (char *) ls_name,
13999                sizeof (mp->ls_name) - 1);
14000     }
14001
14002   /* send it... */
14003   S;
14004
14005   /* Use a control ping for synchronization */
14006   {
14007     vl_api_control_ping_t *mp;
14008     M (CONTROL_PING, control_ping);
14009     S;
14010   }
14011   /* Wait for a reply... */
14012   W;
14013
14014   /* NOTREACHED */
14015   return 0;
14016 }
14017
14018 static int
14019 api_lisp_locator_set_dump (vat_main_t * vam)
14020 {
14021   vl_api_lisp_locator_set_dump_t *mp;
14022   unformat_input_t *input = vam->input;
14023   f64 timeout = ~0;
14024   u8 filter = 0;
14025
14026   /* Parse args required to build the message */
14027   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14028     {
14029       if (unformat (input, "local"))
14030         {
14031           filter = 1;
14032         }
14033       else if (unformat (input, "remote"))
14034         {
14035           filter = 2;
14036         }
14037       else
14038         {
14039           errmsg ("parse error '%U'", format_unformat_error, input);
14040           return -99;
14041         }
14042     }
14043
14044   if (!vam->json_output)
14045     {
14046       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
14047     }
14048
14049   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14050
14051   mp->filter = filter;
14052
14053   /* send it... */
14054   S;
14055
14056   /* Use a control ping for synchronization */
14057   {
14058     vl_api_control_ping_t *mp;
14059     M (CONTROL_PING, control_ping);
14060     S;
14061   }
14062   /* Wait for a reply... */
14063   W;
14064
14065   /* NOTREACHED */
14066   return 0;
14067 }
14068
14069 static int
14070 api_lisp_eid_table_map_dump (vat_main_t * vam)
14071 {
14072   u8 is_l2 = 0;
14073   u8 mode_set = 0;
14074   unformat_input_t *input = vam->input;
14075   vl_api_lisp_eid_table_map_dump_t *mp;
14076   f64 timeout = ~0;
14077
14078   /* Parse args required to build the message */
14079   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14080     {
14081       if (unformat (input, "l2"))
14082         {
14083           is_l2 = 1;
14084           mode_set = 1;
14085         }
14086       else if (unformat (input, "l3"))
14087         {
14088           is_l2 = 0;
14089           mode_set = 1;
14090         }
14091       else
14092         {
14093           errmsg ("parse error '%U'", format_unformat_error, input);
14094           return -99;
14095         }
14096     }
14097
14098   if (!mode_set)
14099     {
14100       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
14101       return -99;
14102     }
14103
14104   if (!vam->json_output)
14105     {
14106       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
14107     }
14108
14109   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14110   mp->is_l2 = is_l2;
14111
14112   /* send it... */
14113   S;
14114
14115   /* Use a control ping for synchronization */
14116   {
14117     vl_api_control_ping_t *mp;
14118     M (CONTROL_PING, control_ping);
14119     S;
14120   }
14121   /* Wait for a reply... */
14122   W;
14123
14124   /* NOTREACHED */
14125   return 0;
14126 }
14127
14128 static int
14129 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14130 {
14131   vl_api_lisp_eid_table_vni_dump_t *mp;
14132   f64 timeout = ~0;
14133
14134   if (!vam->json_output)
14135     {
14136       fformat (vam->ofp, "VNI\n");
14137     }
14138
14139   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14140
14141   /* send it... */
14142   S;
14143
14144   /* Use a control ping for synchronization */
14145   {
14146     vl_api_control_ping_t *mp;
14147     M (CONTROL_PING, control_ping);
14148     S;
14149   }
14150   /* Wait for a reply... */
14151   W;
14152
14153   /* NOTREACHED */
14154   return 0;
14155 }
14156
14157 static int
14158 api_lisp_eid_table_dump (vat_main_t * vam)
14159 {
14160   unformat_input_t *i = vam->input;
14161   vl_api_lisp_eid_table_dump_t *mp;
14162   f64 timeout = ~0;
14163   struct in_addr ip4;
14164   struct in6_addr ip6;
14165   u8 mac[6];
14166   u8 eid_type = ~0, eid_set = 0;
14167   u32 prefix_length = ~0, t, vni = 0;
14168   u8 filter = 0;
14169
14170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14171     {
14172       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14173         {
14174           eid_set = 1;
14175           eid_type = 0;
14176           prefix_length = t;
14177         }
14178       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14179         {
14180           eid_set = 1;
14181           eid_type = 1;
14182           prefix_length = t;
14183         }
14184       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14185         {
14186           eid_set = 1;
14187           eid_type = 2;
14188         }
14189       else if (unformat (i, "vni %d", &t))
14190         {
14191           vni = t;
14192         }
14193       else if (unformat (i, "local"))
14194         {
14195           filter = 1;
14196         }
14197       else if (unformat (i, "remote"))
14198         {
14199           filter = 2;
14200         }
14201       else
14202         {
14203           errmsg ("parse error '%U'", format_unformat_error, i);
14204           return -99;
14205         }
14206     }
14207
14208   if (!vam->json_output)
14209     {
14210       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
14211                "ls_index", "ttl", "authoritative");
14212     }
14213
14214   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14215
14216   mp->filter = filter;
14217   if (eid_set)
14218     {
14219       mp->eid_set = 1;
14220       mp->vni = htonl (vni);
14221       mp->eid_type = eid_type;
14222       switch (eid_type)
14223         {
14224         case 0:
14225           mp->prefix_length = prefix_length;
14226           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14227           break;
14228         case 1:
14229           mp->prefix_length = prefix_length;
14230           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14231           break;
14232         case 2:
14233           clib_memcpy (mp->eid, mac, sizeof (mac));
14234           break;
14235         default:
14236           errmsg ("unknown EID type %d!", eid_type);
14237           return -99;
14238         }
14239     }
14240
14241   /* send it... */
14242   S;
14243
14244   /* Use a control ping for synchronization */
14245   {
14246     vl_api_control_ping_t *mp;
14247     M (CONTROL_PING, control_ping);
14248     S;
14249   }
14250
14251   /* Wait for a reply... */
14252   W;
14253
14254   /* NOTREACHED */
14255   return 0;
14256 }
14257
14258 static int
14259 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14260 {
14261   vl_api_lisp_gpe_tunnel_dump_t *mp;
14262   f64 timeout = ~0;
14263
14264   if (!vam->json_output)
14265     {
14266       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14267                "%=16s%=16s%=16s%=16s%=16s\n",
14268                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14269                "Decap next", "Lisp version", "Flags", "Next protocol",
14270                "ver_res", "res", "iid");
14271     }
14272
14273   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14274   /* send it... */
14275   S;
14276
14277   /* Use a control ping for synchronization */
14278   {
14279     vl_api_control_ping_t *mp;
14280     M (CONTROL_PING, control_ping);
14281     S;
14282   }
14283   /* Wait for a reply... */
14284   W;
14285
14286   /* NOTREACHED */
14287   return 0;
14288 }
14289
14290 static int
14291 api_lisp_adjacencies_get (vat_main_t * vam)
14292 {
14293   unformat_input_t *i = vam->input;
14294   vl_api_lisp_adjacencies_get_t *mp;
14295   f64 timeout = ~0;
14296   u8 vni_set = 0;
14297   u32 vni = ~0;
14298
14299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14300     {
14301       if (unformat (i, "vni %d", &vni))
14302         {
14303           vni_set = 1;
14304         }
14305       else
14306         {
14307           errmsg ("parse error '%U'\n", format_unformat_error, i);
14308           return -99;
14309         }
14310     }
14311
14312   if (!vni_set)
14313     {
14314       errmsg ("vni not set!\n");
14315       return -99;
14316     }
14317
14318   if (!vam->json_output)
14319     {
14320       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14321     }
14322
14323   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14324   mp->vni = clib_host_to_net_u32 (vni);
14325
14326   /* send it... */
14327   S;
14328
14329   /* Wait for a reply... */
14330   W;
14331
14332   /* NOTREACHED */
14333   return 0;
14334 }
14335
14336 static int
14337 api_lisp_map_resolver_dump (vat_main_t * vam)
14338 {
14339   vl_api_lisp_map_resolver_dump_t *mp;
14340   f64 timeout = ~0;
14341
14342   if (!vam->json_output)
14343     {
14344       fformat (vam->ofp, "%=20s\n", "Map resolver");
14345     }
14346
14347   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14348   /* send it... */
14349   S;
14350
14351   /* Use a control ping for synchronization */
14352   {
14353     vl_api_control_ping_t *mp;
14354     M (CONTROL_PING, control_ping);
14355     S;
14356   }
14357   /* Wait for a reply... */
14358   W;
14359
14360   /* NOTREACHED */
14361   return 0;
14362 }
14363
14364 static int
14365 api_show_lisp_status (vat_main_t * vam)
14366 {
14367   vl_api_show_lisp_status_t *mp;
14368   f64 timeout = ~0;
14369
14370   if (!vam->json_output)
14371     {
14372       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14373     }
14374
14375   M (SHOW_LISP_STATUS, show_lisp_status);
14376   /* send it... */
14377   S;
14378   /* Wait for a reply... */
14379   W;
14380
14381   /* NOTREACHED */
14382   return 0;
14383 }
14384
14385 static int
14386 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14387 {
14388   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14389   f64 timeout = ~0;
14390
14391   if (!vam->json_output)
14392     {
14393       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14394     }
14395
14396   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14397   /* send it... */
14398   S;
14399   /* Wait for a reply... */
14400   W;
14401
14402   /* NOTREACHED */
14403   return 0;
14404 }
14405
14406 static int
14407 api_af_packet_create (vat_main_t * vam)
14408 {
14409   unformat_input_t *i = vam->input;
14410   vl_api_af_packet_create_t *mp;
14411   f64 timeout;
14412   u8 *host_if_name = 0;
14413   u8 hw_addr[6];
14414   u8 random_hw_addr = 1;
14415
14416   memset (hw_addr, 0, sizeof (hw_addr));
14417
14418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14419     {
14420       if (unformat (i, "name %s", &host_if_name))
14421         vec_add1 (host_if_name, 0);
14422       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14423         random_hw_addr = 0;
14424       else
14425         break;
14426     }
14427
14428   if (!vec_len (host_if_name))
14429     {
14430       errmsg ("host-interface name must be specified");
14431       return -99;
14432     }
14433
14434   if (vec_len (host_if_name) > 64)
14435     {
14436       errmsg ("host-interface name too long");
14437       return -99;
14438     }
14439
14440   M (AF_PACKET_CREATE, af_packet_create);
14441
14442   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14443   clib_memcpy (mp->hw_addr, hw_addr, 6);
14444   mp->use_random_hw_addr = random_hw_addr;
14445   vec_free (host_if_name);
14446
14447   S;
14448   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14449   /* NOTREACHED */
14450   return 0;
14451 }
14452
14453 static int
14454 api_af_packet_delete (vat_main_t * vam)
14455 {
14456   unformat_input_t *i = vam->input;
14457   vl_api_af_packet_delete_t *mp;
14458   f64 timeout;
14459   u8 *host_if_name = 0;
14460
14461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14462     {
14463       if (unformat (i, "name %s", &host_if_name))
14464         vec_add1 (host_if_name, 0);
14465       else
14466         break;
14467     }
14468
14469   if (!vec_len (host_if_name))
14470     {
14471       errmsg ("host-interface name must be specified");
14472       return -99;
14473     }
14474
14475   if (vec_len (host_if_name) > 64)
14476     {
14477       errmsg ("host-interface name too long");
14478       return -99;
14479     }
14480
14481   M (AF_PACKET_DELETE, af_packet_delete);
14482
14483   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14484   vec_free (host_if_name);
14485
14486   S;
14487   W;
14488   /* NOTREACHED */
14489   return 0;
14490 }
14491
14492 static int
14493 api_policer_add_del (vat_main_t * vam)
14494 {
14495   unformat_input_t *i = vam->input;
14496   vl_api_policer_add_del_t *mp;
14497   f64 timeout;
14498   u8 is_add = 1;
14499   u8 *name = 0;
14500   u32 cir = 0;
14501   u32 eir = 0;
14502   u64 cb = 0;
14503   u64 eb = 0;
14504   u8 rate_type = 0;
14505   u8 round_type = 0;
14506   u8 type = 0;
14507   u8 color_aware = 0;
14508   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14509
14510   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14511   conform_action.dscp = 0;
14512   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14513   exceed_action.dscp = 0;
14514   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14515   violate_action.dscp = 0;
14516
14517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14518     {
14519       if (unformat (i, "del"))
14520         is_add = 0;
14521       else if (unformat (i, "name %s", &name))
14522         vec_add1 (name, 0);
14523       else if (unformat (i, "cir %u", &cir))
14524         ;
14525       else if (unformat (i, "eir %u", &eir))
14526         ;
14527       else if (unformat (i, "cb %u", &cb))
14528         ;
14529       else if (unformat (i, "eb %u", &eb))
14530         ;
14531       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14532                          &rate_type))
14533         ;
14534       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14535                          &round_type))
14536         ;
14537       else if (unformat (i, "type %U", unformat_policer_type, &type))
14538         ;
14539       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14540                          &conform_action))
14541         ;
14542       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14543                          &exceed_action))
14544         ;
14545       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14546                          &violate_action))
14547         ;
14548       else if (unformat (i, "color-aware"))
14549         color_aware = 1;
14550       else
14551         break;
14552     }
14553
14554   if (!vec_len (name))
14555     {
14556       errmsg ("policer name must be specified");
14557       return -99;
14558     }
14559
14560   if (vec_len (name) > 64)
14561     {
14562       errmsg ("policer name too long");
14563       return -99;
14564     }
14565
14566   M (POLICER_ADD_DEL, policer_add_del);
14567
14568   clib_memcpy (mp->name, name, vec_len (name));
14569   vec_free (name);
14570   mp->is_add = is_add;
14571   mp->cir = cir;
14572   mp->eir = eir;
14573   mp->cb = cb;
14574   mp->eb = eb;
14575   mp->rate_type = rate_type;
14576   mp->round_type = round_type;
14577   mp->type = type;
14578   mp->conform_action_type = conform_action.action_type;
14579   mp->conform_dscp = conform_action.dscp;
14580   mp->exceed_action_type = exceed_action.action_type;
14581   mp->exceed_dscp = exceed_action.dscp;
14582   mp->violate_action_type = violate_action.action_type;
14583   mp->violate_dscp = violate_action.dscp;
14584   mp->color_aware = color_aware;
14585
14586   S;
14587   W;
14588   /* NOTREACHED */
14589   return 0;
14590 }
14591
14592 static int
14593 api_policer_dump (vat_main_t * vam)
14594 {
14595   unformat_input_t *i = vam->input;
14596   vl_api_policer_dump_t *mp;
14597   f64 timeout = ~0;
14598   u8 *match_name = 0;
14599   u8 match_name_valid = 0;
14600
14601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14602     {
14603       if (unformat (i, "name %s", &match_name))
14604         {
14605           vec_add1 (match_name, 0);
14606           match_name_valid = 1;
14607         }
14608       else
14609         break;
14610     }
14611
14612   M (POLICER_DUMP, policer_dump);
14613   mp->match_name_valid = match_name_valid;
14614   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14615   vec_free (match_name);
14616   /* send it... */
14617   S;
14618
14619   /* Use a control ping for synchronization */
14620   {
14621     vl_api_control_ping_t *mp;
14622     M (CONTROL_PING, control_ping);
14623     S;
14624   }
14625   /* Wait for a reply... */
14626   W;
14627
14628   /* NOTREACHED */
14629   return 0;
14630 }
14631
14632 static int
14633 api_policer_classify_set_interface (vat_main_t * vam)
14634 {
14635   unformat_input_t *i = vam->input;
14636   vl_api_policer_classify_set_interface_t *mp;
14637   f64 timeout;
14638   u32 sw_if_index;
14639   int sw_if_index_set;
14640   u32 ip4_table_index = ~0;
14641   u32 ip6_table_index = ~0;
14642   u32 l2_table_index = ~0;
14643   u8 is_add = 1;
14644
14645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14646     {
14647       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14648         sw_if_index_set = 1;
14649       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14650         sw_if_index_set = 1;
14651       else if (unformat (i, "del"))
14652         is_add = 0;
14653       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14654         ;
14655       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14656         ;
14657       else if (unformat (i, "l2-table %d", &l2_table_index))
14658         ;
14659       else
14660         {
14661           clib_warning ("parse error '%U'", format_unformat_error, i);
14662           return -99;
14663         }
14664     }
14665
14666   if (sw_if_index_set == 0)
14667     {
14668       errmsg ("missing interface name or sw_if_index\n");
14669       return -99;
14670     }
14671
14672   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14673
14674   mp->sw_if_index = ntohl (sw_if_index);
14675   mp->ip4_table_index = ntohl (ip4_table_index);
14676   mp->ip6_table_index = ntohl (ip6_table_index);
14677   mp->l2_table_index = ntohl (l2_table_index);
14678   mp->is_add = is_add;
14679
14680   S;
14681   W;
14682   /* NOTREACHED */
14683   return 0;
14684 }
14685
14686 static int
14687 api_policer_classify_dump (vat_main_t * vam)
14688 {
14689   unformat_input_t *i = vam->input;
14690   vl_api_policer_classify_dump_t *mp;
14691   f64 timeout = ~0;
14692   u8 type = POLICER_CLASSIFY_N_TABLES;
14693
14694   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14695     ;
14696   else
14697     {
14698       errmsg ("classify table type must be specified\n");
14699       return -99;
14700     }
14701
14702   if (!vam->json_output)
14703     {
14704       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14705     }
14706
14707   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14708   mp->type = type;
14709   /* send it... */
14710   S;
14711
14712   /* Use a control ping for synchronization */
14713   {
14714     vl_api_control_ping_t *mp;
14715     M (CONTROL_PING, control_ping);
14716     S;
14717   }
14718   /* Wait for a reply... */
14719   W;
14720
14721   /* NOTREACHED */
14722   return 0;
14723 }
14724
14725 static int
14726 api_netmap_create (vat_main_t * vam)
14727 {
14728   unformat_input_t *i = vam->input;
14729   vl_api_netmap_create_t *mp;
14730   f64 timeout;
14731   u8 *if_name = 0;
14732   u8 hw_addr[6];
14733   u8 random_hw_addr = 1;
14734   u8 is_pipe = 0;
14735   u8 is_master = 0;
14736
14737   memset (hw_addr, 0, sizeof (hw_addr));
14738
14739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14740     {
14741       if (unformat (i, "name %s", &if_name))
14742         vec_add1 (if_name, 0);
14743       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14744         random_hw_addr = 0;
14745       else if (unformat (i, "pipe"))
14746         is_pipe = 1;
14747       else if (unformat (i, "master"))
14748         is_master = 1;
14749       else if (unformat (i, "slave"))
14750         is_master = 0;
14751       else
14752         break;
14753     }
14754
14755   if (!vec_len (if_name))
14756     {
14757       errmsg ("interface name must be specified");
14758       return -99;
14759     }
14760
14761   if (vec_len (if_name) > 64)
14762     {
14763       errmsg ("interface name too long");
14764       return -99;
14765     }
14766
14767   M (NETMAP_CREATE, netmap_create);
14768
14769   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14770   clib_memcpy (mp->hw_addr, hw_addr, 6);
14771   mp->use_random_hw_addr = random_hw_addr;
14772   mp->is_pipe = is_pipe;
14773   mp->is_master = is_master;
14774   vec_free (if_name);
14775
14776   S;
14777   W;
14778   /* NOTREACHED */
14779   return 0;
14780 }
14781
14782 static int
14783 api_netmap_delete (vat_main_t * vam)
14784 {
14785   unformat_input_t *i = vam->input;
14786   vl_api_netmap_delete_t *mp;
14787   f64 timeout;
14788   u8 *if_name = 0;
14789
14790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14791     {
14792       if (unformat (i, "name %s", &if_name))
14793         vec_add1 (if_name, 0);
14794       else
14795         break;
14796     }
14797
14798   if (!vec_len (if_name))
14799     {
14800       errmsg ("interface name must be specified");
14801       return -99;
14802     }
14803
14804   if (vec_len (if_name) > 64)
14805     {
14806       errmsg ("interface name too long");
14807       return -99;
14808     }
14809
14810   M (NETMAP_DELETE, netmap_delete);
14811
14812   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14813   vec_free (if_name);
14814
14815   S;
14816   W;
14817   /* NOTREACHED */
14818   return 0;
14819 }
14820
14821 static void vl_api_mpls_eth_tunnel_details_t_handler
14822   (vl_api_mpls_eth_tunnel_details_t * mp)
14823 {
14824   vat_main_t *vam = &vat_main;
14825   i32 i;
14826   i32 len = ntohl (mp->nlabels);
14827
14828   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14829            ntohl (mp->tunnel_index),
14830            format_ethernet_address, &mp->tunnel_dst_mac,
14831            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14832   for (i = 0; i < len; i++)
14833     {
14834       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14835     }
14836   fformat (vam->ofp, "\n");
14837   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14838            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14839 }
14840
14841 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14842   (vl_api_mpls_eth_tunnel_details_t * mp)
14843 {
14844   vat_main_t *vam = &vat_main;
14845   vat_json_node_t *node = NULL;
14846   struct in_addr ip4;
14847   i32 i;
14848   i32 len = ntohl (mp->nlabels);
14849
14850   if (VAT_JSON_ARRAY != vam->json_tree.type)
14851     {
14852       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14853       vat_json_init_array (&vam->json_tree);
14854     }
14855   node = vat_json_array_add (&vam->json_tree);
14856
14857   vat_json_init_object (node);
14858   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14859   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14860   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14861   vat_json_object_add_uint (node, "inner_fib_index",
14862                             ntohl (mp->inner_fib_index));
14863   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14864   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14865   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14866   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14867   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14868                                    format (0, "%U", format_ethernet_address,
14869                                            &mp->tunnel_dst_mac));
14870   vat_json_object_add_uint (node, "tx_sw_if_index",
14871                             ntohl (mp->tx_sw_if_index));
14872   vat_json_object_add_uint (node, "label_count", len);
14873   for (i = 0; i < len; i++)
14874     {
14875       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14876     }
14877 }
14878
14879 static int
14880 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14881 {
14882   vl_api_mpls_eth_tunnel_dump_t *mp;
14883   f64 timeout;
14884   i32 index = -1;
14885
14886   /* Parse args required to build the message */
14887   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14888     {
14889       if (!unformat (vam->input, "tunnel_index %d", &index))
14890         {
14891           index = -1;
14892           break;
14893         }
14894     }
14895
14896   fformat (vam->ofp, "  tunnel_index %d\n", index);
14897
14898   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14899   mp->tunnel_index = htonl (index);
14900   S;
14901
14902   /* Use a control ping for synchronization */
14903   {
14904     vl_api_control_ping_t *mp;
14905     M (CONTROL_PING, control_ping);
14906     S;
14907   }
14908   W;
14909 }
14910
14911 static void vl_api_mpls_fib_encap_details_t_handler
14912   (vl_api_mpls_fib_encap_details_t * mp)
14913 {
14914   vat_main_t *vam = &vat_main;
14915   i32 i;
14916   i32 len = ntohl (mp->nlabels);
14917
14918   fformat (vam->ofp, "table %d, dest %U, label ",
14919            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14920   for (i = 0; i < len; i++)
14921     {
14922       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14923     }
14924   fformat (vam->ofp, "\n");
14925 }
14926
14927 static void vl_api_mpls_fib_encap_details_t_handler_json
14928   (vl_api_mpls_fib_encap_details_t * mp)
14929 {
14930   vat_main_t *vam = &vat_main;
14931   vat_json_node_t *node = NULL;
14932   i32 i;
14933   i32 len = ntohl (mp->nlabels);
14934   struct in_addr ip4;
14935
14936   if (VAT_JSON_ARRAY != vam->json_tree.type)
14937     {
14938       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14939       vat_json_init_array (&vam->json_tree);
14940     }
14941   node = vat_json_array_add (&vam->json_tree);
14942
14943   vat_json_init_object (node);
14944   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14945   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14946   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14947   vat_json_object_add_ip4 (node, "dest", ip4);
14948   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14949   vat_json_object_add_uint (node, "label_count", len);
14950   for (i = 0; i < len; i++)
14951     {
14952       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14953     }
14954 }
14955
14956 static int
14957 api_mpls_fib_encap_dump (vat_main_t * vam)
14958 {
14959   vl_api_mpls_fib_encap_dump_t *mp;
14960   f64 timeout;
14961
14962   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14963   S;
14964
14965   /* Use a control ping for synchronization */
14966   {
14967     vl_api_control_ping_t *mp;
14968     M (CONTROL_PING, control_ping);
14969     S;
14970   }
14971   W;
14972 }
14973
14974 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
14975 #define vl_api_mpls_fib_details_t_print vl_noop_handler
14976
14977 static void
14978 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
14979 {
14980   vat_main_t *vam = &vat_main;
14981   int count = ntohl (mp->count);
14982   vl_api_fib_path_t *fp;
14983   int i;
14984
14985   fformat (vam->ofp,
14986            "table-id %d, label %u, ess_bit %u\n",
14987            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
14988   fp = mp->path;
14989   for (i = 0; i < count; i++)
14990     {
14991       if (fp->afi == IP46_TYPE_IP6)
14992         fformat (vam->ofp,
14993                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14994                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14995                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14996                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14997                  format_ip6_address, fp->next_hop);
14998       else if (fp->afi == IP46_TYPE_IP4)
14999         fformat (vam->ofp,
15000                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15001                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15002                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15003                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15004                  format_ip4_address, fp->next_hop);
15005       fp++;
15006     }
15007 }
15008
15009 static void vl_api_mpls_fib_details_t_handler_json
15010   (vl_api_mpls_fib_details_t * mp)
15011 {
15012   vat_main_t *vam = &vat_main;
15013   int count = ntohl (mp->count);
15014   vat_json_node_t *node = NULL;
15015   struct in_addr ip4;
15016   struct in6_addr ip6;
15017   vl_api_fib_path_t *fp;
15018   int i;
15019
15020   if (VAT_JSON_ARRAY != vam->json_tree.type)
15021     {
15022       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15023       vat_json_init_array (&vam->json_tree);
15024     }
15025   node = vat_json_array_add (&vam->json_tree);
15026
15027   vat_json_init_object (node);
15028   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15029   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15030   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15031   vat_json_object_add_uint (node, "path_count", count);
15032   fp = mp->path;
15033   for (i = 0; i < count; i++)
15034     {
15035       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15036       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15037       vat_json_object_add_uint (node, "is_local", fp->is_local);
15038       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15039       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15040       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15041       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15042       if (fp->afi == IP46_TYPE_IP4)
15043         {
15044           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15045           vat_json_object_add_ip4 (node, "next_hop", ip4);
15046         }
15047       else if (fp->afi == IP46_TYPE_IP6)
15048         {
15049           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15050           vat_json_object_add_ip6 (node, "next_hop", ip6);
15051         }
15052     }
15053 }
15054
15055 static int
15056 api_mpls_fib_dump (vat_main_t * vam)
15057 {
15058   vl_api_mpls_fib_dump_t *mp;
15059   f64 timeout;
15060
15061   M (MPLS_FIB_DUMP, mpls_fib_dump);
15062   S;
15063
15064   /* Use a control ping for synchronization */
15065   {
15066     vl_api_control_ping_t *mp;
15067     M (CONTROL_PING, control_ping);
15068     S;
15069   }
15070   W;
15071 }
15072
15073 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15074 #define vl_api_ip_fib_details_t_print vl_noop_handler
15075
15076 static void
15077 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15078 {
15079   vat_main_t *vam = &vat_main;
15080   int count = ntohl (mp->count);
15081   vl_api_fib_path_t *fp;
15082   int i;
15083
15084   fformat (vam->ofp,
15085            "table-id %d, prefix %U/%d\n",
15086            ntohl (mp->table_id), format_ip4_address, mp->address,
15087            mp->address_length);
15088   fp = mp->path;
15089   for (i = 0; i < count; i++)
15090     {
15091       if (fp->afi == IP46_TYPE_IP6)
15092         fformat (vam->ofp,
15093                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15094                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15095                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15096                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15097                  format_ip6_address, fp->next_hop);
15098       else if (fp->afi == IP46_TYPE_IP4)
15099         fformat (vam->ofp,
15100                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15101                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15102                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15103                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15104                  format_ip4_address, fp->next_hop);
15105       fp++;
15106     }
15107 }
15108
15109 static void vl_api_ip_fib_details_t_handler_json
15110   (vl_api_ip_fib_details_t * mp)
15111 {
15112   vat_main_t *vam = &vat_main;
15113   int count = ntohl (mp->count);
15114   vat_json_node_t *node = NULL;
15115   struct in_addr ip4;
15116   struct in6_addr ip6;
15117   vl_api_fib_path_t *fp;
15118   int i;
15119
15120   if (VAT_JSON_ARRAY != vam->json_tree.type)
15121     {
15122       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15123       vat_json_init_array (&vam->json_tree);
15124     }
15125   node = vat_json_array_add (&vam->json_tree);
15126
15127   vat_json_init_object (node);
15128   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15129   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15130   vat_json_object_add_ip4 (node, "prefix", ip4);
15131   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15132   vat_json_object_add_uint (node, "path_count", count);
15133   fp = mp->path;
15134   for (i = 0; i < count; i++)
15135     {
15136       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15137       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15138       vat_json_object_add_uint (node, "is_local", fp->is_local);
15139       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15140       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15141       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15142       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15143       if (fp->afi == IP46_TYPE_IP4)
15144         {
15145           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15146           vat_json_object_add_ip4 (node, "next_hop", ip4);
15147         }
15148       else if (fp->afi == IP46_TYPE_IP6)
15149         {
15150           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15151           vat_json_object_add_ip6 (node, "next_hop", ip6);
15152         }
15153     }
15154 }
15155
15156 static int
15157 api_ip_fib_dump (vat_main_t * vam)
15158 {
15159   vl_api_ip_fib_dump_t *mp;
15160   f64 timeout;
15161
15162   M (IP_FIB_DUMP, ip_fib_dump);
15163   S;
15164
15165   /* Use a control ping for synchronization */
15166   {
15167     vl_api_control_ping_t *mp;
15168     M (CONTROL_PING, control_ping);
15169     S;
15170   }
15171   W;
15172 }
15173
15174 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15175 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15176
15177 static void
15178 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15179 {
15180   vat_main_t *vam = &vat_main;
15181   int count = ntohl (mp->count);
15182   vl_api_fib_path_t *fp;
15183   int i;
15184
15185   fformat (vam->ofp,
15186            "table-id %d, prefix %U/%d\n",
15187            ntohl (mp->table_id), format_ip6_address, mp->address,
15188            mp->address_length);
15189   fp = mp->path;
15190   for (i = 0; i < count; i++)
15191     {
15192       if (fp->afi == IP46_TYPE_IP6)
15193         fformat (vam->ofp,
15194                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15195                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15196                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15197                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15198                  format_ip6_address, fp->next_hop);
15199       else if (fp->afi == IP46_TYPE_IP4)
15200         fformat (vam->ofp,
15201                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15202                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15203                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15204                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15205                  format_ip4_address, fp->next_hop);
15206       fp++;
15207     }
15208 }
15209
15210 static void vl_api_ip6_fib_details_t_handler_json
15211   (vl_api_ip6_fib_details_t * mp)
15212 {
15213   vat_main_t *vam = &vat_main;
15214   int count = ntohl (mp->count);
15215   vat_json_node_t *node = NULL;
15216   struct in_addr ip4;
15217   struct in6_addr ip6;
15218   vl_api_fib_path_t *fp;
15219   int i;
15220
15221   if (VAT_JSON_ARRAY != vam->json_tree.type)
15222     {
15223       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15224       vat_json_init_array (&vam->json_tree);
15225     }
15226   node = vat_json_array_add (&vam->json_tree);
15227
15228   vat_json_init_object (node);
15229   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15230   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15231   vat_json_object_add_ip6 (node, "prefix", ip6);
15232   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15233   vat_json_object_add_uint (node, "path_count", count);
15234   fp = mp->path;
15235   for (i = 0; i < count; i++)
15236     {
15237       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15238       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15239       vat_json_object_add_uint (node, "is_local", fp->is_local);
15240       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15241       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15242       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15243       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15244       if (fp->afi == IP46_TYPE_IP4)
15245         {
15246           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15247           vat_json_object_add_ip4 (node, "next_hop", ip4);
15248         }
15249       else if (fp->afi == IP46_TYPE_IP6)
15250         {
15251           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15252           vat_json_object_add_ip6 (node, "next_hop", ip6);
15253         }
15254     }
15255 }
15256
15257 static int
15258 api_ip6_fib_dump (vat_main_t * vam)
15259 {
15260   vl_api_ip6_fib_dump_t *mp;
15261   f64 timeout;
15262
15263   M (IP6_FIB_DUMP, ip6_fib_dump);
15264   S;
15265
15266   /* Use a control ping for synchronization */
15267   {
15268     vl_api_control_ping_t *mp;
15269     M (CONTROL_PING, control_ping);
15270     S;
15271   }
15272   W;
15273 }
15274
15275 int
15276 api_classify_table_ids (vat_main_t * vam)
15277 {
15278   vl_api_classify_table_ids_t *mp;
15279   f64 timeout;
15280
15281   /* Construct the API message */
15282   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15283   mp->context = 0;
15284
15285   S;
15286   W;
15287   /* NOTREACHED */
15288   return 0;
15289 }
15290
15291 int
15292 api_classify_table_by_interface (vat_main_t * vam)
15293 {
15294   unformat_input_t *input = vam->input;
15295   vl_api_classify_table_by_interface_t *mp;
15296   f64 timeout;
15297
15298   u32 sw_if_index = ~0;
15299   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15300     {
15301       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15302         ;
15303       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15304         ;
15305       else
15306         break;
15307     }
15308   if (sw_if_index == ~0)
15309     {
15310       errmsg ("missing interface name or sw_if_index\n");
15311       return -99;
15312     }
15313
15314   /* Construct the API message */
15315   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15316   mp->context = 0;
15317   mp->sw_if_index = ntohl (sw_if_index);
15318
15319   S;
15320   W;
15321   /* NOTREACHED */
15322   return 0;
15323 }
15324
15325 int
15326 api_classify_table_info (vat_main_t * vam)
15327 {
15328   unformat_input_t *input = vam->input;
15329   vl_api_classify_table_info_t *mp;
15330   f64 timeout;
15331
15332   u32 table_id = ~0;
15333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15334     {
15335       if (unformat (input, "table_id %d", &table_id))
15336         ;
15337       else
15338         break;
15339     }
15340   if (table_id == ~0)
15341     {
15342       errmsg ("missing table id\n");
15343       return -99;
15344     }
15345
15346   /* Construct the API message */
15347   M (CLASSIFY_TABLE_INFO, classify_table_info);
15348   mp->context = 0;
15349   mp->table_id = ntohl (table_id);
15350
15351   S;
15352   W;
15353   /* NOTREACHED */
15354   return 0;
15355 }
15356
15357 int
15358 api_classify_session_dump (vat_main_t * vam)
15359 {
15360   unformat_input_t *input = vam->input;
15361   vl_api_classify_session_dump_t *mp;
15362   f64 timeout;
15363
15364   u32 table_id = ~0;
15365   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15366     {
15367       if (unformat (input, "table_id %d", &table_id))
15368         ;
15369       else
15370         break;
15371     }
15372   if (table_id == ~0)
15373     {
15374       errmsg ("missing table id\n");
15375       return -99;
15376     }
15377
15378   /* Construct the API message */
15379   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15380   mp->context = 0;
15381   mp->table_id = ntohl (table_id);
15382   S;
15383
15384   /* Use a control ping for synchronization */
15385   {
15386     vl_api_control_ping_t *mp;
15387     M (CONTROL_PING, control_ping);
15388     S;
15389   }
15390   W;
15391   /* NOTREACHED */
15392   return 0;
15393 }
15394
15395 static void
15396 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15397 {
15398   vat_main_t *vam = &vat_main;
15399
15400   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15401            "src_address %U, vrf_id %d, path_mtu %u, "
15402            "template_interval %u, udp_checksum %d\n",
15403            format_ip4_address, mp->collector_address,
15404            ntohs (mp->collector_port),
15405            format_ip4_address, mp->src_address,
15406            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15407            ntohl (mp->template_interval), mp->udp_checksum);
15408
15409   vam->retval = 0;
15410   vam->result_ready = 1;
15411 }
15412
15413 static void
15414   vl_api_ipfix_exporter_details_t_handler_json
15415   (vl_api_ipfix_exporter_details_t * mp)
15416 {
15417   vat_main_t *vam = &vat_main;
15418   vat_json_node_t node;
15419   struct in_addr collector_address;
15420   struct in_addr src_address;
15421
15422   vat_json_init_object (&node);
15423   clib_memcpy (&collector_address, &mp->collector_address,
15424                sizeof (collector_address));
15425   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15426   vat_json_object_add_uint (&node, "collector_port",
15427                             ntohs (mp->collector_port));
15428   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15429   vat_json_object_add_ip4 (&node, "src_address", src_address);
15430   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15431   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15432   vat_json_object_add_uint (&node, "template_interval",
15433                             ntohl (mp->template_interval));
15434   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15435
15436   vat_json_print (vam->ofp, &node);
15437   vat_json_free (&node);
15438   vam->retval = 0;
15439   vam->result_ready = 1;
15440 }
15441
15442 int
15443 api_ipfix_exporter_dump (vat_main_t * vam)
15444 {
15445   vl_api_ipfix_exporter_dump_t *mp;
15446   f64 timeout;
15447
15448   /* Construct the API message */
15449   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15450   mp->context = 0;
15451
15452   S;
15453   W;
15454   /* NOTREACHED */
15455   return 0;
15456 }
15457
15458 static int
15459 api_ipfix_classify_stream_dump (vat_main_t * vam)
15460 {
15461   vl_api_ipfix_classify_stream_dump_t *mp;
15462   f64 timeout;
15463
15464   /* Construct the API message */
15465   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15466   mp->context = 0;
15467
15468   S;
15469   W;
15470   /* NOTREACHED */
15471   return 0;
15472 }
15473
15474 static void
15475   vl_api_ipfix_classify_stream_details_t_handler
15476   (vl_api_ipfix_classify_stream_details_t * mp)
15477 {
15478   vat_main_t *vam = &vat_main;
15479   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15480            ntohl (mp->domain_id), ntohs (mp->src_port));
15481   vam->retval = 0;
15482   vam->result_ready = 1;
15483 }
15484
15485 static void
15486   vl_api_ipfix_classify_stream_details_t_handler_json
15487   (vl_api_ipfix_classify_stream_details_t * mp)
15488 {
15489   vat_main_t *vam = &vat_main;
15490   vat_json_node_t node;
15491
15492   vat_json_init_object (&node);
15493   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15494   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15495
15496   vat_json_print (vam->ofp, &node);
15497   vat_json_free (&node);
15498   vam->retval = 0;
15499   vam->result_ready = 1;
15500 }
15501
15502 static int
15503 api_ipfix_classify_table_dump (vat_main_t * vam)
15504 {
15505   vl_api_ipfix_classify_table_dump_t *mp;
15506   f64 timeout;
15507
15508   if (!vam->json_output)
15509     {
15510       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15511                "transport_protocol");
15512     }
15513
15514   /* Construct the API message */
15515   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15516
15517   /* send it... */
15518   S;
15519
15520   /* Use a control ping for synchronization */
15521   {
15522     vl_api_control_ping_t *mp;
15523     M (CONTROL_PING, control_ping);
15524     S;
15525   }
15526   W;
15527 }
15528
15529 static void
15530   vl_api_ipfix_classify_table_details_t_handler
15531   (vl_api_ipfix_classify_table_details_t * mp)
15532 {
15533   vat_main_t *vam = &vat_main;
15534   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15535            mp->transport_protocol);
15536 }
15537
15538 static void
15539   vl_api_ipfix_classify_table_details_t_handler_json
15540   (vl_api_ipfix_classify_table_details_t * mp)
15541 {
15542   vat_json_node_t *node = NULL;
15543   vat_main_t *vam = &vat_main;
15544
15545   if (VAT_JSON_ARRAY != vam->json_tree.type)
15546     {
15547       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15548       vat_json_init_array (&vam->json_tree);
15549     }
15550
15551   node = vat_json_array_add (&vam->json_tree);
15552   vat_json_init_object (node);
15553
15554   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15555   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15556   vat_json_object_add_uint (node, "transport_protocol",
15557                             mp->transport_protocol);
15558 }
15559
15560 static int
15561 api_sw_interface_span_enable_disable (vat_main_t * vam)
15562 {
15563   unformat_input_t *i = vam->input;
15564   vl_api_sw_interface_span_enable_disable_t *mp;
15565   f64 timeout;
15566   u32 src_sw_if_index = ~0;
15567   u32 dst_sw_if_index = ~0;
15568   u8 enable = 1;
15569
15570   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15571     {
15572       if (unformat (i, "src %U", unformat_sw_if_index, vam, &src_sw_if_index))
15573         ;
15574       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15575         ;
15576       else
15577         if (unformat
15578             (i, "dst %U", unformat_sw_if_index, vam, &dst_sw_if_index))
15579         ;
15580       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15581         ;
15582       else if (unformat (i, "disable"))
15583         enable = 0;
15584       else
15585         break;
15586     }
15587
15588   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15589
15590   mp->sw_if_index_from = htonl (src_sw_if_index);
15591   mp->sw_if_index_to = htonl (dst_sw_if_index);
15592   mp->enable = enable;
15593
15594   S;
15595   W;
15596   /* NOTREACHED */
15597   return 0;
15598 }
15599
15600 static void
15601 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
15602                                             * mp)
15603 {
15604   vat_main_t *vam = &vat_main;
15605
15606   fformat (vam->ofp, "%u => %u\n",
15607            ntohl (mp->sw_if_index_from), ntohl (mp->sw_if_index_to));
15608 }
15609
15610 static void
15611   vl_api_sw_interface_span_details_t_handler_json
15612   (vl_api_sw_interface_span_details_t * mp)
15613 {
15614   vat_main_t *vam = &vat_main;
15615   vat_json_node_t *node = NULL;
15616
15617   if (VAT_JSON_ARRAY != vam->json_tree.type)
15618     {
15619       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15620       vat_json_init_array (&vam->json_tree);
15621     }
15622   node = vat_json_array_add (&vam->json_tree);
15623
15624   vat_json_init_object (node);
15625   vat_json_object_add_uint (node, "src-if-index",
15626                             ntohl (mp->sw_if_index_from));
15627   vat_json_object_add_uint (node, "dst-if-index", ntohl (mp->sw_if_index_to));
15628 }
15629
15630 static int
15631 api_sw_interface_span_dump (vat_main_t * vam)
15632 {
15633   vl_api_sw_interface_span_dump_t *mp;
15634   f64 timeout;
15635
15636   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
15637   S;
15638
15639   /* Use a control ping for synchronization */
15640   {
15641     vl_api_control_ping_t *mp;
15642     M (CONTROL_PING, control_ping);
15643     S;
15644   }
15645   W;
15646 }
15647
15648 int
15649 api_pg_create_interface (vat_main_t * vam)
15650 {
15651   unformat_input_t *input = vam->input;
15652   vl_api_pg_create_interface_t *mp;
15653   f64 timeout;
15654
15655   u32 if_id = ~0;
15656   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15657     {
15658       if (unformat (input, "if_id %d", &if_id))
15659         ;
15660       else
15661         break;
15662     }
15663   if (if_id == ~0)
15664     {
15665       errmsg ("missing pg interface index\n");
15666       return -99;
15667     }
15668
15669   /* Construct the API message */
15670   M (PG_CREATE_INTERFACE, pg_create_interface);
15671   mp->context = 0;
15672   mp->interface_id = ntohl (if_id);
15673
15674   S;
15675   W;
15676   /* NOTREACHED */
15677   return 0;
15678 }
15679
15680 int
15681 api_pg_capture (vat_main_t * vam)
15682 {
15683   unformat_input_t *input = vam->input;
15684   vl_api_pg_capture_t *mp;
15685   f64 timeout;
15686
15687   u32 if_id = ~0;
15688   u8 enable = 1;
15689   u32 count = 1;
15690   u8 pcap_file_set = 0;
15691   u8 *pcap_file = 0;
15692   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15693     {
15694       if (unformat (input, "if_id %d", &if_id))
15695         ;
15696       else if (unformat (input, "pcap %s", &pcap_file))
15697         pcap_file_set = 1;
15698       else if (unformat (input, "count %d", &count))
15699         ;
15700       else if (unformat (input, "disable"))
15701         enable = 0;
15702       else
15703         break;
15704     }
15705   if (if_id == ~0)
15706     {
15707       errmsg ("missing pg interface index\n");
15708       return -99;
15709     }
15710   if (pcap_file_set > 0)
15711     {
15712       if (vec_len (pcap_file) > 255)
15713         {
15714           errmsg ("pcap file name is too long\n");
15715           return -99;
15716         }
15717     }
15718
15719   u32 name_len = vec_len (pcap_file);
15720   /* Construct the API message */
15721   M (PG_CAPTURE, pg_capture);
15722   mp->context = 0;
15723   mp->interface_id = ntohl (if_id);
15724   mp->is_enabled = enable;
15725   mp->count = ntohl (count);
15726   mp->pcap_name_length = ntohl (name_len);
15727   if (pcap_file_set != 0)
15728     {
15729       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15730     }
15731   vec_free (pcap_file);
15732
15733   S;
15734   W;
15735   /* NOTREACHED */
15736   return 0;
15737 }
15738
15739 int
15740 api_pg_enable_disable (vat_main_t * vam)
15741 {
15742   unformat_input_t *input = vam->input;
15743   vl_api_pg_enable_disable_t *mp;
15744   f64 timeout;
15745
15746   u8 enable = 1;
15747   u8 stream_name_set = 0;
15748   u8 *stream_name = 0;
15749   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15750     {
15751       if (unformat (input, "stream %s", &stream_name))
15752         stream_name_set = 1;
15753       else if (unformat (input, "disable"))
15754         enable = 0;
15755       else
15756         break;
15757     }
15758
15759   if (stream_name_set > 0)
15760     {
15761       if (vec_len (stream_name) > 255)
15762         {
15763           errmsg ("stream name too long\n");
15764           return -99;
15765         }
15766     }
15767
15768   u32 name_len = vec_len (stream_name);
15769   /* Construct the API message */
15770   M (PG_ENABLE_DISABLE, pg_enable_disable);
15771   mp->context = 0;
15772   mp->is_enabled = enable;
15773   if (stream_name_set != 0)
15774     {
15775       mp->stream_name_length = ntohl (name_len);
15776       clib_memcpy (mp->stream_name, stream_name, name_len);
15777     }
15778   vec_free (stream_name);
15779
15780   S;
15781   W;
15782   /* NOTREACHED */
15783   return 0;
15784 }
15785
15786 int
15787 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15788 {
15789   unformat_input_t *input = vam->input;
15790   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15791   f64 timeout;
15792
15793   u16 *low_ports = 0;
15794   u16 *high_ports = 0;
15795   u16 this_low;
15796   u16 this_hi;
15797   ip4_address_t ip4_addr;
15798   ip6_address_t ip6_addr;
15799   u32 length;
15800   u32 tmp, tmp2;
15801   u8 prefix_set = 0;
15802   u32 vrf_id = ~0;
15803   u8 is_add = 1;
15804   u8 is_ipv6 = 0;
15805
15806   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15807     {
15808       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15809         {
15810           prefix_set = 1;
15811         }
15812       else
15813         if (unformat
15814             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15815         {
15816           prefix_set = 1;
15817           is_ipv6 = 1;
15818         }
15819       else if (unformat (input, "vrf %d", &vrf_id))
15820         ;
15821       else if (unformat (input, "del"))
15822         is_add = 0;
15823       else if (unformat (input, "port %d", &tmp))
15824         {
15825           if (tmp == 0 || tmp > 65535)
15826             {
15827               errmsg ("port %d out of range", tmp);
15828               return -99;
15829             }
15830           this_low = tmp;
15831           this_hi = this_low + 1;
15832           vec_add1 (low_ports, this_low);
15833           vec_add1 (high_ports, this_hi);
15834         }
15835       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15836         {
15837           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15838             {
15839               errmsg ("incorrect range parameters\n");
15840               return -99;
15841             }
15842           this_low = tmp;
15843           /* Note: in debug CLI +1 is added to high before
15844              passing to real fn that does "the work"
15845              (ip_source_and_port_range_check_add_del).
15846              This fn is a wrapper around the binary API fn a
15847              control plane will call, which expects this increment
15848              to have occurred. Hence letting the binary API control
15849              plane fn do the increment for consistency between VAT
15850              and other control planes.
15851            */
15852           this_hi = tmp2;
15853           vec_add1 (low_ports, this_low);
15854           vec_add1 (high_ports, this_hi);
15855         }
15856       else
15857         break;
15858     }
15859
15860   if (prefix_set == 0)
15861     {
15862       errmsg ("<address>/<mask> not specified\n");
15863       return -99;
15864     }
15865
15866   if (vrf_id == ~0)
15867     {
15868       errmsg ("VRF ID required, not specified\n");
15869       return -99;
15870     }
15871
15872   if (vrf_id == 0)
15873     {
15874       errmsg
15875         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15876       return -99;
15877     }
15878
15879   if (vec_len (low_ports) == 0)
15880     {
15881       errmsg ("At least one port or port range required\n");
15882       return -99;
15883     }
15884
15885   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15886      ip_source_and_port_range_check_add_del);
15887
15888   mp->is_add = is_add;
15889
15890   if (is_ipv6)
15891     {
15892       mp->is_ipv6 = 1;
15893       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15894     }
15895   else
15896     {
15897       mp->is_ipv6 = 0;
15898       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15899     }
15900
15901   mp->mask_length = length;
15902   mp->number_of_ranges = vec_len (low_ports);
15903
15904   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15905   vec_free (low_ports);
15906
15907   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15908   vec_free (high_ports);
15909
15910   mp->vrf_id = ntohl (vrf_id);
15911
15912   S;
15913   W;
15914   /* NOTREACHED */
15915   return 0;
15916 }
15917
15918 int
15919 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15920 {
15921   unformat_input_t *input = vam->input;
15922   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15923   f64 timeout;
15924   u32 sw_if_index = ~0;
15925   int vrf_set = 0;
15926   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15927   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15928   u8 is_add = 1;
15929
15930   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15931     {
15932       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15933         ;
15934       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15935         ;
15936       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15937         vrf_set = 1;
15938       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15939         vrf_set = 1;
15940       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15941         vrf_set = 1;
15942       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15943         vrf_set = 1;
15944       else if (unformat (input, "del"))
15945         is_add = 0;
15946       else
15947         break;
15948     }
15949
15950   if (sw_if_index == ~0)
15951     {
15952       errmsg ("Interface required but not specified\n");
15953       return -99;
15954     }
15955
15956   if (vrf_set == 0)
15957     {
15958       errmsg ("VRF ID required but not specified\n");
15959       return -99;
15960     }
15961
15962   if (tcp_out_vrf_id == 0
15963       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15964     {
15965       errmsg
15966         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15967       return -99;
15968     }
15969
15970   /* Construct the API message */
15971   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15972      ip_source_and_port_range_check_interface_add_del);
15973
15974   mp->sw_if_index = ntohl (sw_if_index);
15975   mp->is_add = is_add;
15976   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15977   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15978   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15979   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15980
15981   /* send it... */
15982   S;
15983
15984   /* Wait for a reply... */
15985   W;
15986 }
15987
15988 static int
15989 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15990 {
15991   unformat_input_t *i = vam->input;
15992   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15993   f64 timeout;
15994   u32 local_sa_id = 0;
15995   u32 remote_sa_id = 0;
15996   ip4_address_t src_address;
15997   ip4_address_t dst_address;
15998   u8 is_add = 1;
15999
16000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16001     {
16002       if (unformat (i, "local_sa %d", &local_sa_id))
16003         ;
16004       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16005         ;
16006       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16007         ;
16008       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16009         ;
16010       else if (unformat (i, "del"))
16011         is_add = 0;
16012       else
16013         {
16014           clib_warning ("parse error '%U'", format_unformat_error, i);
16015           return -99;
16016         }
16017     }
16018
16019   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16020
16021   mp->local_sa_id = ntohl (local_sa_id);
16022   mp->remote_sa_id = ntohl (remote_sa_id);
16023   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16024   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16025   mp->is_add = is_add;
16026
16027   S;
16028   W;
16029   /* NOTREACHED */
16030   return 0;
16031 }
16032
16033 static int
16034 api_punt (vat_main_t * vam)
16035 {
16036   unformat_input_t *i = vam->input;
16037   vl_api_punt_t *mp;
16038   f64 timeout;
16039   u32 ipv = ~0;
16040   u32 protocol = ~0;
16041   u32 port = ~0;
16042   int is_add = 1;
16043
16044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16045     {
16046       if (unformat (i, "ip %d", &ipv))
16047         ;
16048       else if (unformat (i, "protocol %d", &protocol))
16049         ;
16050       else if (unformat (i, "port %d", &port))
16051         ;
16052       else if (unformat (i, "del"))
16053         is_add = 0;
16054       else
16055         {
16056           clib_warning ("parse error '%U'", format_unformat_error, i);
16057           return -99;
16058         }
16059     }
16060
16061   M (PUNT, punt);
16062
16063   mp->is_add = (u8) is_add;
16064   mp->ipv = (u8) ipv;
16065   mp->l4_protocol = (u8) protocol;
16066   mp->l4_port = htons ((u16) port);
16067
16068   S;
16069   W;
16070   /* NOTREACHED */
16071   return 0;
16072 }
16073
16074 static void vl_api_ipsec_gre_tunnel_details_t_handler
16075   (vl_api_ipsec_gre_tunnel_details_t * mp)
16076 {
16077   vat_main_t *vam = &vat_main;
16078
16079   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
16080            ntohl (mp->sw_if_index),
16081            format_ip4_address, &mp->src_address,
16082            format_ip4_address, &mp->dst_address,
16083            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16084 }
16085
16086 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16087   (vl_api_ipsec_gre_tunnel_details_t * mp)
16088 {
16089   vat_main_t *vam = &vat_main;
16090   vat_json_node_t *node = NULL;
16091   struct in_addr ip4;
16092
16093   if (VAT_JSON_ARRAY != vam->json_tree.type)
16094     {
16095       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16096       vat_json_init_array (&vam->json_tree);
16097     }
16098   node = vat_json_array_add (&vam->json_tree);
16099
16100   vat_json_init_object (node);
16101   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16102   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16103   vat_json_object_add_ip4 (node, "src_address", ip4);
16104   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16105   vat_json_object_add_ip4 (node, "dst_address", ip4);
16106   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16107   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16108 }
16109
16110 static int
16111 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16112 {
16113   unformat_input_t *i = vam->input;
16114   vl_api_ipsec_gre_tunnel_dump_t *mp;
16115   f64 timeout;
16116   u32 sw_if_index;
16117   u8 sw_if_index_set = 0;
16118
16119   /* Parse args required to build the message */
16120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16121     {
16122       if (unformat (i, "sw_if_index %d", &sw_if_index))
16123         sw_if_index_set = 1;
16124       else
16125         break;
16126     }
16127
16128   if (sw_if_index_set == 0)
16129     {
16130       sw_if_index = ~0;
16131     }
16132
16133   if (!vam->json_output)
16134     {
16135       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
16136                "sw_if_index", "src_address", "dst_address",
16137                "local_sa_id", "remote_sa_id");
16138     }
16139
16140   /* Get list of gre-tunnel interfaces */
16141   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16142
16143   mp->sw_if_index = htonl (sw_if_index);
16144
16145   S;
16146
16147   /* Use a control ping for synchronization */
16148   {
16149     vl_api_control_ping_t *mp;
16150     M (CONTROL_PING, control_ping);
16151     S;
16152   }
16153   W;
16154 }
16155
16156 static int
16157 api_delete_subif (vat_main_t * vam)
16158 {
16159   unformat_input_t *i = vam->input;
16160   vl_api_delete_subif_t *mp;
16161   f64 timeout;
16162   u32 sw_if_index = ~0;
16163
16164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16165     {
16166       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16167         ;
16168       if (unformat (i, "sw_if_index %d", &sw_if_index))
16169         ;
16170       else
16171         break;
16172     }
16173
16174   if (sw_if_index == ~0)
16175     {
16176       errmsg ("missing sw_if_index\n");
16177       return -99;
16178     }
16179
16180   /* Construct the API message */
16181   M (DELETE_SUBIF, delete_subif);
16182   mp->sw_if_index = ntohl (sw_if_index);
16183
16184   S;
16185   W;
16186 }
16187
16188 #define foreach_pbb_vtr_op      \
16189 _("disable",  L2_VTR_DISABLED)  \
16190 _("pop",  L2_VTR_POP_2)         \
16191 _("push",  L2_VTR_PUSH_2)
16192
16193 static int
16194 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16195 {
16196   unformat_input_t *i = vam->input;
16197   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16198   f64 timeout;
16199   u32 sw_if_index = ~0, vtr_op = ~0;
16200   u16 outer_tag = ~0;
16201   u8 dmac[6], smac[6];
16202   u8 dmac_set = 0, smac_set = 0;
16203   u16 vlanid = 0;
16204   u32 sid = ~0;
16205   u32 tmp;
16206
16207   /* Shut up coverity */
16208   memset (dmac, 0, sizeof (dmac));
16209   memset (smac, 0, sizeof (smac));
16210
16211   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16212     {
16213       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16214         ;
16215       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16216         ;
16217       else if (unformat (i, "vtr_op %d", &vtr_op))
16218         ;
16219 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16220       foreach_pbb_vtr_op
16221 #undef _
16222         else if (unformat (i, "translate_pbb_stag"))
16223         {
16224           if (unformat (i, "%d", &tmp))
16225             {
16226               vtr_op = L2_VTR_TRANSLATE_2_1;
16227               outer_tag = tmp;
16228             }
16229           else
16230             {
16231               errmsg
16232                 ("translate_pbb_stag operation requires outer tag definition\n");
16233               return -99;
16234             }
16235         }
16236       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16237         dmac_set++;
16238       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16239         smac_set++;
16240       else if (unformat (i, "sid %d", &sid))
16241         ;
16242       else if (unformat (i, "vlanid %d", &tmp))
16243         vlanid = tmp;
16244       else
16245         {
16246           clib_warning ("parse error '%U'", format_unformat_error, i);
16247           return -99;
16248         }
16249     }
16250
16251   if ((sw_if_index == ~0) || (vtr_op == ~0))
16252     {
16253       errmsg ("missing sw_if_index or vtr operation\n");
16254       return -99;
16255     }
16256   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16257       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16258     {
16259       errmsg
16260         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
16261       return -99;
16262     }
16263
16264   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16265   mp->sw_if_index = ntohl (sw_if_index);
16266   mp->vtr_op = ntohl (vtr_op);
16267   mp->outer_tag = ntohs (outer_tag);
16268   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16269   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16270   mp->b_vlanid = ntohs (vlanid);
16271   mp->i_sid = ntohl (sid);
16272
16273   S;
16274   W;
16275   /* NOTREACHED */
16276   return 0;
16277 }
16278
16279 static int
16280 api_flow_classify_set_interface (vat_main_t * vam)
16281 {
16282   unformat_input_t *i = vam->input;
16283   vl_api_flow_classify_set_interface_t *mp;
16284   f64 timeout;
16285   u32 sw_if_index;
16286   int sw_if_index_set;
16287   u32 ip4_table_index = ~0;
16288   u32 ip6_table_index = ~0;
16289   u8 is_add = 1;
16290
16291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16292     {
16293       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16294         sw_if_index_set = 1;
16295       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16296         sw_if_index_set = 1;
16297       else if (unformat (i, "del"))
16298         is_add = 0;
16299       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16300         ;
16301       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16302         ;
16303       else
16304         {
16305           clib_warning ("parse error '%U'", format_unformat_error, i);
16306           return -99;
16307         }
16308     }
16309
16310   if (sw_if_index_set == 0)
16311     {
16312       errmsg ("missing interface name or sw_if_index\n");
16313       return -99;
16314     }
16315
16316   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16317
16318   mp->sw_if_index = ntohl (sw_if_index);
16319   mp->ip4_table_index = ntohl (ip4_table_index);
16320   mp->ip6_table_index = ntohl (ip6_table_index);
16321   mp->is_add = is_add;
16322
16323   S;
16324   W;
16325   /* NOTREACHED */
16326   return 0;
16327 }
16328
16329 static int
16330 api_flow_classify_dump (vat_main_t * vam)
16331 {
16332   unformat_input_t *i = vam->input;
16333   vl_api_flow_classify_dump_t *mp;
16334   f64 timeout = ~0;
16335   u8 type = FLOW_CLASSIFY_N_TABLES;
16336
16337   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16338     ;
16339   else
16340     {
16341       errmsg ("classify table type must be specified\n");
16342       return -99;
16343     }
16344
16345   if (!vam->json_output)
16346     {
16347       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
16348     }
16349
16350   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16351   mp->type = type;
16352   /* send it... */
16353   S;
16354
16355   /* Use a control ping for synchronization */
16356   {
16357     vl_api_control_ping_t *mp;
16358     M (CONTROL_PING, control_ping);
16359     S;
16360   }
16361   /* Wait for a reply... */
16362   W;
16363
16364   /* NOTREACHED */
16365   return 0;
16366 }
16367
16368 static int
16369 api_feature_enable_disable (vat_main_t * vam)
16370 {
16371   unformat_input_t *i = vam->input;
16372   vl_api_feature_enable_disable_t *mp;
16373   f64 timeout;
16374   u8 *arc_name = 0;
16375   u8 *feature_name = 0;
16376   u32 sw_if_index = ~0;
16377   u8 enable = 1;
16378
16379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16380     {
16381       if (unformat (i, "arc_name %s", &arc_name))
16382         ;
16383       else if (unformat (i, "feature_name %s", &feature_name))
16384         ;
16385       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16386         ;
16387       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16388         ;
16389       else if (unformat (i, "disable"))
16390         enable = 0;
16391       else
16392         break;
16393     }
16394
16395   if (arc_name == 0)
16396     {
16397       errmsg ("missing arc name\n");
16398       return -99;
16399     }
16400   if (vec_len (arc_name) > 63)
16401     {
16402       errmsg ("arc name too long\n");
16403     }
16404
16405   if (feature_name == 0)
16406     {
16407       errmsg ("missing feature name\n");
16408       return -99;
16409     }
16410   if (vec_len (feature_name) > 63)
16411     {
16412       errmsg ("feature name too long\n");
16413     }
16414
16415   if (sw_if_index == ~0)
16416     {
16417       errmsg ("missing interface name or sw_if_index\n");
16418       return -99;
16419     }
16420
16421   /* Construct the API message */
16422   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16423   mp->sw_if_index = ntohl (sw_if_index);
16424   mp->enable = enable;
16425   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16426   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16427   vec_free (arc_name);
16428   vec_free (feature_name);
16429
16430   S;
16431   W;
16432 }
16433
16434 static int
16435 api_sw_interface_tag_add_del (vat_main_t * vam)
16436 {
16437   unformat_input_t *i = vam->input;
16438   vl_api_sw_interface_tag_add_del_t *mp;
16439   f64 timeout;
16440   u32 sw_if_index = ~0;
16441   u8 *tag = 0;
16442   u8 enable = 1;
16443
16444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16445     {
16446       if (unformat (i, "tag %s", &tag))
16447         ;
16448       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16449         ;
16450       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16451         ;
16452       else if (unformat (i, "del"))
16453         enable = 0;
16454       else
16455         break;
16456     }
16457
16458   if (sw_if_index == ~0)
16459     {
16460       errmsg ("missing interface name or sw_if_index\n");
16461       return -99;
16462     }
16463
16464   if (enable && (tag == 0))
16465     {
16466       errmsg ("no tag specified\n");
16467       return -99;
16468     }
16469
16470   /* Construct the API message */
16471   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
16472   mp->sw_if_index = ntohl (sw_if_index);
16473   mp->is_add = enable;
16474   if (enable)
16475     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
16476   vec_free (tag);
16477
16478   S;
16479   W;
16480 }
16481
16482 static int
16483 q_or_quit (vat_main_t * vam)
16484 {
16485   longjmp (vam->jump_buf, 1);
16486   return 0;                     /* not so much */
16487 }
16488
16489 static int
16490 q (vat_main_t * vam)
16491 {
16492   return q_or_quit (vam);
16493 }
16494
16495 static int
16496 quit (vat_main_t * vam)
16497 {
16498   return q_or_quit (vam);
16499 }
16500
16501 static int
16502 comment (vat_main_t * vam)
16503 {
16504   return 0;
16505 }
16506
16507 static int
16508 cmd_cmp (void *a1, void *a2)
16509 {
16510   u8 **c1 = a1;
16511   u8 **c2 = a2;
16512
16513   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
16514 }
16515
16516 static int
16517 help (vat_main_t * vam)
16518 {
16519   u8 **cmds = 0;
16520   u8 *name = 0;
16521   hash_pair_t *p;
16522   unformat_input_t *i = vam->input;
16523   int j;
16524
16525   if (unformat (i, "%s", &name))
16526     {
16527       uword *hs;
16528
16529       vec_add1 (name, 0);
16530
16531       hs = hash_get_mem (vam->help_by_name, name);
16532       if (hs)
16533         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
16534       else
16535         fformat (vam->ofp, "No such msg / command '%s'\n", name);
16536       vec_free (name);
16537       return 0;
16538     }
16539
16540   fformat (vam->ofp, "Help is available for the following:\n");
16541
16542     /* *INDENT-OFF* */
16543     hash_foreach_pair (p, vam->function_by_name,
16544     ({
16545       vec_add1 (cmds, (u8 *)(p->key));
16546     }));
16547     /* *INDENT-ON* */
16548
16549   vec_sort_with_function (cmds, cmd_cmp);
16550
16551   for (j = 0; j < vec_len (cmds); j++)
16552     fformat (vam->ofp, "%s\n", cmds[j]);
16553
16554   vec_free (cmds);
16555   return 0;
16556 }
16557
16558 static int
16559 set (vat_main_t * vam)
16560 {
16561   u8 *name = 0, *value = 0;
16562   unformat_input_t *i = vam->input;
16563
16564   if (unformat (i, "%s", &name))
16565     {
16566       /* The input buffer is a vector, not a string. */
16567       value = vec_dup (i->buffer);
16568       vec_delete (value, i->index, 0);
16569       /* Almost certainly has a trailing newline */
16570       if (value[vec_len (value) - 1] == '\n')
16571         value[vec_len (value) - 1] = 0;
16572       /* Make sure it's a proper string, one way or the other */
16573       vec_add1 (value, 0);
16574       (void) clib_macro_set_value (&vam->macro_main,
16575                                    (char *) name, (char *) value);
16576     }
16577   else
16578     errmsg ("usage: set <name> <value>\n");
16579
16580   vec_free (name);
16581   vec_free (value);
16582   return 0;
16583 }
16584
16585 static int
16586 unset (vat_main_t * vam)
16587 {
16588   u8 *name = 0;
16589
16590   if (unformat (vam->input, "%s", &name))
16591     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
16592       errmsg ("unset: %s wasn't set\n", name);
16593   vec_free (name);
16594   return 0;
16595 }
16596
16597 typedef struct
16598 {
16599   u8 *name;
16600   u8 *value;
16601 } macro_sort_t;
16602
16603
16604 static int
16605 macro_sort_cmp (void *a1, void *a2)
16606 {
16607   macro_sort_t *s1 = a1;
16608   macro_sort_t *s2 = a2;
16609
16610   return strcmp ((char *) (s1->name), (char *) (s2->name));
16611 }
16612
16613 static int
16614 dump_macro_table (vat_main_t * vam)
16615 {
16616   macro_sort_t *sort_me = 0, *sm;
16617   int i;
16618   hash_pair_t *p;
16619
16620     /* *INDENT-OFF* */
16621     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
16622     ({
16623       vec_add2 (sort_me, sm, 1);
16624       sm->name = (u8 *)(p->key);
16625       sm->value = (u8 *) (p->value[0]);
16626     }));
16627     /* *INDENT-ON* */
16628
16629   vec_sort_with_function (sort_me, macro_sort_cmp);
16630
16631   if (vec_len (sort_me))
16632     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
16633   else
16634     fformat (vam->ofp, "The macro table is empty...\n");
16635
16636   for (i = 0; i < vec_len (sort_me); i++)
16637     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
16638   return 0;
16639 }
16640
16641 static int
16642 dump_node_table (vat_main_t * vam)
16643 {
16644   int i, j;
16645   vlib_node_t *node, *next_node;
16646
16647   if (vec_len (vam->graph_nodes) == 0)
16648     {
16649       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16650       return 0;
16651     }
16652
16653   for (i = 0; i < vec_len (vam->graph_nodes); i++)
16654     {
16655       node = vam->graph_nodes[i];
16656       fformat (vam->ofp, "[%d] %s\n", i, node->name);
16657       for (j = 0; j < vec_len (node->next_nodes); j++)
16658         {
16659           if (node->next_nodes[j] != ~0)
16660             {
16661               next_node = vam->graph_nodes[node->next_nodes[j]];
16662               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16663             }
16664         }
16665     }
16666   return 0;
16667 }
16668
16669 static int
16670 value_sort_cmp (void *a1, void *a2)
16671 {
16672   name_sort_t *n1 = a1;
16673   name_sort_t *n2 = a2;
16674
16675   if (n1->value < n2->value)
16676     return -1;
16677   if (n1->value > n2->value)
16678     return 1;
16679   return 0;
16680 }
16681
16682
16683 static int
16684 dump_msg_api_table (vat_main_t * vam)
16685 {
16686   api_main_t *am = &api_main;
16687   name_sort_t *nses = 0, *ns;
16688   hash_pair_t *hp;
16689   int i;
16690
16691   /* *INDENT-OFF* */
16692   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
16693   ({
16694     vec_add2 (nses, ns, 1);
16695     ns->name = (u8 *)(hp->key);
16696     ns->value = (u32) hp->value[0];
16697   }));
16698   /* *INDENT-ON* */
16699
16700   vec_sort_with_function (nses, value_sort_cmp);
16701
16702   for (i = 0; i < vec_len (nses); i++)
16703     fformat (vam->ofp, " [%d]: %s\n", nses[i].value, nses[i].name);
16704   vec_free (nses);
16705   return 0;
16706 }
16707
16708 static int
16709 get_msg_id (vat_main_t * vam)
16710 {
16711   u8 *name_and_crc;
16712   u32 message_index;
16713
16714   if (unformat (vam->input, "%s", &name_and_crc))
16715     {
16716       message_index = vl_api_get_msg_index (name_and_crc);
16717       if (message_index == ~0)
16718         {
16719           fformat (vam->ofp, " '%s' not found\n", name_and_crc);
16720           return 0;
16721         }
16722       fformat (vam->ofp, " '%s' has message index %d\n",
16723                name_and_crc, message_index);
16724       return 0;
16725     }
16726   errmsg ("name_and_crc required...\n");
16727   return 0;
16728 }
16729
16730 static int
16731 search_node_table (vat_main_t * vam)
16732 {
16733   unformat_input_t *line_input = vam->input;
16734   u8 *node_to_find;
16735   int j;
16736   vlib_node_t *node, *next_node;
16737   uword *p;
16738
16739   if (vam->graph_node_index_by_name == 0)
16740     {
16741       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16742       return 0;
16743     }
16744
16745   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16746     {
16747       if (unformat (line_input, "%s", &node_to_find))
16748         {
16749           vec_add1 (node_to_find, 0);
16750           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
16751           if (p == 0)
16752             {
16753               fformat (vam->ofp, "%s not found...\n", node_to_find);
16754               goto out;
16755             }
16756           node = vam->graph_nodes[p[0]];
16757           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
16758           for (j = 0; j < vec_len (node->next_nodes); j++)
16759             {
16760               if (node->next_nodes[j] != ~0)
16761                 {
16762                   next_node = vam->graph_nodes[node->next_nodes[j]];
16763                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16764                 }
16765             }
16766         }
16767
16768       else
16769         {
16770           clib_warning ("parse error '%U'", format_unformat_error,
16771                         line_input);
16772           return -99;
16773         }
16774
16775     out:
16776       vec_free (node_to_find);
16777
16778     }
16779
16780   return 0;
16781 }
16782
16783
16784 static int
16785 script (vat_main_t * vam)
16786 {
16787   u8 *s = 0;
16788   char *save_current_file;
16789   unformat_input_t save_input;
16790   jmp_buf save_jump_buf;
16791   u32 save_line_number;
16792
16793   FILE *new_fp, *save_ifp;
16794
16795   if (unformat (vam->input, "%s", &s))
16796     {
16797       new_fp = fopen ((char *) s, "r");
16798       if (new_fp == 0)
16799         {
16800           errmsg ("Couldn't open script file %s\n", s);
16801           vec_free (s);
16802           return -99;
16803         }
16804     }
16805   else
16806     {
16807       errmsg ("Missing script name\n");
16808       return -99;
16809     }
16810
16811   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
16812   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
16813   save_ifp = vam->ifp;
16814   save_line_number = vam->input_line_number;
16815   save_current_file = (char *) vam->current_file;
16816
16817   vam->input_line_number = 0;
16818   vam->ifp = new_fp;
16819   vam->current_file = s;
16820   do_one_file (vam);
16821
16822   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
16823   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
16824   vam->ifp = save_ifp;
16825   vam->input_line_number = save_line_number;
16826   vam->current_file = (u8 *) save_current_file;
16827   vec_free (s);
16828
16829   return 0;
16830 }
16831
16832 static int
16833 echo (vat_main_t * vam)
16834 {
16835   fformat (vam->ofp, "%v", vam->input->buffer);
16836   return 0;
16837 }
16838
16839 /* List of API message constructors, CLI names map to api_xxx */
16840 #define foreach_vpe_api_msg                                             \
16841 _(create_loopback,"[mac <mac-addr>]")                                   \
16842 _(sw_interface_dump,"")                                                 \
16843 _(sw_interface_set_flags,                                               \
16844   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
16845 _(sw_interface_add_del_address,                                         \
16846   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
16847 _(sw_interface_set_table,                                               \
16848   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
16849 _(sw_interface_set_mpls_enable,                                                \
16850   "<intfc> | sw_if_index [disable | dis]")                                \
16851 _(sw_interface_set_vpath,                                               \
16852   "<intfc> | sw_if_index <id> enable | disable")                        \
16853 _(sw_interface_set_vxlan_bypass,                                               \
16854   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")                        \
16855 _(sw_interface_set_l2_xconnect,                                         \
16856   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16857   "enable | disable")                                                   \
16858 _(sw_interface_set_l2_bridge,                                           \
16859   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16860   "[shg <split-horizon-group>] [bvi]\n"                                 \
16861   "enable | disable")                                                   \
16862 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16863   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16864   "profile <profile-id>\n")                                             \
16865 _(sw_interface_set_dpdk_hqos_subport,                                   \
16866   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16867   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16868 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16869   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16870 _(bridge_domain_add_del,                                                \
16871   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16872 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16873 _(l2fib_add_del,                                                        \
16874   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16875 _(l2_flags,                                                             \
16876   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16877 _(bridge_flags,                                                         \
16878   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16879 _(tap_connect,                                                          \
16880   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
16881 _(tap_modify,                                                           \
16882   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16883 _(tap_delete,                                                           \
16884   "<vpp-if-name> | sw_if_index <id>")                                   \
16885 _(sw_interface_tap_dump, "")                                            \
16886 _(ip_add_del_route,                                                     \
16887   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
16888   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16889   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16890   "[multipath] [count <n>]")                                            \
16891 _(mpls_route_add_del,                                                   \
16892   "<label> <eos> via <addr> [table-id <n>]\n"                           \
16893   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16894   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16895   "[multipath] [count <n>]")                                            \
16896 _(mpls_ip_bind_unbind,                                                  \
16897   "<label> <addr/len>")                                                 \
16898 _(proxy_arp_add_del,                                                    \
16899   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16900 _(proxy_arp_intfc_enable_disable,                                       \
16901   "<intfc> | sw_if_index <id> enable | disable")                        \
16902 _(mpls_add_del_encap,                                                   \
16903   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
16904 _(sw_interface_set_unnumbered,                                          \
16905   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16906 _(ip_neighbor_add_del,                                                  \
16907   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16908   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16909 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16910 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16911 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16912   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16913   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16914   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16915 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16916 _(reset_fib, "vrf <n> [ipv6]")                                          \
16917 _(dhcp_proxy_config,                                                    \
16918   "svr <v46-address> src <v46-address>\n"                               \
16919    "insert-cid <n> [del]")                                              \
16920 _(dhcp_proxy_config_2,                                                  \
16921   "svr <v46-address> src <v46-address>\n"                               \
16922    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16923 _(dhcp_proxy_set_vss,                                                   \
16924   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16925 _(dhcp_client_config,                                                   \
16926   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16927 _(set_ip_flow_hash,                                                     \
16928   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16929 _(sw_interface_ip6_enable_disable,                                      \
16930   "<intfc> | sw_if_index <id> enable | disable")                        \
16931 _(sw_interface_ip6_set_link_local_address,                              \
16932   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16933 _(sw_interface_ip6nd_ra_prefix,                                         \
16934   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16935   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16936   "[nolink] [isno]")                                                    \
16937 _(sw_interface_ip6nd_ra_config,                                         \
16938   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16939   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16940   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16941 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16942 _(l2_patch_add_del,                                                     \
16943   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16944   "enable | disable")                                                   \
16945 _(mpls_ethernet_add_del_tunnel,                                         \
16946   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
16947   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
16948 _(mpls_ethernet_add_del_tunnel_2,                                       \
16949   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
16950   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
16951 _(sr_tunnel_add_del,                                                    \
16952   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16953   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16954   "[policy <policy_name>]")                                             \
16955 _(sr_policy_add_del,                                                    \
16956   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16957 _(sr_multicast_map_add_del,                                             \
16958   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16959 _(classify_add_del_table,                                               \
16960   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16961   " [del] mask <mask-value>\n"                                          \
16962   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
16963   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
16964 _(classify_add_del_session,                                             \
16965   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16966   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16967   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
16968   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
16969 _(classify_set_interface_ip_table,                                      \
16970   "<intfc> | sw_if_index <nn> table <nn>")                              \
16971 _(classify_set_interface_l2_tables,                                     \
16972   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16973   "  [other-table <nn>]")                                               \
16974 _(get_node_index, "node <node-name")                                    \
16975 _(add_node_next, "node <node-name> next <next-node-name>")              \
16976 _(l2tpv3_create_tunnel,                                                 \
16977   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16978   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16979   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16980 _(l2tpv3_set_tunnel_cookies,                                            \
16981   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16982   "[new_remote_cookie <nn>]\n")                                         \
16983 _(l2tpv3_interface_enable_disable,                                      \
16984   "<intfc> | sw_if_index <nn> enable | disable")                        \
16985 _(l2tpv3_set_lookup_key,                                                \
16986   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16987 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16988 _(vxlan_add_del_tunnel,                                                 \
16989   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
16990   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
16991   "vni <vni> [encap-vrf-id <nn>] [decap-next l2|ip4|ip6] [del]")        \
16992 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16993 _(gre_add_del_tunnel,                                                   \
16994   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16995 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16996 _(l2_fib_clear_table, "")                                               \
16997 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16998 _(l2_interface_vlan_tag_rewrite,                                        \
16999   "<intfc> | sw_if_index <nn> \n"                                       \
17000   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
17001   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
17002 _(create_vhost_user_if,                                                 \
17003         "socket <filename> [server] [renumber <dev_instance>] "         \
17004         "[mac <mac_address>]")                                          \
17005 _(modify_vhost_user_if,                                                 \
17006         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
17007         "[server] [renumber <dev_instance>]")                           \
17008 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
17009 _(sw_interface_vhost_user_dump, "")                                     \
17010 _(show_version, "")                                                     \
17011 _(vxlan_gpe_add_del_tunnel,                                             \
17012   "local <addr> remote <addr> vni <nn>\n"                               \
17013     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
17014   "[next-ethernet] [next-nsh]\n")                                       \
17015 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
17016 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
17017 _(interface_name_renumber,                                              \
17018   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
17019 _(input_acl_set_interface,                                              \
17020   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17021   "  [l2-table <nn>] [del]")                                            \
17022 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
17023 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
17024 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
17025 _(ip_dump, "ipv4 | ipv6")                                               \
17026 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
17027 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
17028   "  spid_id <n> ")                                                     \
17029 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
17030   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
17031   "  integ_alg <alg> integ_key <hex>")                                  \
17032 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
17033   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
17034   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17035   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
17036 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
17037 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
17038 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
17039   "(auth_data 0x<data> | auth_data <data>)")                            \
17040 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
17041   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
17042 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
17043   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17044   "(local|remote)")                                                     \
17045 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
17046 _(delete_loopback,"sw_if_index <nn>")                                   \
17047 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17048 _(map_add_domain,                                                       \
17049   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
17050   "ip6-src <ip6addr> "                                                  \
17051   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
17052 _(map_del_domain, "index <n>")                                          \
17053 _(map_add_del_rule,                                                     \
17054   "index <n> psid <n> dst <ip6addr> [del]")                             \
17055 _(map_domain_dump, "")                                                  \
17056 _(map_rule_dump, "index <map-domain>")                                  \
17057 _(want_interface_events,  "enable|disable")                             \
17058 _(want_stats,"enable|disable")                                          \
17059 _(get_first_msg_id, "client <name>")                                    \
17060 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17061 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
17062   "fib-id <nn> [ip4][ip6][default]")                                    \
17063 _(get_node_graph, " ")                                                  \
17064 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
17065 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
17066 _(ioam_disable, "")                                                \
17067 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
17068                             " sw_if_index <sw_if_index> p <priority> "  \
17069                             "w <weight>] [del]")                        \
17070 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
17071                         "iface <intf> | sw_if_index <sw_if_index> "     \
17072                         "p <priority> w <weight> [del]")                \
17073 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
17074                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
17075                           "locator-set <locator_name> [del]")           \
17076 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
17077   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
17078 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
17079 _(lisp_gpe_enable_disable, "enable|disable")                            \
17080 _(lisp_enable_disable, "enable|disable")                                \
17081 _(lisp_gpe_add_del_iface, "up|down")                                    \
17082 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17083                                "[seid <seid>] "                         \
17084                                "rloc <locator> p <prio> "               \
17085                                "w <weight> [rloc <loc> ... ] "          \
17086                                "action <action> [del-all]")             \
17087 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17088                           "<local-eid>")                                \
17089 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
17090 _(lisp_map_request_mode, "src-dst|dst-only")                            \
17091 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
17092 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
17093 _(lisp_locator_set_dump, "[local | remote]")                            \
17094 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
17095 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
17096                        "[local] | [remote]")                            \
17097 _(lisp_eid_table_vni_dump, "")                                          \
17098 _(lisp_eid_table_map_dump, "l2|l3")                                     \
17099 _(lisp_gpe_tunnel_dump, "")                                             \
17100 _(lisp_map_resolver_dump, "")                                           \
17101 _(lisp_adjacencies_get, "vni <vni>")                                    \
17102 _(show_lisp_status, "")                                                 \
17103 _(lisp_get_map_request_itr_rlocs, "")                                   \
17104 _(show_lisp_pitr, "")                                                   \
17105 _(show_lisp_map_request_mode, "")                                       \
17106 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
17107 _(af_packet_delete, "name <host interface name>")                       \
17108 _(policer_add_del, "name <policer name> <params> [del]")                \
17109 _(policer_dump, "[name <policer name>]")                                \
17110 _(policer_classify_set_interface,                                       \
17111   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17112   "  [l2-table <nn>] [del]")                                            \
17113 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
17114 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
17115     "[master|slave]")                                                   \
17116 _(netmap_delete, "name <interface name>")                               \
17117 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
17118 _(mpls_fib_encap_dump, "")                                              \
17119 _(mpls_fib_dump, "")                                                    \
17120 _(classify_table_ids, "")                                               \
17121 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
17122 _(classify_table_info, "table_id <nn>")                                 \
17123 _(classify_session_dump, "table_id <nn>")                               \
17124 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
17125     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
17126     "[template_interval <nn>] [udp_checksum]")                          \
17127 _(ipfix_exporter_dump, "")                                              \
17128 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17129 _(ipfix_classify_stream_dump, "")                                       \
17130 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
17131 _(ipfix_classify_table_dump, "")                                        \
17132 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [[dst <intfc> | dst_sw_if_index <id>] | disable]") \
17133 _(sw_interface_span_dump, "")                                           \
17134 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17135 _(pg_create_interface, "if_id <nn>")                                    \
17136 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17137 _(pg_enable_disable, "[stream <id>] disable")                           \
17138 _(ip_source_and_port_range_check_add_del,                               \
17139   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17140 _(ip_source_and_port_range_check_interface_add_del,                     \
17141   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17142   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17143 _(ipsec_gre_add_del_tunnel,                                             \
17144   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17145 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17146 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17147 _(l2_interface_pbb_tag_rewrite,                                         \
17148   "<intfc> | sw_if_index <nn> \n"                                       \
17149   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17150   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17151 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17152 _(flow_classify_set_interface,                                          \
17153   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17154 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17155 _(ip_fib_dump, "")                                                      \
17156 _(ip6_fib_dump, "")                                                     \
17157 _(feature_enable_disable, "arc_name <arc_name> "                        \
17158   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
17159 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
17160 "[disable]")
17161
17162 /* List of command functions, CLI names map directly to functions */
17163 #define foreach_cli_function                                    \
17164 _(comment, "usage: comment <ignore-rest-of-line>")              \
17165 _(dump_interface_table, "usage: dump_interface_table")          \
17166 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17167 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17168 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17169 _(dump_stats_table, "usage: dump_stats_table")                  \
17170 _(dump_macro_table, "usage: dump_macro_table ")                 \
17171 _(dump_node_table, "usage: dump_node_table")                    \
17172 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17173 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17174 _(echo, "usage: echo <message>")                                \
17175 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17176 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17177 _(help, "usage: help")                                          \
17178 _(q, "usage: quit")                                             \
17179 _(quit, "usage: quit")                                          \
17180 _(search_node_table, "usage: search_node_table <name>...")      \
17181 _(set, "usage: set <variable-name> <value>")                    \
17182 _(script, "usage: script <file-name>")                          \
17183 _(unset, "usage: unset <variable-name>")
17184
17185 #define _(N,n)                                  \
17186     static void vl_api_##n##_t_handler_uni      \
17187     (vl_api_##n##_t * mp)                       \
17188     {                                           \
17189         vat_main_t * vam = &vat_main;           \
17190         if (vam->json_output) {                 \
17191             vl_api_##n##_t_handler_json(mp);    \
17192         } else {                                \
17193             vl_api_##n##_t_handler(mp);         \
17194         }                                       \
17195     }
17196 foreach_vpe_api_reply_msg;
17197 #undef _
17198
17199 void
17200 vat_api_hookup (vat_main_t * vam)
17201 {
17202 #define _(N,n)                                                  \
17203     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17204                            vl_api_##n##_t_handler_uni,          \
17205                            vl_noop_handler,                     \
17206                            vl_api_##n##_t_endian,               \
17207                            vl_api_##n##_t_print,                \
17208                            sizeof(vl_api_##n##_t), 1);
17209   foreach_vpe_api_reply_msg;
17210 #undef _
17211
17212   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17213
17214   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17215
17216   vam->function_by_name = hash_create_string (0, sizeof (uword));
17217
17218   vam->help_by_name = hash_create_string (0, sizeof (uword));
17219
17220   /* API messages we can send */
17221 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17222   foreach_vpe_api_msg;
17223 #undef _
17224
17225   /* Help strings */
17226 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17227   foreach_vpe_api_msg;
17228 #undef _
17229
17230   /* CLI functions */
17231 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17232   foreach_cli_function;
17233 #undef _
17234
17235   /* Help strings */
17236 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17237   foreach_cli_function;
17238 #undef _
17239 }
17240
17241 #undef vl_api_version
17242 #define vl_api_version(n,v) static u32 memory_api_version = v;
17243 #include <vlibmemory/vl_memory_api_h.h>
17244 #undef vl_api_version
17245
17246 #undef vl_api_version
17247 #define vl_api_version(n,v) static u32 vnet_interface_api_version = v;
17248 #include <vnet/interface.api.h>
17249 #undef vl_api_version
17250
17251 #undef vl_api_version
17252 #define vl_api_version(n,v) static u32 vpp_api_version = v;
17253 #include <vpp-api/vpe.api.h>
17254 #undef vl_api_version
17255
17256 static u32 *api_versions[] = {
17257   &memory_api_version,
17258   &vnet_interface_api_version,
17259   &vpp_api_version,
17260 };
17261
17262 void
17263 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
17264 {
17265   int i;
17266
17267   ASSERT (ARRAY_LEN (mp->api_versions) >= ARRAY_LEN (api_versions));
17268
17269   /*
17270    * Send the API signatures. This bit of code must
17271    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
17272    */
17273
17274   for (i = 0; i < ARRAY_LEN (api_versions); i++)
17275     mp->api_versions[i] = clib_host_to_net_u32 (*api_versions[i]);
17276 }
17277
17278 /*
17279  * fd.io coding-style-patch-verification: ON
17280  *
17281  * Local Variables:
17282  * eval: (c-set-style "gnu")
17283  * End:
17284  */