003fd72371408f666532e63dc55abcf257bc2dc9
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248   u32 *r = va_arg (*args, u32 *);
249
250   if (0);
251 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
252   foreach_ipsec_policy_action
253 #undef _
254     else
255     return 0;
256   return 1;
257 }
258
259 uword
260 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
261 {
262   u32 *r = va_arg (*args, u32 *);
263
264   if (0);
265 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
266   foreach_ipsec_crypto_alg
267 #undef _
268     else
269     return 0;
270   return 1;
271 }
272
273 u8 *
274 format_ipsec_crypto_alg (u8 * s, va_list * args)
275 {
276   u32 i = va_arg (*args, u32);
277   u8 *t = 0;
278
279   switch (i)
280     {
281 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
282       foreach_ipsec_crypto_alg
283 #undef _
284     default:
285       return format (s, "unknown");
286     }
287   return format (s, "%s", t);
288 }
289
290 uword
291 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
292 {
293   u32 *r = va_arg (*args, u32 *);
294
295   if (0);
296 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
297   foreach_ipsec_integ_alg
298 #undef _
299     else
300     return 0;
301   return 1;
302 }
303
304 u8 *
305 format_ipsec_integ_alg (u8 * s, va_list * args)
306 {
307   u32 i = va_arg (*args, u32);
308   u8 *t = 0;
309
310   switch (i)
311     {
312 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
313       foreach_ipsec_integ_alg
314 #undef _
315     default:
316       return format (s, "unknown");
317     }
318   return format (s, "%s", t);
319 }
320
321 uword
322 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
323 {
324   u32 *r = va_arg (*args, u32 *);
325
326   if (0);
327 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
328   foreach_ikev2_auth_method
329 #undef _
330     else
331     return 0;
332   return 1;
333 }
334
335 uword
336 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
337 {
338   u32 *r = va_arg (*args, u32 *);
339
340   if (0);
341 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
342   foreach_ikev2_id_type
343 #undef _
344     else
345     return 0;
346   return 1;
347 }
348
349 uword
350 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
351 {
352   u8 *r = va_arg (*args, u8 *);
353
354   if (unformat (input, "kbps"))
355     *r = SSE2_QOS_RATE_KBPS;
356   else if (unformat (input, "pps"))
357     *r = SSE2_QOS_RATE_PPS;
358   else
359     return 0;
360   return 1;
361 }
362
363 uword
364 unformat_policer_round_type (unformat_input_t * input, va_list * args)
365 {
366   u8 *r = va_arg (*args, u8 *);
367
368   if (unformat (input, "closest"))
369     *r = SSE2_QOS_ROUND_TO_CLOSEST;
370   else if (unformat (input, "up"))
371     *r = SSE2_QOS_ROUND_TO_UP;
372   else if (unformat (input, "down"))
373     *r = SSE2_QOS_ROUND_TO_DOWN;
374   else
375     return 0;
376   return 1;
377 }
378
379 uword
380 unformat_policer_type (unformat_input_t * input, va_list * args)
381 {
382   u8 *r = va_arg (*args, u8 *);
383
384   if (unformat (input, "1r2c"))
385     *r = SSE2_QOS_POLICER_TYPE_1R2C;
386   else if (unformat (input, "1r3c"))
387     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
388   else if (unformat (input, "2r3c-2698"))
389     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
390   else if (unformat (input, "2r3c-4115"))
391     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
392   else if (unformat (input, "2r3c-mef5cf1"))
393     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
394   else
395     return 0;
396   return 1;
397 }
398
399 uword
400 unformat_dscp (unformat_input_t * input, va_list * va)
401 {
402   u8 *r = va_arg (*va, u8 *);
403
404   if (0);
405 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
406   foreach_vnet_dscp
407 #undef _
408     else
409     return 0;
410   return 1;
411 }
412
413 uword
414 unformat_policer_action_type (unformat_input_t * input, va_list * va)
415 {
416   sse2_qos_pol_action_params_st *a
417     = va_arg (*va, sse2_qos_pol_action_params_st *);
418
419   if (unformat (input, "drop"))
420     a->action_type = SSE2_QOS_ACTION_DROP;
421   else if (unformat (input, "transmit"))
422     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
423   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
424     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
425   else
426     return 0;
427   return 1;
428 }
429
430 uword
431 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
432 {
433   u32 *r = va_arg (*va, u32 *);
434   u32 tid;
435
436   if (unformat (input, "ip4"))
437     tid = POLICER_CLASSIFY_TABLE_IP4;
438   else if (unformat (input, "ip6"))
439     tid = POLICER_CLASSIFY_TABLE_IP6;
440   else if (unformat (input, "l2"))
441     tid = POLICER_CLASSIFY_TABLE_L2;
442   else
443     return 0;
444
445   *r = tid;
446   return 1;
447 }
448
449 uword
450 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
451 {
452   u32 *r = va_arg (*va, u32 *);
453   u32 tid;
454
455   if (unformat (input, "ip4"))
456     tid = FLOW_CLASSIFY_TABLE_IP4;
457   else if (unformat (input, "ip6"))
458     tid = FLOW_CLASSIFY_TABLE_IP6;
459   else
460     return 0;
461
462   *r = tid;
463   return 1;
464 }
465
466 u8 *
467 format_ip4_address (u8 * s, va_list * args)
468 {
469   u8 *a = va_arg (*args, u8 *);
470   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
471 }
472
473 u8 *
474 format_ip6_address (u8 * s, va_list * args)
475 {
476   ip6_address_t *a = va_arg (*args, ip6_address_t *);
477   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
478
479   i_max_n_zero = ARRAY_LEN (a->as_u16);
480   max_n_zeros = 0;
481   i_first_zero = i_max_n_zero;
482   n_zeros = 0;
483   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
484     {
485       u32 is_zero = a->as_u16[i] == 0;
486       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
487         {
488           i_first_zero = i;
489           n_zeros = 0;
490         }
491       n_zeros += is_zero;
492       if ((!is_zero && n_zeros > max_n_zeros)
493           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
494         {
495           i_max_n_zero = i_first_zero;
496           max_n_zeros = n_zeros;
497           i_first_zero = ARRAY_LEN (a->as_u16);
498           n_zeros = 0;
499         }
500     }
501
502   last_double_colon = 0;
503   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
504     {
505       if (i == i_max_n_zero && max_n_zeros > 1)
506         {
507           s = format (s, "::");
508           i += max_n_zeros - 1;
509           last_double_colon = 1;
510         }
511       else
512         {
513           s = format (s, "%s%x",
514                       (last_double_colon || i == 0) ? "" : ":",
515                       clib_net_to_host_u16 (a->as_u16[i]));
516           last_double_colon = 0;
517         }
518     }
519
520   return s;
521 }
522
523 /* Format an IP46 address. */
524 u8 *
525 format_ip46_address (u8 * s, va_list * args)
526 {
527   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
528   ip46_type_t type = va_arg (*args, ip46_type_t);
529   int is_ip4 = 1;
530
531   switch (type)
532     {
533     case IP46_TYPE_ANY:
534       is_ip4 = ip46_address_is_ip4 (ip46);
535       break;
536     case IP46_TYPE_IP4:
537       is_ip4 = 1;
538       break;
539     case IP46_TYPE_IP6:
540       is_ip4 = 0;
541       break;
542     }
543
544   return is_ip4 ?
545     format (s, "%U", format_ip4_address, &ip46->ip4) :
546     format (s, "%U", format_ip6_address, &ip46->ip6);
547 }
548
549 u8 *
550 format_ethernet_address (u8 * s, va_list * args)
551 {
552   u8 *a = va_arg (*args, u8 *);
553
554   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
555                  a[0], a[1], a[2], a[3], a[4], a[5]);
556 }
557
558 void
559 increment_v4_address (ip4_address_t * a)
560 {
561   u32 v;
562
563   v = ntohl (a->as_u32) + 1;
564   a->as_u32 = ntohl (v);
565 }
566
567 void
568 increment_v6_address (ip6_address_t * a)
569 {
570   u64 v0, v1;
571
572   v0 = clib_net_to_host_u64 (a->as_u64[0]);
573   v1 = clib_net_to_host_u64 (a->as_u64[1]);
574
575   v1 += 1;
576   if (v1 == 0)
577     v0 += 1;
578   a->as_u64[0] = clib_net_to_host_u64 (v0);
579   a->as_u64[1] = clib_net_to_host_u64 (v1);
580 }
581
582 void
583 increment_mac_address (u64 * mac)
584 {
585   u64 tmp = *mac;
586
587   tmp = clib_net_to_host_u64 (tmp);
588   tmp += 1 << 16;               /* skip unused (least significant) octets */
589   tmp = clib_host_to_net_u64 (tmp);
590   *mac = tmp;
591 }
592
593 static void vl_api_create_loopback_reply_t_handler
594   (vl_api_create_loopback_reply_t * mp)
595 {
596   vat_main_t *vam = &vat_main;
597   i32 retval = ntohl (mp->retval);
598
599   vam->retval = retval;
600   vam->regenerate_interface_table = 1;
601   vam->sw_if_index = ntohl (mp->sw_if_index);
602   vam->result_ready = 1;
603 }
604
605 static void vl_api_create_loopback_reply_t_handler_json
606   (vl_api_create_loopback_reply_t * mp)
607 {
608   vat_main_t *vam = &vat_main;
609   vat_json_node_t node;
610
611   vat_json_init_object (&node);
612   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
613   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
614
615   vat_json_print (vam->ofp, &node);
616   vat_json_free (&node);
617   vam->retval = ntohl (mp->retval);
618   vam->result_ready = 1;
619 }
620
621 static void vl_api_af_packet_create_reply_t_handler
622   (vl_api_af_packet_create_reply_t * mp)
623 {
624   vat_main_t *vam = &vat_main;
625   i32 retval = ntohl (mp->retval);
626
627   vam->retval = retval;
628   vam->regenerate_interface_table = 1;
629   vam->sw_if_index = ntohl (mp->sw_if_index);
630   vam->result_ready = 1;
631 }
632
633 static void vl_api_af_packet_create_reply_t_handler_json
634   (vl_api_af_packet_create_reply_t * mp)
635 {
636   vat_main_t *vam = &vat_main;
637   vat_json_node_t node;
638
639   vat_json_init_object (&node);
640   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
641   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
642
643   vat_json_print (vam->ofp, &node);
644   vat_json_free (&node);
645
646   vam->retval = ntohl (mp->retval);
647   vam->result_ready = 1;
648 }
649
650 static void vl_api_create_vlan_subif_reply_t_handler
651   (vl_api_create_vlan_subif_reply_t * mp)
652 {
653   vat_main_t *vam = &vat_main;
654   i32 retval = ntohl (mp->retval);
655
656   vam->retval = retval;
657   vam->regenerate_interface_table = 1;
658   vam->sw_if_index = ntohl (mp->sw_if_index);
659   vam->result_ready = 1;
660 }
661
662 static void vl_api_create_vlan_subif_reply_t_handler_json
663   (vl_api_create_vlan_subif_reply_t * mp)
664 {
665   vat_main_t *vam = &vat_main;
666   vat_json_node_t node;
667
668   vat_json_init_object (&node);
669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
670   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
671
672   vat_json_print (vam->ofp, &node);
673   vat_json_free (&node);
674
675   vam->retval = ntohl (mp->retval);
676   vam->result_ready = 1;
677 }
678
679 static void vl_api_create_subif_reply_t_handler
680   (vl_api_create_subif_reply_t * mp)
681 {
682   vat_main_t *vam = &vat_main;
683   i32 retval = ntohl (mp->retval);
684
685   vam->retval = retval;
686   vam->regenerate_interface_table = 1;
687   vam->sw_if_index = ntohl (mp->sw_if_index);
688   vam->result_ready = 1;
689 }
690
691 static void vl_api_create_subif_reply_t_handler_json
692   (vl_api_create_subif_reply_t * mp)
693 {
694   vat_main_t *vam = &vat_main;
695   vat_json_node_t node;
696
697   vat_json_init_object (&node);
698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
699   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
700
701   vat_json_print (vam->ofp, &node);
702   vat_json_free (&node);
703
704   vam->retval = ntohl (mp->retval);
705   vam->result_ready = 1;
706 }
707
708 static void vl_api_interface_name_renumber_reply_t_handler
709   (vl_api_interface_name_renumber_reply_t * mp)
710 {
711   vat_main_t *vam = &vat_main;
712   i32 retval = ntohl (mp->retval);
713
714   vam->retval = retval;
715   vam->regenerate_interface_table = 1;
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler_json
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   vat_json_node_t node;
724
725   vat_json_init_object (&node);
726   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
727
728   vat_json_print (vam->ofp, &node);
729   vat_json_free (&node);
730
731   vam->retval = ntohl (mp->retval);
732   vam->result_ready = 1;
733 }
734
735 /*
736  * Special-case: build the interface table, maintain
737  * the next loopback sw_if_index vbl.
738  */
739 static void vl_api_sw_interface_details_t_handler
740   (vl_api_sw_interface_details_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   u8 *s = format (0, "%s%c", mp->interface_name, 0);
744
745   hash_set_mem (vam->sw_if_index_by_interface_name, s,
746                 ntohl (mp->sw_if_index));
747
748   /* In sub interface case, fill the sub interface table entry */
749   if (mp->sw_if_index != mp->sup_sw_if_index)
750     {
751       sw_interface_subif_t *sub = NULL;
752
753       vec_add2 (vam->sw_if_subif_table, sub, 1);
754
755       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
756       strncpy ((char *) sub->interface_name, (char *) s,
757                vec_len (sub->interface_name));
758       sub->sw_if_index = ntohl (mp->sw_if_index);
759       sub->sub_id = ntohl (mp->sub_id);
760
761       sub->sub_dot1ad = mp->sub_dot1ad;
762       sub->sub_number_of_tags = mp->sub_number_of_tags;
763       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
764       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
765       sub->sub_exact_match = mp->sub_exact_match;
766       sub->sub_default = mp->sub_default;
767       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
768       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
769
770       /* vlan tag rewrite */
771       sub->vtr_op = ntohl (mp->vtr_op);
772       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
773       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
774       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
775     }
776 }
777
778 static void vl_api_sw_interface_details_t_handler_json
779   (vl_api_sw_interface_details_t * mp)
780 {
781   vat_main_t *vam = &vat_main;
782   vat_json_node_t *node = NULL;
783
784   if (VAT_JSON_ARRAY != vam->json_tree.type)
785     {
786       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
787       vat_json_init_array (&vam->json_tree);
788     }
789   node = vat_json_array_add (&vam->json_tree);
790
791   vat_json_init_object (node);
792   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
793   vat_json_object_add_uint (node, "sup_sw_if_index",
794                             ntohl (mp->sup_sw_if_index));
795   vat_json_object_add_uint (node, "l2_address_length",
796                             ntohl (mp->l2_address_length));
797   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
798                              sizeof (mp->l2_address));
799   vat_json_object_add_string_copy (node, "interface_name",
800                                    mp->interface_name);
801   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
802   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
803   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
804   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
805   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
806   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
807   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
808   vat_json_object_add_uint (node, "sub_number_of_tags",
809                             mp->sub_number_of_tags);
810   vat_json_object_add_uint (node, "sub_outer_vlan_id",
811                             ntohs (mp->sub_outer_vlan_id));
812   vat_json_object_add_uint (node, "sub_inner_vlan_id",
813                             ntohs (mp->sub_inner_vlan_id));
814   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
815   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
816   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
817                             mp->sub_outer_vlan_id_any);
818   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
819                             mp->sub_inner_vlan_id_any);
820   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
821   vat_json_object_add_uint (node, "vtr_push_dot1q",
822                             ntohl (mp->vtr_push_dot1q));
823   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
824   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
825 }
826
827 static void vl_api_sw_interface_set_flags_t_handler
828   (vl_api_sw_interface_set_flags_t * mp)
829 {
830   vat_main_t *vam = &vat_main;
831   if (vam->interface_event_display)
832     errmsg ("interface flags: sw_if_index %d %s %s\n",
833             ntohl (mp->sw_if_index),
834             mp->admin_up_down ? "admin-up" : "admin-down",
835             mp->link_up_down ? "link-up" : "link-down");
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler_json
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   /* JSON output not supported */
842 }
843
844 static void
845 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
846 {
847   vat_main_t *vam = &vat_main;
848   i32 retval = ntohl (mp->retval);
849
850   vam->retval = retval;
851   vam->shmem_result = (u8 *) mp->reply_in_shmem;
852   vam->result_ready = 1;
853 }
854
855 static void
856 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   vat_json_node_t node;
860   api_main_t *am = &api_main;
861   void *oldheap;
862   u8 *reply;
863
864   vat_json_init_object (&node);
865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
866   vat_json_object_add_uint (&node, "reply_in_shmem",
867                             ntohl (mp->reply_in_shmem));
868   /* Toss the shared-memory original... */
869   pthread_mutex_lock (&am->vlib_rp->mutex);
870   oldheap = svm_push_data_heap (am->vlib_rp);
871
872   reply = (u8 *) (mp->reply_in_shmem);
873   vec_free (reply);
874
875   svm_pop_heap (oldheap);
876   pthread_mutex_unlock (&am->vlib_rp->mutex);
877
878   vat_json_print (vam->ofp, &node);
879   vat_json_free (&node);
880
881   vam->retval = ntohl (mp->retval);
882   vam->result_ready = 1;
883 }
884
885 static void
886 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   i32 retval = ntohl (mp->retval);
890
891   vam->retval = retval;
892   vam->cmd_reply = mp->reply;
893   vam->result_ready = 1;
894 }
895
896 static void
897 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   vat_json_node_t node;
901
902   vat_json_init_object (&node);
903   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
904   vat_json_object_add_string_copy (&node, "reply", mp->reply);
905
906   vat_json_print (vam->ofp, &node);
907   vat_json_free (&node);
908
909   vam->retval = ntohl (mp->retval);
910   vam->result_ready = 1;
911 }
912
913 static void vl_api_classify_add_del_table_reply_t_handler
914   (vl_api_classify_add_del_table_reply_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   i32 retval = ntohl (mp->retval);
918   if (vam->async_mode)
919     {
920       vam->async_errors += (retval < 0);
921     }
922   else
923     {
924       vam->retval = retval;
925       if (retval == 0 &&
926           ((mp->new_table_index != 0xFFFFFFFF) ||
927            (mp->skip_n_vectors != 0xFFFFFFFF) ||
928            (mp->match_n_vectors != 0xFFFFFFFF)))
929         /*
930          * Note: this is just barely thread-safe, depends on
931          * the main thread spinning waiting for an answer...
932          */
933         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
934                 ntohl (mp->new_table_index),
935                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
936       vam->result_ready = 1;
937     }
938 }
939
940 static void vl_api_classify_add_del_table_reply_t_handler_json
941   (vl_api_classify_add_del_table_reply_t * mp)
942 {
943   vat_main_t *vam = &vat_main;
944   vat_json_node_t node;
945
946   vat_json_init_object (&node);
947   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
948   vat_json_object_add_uint (&node, "new_table_index",
949                             ntohl (mp->new_table_index));
950   vat_json_object_add_uint (&node, "skip_n_vectors",
951                             ntohl (mp->skip_n_vectors));
952   vat_json_object_add_uint (&node, "match_n_vectors",
953                             ntohl (mp->match_n_vectors));
954
955   vat_json_print (vam->ofp, &node);
956   vat_json_free (&node);
957
958   vam->retval = ntohl (mp->retval);
959   vam->result_ready = 1;
960 }
961
962 static void vl_api_get_node_index_reply_t_handler
963   (vl_api_get_node_index_reply_t * mp)
964 {
965   vat_main_t *vam = &vat_main;
966   i32 retval = ntohl (mp->retval);
967   if (vam->async_mode)
968     {
969       vam->async_errors += (retval < 0);
970     }
971   else
972     {
973       vam->retval = retval;
974       if (retval == 0)
975         errmsg ("node index %d\n", ntohl (mp->node_index));
976       vam->result_ready = 1;
977     }
978 }
979
980 static void vl_api_get_node_index_reply_t_handler_json
981   (vl_api_get_node_index_reply_t * mp)
982 {
983   vat_main_t *vam = &vat_main;
984   vat_json_node_t node;
985
986   vat_json_init_object (&node);
987   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
988   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
989
990   vat_json_print (vam->ofp, &node);
991   vat_json_free (&node);
992
993   vam->retval = ntohl (mp->retval);
994   vam->result_ready = 1;
995 }
996
997 static void vl_api_get_next_index_reply_t_handler
998   (vl_api_get_next_index_reply_t * mp)
999 {
1000   vat_main_t *vam = &vat_main;
1001   i32 retval = ntohl (mp->retval);
1002   if (vam->async_mode)
1003     {
1004       vam->async_errors += (retval < 0);
1005     }
1006   else
1007     {
1008       vam->retval = retval;
1009       if (retval == 0)
1010         errmsg ("next node index %d\n", ntohl (mp->next_index));
1011       vam->result_ready = 1;
1012     }
1013 }
1014
1015 static void vl_api_get_next_index_reply_t_handler_json
1016   (vl_api_get_next_index_reply_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   vat_json_node_t node;
1020
1021   vat_json_init_object (&node);
1022   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1023   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1024
1025   vat_json_print (vam->ofp, &node);
1026   vat_json_free (&node);
1027
1028   vam->retval = ntohl (mp->retval);
1029   vam->result_ready = 1;
1030 }
1031
1032 static void vl_api_add_node_next_reply_t_handler
1033   (vl_api_add_node_next_reply_t * mp)
1034 {
1035   vat_main_t *vam = &vat_main;
1036   i32 retval = ntohl (mp->retval);
1037   if (vam->async_mode)
1038     {
1039       vam->async_errors += (retval < 0);
1040     }
1041   else
1042     {
1043       vam->retval = retval;
1044       if (retval == 0)
1045         errmsg ("next index %d\n", ntohl (mp->next_index));
1046       vam->result_ready = 1;
1047     }
1048 }
1049
1050 static void vl_api_add_node_next_reply_t_handler_json
1051   (vl_api_add_node_next_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   vat_json_node_t node;
1055
1056   vat_json_init_object (&node);
1057   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1058   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1059
1060   vat_json_print (vam->ofp, &node);
1061   vat_json_free (&node);
1062
1063   vam->retval = ntohl (mp->retval);
1064   vam->result_ready = 1;
1065 }
1066
1067 static void vl_api_show_version_reply_t_handler
1068   (vl_api_show_version_reply_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   i32 retval = ntohl (mp->retval);
1072
1073   if (retval >= 0)
1074     {
1075       errmsg ("        program: %s\n", mp->program);
1076       errmsg ("        version: %s\n", mp->version);
1077       errmsg ("     build date: %s\n", mp->build_date);
1078       errmsg ("build directory: %s\n", mp->build_directory);
1079     }
1080   vam->retval = retval;
1081   vam->result_ready = 1;
1082 }
1083
1084 static void vl_api_show_version_reply_t_handler_json
1085   (vl_api_show_version_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   vat_json_node_t node;
1089
1090   vat_json_init_object (&node);
1091   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1092   vat_json_object_add_string_copy (&node, "program", mp->program);
1093   vat_json_object_add_string_copy (&node, "version", mp->version);
1094   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1095   vat_json_object_add_string_copy (&node, "build_directory",
1096                                    mp->build_directory);
1097
1098   vat_json_print (vam->ofp, &node);
1099   vat_json_free (&node);
1100
1101   vam->retval = ntohl (mp->retval);
1102   vam->result_ready = 1;
1103 }
1104
1105 static void
1106 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1107 {
1108   vat_main_t *vam = &vat_main;
1109   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1110           mp->mac_ip ? "mac/ip binding" : "address resolution",
1111           format_ip4_address, &mp->address,
1112           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1113 }
1114
1115 static void
1116 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1117 {
1118   /* JSON output not supported */
1119 }
1120
1121 static void
1122 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1123 {
1124   vat_main_t *vam = &vat_main;
1125   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1126           mp->mac_ip ? "mac/ip binding" : "address resolution",
1127           format_ip6_address, mp->address,
1128           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1129 }
1130
1131 static void
1132 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1133 {
1134   /* JSON output not supported */
1135 }
1136
1137 /*
1138  * Special-case: build the bridge domain table, maintain
1139  * the next bd id vbl.
1140  */
1141 static void vl_api_bridge_domain_details_t_handler
1142   (vl_api_bridge_domain_details_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1146
1147   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1148            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1149
1150   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1151            ntohl (mp->bd_id), mp->learn, mp->forward,
1152            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1153
1154   if (n_sw_ifs)
1155     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1156              "Interface Name");
1157 }
1158
1159 static void vl_api_bridge_domain_details_t_handler_json
1160   (vl_api_bridge_domain_details_t * mp)
1161 {
1162   vat_main_t *vam = &vat_main;
1163   vat_json_node_t *node, *array = NULL;
1164
1165   if (VAT_JSON_ARRAY != vam->json_tree.type)
1166     {
1167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1168       vat_json_init_array (&vam->json_tree);
1169     }
1170   node = vat_json_array_add (&vam->json_tree);
1171
1172   vat_json_init_object (node);
1173   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1174   vat_json_object_add_uint (node, "flood", mp->flood);
1175   vat_json_object_add_uint (node, "forward", mp->forward);
1176   vat_json_object_add_uint (node, "learn", mp->learn);
1177   vat_json_object_add_uint (node, "bvi_sw_if_index",
1178                             ntohl (mp->bvi_sw_if_index));
1179   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1180   array = vat_json_object_add (node, "sw_if");
1181   vat_json_init_array (array);
1182 }
1183
1184 /*
1185  * Special-case: build the bridge domain sw if table.
1186  */
1187 static void vl_api_bridge_domain_sw_if_details_t_handler
1188   (vl_api_bridge_domain_sw_if_details_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   hash_pair_t *p;
1192   u8 *sw_if_name = 0;
1193   u32 sw_if_index;
1194
1195   sw_if_index = ntohl (mp->sw_if_index);
1196   /* *INDENT-OFF* */
1197   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1198   ({
1199     if ((u32) p->value[0] == sw_if_index)
1200       {
1201         sw_if_name = (u8 *)(p->key);
1202         break;
1203       }
1204   }));
1205   /* *INDENT-ON* */
1206
1207   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1208            mp->shg, sw_if_name ? (char *) sw_if_name :
1209            "sw_if_index not found!");
1210 }
1211
1212 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1213   (vl_api_bridge_domain_sw_if_details_t * mp)
1214 {
1215   vat_main_t *vam = &vat_main;
1216   vat_json_node_t *node = NULL;
1217   uword last_index = 0;
1218
1219   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1220   ASSERT (vec_len (vam->json_tree.array) >= 1);
1221   last_index = vec_len (vam->json_tree.array) - 1;
1222   node = &vam->json_tree.array[last_index];
1223   node = vat_json_object_get_element (node, "sw_if");
1224   ASSERT (NULL != node);
1225   node = vat_json_array_add (node);
1226
1227   vat_json_init_object (node);
1228   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1230   vat_json_object_add_uint (node, "shg", mp->shg);
1231 }
1232
1233 static void vl_api_control_ping_reply_t_handler
1234   (vl_api_control_ping_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   i32 retval = ntohl (mp->retval);
1238   if (vam->async_mode)
1239     {
1240       vam->async_errors += (retval < 0);
1241     }
1242   else
1243     {
1244       vam->retval = retval;
1245       vam->result_ready = 1;
1246     }
1247 }
1248
1249 static void vl_api_control_ping_reply_t_handler_json
1250   (vl_api_control_ping_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254
1255   if (VAT_JSON_NONE != vam->json_tree.type)
1256     {
1257       vat_json_print (vam->ofp, &vam->json_tree);
1258       vat_json_free (&vam->json_tree);
1259       vam->json_tree.type = VAT_JSON_NONE;
1260     }
1261   else
1262     {
1263       /* just print [] */
1264       vat_json_init_array (&vam->json_tree);
1265       vat_json_print (vam->ofp, &vam->json_tree);
1266       vam->json_tree.type = VAT_JSON_NONE;
1267     }
1268
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void
1274 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278   if (vam->async_mode)
1279     {
1280       vam->async_errors += (retval < 0);
1281     }
1282   else
1283     {
1284       vam->retval = retval;
1285       vam->result_ready = 1;
1286     }
1287 }
1288
1289 static void vl_api_l2_flags_reply_t_handler_json
1290   (vl_api_l2_flags_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   vat_json_node_t node;
1294
1295   vat_json_init_object (&node);
1296   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1297   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1298                             ntohl (mp->resulting_feature_bitmap));
1299
1300   vat_json_print (vam->ofp, &node);
1301   vat_json_free (&node);
1302
1303   vam->retval = ntohl (mp->retval);
1304   vam->result_ready = 1;
1305 }
1306
1307 static void vl_api_bridge_flags_reply_t_handler
1308   (vl_api_bridge_flags_reply_t * mp)
1309 {
1310   vat_main_t *vam = &vat_main;
1311   i32 retval = ntohl (mp->retval);
1312   if (vam->async_mode)
1313     {
1314       vam->async_errors += (retval < 0);
1315     }
1316   else
1317     {
1318       vam->retval = retval;
1319       vam->result_ready = 1;
1320     }
1321 }
1322
1323 static void vl_api_bridge_flags_reply_t_handler_json
1324   (vl_api_bridge_flags_reply_t * mp)
1325 {
1326   vat_main_t *vam = &vat_main;
1327   vat_json_node_t node;
1328
1329   vat_json_init_object (&node);
1330   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1331   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1332                             ntohl (mp->resulting_feature_bitmap));
1333
1334   vat_json_print (vam->ofp, &node);
1335   vat_json_free (&node);
1336
1337   vam->retval = ntohl (mp->retval);
1338   vam->result_ready = 1;
1339 }
1340
1341 static void vl_api_tap_connect_reply_t_handler
1342   (vl_api_tap_connect_reply_t * mp)
1343 {
1344   vat_main_t *vam = &vat_main;
1345   i32 retval = ntohl (mp->retval);
1346   if (vam->async_mode)
1347     {
1348       vam->async_errors += (retval < 0);
1349     }
1350   else
1351     {
1352       vam->retval = retval;
1353       vam->sw_if_index = ntohl (mp->sw_if_index);
1354       vam->result_ready = 1;
1355     }
1356
1357 }
1358
1359 static void vl_api_tap_connect_reply_t_handler_json
1360   (vl_api_tap_connect_reply_t * mp)
1361 {
1362   vat_main_t *vam = &vat_main;
1363   vat_json_node_t node;
1364
1365   vat_json_init_object (&node);
1366   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1367   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1368
1369   vat_json_print (vam->ofp, &node);
1370   vat_json_free (&node);
1371
1372   vam->retval = ntohl (mp->retval);
1373   vam->result_ready = 1;
1374
1375 }
1376
1377 static void
1378 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1379 {
1380   vat_main_t *vam = &vat_main;
1381   i32 retval = ntohl (mp->retval);
1382   if (vam->async_mode)
1383     {
1384       vam->async_errors += (retval < 0);
1385     }
1386   else
1387     {
1388       vam->retval = retval;
1389       vam->sw_if_index = ntohl (mp->sw_if_index);
1390       vam->result_ready = 1;
1391     }
1392 }
1393
1394 static void vl_api_tap_modify_reply_t_handler_json
1395   (vl_api_tap_modify_reply_t * mp)
1396 {
1397   vat_main_t *vam = &vat_main;
1398   vat_json_node_t node;
1399
1400   vat_json_init_object (&node);
1401   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1402   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1403
1404   vat_json_print (vam->ofp, &node);
1405   vat_json_free (&node);
1406
1407   vam->retval = ntohl (mp->retval);
1408   vam->result_ready = 1;
1409 }
1410
1411 static void
1412 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1413 {
1414   vat_main_t *vam = &vat_main;
1415   i32 retval = ntohl (mp->retval);
1416   if (vam->async_mode)
1417     {
1418       vam->async_errors += (retval < 0);
1419     }
1420   else
1421     {
1422       vam->retval = retval;
1423       vam->result_ready = 1;
1424     }
1425 }
1426
1427 static void vl_api_tap_delete_reply_t_handler_json
1428   (vl_api_tap_delete_reply_t * mp)
1429 {
1430   vat_main_t *vam = &vat_main;
1431   vat_json_node_t node;
1432
1433   vat_json_init_object (&node);
1434   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1435
1436   vat_json_print (vam->ofp, &node);
1437   vat_json_free (&node);
1438
1439   vam->retval = ntohl (mp->retval);
1440   vam->result_ready = 1;
1441 }
1442
1443 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1444   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   i32 retval = ntohl (mp->retval);
1448   if (vam->async_mode)
1449     {
1450       vam->async_errors += (retval < 0);
1451     }
1452   else
1453     {
1454       vam->retval = retval;
1455       vam->result_ready = 1;
1456     }
1457 }
1458
1459 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1460   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   vat_json_node_t node;
1464
1465   vat_json_init_object (&node);
1466   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1467   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1468                             ntohl (mp->sw_if_index));
1469
1470   vat_json_print (vam->ofp, &node);
1471   vat_json_free (&node);
1472
1473   vam->retval = ntohl (mp->retval);
1474   vam->result_ready = 1;
1475 }
1476
1477 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1478   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1479 {
1480   vat_main_t *vam = &vat_main;
1481   i32 retval = ntohl (mp->retval);
1482   if (vam->async_mode)
1483     {
1484       vam->async_errors += (retval < 0);
1485     }
1486   else
1487     {
1488       vam->retval = retval;
1489       vam->sw_if_index = ntohl (mp->sw_if_index);
1490       vam->result_ready = 1;
1491     }
1492 }
1493
1494 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1495   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   vat_json_node_t node;
1499
1500   vat_json_init_object (&node);
1501   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1502   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1503
1504   vat_json_print (vam->ofp, &node);
1505   vat_json_free (&node);
1506
1507   vam->retval = ntohl (mp->retval);
1508   vam->result_ready = 1;
1509 }
1510
1511
1512 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1513   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1514 {
1515   vat_main_t *vam = &vat_main;
1516   i32 retval = ntohl (mp->retval);
1517   if (vam->async_mode)
1518     {
1519       vam->async_errors += (retval < 0);
1520     }
1521   else
1522     {
1523       vam->retval = retval;
1524       vam->result_ready = 1;
1525     }
1526 }
1527
1528 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1529   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1530 {
1531   vat_main_t *vam = &vat_main;
1532   vat_json_node_t node;
1533
1534   vat_json_init_object (&node);
1535   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1536   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1537
1538   vat_json_print (vam->ofp, &node);
1539   vat_json_free (&node);
1540
1541   vam->retval = ntohl (mp->retval);
1542   vam->result_ready = 1;
1543 }
1544
1545 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1546   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   i32 retval = ntohl (mp->retval);
1550   if (vam->async_mode)
1551     {
1552       vam->async_errors += (retval < 0);
1553     }
1554   else
1555     {
1556       vam->retval = retval;
1557       vam->sw_if_index = ntohl (mp->sw_if_index);
1558       vam->result_ready = 1;
1559     }
1560 }
1561
1562 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1563   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1564 {
1565   vat_main_t *vam = &vat_main;
1566   vat_json_node_t node;
1567
1568   vat_json_init_object (&node);
1569   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1570   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1571
1572   vat_json_print (vam->ofp, &node);
1573   vat_json_free (&node);
1574
1575   vam->retval = ntohl (mp->retval);
1576   vam->result_ready = 1;
1577 }
1578
1579 static void vl_api_gre_add_del_tunnel_reply_t_handler
1580   (vl_api_gre_add_del_tunnel_reply_t * mp)
1581 {
1582   vat_main_t *vam = &vat_main;
1583   i32 retval = ntohl (mp->retval);
1584   if (vam->async_mode)
1585     {
1586       vam->async_errors += (retval < 0);
1587     }
1588   else
1589     {
1590       vam->retval = retval;
1591       vam->sw_if_index = ntohl (mp->sw_if_index);
1592       vam->result_ready = 1;
1593     }
1594 }
1595
1596 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1597   (vl_api_gre_add_del_tunnel_reply_t * mp)
1598 {
1599   vat_main_t *vam = &vat_main;
1600   vat_json_node_t node;
1601
1602   vat_json_init_object (&node);
1603   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1604   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1605
1606   vat_json_print (vam->ofp, &node);
1607   vat_json_free (&node);
1608
1609   vam->retval = ntohl (mp->retval);
1610   vam->result_ready = 1;
1611 }
1612
1613 static void vl_api_create_vhost_user_if_reply_t_handler
1614   (vl_api_create_vhost_user_if_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   i32 retval = ntohl (mp->retval);
1618   if (vam->async_mode)
1619     {
1620       vam->async_errors += (retval < 0);
1621     }
1622   else
1623     {
1624       vam->retval = retval;
1625       vam->sw_if_index = ntohl (mp->sw_if_index);
1626       vam->result_ready = 1;
1627     }
1628 }
1629
1630 static void vl_api_create_vhost_user_if_reply_t_handler_json
1631   (vl_api_create_vhost_user_if_reply_t * mp)
1632 {
1633   vat_main_t *vam = &vat_main;
1634   vat_json_node_t node;
1635
1636   vat_json_init_object (&node);
1637   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1638   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1639
1640   vat_json_print (vam->ofp, &node);
1641   vat_json_free (&node);
1642
1643   vam->retval = ntohl (mp->retval);
1644   vam->result_ready = 1;
1645 }
1646
1647 static void vl_api_ip_address_details_t_handler
1648   (vl_api_ip_address_details_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   static ip_address_details_t empty_ip_address_details = { {0} };
1652   ip_address_details_t *address = NULL;
1653   ip_details_t *current_ip_details = NULL;
1654   ip_details_t *details = NULL;
1655
1656   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1657
1658   if (!details || vam->current_sw_if_index >= vec_len (details)
1659       || !details[vam->current_sw_if_index].present)
1660     {
1661       errmsg ("ip address details arrived but not stored\n");
1662       errmsg ("ip_dump should be called first\n");
1663       return;
1664     }
1665
1666   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1667
1668 #define addresses (current_ip_details->addr)
1669
1670   vec_validate_init_empty (addresses, vec_len (addresses),
1671                            empty_ip_address_details);
1672
1673   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1674
1675   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1676   address->prefix_length = mp->prefix_length;
1677 #undef addresses
1678 }
1679
1680 static void vl_api_ip_address_details_t_handler_json
1681   (vl_api_ip_address_details_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t *node = NULL;
1685   struct in6_addr ip6;
1686   struct in_addr ip4;
1687
1688   if (VAT_JSON_ARRAY != vam->json_tree.type)
1689     {
1690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1691       vat_json_init_array (&vam->json_tree);
1692     }
1693   node = vat_json_array_add (&vam->json_tree);
1694
1695   vat_json_init_object (node);
1696   if (vam->is_ipv6)
1697     {
1698       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1699       vat_json_object_add_ip6 (node, "ip", ip6);
1700     }
1701   else
1702     {
1703       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1704       vat_json_object_add_ip4 (node, "ip", ip4);
1705     }
1706   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1707 }
1708
1709 static void
1710 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   static ip_details_t empty_ip_details = { 0 };
1714   ip_details_t *ip = NULL;
1715   u32 sw_if_index = ~0;
1716
1717   sw_if_index = ntohl (mp->sw_if_index);
1718
1719   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1720                            sw_if_index, empty_ip_details);
1721
1722   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1723                          sw_if_index);
1724
1725   ip->present = 1;
1726 }
1727
1728 static void
1729 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732
1733   if (VAT_JSON_ARRAY != vam->json_tree.type)
1734     {
1735       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1736       vat_json_init_array (&vam->json_tree);
1737     }
1738   vat_json_array_add_uint (&vam->json_tree,
1739                            clib_net_to_host_u32 (mp->sw_if_index));
1740 }
1741
1742 static void vl_api_map_domain_details_t_handler_json
1743   (vl_api_map_domain_details_t * mp)
1744 {
1745   vat_json_node_t *node = NULL;
1746   vat_main_t *vam = &vat_main;
1747   struct in6_addr ip6;
1748   struct in_addr ip4;
1749
1750   if (VAT_JSON_ARRAY != vam->json_tree.type)
1751     {
1752       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1753       vat_json_init_array (&vam->json_tree);
1754     }
1755
1756   node = vat_json_array_add (&vam->json_tree);
1757   vat_json_init_object (node);
1758
1759   vat_json_object_add_uint (node, "domain_index",
1760                             clib_net_to_host_u32 (mp->domain_index));
1761   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1762   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1763   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1764   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1765   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1766   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1767   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1768   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1769   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1770   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1771   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1772   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1773   vat_json_object_add_uint (node, "flags", mp->flags);
1774   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1775   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1776 }
1777
1778 static void vl_api_map_domain_details_t_handler
1779   (vl_api_map_domain_details_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782
1783   if (mp->is_translation)
1784     {
1785       fformat (vam->ofp,
1786                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1787                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1788                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1789                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1790                clib_net_to_host_u32 (mp->domain_index));
1791     }
1792   else
1793     {
1794       fformat (vam->ofp,
1795                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1796                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1797                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1798                format_ip6_address, mp->ip6_src,
1799                clib_net_to_host_u32 (mp->domain_index));
1800     }
1801   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1802            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1803            mp->is_translation ? "map-t" : "");
1804 }
1805
1806 static void vl_api_map_rule_details_t_handler_json
1807   (vl_api_map_rule_details_t * mp)
1808 {
1809   struct in6_addr ip6;
1810   vat_json_node_t *node = NULL;
1811   vat_main_t *vam = &vat_main;
1812
1813   if (VAT_JSON_ARRAY != vam->json_tree.type)
1814     {
1815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1816       vat_json_init_array (&vam->json_tree);
1817     }
1818
1819   node = vat_json_array_add (&vam->json_tree);
1820   vat_json_init_object (node);
1821
1822   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1823   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1824   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1825 }
1826
1827 static void
1828 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1829 {
1830   vat_main_t *vam = &vat_main;
1831   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1832            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1833 }
1834
1835 static void
1836 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1837 {
1838   vat_main_t *vam = &vat_main;
1839   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1840           "router_addr %U host_mac %U\n",
1841           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1842           format_ip4_address, &mp->host_address,
1843           format_ip4_address, &mp->router_address,
1844           format_ethernet_address, mp->host_mac);
1845 }
1846
1847 static void vl_api_dhcp_compl_event_t_handler_json
1848   (vl_api_dhcp_compl_event_t * mp)
1849 {
1850   /* JSON output not supported */
1851 }
1852
1853 static void
1854 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1855                               u32 counter)
1856 {
1857   vat_main_t *vam = &vat_main;
1858   static u64 default_counter = 0;
1859
1860   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1861                            NULL);
1862   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1863                            sw_if_index, default_counter);
1864   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1865 }
1866
1867 static void
1868 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1869                                 interface_counter_t counter)
1870 {
1871   vat_main_t *vam = &vat_main;
1872   static interface_counter_t default_counter = { 0, };
1873
1874   vec_validate_init_empty (vam->combined_interface_counters,
1875                            vnet_counter_type, NULL);
1876   vec_validate_init_empty (vam->combined_interface_counters
1877                            [vnet_counter_type], sw_if_index, default_counter);
1878   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1879 }
1880
1881 static void vl_api_vnet_interface_counters_t_handler
1882   (vl_api_vnet_interface_counters_t * mp)
1883 {
1884   /* not supported */
1885 }
1886
1887 static void vl_api_vnet_interface_counters_t_handler_json
1888   (vl_api_vnet_interface_counters_t * mp)
1889 {
1890   interface_counter_t counter;
1891   vlib_counter_t *v;
1892   u64 *v_packets;
1893   u64 packets;
1894   u32 count;
1895   u32 first_sw_if_index;
1896   int i;
1897
1898   count = ntohl (mp->count);
1899   first_sw_if_index = ntohl (mp->first_sw_if_index);
1900
1901   if (!mp->is_combined)
1902     {
1903       v_packets = (u64 *) & mp->data;
1904       for (i = 0; i < count; i++)
1905         {
1906           packets =
1907             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1908           set_simple_interface_counter (mp->vnet_counter_type,
1909                                         first_sw_if_index + i, packets);
1910           v_packets++;
1911         }
1912     }
1913   else
1914     {
1915       v = (vlib_counter_t *) & mp->data;
1916       for (i = 0; i < count; i++)
1917         {
1918           counter.packets =
1919             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1920           counter.bytes =
1921             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1922           set_combined_interface_counter (mp->vnet_counter_type,
1923                                           first_sw_if_index + i, counter);
1924           v++;
1925         }
1926     }
1927 }
1928
1929 static u32
1930 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1931 {
1932   vat_main_t *vam = &vat_main;
1933   u32 i;
1934
1935   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1936     {
1937       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1938         {
1939           return i;
1940         }
1941     }
1942   return ~0;
1943 }
1944
1945 static u32
1946 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1947 {
1948   vat_main_t *vam = &vat_main;
1949   u32 i;
1950
1951   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1952     {
1953       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1954         {
1955           return i;
1956         }
1957     }
1958   return ~0;
1959 }
1960
1961 static void vl_api_vnet_ip4_fib_counters_t_handler
1962   (vl_api_vnet_ip4_fib_counters_t * mp)
1963 {
1964   /* not supported */
1965 }
1966
1967 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1968   (vl_api_vnet_ip4_fib_counters_t * mp)
1969 {
1970   vat_main_t *vam = &vat_main;
1971   vl_api_ip4_fib_counter_t *v;
1972   ip4_fib_counter_t *counter;
1973   struct in_addr ip4;
1974   u32 vrf_id;
1975   u32 vrf_index;
1976   u32 count;
1977   int i;
1978
1979   vrf_id = ntohl (mp->vrf_id);
1980   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
1981   if (~0 == vrf_index)
1982     {
1983       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
1984       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1985       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1986       vec_validate (vam->ip4_fib_counters, vrf_index);
1987       vam->ip4_fib_counters[vrf_index] = NULL;
1988     }
1989
1990   vec_free (vam->ip4_fib_counters[vrf_index]);
1991   v = (vl_api_ip4_fib_counter_t *) & mp->c;
1992   count = ntohl (mp->count);
1993   for (i = 0; i < count; i++)
1994     {
1995       vec_validate (vam->ip4_fib_counters[vrf_index], i);
1996       counter = &vam->ip4_fib_counters[vrf_index][i];
1997       clib_memcpy (&ip4, &v->address, sizeof (ip4));
1998       counter->address = ip4;
1999       counter->address_length = v->address_length;
2000       counter->packets = clib_net_to_host_u64 (v->packets);
2001       counter->bytes = clib_net_to_host_u64 (v->bytes);
2002       v++;
2003     }
2004 }
2005
2006 static void vl_api_vnet_ip6_fib_counters_t_handler
2007   (vl_api_vnet_ip6_fib_counters_t * mp)
2008 {
2009   /* not supported */
2010 }
2011
2012 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2013   (vl_api_vnet_ip6_fib_counters_t * mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016   vl_api_ip6_fib_counter_t *v;
2017   ip6_fib_counter_t *counter;
2018   struct in6_addr ip6;
2019   u32 vrf_id;
2020   u32 vrf_index;
2021   u32 count;
2022   int i;
2023
2024   vrf_id = ntohl (mp->vrf_id);
2025   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2026   if (~0 == vrf_index)
2027     {
2028       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2029       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2030       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2031       vec_validate (vam->ip6_fib_counters, vrf_index);
2032       vam->ip6_fib_counters[vrf_index] = NULL;
2033     }
2034
2035   vec_free (vam->ip6_fib_counters[vrf_index]);
2036   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2037   count = ntohl (mp->count);
2038   for (i = 0; i < count; i++)
2039     {
2040       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2041       counter = &vam->ip6_fib_counters[vrf_index][i];
2042       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2043       counter->address = ip6;
2044       counter->address_length = v->address_length;
2045       counter->packets = clib_net_to_host_u64 (v->packets);
2046       counter->bytes = clib_net_to_host_u64 (v->bytes);
2047       v++;
2048     }
2049 }
2050
2051 static void vl_api_get_first_msg_id_reply_t_handler
2052   (vl_api_get_first_msg_id_reply_t * mp)
2053 {
2054   vat_main_t *vam = &vat_main;
2055   i32 retval = ntohl (mp->retval);
2056
2057   if (vam->async_mode)
2058     {
2059       vam->async_errors += (retval < 0);
2060     }
2061   else
2062     {
2063       vam->retval = retval;
2064       vam->result_ready = 1;
2065     }
2066   if (retval >= 0)
2067     {
2068       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2069     }
2070 }
2071
2072 static void vl_api_get_first_msg_id_reply_t_handler_json
2073   (vl_api_get_first_msg_id_reply_t * mp)
2074 {
2075   vat_main_t *vam = &vat_main;
2076   vat_json_node_t node;
2077
2078   vat_json_init_object (&node);
2079   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2080   vat_json_object_add_uint (&node, "first_msg_id",
2081                             (uint) ntohs (mp->first_msg_id));
2082
2083   vat_json_print (vam->ofp, &node);
2084   vat_json_free (&node);
2085
2086   vam->retval = ntohl (mp->retval);
2087   vam->result_ready = 1;
2088 }
2089
2090 static void vl_api_get_node_graph_reply_t_handler
2091   (vl_api_get_node_graph_reply_t * mp)
2092 {
2093   vat_main_t *vam = &vat_main;
2094   api_main_t *am = &api_main;
2095   i32 retval = ntohl (mp->retval);
2096   u8 *pvt_copy, *reply;
2097   void *oldheap;
2098   vlib_node_t *node;
2099   int i;
2100
2101   if (vam->async_mode)
2102     {
2103       vam->async_errors += (retval < 0);
2104     }
2105   else
2106     {
2107       vam->retval = retval;
2108       vam->result_ready = 1;
2109     }
2110
2111   /* "Should never happen..." */
2112   if (retval != 0)
2113     return;
2114
2115   reply = (u8 *) (mp->reply_in_shmem);
2116   pvt_copy = vec_dup (reply);
2117
2118   /* Toss the shared-memory original... */
2119   pthread_mutex_lock (&am->vlib_rp->mutex);
2120   oldheap = svm_push_data_heap (am->vlib_rp);
2121
2122   vec_free (reply);
2123
2124   svm_pop_heap (oldheap);
2125   pthread_mutex_unlock (&am->vlib_rp->mutex);
2126
2127   if (vam->graph_nodes)
2128     {
2129       hash_free (vam->graph_node_index_by_name);
2130
2131       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2132         {
2133           node = vam->graph_nodes[i];
2134           vec_free (node->name);
2135           vec_free (node->next_nodes);
2136           vec_free (node);
2137         }
2138       vec_free (vam->graph_nodes);
2139     }
2140
2141   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2142   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2143   vec_free (pvt_copy);
2144
2145   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2146     {
2147       node = vam->graph_nodes[i];
2148       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2149     }
2150 }
2151
2152 static void vl_api_get_node_graph_reply_t_handler_json
2153   (vl_api_get_node_graph_reply_t * mp)
2154 {
2155   vat_main_t *vam = &vat_main;
2156   api_main_t *am = &api_main;
2157   void *oldheap;
2158   vat_json_node_t node;
2159   u8 *reply;
2160
2161   /* $$$$ make this real? */
2162   vat_json_init_object (&node);
2163   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2164   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2165
2166   reply = (u8 *) (mp->reply_in_shmem);
2167
2168   /* Toss the shared-memory original... */
2169   pthread_mutex_lock (&am->vlib_rp->mutex);
2170   oldheap = svm_push_data_heap (am->vlib_rp);
2171
2172   vec_free (reply);
2173
2174   svm_pop_heap (oldheap);
2175   pthread_mutex_unlock (&am->vlib_rp->mutex);
2176
2177   vat_json_print (vam->ofp, &node);
2178   vat_json_free (&node);
2179
2180   vam->retval = ntohl (mp->retval);
2181   vam->result_ready = 1;
2182 }
2183
2184 static void
2185 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2186 {
2187   vat_main_t *vam = &vat_main;
2188   u8 *s = 0;
2189
2190   if (mp->local)
2191     {
2192       s = format (s, "%=16d%=16d%=16d\n",
2193                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2194     }
2195   else
2196     {
2197       s = format (s, "%=16U%=16d%=16d\n",
2198                   mp->is_ipv6 ? format_ip6_address :
2199                   format_ip4_address,
2200                   mp->ip_address, mp->priority, mp->weight);
2201     }
2202
2203   fformat (vam->ofp, "%v", s);
2204   vec_free (s);
2205 }
2206
2207 static void
2208 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2209                                             mp)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   vat_json_node_t *node = NULL;
2213   struct in6_addr ip6;
2214   struct in_addr ip4;
2215
2216   if (VAT_JSON_ARRAY != vam->json_tree.type)
2217     {
2218       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2219       vat_json_init_array (&vam->json_tree);
2220     }
2221   node = vat_json_array_add (&vam->json_tree);
2222   vat_json_init_object (node);
2223
2224   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2225   vat_json_object_add_uint (node, "priority", mp->priority);
2226   vat_json_object_add_uint (node, "weight", mp->weight);
2227
2228   if (mp->local)
2229     vat_json_object_add_uint (node, "sw_if_index",
2230                               clib_net_to_host_u32 (mp->sw_if_index));
2231   else
2232     {
2233       if (mp->is_ipv6)
2234         {
2235           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2236           vat_json_object_add_ip6 (node, "address", ip6);
2237         }
2238       else
2239         {
2240           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2241           vat_json_object_add_ip4 (node, "address", ip4);
2242         }
2243     }
2244 }
2245
2246 static void
2247 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2248                                            mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   u8 *ls_name = 0;
2252
2253   ls_name = format (0, "%s", mp->ls_name);
2254
2255   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2256            ls_name);
2257   vec_free (ls_name);
2258 }
2259
2260 static void
2261   vl_api_lisp_locator_set_details_t_handler_json
2262   (vl_api_lisp_locator_set_details_t * mp)
2263 {
2264   vat_main_t *vam = &vat_main;
2265   vat_json_node_t *node = 0;
2266   u8 *ls_name = 0;
2267
2268   ls_name = format (0, "%s", mp->ls_name);
2269   vec_add1 (ls_name, 0);
2270
2271   if (VAT_JSON_ARRAY != vam->json_tree.type)
2272     {
2273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2274       vat_json_init_array (&vam->json_tree);
2275     }
2276   node = vat_json_array_add (&vam->json_tree);
2277
2278   vat_json_init_object (node);
2279   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2280   vat_json_object_add_uint (node, "ls_index",
2281                             clib_net_to_host_u32 (mp->ls_index));
2282   vec_free (ls_name);
2283 }
2284
2285 static u8 *
2286 format_lisp_flat_eid (u8 * s, va_list * args)
2287 {
2288   u32 type = va_arg (*args, u32);
2289   u8 *eid = va_arg (*args, u8 *);
2290   u32 eid_len = va_arg (*args, u32);
2291
2292   switch (type)
2293     {
2294     case 0:
2295       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2296     case 1:
2297       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2298     case 2:
2299       return format (s, "%U", format_ethernet_address, eid);
2300     }
2301   return 0;
2302 }
2303
2304 static u8 *
2305 format_lisp_eid_vat (u8 * s, va_list * args)
2306 {
2307   u32 type = va_arg (*args, u32);
2308   u8 *eid = va_arg (*args, u8 *);
2309   u32 eid_len = va_arg (*args, u32);
2310   u8 *seid = va_arg (*args, u8 *);
2311   u32 seid_len = va_arg (*args, u32);
2312   u32 is_src_dst = va_arg (*args, u32);
2313
2314   if (is_src_dst)
2315     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2316
2317   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2318
2319   return s;
2320 }
2321
2322 static void
2323 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2324 {
2325   vat_main_t *vam = &vat_main;
2326   u8 *s = 0, *eid = 0;
2327
2328   if (~0 == mp->locator_set_index)
2329     s = format (0, "action: %d", mp->action);
2330   else
2331     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2332
2333   eid = format (0, "%U", format_lisp_eid_vat,
2334                 mp->eid_type,
2335                 mp->eid,
2336                 mp->eid_prefix_len,
2337                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2338   vec_add1 (eid, 0);
2339
2340   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s\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            clib_net_to_host_u16 (mp->key_id), mp->key);
2346
2347   vec_free (s);
2348   vec_free (eid);
2349 }
2350
2351 static void
2352 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2353                                               * mp)
2354 {
2355   vat_main_t *vam = &vat_main;
2356   vat_json_node_t *node = 0;
2357   u8 *eid = 0;
2358
2359   if (VAT_JSON_ARRAY != vam->json_tree.type)
2360     {
2361       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2362       vat_json_init_array (&vam->json_tree);
2363     }
2364   node = vat_json_array_add (&vam->json_tree);
2365
2366   vat_json_init_object (node);
2367   if (~0 == mp->locator_set_index)
2368     vat_json_object_add_uint (node, "action", mp->action);
2369   else
2370     vat_json_object_add_uint (node, "locator_set_index",
2371                               clib_net_to_host_u32 (mp->locator_set_index));
2372
2373   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2374   eid = format (0, "%U", format_lisp_eid_vat,
2375                 mp->eid_type,
2376                 mp->eid,
2377                 mp->eid_prefix_len,
2378                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2379   vec_add1 (eid, 0);
2380   vat_json_object_add_string_copy (node, "eid", eid);
2381   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2382   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2383   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2384
2385   if (mp->key_id)
2386     {
2387       vat_json_object_add_uint (node, "key_id",
2388                                 clib_net_to_host_u16 (mp->key_id));
2389       vat_json_object_add_string_copy (node, "key", mp->key);
2390     }
2391   vec_free (eid);
2392 }
2393
2394 static void
2395   vl_api_lisp_eid_table_map_details_t_handler
2396   (vl_api_lisp_eid_table_map_details_t * mp)
2397 {
2398   vat_main_t *vam = &vat_main;
2399
2400   u8 *line = format (0, "%=10d%=10d",
2401                      clib_net_to_host_u32 (mp->vni),
2402                      clib_net_to_host_u32 (mp->dp_table));
2403   fformat (vam->ofp, "%v\n", line);
2404   vec_free (line);
2405 }
2406
2407 static void
2408   vl_api_lisp_eid_table_map_details_t_handler_json
2409   (vl_api_lisp_eid_table_map_details_t * mp)
2410 {
2411   vat_main_t *vam = &vat_main;
2412   vat_json_node_t *node = NULL;
2413
2414   if (VAT_JSON_ARRAY != vam->json_tree.type)
2415     {
2416       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2417       vat_json_init_array (&vam->json_tree);
2418     }
2419   node = vat_json_array_add (&vam->json_tree);
2420   vat_json_init_object (node);
2421   vat_json_object_add_uint (node, "dp_table",
2422                             clib_net_to_host_u32 (mp->dp_table));
2423   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2424 }
2425
2426 static void
2427   vl_api_lisp_eid_table_vni_details_t_handler
2428   (vl_api_lisp_eid_table_vni_details_t * mp)
2429 {
2430   vat_main_t *vam = &vat_main;
2431
2432   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2433   fformat (vam->ofp, "%v\n", line);
2434   vec_free (line);
2435 }
2436
2437 static void
2438   vl_api_lisp_eid_table_vni_details_t_handler_json
2439   (vl_api_lisp_eid_table_vni_details_t * mp)
2440 {
2441   vat_main_t *vam = &vat_main;
2442   vat_json_node_t *node = NULL;
2443
2444   if (VAT_JSON_ARRAY != vam->json_tree.type)
2445     {
2446       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2447       vat_json_init_array (&vam->json_tree);
2448     }
2449   node = vat_json_array_add (&vam->json_tree);
2450   vat_json_init_object (node);
2451   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2452 }
2453
2454 static u8 *
2455 format_decap_next (u8 * s, va_list * args)
2456 {
2457   u32 next_index = va_arg (*args, u32);
2458
2459   switch (next_index)
2460     {
2461     case LISP_GPE_INPUT_NEXT_DROP:
2462       return format (s, "drop");
2463     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2464       return format (s, "ip4");
2465     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2466       return format (s, "ip6");
2467     default:
2468       return format (s, "unknown %d", next_index);
2469     }
2470   return s;
2471 }
2472
2473 static void
2474 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2475                                           mp)
2476 {
2477   vat_main_t *vam = &vat_main;
2478   u8 *iid_str;
2479   u8 *flag_str = NULL;
2480
2481   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2482
2483 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2484   foreach_lisp_gpe_flag_bit;
2485 #undef _
2486
2487   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2488            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2489            mp->tunnels,
2490            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2491            mp->source_ip,
2492            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2493            mp->destination_ip,
2494            ntohl (mp->encap_fib_id),
2495            ntohl (mp->decap_fib_id),
2496            format_decap_next, ntohl (mp->dcap_next),
2497            mp->ver_res >> 6,
2498            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2499
2500   vec_free (iid_str);
2501 }
2502
2503 static void
2504   vl_api_lisp_gpe_tunnel_details_t_handler_json
2505   (vl_api_lisp_gpe_tunnel_details_t * mp)
2506 {
2507   vat_main_t *vam = &vat_main;
2508   vat_json_node_t *node = NULL;
2509   struct in6_addr ip6;
2510   struct in_addr ip4;
2511   u8 *next_decap_str;
2512
2513   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2514
2515   if (VAT_JSON_ARRAY != vam->json_tree.type)
2516     {
2517       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2518       vat_json_init_array (&vam->json_tree);
2519     }
2520   node = vat_json_array_add (&vam->json_tree);
2521
2522   vat_json_init_object (node);
2523   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2524   if (mp->is_ipv6)
2525     {
2526       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2527       vat_json_object_add_ip6 (node, "source address", ip6);
2528       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2529       vat_json_object_add_ip6 (node, "destination address", ip6);
2530     }
2531   else
2532     {
2533       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2534       vat_json_object_add_ip4 (node, "source address", ip4);
2535       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2536       vat_json_object_add_ip4 (node, "destination address", ip4);
2537     }
2538   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2539   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2540   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2541   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2542   vat_json_object_add_uint (node, "flags", mp->flags);
2543   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2544   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2545   vat_json_object_add_uint (node, "res", mp->res);
2546   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2547
2548   vec_free (next_decap_str);
2549 }
2550
2551 static void
2552   vl_api_show_lisp_map_register_state_reply_t_handler
2553   (vl_api_show_lisp_map_register_state_reply_t * mp)
2554 {
2555   vat_main_t *vam = &vat_main;
2556   int retval = clib_net_to_host_u32 (mp->retval);
2557
2558   fformat (vam->ofp, "%s\n", mp->is_enabled ? "enabled" : "disabled");
2559
2560   vam->retval = retval;
2561   vam->result_ready = 1;
2562 }
2563
2564 static void
2565   vl_api_show_lisp_map_register_state_reply_t_handler_json
2566   (vl_api_show_lisp_map_register_state_reply_t * mp)
2567 {
2568   vat_main_t *vam = &vat_main;
2569   vat_json_node_t _node, *node = &_node;
2570   int retval = clib_net_to_host_u32 (mp->retval);
2571
2572   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2573
2574   vat_json_init_object (node);
2575   vat_json_object_add_string_copy (node, "state", s);
2576
2577   vat_json_print (vam->ofp, node);
2578   vat_json_free (node);
2579
2580   vam->retval = retval;
2581   vam->result_ready = 1;
2582   vec_free (s);
2583 }
2584
2585 static void
2586   vl_api_show_lisp_rloc_probe_state_reply_t_handler
2587   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2588 {
2589   vat_main_t *vam = &vat_main;
2590   int retval = clib_net_to_host_u32 (mp->retval);
2591
2592   if (retval)
2593     goto end;
2594
2595   fformat (vam->ofp, "%s\n", mp->is_enabled ? "enabled" : "disabled");
2596 end:
2597   vam->retval = retval;
2598   vam->result_ready = 1;
2599 }
2600
2601 static void
2602   vl_api_show_lisp_rloc_probe_state_reply_t_handler_json
2603   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2604 {
2605   vat_main_t *vam = &vat_main;
2606   vat_json_node_t _node, *node = &_node;
2607   int retval = clib_net_to_host_u32 (mp->retval);
2608
2609   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2610   vat_json_init_object (node);
2611   vat_json_object_add_string_copy (node, "state", s);
2612
2613   vat_json_print (vam->ofp, node);
2614   vat_json_free (node);
2615
2616   vam->retval = retval;
2617   vam->result_ready = 1;
2618   vec_free (s);
2619 }
2620
2621 static void
2622   vl_api_lisp_adjacencies_get_reply_t_handler
2623   (vl_api_lisp_adjacencies_get_reply_t * mp)
2624 {
2625   vat_main_t *vam = &vat_main;
2626   u32 i, n;
2627   int retval = clib_net_to_host_u32 (mp->retval);
2628   vl_api_lisp_adjacency_t *a;
2629
2630   if (retval)
2631     goto end;
2632
2633   n = clib_net_to_host_u32 (mp->count);
2634
2635   for (i = 0; i < n; i++)
2636     {
2637       a = &mp->adjacencies[i];
2638       fformat (vam->ofp, "%U %40U\n",
2639                format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2640                format_lisp_flat_eid, a->eid_type, a->reid,
2641                a->reid_prefix_len);
2642     }
2643
2644 end:
2645   vam->retval = retval;
2646   vam->result_ready = 1;
2647 }
2648
2649 static void
2650   vl_api_lisp_adjacencies_get_reply_t_handler_json
2651   (vl_api_lisp_adjacencies_get_reply_t * mp)
2652 {
2653   u8 *s = 0;
2654   vat_main_t *vam = &vat_main;
2655   vat_json_node_t *e = 0, root;
2656   u32 i, n;
2657   int retval = clib_net_to_host_u32 (mp->retval);
2658   vl_api_lisp_adjacency_t *a;
2659
2660   if (retval)
2661     goto end;
2662
2663   n = clib_net_to_host_u32 (mp->count);
2664   vat_json_init_array (&root);
2665
2666   for (i = 0; i < n; i++)
2667     {
2668       e = vat_json_array_add (&root);
2669       a = &mp->adjacencies[i];
2670
2671       vat_json_init_object (e);
2672       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2673                   a->leid_prefix_len);
2674       vec_add1 (s, 0);
2675       vat_json_object_add_string_copy (e, "leid", s);
2676       vec_free (s);
2677
2678       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2679                   a->reid_prefix_len);
2680       vec_add1 (s, 0);
2681       vat_json_object_add_string_copy (e, "reid", s);
2682       vec_free (s);
2683     }
2684
2685   vat_json_print (vam->ofp, &root);
2686   vat_json_free (&root);
2687
2688 end:
2689   vam->retval = retval;
2690   vam->result_ready = 1;
2691 }
2692
2693 static void
2694 vl_api_lisp_map_server_details_t_handler (vl_api_lisp_map_server_details_t
2695                                           * mp)
2696 {
2697   vat_main_t *vam = &vat_main;
2698
2699   fformat (vam->ofp, "%=20U\n",
2700            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2701            mp->ip_address);
2702 }
2703
2704 static void
2705   vl_api_lisp_map_server_details_t_handler_json
2706   (vl_api_lisp_map_server_details_t * mp)
2707 {
2708   vat_main_t *vam = &vat_main;
2709   vat_json_node_t *node = NULL;
2710   struct in6_addr ip6;
2711   struct in_addr ip4;
2712
2713   if (VAT_JSON_ARRAY != vam->json_tree.type)
2714     {
2715       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2716       vat_json_init_array (&vam->json_tree);
2717     }
2718   node = vat_json_array_add (&vam->json_tree);
2719
2720   vat_json_init_object (node);
2721   if (mp->is_ipv6)
2722     {
2723       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2724       vat_json_object_add_ip6 (node, "map-server", ip6);
2725     }
2726   else
2727     {
2728       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2729       vat_json_object_add_ip4 (node, "map-server", ip4);
2730     }
2731 }
2732
2733 static void
2734 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2735                                             * mp)
2736 {
2737   vat_main_t *vam = &vat_main;
2738
2739   fformat (vam->ofp, "%=20U\n",
2740            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2741            mp->ip_address);
2742 }
2743
2744 static void
2745   vl_api_lisp_map_resolver_details_t_handler_json
2746   (vl_api_lisp_map_resolver_details_t * mp)
2747 {
2748   vat_main_t *vam = &vat_main;
2749   vat_json_node_t *node = NULL;
2750   struct in6_addr ip6;
2751   struct in_addr ip4;
2752
2753   if (VAT_JSON_ARRAY != vam->json_tree.type)
2754     {
2755       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2756       vat_json_init_array (&vam->json_tree);
2757     }
2758   node = vat_json_array_add (&vam->json_tree);
2759
2760   vat_json_init_object (node);
2761   if (mp->is_ipv6)
2762     {
2763       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2764       vat_json_object_add_ip6 (node, "map resolver", ip6);
2765     }
2766   else
2767     {
2768       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2769       vat_json_object_add_ip4 (node, "map resolver", ip4);
2770     }
2771 }
2772
2773 static void
2774   vl_api_show_lisp_status_reply_t_handler
2775   (vl_api_show_lisp_status_reply_t * mp)
2776 {
2777   vat_main_t *vam = &vat_main;
2778   i32 retval = ntohl (mp->retval);
2779
2780   if (0 <= retval)
2781     {
2782       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2783                mp->feature_status ? "enabled" : "disabled",
2784                mp->gpe_status ? "enabled" : "disabled");
2785     }
2786
2787   vam->retval = retval;
2788   vam->result_ready = 1;
2789 }
2790
2791 static void
2792   vl_api_show_lisp_status_reply_t_handler_json
2793   (vl_api_show_lisp_status_reply_t * mp)
2794 {
2795   vat_main_t *vam = &vat_main;
2796   vat_json_node_t node;
2797   u8 *gpe_status = NULL;
2798   u8 *feature_status = NULL;
2799
2800   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2801   feature_status = format (0, "%s",
2802                            mp->feature_status ? "enabled" : "disabled");
2803   vec_add1 (gpe_status, 0);
2804   vec_add1 (feature_status, 0);
2805
2806   vat_json_init_object (&node);
2807   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2808   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2809
2810   vec_free (gpe_status);
2811   vec_free (feature_status);
2812
2813   vat_json_print (vam->ofp, &node);
2814   vat_json_free (&node);
2815
2816   vam->retval = ntohl (mp->retval);
2817   vam->result_ready = 1;
2818 }
2819
2820 static void
2821   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2822   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2823 {
2824   vat_main_t *vam = &vat_main;
2825   i32 retval = ntohl (mp->retval);
2826
2827   if (retval >= 0)
2828     {
2829       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2830     }
2831
2832   vam->retval = retval;
2833   vam->result_ready = 1;
2834 }
2835
2836 static void
2837   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2838   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2839 {
2840   vat_main_t *vam = &vat_main;
2841   vat_json_node_t *node = NULL;
2842
2843   if (VAT_JSON_ARRAY != vam->json_tree.type)
2844     {
2845       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2846       vat_json_init_array (&vam->json_tree);
2847     }
2848   node = vat_json_array_add (&vam->json_tree);
2849
2850   vat_json_init_object (node);
2851   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2852
2853   vat_json_print (vam->ofp, node);
2854   vat_json_free (node);
2855
2856   vam->retval = ntohl (mp->retval);
2857   vam->result_ready = 1;
2858 }
2859
2860 static u8 *
2861 format_lisp_map_request_mode (u8 * s, va_list * args)
2862 {
2863   u32 mode = va_arg (*args, u32);
2864
2865   switch (mode)
2866     {
2867     case 0:
2868       return format (0, "dst-only");
2869     case 1:
2870       return format (0, "src-dst");
2871     }
2872   return 0;
2873 }
2874
2875 static void
2876   vl_api_show_lisp_map_request_mode_reply_t_handler
2877   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2878 {
2879   vat_main_t *vam = &vat_main;
2880   i32 retval = ntohl (mp->retval);
2881
2882   if (0 <= retval)
2883     {
2884       u32 mode = mp->mode;
2885       fformat (vam->ofp, "map_request_mode: %U\n",
2886                format_lisp_map_request_mode, mode);
2887     }
2888
2889   vam->retval = retval;
2890   vam->result_ready = 1;
2891 }
2892
2893 static void
2894   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2895   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2896 {
2897   vat_main_t *vam = &vat_main;
2898   vat_json_node_t node;
2899   u8 *s = 0;
2900   u32 mode;
2901
2902   mode = mp->mode;
2903   s = format (0, "%U", format_lisp_map_request_mode, mode);
2904   vec_add1 (s, 0);
2905
2906   vat_json_init_object (&node);
2907   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2908   vat_json_print (vam->ofp, &node);
2909   vat_json_free (&node);
2910
2911   vec_free (s);
2912   vam->retval = ntohl (mp->retval);
2913   vam->result_ready = 1;
2914 }
2915
2916 static void
2917 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2918 {
2919   vat_main_t *vam = &vat_main;
2920   i32 retval = ntohl (mp->retval);
2921
2922   if (0 <= retval)
2923     {
2924       fformat (vam->ofp, "%-20s%-16s\n",
2925                mp->status ? "enabled" : "disabled",
2926                mp->status ? (char *) mp->locator_set_name : "");
2927     }
2928
2929   vam->retval = retval;
2930   vam->result_ready = 1;
2931 }
2932
2933 static void
2934 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2935                                             mp)
2936 {
2937   vat_main_t *vam = &vat_main;
2938   vat_json_node_t node;
2939   u8 *status = 0;
2940
2941   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2942   vec_add1 (status, 0);
2943
2944   vat_json_init_object (&node);
2945   vat_json_object_add_string_copy (&node, "status", status);
2946   if (mp->status)
2947     {
2948       vat_json_object_add_string_copy (&node, "locator_set",
2949                                        mp->locator_set_name);
2950     }
2951
2952   vec_free (status);
2953
2954   vat_json_print (vam->ofp, &node);
2955   vat_json_free (&node);
2956
2957   vam->retval = ntohl (mp->retval);
2958   vam->result_ready = 1;
2959 }
2960
2961 static u8 *
2962 format_policer_type (u8 * s, va_list * va)
2963 {
2964   u32 i = va_arg (*va, u32);
2965
2966   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2967     s = format (s, "1r2c");
2968   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2969     s = format (s, "1r3c");
2970   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2971     s = format (s, "2r3c-2698");
2972   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2973     s = format (s, "2r3c-4115");
2974   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2975     s = format (s, "2r3c-mef5cf1");
2976   else
2977     s = format (s, "ILLEGAL");
2978   return s;
2979 }
2980
2981 static u8 *
2982 format_policer_rate_type (u8 * s, va_list * va)
2983 {
2984   u32 i = va_arg (*va, u32);
2985
2986   if (i == SSE2_QOS_RATE_KBPS)
2987     s = format (s, "kbps");
2988   else if (i == SSE2_QOS_RATE_PPS)
2989     s = format (s, "pps");
2990   else
2991     s = format (s, "ILLEGAL");
2992   return s;
2993 }
2994
2995 static u8 *
2996 format_policer_round_type (u8 * s, va_list * va)
2997 {
2998   u32 i = va_arg (*va, u32);
2999
3000   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3001     s = format (s, "closest");
3002   else if (i == SSE2_QOS_ROUND_TO_UP)
3003     s = format (s, "up");
3004   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3005     s = format (s, "down");
3006   else
3007     s = format (s, "ILLEGAL");
3008   return s;
3009 }
3010
3011 static u8 *
3012 format_policer_action_type (u8 * s, va_list * va)
3013 {
3014   u32 i = va_arg (*va, u32);
3015
3016   if (i == SSE2_QOS_ACTION_DROP)
3017     s = format (s, "drop");
3018   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3019     s = format (s, "transmit");
3020   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3021     s = format (s, "mark-and-transmit");
3022   else
3023     s = format (s, "ILLEGAL");
3024   return s;
3025 }
3026
3027 static u8 *
3028 format_dscp (u8 * s, va_list * va)
3029 {
3030   u32 i = va_arg (*va, u32);
3031   char *t = 0;
3032
3033   switch (i)
3034     {
3035 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3036       foreach_vnet_dscp
3037 #undef _
3038     default:
3039       return format (s, "ILLEGAL");
3040     }
3041   s = format (s, "%s", t);
3042   return s;
3043 }
3044
3045 static void
3046 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3047 {
3048   vat_main_t *vam = &vat_main;
3049   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3050
3051   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3052     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3053   else
3054     conform_dscp_str = format (0, "");
3055
3056   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3057     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3058   else
3059     exceed_dscp_str = format (0, "");
3060
3061   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3062     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3063   else
3064     violate_dscp_str = format (0, "");
3065
3066   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3067            "rate type %U, round type %U, %s rate, %s color-aware, "
3068            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3069            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3070            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
3071            mp->name,
3072            format_policer_type, mp->type,
3073            ntohl (mp->cir),
3074            ntohl (mp->eir),
3075            clib_net_to_host_u64 (mp->cb),
3076            clib_net_to_host_u64 (mp->eb),
3077            format_policer_rate_type, mp->rate_type,
3078            format_policer_round_type, mp->round_type,
3079            mp->single_rate ? "single" : "dual",
3080            mp->color_aware ? "is" : "not",
3081            ntohl (mp->cir_tokens_per_period),
3082            ntohl (mp->pir_tokens_per_period),
3083            ntohl (mp->scale),
3084            ntohl (mp->current_limit),
3085            ntohl (mp->current_bucket),
3086            ntohl (mp->extended_limit),
3087            ntohl (mp->extended_bucket),
3088            clib_net_to_host_u64 (mp->last_update_time),
3089            format_policer_action_type, mp->conform_action_type,
3090            conform_dscp_str,
3091            format_policer_action_type, mp->exceed_action_type,
3092            exceed_dscp_str,
3093            format_policer_action_type, mp->violate_action_type,
3094            violate_dscp_str);
3095
3096   vec_free (conform_dscp_str);
3097   vec_free (exceed_dscp_str);
3098   vec_free (violate_dscp_str);
3099 }
3100
3101 static void vl_api_policer_details_t_handler_json
3102   (vl_api_policer_details_t * mp)
3103 {
3104   vat_main_t *vam = &vat_main;
3105   vat_json_node_t *node;
3106   u8 *rate_type_str, *round_type_str, *type_str;
3107   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3108
3109   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3110   round_type_str =
3111     format (0, "%U", format_policer_round_type, mp->round_type);
3112   type_str = format (0, "%U", format_policer_type, mp->type);
3113   conform_action_str = format (0, "%U", format_policer_action_type,
3114                                mp->conform_action_type);
3115   exceed_action_str = format (0, "%U", format_policer_action_type,
3116                               mp->exceed_action_type);
3117   violate_action_str = format (0, "%U", format_policer_action_type,
3118                                mp->violate_action_type);
3119
3120   if (VAT_JSON_ARRAY != vam->json_tree.type)
3121     {
3122       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3123       vat_json_init_array (&vam->json_tree);
3124     }
3125   node = vat_json_array_add (&vam->json_tree);
3126
3127   vat_json_init_object (node);
3128   vat_json_object_add_string_copy (node, "name", mp->name);
3129   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3130   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3131   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3132   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3133   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3134   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3135   vat_json_object_add_string_copy (node, "type", type_str);
3136   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3137   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3138   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3139   vat_json_object_add_uint (node, "cir_tokens_per_period",
3140                             ntohl (mp->cir_tokens_per_period));
3141   vat_json_object_add_uint (node, "eir_tokens_per_period",
3142                             ntohl (mp->pir_tokens_per_period));
3143   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3144   vat_json_object_add_uint (node, "current_bucket",
3145                             ntohl (mp->current_bucket));
3146   vat_json_object_add_uint (node, "extended_limit",
3147                             ntohl (mp->extended_limit));
3148   vat_json_object_add_uint (node, "extended_bucket",
3149                             ntohl (mp->extended_bucket));
3150   vat_json_object_add_uint (node, "last_update_time",
3151                             ntohl (mp->last_update_time));
3152   vat_json_object_add_string_copy (node, "conform_action",
3153                                    conform_action_str);
3154   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3155     {
3156       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3157       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3158       vec_free (dscp_str);
3159     }
3160   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3161   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3162     {
3163       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3164       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3165       vec_free (dscp_str);
3166     }
3167   vat_json_object_add_string_copy (node, "violate_action",
3168                                    violate_action_str);
3169   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3170     {
3171       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3172       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3173       vec_free (dscp_str);
3174     }
3175
3176   vec_free (rate_type_str);
3177   vec_free (round_type_str);
3178   vec_free (type_str);
3179   vec_free (conform_action_str);
3180   vec_free (exceed_action_str);
3181   vec_free (violate_action_str);
3182 }
3183
3184 static void
3185 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3186                                            mp)
3187 {
3188   vat_main_t *vam = &vat_main;
3189   int i, count = ntohl (mp->count);
3190
3191   if (count > 0)
3192     fformat (vam->ofp, "classify table ids (%d) : ", count);
3193   for (i = 0; i < count; i++)
3194     {
3195       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3196       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3197     }
3198   vam->retval = ntohl (mp->retval);
3199   vam->result_ready = 1;
3200 }
3201
3202 static void
3203   vl_api_classify_table_ids_reply_t_handler_json
3204   (vl_api_classify_table_ids_reply_t * mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207   int i, count = ntohl (mp->count);
3208
3209   if (count > 0)
3210     {
3211       vat_json_node_t node;
3212
3213       vat_json_init_object (&node);
3214       for (i = 0; i < count; i++)
3215         {
3216           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3217         }
3218       vat_json_print (vam->ofp, &node);
3219       vat_json_free (&node);
3220     }
3221   vam->retval = ntohl (mp->retval);
3222   vam->result_ready = 1;
3223 }
3224
3225 static void
3226   vl_api_classify_table_by_interface_reply_t_handler
3227   (vl_api_classify_table_by_interface_reply_t * mp)
3228 {
3229   vat_main_t *vam = &vat_main;
3230   u32 table_id;
3231
3232   table_id = ntohl (mp->l2_table_id);
3233   if (table_id != ~0)
3234     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3235   else
3236     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3237   table_id = ntohl (mp->ip4_table_id);
3238   if (table_id != ~0)
3239     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3240   else
3241     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3242   table_id = ntohl (mp->ip6_table_id);
3243   if (table_id != ~0)
3244     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3245   else
3246     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3247   vam->retval = ntohl (mp->retval);
3248   vam->result_ready = 1;
3249 }
3250
3251 static void
3252   vl_api_classify_table_by_interface_reply_t_handler_json
3253   (vl_api_classify_table_by_interface_reply_t * mp)
3254 {
3255   vat_main_t *vam = &vat_main;
3256   vat_json_node_t node;
3257
3258   vat_json_init_object (&node);
3259
3260   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3261   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3262   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3263
3264   vat_json_print (vam->ofp, &node);
3265   vat_json_free (&node);
3266
3267   vam->retval = ntohl (mp->retval);
3268   vam->result_ready = 1;
3269 }
3270
3271 static void vl_api_policer_add_del_reply_t_handler
3272   (vl_api_policer_add_del_reply_t * mp)
3273 {
3274   vat_main_t *vam = &vat_main;
3275   i32 retval = ntohl (mp->retval);
3276   if (vam->async_mode)
3277     {
3278       vam->async_errors += (retval < 0);
3279     }
3280   else
3281     {
3282       vam->retval = retval;
3283       vam->result_ready = 1;
3284       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3285         /*
3286          * Note: this is just barely thread-safe, depends on
3287          * the main thread spinning waiting for an answer...
3288          */
3289         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3290     }
3291 }
3292
3293 static void vl_api_policer_add_del_reply_t_handler_json
3294   (vl_api_policer_add_del_reply_t * mp)
3295 {
3296   vat_main_t *vam = &vat_main;
3297   vat_json_node_t node;
3298
3299   vat_json_init_object (&node);
3300   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3301   vat_json_object_add_uint (&node, "policer_index",
3302                             ntohl (mp->policer_index));
3303
3304   vat_json_print (vam->ofp, &node);
3305   vat_json_free (&node);
3306
3307   vam->retval = ntohl (mp->retval);
3308   vam->result_ready = 1;
3309 }
3310
3311 /* Format hex dump. */
3312 u8 *
3313 format_hex_bytes (u8 * s, va_list * va)
3314 {
3315   u8 *bytes = va_arg (*va, u8 *);
3316   int n_bytes = va_arg (*va, int);
3317   uword i;
3318
3319   /* Print short or long form depending on byte count. */
3320   uword short_form = n_bytes <= 32;
3321   uword indent = format_get_indent (s);
3322
3323   if (n_bytes == 0)
3324     return s;
3325
3326   for (i = 0; i < n_bytes; i++)
3327     {
3328       if (!short_form && (i % 32) == 0)
3329         s = format (s, "%08x: ", i);
3330       s = format (s, "%02x", bytes[i]);
3331       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3332         s = format (s, "\n%U", format_white_space, indent);
3333     }
3334
3335   return s;
3336 }
3337
3338 static void
3339 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3340                                             * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   i32 retval = ntohl (mp->retval);
3344   if (retval == 0)
3345     {
3346       fformat (vam->ofp, "classify table info :\n");
3347       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3348                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3349                ntohl (mp->miss_next_index));
3350       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3351                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3352                ntohl (mp->match_n_vectors));
3353       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3354                ntohl (mp->mask_length));
3355     }
3356   vam->retval = retval;
3357   vam->result_ready = 1;
3358 }
3359
3360 static void
3361   vl_api_classify_table_info_reply_t_handler_json
3362   (vl_api_classify_table_info_reply_t * mp)
3363 {
3364   vat_main_t *vam = &vat_main;
3365   vat_json_node_t node;
3366
3367   i32 retval = ntohl (mp->retval);
3368   if (retval == 0)
3369     {
3370       vat_json_init_object (&node);
3371
3372       vat_json_object_add_int (&node, "sessions",
3373                                ntohl (mp->active_sessions));
3374       vat_json_object_add_int (&node, "nexttbl",
3375                                ntohl (mp->next_table_index));
3376       vat_json_object_add_int (&node, "nextnode",
3377                                ntohl (mp->miss_next_index));
3378       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3379       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3380       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3381       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3382                       ntohl (mp->mask_length), 0);
3383       vat_json_object_add_string_copy (&node, "mask", s);
3384
3385       vat_json_print (vam->ofp, &node);
3386       vat_json_free (&node);
3387     }
3388   vam->retval = ntohl (mp->retval);
3389   vam->result_ready = 1;
3390 }
3391
3392 static void
3393 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3394                                            mp)
3395 {
3396   vat_main_t *vam = &vat_main;
3397
3398   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3399            ntohl (mp->hit_next_index), ntohl (mp->advance),
3400            ntohl (mp->opaque_index));
3401   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3402            ntohl (mp->match_length));
3403 }
3404
3405 static void
3406   vl_api_classify_session_details_t_handler_json
3407   (vl_api_classify_session_details_t * mp)
3408 {
3409   vat_main_t *vam = &vat_main;
3410   vat_json_node_t *node = NULL;
3411
3412   if (VAT_JSON_ARRAY != vam->json_tree.type)
3413     {
3414       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3415       vat_json_init_array (&vam->json_tree);
3416     }
3417   node = vat_json_array_add (&vam->json_tree);
3418
3419   vat_json_init_object (node);
3420   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3421   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3422   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3423   u8 *s =
3424     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3425             0);
3426   vat_json_object_add_string_copy (node, "match", s);
3427 }
3428
3429 static void vl_api_pg_create_interface_reply_t_handler
3430   (vl_api_pg_create_interface_reply_t * mp)
3431 {
3432   vat_main_t *vam = &vat_main;
3433
3434   vam->retval = ntohl (mp->retval);
3435   vam->result_ready = 1;
3436 }
3437
3438 static void vl_api_pg_create_interface_reply_t_handler_json
3439   (vl_api_pg_create_interface_reply_t * mp)
3440 {
3441   vat_main_t *vam = &vat_main;
3442   vat_json_node_t node;
3443
3444   i32 retval = ntohl (mp->retval);
3445   if (retval == 0)
3446     {
3447       vat_json_init_object (&node);
3448
3449       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3450
3451       vat_json_print (vam->ofp, &node);
3452       vat_json_free (&node);
3453     }
3454   vam->retval = ntohl (mp->retval);
3455   vam->result_ready = 1;
3456 }
3457
3458 static void vl_api_policer_classify_details_t_handler
3459   (vl_api_policer_classify_details_t * mp)
3460 {
3461   vat_main_t *vam = &vat_main;
3462
3463   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3464            ntohl (mp->table_index));
3465 }
3466
3467 static void vl_api_policer_classify_details_t_handler_json
3468   (vl_api_policer_classify_details_t * mp)
3469 {
3470   vat_main_t *vam = &vat_main;
3471   vat_json_node_t *node;
3472
3473   if (VAT_JSON_ARRAY != vam->json_tree.type)
3474     {
3475       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3476       vat_json_init_array (&vam->json_tree);
3477     }
3478   node = vat_json_array_add (&vam->json_tree);
3479
3480   vat_json_init_object (node);
3481   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3482   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3483 }
3484
3485 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3486   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3487 {
3488   vat_main_t *vam = &vat_main;
3489   i32 retval = ntohl (mp->retval);
3490   if (vam->async_mode)
3491     {
3492       vam->async_errors += (retval < 0);
3493     }
3494   else
3495     {
3496       vam->retval = retval;
3497       vam->sw_if_index = ntohl (mp->sw_if_index);
3498       vam->result_ready = 1;
3499     }
3500 }
3501
3502 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3503   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3504 {
3505   vat_main_t *vam = &vat_main;
3506   vat_json_node_t node;
3507
3508   vat_json_init_object (&node);
3509   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3510   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3511
3512   vat_json_print (vam->ofp, &node);
3513   vat_json_free (&node);
3514
3515   vam->retval = ntohl (mp->retval);
3516   vam->result_ready = 1;
3517 }
3518
3519 static void vl_api_flow_classify_details_t_handler
3520   (vl_api_flow_classify_details_t * mp)
3521 {
3522   vat_main_t *vam = &vat_main;
3523
3524   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3525            ntohl (mp->table_index));
3526 }
3527
3528 static void vl_api_flow_classify_details_t_handler_json
3529   (vl_api_flow_classify_details_t * mp)
3530 {
3531   vat_main_t *vam = &vat_main;
3532   vat_json_node_t *node;
3533
3534   if (VAT_JSON_ARRAY != vam->json_tree.type)
3535     {
3536       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3537       vat_json_init_array (&vam->json_tree);
3538     }
3539   node = vat_json_array_add (&vam->json_tree);
3540
3541   vat_json_init_object (node);
3542   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3543   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3544 }
3545
3546
3547
3548 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3549 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3550 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3551 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3552 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3553 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3554
3555 /*
3556  * Generate boilerplate reply handlers, which
3557  * dig the return value out of the xxx_reply_t API message,
3558  * stick it into vam->retval, and set vam->result_ready
3559  *
3560  * Could also do this by pointing N message decode slots at
3561  * a single function, but that could break in subtle ways.
3562  */
3563
3564 #define foreach_standard_reply_retval_handler           \
3565 _(sw_interface_set_flags_reply)                         \
3566 _(sw_interface_add_del_address_reply)                   \
3567 _(sw_interface_set_table_reply)                         \
3568 _(sw_interface_set_mpls_enable_reply)                   \
3569 _(sw_interface_set_vpath_reply)                         \
3570 _(sw_interface_set_vxlan_bypass_reply)                  \
3571 _(sw_interface_set_l2_bridge_reply)                     \
3572 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3573 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3574 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3575 _(bridge_domain_add_del_reply)                          \
3576 _(sw_interface_set_l2_xconnect_reply)                   \
3577 _(l2fib_add_del_reply)                                  \
3578 _(ip_add_del_route_reply)                               \
3579 _(mpls_route_add_del_reply)                             \
3580 _(mpls_ip_bind_unbind_reply)                            \
3581 _(proxy_arp_add_del_reply)                              \
3582 _(proxy_arp_intfc_enable_disable_reply)                 \
3583 _(sw_interface_set_unnumbered_reply)                    \
3584 _(ip_neighbor_add_del_reply)                            \
3585 _(reset_vrf_reply)                                      \
3586 _(oam_add_del_reply)                                    \
3587 _(reset_fib_reply)                                      \
3588 _(dhcp_proxy_config_reply)                              \
3589 _(dhcp_proxy_config_2_reply)                            \
3590 _(dhcp_proxy_set_vss_reply)                             \
3591 _(dhcp_client_config_reply)                             \
3592 _(set_ip_flow_hash_reply)                               \
3593 _(sw_interface_ip6_enable_disable_reply)                \
3594 _(sw_interface_ip6_set_link_local_address_reply)        \
3595 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3596 _(sw_interface_ip6nd_ra_config_reply)                   \
3597 _(set_arp_neighbor_limit_reply)                         \
3598 _(l2_patch_add_del_reply)                               \
3599 _(sr_tunnel_add_del_reply)                              \
3600 _(sr_policy_add_del_reply)                              \
3601 _(sr_multicast_map_add_del_reply)                       \
3602 _(classify_add_del_session_reply)                       \
3603 _(classify_set_interface_ip_table_reply)                \
3604 _(classify_set_interface_l2_tables_reply)               \
3605 _(l2tpv3_set_tunnel_cookies_reply)                      \
3606 _(l2tpv3_interface_enable_disable_reply)                \
3607 _(l2tpv3_set_lookup_key_reply)                          \
3608 _(l2_fib_clear_table_reply)                             \
3609 _(l2_interface_efp_filter_reply)                        \
3610 _(l2_interface_vlan_tag_rewrite_reply)                  \
3611 _(modify_vhost_user_if_reply)                           \
3612 _(delete_vhost_user_if_reply)                           \
3613 _(want_ip4_arp_events_reply)                            \
3614 _(want_ip6_nd_events_reply)                             \
3615 _(input_acl_set_interface_reply)                        \
3616 _(ipsec_spd_add_del_reply)                              \
3617 _(ipsec_interface_add_del_spd_reply)                    \
3618 _(ipsec_spd_add_del_entry_reply)                        \
3619 _(ipsec_sad_add_del_entry_reply)                        \
3620 _(ipsec_sa_set_key_reply)                               \
3621 _(ikev2_profile_add_del_reply)                          \
3622 _(ikev2_profile_set_auth_reply)                         \
3623 _(ikev2_profile_set_id_reply)                           \
3624 _(ikev2_profile_set_ts_reply)                           \
3625 _(ikev2_set_local_key_reply)                            \
3626 _(delete_loopback_reply)                                \
3627 _(bd_ip_mac_add_del_reply)                              \
3628 _(map_del_domain_reply)                                 \
3629 _(map_add_del_rule_reply)                               \
3630 _(want_interface_events_reply)                          \
3631 _(want_stats_reply)                                     \
3632 _(cop_interface_enable_disable_reply)                   \
3633 _(cop_whitelist_enable_disable_reply)                   \
3634 _(sw_interface_clear_stats_reply)                       \
3635 _(ioam_enable_reply)                              \
3636 _(ioam_disable_reply)                              \
3637 _(lisp_add_del_locator_reply)                           \
3638 _(lisp_add_del_local_eid_reply)                         \
3639 _(lisp_add_del_remote_mapping_reply)                    \
3640 _(lisp_add_del_adjacency_reply)                         \
3641 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3642 _(lisp_add_del_map_resolver_reply)                      \
3643 _(lisp_add_del_map_server_reply)                        \
3644 _(lisp_gpe_enable_disable_reply)                        \
3645 _(lisp_gpe_add_del_iface_reply)                         \
3646 _(lisp_enable_disable_reply)                            \
3647 _(lisp_rloc_probe_enable_disable_reply)                 \
3648 _(lisp_map_register_enable_disable_reply)               \
3649 _(lisp_pitr_set_locator_set_reply)                      \
3650 _(lisp_map_request_mode_reply)                          \
3651 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3652 _(lisp_eid_table_add_del_map_reply)                     \
3653 _(vxlan_gpe_add_del_tunnel_reply)                       \
3654 _(af_packet_delete_reply)                               \
3655 _(policer_classify_set_interface_reply)                 \
3656 _(netmap_create_reply)                                  \
3657 _(netmap_delete_reply)                                  \
3658 _(set_ipfix_exporter_reply)                             \
3659 _(set_ipfix_classify_stream_reply)                      \
3660 _(ipfix_classify_table_add_del_reply)                   \
3661 _(flow_classify_set_interface_reply)                    \
3662 _(sw_interface_span_enable_disable_reply)               \
3663 _(pg_capture_reply)                                     \
3664 _(pg_enable_disable_reply)                              \
3665 _(ip_source_and_port_range_check_add_del_reply)         \
3666 _(ip_source_and_port_range_check_interface_add_del_reply)\
3667 _(delete_subif_reply)                                   \
3668 _(l2_interface_pbb_tag_rewrite_reply)                   \
3669 _(punt_reply)                                           \
3670 _(feature_enable_disable_reply)                         \
3671 _(sw_interface_tag_add_del_reply)                       \
3672 _(sw_interface_set_mtu_reply)
3673
3674 #define _(n)                                    \
3675     static void vl_api_##n##_t_handler          \
3676     (vl_api_##n##_t * mp)                       \
3677     {                                           \
3678         vat_main_t * vam = &vat_main;           \
3679         i32 retval = ntohl(mp->retval);         \
3680         if (vam->async_mode) {                  \
3681             vam->async_errors += (retval < 0);  \
3682         } else {                                \
3683             vam->retval = retval;               \
3684             vam->result_ready = 1;              \
3685         }                                       \
3686     }
3687 foreach_standard_reply_retval_handler;
3688 #undef _
3689
3690 #define _(n)                                    \
3691     static void vl_api_##n##_t_handler_json     \
3692     (vl_api_##n##_t * mp)                       \
3693     {                                           \
3694         vat_main_t * vam = &vat_main;           \
3695         vat_json_node_t node;                   \
3696         vat_json_init_object(&node);            \
3697         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3698         vat_json_print(vam->ofp, &node);        \
3699         vam->retval = ntohl(mp->retval);        \
3700         vam->result_ready = 1;                  \
3701     }
3702 foreach_standard_reply_retval_handler;
3703 #undef _
3704
3705 /*
3706  * Table of message reply handlers, must include boilerplate handlers
3707  * we just generated
3708  */
3709
3710 #define foreach_vpe_api_reply_msg                                       \
3711 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3712 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3713 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3714 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3715 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3716 _(CLI_REPLY, cli_reply)                                                 \
3717 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3718 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3719   sw_interface_add_del_address_reply)                                   \
3720 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3721 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3722 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3723 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3724 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3725   sw_interface_set_l2_xconnect_reply)                                   \
3726 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3727   sw_interface_set_l2_bridge_reply)                                     \
3728 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3729   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3730 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3731   sw_interface_set_dpdk_hqos_subport_reply)                             \
3732 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3733   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3734 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3735 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3736 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3737 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3738 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3739 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3740 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3741 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3742 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3743 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3744 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3745 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3746 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3747 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3748 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3749   proxy_arp_intfc_enable_disable_reply)                                 \
3750 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
3751 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3752   sw_interface_set_unnumbered_reply)                                    \
3753 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3754 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3755 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3756 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3757 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3758 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3759 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3760 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3761 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3762 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3763 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3764 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3765   sw_interface_ip6_enable_disable_reply)                                \
3766 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3767   sw_interface_ip6_set_link_local_address_reply)                        \
3768 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3769   sw_interface_ip6nd_ra_prefix_reply)                                   \
3770 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3771   sw_interface_ip6nd_ra_config_reply)                                   \
3772 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3773 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3774 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3775 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3776 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3777 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3778 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3779 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3780 classify_set_interface_ip_table_reply)                                  \
3781 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3782   classify_set_interface_l2_tables_reply)                               \
3783 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3784 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3785 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3786 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3787 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3788   l2tpv3_interface_enable_disable_reply)                                \
3789 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3790 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3791 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3792 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3793 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3794 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3795 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3796 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3797 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3798 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3799 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3800 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3801 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3802 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3803 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3804 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3805 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3806 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3807 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3808 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3809 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3810 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3811 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3812 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3813 _(IP_DETAILS, ip_details)                                               \
3814 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3815 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3816 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3817 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3818 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3819 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3820 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3821 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3822 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3823 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3824 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3825 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3826 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3827 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3828 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3829 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3830 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3831 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3832 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3833 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3834 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3835 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3836 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3837 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3838 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3839 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3840 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3841 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3842 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3843 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3844 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3845 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3846 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3847 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3848 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3849 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3850 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3851 _(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply)         \
3852 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3853 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3854 _(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY,                               \
3855   lisp_map_register_enable_disable_reply)                               \
3856 _(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                 \
3857   lisp_rloc_probe_enable_disable_reply)                                 \
3858 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3859 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3860 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3861 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3862 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3863 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3864 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3865 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3866 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3867 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3868 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3869 _(LISP_MAP_SERVER_DETAILS, lisp_map_server_details)                     \
3870 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3871 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3872 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3873   lisp_add_del_map_request_itr_rlocs_reply)                             \
3874 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3875   lisp_get_map_request_itr_rlocs_reply)                                 \
3876 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3877 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3878 _(SHOW_LISP_RLOC_PROBE_STATE_REPLY, show_lisp_rloc_probe_state_reply)   \
3879 _(SHOW_LISP_MAP_REGISTER_STATE_REPLY,                                   \
3880   show_lisp_map_register_state_reply)                                   \
3881 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3882 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3883 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3884 _(POLICER_DETAILS, policer_details)                                     \
3885 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3886 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3887 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3888 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3889 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
3890 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3891 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3892 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3893 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3894 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3895 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3896 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3897 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3898 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3899 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3900 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3901 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3902 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3903 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3904 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3905 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3906 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3907 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3908 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3909 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3910  ip_source_and_port_range_check_add_del_reply)                          \
3911 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3912  ip_source_and_port_range_check_interface_add_del_reply)                \
3913 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3914 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3915 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3916 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3917 _(PUNT_REPLY, punt_reply)                                               \
3918 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3919 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3920 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
3921 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
3922 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
3923 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)
3924
3925 /* M: construct, but don't yet send a message */
3926
3927 #define M(T,t)                                  \
3928 do {                                            \
3929     vam->result_ready = 0;                      \
3930     mp = vl_msg_api_alloc(sizeof(*mp));         \
3931     memset (mp, 0, sizeof (*mp));               \
3932     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3933     mp->client_index = vam->my_client_index;    \
3934 } while(0);
3935
3936 #define M2(T,t,n)                               \
3937 do {                                            \
3938     vam->result_ready = 0;                      \
3939     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3940     memset (mp, 0, sizeof (*mp));               \
3941     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3942     mp->client_index = vam->my_client_index;    \
3943 } while(0);
3944
3945
3946 /* S: send a message */
3947 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3948
3949 /* W: wait for results, with timeout */
3950 #define W                                       \
3951 do {                                            \
3952     timeout = vat_time_now (vam) + 1.0;         \
3953                                                 \
3954     while (vat_time_now (vam) < timeout) {      \
3955         if (vam->result_ready == 1) {           \
3956             return (vam->retval);               \
3957         }                                       \
3958     }                                           \
3959     return -99;                                 \
3960 } while(0);
3961
3962 /* W2: wait for results, with timeout */
3963 #define W2(body)                                \
3964 do {                                            \
3965     timeout = vat_time_now (vam) + 1.0;         \
3966                                                 \
3967     while (vat_time_now (vam) < timeout) {      \
3968         if (vam->result_ready == 1) {           \
3969           (body);                               \
3970           return (vam->retval);                 \
3971         }                                       \
3972     }                                           \
3973     return -99;                                 \
3974 } while(0);
3975
3976 typedef struct
3977 {
3978   u8 *name;
3979   u32 value;
3980 } name_sort_t;
3981
3982
3983 #define STR_VTR_OP_CASE(op)     \
3984     case L2_VTR_ ## op:         \
3985         return "" # op;
3986
3987 static const char *
3988 str_vtr_op (u32 vtr_op)
3989 {
3990   switch (vtr_op)
3991     {
3992       STR_VTR_OP_CASE (DISABLED);
3993       STR_VTR_OP_CASE (PUSH_1);
3994       STR_VTR_OP_CASE (PUSH_2);
3995       STR_VTR_OP_CASE (POP_1);
3996       STR_VTR_OP_CASE (POP_2);
3997       STR_VTR_OP_CASE (TRANSLATE_1_1);
3998       STR_VTR_OP_CASE (TRANSLATE_1_2);
3999       STR_VTR_OP_CASE (TRANSLATE_2_1);
4000       STR_VTR_OP_CASE (TRANSLATE_2_2);
4001     }
4002
4003   return "UNKNOWN";
4004 }
4005
4006 static int
4007 dump_sub_interface_table (vat_main_t * vam)
4008 {
4009   const sw_interface_subif_t *sub = NULL;
4010
4011   if (vam->json_output)
4012     {
4013       clib_warning
4014         ("JSON output supported only for VPE API calls and dump_stats_table");
4015       return -99;
4016     }
4017
4018   fformat (vam->ofp,
4019            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
4020            "Interface", "sw_if_index",
4021            "sub id", "dot1ad", "tags", "outer id",
4022            "inner id", "exact", "default", "outer any", "inner any");
4023
4024   vec_foreach (sub, vam->sw_if_subif_table)
4025   {
4026     fformat (vam->ofp,
4027              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
4028              sub->interface_name,
4029              sub->sw_if_index,
4030              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4031              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4032              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4033              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4034     if (sub->vtr_op != L2_VTR_DISABLED)
4035       {
4036         fformat (vam->ofp,
4037                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4038                  "tag1: %d tag2: %d ]\n",
4039                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4040                  sub->vtr_tag1, sub->vtr_tag2);
4041       }
4042   }
4043
4044   return 0;
4045 }
4046
4047 static int
4048 name_sort_cmp (void *a1, void *a2)
4049 {
4050   name_sort_t *n1 = a1;
4051   name_sort_t *n2 = a2;
4052
4053   return strcmp ((char *) n1->name, (char *) n2->name);
4054 }
4055
4056 static int
4057 dump_interface_table (vat_main_t * vam)
4058 {
4059   hash_pair_t *p;
4060   name_sort_t *nses = 0, *ns;
4061
4062   if (vam->json_output)
4063     {
4064       clib_warning
4065         ("JSON output supported only for VPE API calls and dump_stats_table");
4066       return -99;
4067     }
4068
4069   /* *INDENT-OFF* */
4070   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4071   ({
4072     vec_add2 (nses, ns, 1);
4073     ns->name = (u8 *)(p->key);
4074     ns->value = (u32) p->value[0];
4075   }));
4076   /* *INDENT-ON* */
4077
4078   vec_sort_with_function (nses, name_sort_cmp);
4079
4080   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
4081   vec_foreach (ns, nses)
4082   {
4083     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
4084   }
4085   vec_free (nses);
4086   return 0;
4087 }
4088
4089 static int
4090 dump_ip_table (vat_main_t * vam, int is_ipv6)
4091 {
4092   const ip_details_t *det = NULL;
4093   const ip_address_details_t *address = NULL;
4094   u32 i = ~0;
4095
4096   fformat (vam->ofp, "%-12s\n", "sw_if_index");
4097
4098   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4099   {
4100     i++;
4101     if (!det->present)
4102       {
4103         continue;
4104       }
4105     fformat (vam->ofp, "%-12d\n", i);
4106     fformat (vam->ofp,
4107              "            %-30s%-13s\n", "Address", "Prefix length");
4108     if (!det->addr)
4109       {
4110         continue;
4111       }
4112     vec_foreach (address, det->addr)
4113     {
4114       fformat (vam->ofp,
4115                "            %-30U%-13d\n",
4116                is_ipv6 ? format_ip6_address : format_ip4_address,
4117                address->ip, address->prefix_length);
4118     }
4119   }
4120
4121   return 0;
4122 }
4123
4124 static int
4125 dump_ipv4_table (vat_main_t * vam)
4126 {
4127   if (vam->json_output)
4128     {
4129       clib_warning
4130         ("JSON output supported only for VPE API calls and dump_stats_table");
4131       return -99;
4132     }
4133
4134   return dump_ip_table (vam, 0);
4135 }
4136
4137 static int
4138 dump_ipv6_table (vat_main_t * vam)
4139 {
4140   if (vam->json_output)
4141     {
4142       clib_warning
4143         ("JSON output supported only for VPE API calls and dump_stats_table");
4144       return -99;
4145     }
4146
4147   return dump_ip_table (vam, 1);
4148 }
4149
4150 static char *
4151 counter_type_to_str (u8 counter_type, u8 is_combined)
4152 {
4153   if (!is_combined)
4154     {
4155       switch (counter_type)
4156         {
4157         case VNET_INTERFACE_COUNTER_DROP:
4158           return "drop";
4159         case VNET_INTERFACE_COUNTER_PUNT:
4160           return "punt";
4161         case VNET_INTERFACE_COUNTER_IP4:
4162           return "ip4";
4163         case VNET_INTERFACE_COUNTER_IP6:
4164           return "ip6";
4165         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4166           return "rx-no-buf";
4167         case VNET_INTERFACE_COUNTER_RX_MISS:
4168           return "rx-miss";
4169         case VNET_INTERFACE_COUNTER_RX_ERROR:
4170           return "rx-error";
4171         case VNET_INTERFACE_COUNTER_TX_ERROR:
4172           return "tx-error";
4173         default:
4174           return "INVALID-COUNTER-TYPE";
4175         }
4176     }
4177   else
4178     {
4179       switch (counter_type)
4180         {
4181         case VNET_INTERFACE_COUNTER_RX:
4182           return "rx";
4183         case VNET_INTERFACE_COUNTER_TX:
4184           return "tx";
4185         default:
4186           return "INVALID-COUNTER-TYPE";
4187         }
4188     }
4189 }
4190
4191 static int
4192 dump_stats_table (vat_main_t * vam)
4193 {
4194   vat_json_node_t node;
4195   vat_json_node_t *msg_array;
4196   vat_json_node_t *msg;
4197   vat_json_node_t *counter_array;
4198   vat_json_node_t *counter;
4199   interface_counter_t c;
4200   u64 packets;
4201   ip4_fib_counter_t *c4;
4202   ip6_fib_counter_t *c6;
4203   int i, j;
4204
4205   if (!vam->json_output)
4206     {
4207       clib_warning ("dump_stats_table supported only in JSON format");
4208       return -99;
4209     }
4210
4211   vat_json_init_object (&node);
4212
4213   /* interface counters */
4214   msg_array = vat_json_object_add (&node, "interface_counters");
4215   vat_json_init_array (msg_array);
4216   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4217     {
4218       msg = vat_json_array_add (msg_array);
4219       vat_json_init_object (msg);
4220       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4221                                        (u8 *) counter_type_to_str (i, 0));
4222       vat_json_object_add_int (msg, "is_combined", 0);
4223       counter_array = vat_json_object_add (msg, "data");
4224       vat_json_init_array (counter_array);
4225       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4226         {
4227           packets = vam->simple_interface_counters[i][j];
4228           vat_json_array_add_uint (counter_array, packets);
4229         }
4230     }
4231   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4232     {
4233       msg = vat_json_array_add (msg_array);
4234       vat_json_init_object (msg);
4235       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4236                                        (u8 *) counter_type_to_str (i, 1));
4237       vat_json_object_add_int (msg, "is_combined", 1);
4238       counter_array = vat_json_object_add (msg, "data");
4239       vat_json_init_array (counter_array);
4240       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4241         {
4242           c = vam->combined_interface_counters[i][j];
4243           counter = vat_json_array_add (counter_array);
4244           vat_json_init_object (counter);
4245           vat_json_object_add_uint (counter, "packets", c.packets);
4246           vat_json_object_add_uint (counter, "bytes", c.bytes);
4247         }
4248     }
4249
4250   /* ip4 fib counters */
4251   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4252   vat_json_init_array (msg_array);
4253   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4254     {
4255       msg = vat_json_array_add (msg_array);
4256       vat_json_init_object (msg);
4257       vat_json_object_add_uint (msg, "vrf_id",
4258                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4259       counter_array = vat_json_object_add (msg, "c");
4260       vat_json_init_array (counter_array);
4261       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4262         {
4263           counter = vat_json_array_add (counter_array);
4264           vat_json_init_object (counter);
4265           c4 = &vam->ip4_fib_counters[i][j];
4266           vat_json_object_add_ip4 (counter, "address", c4->address);
4267           vat_json_object_add_uint (counter, "address_length",
4268                                     c4->address_length);
4269           vat_json_object_add_uint (counter, "packets", c4->packets);
4270           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4271         }
4272     }
4273
4274   /* ip6 fib counters */
4275   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4276   vat_json_init_array (msg_array);
4277   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4278     {
4279       msg = vat_json_array_add (msg_array);
4280       vat_json_init_object (msg);
4281       vat_json_object_add_uint (msg, "vrf_id",
4282                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4283       counter_array = vat_json_object_add (msg, "c");
4284       vat_json_init_array (counter_array);
4285       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4286         {
4287           counter = vat_json_array_add (counter_array);
4288           vat_json_init_object (counter);
4289           c6 = &vam->ip6_fib_counters[i][j];
4290           vat_json_object_add_ip6 (counter, "address", c6->address);
4291           vat_json_object_add_uint (counter, "address_length",
4292                                     c6->address_length);
4293           vat_json_object_add_uint (counter, "packets", c6->packets);
4294           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4295         }
4296     }
4297
4298   vat_json_print (vam->ofp, &node);
4299   vat_json_free (&node);
4300
4301   return 0;
4302 }
4303
4304 int
4305 exec (vat_main_t * vam)
4306 {
4307   api_main_t *am = &api_main;
4308   vl_api_cli_request_t *mp;
4309   f64 timeout;
4310   void *oldheap;
4311   u8 *cmd = 0;
4312   unformat_input_t *i = vam->input;
4313
4314   if (vec_len (i->buffer) == 0)
4315     return -1;
4316
4317   if (vam->exec_mode == 0 && unformat (i, "mode"))
4318     {
4319       vam->exec_mode = 1;
4320       return 0;
4321     }
4322   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4323     {
4324       vam->exec_mode = 0;
4325       return 0;
4326     }
4327
4328
4329   M (CLI_REQUEST, cli_request);
4330
4331   /*
4332    * Copy cmd into shared memory.
4333    * In order for the CLI command to work, it
4334    * must be a vector ending in \n, not a C-string ending
4335    * in \n\0.
4336    */
4337   pthread_mutex_lock (&am->vlib_rp->mutex);
4338   oldheap = svm_push_data_heap (am->vlib_rp);
4339
4340   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4341   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4342
4343   svm_pop_heap (oldheap);
4344   pthread_mutex_unlock (&am->vlib_rp->mutex);
4345
4346   mp->cmd_in_shmem = (u64) cmd;
4347   S;
4348   timeout = vat_time_now (vam) + 10.0;
4349
4350   while (vat_time_now (vam) < timeout)
4351     {
4352       if (vam->result_ready == 1)
4353         {
4354           u8 *free_me;
4355           if (vam->shmem_result != NULL)
4356             fformat (vam->ofp, "%s", vam->shmem_result);
4357           pthread_mutex_lock (&am->vlib_rp->mutex);
4358           oldheap = svm_push_data_heap (am->vlib_rp);
4359
4360           free_me = (u8 *) vam->shmem_result;
4361           vec_free (free_me);
4362
4363           svm_pop_heap (oldheap);
4364           pthread_mutex_unlock (&am->vlib_rp->mutex);
4365           return 0;
4366         }
4367     }
4368   return -99;
4369 }
4370
4371 /*
4372  * Future replacement of exec() that passes CLI buffers directly in
4373  * the API messages instead of an additional shared memory area.
4374  */
4375 static int
4376 exec_inband (vat_main_t * vam)
4377 {
4378   vl_api_cli_inband_t *mp;
4379   f64 timeout;
4380   unformat_input_t *i = vam->input;
4381
4382   if (vec_len (i->buffer) == 0)
4383     return -1;
4384
4385   if (vam->exec_mode == 0 && unformat (i, "mode"))
4386     {
4387       vam->exec_mode = 1;
4388       return 0;
4389     }
4390   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4391     {
4392       vam->exec_mode = 0;
4393       return 0;
4394     }
4395
4396   /*
4397    * In order for the CLI command to work, it
4398    * must be a vector ending in \n, not a C-string ending
4399    * in \n\0.
4400    */
4401   u32 len = vec_len (vam->input->buffer);
4402   M2 (CLI_INBAND, cli_inband, len);
4403   clib_memcpy (mp->cmd, vam->input->buffer, len);
4404   mp->length = htonl (len);
4405
4406   S;
4407   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4408 }
4409
4410 static int
4411 api_create_loopback (vat_main_t * vam)
4412 {
4413   unformat_input_t *i = vam->input;
4414   vl_api_create_loopback_t *mp;
4415   f64 timeout;
4416   u8 mac_address[6];
4417   u8 mac_set = 0;
4418
4419   memset (mac_address, 0, sizeof (mac_address));
4420
4421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4422     {
4423       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4424         mac_set = 1;
4425       else
4426         break;
4427     }
4428
4429   /* Construct the API message */
4430   M (CREATE_LOOPBACK, create_loopback);
4431   if (mac_set)
4432     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4433
4434   S;
4435   W;
4436 }
4437
4438 static int
4439 api_delete_loopback (vat_main_t * vam)
4440 {
4441   unformat_input_t *i = vam->input;
4442   vl_api_delete_loopback_t *mp;
4443   f64 timeout;
4444   u32 sw_if_index = ~0;
4445
4446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4447     {
4448       if (unformat (i, "sw_if_index %d", &sw_if_index))
4449         ;
4450       else
4451         break;
4452     }
4453
4454   if (sw_if_index == ~0)
4455     {
4456       errmsg ("missing sw_if_index\n");
4457       return -99;
4458     }
4459
4460   /* Construct the API message */
4461   M (DELETE_LOOPBACK, delete_loopback);
4462   mp->sw_if_index = ntohl (sw_if_index);
4463
4464   S;
4465   W;
4466 }
4467
4468 static int
4469 api_want_stats (vat_main_t * vam)
4470 {
4471   unformat_input_t *i = vam->input;
4472   vl_api_want_stats_t *mp;
4473   f64 timeout;
4474   int enable = -1;
4475
4476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4477     {
4478       if (unformat (i, "enable"))
4479         enable = 1;
4480       else if (unformat (i, "disable"))
4481         enable = 0;
4482       else
4483         break;
4484     }
4485
4486   if (enable == -1)
4487     {
4488       errmsg ("missing enable|disable\n");
4489       return -99;
4490     }
4491
4492   M (WANT_STATS, want_stats);
4493   mp->enable_disable = enable;
4494
4495   S;
4496   W;
4497 }
4498
4499 static int
4500 api_want_interface_events (vat_main_t * vam)
4501 {
4502   unformat_input_t *i = vam->input;
4503   vl_api_want_interface_events_t *mp;
4504   f64 timeout;
4505   int enable = -1;
4506
4507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4508     {
4509       if (unformat (i, "enable"))
4510         enable = 1;
4511       else if (unformat (i, "disable"))
4512         enable = 0;
4513       else
4514         break;
4515     }
4516
4517   if (enable == -1)
4518     {
4519       errmsg ("missing enable|disable\n");
4520       return -99;
4521     }
4522
4523   M (WANT_INTERFACE_EVENTS, want_interface_events);
4524   mp->enable_disable = enable;
4525
4526   vam->interface_event_display = enable;
4527
4528   S;
4529   W;
4530 }
4531
4532
4533 /* Note: non-static, called once to set up the initial intfc table */
4534 int
4535 api_sw_interface_dump (vat_main_t * vam)
4536 {
4537   vl_api_sw_interface_dump_t *mp;
4538   f64 timeout;
4539   hash_pair_t *p;
4540   name_sort_t *nses = 0, *ns;
4541   sw_interface_subif_t *sub = NULL;
4542
4543   /* Toss the old name table */
4544   /* *INDENT-OFF* */
4545   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4546   ({
4547     vec_add2 (nses, ns, 1);
4548     ns->name = (u8 *)(p->key);
4549     ns->value = (u32) p->value[0];
4550   }));
4551   /* *INDENT-ON* */
4552
4553   hash_free (vam->sw_if_index_by_interface_name);
4554
4555   vec_foreach (ns, nses) vec_free (ns->name);
4556
4557   vec_free (nses);
4558
4559   vec_foreach (sub, vam->sw_if_subif_table)
4560   {
4561     vec_free (sub->interface_name);
4562   }
4563   vec_free (vam->sw_if_subif_table);
4564
4565   /* recreate the interface name hash table */
4566   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4567
4568   /* Get list of ethernets */
4569   M (SW_INTERFACE_DUMP, sw_interface_dump);
4570   mp->name_filter_valid = 1;
4571   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4572   S;
4573
4574   /* and local / loopback interfaces */
4575   M (SW_INTERFACE_DUMP, sw_interface_dump);
4576   mp->name_filter_valid = 1;
4577   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4578   S;
4579
4580   /* and packet-generator interfaces */
4581   M (SW_INTERFACE_DUMP, sw_interface_dump);
4582   mp->name_filter_valid = 1;
4583   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4584   S;
4585
4586   /* and vxlan-gpe tunnel interfaces */
4587   M (SW_INTERFACE_DUMP, sw_interface_dump);
4588   mp->name_filter_valid = 1;
4589   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4590            sizeof (mp->name_filter) - 1);
4591   S;
4592
4593   /* and vxlan tunnel interfaces */
4594   M (SW_INTERFACE_DUMP, sw_interface_dump);
4595   mp->name_filter_valid = 1;
4596   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4597   S;
4598
4599   /* and host (af_packet) interfaces */
4600   M (SW_INTERFACE_DUMP, sw_interface_dump);
4601   mp->name_filter_valid = 1;
4602   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4603   S;
4604
4605   /* and l2tpv3 tunnel interfaces */
4606   M (SW_INTERFACE_DUMP, sw_interface_dump);
4607   mp->name_filter_valid = 1;
4608   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4609            sizeof (mp->name_filter) - 1);
4610   S;
4611
4612   /* and GRE tunnel interfaces */
4613   M (SW_INTERFACE_DUMP, sw_interface_dump);
4614   mp->name_filter_valid = 1;
4615   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4616   S;
4617
4618   /* and LISP-GPE interfaces */
4619   M (SW_INTERFACE_DUMP, sw_interface_dump);
4620   mp->name_filter_valid = 1;
4621   strncpy ((char *) mp->name_filter, "lisp_gpe",
4622            sizeof (mp->name_filter) - 1);
4623   S;
4624
4625   /* and IPSEC tunnel interfaces */
4626   M (SW_INTERFACE_DUMP, sw_interface_dump);
4627   mp->name_filter_valid = 1;
4628   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4629   S;
4630
4631   /* Use a control ping for synchronization */
4632   {
4633     vl_api_control_ping_t *mp;
4634     M (CONTROL_PING, control_ping);
4635     S;
4636   }
4637   W;
4638 }
4639
4640 static int
4641 api_sw_interface_set_flags (vat_main_t * vam)
4642 {
4643   unformat_input_t *i = vam->input;
4644   vl_api_sw_interface_set_flags_t *mp;
4645   f64 timeout;
4646   u32 sw_if_index;
4647   u8 sw_if_index_set = 0;
4648   u8 admin_up = 0, link_up = 0;
4649
4650   /* Parse args required to build the message */
4651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4652     {
4653       if (unformat (i, "admin-up"))
4654         admin_up = 1;
4655       else if (unformat (i, "admin-down"))
4656         admin_up = 0;
4657       else if (unformat (i, "link-up"))
4658         link_up = 1;
4659       else if (unformat (i, "link-down"))
4660         link_up = 0;
4661       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4662         sw_if_index_set = 1;
4663       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4664         sw_if_index_set = 1;
4665       else
4666         break;
4667     }
4668
4669   if (sw_if_index_set == 0)
4670     {
4671       errmsg ("missing interface name or sw_if_index\n");
4672       return -99;
4673     }
4674
4675   /* Construct the API message */
4676   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4677   mp->sw_if_index = ntohl (sw_if_index);
4678   mp->admin_up_down = admin_up;
4679   mp->link_up_down = link_up;
4680
4681   /* send it... */
4682   S;
4683
4684   /* Wait for a reply, return the good/bad news... */
4685   W;
4686 }
4687
4688 static int
4689 api_sw_interface_clear_stats (vat_main_t * vam)
4690 {
4691   unformat_input_t *i = vam->input;
4692   vl_api_sw_interface_clear_stats_t *mp;
4693   f64 timeout;
4694   u32 sw_if_index;
4695   u8 sw_if_index_set = 0;
4696
4697   /* Parse args required to build the message */
4698   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4699     {
4700       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4701         sw_if_index_set = 1;
4702       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4703         sw_if_index_set = 1;
4704       else
4705         break;
4706     }
4707
4708   /* Construct the API message */
4709   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4710
4711   if (sw_if_index_set == 1)
4712     mp->sw_if_index = ntohl (sw_if_index);
4713   else
4714     mp->sw_if_index = ~0;
4715
4716   /* send it... */
4717   S;
4718
4719   /* Wait for a reply, return the good/bad news... */
4720   W;
4721 }
4722
4723 static int
4724 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4725 {
4726   unformat_input_t *i = vam->input;
4727   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4728   f64 timeout;
4729   u32 sw_if_index;
4730   u8 sw_if_index_set = 0;
4731   u32 subport;
4732   u8 subport_set = 0;
4733   u32 pipe;
4734   u8 pipe_set = 0;
4735   u32 profile;
4736   u8 profile_set = 0;
4737
4738   /* Parse args required to build the message */
4739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4740     {
4741       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4742         sw_if_index_set = 1;
4743       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4744         sw_if_index_set = 1;
4745       else if (unformat (i, "subport %u", &subport))
4746         subport_set = 1;
4747       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4748         sw_if_index_set = 1;
4749       else if (unformat (i, "pipe %u", &pipe))
4750         pipe_set = 1;
4751       else if (unformat (i, "profile %u", &profile))
4752         profile_set = 1;
4753       else
4754         break;
4755     }
4756
4757   if (sw_if_index_set == 0)
4758     {
4759       errmsg ("missing interface name or sw_if_index\n");
4760       return -99;
4761     }
4762
4763   if (subport_set == 0)
4764     {
4765       errmsg ("missing subport \n");
4766       return -99;
4767     }
4768
4769   if (pipe_set == 0)
4770     {
4771       errmsg ("missing pipe\n");
4772       return -99;
4773     }
4774
4775   if (profile_set == 0)
4776     {
4777       errmsg ("missing profile\n");
4778       return -99;
4779     }
4780
4781   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4782
4783   mp->sw_if_index = ntohl (sw_if_index);
4784   mp->subport = ntohl (subport);
4785   mp->pipe = ntohl (pipe);
4786   mp->profile = ntohl (profile);
4787
4788
4789   S;
4790   W;
4791   /* NOTREACHED */
4792   return 0;
4793 }
4794
4795 static int
4796 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4797 {
4798   unformat_input_t *i = vam->input;
4799   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4800   f64 timeout;
4801   u32 sw_if_index;
4802   u8 sw_if_index_set = 0;
4803   u32 subport;
4804   u8 subport_set = 0;
4805   u32 tb_rate = 1250000000;     /* 10GbE */
4806   u32 tb_size = 1000000;
4807   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4808   u32 tc_period = 10;
4809
4810   /* Parse args required to build the message */
4811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4812     {
4813       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4814         sw_if_index_set = 1;
4815       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4816         sw_if_index_set = 1;
4817       else if (unformat (i, "subport %u", &subport))
4818         subport_set = 1;
4819       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4820         sw_if_index_set = 1;
4821       else if (unformat (i, "rate %u", &tb_rate))
4822         {
4823           u32 tc_id;
4824
4825           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4826                tc_id++)
4827             tc_rate[tc_id] = tb_rate;
4828         }
4829       else if (unformat (i, "bktsize %u", &tb_size))
4830         ;
4831       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4832         ;
4833       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4834         ;
4835       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4836         ;
4837       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4838         ;
4839       else if (unformat (i, "period %u", &tc_period))
4840         ;
4841       else
4842         break;
4843     }
4844
4845   if (sw_if_index_set == 0)
4846     {
4847       errmsg ("missing interface name or sw_if_index\n");
4848       return -99;
4849     }
4850
4851   if (subport_set == 0)
4852     {
4853       errmsg ("missing subport \n");
4854       return -99;
4855     }
4856
4857   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4858
4859   mp->sw_if_index = ntohl (sw_if_index);
4860   mp->subport = ntohl (subport);
4861   mp->tb_rate = ntohl (tb_rate);
4862   mp->tb_size = ntohl (tb_size);
4863   mp->tc_rate[0] = ntohl (tc_rate[0]);
4864   mp->tc_rate[1] = ntohl (tc_rate[1]);
4865   mp->tc_rate[2] = ntohl (tc_rate[2]);
4866   mp->tc_rate[3] = ntohl (tc_rate[3]);
4867   mp->tc_period = ntohl (tc_period);
4868
4869   S;
4870   W;
4871   /* NOTREACHED */
4872   return 0;
4873 }
4874
4875 static int
4876 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4877 {
4878   unformat_input_t *i = vam->input;
4879   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4880   f64 timeout;
4881   u32 sw_if_index;
4882   u8 sw_if_index_set = 0;
4883   u8 entry_set = 0;
4884   u8 tc_set = 0;
4885   u8 queue_set = 0;
4886   u32 entry, tc, queue;
4887
4888   /* Parse args required to build the message */
4889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4890     {
4891       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4892         sw_if_index_set = 1;
4893       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4894         sw_if_index_set = 1;
4895       else if (unformat (i, "entry %d", &entry))
4896         entry_set = 1;
4897       else if (unformat (i, "tc %d", &tc))
4898         tc_set = 1;
4899       else if (unformat (i, "queue %d", &queue))
4900         queue_set = 1;
4901       else
4902         break;
4903     }
4904
4905   if (sw_if_index_set == 0)
4906     {
4907       errmsg ("missing interface name or sw_if_index\n");
4908       return -99;
4909     }
4910
4911   if (entry_set == 0)
4912     {
4913       errmsg ("missing entry \n");
4914       return -99;
4915     }
4916
4917   if (tc_set == 0)
4918     {
4919       errmsg ("missing traffic class \n");
4920       return -99;
4921     }
4922
4923   if (queue_set == 0)
4924     {
4925       errmsg ("missing queue \n");
4926       return -99;
4927     }
4928
4929   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4930
4931   mp->sw_if_index = ntohl (sw_if_index);
4932   mp->entry = ntohl (entry);
4933   mp->tc = ntohl (tc);
4934   mp->queue = ntohl (queue);
4935
4936   S;
4937   W;
4938   /* NOTREACHED */
4939   return 0;
4940 }
4941
4942 static int
4943 api_sw_interface_add_del_address (vat_main_t * vam)
4944 {
4945   unformat_input_t *i = vam->input;
4946   vl_api_sw_interface_add_del_address_t *mp;
4947   f64 timeout;
4948   u32 sw_if_index;
4949   u8 sw_if_index_set = 0;
4950   u8 is_add = 1, del_all = 0;
4951   u32 address_length = 0;
4952   u8 v4_address_set = 0;
4953   u8 v6_address_set = 0;
4954   ip4_address_t v4address;
4955   ip6_address_t v6address;
4956
4957   /* Parse args required to build the message */
4958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4959     {
4960       if (unformat (i, "del-all"))
4961         del_all = 1;
4962       else if (unformat (i, "del"))
4963         is_add = 0;
4964       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4965         sw_if_index_set = 1;
4966       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4967         sw_if_index_set = 1;
4968       else if (unformat (i, "%U/%d",
4969                          unformat_ip4_address, &v4address, &address_length))
4970         v4_address_set = 1;
4971       else if (unformat (i, "%U/%d",
4972                          unformat_ip6_address, &v6address, &address_length))
4973         v6_address_set = 1;
4974       else
4975         break;
4976     }
4977
4978   if (sw_if_index_set == 0)
4979     {
4980       errmsg ("missing interface name or sw_if_index\n");
4981       return -99;
4982     }
4983   if (v4_address_set && v6_address_set)
4984     {
4985       errmsg ("both v4 and v6 addresses set\n");
4986       return -99;
4987     }
4988   if (!v4_address_set && !v6_address_set && !del_all)
4989     {
4990       errmsg ("no addresses set\n");
4991       return -99;
4992     }
4993
4994   /* Construct the API message */
4995   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4996
4997   mp->sw_if_index = ntohl (sw_if_index);
4998   mp->is_add = is_add;
4999   mp->del_all = del_all;
5000   if (v6_address_set)
5001     {
5002       mp->is_ipv6 = 1;
5003       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5004     }
5005   else
5006     {
5007       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5008     }
5009   mp->address_length = address_length;
5010
5011   /* send it... */
5012   S;
5013
5014   /* Wait for a reply, return good/bad news  */
5015   W;
5016 }
5017
5018 static int
5019 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5020 {
5021   unformat_input_t *i = vam->input;
5022   vl_api_sw_interface_set_mpls_enable_t *mp;
5023   f64 timeout;
5024   u32 sw_if_index;
5025   u8 sw_if_index_set = 0;
5026   u8 enable = 1;
5027
5028   /* Parse args required to build the message */
5029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5030     {
5031       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5032         sw_if_index_set = 1;
5033       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5034         sw_if_index_set = 1;
5035       else if (unformat (i, "disable"))
5036         enable = 0;
5037       else if (unformat (i, "dis"))
5038         enable = 0;
5039       else
5040         break;
5041     }
5042
5043   if (sw_if_index_set == 0)
5044     {
5045       errmsg ("missing interface name or sw_if_index\n");
5046       return -99;
5047     }
5048
5049   /* Construct the API message */
5050   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
5051
5052   mp->sw_if_index = ntohl (sw_if_index);
5053   mp->enable = enable;
5054
5055   /* send it... */
5056   S;
5057
5058   /* Wait for a reply... */
5059   W;
5060 }
5061
5062 static int
5063 api_sw_interface_set_table (vat_main_t * vam)
5064 {
5065   unformat_input_t *i = vam->input;
5066   vl_api_sw_interface_set_table_t *mp;
5067   f64 timeout;
5068   u32 sw_if_index, vrf_id = 0;
5069   u8 sw_if_index_set = 0;
5070   u8 is_ipv6 = 0;
5071
5072   /* Parse args required to build the message */
5073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5074     {
5075       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5076         sw_if_index_set = 1;
5077       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5078         sw_if_index_set = 1;
5079       else if (unformat (i, "vrf %d", &vrf_id))
5080         ;
5081       else if (unformat (i, "ipv6"))
5082         is_ipv6 = 1;
5083       else
5084         break;
5085     }
5086
5087   if (sw_if_index_set == 0)
5088     {
5089       errmsg ("missing interface name or sw_if_index\n");
5090       return -99;
5091     }
5092
5093   /* Construct the API message */
5094   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
5095
5096   mp->sw_if_index = ntohl (sw_if_index);
5097   mp->is_ipv6 = is_ipv6;
5098   mp->vrf_id = ntohl (vrf_id);
5099
5100   /* send it... */
5101   S;
5102
5103   /* Wait for a reply... */
5104   W;
5105 }
5106
5107 static int
5108 api_sw_interface_set_vpath (vat_main_t * vam)
5109 {
5110   unformat_input_t *i = vam->input;
5111   vl_api_sw_interface_set_vpath_t *mp;
5112   f64 timeout;
5113   u32 sw_if_index = 0;
5114   u8 sw_if_index_set = 0;
5115   u8 is_enable = 0;
5116
5117   /* Parse args required to build the message */
5118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5119     {
5120       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5121         sw_if_index_set = 1;
5122       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5123         sw_if_index_set = 1;
5124       else if (unformat (i, "enable"))
5125         is_enable = 1;
5126       else if (unformat (i, "disable"))
5127         is_enable = 0;
5128       else
5129         break;
5130     }
5131
5132   if (sw_if_index_set == 0)
5133     {
5134       errmsg ("missing interface name or sw_if_index\n");
5135       return -99;
5136     }
5137
5138   /* Construct the API message */
5139   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5140
5141   mp->sw_if_index = ntohl (sw_if_index);
5142   mp->enable = is_enable;
5143
5144   /* send it... */
5145   S;
5146
5147   /* Wait for a reply... */
5148   W;
5149 }
5150
5151 static int
5152 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5153 {
5154   unformat_input_t *i = vam->input;
5155   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5156   f64 timeout;
5157   u32 sw_if_index = 0;
5158   u8 sw_if_index_set = 0;
5159   u8 is_enable = 0;
5160   u8 is_ipv6 = 0;
5161
5162   /* Parse args required to build the message */
5163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5164     {
5165       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5166         sw_if_index_set = 1;
5167       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5168         sw_if_index_set = 1;
5169       else if (unformat (i, "enable"))
5170         is_enable = 1;
5171       else if (unformat (i, "disable"))
5172         is_enable = 0;
5173       else if (unformat (i, "ip4"))
5174         is_ipv6 = 0;
5175       else if (unformat (i, "ip6"))
5176         is_ipv6 = 1;
5177       else
5178         break;
5179     }
5180
5181   if (sw_if_index_set == 0)
5182     {
5183       errmsg ("missing interface name or sw_if_index\n");
5184       return -99;
5185     }
5186
5187   /* Construct the API message */
5188   M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5189
5190   mp->sw_if_index = ntohl (sw_if_index);
5191   mp->enable = is_enable;
5192   mp->is_ipv6 = is_ipv6;
5193
5194   /* send it... */
5195   S;
5196
5197   /* Wait for a reply... */
5198   W;
5199 }
5200
5201 static int
5202 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5203 {
5204   unformat_input_t *i = vam->input;
5205   vl_api_sw_interface_set_l2_xconnect_t *mp;
5206   f64 timeout;
5207   u32 rx_sw_if_index;
5208   u8 rx_sw_if_index_set = 0;
5209   u32 tx_sw_if_index;
5210   u8 tx_sw_if_index_set = 0;
5211   u8 enable = 1;
5212
5213   /* Parse args required to build the message */
5214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5215     {
5216       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5217         rx_sw_if_index_set = 1;
5218       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5219         tx_sw_if_index_set = 1;
5220       else if (unformat (i, "rx"))
5221         {
5222           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5223             {
5224               if (unformat (i, "%U", unformat_sw_if_index, vam,
5225                             &rx_sw_if_index))
5226                 rx_sw_if_index_set = 1;
5227             }
5228           else
5229             break;
5230         }
5231       else if (unformat (i, "tx"))
5232         {
5233           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5234             {
5235               if (unformat (i, "%U", unformat_sw_if_index, vam,
5236                             &tx_sw_if_index))
5237                 tx_sw_if_index_set = 1;
5238             }
5239           else
5240             break;
5241         }
5242       else if (unformat (i, "enable"))
5243         enable = 1;
5244       else if (unformat (i, "disable"))
5245         enable = 0;
5246       else
5247         break;
5248     }
5249
5250   if (rx_sw_if_index_set == 0)
5251     {
5252       errmsg ("missing rx interface name or rx_sw_if_index\n");
5253       return -99;
5254     }
5255
5256   if (enable && (tx_sw_if_index_set == 0))
5257     {
5258       errmsg ("missing tx interface name or tx_sw_if_index\n");
5259       return -99;
5260     }
5261
5262   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5263
5264   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5265   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5266   mp->enable = enable;
5267
5268   S;
5269   W;
5270   /* NOTREACHED */
5271   return 0;
5272 }
5273
5274 static int
5275 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5276 {
5277   unformat_input_t *i = vam->input;
5278   vl_api_sw_interface_set_l2_bridge_t *mp;
5279   f64 timeout;
5280   u32 rx_sw_if_index;
5281   u8 rx_sw_if_index_set = 0;
5282   u32 bd_id;
5283   u8 bd_id_set = 0;
5284   u8 bvi = 0;
5285   u32 shg = 0;
5286   u8 enable = 1;
5287
5288   /* Parse args required to build the message */
5289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5290     {
5291       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5292         rx_sw_if_index_set = 1;
5293       else if (unformat (i, "bd_id %d", &bd_id))
5294         bd_id_set = 1;
5295       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5296         rx_sw_if_index_set = 1;
5297       else if (unformat (i, "shg %d", &shg))
5298         ;
5299       else if (unformat (i, "bvi"))
5300         bvi = 1;
5301       else if (unformat (i, "enable"))
5302         enable = 1;
5303       else if (unformat (i, "disable"))
5304         enable = 0;
5305       else
5306         break;
5307     }
5308
5309   if (rx_sw_if_index_set == 0)
5310     {
5311       errmsg ("missing rx interface name or sw_if_index\n");
5312       return -99;
5313     }
5314
5315   if (enable && (bd_id_set == 0))
5316     {
5317       errmsg ("missing bridge domain\n");
5318       return -99;
5319     }
5320
5321   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5322
5323   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5324   mp->bd_id = ntohl (bd_id);
5325   mp->shg = (u8) shg;
5326   mp->bvi = bvi;
5327   mp->enable = enable;
5328
5329   S;
5330   W;
5331   /* NOTREACHED */
5332   return 0;
5333 }
5334
5335 static int
5336 api_bridge_domain_dump (vat_main_t * vam)
5337 {
5338   unformat_input_t *i = vam->input;
5339   vl_api_bridge_domain_dump_t *mp;
5340   f64 timeout;
5341   u32 bd_id = ~0;
5342
5343   /* Parse args required to build the message */
5344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5345     {
5346       if (unformat (i, "bd_id %d", &bd_id))
5347         ;
5348       else
5349         break;
5350     }
5351
5352   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5353   mp->bd_id = ntohl (bd_id);
5354   S;
5355
5356   /* Use a control ping for synchronization */
5357   {
5358     vl_api_control_ping_t *mp;
5359     M (CONTROL_PING, control_ping);
5360     S;
5361   }
5362
5363   W;
5364   /* NOTREACHED */
5365   return 0;
5366 }
5367
5368 static int
5369 api_bridge_domain_add_del (vat_main_t * vam)
5370 {
5371   unformat_input_t *i = vam->input;
5372   vl_api_bridge_domain_add_del_t *mp;
5373   f64 timeout;
5374   u32 bd_id = ~0;
5375   u8 is_add = 1;
5376   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5377
5378   /* Parse args required to build the message */
5379   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5380     {
5381       if (unformat (i, "bd_id %d", &bd_id))
5382         ;
5383       else if (unformat (i, "flood %d", &flood))
5384         ;
5385       else if (unformat (i, "uu-flood %d", &uu_flood))
5386         ;
5387       else if (unformat (i, "forward %d", &forward))
5388         ;
5389       else if (unformat (i, "learn %d", &learn))
5390         ;
5391       else if (unformat (i, "arp-term %d", &arp_term))
5392         ;
5393       else if (unformat (i, "del"))
5394         {
5395           is_add = 0;
5396           flood = uu_flood = forward = learn = 0;
5397         }
5398       else
5399         break;
5400     }
5401
5402   if (bd_id == ~0)
5403     {
5404       errmsg ("missing bridge domain\n");
5405       return -99;
5406     }
5407
5408   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5409
5410   mp->bd_id = ntohl (bd_id);
5411   mp->flood = flood;
5412   mp->uu_flood = uu_flood;
5413   mp->forward = forward;
5414   mp->learn = learn;
5415   mp->arp_term = arp_term;
5416   mp->is_add = is_add;
5417
5418   S;
5419   W;
5420   /* NOTREACHED */
5421   return 0;
5422 }
5423
5424 static int
5425 api_l2fib_add_del (vat_main_t * vam)
5426 {
5427   unformat_input_t *i = vam->input;
5428   vl_api_l2fib_add_del_t *mp;
5429   f64 timeout;
5430   u64 mac = 0;
5431   u8 mac_set = 0;
5432   u32 bd_id;
5433   u8 bd_id_set = 0;
5434   u32 sw_if_index = ~0;
5435   u8 sw_if_index_set = 0;
5436   u8 is_add = 1;
5437   u8 static_mac = 0;
5438   u8 filter_mac = 0;
5439   u8 bvi_mac = 0;
5440   int count = 1;
5441   f64 before = 0;
5442   int j;
5443
5444   /* Parse args required to build the message */
5445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5446     {
5447       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5448         mac_set = 1;
5449       else if (unformat (i, "bd_id %d", &bd_id))
5450         bd_id_set = 1;
5451       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5452         sw_if_index_set = 1;
5453       else if (unformat (i, "sw_if"))
5454         {
5455           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5456             {
5457               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5458                 sw_if_index_set = 1;
5459             }
5460           else
5461             break;
5462         }
5463       else if (unformat (i, "static"))
5464         static_mac = 1;
5465       else if (unformat (i, "filter"))
5466         {
5467           filter_mac = 1;
5468           static_mac = 1;
5469         }
5470       else if (unformat (i, "bvi"))
5471         {
5472           bvi_mac = 1;
5473           static_mac = 1;
5474         }
5475       else if (unformat (i, "del"))
5476         is_add = 0;
5477       else if (unformat (i, "count %d", &count))
5478         ;
5479       else
5480         break;
5481     }
5482
5483   if (mac_set == 0)
5484     {
5485       errmsg ("missing mac address\n");
5486       return -99;
5487     }
5488
5489   if (bd_id_set == 0)
5490     {
5491       errmsg ("missing bridge domain\n");
5492       return -99;
5493     }
5494
5495   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5496     {
5497       errmsg ("missing interface name or sw_if_index\n");
5498       return -99;
5499     }
5500
5501   if (count > 1)
5502     {
5503       /* Turn on async mode */
5504       vam->async_mode = 1;
5505       vam->async_errors = 0;
5506       before = vat_time_now (vam);
5507     }
5508
5509   for (j = 0; j < count; j++)
5510     {
5511       M (L2FIB_ADD_DEL, l2fib_add_del);
5512
5513       mp->mac = mac;
5514       mp->bd_id = ntohl (bd_id);
5515       mp->is_add = is_add;
5516
5517       if (is_add)
5518         {
5519           mp->sw_if_index = ntohl (sw_if_index);
5520           mp->static_mac = static_mac;
5521           mp->filter_mac = filter_mac;
5522           mp->bvi_mac = bvi_mac;
5523         }
5524       increment_mac_address (&mac);
5525       /* send it... */
5526       S;
5527     }
5528
5529   if (count > 1)
5530     {
5531       vl_api_control_ping_t *mp;
5532       f64 after;
5533
5534       /* Shut off async mode */
5535       vam->async_mode = 0;
5536
5537       M (CONTROL_PING, control_ping);
5538       S;
5539
5540       timeout = vat_time_now (vam) + 1.0;
5541       while (vat_time_now (vam) < timeout)
5542         if (vam->result_ready == 1)
5543           goto out;
5544       vam->retval = -99;
5545
5546     out:
5547       if (vam->retval == -99)
5548         errmsg ("timeout\n");
5549
5550       if (vam->async_errors > 0)
5551         {
5552           errmsg ("%d asynchronous errors\n", vam->async_errors);
5553           vam->retval = -98;
5554         }
5555       vam->async_errors = 0;
5556       after = vat_time_now (vam);
5557
5558       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5559                count, after - before, count / (after - before));
5560     }
5561   else
5562     {
5563       /* Wait for a reply... */
5564       W;
5565     }
5566   /* Return the good/bad news */
5567   return (vam->retval);
5568 }
5569
5570 static int
5571 api_l2_flags (vat_main_t * vam)
5572 {
5573   unformat_input_t *i = vam->input;
5574   vl_api_l2_flags_t *mp;
5575   f64 timeout;
5576   u32 sw_if_index;
5577   u32 feature_bitmap = 0;
5578   u8 sw_if_index_set = 0;
5579
5580   /* Parse args required to build the message */
5581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5582     {
5583       if (unformat (i, "sw_if_index %d", &sw_if_index))
5584         sw_if_index_set = 1;
5585       else if (unformat (i, "sw_if"))
5586         {
5587           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5588             {
5589               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5590                 sw_if_index_set = 1;
5591             }
5592           else
5593             break;
5594         }
5595       else if (unformat (i, "learn"))
5596         feature_bitmap |= L2INPUT_FEAT_LEARN;
5597       else if (unformat (i, "forward"))
5598         feature_bitmap |= L2INPUT_FEAT_FWD;
5599       else if (unformat (i, "flood"))
5600         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5601       else if (unformat (i, "uu-flood"))
5602         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5603       else
5604         break;
5605     }
5606
5607   if (sw_if_index_set == 0)
5608     {
5609       errmsg ("missing interface name or sw_if_index\n");
5610       return -99;
5611     }
5612
5613   M (L2_FLAGS, l2_flags);
5614
5615   mp->sw_if_index = ntohl (sw_if_index);
5616   mp->feature_bitmap = ntohl (feature_bitmap);
5617
5618   S;
5619   W;
5620   /* NOTREACHED */
5621   return 0;
5622 }
5623
5624 static int
5625 api_bridge_flags (vat_main_t * vam)
5626 {
5627   unformat_input_t *i = vam->input;
5628   vl_api_bridge_flags_t *mp;
5629   f64 timeout;
5630   u32 bd_id;
5631   u8 bd_id_set = 0;
5632   u8 is_set = 1;
5633   u32 flags = 0;
5634
5635   /* Parse args required to build the message */
5636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5637     {
5638       if (unformat (i, "bd_id %d", &bd_id))
5639         bd_id_set = 1;
5640       else if (unformat (i, "learn"))
5641         flags |= L2_LEARN;
5642       else if (unformat (i, "forward"))
5643         flags |= L2_FWD;
5644       else if (unformat (i, "flood"))
5645         flags |= L2_FLOOD;
5646       else if (unformat (i, "uu-flood"))
5647         flags |= L2_UU_FLOOD;
5648       else if (unformat (i, "arp-term"))
5649         flags |= L2_ARP_TERM;
5650       else if (unformat (i, "off"))
5651         is_set = 0;
5652       else if (unformat (i, "disable"))
5653         is_set = 0;
5654       else
5655         break;
5656     }
5657
5658   if (bd_id_set == 0)
5659     {
5660       errmsg ("missing bridge domain\n");
5661       return -99;
5662     }
5663
5664   M (BRIDGE_FLAGS, bridge_flags);
5665
5666   mp->bd_id = ntohl (bd_id);
5667   mp->feature_bitmap = ntohl (flags);
5668   mp->is_set = is_set;
5669
5670   S;
5671   W;
5672   /* NOTREACHED */
5673   return 0;
5674 }
5675
5676 static int
5677 api_bd_ip_mac_add_del (vat_main_t * vam)
5678 {
5679   unformat_input_t *i = vam->input;
5680   vl_api_bd_ip_mac_add_del_t *mp;
5681   f64 timeout;
5682   u32 bd_id;
5683   u8 is_ipv6 = 0;
5684   u8 is_add = 1;
5685   u8 bd_id_set = 0;
5686   u8 ip_set = 0;
5687   u8 mac_set = 0;
5688   ip4_address_t v4addr;
5689   ip6_address_t v6addr;
5690   u8 macaddr[6];
5691
5692
5693   /* Parse args required to build the message */
5694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5695     {
5696       if (unformat (i, "bd_id %d", &bd_id))
5697         {
5698           bd_id_set++;
5699         }
5700       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5701         {
5702           ip_set++;
5703         }
5704       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5705         {
5706           ip_set++;
5707           is_ipv6++;
5708         }
5709       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5710         {
5711           mac_set++;
5712         }
5713       else if (unformat (i, "del"))
5714         is_add = 0;
5715       else
5716         break;
5717     }
5718
5719   if (bd_id_set == 0)
5720     {
5721       errmsg ("missing bridge domain\n");
5722       return -99;
5723     }
5724   else if (ip_set == 0)
5725     {
5726       errmsg ("missing IP address\n");
5727       return -99;
5728     }
5729   else if (mac_set == 0)
5730     {
5731       errmsg ("missing MAC address\n");
5732       return -99;
5733     }
5734
5735   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5736
5737   mp->bd_id = ntohl (bd_id);
5738   mp->is_ipv6 = is_ipv6;
5739   mp->is_add = is_add;
5740   if (is_ipv6)
5741     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5742   else
5743     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5744   clib_memcpy (mp->mac_address, macaddr, 6);
5745   S;
5746   W;
5747   /* NOTREACHED */
5748   return 0;
5749 }
5750
5751 static int
5752 api_tap_connect (vat_main_t * vam)
5753 {
5754   unformat_input_t *i = vam->input;
5755   vl_api_tap_connect_t *mp;
5756   f64 timeout;
5757   u8 mac_address[6];
5758   u8 random_mac = 1;
5759   u8 name_set = 0;
5760   u8 *tap_name;
5761   u8 *tag = 0;
5762
5763   memset (mac_address, 0, sizeof (mac_address));
5764
5765   /* Parse args required to build the message */
5766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5767     {
5768       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5769         {
5770           random_mac = 0;
5771         }
5772       else if (unformat (i, "random-mac"))
5773         random_mac = 1;
5774       else if (unformat (i, "tapname %s", &tap_name))
5775         name_set = 1;
5776       else if (unformat (i, "tag %s", &tag))
5777         ;
5778       else
5779         break;
5780     }
5781
5782   if (name_set == 0)
5783     {
5784       errmsg ("missing tap name\n");
5785       return -99;
5786     }
5787   if (vec_len (tap_name) > 63)
5788     {
5789       errmsg ("tap name too long\n");
5790       return -99;
5791     }
5792   vec_add1 (tap_name, 0);
5793
5794   if (vec_len (tag) > 63)
5795     {
5796       errmsg ("tag too long\n");
5797       return -99;
5798     }
5799
5800   /* Construct the API message */
5801   M (TAP_CONNECT, tap_connect);
5802
5803   mp->use_random_mac = random_mac;
5804   clib_memcpy (mp->mac_address, mac_address, 6);
5805   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5806   if (tag)
5807     clib_memcpy (mp->tag, tag, vec_len (tag));
5808
5809   vec_free (tap_name);
5810   vec_free (tag);
5811
5812   /* send it... */
5813   S;
5814
5815   /* Wait for a reply... */
5816   W;
5817 }
5818
5819 static int
5820 api_tap_modify (vat_main_t * vam)
5821 {
5822   unformat_input_t *i = vam->input;
5823   vl_api_tap_modify_t *mp;
5824   f64 timeout;
5825   u8 mac_address[6];
5826   u8 random_mac = 1;
5827   u8 name_set = 0;
5828   u8 *tap_name;
5829   u32 sw_if_index = ~0;
5830   u8 sw_if_index_set = 0;
5831
5832   memset (mac_address, 0, sizeof (mac_address));
5833
5834   /* Parse args required to build the message */
5835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5836     {
5837       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5838         sw_if_index_set = 1;
5839       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5840         sw_if_index_set = 1;
5841       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5842         {
5843           random_mac = 0;
5844         }
5845       else if (unformat (i, "random-mac"))
5846         random_mac = 1;
5847       else if (unformat (i, "tapname %s", &tap_name))
5848         name_set = 1;
5849       else
5850         break;
5851     }
5852
5853   if (sw_if_index_set == 0)
5854     {
5855       errmsg ("missing vpp interface name");
5856       return -99;
5857     }
5858   if (name_set == 0)
5859     {
5860       errmsg ("missing tap name\n");
5861       return -99;
5862     }
5863   if (vec_len (tap_name) > 63)
5864     {
5865       errmsg ("tap name too long\n");
5866     }
5867   vec_add1 (tap_name, 0);
5868
5869   /* Construct the API message */
5870   M (TAP_MODIFY, tap_modify);
5871
5872   mp->use_random_mac = random_mac;
5873   mp->sw_if_index = ntohl (sw_if_index);
5874   clib_memcpy (mp->mac_address, mac_address, 6);
5875   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5876   vec_free (tap_name);
5877
5878   /* send it... */
5879   S;
5880
5881   /* Wait for a reply... */
5882   W;
5883 }
5884
5885 static int
5886 api_tap_delete (vat_main_t * vam)
5887 {
5888   unformat_input_t *i = vam->input;
5889   vl_api_tap_delete_t *mp;
5890   f64 timeout;
5891   u32 sw_if_index = ~0;
5892   u8 sw_if_index_set = 0;
5893
5894   /* Parse args required to build the message */
5895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5896     {
5897       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5898         sw_if_index_set = 1;
5899       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5900         sw_if_index_set = 1;
5901       else
5902         break;
5903     }
5904
5905   if (sw_if_index_set == 0)
5906     {
5907       errmsg ("missing vpp interface name");
5908       return -99;
5909     }
5910
5911   /* Construct the API message */
5912   M (TAP_DELETE, tap_delete);
5913
5914   mp->sw_if_index = ntohl (sw_if_index);
5915
5916   /* send it... */
5917   S;
5918
5919   /* Wait for a reply... */
5920   W;
5921 }
5922
5923 static int
5924 api_ip_add_del_route (vat_main_t * vam)
5925 {
5926   unformat_input_t *i = vam->input;
5927   vl_api_ip_add_del_route_t *mp;
5928   f64 timeout;
5929   u32 sw_if_index = ~0, vrf_id = 0;
5930   u8 is_ipv6 = 0;
5931   u8 is_local = 0, is_drop = 0;
5932   u8 is_unreach = 0, is_prohibit = 0;
5933   u8 create_vrf_if_needed = 0;
5934   u8 is_add = 1;
5935   u32 next_hop_weight = 1;
5936   u8 not_last = 0;
5937   u8 is_multipath = 0;
5938   u8 address_set = 0;
5939   u8 address_length_set = 0;
5940   u32 next_hop_table_id = 0;
5941   u32 resolve_attempts = 0;
5942   u32 dst_address_length = 0;
5943   u8 next_hop_set = 0;
5944   ip4_address_t v4_dst_address, v4_next_hop_address;
5945   ip6_address_t v6_dst_address, v6_next_hop_address;
5946   int count = 1;
5947   int j;
5948   f64 before = 0;
5949   u32 random_add_del = 0;
5950   u32 *random_vector = 0;
5951   uword *random_hash;
5952   u32 random_seed = 0xdeaddabe;
5953   u32 classify_table_index = ~0;
5954   u8 is_classify = 0;
5955   u8 resolve_host = 0, resolve_attached = 0;
5956   mpls_label_t *next_hop_out_label_stack = NULL;
5957   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5958   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
5959
5960   /* Parse args required to build the message */
5961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5962     {
5963       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5964         ;
5965       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5966         ;
5967       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5968         {
5969           address_set = 1;
5970           is_ipv6 = 0;
5971         }
5972       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5973         {
5974           address_set = 1;
5975           is_ipv6 = 1;
5976         }
5977       else if (unformat (i, "/%d", &dst_address_length))
5978         {
5979           address_length_set = 1;
5980         }
5981
5982       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5983                                          &v4_next_hop_address))
5984         {
5985           next_hop_set = 1;
5986         }
5987       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5988                                          &v6_next_hop_address))
5989         {
5990           next_hop_set = 1;
5991         }
5992       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5993         ;
5994       else if (unformat (i, "weight %d", &next_hop_weight))
5995         ;
5996       else if (unformat (i, "drop"))
5997         {
5998           is_drop = 1;
5999         }
6000       else if (unformat (i, "null-send-unreach"))
6001         {
6002           is_unreach = 1;
6003         }
6004       else if (unformat (i, "null-send-prohibit"))
6005         {
6006           is_prohibit = 1;
6007         }
6008       else if (unformat (i, "local"))
6009         {
6010           is_local = 1;
6011         }
6012       else if (unformat (i, "classify %d", &classify_table_index))
6013         {
6014           is_classify = 1;
6015         }
6016       else if (unformat (i, "del"))
6017         is_add = 0;
6018       else if (unformat (i, "add"))
6019         is_add = 1;
6020       else if (unformat (i, "not-last"))
6021         not_last = 1;
6022       else if (unformat (i, "resolve-via-host"))
6023         resolve_host = 1;
6024       else if (unformat (i, "resolve-via-attached"))
6025         resolve_attached = 1;
6026       else if (unformat (i, "multipath"))
6027         is_multipath = 1;
6028       else if (unformat (i, "vrf %d", &vrf_id))
6029         ;
6030       else if (unformat (i, "create-vrf"))
6031         create_vrf_if_needed = 1;
6032       else if (unformat (i, "count %d", &count))
6033         ;
6034       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6035         ;
6036       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6037         ;
6038       else if (unformat (i, "out-label %d", &next_hop_out_label))
6039         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6040       else if (unformat (i, "via-label %d", &next_hop_via_label))
6041         ;
6042       else if (unformat (i, "random"))
6043         random_add_del = 1;
6044       else if (unformat (i, "seed %d", &random_seed))
6045         ;
6046       else
6047         {
6048           clib_warning ("parse error '%U'", format_unformat_error, i);
6049           return -99;
6050         }
6051     }
6052
6053   if (!next_hop_set && !is_drop && !is_local &&
6054       !is_classify && !is_unreach && !is_prohibit &&
6055       MPLS_LABEL_INVALID == next_hop_via_label)
6056     {
6057       errmsg
6058         ("next hop / local / drop / unreach / prohibit / classify not set\n");
6059       return -99;
6060     }
6061
6062   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6063     {
6064       errmsg ("next hop and next-hop via label set\n");
6065       return -99;
6066     }
6067   if (address_set == 0)
6068     {
6069       errmsg ("missing addresses\n");
6070       return -99;
6071     }
6072
6073   if (address_length_set == 0)
6074     {
6075       errmsg ("missing address length\n");
6076       return -99;
6077     }
6078
6079   /* Generate a pile of unique, random routes */
6080   if (random_add_del)
6081     {
6082       u32 this_random_address;
6083       random_hash = hash_create (count, sizeof (uword));
6084
6085       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6086       for (j = 0; j <= count; j++)
6087         {
6088           do
6089             {
6090               this_random_address = random_u32 (&random_seed);
6091               this_random_address =
6092                 clib_host_to_net_u32 (this_random_address);
6093             }
6094           while (hash_get (random_hash, this_random_address));
6095           vec_add1 (random_vector, this_random_address);
6096           hash_set (random_hash, this_random_address, 1);
6097         }
6098       hash_free (random_hash);
6099       v4_dst_address.as_u32 = random_vector[0];
6100     }
6101
6102   if (count > 1)
6103     {
6104       /* Turn on async mode */
6105       vam->async_mode = 1;
6106       vam->async_errors = 0;
6107       before = vat_time_now (vam);
6108     }
6109
6110   for (j = 0; j < count; j++)
6111     {
6112       /* Construct the API message */
6113       M2 (IP_ADD_DEL_ROUTE, ip_add_del_route,
6114           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6115
6116       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6117       mp->table_id = ntohl (vrf_id);
6118       mp->create_vrf_if_needed = create_vrf_if_needed;
6119
6120       mp->is_add = is_add;
6121       mp->is_drop = is_drop;
6122       mp->is_unreach = is_unreach;
6123       mp->is_prohibit = is_prohibit;
6124       mp->is_ipv6 = is_ipv6;
6125       mp->is_local = is_local;
6126       mp->is_classify = is_classify;
6127       mp->is_multipath = is_multipath;
6128       mp->is_resolve_host = resolve_host;
6129       mp->is_resolve_attached = resolve_attached;
6130       mp->not_last = not_last;
6131       mp->next_hop_weight = next_hop_weight;
6132       mp->dst_address_length = dst_address_length;
6133       mp->next_hop_table_id = ntohl (next_hop_table_id);
6134       mp->classify_table_index = ntohl (classify_table_index);
6135       mp->next_hop_via_label = ntohl (next_hop_via_label);
6136       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6137       if (0 != mp->next_hop_n_out_labels)
6138         {
6139           memcpy (mp->next_hop_out_label_stack,
6140                   next_hop_out_label_stack,
6141                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6142           vec_free (next_hop_out_label_stack);
6143         }
6144
6145       if (is_ipv6)
6146         {
6147           clib_memcpy (mp->dst_address, &v6_dst_address,
6148                        sizeof (v6_dst_address));
6149           if (next_hop_set)
6150             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6151                          sizeof (v6_next_hop_address));
6152           increment_v6_address (&v6_dst_address);
6153         }
6154       else
6155         {
6156           clib_memcpy (mp->dst_address, &v4_dst_address,
6157                        sizeof (v4_dst_address));
6158           if (next_hop_set)
6159             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6160                          sizeof (v4_next_hop_address));
6161           if (random_add_del)
6162             v4_dst_address.as_u32 = random_vector[j + 1];
6163           else
6164             increment_v4_address (&v4_dst_address);
6165         }
6166       /* send it... */
6167       S;
6168       /* If we receive SIGTERM, stop now... */
6169       if (vam->do_exit)
6170         break;
6171     }
6172
6173   /* When testing multiple add/del ops, use a control-ping to sync */
6174   if (count > 1)
6175     {
6176       vl_api_control_ping_t *mp;
6177       f64 after;
6178
6179       /* Shut off async mode */
6180       vam->async_mode = 0;
6181
6182       M (CONTROL_PING, control_ping);
6183       S;
6184
6185       timeout = vat_time_now (vam) + 1.0;
6186       while (vat_time_now (vam) < timeout)
6187         if (vam->result_ready == 1)
6188           goto out;
6189       vam->retval = -99;
6190
6191     out:
6192       if (vam->retval == -99)
6193         errmsg ("timeout\n");
6194
6195       if (vam->async_errors > 0)
6196         {
6197           errmsg ("%d asynchronous errors\n", vam->async_errors);
6198           vam->retval = -98;
6199         }
6200       vam->async_errors = 0;
6201       after = vat_time_now (vam);
6202
6203       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6204       if (j > 0)
6205         count = j;
6206
6207       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6208                count, after - before, count / (after - before));
6209     }
6210   else
6211     {
6212       /* Wait for a reply... */
6213       W;
6214     }
6215
6216   /* Return the good/bad news */
6217   return (vam->retval);
6218 }
6219
6220 static int
6221 api_mpls_route_add_del (vat_main_t * vam)
6222 {
6223   unformat_input_t *i = vam->input;
6224   vl_api_mpls_route_add_del_t *mp;
6225   f64 timeout;
6226   u32 sw_if_index = ~0, table_id = 0;
6227   u8 create_table_if_needed = 0;
6228   u8 is_add = 1;
6229   u32 next_hop_weight = 1;
6230   u8 is_multipath = 0;
6231   u32 next_hop_table_id = 0;
6232   u8 next_hop_set = 0;
6233   ip4_address_t v4_next_hop_address = {
6234     .as_u32 = 0,
6235   };
6236   ip6_address_t v6_next_hop_address = { {0} };
6237   int count = 1;
6238   int j;
6239   f64 before = 0;
6240   u32 classify_table_index = ~0;
6241   u8 is_classify = 0;
6242   u8 resolve_host = 0, resolve_attached = 0;
6243   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6244   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6245   mpls_label_t *next_hop_out_label_stack = NULL;
6246   mpls_label_t local_label = MPLS_LABEL_INVALID;
6247   u8 is_eos = 0;
6248   u8 next_hop_proto_is_ip4 = 1;
6249
6250   /* Parse args required to build the message */
6251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6252     {
6253       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6254         ;
6255       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6256         ;
6257       else if (unformat (i, "%d", &local_label))
6258         ;
6259       else if (unformat (i, "eos"))
6260         is_eos = 1;
6261       else if (unformat (i, "non-eos"))
6262         is_eos = 0;
6263       else if (unformat (i, "via %U", unformat_ip4_address,
6264                          &v4_next_hop_address))
6265         {
6266           next_hop_set = 1;
6267           next_hop_proto_is_ip4 = 1;
6268         }
6269       else if (unformat (i, "via %U", unformat_ip6_address,
6270                          &v6_next_hop_address))
6271         {
6272           next_hop_set = 1;
6273           next_hop_proto_is_ip4 = 0;
6274         }
6275       else if (unformat (i, "weight %d", &next_hop_weight))
6276         ;
6277       else if (unformat (i, "create-table"))
6278         create_table_if_needed = 1;
6279       else if (unformat (i, "classify %d", &classify_table_index))
6280         {
6281           is_classify = 1;
6282         }
6283       else if (unformat (i, "del"))
6284         is_add = 0;
6285       else if (unformat (i, "add"))
6286         is_add = 1;
6287       else if (unformat (i, "resolve-via-host"))
6288         resolve_host = 1;
6289       else if (unformat (i, "resolve-via-attached"))
6290         resolve_attached = 1;
6291       else if (unformat (i, "multipath"))
6292         is_multipath = 1;
6293       else if (unformat (i, "count %d", &count))
6294         ;
6295       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6296         {
6297           next_hop_set = 1;
6298           next_hop_proto_is_ip4 = 1;
6299         }
6300       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6301         {
6302           next_hop_set = 1;
6303           next_hop_proto_is_ip4 = 0;
6304         }
6305       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6306         ;
6307       else if (unformat (i, "via-label %d", &next_hop_via_label))
6308         ;
6309       else if (unformat (i, "out-label %d", &next_hop_out_label))
6310         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6311       else
6312         {
6313           clib_warning ("parse error '%U'", format_unformat_error, i);
6314           return -99;
6315         }
6316     }
6317
6318   if (!next_hop_set && !is_classify)
6319     {
6320       errmsg ("next hop / classify not set\n");
6321       return -99;
6322     }
6323
6324   if (MPLS_LABEL_INVALID == local_label)
6325     {
6326       errmsg ("missing label\n");
6327       return -99;
6328     }
6329
6330   if (count > 1)
6331     {
6332       /* Turn on async mode */
6333       vam->async_mode = 1;
6334       vam->async_errors = 0;
6335       before = vat_time_now (vam);
6336     }
6337
6338   for (j = 0; j < count; j++)
6339     {
6340       /* Construct the API message */
6341       M2 (MPLS_ROUTE_ADD_DEL, mpls_route_add_del,
6342           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6343
6344       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6345       mp->mr_table_id = ntohl (table_id);
6346       mp->mr_create_table_if_needed = create_table_if_needed;
6347
6348       mp->mr_is_add = is_add;
6349       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6350       mp->mr_is_classify = is_classify;
6351       mp->mr_is_multipath = is_multipath;
6352       mp->mr_is_resolve_host = resolve_host;
6353       mp->mr_is_resolve_attached = resolve_attached;
6354       mp->mr_next_hop_weight = next_hop_weight;
6355       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6356       mp->mr_classify_table_index = ntohl (classify_table_index);
6357       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6358       mp->mr_label = ntohl (local_label);
6359       mp->mr_eos = is_eos;
6360
6361       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6362       if (0 != mp->mr_next_hop_n_out_labels)
6363         {
6364           memcpy (mp->mr_next_hop_out_label_stack,
6365                   next_hop_out_label_stack,
6366                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6367           vec_free (next_hop_out_label_stack);
6368         }
6369
6370       if (next_hop_set)
6371         {
6372           if (next_hop_proto_is_ip4)
6373             {
6374               clib_memcpy (mp->mr_next_hop,
6375                            &v4_next_hop_address,
6376                            sizeof (v4_next_hop_address));
6377             }
6378           else
6379             {
6380               clib_memcpy (mp->mr_next_hop,
6381                            &v6_next_hop_address,
6382                            sizeof (v6_next_hop_address));
6383             }
6384         }
6385       local_label++;
6386
6387       /* send it... */
6388       S;
6389       /* If we receive SIGTERM, stop now... */
6390       if (vam->do_exit)
6391         break;
6392     }
6393
6394   /* When testing multiple add/del ops, use a control-ping to sync */
6395   if (count > 1)
6396     {
6397       vl_api_control_ping_t *mp;
6398       f64 after;
6399
6400       /* Shut off async mode */
6401       vam->async_mode = 0;
6402
6403       M (CONTROL_PING, control_ping);
6404       S;
6405
6406       timeout = vat_time_now (vam) + 1.0;
6407       while (vat_time_now (vam) < timeout)
6408         if (vam->result_ready == 1)
6409           goto out;
6410       vam->retval = -99;
6411
6412     out:
6413       if (vam->retval == -99)
6414         errmsg ("timeout\n");
6415
6416       if (vam->async_errors > 0)
6417         {
6418           errmsg ("%d asynchronous errors\n", vam->async_errors);
6419           vam->retval = -98;
6420         }
6421       vam->async_errors = 0;
6422       after = vat_time_now (vam);
6423
6424       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6425       if (j > 0)
6426         count = j;
6427
6428       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6429                count, after - before, count / (after - before));
6430     }
6431   else
6432     {
6433       /* Wait for a reply... */
6434       W;
6435     }
6436
6437   /* Return the good/bad news */
6438   return (vam->retval);
6439 }
6440
6441 static int
6442 api_mpls_ip_bind_unbind (vat_main_t * vam)
6443 {
6444   unformat_input_t *i = vam->input;
6445   vl_api_mpls_ip_bind_unbind_t *mp;
6446   f64 timeout;
6447   u32 ip_table_id = 0;
6448   u8 create_table_if_needed = 0;
6449   u8 is_bind = 1;
6450   u8 is_ip4 = 1;
6451   ip4_address_t v4_address;
6452   ip6_address_t v6_address;
6453   u32 address_length;
6454   u8 address_set = 0;
6455   mpls_label_t local_label = MPLS_LABEL_INVALID;
6456
6457   /* Parse args required to build the message */
6458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6459     {
6460       if (unformat (i, "%U/%d", unformat_ip4_address,
6461                     &v4_address, &address_length))
6462         {
6463           is_ip4 = 1;
6464           address_set = 1;
6465         }
6466       else if (unformat (i, "%U/%d", unformat_ip6_address,
6467                          &v6_address, &address_length))
6468         {
6469           is_ip4 = 0;
6470           address_set = 1;
6471         }
6472       else if (unformat (i, "%d", &local_label))
6473         ;
6474       else if (unformat (i, "create-table"))
6475         create_table_if_needed = 1;
6476       else if (unformat (i, "table-id %d", &ip_table_id))
6477         ;
6478       else if (unformat (i, "unbind"))
6479         is_bind = 0;
6480       else if (unformat (i, "bind"))
6481         is_bind = 1;
6482       else
6483         {
6484           clib_warning ("parse error '%U'", format_unformat_error, i);
6485           return -99;
6486         }
6487     }
6488
6489   if (!address_set)
6490     {
6491       errmsg ("IP addres not set\n");
6492       return -99;
6493     }
6494
6495   if (MPLS_LABEL_INVALID == local_label)
6496     {
6497       errmsg ("missing label\n");
6498       return -99;
6499     }
6500
6501   /* Construct the API message */
6502   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6503
6504   mp->mb_create_table_if_needed = create_table_if_needed;
6505   mp->mb_is_bind = is_bind;
6506   mp->mb_is_ip4 = is_ip4;
6507   mp->mb_ip_table_id = ntohl (ip_table_id);
6508   mp->mb_mpls_table_id = 0;
6509   mp->mb_label = ntohl (local_label);
6510   mp->mb_address_length = address_length;
6511
6512   if (is_ip4)
6513     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6514   else
6515     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6516
6517   /* send it... */
6518   S;
6519
6520   /* Wait for a reply... */
6521   W;
6522 }
6523
6524 static int
6525 api_proxy_arp_add_del (vat_main_t * vam)
6526 {
6527   unformat_input_t *i = vam->input;
6528   vl_api_proxy_arp_add_del_t *mp;
6529   f64 timeout;
6530   u32 vrf_id = 0;
6531   u8 is_add = 1;
6532   ip4_address_t lo, hi;
6533   u8 range_set = 0;
6534
6535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6536     {
6537       if (unformat (i, "vrf %d", &vrf_id))
6538         ;
6539       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6540                          unformat_ip4_address, &hi))
6541         range_set = 1;
6542       else if (unformat (i, "del"))
6543         is_add = 0;
6544       else
6545         {
6546           clib_warning ("parse error '%U'", format_unformat_error, i);
6547           return -99;
6548         }
6549     }
6550
6551   if (range_set == 0)
6552     {
6553       errmsg ("address range not set\n");
6554       return -99;
6555     }
6556
6557   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6558
6559   mp->vrf_id = ntohl (vrf_id);
6560   mp->is_add = is_add;
6561   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6562   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6563
6564   S;
6565   W;
6566   /* NOTREACHED */
6567   return 0;
6568 }
6569
6570 static int
6571 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6572 {
6573   unformat_input_t *i = vam->input;
6574   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6575   f64 timeout;
6576   u32 sw_if_index;
6577   u8 enable = 1;
6578   u8 sw_if_index_set = 0;
6579
6580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6581     {
6582       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6583         sw_if_index_set = 1;
6584       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6585         sw_if_index_set = 1;
6586       else if (unformat (i, "enable"))
6587         enable = 1;
6588       else if (unformat (i, "disable"))
6589         enable = 0;
6590       else
6591         {
6592           clib_warning ("parse error '%U'", format_unformat_error, i);
6593           return -99;
6594         }
6595     }
6596
6597   if (sw_if_index_set == 0)
6598     {
6599       errmsg ("missing interface name or sw_if_index\n");
6600       return -99;
6601     }
6602
6603   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6604
6605   mp->sw_if_index = ntohl (sw_if_index);
6606   mp->enable_disable = enable;
6607
6608   S;
6609   W;
6610   /* NOTREACHED */
6611   return 0;
6612 }
6613
6614 static int
6615 api_mpls_tunnel_add_del (vat_main_t * vam)
6616 {
6617   unformat_input_t *i = vam->input;
6618   vl_api_mpls_tunnel_add_del_t *mp;
6619   f64 timeout;
6620
6621   u8 is_add = 1;
6622   u8 l2_only = 0;
6623   u32 sw_if_index = ~0;
6624   u32 next_hop_sw_if_index = ~0;
6625   u32 next_hop_proto_is_ip4 = 1;
6626
6627   u32 next_hop_table_id = 0;
6628   ip4_address_t v4_next_hop_address = {
6629     .as_u32 = 0,
6630   };
6631   ip6_address_t v6_next_hop_address = { {0} };
6632   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6633
6634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6635     {
6636       if (unformat (i, "add"))
6637         is_add = 1;
6638       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6639         is_add = 0;
6640       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6641         ;
6642       else if (unformat (i, "via %U",
6643                          unformat_ip4_address, &v4_next_hop_address))
6644         {
6645           next_hop_proto_is_ip4 = 1;
6646         }
6647       else if (unformat (i, "via %U",
6648                          unformat_ip6_address, &v6_next_hop_address))
6649         {
6650           next_hop_proto_is_ip4 = 0;
6651         }
6652       else if (unformat (i, "l2-only"))
6653         l2_only = 1;
6654       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6655         ;
6656       else if (unformat (i, "out-label %d", &next_hop_out_label))
6657         vec_add1 (labels, ntohl (next_hop_out_label));
6658       else
6659         {
6660           clib_warning ("parse error '%U'", format_unformat_error, i);
6661           return -99;
6662         }
6663     }
6664
6665   M2 (MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del,
6666       sizeof (mpls_label_t) * vec_len (labels));
6667
6668   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
6669   mp->mt_sw_if_index = ntohl (sw_if_index);
6670   mp->mt_is_add = is_add;
6671   mp->mt_l2_only = l2_only;
6672   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
6673   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6674
6675   mp->mt_next_hop_n_out_labels = vec_len (labels);
6676
6677   if (0 != mp->mt_next_hop_n_out_labels)
6678     {
6679       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
6680                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
6681       vec_free (labels);
6682     }
6683
6684   if (next_hop_proto_is_ip4)
6685     {
6686       clib_memcpy (mp->mt_next_hop,
6687                    &v4_next_hop_address, sizeof (v4_next_hop_address));
6688     }
6689   else
6690     {
6691       clib_memcpy (mp->mt_next_hop,
6692                    &v6_next_hop_address, sizeof (v6_next_hop_address));
6693     }
6694
6695   S;
6696   W;
6697   /* NOTREACHED */
6698   return 0;
6699 }
6700
6701 static int
6702 api_sw_interface_set_unnumbered (vat_main_t * vam)
6703 {
6704   unformat_input_t *i = vam->input;
6705   vl_api_sw_interface_set_unnumbered_t *mp;
6706   f64 timeout;
6707   u32 sw_if_index;
6708   u32 unnum_sw_index = ~0;
6709   u8 is_add = 1;
6710   u8 sw_if_index_set = 0;
6711
6712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6713     {
6714       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6715         sw_if_index_set = 1;
6716       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6717         sw_if_index_set = 1;
6718       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6719         ;
6720       else if (unformat (i, "del"))
6721         is_add = 0;
6722       else
6723         {
6724           clib_warning ("parse error '%U'", format_unformat_error, i);
6725           return -99;
6726         }
6727     }
6728
6729   if (sw_if_index_set == 0)
6730     {
6731       errmsg ("missing interface name or sw_if_index\n");
6732       return -99;
6733     }
6734
6735   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6736
6737   mp->sw_if_index = ntohl (sw_if_index);
6738   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6739   mp->is_add = is_add;
6740
6741   S;
6742   W;
6743   /* NOTREACHED */
6744   return 0;
6745 }
6746
6747 static int
6748 api_ip_neighbor_add_del (vat_main_t * vam)
6749 {
6750   unformat_input_t *i = vam->input;
6751   vl_api_ip_neighbor_add_del_t *mp;
6752   f64 timeout;
6753   u32 sw_if_index;
6754   u8 sw_if_index_set = 0;
6755   u32 vrf_id = 0;
6756   u8 is_add = 1;
6757   u8 is_static = 0;
6758   u8 mac_address[6];
6759   u8 mac_set = 0;
6760   u8 v4_address_set = 0;
6761   u8 v6_address_set = 0;
6762   ip4_address_t v4address;
6763   ip6_address_t v6address;
6764
6765   memset (mac_address, 0, sizeof (mac_address));
6766
6767   /* Parse args required to build the message */
6768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6769     {
6770       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6771         {
6772           mac_set = 1;
6773         }
6774       else if (unformat (i, "del"))
6775         is_add = 0;
6776       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6777         sw_if_index_set = 1;
6778       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6779         sw_if_index_set = 1;
6780       else if (unformat (i, "is_static"))
6781         is_static = 1;
6782       else if (unformat (i, "vrf %d", &vrf_id))
6783         ;
6784       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6785         v4_address_set = 1;
6786       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6787         v6_address_set = 1;
6788       else
6789         {
6790           clib_warning ("parse error '%U'", format_unformat_error, i);
6791           return -99;
6792         }
6793     }
6794
6795   if (sw_if_index_set == 0)
6796     {
6797       errmsg ("missing interface name or sw_if_index\n");
6798       return -99;
6799     }
6800   if (v4_address_set && v6_address_set)
6801     {
6802       errmsg ("both v4 and v6 addresses set\n");
6803       return -99;
6804     }
6805   if (!v4_address_set && !v6_address_set)
6806     {
6807       errmsg ("no address set\n");
6808       return -99;
6809     }
6810
6811   /* Construct the API message */
6812   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6813
6814   mp->sw_if_index = ntohl (sw_if_index);
6815   mp->is_add = is_add;
6816   mp->vrf_id = ntohl (vrf_id);
6817   mp->is_static = is_static;
6818   if (mac_set)
6819     clib_memcpy (mp->mac_address, mac_address, 6);
6820   if (v6_address_set)
6821     {
6822       mp->is_ipv6 = 1;
6823       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6824     }
6825   else
6826     {
6827       /* mp->is_ipv6 = 0; via memset in M macro above */
6828       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6829     }
6830
6831   /* send it... */
6832   S;
6833
6834   /* Wait for a reply, return good/bad news  */
6835   W;
6836
6837   /* NOTREACHED */
6838   return 0;
6839 }
6840
6841 static int
6842 api_reset_vrf (vat_main_t * vam)
6843 {
6844   unformat_input_t *i = vam->input;
6845   vl_api_reset_vrf_t *mp;
6846   f64 timeout;
6847   u32 vrf_id = 0;
6848   u8 is_ipv6 = 0;
6849   u8 vrf_id_set = 0;
6850
6851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6852     {
6853       if (unformat (i, "vrf %d", &vrf_id))
6854         vrf_id_set = 1;
6855       else if (unformat (i, "ipv6"))
6856         is_ipv6 = 1;
6857       else
6858         {
6859           clib_warning ("parse error '%U'", format_unformat_error, i);
6860           return -99;
6861         }
6862     }
6863
6864   if (vrf_id_set == 0)
6865     {
6866       errmsg ("missing vrf id\n");
6867       return -99;
6868     }
6869
6870   M (RESET_VRF, reset_vrf);
6871
6872   mp->vrf_id = ntohl (vrf_id);
6873   mp->is_ipv6 = is_ipv6;
6874
6875   S;
6876   W;
6877   /* NOTREACHED */
6878   return 0;
6879 }
6880
6881 static int
6882 api_create_vlan_subif (vat_main_t * vam)
6883 {
6884   unformat_input_t *i = vam->input;
6885   vl_api_create_vlan_subif_t *mp;
6886   f64 timeout;
6887   u32 sw_if_index;
6888   u8 sw_if_index_set = 0;
6889   u32 vlan_id;
6890   u8 vlan_id_set = 0;
6891
6892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6893     {
6894       if (unformat (i, "sw_if_index %d", &sw_if_index))
6895         sw_if_index_set = 1;
6896       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6897         sw_if_index_set = 1;
6898       else if (unformat (i, "vlan %d", &vlan_id))
6899         vlan_id_set = 1;
6900       else
6901         {
6902           clib_warning ("parse error '%U'", format_unformat_error, i);
6903           return -99;
6904         }
6905     }
6906
6907   if (sw_if_index_set == 0)
6908     {
6909       errmsg ("missing interface name or sw_if_index\n");
6910       return -99;
6911     }
6912
6913   if (vlan_id_set == 0)
6914     {
6915       errmsg ("missing vlan_id\n");
6916       return -99;
6917     }
6918   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6919
6920   mp->sw_if_index = ntohl (sw_if_index);
6921   mp->vlan_id = ntohl (vlan_id);
6922
6923   S;
6924   W;
6925   /* NOTREACHED */
6926   return 0;
6927 }
6928
6929 #define foreach_create_subif_bit                \
6930 _(no_tags)                                      \
6931 _(one_tag)                                      \
6932 _(two_tags)                                     \
6933 _(dot1ad)                                       \
6934 _(exact_match)                                  \
6935 _(default_sub)                                  \
6936 _(outer_vlan_id_any)                            \
6937 _(inner_vlan_id_any)
6938
6939 static int
6940 api_create_subif (vat_main_t * vam)
6941 {
6942   unformat_input_t *i = vam->input;
6943   vl_api_create_subif_t *mp;
6944   f64 timeout;
6945   u32 sw_if_index;
6946   u8 sw_if_index_set = 0;
6947   u32 sub_id;
6948   u8 sub_id_set = 0;
6949   u32 no_tags = 0;
6950   u32 one_tag = 0;
6951   u32 two_tags = 0;
6952   u32 dot1ad = 0;
6953   u32 exact_match = 0;
6954   u32 default_sub = 0;
6955   u32 outer_vlan_id_any = 0;
6956   u32 inner_vlan_id_any = 0;
6957   u32 tmp;
6958   u16 outer_vlan_id = 0;
6959   u16 inner_vlan_id = 0;
6960
6961   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6962     {
6963       if (unformat (i, "sw_if_index %d", &sw_if_index))
6964         sw_if_index_set = 1;
6965       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6966         sw_if_index_set = 1;
6967       else if (unformat (i, "sub_id %d", &sub_id))
6968         sub_id_set = 1;
6969       else if (unformat (i, "outer_vlan_id %d", &tmp))
6970         outer_vlan_id = tmp;
6971       else if (unformat (i, "inner_vlan_id %d", &tmp))
6972         inner_vlan_id = tmp;
6973
6974 #define _(a) else if (unformat (i, #a)) a = 1 ;
6975       foreach_create_subif_bit
6976 #undef _
6977         else
6978         {
6979           clib_warning ("parse error '%U'", format_unformat_error, i);
6980           return -99;
6981         }
6982     }
6983
6984   if (sw_if_index_set == 0)
6985     {
6986       errmsg ("missing interface name or sw_if_index\n");
6987       return -99;
6988     }
6989
6990   if (sub_id_set == 0)
6991     {
6992       errmsg ("missing sub_id\n");
6993       return -99;
6994     }
6995   M (CREATE_SUBIF, create_subif);
6996
6997   mp->sw_if_index = ntohl (sw_if_index);
6998   mp->sub_id = ntohl (sub_id);
6999
7000 #define _(a) mp->a = a;
7001   foreach_create_subif_bit;
7002 #undef _
7003
7004   mp->outer_vlan_id = ntohs (outer_vlan_id);
7005   mp->inner_vlan_id = ntohs (inner_vlan_id);
7006
7007   S;
7008   W;
7009   /* NOTREACHED */
7010   return 0;
7011 }
7012
7013 static int
7014 api_oam_add_del (vat_main_t * vam)
7015 {
7016   unformat_input_t *i = vam->input;
7017   vl_api_oam_add_del_t *mp;
7018   f64 timeout;
7019   u32 vrf_id = 0;
7020   u8 is_add = 1;
7021   ip4_address_t src, dst;
7022   u8 src_set = 0;
7023   u8 dst_set = 0;
7024
7025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7026     {
7027       if (unformat (i, "vrf %d", &vrf_id))
7028         ;
7029       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7030         src_set = 1;
7031       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7032         dst_set = 1;
7033       else if (unformat (i, "del"))
7034         is_add = 0;
7035       else
7036         {
7037           clib_warning ("parse error '%U'", format_unformat_error, i);
7038           return -99;
7039         }
7040     }
7041
7042   if (src_set == 0)
7043     {
7044       errmsg ("missing src addr\n");
7045       return -99;
7046     }
7047
7048   if (dst_set == 0)
7049     {
7050       errmsg ("missing dst addr\n");
7051       return -99;
7052     }
7053
7054   M (OAM_ADD_DEL, oam_add_del);
7055
7056   mp->vrf_id = ntohl (vrf_id);
7057   mp->is_add = is_add;
7058   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7059   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7060
7061   S;
7062   W;
7063   /* NOTREACHED */
7064   return 0;
7065 }
7066
7067 static int
7068 api_reset_fib (vat_main_t * vam)
7069 {
7070   unformat_input_t *i = vam->input;
7071   vl_api_reset_fib_t *mp;
7072   f64 timeout;
7073   u32 vrf_id = 0;
7074   u8 is_ipv6 = 0;
7075   u8 vrf_id_set = 0;
7076
7077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7078     {
7079       if (unformat (i, "vrf %d", &vrf_id))
7080         vrf_id_set = 1;
7081       else if (unformat (i, "ipv6"))
7082         is_ipv6 = 1;
7083       else
7084         {
7085           clib_warning ("parse error '%U'", format_unformat_error, i);
7086           return -99;
7087         }
7088     }
7089
7090   if (vrf_id_set == 0)
7091     {
7092       errmsg ("missing vrf id\n");
7093       return -99;
7094     }
7095
7096   M (RESET_FIB, reset_fib);
7097
7098   mp->vrf_id = ntohl (vrf_id);
7099   mp->is_ipv6 = is_ipv6;
7100
7101   S;
7102   W;
7103   /* NOTREACHED */
7104   return 0;
7105 }
7106
7107 static int
7108 api_dhcp_proxy_config (vat_main_t * vam)
7109 {
7110   unformat_input_t *i = vam->input;
7111   vl_api_dhcp_proxy_config_t *mp;
7112   f64 timeout;
7113   u32 vrf_id = 0;
7114   u8 is_add = 1;
7115   u8 insert_cid = 1;
7116   u8 v4_address_set = 0;
7117   u8 v6_address_set = 0;
7118   ip4_address_t v4address;
7119   ip6_address_t v6address;
7120   u8 v4_src_address_set = 0;
7121   u8 v6_src_address_set = 0;
7122   ip4_address_t v4srcaddress;
7123   ip6_address_t v6srcaddress;
7124
7125   /* Parse args required to build the message */
7126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7127     {
7128       if (unformat (i, "del"))
7129         is_add = 0;
7130       else if (unformat (i, "vrf %d", &vrf_id))
7131         ;
7132       else if (unformat (i, "insert-cid %d", &insert_cid))
7133         ;
7134       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7135         v4_address_set = 1;
7136       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7137         v6_address_set = 1;
7138       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7139         v4_src_address_set = 1;
7140       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7141         v6_src_address_set = 1;
7142       else
7143         break;
7144     }
7145
7146   if (v4_address_set && v6_address_set)
7147     {
7148       errmsg ("both v4 and v6 server addresses set\n");
7149       return -99;
7150     }
7151   if (!v4_address_set && !v6_address_set)
7152     {
7153       errmsg ("no server addresses set\n");
7154       return -99;
7155     }
7156
7157   if (v4_src_address_set && v6_src_address_set)
7158     {
7159       errmsg ("both v4 and v6  src addresses set\n");
7160       return -99;
7161     }
7162   if (!v4_src_address_set && !v6_src_address_set)
7163     {
7164       errmsg ("no src addresses set\n");
7165       return -99;
7166     }
7167
7168   if (!(v4_src_address_set && v4_address_set) &&
7169       !(v6_src_address_set && v6_address_set))
7170     {
7171       errmsg ("no matching server and src addresses set\n");
7172       return -99;
7173     }
7174
7175   /* Construct the API message */
7176   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7177
7178   mp->insert_circuit_id = insert_cid;
7179   mp->is_add = is_add;
7180   mp->vrf_id = ntohl (vrf_id);
7181   if (v6_address_set)
7182     {
7183       mp->is_ipv6 = 1;
7184       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7185       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7186     }
7187   else
7188     {
7189       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7190       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7191     }
7192
7193   /* send it... */
7194   S;
7195
7196   /* Wait for a reply, return good/bad news  */
7197   W;
7198   /* NOTREACHED */
7199   return 0;
7200 }
7201
7202 static int
7203 api_dhcp_proxy_config_2 (vat_main_t * vam)
7204 {
7205   unformat_input_t *i = vam->input;
7206   vl_api_dhcp_proxy_config_2_t *mp;
7207   f64 timeout;
7208   u32 rx_vrf_id = 0;
7209   u32 server_vrf_id = 0;
7210   u8 is_add = 1;
7211   u8 insert_cid = 1;
7212   u8 v4_address_set = 0;
7213   u8 v6_address_set = 0;
7214   ip4_address_t v4address;
7215   ip6_address_t v6address;
7216   u8 v4_src_address_set = 0;
7217   u8 v6_src_address_set = 0;
7218   ip4_address_t v4srcaddress;
7219   ip6_address_t v6srcaddress;
7220
7221   /* Parse args required to build the message */
7222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7223     {
7224       if (unformat (i, "del"))
7225         is_add = 0;
7226       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7227         ;
7228       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7229         ;
7230       else if (unformat (i, "insert-cid %d", &insert_cid))
7231         ;
7232       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7233         v4_address_set = 1;
7234       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7235         v6_address_set = 1;
7236       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7237         v4_src_address_set = 1;
7238       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7239         v6_src_address_set = 1;
7240       else
7241         break;
7242     }
7243
7244   if (v4_address_set && v6_address_set)
7245     {
7246       errmsg ("both v4 and v6 server addresses set\n");
7247       return -99;
7248     }
7249   if (!v4_address_set && !v6_address_set)
7250     {
7251       errmsg ("no server addresses set\n");
7252       return -99;
7253     }
7254
7255   if (v4_src_address_set && v6_src_address_set)
7256     {
7257       errmsg ("both v4 and v6  src addresses set\n");
7258       return -99;
7259     }
7260   if (!v4_src_address_set && !v6_src_address_set)
7261     {
7262       errmsg ("no src addresses set\n");
7263       return -99;
7264     }
7265
7266   if (!(v4_src_address_set && v4_address_set) &&
7267       !(v6_src_address_set && v6_address_set))
7268     {
7269       errmsg ("no matching server and src addresses set\n");
7270       return -99;
7271     }
7272
7273   /* Construct the API message */
7274   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7275
7276   mp->insert_circuit_id = insert_cid;
7277   mp->is_add = is_add;
7278   mp->rx_vrf_id = ntohl (rx_vrf_id);
7279   mp->server_vrf_id = ntohl (server_vrf_id);
7280   if (v6_address_set)
7281     {
7282       mp->is_ipv6 = 1;
7283       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7284       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7285     }
7286   else
7287     {
7288       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7289       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7290     }
7291
7292   /* send it... */
7293   S;
7294
7295   /* Wait for a reply, return good/bad news  */
7296   W;
7297   /* NOTREACHED */
7298   return 0;
7299 }
7300
7301 static int
7302 api_dhcp_proxy_set_vss (vat_main_t * vam)
7303 {
7304   unformat_input_t *i = vam->input;
7305   vl_api_dhcp_proxy_set_vss_t *mp;
7306   f64 timeout;
7307   u8 is_ipv6 = 0;
7308   u8 is_add = 1;
7309   u32 tbl_id;
7310   u8 tbl_id_set = 0;
7311   u32 oui;
7312   u8 oui_set = 0;
7313   u32 fib_id;
7314   u8 fib_id_set = 0;
7315
7316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7317     {
7318       if (unformat (i, "tbl_id %d", &tbl_id))
7319         tbl_id_set = 1;
7320       if (unformat (i, "fib_id %d", &fib_id))
7321         fib_id_set = 1;
7322       if (unformat (i, "oui %d", &oui))
7323         oui_set = 1;
7324       else if (unformat (i, "ipv6"))
7325         is_ipv6 = 1;
7326       else if (unformat (i, "del"))
7327         is_add = 0;
7328       else
7329         {
7330           clib_warning ("parse error '%U'", format_unformat_error, i);
7331           return -99;
7332         }
7333     }
7334
7335   if (tbl_id_set == 0)
7336     {
7337       errmsg ("missing tbl id\n");
7338       return -99;
7339     }
7340
7341   if (fib_id_set == 0)
7342     {
7343       errmsg ("missing fib id\n");
7344       return -99;
7345     }
7346   if (oui_set == 0)
7347     {
7348       errmsg ("missing oui\n");
7349       return -99;
7350     }
7351
7352   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7353   mp->tbl_id = ntohl (tbl_id);
7354   mp->fib_id = ntohl (fib_id);
7355   mp->oui = ntohl (oui);
7356   mp->is_ipv6 = is_ipv6;
7357   mp->is_add = is_add;
7358
7359   S;
7360   W;
7361   /* NOTREACHED */
7362   return 0;
7363 }
7364
7365 static int
7366 api_dhcp_client_config (vat_main_t * vam)
7367 {
7368   unformat_input_t *i = vam->input;
7369   vl_api_dhcp_client_config_t *mp;
7370   f64 timeout;
7371   u32 sw_if_index;
7372   u8 sw_if_index_set = 0;
7373   u8 is_add = 1;
7374   u8 *hostname = 0;
7375   u8 disable_event = 0;
7376
7377   /* Parse args required to build the message */
7378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7379     {
7380       if (unformat (i, "del"))
7381         is_add = 0;
7382       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7383         sw_if_index_set = 1;
7384       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7385         sw_if_index_set = 1;
7386       else if (unformat (i, "hostname %s", &hostname))
7387         ;
7388       else if (unformat (i, "disable_event"))
7389         disable_event = 1;
7390       else
7391         break;
7392     }
7393
7394   if (sw_if_index_set == 0)
7395     {
7396       errmsg ("missing interface name or sw_if_index\n");
7397       return -99;
7398     }
7399
7400   if (vec_len (hostname) > 63)
7401     {
7402       errmsg ("hostname too long\n");
7403     }
7404   vec_add1 (hostname, 0);
7405
7406   /* Construct the API message */
7407   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7408
7409   mp->sw_if_index = ntohl (sw_if_index);
7410   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7411   vec_free (hostname);
7412   mp->is_add = is_add;
7413   mp->want_dhcp_event = disable_event ? 0 : 1;
7414   mp->pid = getpid ();
7415
7416   /* send it... */
7417   S;
7418
7419   /* Wait for a reply, return good/bad news  */
7420   W;
7421   /* NOTREACHED */
7422   return 0;
7423 }
7424
7425 static int
7426 api_set_ip_flow_hash (vat_main_t * vam)
7427 {
7428   unformat_input_t *i = vam->input;
7429   vl_api_set_ip_flow_hash_t *mp;
7430   f64 timeout;
7431   u32 vrf_id = 0;
7432   u8 is_ipv6 = 0;
7433   u8 vrf_id_set = 0;
7434   u8 src = 0;
7435   u8 dst = 0;
7436   u8 sport = 0;
7437   u8 dport = 0;
7438   u8 proto = 0;
7439   u8 reverse = 0;
7440
7441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7442     {
7443       if (unformat (i, "vrf %d", &vrf_id))
7444         vrf_id_set = 1;
7445       else if (unformat (i, "ipv6"))
7446         is_ipv6 = 1;
7447       else if (unformat (i, "src"))
7448         src = 1;
7449       else if (unformat (i, "dst"))
7450         dst = 1;
7451       else if (unformat (i, "sport"))
7452         sport = 1;
7453       else if (unformat (i, "dport"))
7454         dport = 1;
7455       else if (unformat (i, "proto"))
7456         proto = 1;
7457       else if (unformat (i, "reverse"))
7458         reverse = 1;
7459
7460       else
7461         {
7462           clib_warning ("parse error '%U'", format_unformat_error, i);
7463           return -99;
7464         }
7465     }
7466
7467   if (vrf_id_set == 0)
7468     {
7469       errmsg ("missing vrf id\n");
7470       return -99;
7471     }
7472
7473   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7474   mp->src = src;
7475   mp->dst = dst;
7476   mp->sport = sport;
7477   mp->dport = dport;
7478   mp->proto = proto;
7479   mp->reverse = reverse;
7480   mp->vrf_id = ntohl (vrf_id);
7481   mp->is_ipv6 = is_ipv6;
7482
7483   S;
7484   W;
7485   /* NOTREACHED */
7486   return 0;
7487 }
7488
7489 static int
7490 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7491 {
7492   unformat_input_t *i = vam->input;
7493   vl_api_sw_interface_ip6_enable_disable_t *mp;
7494   f64 timeout;
7495   u32 sw_if_index;
7496   u8 sw_if_index_set = 0;
7497   u8 enable = 0;
7498
7499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7500     {
7501       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7502         sw_if_index_set = 1;
7503       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7504         sw_if_index_set = 1;
7505       else if (unformat (i, "enable"))
7506         enable = 1;
7507       else if (unformat (i, "disable"))
7508         enable = 0;
7509       else
7510         {
7511           clib_warning ("parse error '%U'", format_unformat_error, i);
7512           return -99;
7513         }
7514     }
7515
7516   if (sw_if_index_set == 0)
7517     {
7518       errmsg ("missing interface name or sw_if_index\n");
7519       return -99;
7520     }
7521
7522   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7523
7524   mp->sw_if_index = ntohl (sw_if_index);
7525   mp->enable = enable;
7526
7527   S;
7528   W;
7529   /* NOTREACHED */
7530   return 0;
7531 }
7532
7533 static int
7534 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7535 {
7536   unformat_input_t *i = vam->input;
7537   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7538   f64 timeout;
7539   u32 sw_if_index;
7540   u8 sw_if_index_set = 0;
7541   u32 address_length = 0;
7542   u8 v6_address_set = 0;
7543   ip6_address_t v6address;
7544
7545   /* Parse args required to build the message */
7546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7547     {
7548       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7549         sw_if_index_set = 1;
7550       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7551         sw_if_index_set = 1;
7552       else if (unformat (i, "%U/%d",
7553                          unformat_ip6_address, &v6address, &address_length))
7554         v6_address_set = 1;
7555       else
7556         break;
7557     }
7558
7559   if (sw_if_index_set == 0)
7560     {
7561       errmsg ("missing interface name or sw_if_index\n");
7562       return -99;
7563     }
7564   if (!v6_address_set)
7565     {
7566       errmsg ("no address set\n");
7567       return -99;
7568     }
7569
7570   /* Construct the API message */
7571   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7572      sw_interface_ip6_set_link_local_address);
7573
7574   mp->sw_if_index = ntohl (sw_if_index);
7575   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7576   mp->address_length = address_length;
7577
7578   /* send it... */
7579   S;
7580
7581   /* Wait for a reply, return good/bad news  */
7582   W;
7583
7584   /* NOTREACHED */
7585   return 0;
7586 }
7587
7588
7589 static int
7590 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7591 {
7592   unformat_input_t *i = vam->input;
7593   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7594   f64 timeout;
7595   u32 sw_if_index;
7596   u8 sw_if_index_set = 0;
7597   u32 address_length = 0;
7598   u8 v6_address_set = 0;
7599   ip6_address_t v6address;
7600   u8 use_default = 0;
7601   u8 no_advertise = 0;
7602   u8 off_link = 0;
7603   u8 no_autoconfig = 0;
7604   u8 no_onlink = 0;
7605   u8 is_no = 0;
7606   u32 val_lifetime = 0;
7607   u32 pref_lifetime = 0;
7608
7609   /* Parse args required to build the message */
7610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7611     {
7612       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7613         sw_if_index_set = 1;
7614       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7615         sw_if_index_set = 1;
7616       else if (unformat (i, "%U/%d",
7617                          unformat_ip6_address, &v6address, &address_length))
7618         v6_address_set = 1;
7619       else if (unformat (i, "val_life %d", &val_lifetime))
7620         ;
7621       else if (unformat (i, "pref_life %d", &pref_lifetime))
7622         ;
7623       else if (unformat (i, "def"))
7624         use_default = 1;
7625       else if (unformat (i, "noadv"))
7626         no_advertise = 1;
7627       else if (unformat (i, "offl"))
7628         off_link = 1;
7629       else if (unformat (i, "noauto"))
7630         no_autoconfig = 1;
7631       else if (unformat (i, "nolink"))
7632         no_onlink = 1;
7633       else if (unformat (i, "isno"))
7634         is_no = 1;
7635       else
7636         {
7637           clib_warning ("parse error '%U'", format_unformat_error, i);
7638           return -99;
7639         }
7640     }
7641
7642   if (sw_if_index_set == 0)
7643     {
7644       errmsg ("missing interface name or sw_if_index\n");
7645       return -99;
7646     }
7647   if (!v6_address_set)
7648     {
7649       errmsg ("no address set\n");
7650       return -99;
7651     }
7652
7653   /* Construct the API message */
7654   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7655
7656   mp->sw_if_index = ntohl (sw_if_index);
7657   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7658   mp->address_length = address_length;
7659   mp->use_default = use_default;
7660   mp->no_advertise = no_advertise;
7661   mp->off_link = off_link;
7662   mp->no_autoconfig = no_autoconfig;
7663   mp->no_onlink = no_onlink;
7664   mp->is_no = is_no;
7665   mp->val_lifetime = ntohl (val_lifetime);
7666   mp->pref_lifetime = ntohl (pref_lifetime);
7667
7668   /* send it... */
7669   S;
7670
7671   /* Wait for a reply, return good/bad news  */
7672   W;
7673
7674   /* NOTREACHED */
7675   return 0;
7676 }
7677
7678 static int
7679 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7680 {
7681   unformat_input_t *i = vam->input;
7682   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7683   f64 timeout;
7684   u32 sw_if_index;
7685   u8 sw_if_index_set = 0;
7686   u8 suppress = 0;
7687   u8 managed = 0;
7688   u8 other = 0;
7689   u8 ll_option = 0;
7690   u8 send_unicast = 0;
7691   u8 cease = 0;
7692   u8 is_no = 0;
7693   u8 default_router = 0;
7694   u32 max_interval = 0;
7695   u32 min_interval = 0;
7696   u32 lifetime = 0;
7697   u32 initial_count = 0;
7698   u32 initial_interval = 0;
7699
7700
7701   /* Parse args required to build the message */
7702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7703     {
7704       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7705         sw_if_index_set = 1;
7706       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7707         sw_if_index_set = 1;
7708       else if (unformat (i, "maxint %d", &max_interval))
7709         ;
7710       else if (unformat (i, "minint %d", &min_interval))
7711         ;
7712       else if (unformat (i, "life %d", &lifetime))
7713         ;
7714       else if (unformat (i, "count %d", &initial_count))
7715         ;
7716       else if (unformat (i, "interval %d", &initial_interval))
7717         ;
7718       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7719         suppress = 1;
7720       else if (unformat (i, "managed"))
7721         managed = 1;
7722       else if (unformat (i, "other"))
7723         other = 1;
7724       else if (unformat (i, "ll"))
7725         ll_option = 1;
7726       else if (unformat (i, "send"))
7727         send_unicast = 1;
7728       else if (unformat (i, "cease"))
7729         cease = 1;
7730       else if (unformat (i, "isno"))
7731         is_no = 1;
7732       else if (unformat (i, "def"))
7733         default_router = 1;
7734       else
7735         {
7736           clib_warning ("parse error '%U'", format_unformat_error, i);
7737           return -99;
7738         }
7739     }
7740
7741   if (sw_if_index_set == 0)
7742     {
7743       errmsg ("missing interface name or sw_if_index\n");
7744       return -99;
7745     }
7746
7747   /* Construct the API message */
7748   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7749
7750   mp->sw_if_index = ntohl (sw_if_index);
7751   mp->max_interval = ntohl (max_interval);
7752   mp->min_interval = ntohl (min_interval);
7753   mp->lifetime = ntohl (lifetime);
7754   mp->initial_count = ntohl (initial_count);
7755   mp->initial_interval = ntohl (initial_interval);
7756   mp->suppress = suppress;
7757   mp->managed = managed;
7758   mp->other = other;
7759   mp->ll_option = ll_option;
7760   mp->send_unicast = send_unicast;
7761   mp->cease = cease;
7762   mp->is_no = is_no;
7763   mp->default_router = default_router;
7764
7765   /* send it... */
7766   S;
7767
7768   /* Wait for a reply, return good/bad news  */
7769   W;
7770
7771   /* NOTREACHED */
7772   return 0;
7773 }
7774
7775 static int
7776 api_set_arp_neighbor_limit (vat_main_t * vam)
7777 {
7778   unformat_input_t *i = vam->input;
7779   vl_api_set_arp_neighbor_limit_t *mp;
7780   f64 timeout;
7781   u32 arp_nbr_limit;
7782   u8 limit_set = 0;
7783   u8 is_ipv6 = 0;
7784
7785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7786     {
7787       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7788         limit_set = 1;
7789       else if (unformat (i, "ipv6"))
7790         is_ipv6 = 1;
7791       else
7792         {
7793           clib_warning ("parse error '%U'", format_unformat_error, i);
7794           return -99;
7795         }
7796     }
7797
7798   if (limit_set == 0)
7799     {
7800       errmsg ("missing limit value\n");
7801       return -99;
7802     }
7803
7804   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7805
7806   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7807   mp->is_ipv6 = is_ipv6;
7808
7809   S;
7810   W;
7811   /* NOTREACHED */
7812   return 0;
7813 }
7814
7815 static int
7816 api_l2_patch_add_del (vat_main_t * vam)
7817 {
7818   unformat_input_t *i = vam->input;
7819   vl_api_l2_patch_add_del_t *mp;
7820   f64 timeout;
7821   u32 rx_sw_if_index;
7822   u8 rx_sw_if_index_set = 0;
7823   u32 tx_sw_if_index;
7824   u8 tx_sw_if_index_set = 0;
7825   u8 is_add = 1;
7826
7827   /* Parse args required to build the message */
7828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7829     {
7830       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7831         rx_sw_if_index_set = 1;
7832       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7833         tx_sw_if_index_set = 1;
7834       else if (unformat (i, "rx"))
7835         {
7836           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7837             {
7838               if (unformat (i, "%U", unformat_sw_if_index, vam,
7839                             &rx_sw_if_index))
7840                 rx_sw_if_index_set = 1;
7841             }
7842           else
7843             break;
7844         }
7845       else if (unformat (i, "tx"))
7846         {
7847           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7848             {
7849               if (unformat (i, "%U", unformat_sw_if_index, vam,
7850                             &tx_sw_if_index))
7851                 tx_sw_if_index_set = 1;
7852             }
7853           else
7854             break;
7855         }
7856       else if (unformat (i, "del"))
7857         is_add = 0;
7858       else
7859         break;
7860     }
7861
7862   if (rx_sw_if_index_set == 0)
7863     {
7864       errmsg ("missing rx interface name or rx_sw_if_index\n");
7865       return -99;
7866     }
7867
7868   if (tx_sw_if_index_set == 0)
7869     {
7870       errmsg ("missing tx interface name or tx_sw_if_index\n");
7871       return -99;
7872     }
7873
7874   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7875
7876   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7877   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7878   mp->is_add = is_add;
7879
7880   S;
7881   W;
7882   /* NOTREACHED */
7883   return 0;
7884 }
7885
7886 static int
7887 api_ioam_enable (vat_main_t * vam)
7888 {
7889   unformat_input_t *input = vam->input;
7890   vl_api_ioam_enable_t *mp;
7891   f64 timeout;
7892   u32 id = 0;
7893   int has_trace_option = 0;
7894   int has_pot_option = 0;
7895   int has_seqno_option = 0;
7896   int has_analyse_option = 0;
7897
7898   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7899     {
7900       if (unformat (input, "trace"))
7901         has_trace_option = 1;
7902       else if (unformat (input, "pot"))
7903         has_pot_option = 1;
7904       else if (unformat (input, "seqno"))
7905         has_seqno_option = 1;
7906       else if (unformat (input, "analyse"))
7907         has_analyse_option = 1;
7908       else
7909         break;
7910     }
7911   M (IOAM_ENABLE, ioam_enable);
7912   mp->id = htons (id);
7913   mp->seqno = has_seqno_option;
7914   mp->analyse = has_analyse_option;
7915   mp->pot_enable = has_pot_option;
7916   mp->trace_enable = has_trace_option;
7917
7918   S;
7919   W;
7920
7921   return (0);
7922
7923 }
7924
7925
7926 static int
7927 api_ioam_disable (vat_main_t * vam)
7928 {
7929   vl_api_ioam_disable_t *mp;
7930   f64 timeout;
7931
7932   M (IOAM_DISABLE, ioam_disable);
7933   S;
7934   W;
7935   return 0;
7936 }
7937
7938 static int
7939 api_sr_tunnel_add_del (vat_main_t * vam)
7940 {
7941   unformat_input_t *i = vam->input;
7942   vl_api_sr_tunnel_add_del_t *mp;
7943   f64 timeout;
7944   int is_del = 0;
7945   int pl_index;
7946   ip6_address_t src_address;
7947   int src_address_set = 0;
7948   ip6_address_t dst_address;
7949   u32 dst_mask_width;
7950   int dst_address_set = 0;
7951   u16 flags = 0;
7952   u32 rx_table_id = 0;
7953   u32 tx_table_id = 0;
7954   ip6_address_t *segments = 0;
7955   ip6_address_t *this_seg;
7956   ip6_address_t *tags = 0;
7957   ip6_address_t *this_tag;
7958   ip6_address_t next_address, tag;
7959   u8 *name = 0;
7960   u8 *policy_name = 0;
7961
7962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7963     {
7964       if (unformat (i, "del"))
7965         is_del = 1;
7966       else if (unformat (i, "name %s", &name))
7967         ;
7968       else if (unformat (i, "policy %s", &policy_name))
7969         ;
7970       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7971         ;
7972       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7973         ;
7974       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7975         src_address_set = 1;
7976       else if (unformat (i, "dst %U/%d",
7977                          unformat_ip6_address, &dst_address, &dst_mask_width))
7978         dst_address_set = 1;
7979       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7980         {
7981           vec_add2 (segments, this_seg, 1);
7982           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7983                        sizeof (*this_seg));
7984         }
7985       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7986         {
7987           vec_add2 (tags, this_tag, 1);
7988           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7989         }
7990       else if (unformat (i, "clean"))
7991         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7992       else if (unformat (i, "protected"))
7993         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7994       else if (unformat (i, "InPE %d", &pl_index))
7995         {
7996           if (pl_index <= 0 || pl_index > 4)
7997             {
7998             pl_index_range_error:
7999               errmsg ("pl index %d out of range\n", pl_index);
8000               return -99;
8001             }
8002           flags |=
8003             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8004         }
8005       else if (unformat (i, "EgPE %d", &pl_index))
8006         {
8007           if (pl_index <= 0 || pl_index > 4)
8008             goto pl_index_range_error;
8009           flags |=
8010             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8011         }
8012       else if (unformat (i, "OrgSrc %d", &pl_index))
8013         {
8014           if (pl_index <= 0 || pl_index > 4)
8015             goto pl_index_range_error;
8016           flags |=
8017             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8018         }
8019       else
8020         break;
8021     }
8022
8023   if (!src_address_set)
8024     {
8025       errmsg ("src address required\n");
8026       return -99;
8027     }
8028
8029   if (!dst_address_set)
8030     {
8031       errmsg ("dst address required\n");
8032       return -99;
8033     }
8034
8035   if (!segments)
8036     {
8037       errmsg ("at least one sr segment required\n");
8038       return -99;
8039     }
8040
8041   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
8042       vec_len (segments) * sizeof (ip6_address_t)
8043       + vec_len (tags) * sizeof (ip6_address_t));
8044
8045   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8046   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8047   mp->dst_mask_width = dst_mask_width;
8048   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8049   mp->n_segments = vec_len (segments);
8050   mp->n_tags = vec_len (tags);
8051   mp->is_add = is_del == 0;
8052   clib_memcpy (mp->segs_and_tags, segments,
8053                vec_len (segments) * sizeof (ip6_address_t));
8054   clib_memcpy (mp->segs_and_tags +
8055                vec_len (segments) * sizeof (ip6_address_t), tags,
8056                vec_len (tags) * sizeof (ip6_address_t));
8057
8058   mp->outer_vrf_id = ntohl (rx_table_id);
8059   mp->inner_vrf_id = ntohl (tx_table_id);
8060   memcpy (mp->name, name, vec_len (name));
8061   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8062
8063   vec_free (segments);
8064   vec_free (tags);
8065
8066   S;
8067   W;
8068   /* NOTREACHED */
8069 }
8070
8071 static int
8072 api_sr_policy_add_del (vat_main_t * vam)
8073 {
8074   unformat_input_t *input = vam->input;
8075   vl_api_sr_policy_add_del_t *mp;
8076   f64 timeout;
8077   int is_del = 0;
8078   u8 *name = 0;
8079   u8 *tunnel_name = 0;
8080   u8 **tunnel_names = 0;
8081
8082   int name_set = 0;
8083   int tunnel_set = 0;
8084   int j = 0;
8085   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8086   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8087
8088   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8089     {
8090       if (unformat (input, "del"))
8091         is_del = 1;
8092       else if (unformat (input, "name %s", &name))
8093         name_set = 1;
8094       else if (unformat (input, "tunnel %s", &tunnel_name))
8095         {
8096           if (tunnel_name)
8097             {
8098               vec_add1 (tunnel_names, tunnel_name);
8099               /* For serializer:
8100                  - length = #bytes to store in serial vector
8101                  - +1 = byte to store that length
8102                */
8103               tunnel_names_length += (vec_len (tunnel_name) + 1);
8104               tunnel_set = 1;
8105               tunnel_name = 0;
8106             }
8107         }
8108       else
8109         break;
8110     }
8111
8112   if (!name_set)
8113     {
8114       errmsg ("policy name required\n");
8115       return -99;
8116     }
8117
8118   if ((!tunnel_set) && (!is_del))
8119     {
8120       errmsg ("tunnel name required\n");
8121       return -99;
8122     }
8123
8124   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8125
8126
8127
8128   mp->is_add = !is_del;
8129
8130   memcpy (mp->name, name, vec_len (name));
8131   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8132   u8 *serial_orig = 0;
8133   vec_validate (serial_orig, tunnel_names_length);
8134   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8135   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8136
8137   for (j = 0; j < vec_len (tunnel_names); j++)
8138     {
8139       tun_name_len = vec_len (tunnel_names[j]);
8140       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8141       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8142       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8143       serial_orig += tun_name_len;      // Advance past the copy
8144     }
8145   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8146
8147   vec_free (tunnel_names);
8148   vec_free (tunnel_name);
8149
8150   S;
8151   W;
8152   /* NOTREACHED */
8153 }
8154
8155 static int
8156 api_sr_multicast_map_add_del (vat_main_t * vam)
8157 {
8158   unformat_input_t *input = vam->input;
8159   vl_api_sr_multicast_map_add_del_t *mp;
8160   f64 timeout;
8161   int is_del = 0;
8162   ip6_address_t multicast_address;
8163   u8 *policy_name = 0;
8164   int multicast_address_set = 0;
8165
8166   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8167     {
8168       if (unformat (input, "del"))
8169         is_del = 1;
8170       else
8171         if (unformat
8172             (input, "address %U", unformat_ip6_address, &multicast_address))
8173         multicast_address_set = 1;
8174       else if (unformat (input, "sr-policy %s", &policy_name))
8175         ;
8176       else
8177         break;
8178     }
8179
8180   if (!is_del && !policy_name)
8181     {
8182       errmsg ("sr-policy name required\n");
8183       return -99;
8184     }
8185
8186
8187   if (!multicast_address_set)
8188     {
8189       errmsg ("address required\n");
8190       return -99;
8191     }
8192
8193   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8194
8195   mp->is_add = !is_del;
8196   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8197   clib_memcpy (mp->multicast_address, &multicast_address,
8198                sizeof (mp->multicast_address));
8199
8200
8201   vec_free (policy_name);
8202
8203   S;
8204   W;
8205   /* NOTREACHED */
8206 }
8207
8208
8209 #define foreach_tcp_proto_field                 \
8210 _(src_port)                                     \
8211 _(dst_port)
8212
8213 #define foreach_udp_proto_field                 \
8214 _(src_port)                                     \
8215 _(dst_port)
8216
8217 #define foreach_ip4_proto_field                 \
8218 _(src_address)                                  \
8219 _(dst_address)                                  \
8220 _(tos)                                          \
8221 _(length)                                       \
8222 _(fragment_id)                                  \
8223 _(ttl)                                          \
8224 _(protocol)                                     \
8225 _(checksum)
8226
8227 uword
8228 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8229 {
8230   u8 **maskp = va_arg (*args, u8 **);
8231   u8 *mask = 0;
8232   u8 found_something = 0;
8233   tcp_header_t *tcp;
8234
8235 #define _(a) u8 a=0;
8236   foreach_tcp_proto_field;
8237 #undef _
8238
8239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8240     {
8241       if (0);
8242 #define _(a) else if (unformat (input, #a)) a=1;
8243       foreach_tcp_proto_field
8244 #undef _
8245         else
8246         break;
8247     }
8248
8249 #define _(a) found_something += a;
8250   foreach_tcp_proto_field;
8251 #undef _
8252
8253   if (found_something == 0)
8254     return 0;
8255
8256   vec_validate (mask, sizeof (*tcp) - 1);
8257
8258   tcp = (tcp_header_t *) mask;
8259
8260 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8261   foreach_tcp_proto_field;
8262 #undef _
8263
8264   *maskp = mask;
8265   return 1;
8266 }
8267
8268 uword
8269 unformat_udp_mask (unformat_input_t * input, va_list * args)
8270 {
8271   u8 **maskp = va_arg (*args, u8 **);
8272   u8 *mask = 0;
8273   u8 found_something = 0;
8274   udp_header_t *udp;
8275
8276 #define _(a) u8 a=0;
8277   foreach_udp_proto_field;
8278 #undef _
8279
8280   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8281     {
8282       if (0);
8283 #define _(a) else if (unformat (input, #a)) a=1;
8284       foreach_udp_proto_field
8285 #undef _
8286         else
8287         break;
8288     }
8289
8290 #define _(a) found_something += a;
8291   foreach_udp_proto_field;
8292 #undef _
8293
8294   if (found_something == 0)
8295     return 0;
8296
8297   vec_validate (mask, sizeof (*udp) - 1);
8298
8299   udp = (udp_header_t *) mask;
8300
8301 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8302   foreach_udp_proto_field;
8303 #undef _
8304
8305   *maskp = mask;
8306   return 1;
8307 }
8308
8309 typedef struct
8310 {
8311   u16 src_port, dst_port;
8312 } tcpudp_header_t;
8313
8314 uword
8315 unformat_l4_mask (unformat_input_t * input, va_list * args)
8316 {
8317   u8 **maskp = va_arg (*args, u8 **);
8318   u16 src_port = 0, dst_port = 0;
8319   tcpudp_header_t *tcpudp;
8320
8321   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8322     {
8323       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8324         return 1;
8325       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8326         return 1;
8327       else if (unformat (input, "src_port"))
8328         src_port = 0xFFFF;
8329       else if (unformat (input, "dst_port"))
8330         dst_port = 0xFFFF;
8331       else
8332         return 0;
8333     }
8334
8335   if (!src_port && !dst_port)
8336     return 0;
8337
8338   u8 *mask = 0;
8339   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8340
8341   tcpudp = (tcpudp_header_t *) mask;
8342   tcpudp->src_port = src_port;
8343   tcpudp->dst_port = dst_port;
8344
8345   *maskp = mask;
8346
8347   return 1;
8348 }
8349
8350 uword
8351 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8352 {
8353   u8 **maskp = va_arg (*args, u8 **);
8354   u8 *mask = 0;
8355   u8 found_something = 0;
8356   ip4_header_t *ip;
8357
8358 #define _(a) u8 a=0;
8359   foreach_ip4_proto_field;
8360 #undef _
8361   u8 version = 0;
8362   u8 hdr_length = 0;
8363
8364
8365   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8366     {
8367       if (unformat (input, "version"))
8368         version = 1;
8369       else if (unformat (input, "hdr_length"))
8370         hdr_length = 1;
8371       else if (unformat (input, "src"))
8372         src_address = 1;
8373       else if (unformat (input, "dst"))
8374         dst_address = 1;
8375       else if (unformat (input, "proto"))
8376         protocol = 1;
8377
8378 #define _(a) else if (unformat (input, #a)) a=1;
8379       foreach_ip4_proto_field
8380 #undef _
8381         else
8382         break;
8383     }
8384
8385 #define _(a) found_something += a;
8386   foreach_ip4_proto_field;
8387 #undef _
8388
8389   if (found_something == 0)
8390     return 0;
8391
8392   vec_validate (mask, sizeof (*ip) - 1);
8393
8394   ip = (ip4_header_t *) mask;
8395
8396 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8397   foreach_ip4_proto_field;
8398 #undef _
8399
8400   ip->ip_version_and_header_length = 0;
8401
8402   if (version)
8403     ip->ip_version_and_header_length |= 0xF0;
8404
8405   if (hdr_length)
8406     ip->ip_version_and_header_length |= 0x0F;
8407
8408   *maskp = mask;
8409   return 1;
8410 }
8411
8412 #define foreach_ip6_proto_field                 \
8413 _(src_address)                                  \
8414 _(dst_address)                                  \
8415 _(payload_length)                               \
8416 _(hop_limit)                                    \
8417 _(protocol)
8418
8419 uword
8420 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8421 {
8422   u8 **maskp = va_arg (*args, u8 **);
8423   u8 *mask = 0;
8424   u8 found_something = 0;
8425   ip6_header_t *ip;
8426   u32 ip_version_traffic_class_and_flow_label;
8427
8428 #define _(a) u8 a=0;
8429   foreach_ip6_proto_field;
8430 #undef _
8431   u8 version = 0;
8432   u8 traffic_class = 0;
8433   u8 flow_label = 0;
8434
8435   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8436     {
8437       if (unformat (input, "version"))
8438         version = 1;
8439       else if (unformat (input, "traffic-class"))
8440         traffic_class = 1;
8441       else if (unformat (input, "flow-label"))
8442         flow_label = 1;
8443       else if (unformat (input, "src"))
8444         src_address = 1;
8445       else if (unformat (input, "dst"))
8446         dst_address = 1;
8447       else if (unformat (input, "proto"))
8448         protocol = 1;
8449
8450 #define _(a) else if (unformat (input, #a)) a=1;
8451       foreach_ip6_proto_field
8452 #undef _
8453         else
8454         break;
8455     }
8456
8457 #define _(a) found_something += a;
8458   foreach_ip6_proto_field;
8459 #undef _
8460
8461   if (found_something == 0)
8462     return 0;
8463
8464   vec_validate (mask, sizeof (*ip) - 1);
8465
8466   ip = (ip6_header_t *) mask;
8467
8468 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8469   foreach_ip6_proto_field;
8470 #undef _
8471
8472   ip_version_traffic_class_and_flow_label = 0;
8473
8474   if (version)
8475     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8476
8477   if (traffic_class)
8478     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8479
8480   if (flow_label)
8481     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8482
8483   ip->ip_version_traffic_class_and_flow_label =
8484     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8485
8486   *maskp = mask;
8487   return 1;
8488 }
8489
8490 uword
8491 unformat_l3_mask (unformat_input_t * input, va_list * args)
8492 {
8493   u8 **maskp = va_arg (*args, u8 **);
8494
8495   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8496     {
8497       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8498         return 1;
8499       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8500         return 1;
8501       else
8502         break;
8503     }
8504   return 0;
8505 }
8506
8507 uword
8508 unformat_l2_mask (unformat_input_t * input, va_list * args)
8509 {
8510   u8 **maskp = va_arg (*args, u8 **);
8511   u8 *mask = 0;
8512   u8 src = 0;
8513   u8 dst = 0;
8514   u8 proto = 0;
8515   u8 tag1 = 0;
8516   u8 tag2 = 0;
8517   u8 ignore_tag1 = 0;
8518   u8 ignore_tag2 = 0;
8519   u8 cos1 = 0;
8520   u8 cos2 = 0;
8521   u8 dot1q = 0;
8522   u8 dot1ad = 0;
8523   int len = 14;
8524
8525   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8526     {
8527       if (unformat (input, "src"))
8528         src = 1;
8529       else if (unformat (input, "dst"))
8530         dst = 1;
8531       else if (unformat (input, "proto"))
8532         proto = 1;
8533       else if (unformat (input, "tag1"))
8534         tag1 = 1;
8535       else if (unformat (input, "tag2"))
8536         tag2 = 1;
8537       else if (unformat (input, "ignore-tag1"))
8538         ignore_tag1 = 1;
8539       else if (unformat (input, "ignore-tag2"))
8540         ignore_tag2 = 1;
8541       else if (unformat (input, "cos1"))
8542         cos1 = 1;
8543       else if (unformat (input, "cos2"))
8544         cos2 = 1;
8545       else if (unformat (input, "dot1q"))
8546         dot1q = 1;
8547       else if (unformat (input, "dot1ad"))
8548         dot1ad = 1;
8549       else
8550         break;
8551     }
8552   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8553        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8554     return 0;
8555
8556   if (tag1 || ignore_tag1 || cos1 || dot1q)
8557     len = 18;
8558   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8559     len = 22;
8560
8561   vec_validate (mask, len - 1);
8562
8563   if (dst)
8564     memset (mask, 0xff, 6);
8565
8566   if (src)
8567     memset (mask + 6, 0xff, 6);
8568
8569   if (tag2 || dot1ad)
8570     {
8571       /* inner vlan tag */
8572       if (tag2)
8573         {
8574           mask[19] = 0xff;
8575           mask[18] = 0x0f;
8576         }
8577       if (cos2)
8578         mask[18] |= 0xe0;
8579       if (proto)
8580         mask[21] = mask[20] = 0xff;
8581       if (tag1)
8582         {
8583           mask[15] = 0xff;
8584           mask[14] = 0x0f;
8585         }
8586       if (cos1)
8587         mask[14] |= 0xe0;
8588       *maskp = mask;
8589       return 1;
8590     }
8591   if (tag1 | dot1q)
8592     {
8593       if (tag1)
8594         {
8595           mask[15] = 0xff;
8596           mask[14] = 0x0f;
8597         }
8598       if (cos1)
8599         mask[14] |= 0xe0;
8600       if (proto)
8601         mask[16] = mask[17] = 0xff;
8602
8603       *maskp = mask;
8604       return 1;
8605     }
8606   if (cos2)
8607     mask[18] |= 0xe0;
8608   if (cos1)
8609     mask[14] |= 0xe0;
8610   if (proto)
8611     mask[12] = mask[13] = 0xff;
8612
8613   *maskp = mask;
8614   return 1;
8615 }
8616
8617 uword
8618 unformat_classify_mask (unformat_input_t * input, va_list * args)
8619 {
8620   u8 **maskp = va_arg (*args, u8 **);
8621   u32 *skipp = va_arg (*args, u32 *);
8622   u32 *matchp = va_arg (*args, u32 *);
8623   u32 match;
8624   u8 *mask = 0;
8625   u8 *l2 = 0;
8626   u8 *l3 = 0;
8627   u8 *l4 = 0;
8628   int i;
8629
8630   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8631     {
8632       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8633         ;
8634       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8635         ;
8636       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8637         ;
8638       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8639         ;
8640       else
8641         break;
8642     }
8643
8644   if (l4 && !l3)
8645     {
8646       vec_free (mask);
8647       vec_free (l2);
8648       vec_free (l4);
8649       return 0;
8650     }
8651
8652   if (mask || l2 || l3 || l4)
8653     {
8654       if (l2 || l3 || l4)
8655         {
8656           /* "With a free Ethernet header in every package" */
8657           if (l2 == 0)
8658             vec_validate (l2, 13);
8659           mask = l2;
8660           if (vec_len (l3))
8661             {
8662               vec_append (mask, l3);
8663               vec_free (l3);
8664             }
8665           if (vec_len (l4))
8666             {
8667               vec_append (mask, l4);
8668               vec_free (l4);
8669             }
8670         }
8671
8672       /* Scan forward looking for the first significant mask octet */
8673       for (i = 0; i < vec_len (mask); i++)
8674         if (mask[i])
8675           break;
8676
8677       /* compute (skip, match) params */
8678       *skipp = i / sizeof (u32x4);
8679       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8680
8681       /* Pad mask to an even multiple of the vector size */
8682       while (vec_len (mask) % sizeof (u32x4))
8683         vec_add1 (mask, 0);
8684
8685       match = vec_len (mask) / sizeof (u32x4);
8686
8687       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8688         {
8689           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8690           if (*tmp || *(tmp + 1))
8691             break;
8692           match--;
8693         }
8694       if (match == 0)
8695         clib_warning ("BUG: match 0");
8696
8697       _vec_len (mask) = match * sizeof (u32x4);
8698
8699       *matchp = match;
8700       *maskp = mask;
8701
8702       return 1;
8703     }
8704
8705   return 0;
8706 }
8707
8708 #define foreach_l2_next                         \
8709 _(drop, DROP)                                   \
8710 _(ethernet, ETHERNET_INPUT)                     \
8711 _(ip4, IP4_INPUT)                               \
8712 _(ip6, IP6_INPUT)
8713
8714 uword
8715 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8716 {
8717   u32 *miss_next_indexp = va_arg (*args, u32 *);
8718   u32 next_index = 0;
8719   u32 tmp;
8720
8721 #define _(n,N) \
8722   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8723   foreach_l2_next;
8724 #undef _
8725
8726   if (unformat (input, "%d", &tmp))
8727     {
8728       next_index = tmp;
8729       goto out;
8730     }
8731
8732   return 0;
8733
8734 out:
8735   *miss_next_indexp = next_index;
8736   return 1;
8737 }
8738
8739 #define foreach_ip_next                         \
8740 _(drop, DROP)                                   \
8741 _(local, LOCAL)                                 \
8742 _(rewrite, REWRITE)
8743
8744 uword
8745 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8746 {
8747   u32 *miss_next_indexp = va_arg (*args, u32 *);
8748   u32 next_index = 0;
8749   u32 tmp;
8750
8751 #define _(n,N) \
8752   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8753   foreach_ip_next;
8754 #undef _
8755
8756   if (unformat (input, "%d", &tmp))
8757     {
8758       next_index = tmp;
8759       goto out;
8760     }
8761
8762   return 0;
8763
8764 out:
8765   *miss_next_indexp = next_index;
8766   return 1;
8767 }
8768
8769 #define foreach_acl_next                        \
8770 _(deny, DENY)
8771
8772 uword
8773 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8774 {
8775   u32 *miss_next_indexp = va_arg (*args, u32 *);
8776   u32 next_index = 0;
8777   u32 tmp;
8778
8779 #define _(n,N) \
8780   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8781   foreach_acl_next;
8782 #undef _
8783
8784   if (unformat (input, "permit"))
8785     {
8786       next_index = ~0;
8787       goto out;
8788     }
8789   else if (unformat (input, "%d", &tmp))
8790     {
8791       next_index = tmp;
8792       goto out;
8793     }
8794
8795   return 0;
8796
8797 out:
8798   *miss_next_indexp = next_index;
8799   return 1;
8800 }
8801
8802 uword
8803 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8804 {
8805   u32 *r = va_arg (*args, u32 *);
8806
8807   if (unformat (input, "conform-color"))
8808     *r = POLICE_CONFORM;
8809   else if (unformat (input, "exceed-color"))
8810     *r = POLICE_EXCEED;
8811   else
8812     return 0;
8813
8814   return 1;
8815 }
8816
8817 static int
8818 api_classify_add_del_table (vat_main_t * vam)
8819 {
8820   unformat_input_t *i = vam->input;
8821   vl_api_classify_add_del_table_t *mp;
8822
8823   u32 nbuckets = 2;
8824   u32 skip = ~0;
8825   u32 match = ~0;
8826   int is_add = 1;
8827   u32 table_index = ~0;
8828   u32 next_table_index = ~0;
8829   u32 miss_next_index = ~0;
8830   u32 memory_size = 32 << 20;
8831   u8 *mask = 0;
8832   f64 timeout;
8833   u32 current_data_flag = 0;
8834   int current_data_offset = 0;
8835
8836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8837     {
8838       if (unformat (i, "del"))
8839         is_add = 0;
8840       else if (unformat (i, "buckets %d", &nbuckets))
8841         ;
8842       else if (unformat (i, "memory_size %d", &memory_size))
8843         ;
8844       else if (unformat (i, "skip %d", &skip))
8845         ;
8846       else if (unformat (i, "match %d", &match))
8847         ;
8848       else if (unformat (i, "table %d", &table_index))
8849         ;
8850       else if (unformat (i, "mask %U", unformat_classify_mask,
8851                          &mask, &skip, &match))
8852         ;
8853       else if (unformat (i, "next-table %d", &next_table_index))
8854         ;
8855       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8856                          &miss_next_index))
8857         ;
8858       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8859                          &miss_next_index))
8860         ;
8861       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8862                          &miss_next_index))
8863         ;
8864       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8865         ;
8866       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8867         ;
8868       else
8869         break;
8870     }
8871
8872   if (is_add && mask == 0)
8873     {
8874       errmsg ("Mask required\n");
8875       return -99;
8876     }
8877
8878   if (is_add && skip == ~0)
8879     {
8880       errmsg ("skip count required\n");
8881       return -99;
8882     }
8883
8884   if (is_add && match == ~0)
8885     {
8886       errmsg ("match count required\n");
8887       return -99;
8888     }
8889
8890   if (!is_add && table_index == ~0)
8891     {
8892       errmsg ("table index required for delete\n");
8893       return -99;
8894     }
8895
8896   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8897
8898   mp->is_add = is_add;
8899   mp->table_index = ntohl (table_index);
8900   mp->nbuckets = ntohl (nbuckets);
8901   mp->memory_size = ntohl (memory_size);
8902   mp->skip_n_vectors = ntohl (skip);
8903   mp->match_n_vectors = ntohl (match);
8904   mp->next_table_index = ntohl (next_table_index);
8905   mp->miss_next_index = ntohl (miss_next_index);
8906   mp->current_data_flag = ntohl (current_data_flag);
8907   mp->current_data_offset = ntohl (current_data_offset);
8908   clib_memcpy (mp->mask, mask, vec_len (mask));
8909
8910   vec_free (mask);
8911
8912   S;
8913   W;
8914   /* NOTREACHED */
8915 }
8916
8917 uword
8918 unformat_l4_match (unformat_input_t * input, va_list * args)
8919 {
8920   u8 **matchp = va_arg (*args, u8 **);
8921
8922   u8 *proto_header = 0;
8923   int src_port = 0;
8924   int dst_port = 0;
8925
8926   tcpudp_header_t h;
8927
8928   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8929     {
8930       if (unformat (input, "src_port %d", &src_port))
8931         ;
8932       else if (unformat (input, "dst_port %d", &dst_port))
8933         ;
8934       else
8935         return 0;
8936     }
8937
8938   h.src_port = clib_host_to_net_u16 (src_port);
8939   h.dst_port = clib_host_to_net_u16 (dst_port);
8940   vec_validate (proto_header, sizeof (h) - 1);
8941   memcpy (proto_header, &h, sizeof (h));
8942
8943   *matchp = proto_header;
8944
8945   return 1;
8946 }
8947
8948 uword
8949 unformat_ip4_match (unformat_input_t * input, va_list * args)
8950 {
8951   u8 **matchp = va_arg (*args, u8 **);
8952   u8 *match = 0;
8953   ip4_header_t *ip;
8954   int version = 0;
8955   u32 version_val;
8956   int hdr_length = 0;
8957   u32 hdr_length_val;
8958   int src = 0, dst = 0;
8959   ip4_address_t src_val, dst_val;
8960   int proto = 0;
8961   u32 proto_val;
8962   int tos = 0;
8963   u32 tos_val;
8964   int length = 0;
8965   u32 length_val;
8966   int fragment_id = 0;
8967   u32 fragment_id_val;
8968   int ttl = 0;
8969   int ttl_val;
8970   int checksum = 0;
8971   u32 checksum_val;
8972
8973   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8974     {
8975       if (unformat (input, "version %d", &version_val))
8976         version = 1;
8977       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8978         hdr_length = 1;
8979       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8980         src = 1;
8981       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8982         dst = 1;
8983       else if (unformat (input, "proto %d", &proto_val))
8984         proto = 1;
8985       else if (unformat (input, "tos %d", &tos_val))
8986         tos = 1;
8987       else if (unformat (input, "length %d", &length_val))
8988         length = 1;
8989       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8990         fragment_id = 1;
8991       else if (unformat (input, "ttl %d", &ttl_val))
8992         ttl = 1;
8993       else if (unformat (input, "checksum %d", &checksum_val))
8994         checksum = 1;
8995       else
8996         break;
8997     }
8998
8999   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9000       + ttl + checksum == 0)
9001     return 0;
9002
9003   /*
9004    * Aligned because we use the real comparison functions
9005    */
9006   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9007
9008   ip = (ip4_header_t *) match;
9009
9010   /* These are realistically matched in practice */
9011   if (src)
9012     ip->src_address.as_u32 = src_val.as_u32;
9013
9014   if (dst)
9015     ip->dst_address.as_u32 = dst_val.as_u32;
9016
9017   if (proto)
9018     ip->protocol = proto_val;
9019
9020
9021   /* These are not, but they're included for completeness */
9022   if (version)
9023     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9024
9025   if (hdr_length)
9026     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9027
9028   if (tos)
9029     ip->tos = tos_val;
9030
9031   if (length)
9032     ip->length = clib_host_to_net_u16 (length_val);
9033
9034   if (ttl)
9035     ip->ttl = ttl_val;
9036
9037   if (checksum)
9038     ip->checksum = clib_host_to_net_u16 (checksum_val);
9039
9040   *matchp = match;
9041   return 1;
9042 }
9043
9044 uword
9045 unformat_ip6_match (unformat_input_t * input, va_list * args)
9046 {
9047   u8 **matchp = va_arg (*args, u8 **);
9048   u8 *match = 0;
9049   ip6_header_t *ip;
9050   int version = 0;
9051   u32 version_val;
9052   u8 traffic_class = 0;
9053   u32 traffic_class_val = 0;
9054   u8 flow_label = 0;
9055   u8 flow_label_val;
9056   int src = 0, dst = 0;
9057   ip6_address_t src_val, dst_val;
9058   int proto = 0;
9059   u32 proto_val;
9060   int payload_length = 0;
9061   u32 payload_length_val;
9062   int hop_limit = 0;
9063   int hop_limit_val;
9064   u32 ip_version_traffic_class_and_flow_label;
9065
9066   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9067     {
9068       if (unformat (input, "version %d", &version_val))
9069         version = 1;
9070       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9071         traffic_class = 1;
9072       else if (unformat (input, "flow_label %d", &flow_label_val))
9073         flow_label = 1;
9074       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9075         src = 1;
9076       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9077         dst = 1;
9078       else if (unformat (input, "proto %d", &proto_val))
9079         proto = 1;
9080       else if (unformat (input, "payload_length %d", &payload_length_val))
9081         payload_length = 1;
9082       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9083         hop_limit = 1;
9084       else
9085         break;
9086     }
9087
9088   if (version + traffic_class + flow_label + src + dst + proto +
9089       payload_length + hop_limit == 0)
9090     return 0;
9091
9092   /*
9093    * Aligned because we use the real comparison functions
9094    */
9095   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9096
9097   ip = (ip6_header_t *) match;
9098
9099   if (src)
9100     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9101
9102   if (dst)
9103     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9104
9105   if (proto)
9106     ip->protocol = proto_val;
9107
9108   ip_version_traffic_class_and_flow_label = 0;
9109
9110   if (version)
9111     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9112
9113   if (traffic_class)
9114     ip_version_traffic_class_and_flow_label |=
9115       (traffic_class_val & 0xFF) << 20;
9116
9117   if (flow_label)
9118     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9119
9120   ip->ip_version_traffic_class_and_flow_label =
9121     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9122
9123   if (payload_length)
9124     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9125
9126   if (hop_limit)
9127     ip->hop_limit = hop_limit_val;
9128
9129   *matchp = match;
9130   return 1;
9131 }
9132
9133 uword
9134 unformat_l3_match (unformat_input_t * input, va_list * args)
9135 {
9136   u8 **matchp = va_arg (*args, u8 **);
9137
9138   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9139     {
9140       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9141         return 1;
9142       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9143         return 1;
9144       else
9145         break;
9146     }
9147   return 0;
9148 }
9149
9150 uword
9151 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9152 {
9153   u8 *tagp = va_arg (*args, u8 *);
9154   u32 tag;
9155
9156   if (unformat (input, "%d", &tag))
9157     {
9158       tagp[0] = (tag >> 8) & 0x0F;
9159       tagp[1] = tag & 0xFF;
9160       return 1;
9161     }
9162
9163   return 0;
9164 }
9165
9166 uword
9167 unformat_l2_match (unformat_input_t * input, va_list * args)
9168 {
9169   u8 **matchp = va_arg (*args, u8 **);
9170   u8 *match = 0;
9171   u8 src = 0;
9172   u8 src_val[6];
9173   u8 dst = 0;
9174   u8 dst_val[6];
9175   u8 proto = 0;
9176   u16 proto_val;
9177   u8 tag1 = 0;
9178   u8 tag1_val[2];
9179   u8 tag2 = 0;
9180   u8 tag2_val[2];
9181   int len = 14;
9182   u8 ignore_tag1 = 0;
9183   u8 ignore_tag2 = 0;
9184   u8 cos1 = 0;
9185   u8 cos2 = 0;
9186   u32 cos1_val = 0;
9187   u32 cos2_val = 0;
9188
9189   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9190     {
9191       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9192         src = 1;
9193       else
9194         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9195         dst = 1;
9196       else if (unformat (input, "proto %U",
9197                          unformat_ethernet_type_host_byte_order, &proto_val))
9198         proto = 1;
9199       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9200         tag1 = 1;
9201       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9202         tag2 = 1;
9203       else if (unformat (input, "ignore-tag1"))
9204         ignore_tag1 = 1;
9205       else if (unformat (input, "ignore-tag2"))
9206         ignore_tag2 = 1;
9207       else if (unformat (input, "cos1 %d", &cos1_val))
9208         cos1 = 1;
9209       else if (unformat (input, "cos2 %d", &cos2_val))
9210         cos2 = 1;
9211       else
9212         break;
9213     }
9214   if ((src + dst + proto + tag1 + tag2 +
9215        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9216     return 0;
9217
9218   if (tag1 || ignore_tag1 || cos1)
9219     len = 18;
9220   if (tag2 || ignore_tag2 || cos2)
9221     len = 22;
9222
9223   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9224
9225   if (dst)
9226     clib_memcpy (match, dst_val, 6);
9227
9228   if (src)
9229     clib_memcpy (match + 6, src_val, 6);
9230
9231   if (tag2)
9232     {
9233       /* inner vlan tag */
9234       match[19] = tag2_val[1];
9235       match[18] = tag2_val[0];
9236       if (cos2)
9237         match[18] |= (cos2_val & 0x7) << 5;
9238       if (proto)
9239         {
9240           match[21] = proto_val & 0xff;
9241           match[20] = proto_val >> 8;
9242         }
9243       if (tag1)
9244         {
9245           match[15] = tag1_val[1];
9246           match[14] = tag1_val[0];
9247         }
9248       if (cos1)
9249         match[14] |= (cos1_val & 0x7) << 5;
9250       *matchp = match;
9251       return 1;
9252     }
9253   if (tag1)
9254     {
9255       match[15] = tag1_val[1];
9256       match[14] = tag1_val[0];
9257       if (proto)
9258         {
9259           match[17] = proto_val & 0xff;
9260           match[16] = proto_val >> 8;
9261         }
9262       if (cos1)
9263         match[14] |= (cos1_val & 0x7) << 5;
9264
9265       *matchp = match;
9266       return 1;
9267     }
9268   if (cos2)
9269     match[18] |= (cos2_val & 0x7) << 5;
9270   if (cos1)
9271     match[14] |= (cos1_val & 0x7) << 5;
9272   if (proto)
9273     {
9274       match[13] = proto_val & 0xff;
9275       match[12] = proto_val >> 8;
9276     }
9277
9278   *matchp = match;
9279   return 1;
9280 }
9281
9282
9283 uword
9284 unformat_classify_match (unformat_input_t * input, va_list * args)
9285 {
9286   u8 **matchp = va_arg (*args, u8 **);
9287   u32 skip_n_vectors = va_arg (*args, u32);
9288   u32 match_n_vectors = va_arg (*args, u32);
9289
9290   u8 *match = 0;
9291   u8 *l2 = 0;
9292   u8 *l3 = 0;
9293   u8 *l4 = 0;
9294
9295   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9296     {
9297       if (unformat (input, "hex %U", unformat_hex_string, &match))
9298         ;
9299       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9300         ;
9301       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9302         ;
9303       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9304         ;
9305       else
9306         break;
9307     }
9308
9309   if (l4 && !l3)
9310     {
9311       vec_free (match);
9312       vec_free (l2);
9313       vec_free (l4);
9314       return 0;
9315     }
9316
9317   if (match || l2 || l3 || l4)
9318     {
9319       if (l2 || l3 || l4)
9320         {
9321           /* "Win a free Ethernet header in every packet" */
9322           if (l2 == 0)
9323             vec_validate_aligned (l2, 13, sizeof (u32x4));
9324           match = l2;
9325           if (vec_len (l3))
9326             {
9327               vec_append_aligned (match, l3, sizeof (u32x4));
9328               vec_free (l3);
9329             }
9330           if (vec_len (l4))
9331             {
9332               vec_append_aligned (match, l4, sizeof (u32x4));
9333               vec_free (l4);
9334             }
9335         }
9336
9337       /* Make sure the vector is big enough even if key is all 0's */
9338       vec_validate_aligned
9339         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9340          sizeof (u32x4));
9341
9342       /* Set size, include skipped vectors */
9343       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9344
9345       *matchp = match;
9346
9347       return 1;
9348     }
9349
9350   return 0;
9351 }
9352
9353 static int
9354 api_classify_add_del_session (vat_main_t * vam)
9355 {
9356   unformat_input_t *i = vam->input;
9357   vl_api_classify_add_del_session_t *mp;
9358   int is_add = 1;
9359   u32 table_index = ~0;
9360   u32 hit_next_index = ~0;
9361   u32 opaque_index = ~0;
9362   u8 *match = 0;
9363   i32 advance = 0;
9364   f64 timeout;
9365   u32 skip_n_vectors = 0;
9366   u32 match_n_vectors = 0;
9367   u32 action = 0;
9368   u32 metadata = 0;
9369
9370   /*
9371    * Warning: you have to supply skip_n and match_n
9372    * because the API client cant simply look at the classify
9373    * table object.
9374    */
9375
9376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9377     {
9378       if (unformat (i, "del"))
9379         is_add = 0;
9380       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9381                          &hit_next_index))
9382         ;
9383       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9384                          &hit_next_index))
9385         ;
9386       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9387                          &hit_next_index))
9388         ;
9389       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9390         ;
9391       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9392         ;
9393       else if (unformat (i, "opaque-index %d", &opaque_index))
9394         ;
9395       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9396         ;
9397       else if (unformat (i, "match_n %d", &match_n_vectors))
9398         ;
9399       else if (unformat (i, "match %U", unformat_classify_match,
9400                          &match, skip_n_vectors, match_n_vectors))
9401         ;
9402       else if (unformat (i, "advance %d", &advance))
9403         ;
9404       else if (unformat (i, "table-index %d", &table_index))
9405         ;
9406       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9407         action = 1;
9408       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9409         action = 2;
9410       else if (unformat (i, "action %d", &action))
9411         ;
9412       else if (unformat (i, "metadata %d", &metadata))
9413         ;
9414       else
9415         break;
9416     }
9417
9418   if (table_index == ~0)
9419     {
9420       errmsg ("Table index required\n");
9421       return -99;
9422     }
9423
9424   if (is_add && match == 0)
9425     {
9426       errmsg ("Match value required\n");
9427       return -99;
9428     }
9429
9430   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9431
9432   mp->is_add = is_add;
9433   mp->table_index = ntohl (table_index);
9434   mp->hit_next_index = ntohl (hit_next_index);
9435   mp->opaque_index = ntohl (opaque_index);
9436   mp->advance = ntohl (advance);
9437   mp->action = action;
9438   mp->metadata = ntohl (metadata);
9439   clib_memcpy (mp->match, match, vec_len (match));
9440   vec_free (match);
9441
9442   S;
9443   W;
9444   /* NOTREACHED */
9445 }
9446
9447 static int
9448 api_classify_set_interface_ip_table (vat_main_t * vam)
9449 {
9450   unformat_input_t *i = vam->input;
9451   vl_api_classify_set_interface_ip_table_t *mp;
9452   f64 timeout;
9453   u32 sw_if_index;
9454   int sw_if_index_set;
9455   u32 table_index = ~0;
9456   u8 is_ipv6 = 0;
9457
9458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9459     {
9460       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9461         sw_if_index_set = 1;
9462       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9463         sw_if_index_set = 1;
9464       else if (unformat (i, "table %d", &table_index))
9465         ;
9466       else
9467         {
9468           clib_warning ("parse error '%U'", format_unformat_error, i);
9469           return -99;
9470         }
9471     }
9472
9473   if (sw_if_index_set == 0)
9474     {
9475       errmsg ("missing interface name or sw_if_index\n");
9476       return -99;
9477     }
9478
9479
9480   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9481
9482   mp->sw_if_index = ntohl (sw_if_index);
9483   mp->table_index = ntohl (table_index);
9484   mp->is_ipv6 = is_ipv6;
9485
9486   S;
9487   W;
9488   /* NOTREACHED */
9489   return 0;
9490 }
9491
9492 static int
9493 api_classify_set_interface_l2_tables (vat_main_t * vam)
9494 {
9495   unformat_input_t *i = vam->input;
9496   vl_api_classify_set_interface_l2_tables_t *mp;
9497   f64 timeout;
9498   u32 sw_if_index;
9499   int sw_if_index_set;
9500   u32 ip4_table_index = ~0;
9501   u32 ip6_table_index = ~0;
9502   u32 other_table_index = ~0;
9503   u32 is_input = 1;
9504
9505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9506     {
9507       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9508         sw_if_index_set = 1;
9509       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9510         sw_if_index_set = 1;
9511       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9512         ;
9513       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9514         ;
9515       else if (unformat (i, "other-table %d", &other_table_index))
9516         ;
9517       else if (unformat (i, "is-input %d", &is_input))
9518         ;
9519       else
9520         {
9521           clib_warning ("parse error '%U'", format_unformat_error, i);
9522           return -99;
9523         }
9524     }
9525
9526   if (sw_if_index_set == 0)
9527     {
9528       errmsg ("missing interface name or sw_if_index\n");
9529       return -99;
9530     }
9531
9532
9533   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9534
9535   mp->sw_if_index = ntohl (sw_if_index);
9536   mp->ip4_table_index = ntohl (ip4_table_index);
9537   mp->ip6_table_index = ntohl (ip6_table_index);
9538   mp->other_table_index = ntohl (other_table_index);
9539   mp->is_input = (u8) is_input;
9540
9541   S;
9542   W;
9543   /* NOTREACHED */
9544   return 0;
9545 }
9546
9547 static int
9548 api_set_ipfix_exporter (vat_main_t * vam)
9549 {
9550   unformat_input_t *i = vam->input;
9551   vl_api_set_ipfix_exporter_t *mp;
9552   ip4_address_t collector_address;
9553   u8 collector_address_set = 0;
9554   u32 collector_port = ~0;
9555   ip4_address_t src_address;
9556   u8 src_address_set = 0;
9557   u32 vrf_id = ~0;
9558   u32 path_mtu = ~0;
9559   u32 template_interval = ~0;
9560   u8 udp_checksum = 0;
9561   f64 timeout;
9562
9563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9564     {
9565       if (unformat (i, "collector_address %U", unformat_ip4_address,
9566                     &collector_address))
9567         collector_address_set = 1;
9568       else if (unformat (i, "collector_port %d", &collector_port))
9569         ;
9570       else if (unformat (i, "src_address %U", unformat_ip4_address,
9571                          &src_address))
9572         src_address_set = 1;
9573       else if (unformat (i, "vrf_id %d", &vrf_id))
9574         ;
9575       else if (unformat (i, "path_mtu %d", &path_mtu))
9576         ;
9577       else if (unformat (i, "template_interval %d", &template_interval))
9578         ;
9579       else if (unformat (i, "udp_checksum"))
9580         udp_checksum = 1;
9581       else
9582         break;
9583     }
9584
9585   if (collector_address_set == 0)
9586     {
9587       errmsg ("collector_address required\n");
9588       return -99;
9589     }
9590
9591   if (src_address_set == 0)
9592     {
9593       errmsg ("src_address required\n");
9594       return -99;
9595     }
9596
9597   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9598
9599   memcpy (mp->collector_address, collector_address.data,
9600           sizeof (collector_address.data));
9601   mp->collector_port = htons ((u16) collector_port);
9602   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9603   mp->vrf_id = htonl (vrf_id);
9604   mp->path_mtu = htonl (path_mtu);
9605   mp->template_interval = htonl (template_interval);
9606   mp->udp_checksum = udp_checksum;
9607
9608   S;
9609   W;
9610   /* NOTREACHED */
9611 }
9612
9613 static int
9614 api_set_ipfix_classify_stream (vat_main_t * vam)
9615 {
9616   unformat_input_t *i = vam->input;
9617   vl_api_set_ipfix_classify_stream_t *mp;
9618   u32 domain_id = 0;
9619   u32 src_port = UDP_DST_PORT_ipfix;
9620   f64 timeout;
9621
9622   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9623     {
9624       if (unformat (i, "domain %d", &domain_id))
9625         ;
9626       else if (unformat (i, "src_port %d", &src_port))
9627         ;
9628       else
9629         {
9630           errmsg ("unknown input `%U'", format_unformat_error, i);
9631           return -99;
9632         }
9633     }
9634
9635   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9636
9637   mp->domain_id = htonl (domain_id);
9638   mp->src_port = htons ((u16) src_port);
9639
9640   S;
9641   W;
9642   /* NOTREACHED */
9643 }
9644
9645 static int
9646 api_ipfix_classify_table_add_del (vat_main_t * vam)
9647 {
9648   unformat_input_t *i = vam->input;
9649   vl_api_ipfix_classify_table_add_del_t *mp;
9650   int is_add = -1;
9651   u32 classify_table_index = ~0;
9652   u8 ip_version = 0;
9653   u8 transport_protocol = 255;
9654   f64 timeout;
9655
9656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9657     {
9658       if (unformat (i, "add"))
9659         is_add = 1;
9660       else if (unformat (i, "del"))
9661         is_add = 0;
9662       else if (unformat (i, "table %d", &classify_table_index))
9663         ;
9664       else if (unformat (i, "ip4"))
9665         ip_version = 4;
9666       else if (unformat (i, "ip6"))
9667         ip_version = 6;
9668       else if (unformat (i, "tcp"))
9669         transport_protocol = 6;
9670       else if (unformat (i, "udp"))
9671         transport_protocol = 17;
9672       else
9673         {
9674           errmsg ("unknown input `%U'", format_unformat_error, i);
9675           return -99;
9676         }
9677     }
9678
9679   if (is_add == -1)
9680     {
9681       errmsg ("expecting: add|del");
9682       return -99;
9683     }
9684   if (classify_table_index == ~0)
9685     {
9686       errmsg ("classifier table not specified");
9687       return -99;
9688     }
9689   if (ip_version == 0)
9690     {
9691       errmsg ("IP version not specified");
9692       return -99;
9693     }
9694
9695   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9696
9697   mp->is_add = is_add;
9698   mp->table_id = htonl (classify_table_index);
9699   mp->ip_version = ip_version;
9700   mp->transport_protocol = transport_protocol;
9701
9702   S;
9703   W;
9704   /* NOTREACHED */
9705 }
9706
9707 static int
9708 api_get_node_index (vat_main_t * vam)
9709 {
9710   unformat_input_t *i = vam->input;
9711   vl_api_get_node_index_t *mp;
9712   f64 timeout;
9713   u8 *name = 0;
9714
9715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9716     {
9717       if (unformat (i, "node %s", &name))
9718         ;
9719       else
9720         break;
9721     }
9722   if (name == 0)
9723     {
9724       errmsg ("node name required\n");
9725       return -99;
9726     }
9727   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9728     {
9729       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9730       return -99;
9731     }
9732
9733   M (GET_NODE_INDEX, get_node_index);
9734   clib_memcpy (mp->node_name, name, vec_len (name));
9735   vec_free (name);
9736
9737   S;
9738   W;
9739   /* NOTREACHED */
9740   return 0;
9741 }
9742
9743 static int
9744 api_get_next_index (vat_main_t * vam)
9745 {
9746   unformat_input_t *i = vam->input;
9747   vl_api_get_next_index_t *mp;
9748   f64 timeout;
9749   u8 *node_name = 0, *next_node_name = 0;
9750
9751   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9752     {
9753       if (unformat (i, "node-name %s", &node_name))
9754         ;
9755       else if (unformat (i, "next-node-name %s", &next_node_name))
9756         break;
9757     }
9758
9759   if (node_name == 0)
9760     {
9761       errmsg ("node name required\n");
9762       return -99;
9763     }
9764   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9765     {
9766       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9767       return -99;
9768     }
9769
9770   if (next_node_name == 0)
9771     {
9772       errmsg ("next node name required\n");
9773       return -99;
9774     }
9775   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9776     {
9777       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9778       return -99;
9779     }
9780
9781   M (GET_NEXT_INDEX, get_next_index);
9782   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9783   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9784   vec_free (node_name);
9785   vec_free (next_node_name);
9786
9787   S;
9788   W;
9789   /* NOTREACHED */
9790   return 0;
9791 }
9792
9793 static int
9794 api_add_node_next (vat_main_t * vam)
9795 {
9796   unformat_input_t *i = vam->input;
9797   vl_api_add_node_next_t *mp;
9798   f64 timeout;
9799   u8 *name = 0;
9800   u8 *next = 0;
9801
9802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9803     {
9804       if (unformat (i, "node %s", &name))
9805         ;
9806       else if (unformat (i, "next %s", &next))
9807         ;
9808       else
9809         break;
9810     }
9811   if (name == 0)
9812     {
9813       errmsg ("node name required\n");
9814       return -99;
9815     }
9816   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9817     {
9818       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9819       return -99;
9820     }
9821   if (next == 0)
9822     {
9823       errmsg ("next node required\n");
9824       return -99;
9825     }
9826   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9827     {
9828       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9829       return -99;
9830     }
9831
9832   M (ADD_NODE_NEXT, add_node_next);
9833   clib_memcpy (mp->node_name, name, vec_len (name));
9834   clib_memcpy (mp->next_name, next, vec_len (next));
9835   vec_free (name);
9836   vec_free (next);
9837
9838   S;
9839   W;
9840   /* NOTREACHED */
9841   return 0;
9842 }
9843
9844 static int
9845 api_l2tpv3_create_tunnel (vat_main_t * vam)
9846 {
9847   unformat_input_t *i = vam->input;
9848   ip6_address_t client_address, our_address;
9849   int client_address_set = 0;
9850   int our_address_set = 0;
9851   u32 local_session_id = 0;
9852   u32 remote_session_id = 0;
9853   u64 local_cookie = 0;
9854   u64 remote_cookie = 0;
9855   u8 l2_sublayer_present = 0;
9856   vl_api_l2tpv3_create_tunnel_t *mp;
9857   f64 timeout;
9858
9859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9860     {
9861       if (unformat (i, "client_address %U", unformat_ip6_address,
9862                     &client_address))
9863         client_address_set = 1;
9864       else if (unformat (i, "our_address %U", unformat_ip6_address,
9865                          &our_address))
9866         our_address_set = 1;
9867       else if (unformat (i, "local_session_id %d", &local_session_id))
9868         ;
9869       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9870         ;
9871       else if (unformat (i, "local_cookie %lld", &local_cookie))
9872         ;
9873       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9874         ;
9875       else if (unformat (i, "l2-sublayer-present"))
9876         l2_sublayer_present = 1;
9877       else
9878         break;
9879     }
9880
9881   if (client_address_set == 0)
9882     {
9883       errmsg ("client_address required\n");
9884       return -99;
9885     }
9886
9887   if (our_address_set == 0)
9888     {
9889       errmsg ("our_address required\n");
9890       return -99;
9891     }
9892
9893   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9894
9895   clib_memcpy (mp->client_address, client_address.as_u8,
9896                sizeof (mp->client_address));
9897
9898   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9899
9900   mp->local_session_id = ntohl (local_session_id);
9901   mp->remote_session_id = ntohl (remote_session_id);
9902   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9903   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9904   mp->l2_sublayer_present = l2_sublayer_present;
9905   mp->is_ipv6 = 1;
9906
9907   S;
9908   W;
9909   /* NOTREACHED */
9910   return 0;
9911 }
9912
9913 static int
9914 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9915 {
9916   unformat_input_t *i = vam->input;
9917   u32 sw_if_index;
9918   u8 sw_if_index_set = 0;
9919   u64 new_local_cookie = 0;
9920   u64 new_remote_cookie = 0;
9921   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9922   f64 timeout;
9923
9924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9925     {
9926       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9927         sw_if_index_set = 1;
9928       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9929         sw_if_index_set = 1;
9930       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9931         ;
9932       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9933         ;
9934       else
9935         break;
9936     }
9937
9938   if (sw_if_index_set == 0)
9939     {
9940       errmsg ("missing interface name or sw_if_index\n");
9941       return -99;
9942     }
9943
9944   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9945
9946   mp->sw_if_index = ntohl (sw_if_index);
9947   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9948   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9949
9950   S;
9951   W;
9952   /* NOTREACHED */
9953   return 0;
9954 }
9955
9956 static int
9957 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9958 {
9959   unformat_input_t *i = vam->input;
9960   vl_api_l2tpv3_interface_enable_disable_t *mp;
9961   f64 timeout;
9962   u32 sw_if_index;
9963   u8 sw_if_index_set = 0;
9964   u8 enable_disable = 1;
9965
9966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9967     {
9968       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9969         sw_if_index_set = 1;
9970       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9971         sw_if_index_set = 1;
9972       else if (unformat (i, "enable"))
9973         enable_disable = 1;
9974       else if (unformat (i, "disable"))
9975         enable_disable = 0;
9976       else
9977         break;
9978     }
9979
9980   if (sw_if_index_set == 0)
9981     {
9982       errmsg ("missing interface name or sw_if_index\n");
9983       return -99;
9984     }
9985
9986   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9987
9988   mp->sw_if_index = ntohl (sw_if_index);
9989   mp->enable_disable = enable_disable;
9990
9991   S;
9992   W;
9993   /* NOTREACHED */
9994   return 0;
9995 }
9996
9997 static int
9998 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9999 {
10000   unformat_input_t *i = vam->input;
10001   vl_api_l2tpv3_set_lookup_key_t *mp;
10002   f64 timeout;
10003   u8 key = ~0;
10004
10005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10006     {
10007       if (unformat (i, "lookup_v6_src"))
10008         key = L2T_LOOKUP_SRC_ADDRESS;
10009       else if (unformat (i, "lookup_v6_dst"))
10010         key = L2T_LOOKUP_DST_ADDRESS;
10011       else if (unformat (i, "lookup_session_id"))
10012         key = L2T_LOOKUP_SESSION_ID;
10013       else
10014         break;
10015     }
10016
10017   if (key == (u8) ~ 0)
10018     {
10019       errmsg ("l2tp session lookup key unset\n");
10020       return -99;
10021     }
10022
10023   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
10024
10025   mp->key = key;
10026
10027   S;
10028   W;
10029   /* NOTREACHED */
10030   return 0;
10031 }
10032
10033 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10034   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10035 {
10036   vat_main_t *vam = &vat_main;
10037
10038   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
10039            format_ip6_address, mp->our_address,
10040            format_ip6_address, mp->client_address,
10041            clib_net_to_host_u32 (mp->sw_if_index));
10042
10043   fformat (vam->ofp,
10044            "   local cookies %016llx %016llx remote cookie %016llx\n",
10045            clib_net_to_host_u64 (mp->local_cookie[0]),
10046            clib_net_to_host_u64 (mp->local_cookie[1]),
10047            clib_net_to_host_u64 (mp->remote_cookie));
10048
10049   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
10050            clib_net_to_host_u32 (mp->local_session_id),
10051            clib_net_to_host_u32 (mp->remote_session_id));
10052
10053   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
10054            mp->l2_sublayer_present ? "preset" : "absent");
10055
10056 }
10057
10058 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10059   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10060 {
10061   vat_main_t *vam = &vat_main;
10062   vat_json_node_t *node = NULL;
10063   struct in6_addr addr;
10064
10065   if (VAT_JSON_ARRAY != vam->json_tree.type)
10066     {
10067       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10068       vat_json_init_array (&vam->json_tree);
10069     }
10070   node = vat_json_array_add (&vam->json_tree);
10071
10072   vat_json_init_object (node);
10073
10074   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10075   vat_json_object_add_ip6 (node, "our_address", addr);
10076   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10077   vat_json_object_add_ip6 (node, "client_address", addr);
10078
10079   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10080   vat_json_init_array (lc);
10081   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10082   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10083   vat_json_object_add_uint (node, "remote_cookie",
10084                             clib_net_to_host_u64 (mp->remote_cookie));
10085
10086   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10087   vat_json_object_add_uint (node, "local_session_id",
10088                             clib_net_to_host_u32 (mp->local_session_id));
10089   vat_json_object_add_uint (node, "remote_session_id",
10090                             clib_net_to_host_u32 (mp->remote_session_id));
10091   vat_json_object_add_string_copy (node, "l2_sublayer",
10092                                    mp->l2_sublayer_present ? (u8 *) "present"
10093                                    : (u8 *) "absent");
10094 }
10095
10096 static int
10097 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10098 {
10099   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10100   f64 timeout;
10101
10102   /* Get list of l2tpv3-tunnel interfaces */
10103   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10104   S;
10105
10106   /* Use a control ping for synchronization */
10107   {
10108     vl_api_control_ping_t *mp;
10109     M (CONTROL_PING, control_ping);
10110     S;
10111   }
10112   W;
10113 }
10114
10115
10116 static void vl_api_sw_interface_tap_details_t_handler
10117   (vl_api_sw_interface_tap_details_t * mp)
10118 {
10119   vat_main_t *vam = &vat_main;
10120
10121   fformat (vam->ofp, "%-16s %d\n",
10122            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10123 }
10124
10125 static void vl_api_sw_interface_tap_details_t_handler_json
10126   (vl_api_sw_interface_tap_details_t * mp)
10127 {
10128   vat_main_t *vam = &vat_main;
10129   vat_json_node_t *node = NULL;
10130
10131   if (VAT_JSON_ARRAY != vam->json_tree.type)
10132     {
10133       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10134       vat_json_init_array (&vam->json_tree);
10135     }
10136   node = vat_json_array_add (&vam->json_tree);
10137
10138   vat_json_init_object (node);
10139   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10140   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10141 }
10142
10143 static int
10144 api_sw_interface_tap_dump (vat_main_t * vam)
10145 {
10146   vl_api_sw_interface_tap_dump_t *mp;
10147   f64 timeout;
10148
10149   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10150   /* Get list of tap interfaces */
10151   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10152   S;
10153
10154   /* Use a control ping for synchronization */
10155   {
10156     vl_api_control_ping_t *mp;
10157     M (CONTROL_PING, control_ping);
10158     S;
10159   }
10160   W;
10161 }
10162
10163 static uword unformat_vxlan_decap_next
10164   (unformat_input_t * input, va_list * args)
10165 {
10166   u32 *result = va_arg (*args, u32 *);
10167   u32 tmp;
10168
10169   if (unformat (input, "l2"))
10170     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10171   else if (unformat (input, "%d", &tmp))
10172     *result = tmp;
10173   else
10174     return 0;
10175   return 1;
10176 }
10177
10178 static int
10179 api_vxlan_add_del_tunnel (vat_main_t * vam)
10180 {
10181   unformat_input_t *line_input = vam->input;
10182   vl_api_vxlan_add_del_tunnel_t *mp;
10183   f64 timeout;
10184   ip46_address_t src, dst;
10185   u8 is_add = 1;
10186   u8 ipv4_set = 0, ipv6_set = 0;
10187   u8 src_set = 0;
10188   u8 dst_set = 0;
10189   u8 grp_set = 0;
10190   u32 mcast_sw_if_index = ~0;
10191   u32 encap_vrf_id = 0;
10192   u32 decap_next_index = ~0;
10193   u32 vni = 0;
10194
10195   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10196   memset (&src, 0, sizeof src);
10197   memset (&dst, 0, sizeof dst);
10198
10199   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10200     {
10201       if (unformat (line_input, "del"))
10202         is_add = 0;
10203       else
10204         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10205         {
10206           ipv4_set = 1;
10207           src_set = 1;
10208         }
10209       else
10210         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10211         {
10212           ipv4_set = 1;
10213           dst_set = 1;
10214         }
10215       else
10216         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10217         {
10218           ipv6_set = 1;
10219           src_set = 1;
10220         }
10221       else
10222         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10223         {
10224           ipv6_set = 1;
10225           dst_set = 1;
10226         }
10227       else if (unformat (line_input, "group %U %U",
10228                          unformat_ip4_address, &dst.ip4,
10229                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10230         {
10231           grp_set = dst_set = 1;
10232           ipv4_set = 1;
10233         }
10234       else if (unformat (line_input, "group %U",
10235                          unformat_ip4_address, &dst.ip4))
10236         {
10237           grp_set = dst_set = 1;
10238           ipv4_set = 1;
10239         }
10240       else if (unformat (line_input, "group %U %U",
10241                          unformat_ip6_address, &dst.ip6,
10242                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10243         {
10244           grp_set = dst_set = 1;
10245           ipv6_set = 1;
10246         }
10247       else if (unformat (line_input, "group %U",
10248                          unformat_ip6_address, &dst.ip6))
10249         {
10250           grp_set = dst_set = 1;
10251           ipv6_set = 1;
10252         }
10253       else
10254         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10255         ;
10256       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10257         ;
10258       else if (unformat (line_input, "decap-next %U",
10259                          unformat_vxlan_decap_next, &decap_next_index))
10260         ;
10261       else if (unformat (line_input, "vni %d", &vni))
10262         ;
10263       else
10264         {
10265           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10266           return -99;
10267         }
10268     }
10269
10270   if (src_set == 0)
10271     {
10272       errmsg ("tunnel src address not specified\n");
10273       return -99;
10274     }
10275   if (dst_set == 0)
10276     {
10277       errmsg ("tunnel dst address not specified\n");
10278       return -99;
10279     }
10280
10281   if (grp_set && !ip46_address_is_multicast (&dst))
10282     {
10283       errmsg ("tunnel group address not multicast\n");
10284       return -99;
10285     }
10286   if (grp_set && mcast_sw_if_index == ~0)
10287     {
10288       errmsg ("tunnel nonexistent multicast device\n");
10289       return -99;
10290     }
10291
10292
10293   if (ipv4_set && ipv6_set)
10294     {
10295       errmsg ("both IPv4 and IPv6 addresses specified");
10296       return -99;
10297     }
10298
10299   if ((vni == 0) || (vni >> 24))
10300     {
10301       errmsg ("vni not specified or out of range\n");
10302       return -99;
10303     }
10304
10305   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10306
10307   if (ipv6_set)
10308     {
10309       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10310       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10311     }
10312   else
10313     {
10314       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10315       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10316     }
10317   mp->encap_vrf_id = ntohl (encap_vrf_id);
10318   mp->decap_next_index = ntohl (decap_next_index);
10319   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10320   mp->vni = ntohl (vni);
10321   mp->is_add = is_add;
10322   mp->is_ipv6 = ipv6_set;
10323
10324   S;
10325   W;
10326   /* NOTREACHED */
10327   return 0;
10328 }
10329
10330 static void vl_api_vxlan_tunnel_details_t_handler
10331   (vl_api_vxlan_tunnel_details_t * mp)
10332 {
10333   vat_main_t *vam = &vat_main;
10334   ip46_address_t src, dst;
10335
10336   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10337   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10338
10339   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d\n",
10340            ntohl (mp->sw_if_index),
10341            format_ip46_address, &src, IP46_TYPE_ANY,
10342            format_ip46_address, &dst, IP46_TYPE_ANY,
10343            ntohl (mp->encap_vrf_id),
10344            ntohl (mp->decap_next_index), ntohl (mp->vni),
10345            ntohl (mp->mcast_sw_if_index));
10346 }
10347
10348 static void vl_api_vxlan_tunnel_details_t_handler_json
10349   (vl_api_vxlan_tunnel_details_t * mp)
10350 {
10351   vat_main_t *vam = &vat_main;
10352   vat_json_node_t *node = NULL;
10353
10354   if (VAT_JSON_ARRAY != vam->json_tree.type)
10355     {
10356       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10357       vat_json_init_array (&vam->json_tree);
10358     }
10359   node = vat_json_array_add (&vam->json_tree);
10360
10361   vat_json_init_object (node);
10362   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10363   if (mp->is_ipv6)
10364     {
10365       struct in6_addr ip6;
10366
10367       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10368       vat_json_object_add_ip6 (node, "src_address", ip6);
10369       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10370       vat_json_object_add_ip6 (node, "dst_address", ip6);
10371     }
10372   else
10373     {
10374       struct in_addr ip4;
10375
10376       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10377       vat_json_object_add_ip4 (node, "src_address", ip4);
10378       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10379       vat_json_object_add_ip4 (node, "dst_address", ip4);
10380     }
10381   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10382   vat_json_object_add_uint (node, "decap_next_index",
10383                             ntohl (mp->decap_next_index));
10384   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10385   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10386   vat_json_object_add_uint (node, "mcast_sw_if_index",
10387                             ntohl (mp->mcast_sw_if_index));
10388 }
10389
10390 static int
10391 api_vxlan_tunnel_dump (vat_main_t * vam)
10392 {
10393   unformat_input_t *i = vam->input;
10394   vl_api_vxlan_tunnel_dump_t *mp;
10395   f64 timeout;
10396   u32 sw_if_index;
10397   u8 sw_if_index_set = 0;
10398
10399   /* Parse args required to build the message */
10400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10401     {
10402       if (unformat (i, "sw_if_index %d", &sw_if_index))
10403         sw_if_index_set = 1;
10404       else
10405         break;
10406     }
10407
10408   if (sw_if_index_set == 0)
10409     {
10410       sw_if_index = ~0;
10411     }
10412
10413   if (!vam->json_output)
10414     {
10415       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s\n",
10416                "sw_if_index", "src_address", "dst_address",
10417                "encap_vrf_id", "decap_next_index", "vni",
10418                "mcast_sw_if_index");
10419     }
10420
10421   /* Get list of vxlan-tunnel interfaces */
10422   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10423
10424   mp->sw_if_index = htonl (sw_if_index);
10425
10426   S;
10427
10428   /* Use a control ping for synchronization */
10429   {
10430     vl_api_control_ping_t *mp;
10431     M (CONTROL_PING, control_ping);
10432     S;
10433   }
10434   W;
10435 }
10436
10437 static int
10438 api_gre_add_del_tunnel (vat_main_t * vam)
10439 {
10440   unformat_input_t *line_input = vam->input;
10441   vl_api_gre_add_del_tunnel_t *mp;
10442   f64 timeout;
10443   ip4_address_t src4, dst4;
10444   u8 is_add = 1;
10445   u8 teb = 0;
10446   u8 src_set = 0;
10447   u8 dst_set = 0;
10448   u32 outer_fib_id = 0;
10449
10450   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10451     {
10452       if (unformat (line_input, "del"))
10453         is_add = 0;
10454       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10455         src_set = 1;
10456       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10457         dst_set = 1;
10458       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10459         ;
10460       else if (unformat (line_input, "teb"))
10461         teb = 1;
10462       else
10463         {
10464           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10465           return -99;
10466         }
10467     }
10468
10469   if (src_set == 0)
10470     {
10471       errmsg ("tunnel src address not specified\n");
10472       return -99;
10473     }
10474   if (dst_set == 0)
10475     {
10476       errmsg ("tunnel dst address not specified\n");
10477       return -99;
10478     }
10479
10480
10481   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10482
10483   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10484   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10485   mp->outer_fib_id = ntohl (outer_fib_id);
10486   mp->is_add = is_add;
10487   mp->teb = teb;
10488
10489   S;
10490   W;
10491   /* NOTREACHED */
10492   return 0;
10493 }
10494
10495 static void vl_api_gre_tunnel_details_t_handler
10496   (vl_api_gre_tunnel_details_t * mp)
10497 {
10498   vat_main_t *vam = &vat_main;
10499
10500   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10501            ntohl (mp->sw_if_index),
10502            format_ip4_address, &mp->src_address,
10503            format_ip4_address, &mp->dst_address,
10504            mp->teb, ntohl (mp->outer_fib_id));
10505 }
10506
10507 static void vl_api_gre_tunnel_details_t_handler_json
10508   (vl_api_gre_tunnel_details_t * mp)
10509 {
10510   vat_main_t *vam = &vat_main;
10511   vat_json_node_t *node = NULL;
10512   struct in_addr ip4;
10513
10514   if (VAT_JSON_ARRAY != vam->json_tree.type)
10515     {
10516       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10517       vat_json_init_array (&vam->json_tree);
10518     }
10519   node = vat_json_array_add (&vam->json_tree);
10520
10521   vat_json_init_object (node);
10522   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10523   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10524   vat_json_object_add_ip4 (node, "src_address", ip4);
10525   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10526   vat_json_object_add_ip4 (node, "dst_address", ip4);
10527   vat_json_object_add_uint (node, "teb", mp->teb);
10528   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10529 }
10530
10531 static int
10532 api_gre_tunnel_dump (vat_main_t * vam)
10533 {
10534   unformat_input_t *i = vam->input;
10535   vl_api_gre_tunnel_dump_t *mp;
10536   f64 timeout;
10537   u32 sw_if_index;
10538   u8 sw_if_index_set = 0;
10539
10540   /* Parse args required to build the message */
10541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10542     {
10543       if (unformat (i, "sw_if_index %d", &sw_if_index))
10544         sw_if_index_set = 1;
10545       else
10546         break;
10547     }
10548
10549   if (sw_if_index_set == 0)
10550     {
10551       sw_if_index = ~0;
10552     }
10553
10554   if (!vam->json_output)
10555     {
10556       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10557                "sw_if_index", "src_address", "dst_address", "teb",
10558                "outer_fib_id");
10559     }
10560
10561   /* Get list of gre-tunnel interfaces */
10562   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10563
10564   mp->sw_if_index = htonl (sw_if_index);
10565
10566   S;
10567
10568   /* Use a control ping for synchronization */
10569   {
10570     vl_api_control_ping_t *mp;
10571     M (CONTROL_PING, control_ping);
10572     S;
10573   }
10574   W;
10575 }
10576
10577 static int
10578 api_l2_fib_clear_table (vat_main_t * vam)
10579 {
10580 //  unformat_input_t * i = vam->input;
10581   vl_api_l2_fib_clear_table_t *mp;
10582   f64 timeout;
10583
10584   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10585
10586   S;
10587   W;
10588   /* NOTREACHED */
10589   return 0;
10590 }
10591
10592 static int
10593 api_l2_interface_efp_filter (vat_main_t * vam)
10594 {
10595   unformat_input_t *i = vam->input;
10596   vl_api_l2_interface_efp_filter_t *mp;
10597   f64 timeout;
10598   u32 sw_if_index;
10599   u8 enable = 1;
10600   u8 sw_if_index_set = 0;
10601
10602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10603     {
10604       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10605         sw_if_index_set = 1;
10606       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10607         sw_if_index_set = 1;
10608       else if (unformat (i, "enable"))
10609         enable = 1;
10610       else if (unformat (i, "disable"))
10611         enable = 0;
10612       else
10613         {
10614           clib_warning ("parse error '%U'", format_unformat_error, i);
10615           return -99;
10616         }
10617     }
10618
10619   if (sw_if_index_set == 0)
10620     {
10621       errmsg ("missing sw_if_index\n");
10622       return -99;
10623     }
10624
10625   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10626
10627   mp->sw_if_index = ntohl (sw_if_index);
10628   mp->enable_disable = enable;
10629
10630   S;
10631   W;
10632   /* NOTREACHED */
10633   return 0;
10634 }
10635
10636 #define foreach_vtr_op                          \
10637 _("disable",  L2_VTR_DISABLED)                  \
10638 _("push-1",  L2_VTR_PUSH_1)                     \
10639 _("push-2",  L2_VTR_PUSH_2)                     \
10640 _("pop-1",  L2_VTR_POP_1)                       \
10641 _("pop-2",  L2_VTR_POP_2)                       \
10642 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10643 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10644 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10645 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10646
10647 static int
10648 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10649 {
10650   unformat_input_t *i = vam->input;
10651   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10652   f64 timeout;
10653   u32 sw_if_index;
10654   u8 sw_if_index_set = 0;
10655   u8 vtr_op_set = 0;
10656   u32 vtr_op = 0;
10657   u32 push_dot1q = 1;
10658   u32 tag1 = ~0;
10659   u32 tag2 = ~0;
10660
10661   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10662     {
10663       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10664         sw_if_index_set = 1;
10665       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10666         sw_if_index_set = 1;
10667       else if (unformat (i, "vtr_op %d", &vtr_op))
10668         vtr_op_set = 1;
10669 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10670       foreach_vtr_op
10671 #undef _
10672         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10673         ;
10674       else if (unformat (i, "tag1 %d", &tag1))
10675         ;
10676       else if (unformat (i, "tag2 %d", &tag2))
10677         ;
10678       else
10679         {
10680           clib_warning ("parse error '%U'", format_unformat_error, i);
10681           return -99;
10682         }
10683     }
10684
10685   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10686     {
10687       errmsg ("missing vtr operation or sw_if_index\n");
10688       return -99;
10689     }
10690
10691   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10692     mp->sw_if_index = ntohl (sw_if_index);
10693   mp->vtr_op = ntohl (vtr_op);
10694   mp->push_dot1q = ntohl (push_dot1q);
10695   mp->tag1 = ntohl (tag1);
10696   mp->tag2 = ntohl (tag2);
10697
10698   S;
10699   W;
10700   /* NOTREACHED */
10701   return 0;
10702 }
10703
10704 static int
10705 api_create_vhost_user_if (vat_main_t * vam)
10706 {
10707   unformat_input_t *i = vam->input;
10708   vl_api_create_vhost_user_if_t *mp;
10709   f64 timeout;
10710   u8 *file_name;
10711   u8 is_server = 0;
10712   u8 file_name_set = 0;
10713   u32 custom_dev_instance = ~0;
10714   u8 hwaddr[6];
10715   u8 use_custom_mac = 0;
10716   u8 *tag = 0;
10717
10718   /* Shut up coverity */
10719   memset (hwaddr, 0, sizeof (hwaddr));
10720
10721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10722     {
10723       if (unformat (i, "socket %s", &file_name))
10724         {
10725           file_name_set = 1;
10726         }
10727       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10728         ;
10729       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10730         use_custom_mac = 1;
10731       else if (unformat (i, "server"))
10732         is_server = 1;
10733       else if (unformat (i, "tag %s", &tag))
10734         ;
10735       else
10736         break;
10737     }
10738
10739   if (file_name_set == 0)
10740     {
10741       errmsg ("missing socket file name\n");
10742       return -99;
10743     }
10744
10745   if (vec_len (file_name) > 255)
10746     {
10747       errmsg ("socket file name too long\n");
10748       return -99;
10749     }
10750   vec_add1 (file_name, 0);
10751
10752   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10753
10754   mp->is_server = is_server;
10755   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10756   vec_free (file_name);
10757   if (custom_dev_instance != ~0)
10758     {
10759       mp->renumber = 1;
10760       mp->custom_dev_instance = ntohl (custom_dev_instance);
10761     }
10762   mp->use_custom_mac = use_custom_mac;
10763   clib_memcpy (mp->mac_address, hwaddr, 6);
10764   if (tag)
10765     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10766   vec_free (tag);
10767
10768   S;
10769   W;
10770   /* NOTREACHED */
10771   return 0;
10772 }
10773
10774 static int
10775 api_modify_vhost_user_if (vat_main_t * vam)
10776 {
10777   unformat_input_t *i = vam->input;
10778   vl_api_modify_vhost_user_if_t *mp;
10779   f64 timeout;
10780   u8 *file_name;
10781   u8 is_server = 0;
10782   u8 file_name_set = 0;
10783   u32 custom_dev_instance = ~0;
10784   u8 sw_if_index_set = 0;
10785   u32 sw_if_index = (u32) ~ 0;
10786
10787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10788     {
10789       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10790         sw_if_index_set = 1;
10791       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10792         sw_if_index_set = 1;
10793       else if (unformat (i, "socket %s", &file_name))
10794         {
10795           file_name_set = 1;
10796         }
10797       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10798         ;
10799       else if (unformat (i, "server"))
10800         is_server = 1;
10801       else
10802         break;
10803     }
10804
10805   if (sw_if_index_set == 0)
10806     {
10807       errmsg ("missing sw_if_index or interface name\n");
10808       return -99;
10809     }
10810
10811   if (file_name_set == 0)
10812     {
10813       errmsg ("missing socket file name\n");
10814       return -99;
10815     }
10816
10817   if (vec_len (file_name) > 255)
10818     {
10819       errmsg ("socket file name too long\n");
10820       return -99;
10821     }
10822   vec_add1 (file_name, 0);
10823
10824   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10825
10826   mp->sw_if_index = ntohl (sw_if_index);
10827   mp->is_server = is_server;
10828   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10829   vec_free (file_name);
10830   if (custom_dev_instance != ~0)
10831     {
10832       mp->renumber = 1;
10833       mp->custom_dev_instance = ntohl (custom_dev_instance);
10834     }
10835
10836   S;
10837   W;
10838   /* NOTREACHED */
10839   return 0;
10840 }
10841
10842 static int
10843 api_delete_vhost_user_if (vat_main_t * vam)
10844 {
10845   unformat_input_t *i = vam->input;
10846   vl_api_delete_vhost_user_if_t *mp;
10847   f64 timeout;
10848   u32 sw_if_index = ~0;
10849   u8 sw_if_index_set = 0;
10850
10851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10852     {
10853       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10854         sw_if_index_set = 1;
10855       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10856         sw_if_index_set = 1;
10857       else
10858         break;
10859     }
10860
10861   if (sw_if_index_set == 0)
10862     {
10863       errmsg ("missing sw_if_index or interface name\n");
10864       return -99;
10865     }
10866
10867
10868   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10869
10870   mp->sw_if_index = ntohl (sw_if_index);
10871
10872   S;
10873   W;
10874   /* NOTREACHED */
10875   return 0;
10876 }
10877
10878 static void vl_api_sw_interface_vhost_user_details_t_handler
10879   (vl_api_sw_interface_vhost_user_details_t * mp)
10880 {
10881   vat_main_t *vam = &vat_main;
10882
10883   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10884            (char *) mp->interface_name,
10885            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10886            clib_net_to_host_u64 (mp->features), mp->is_server,
10887            ntohl (mp->num_regions), (char *) mp->sock_filename);
10888   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10889 }
10890
10891 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10892   (vl_api_sw_interface_vhost_user_details_t * mp)
10893 {
10894   vat_main_t *vam = &vat_main;
10895   vat_json_node_t *node = NULL;
10896
10897   if (VAT_JSON_ARRAY != vam->json_tree.type)
10898     {
10899       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10900       vat_json_init_array (&vam->json_tree);
10901     }
10902   node = vat_json_array_add (&vam->json_tree);
10903
10904   vat_json_init_object (node);
10905   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10906   vat_json_object_add_string_copy (node, "interface_name",
10907                                    mp->interface_name);
10908   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10909                             ntohl (mp->virtio_net_hdr_sz));
10910   vat_json_object_add_uint (node, "features",
10911                             clib_net_to_host_u64 (mp->features));
10912   vat_json_object_add_uint (node, "is_server", mp->is_server);
10913   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10914   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10915   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10916 }
10917
10918 static int
10919 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10920 {
10921   vl_api_sw_interface_vhost_user_dump_t *mp;
10922   f64 timeout;
10923   fformat (vam->ofp,
10924            "Interface name           idx hdr_sz features server regions filename\n");
10925
10926   /* Get list of vhost-user interfaces */
10927   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10928   S;
10929
10930   /* Use a control ping for synchronization */
10931   {
10932     vl_api_control_ping_t *mp;
10933     M (CONTROL_PING, control_ping);
10934     S;
10935   }
10936   W;
10937 }
10938
10939 static int
10940 api_show_version (vat_main_t * vam)
10941 {
10942   vl_api_show_version_t *mp;
10943   f64 timeout;
10944
10945   M (SHOW_VERSION, show_version);
10946
10947   S;
10948   W;
10949   /* NOTREACHED */
10950   return 0;
10951 }
10952
10953
10954 static int
10955 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10956 {
10957   unformat_input_t *line_input = vam->input;
10958   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10959   f64 timeout;
10960   ip4_address_t local4, remote4;
10961   ip6_address_t local6, remote6;
10962   u8 is_add = 1;
10963   u8 ipv4_set = 0, ipv6_set = 0;
10964   u8 local_set = 0;
10965   u8 remote_set = 0;
10966   u32 encap_vrf_id = 0;
10967   u32 decap_vrf_id = 0;
10968   u8 protocol = ~0;
10969   u32 vni;
10970   u8 vni_set = 0;
10971
10972   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10973     {
10974       if (unformat (line_input, "del"))
10975         is_add = 0;
10976       else if (unformat (line_input, "local %U",
10977                          unformat_ip4_address, &local4))
10978         {
10979           local_set = 1;
10980           ipv4_set = 1;
10981         }
10982       else if (unformat (line_input, "remote %U",
10983                          unformat_ip4_address, &remote4))
10984         {
10985           remote_set = 1;
10986           ipv4_set = 1;
10987         }
10988       else if (unformat (line_input, "local %U",
10989                          unformat_ip6_address, &local6))
10990         {
10991           local_set = 1;
10992           ipv6_set = 1;
10993         }
10994       else if (unformat (line_input, "remote %U",
10995                          unformat_ip6_address, &remote6))
10996         {
10997           remote_set = 1;
10998           ipv6_set = 1;
10999         }
11000       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11001         ;
11002       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11003         ;
11004       else if (unformat (line_input, "vni %d", &vni))
11005         vni_set = 1;
11006       else if (unformat (line_input, "next-ip4"))
11007         protocol = 1;
11008       else if (unformat (line_input, "next-ip6"))
11009         protocol = 2;
11010       else if (unformat (line_input, "next-ethernet"))
11011         protocol = 3;
11012       else if (unformat (line_input, "next-nsh"))
11013         protocol = 4;
11014       else
11015         {
11016           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
11017           return -99;
11018         }
11019     }
11020
11021   if (local_set == 0)
11022     {
11023       errmsg ("tunnel local address not specified\n");
11024       return -99;
11025     }
11026   if (remote_set == 0)
11027     {
11028       errmsg ("tunnel remote address not specified\n");
11029       return -99;
11030     }
11031   if (ipv4_set && ipv6_set)
11032     {
11033       errmsg ("both IPv4 and IPv6 addresses specified");
11034       return -99;
11035     }
11036
11037   if (vni_set == 0)
11038     {
11039       errmsg ("vni not specified\n");
11040       return -99;
11041     }
11042
11043   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
11044
11045
11046   if (ipv6_set)
11047     {
11048       clib_memcpy (&mp->local, &local6, sizeof (local6));
11049       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11050     }
11051   else
11052     {
11053       clib_memcpy (&mp->local, &local4, sizeof (local4));
11054       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11055     }
11056
11057   mp->encap_vrf_id = ntohl (encap_vrf_id);
11058   mp->decap_vrf_id = ntohl (decap_vrf_id);
11059   mp->protocol = ntohl (protocol);
11060   mp->vni = ntohl (vni);
11061   mp->is_add = is_add;
11062   mp->is_ipv6 = ipv6_set;
11063
11064   S;
11065   W;
11066   /* NOTREACHED */
11067   return 0;
11068 }
11069
11070 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11071   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11072 {
11073   vat_main_t *vam = &vat_main;
11074
11075   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
11076            ntohl (mp->sw_if_index),
11077            format_ip46_address, &(mp->local[0]),
11078            format_ip46_address, &(mp->remote[0]),
11079            ntohl (mp->vni),
11080            ntohl (mp->protocol),
11081            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11082 }
11083
11084 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11085   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11086 {
11087   vat_main_t *vam = &vat_main;
11088   vat_json_node_t *node = NULL;
11089   struct in_addr ip4;
11090   struct in6_addr ip6;
11091
11092   if (VAT_JSON_ARRAY != vam->json_tree.type)
11093     {
11094       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11095       vat_json_init_array (&vam->json_tree);
11096     }
11097   node = vat_json_array_add (&vam->json_tree);
11098
11099   vat_json_init_object (node);
11100   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11101   if (mp->is_ipv6)
11102     {
11103       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11104       vat_json_object_add_ip6 (node, "local", ip6);
11105       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11106       vat_json_object_add_ip6 (node, "remote", ip6);
11107     }
11108   else
11109     {
11110       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11111       vat_json_object_add_ip4 (node, "local", ip4);
11112       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11113       vat_json_object_add_ip4 (node, "remote", ip4);
11114     }
11115   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11116   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11117   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11118   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11119   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11120 }
11121
11122 static int
11123 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11124 {
11125   unformat_input_t *i = vam->input;
11126   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11127   f64 timeout;
11128   u32 sw_if_index;
11129   u8 sw_if_index_set = 0;
11130
11131   /* Parse args required to build the message */
11132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11133     {
11134       if (unformat (i, "sw_if_index %d", &sw_if_index))
11135         sw_if_index_set = 1;
11136       else
11137         break;
11138     }
11139
11140   if (sw_if_index_set == 0)
11141     {
11142       sw_if_index = ~0;
11143     }
11144
11145   if (!vam->json_output)
11146     {
11147       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
11148                "sw_if_index", "local", "remote", "vni",
11149                "protocol", "encap_vrf_id", "decap_vrf_id");
11150     }
11151
11152   /* Get list of vxlan-tunnel interfaces */
11153   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11154
11155   mp->sw_if_index = htonl (sw_if_index);
11156
11157   S;
11158
11159   /* Use a control ping for synchronization */
11160   {
11161     vl_api_control_ping_t *mp;
11162     M (CONTROL_PING, control_ping);
11163     S;
11164   }
11165   W;
11166 }
11167
11168 u8 *
11169 format_l2_fib_mac_address (u8 * s, va_list * args)
11170 {
11171   u8 *a = va_arg (*args, u8 *);
11172
11173   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11174                  a[2], a[3], a[4], a[5], a[6], a[7]);
11175 }
11176
11177 static void vl_api_l2_fib_table_entry_t_handler
11178   (vl_api_l2_fib_table_entry_t * mp)
11179 {
11180   vat_main_t *vam = &vat_main;
11181
11182   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11183            "       %d       %d     %d\n",
11184            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11185            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11186            mp->bvi_mac);
11187 }
11188
11189 static void vl_api_l2_fib_table_entry_t_handler_json
11190   (vl_api_l2_fib_table_entry_t * mp)
11191 {
11192   vat_main_t *vam = &vat_main;
11193   vat_json_node_t *node = NULL;
11194
11195   if (VAT_JSON_ARRAY != vam->json_tree.type)
11196     {
11197       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11198       vat_json_init_array (&vam->json_tree);
11199     }
11200   node = vat_json_array_add (&vam->json_tree);
11201
11202   vat_json_init_object (node);
11203   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11204   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11205   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11206   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11207   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11208   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11209 }
11210
11211 static int
11212 api_l2_fib_table_dump (vat_main_t * vam)
11213 {
11214   unformat_input_t *i = vam->input;
11215   vl_api_l2_fib_table_dump_t *mp;
11216   f64 timeout;
11217   u32 bd_id;
11218   u8 bd_id_set = 0;
11219
11220   /* Parse args required to build the message */
11221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11222     {
11223       if (unformat (i, "bd_id %d", &bd_id))
11224         bd_id_set = 1;
11225       else
11226         break;
11227     }
11228
11229   if (bd_id_set == 0)
11230     {
11231       errmsg ("missing bridge domain\n");
11232       return -99;
11233     }
11234
11235   fformat (vam->ofp,
11236            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11237
11238   /* Get list of l2 fib entries */
11239   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11240
11241   mp->bd_id = ntohl (bd_id);
11242   S;
11243
11244   /* Use a control ping for synchronization */
11245   {
11246     vl_api_control_ping_t *mp;
11247     M (CONTROL_PING, control_ping);
11248     S;
11249   }
11250   W;
11251 }
11252
11253
11254 static int
11255 api_interface_name_renumber (vat_main_t * vam)
11256 {
11257   unformat_input_t *line_input = vam->input;
11258   vl_api_interface_name_renumber_t *mp;
11259   u32 sw_if_index = ~0;
11260   f64 timeout;
11261   u32 new_show_dev_instance = ~0;
11262
11263   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11264     {
11265       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11266                     &sw_if_index))
11267         ;
11268       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11269         ;
11270       else if (unformat (line_input, "new_show_dev_instance %d",
11271                          &new_show_dev_instance))
11272         ;
11273       else
11274         break;
11275     }
11276
11277   if (sw_if_index == ~0)
11278     {
11279       errmsg ("missing interface name or sw_if_index\n");
11280       return -99;
11281     }
11282
11283   if (new_show_dev_instance == ~0)
11284     {
11285       errmsg ("missing new_show_dev_instance\n");
11286       return -99;
11287     }
11288
11289   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11290
11291   mp->sw_if_index = ntohl (sw_if_index);
11292   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11293
11294   S;
11295   W;
11296 }
11297
11298 static int
11299 api_want_ip4_arp_events (vat_main_t * vam)
11300 {
11301   unformat_input_t *line_input = vam->input;
11302   vl_api_want_ip4_arp_events_t *mp;
11303   f64 timeout;
11304   ip4_address_t address;
11305   int address_set = 0;
11306   u32 enable_disable = 1;
11307
11308   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11309     {
11310       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11311         address_set = 1;
11312       else if (unformat (line_input, "del"))
11313         enable_disable = 0;
11314       else
11315         break;
11316     }
11317
11318   if (address_set == 0)
11319     {
11320       errmsg ("missing addresses\n");
11321       return -99;
11322     }
11323
11324   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11325   mp->enable_disable = enable_disable;
11326   mp->pid = getpid ();
11327   mp->address = address.as_u32;
11328
11329   S;
11330   W;
11331 }
11332
11333 static int
11334 api_want_ip6_nd_events (vat_main_t * vam)
11335 {
11336   unformat_input_t *line_input = vam->input;
11337   vl_api_want_ip6_nd_events_t *mp;
11338   f64 timeout;
11339   ip6_address_t address;
11340   int address_set = 0;
11341   u32 enable_disable = 1;
11342
11343   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11344     {
11345       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11346         address_set = 1;
11347       else if (unformat (line_input, "del"))
11348         enable_disable = 0;
11349       else
11350         break;
11351     }
11352
11353   if (address_set == 0)
11354     {
11355       errmsg ("missing addresses\n");
11356       return -99;
11357     }
11358
11359   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11360   mp->enable_disable = enable_disable;
11361   mp->pid = getpid ();
11362   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11363
11364   S;
11365   W;
11366 }
11367
11368 static int
11369 api_input_acl_set_interface (vat_main_t * vam)
11370 {
11371   unformat_input_t *i = vam->input;
11372   vl_api_input_acl_set_interface_t *mp;
11373   f64 timeout;
11374   u32 sw_if_index;
11375   int sw_if_index_set;
11376   u32 ip4_table_index = ~0;
11377   u32 ip6_table_index = ~0;
11378   u32 l2_table_index = ~0;
11379   u8 is_add = 1;
11380
11381   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11382     {
11383       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11384         sw_if_index_set = 1;
11385       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11386         sw_if_index_set = 1;
11387       else if (unformat (i, "del"))
11388         is_add = 0;
11389       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11390         ;
11391       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11392         ;
11393       else if (unformat (i, "l2-table %d", &l2_table_index))
11394         ;
11395       else
11396         {
11397           clib_warning ("parse error '%U'", format_unformat_error, i);
11398           return -99;
11399         }
11400     }
11401
11402   if (sw_if_index_set == 0)
11403     {
11404       errmsg ("missing interface name or sw_if_index\n");
11405       return -99;
11406     }
11407
11408   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11409
11410   mp->sw_if_index = ntohl (sw_if_index);
11411   mp->ip4_table_index = ntohl (ip4_table_index);
11412   mp->ip6_table_index = ntohl (ip6_table_index);
11413   mp->l2_table_index = ntohl (l2_table_index);
11414   mp->is_add = is_add;
11415
11416   S;
11417   W;
11418   /* NOTREACHED */
11419   return 0;
11420 }
11421
11422 static int
11423 api_ip_address_dump (vat_main_t * vam)
11424 {
11425   unformat_input_t *i = vam->input;
11426   vl_api_ip_address_dump_t *mp;
11427   u32 sw_if_index = ~0;
11428   u8 sw_if_index_set = 0;
11429   u8 ipv4_set = 0;
11430   u8 ipv6_set = 0;
11431   f64 timeout;
11432
11433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11434     {
11435       if (unformat (i, "sw_if_index %d", &sw_if_index))
11436         sw_if_index_set = 1;
11437       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11438         sw_if_index_set = 1;
11439       else if (unformat (i, "ipv4"))
11440         ipv4_set = 1;
11441       else if (unformat (i, "ipv6"))
11442         ipv6_set = 1;
11443       else
11444         break;
11445     }
11446
11447   if (ipv4_set && ipv6_set)
11448     {
11449       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11450       return -99;
11451     }
11452
11453   if ((!ipv4_set) && (!ipv6_set))
11454     {
11455       errmsg ("no ipv4 nor ipv6 flag set\n");
11456       return -99;
11457     }
11458
11459   if (sw_if_index_set == 0)
11460     {
11461       errmsg ("missing interface name or sw_if_index\n");
11462       return -99;
11463     }
11464
11465   vam->current_sw_if_index = sw_if_index;
11466   vam->is_ipv6 = ipv6_set;
11467
11468   M (IP_ADDRESS_DUMP, ip_address_dump);
11469   mp->sw_if_index = ntohl (sw_if_index);
11470   mp->is_ipv6 = ipv6_set;
11471   S;
11472
11473   /* Use a control ping for synchronization */
11474   {
11475     vl_api_control_ping_t *mp;
11476     M (CONTROL_PING, control_ping);
11477     S;
11478   }
11479   W;
11480 }
11481
11482 static int
11483 api_ip_dump (vat_main_t * vam)
11484 {
11485   vl_api_ip_dump_t *mp;
11486   unformat_input_t *in = vam->input;
11487   int ipv4_set = 0;
11488   int ipv6_set = 0;
11489   int is_ipv6;
11490   f64 timeout;
11491   int i;
11492
11493   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11494     {
11495       if (unformat (in, "ipv4"))
11496         ipv4_set = 1;
11497       else if (unformat (in, "ipv6"))
11498         ipv6_set = 1;
11499       else
11500         break;
11501     }
11502
11503   if (ipv4_set && ipv6_set)
11504     {
11505       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11506       return -99;
11507     }
11508
11509   if ((!ipv4_set) && (!ipv6_set))
11510     {
11511       errmsg ("no ipv4 nor ipv6 flag set\n");
11512       return -99;
11513     }
11514
11515   is_ipv6 = ipv6_set;
11516   vam->is_ipv6 = is_ipv6;
11517
11518   /* free old data */
11519   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11520     {
11521       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11522     }
11523   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11524
11525   M (IP_DUMP, ip_dump);
11526   mp->is_ipv6 = ipv6_set;
11527   S;
11528
11529   /* Use a control ping for synchronization */
11530   {
11531     vl_api_control_ping_t *mp;
11532     M (CONTROL_PING, control_ping);
11533     S;
11534   }
11535   W;
11536 }
11537
11538 static int
11539 api_ipsec_spd_add_del (vat_main_t * vam)
11540 {
11541   unformat_input_t *i = vam->input;
11542   vl_api_ipsec_spd_add_del_t *mp;
11543   f64 timeout;
11544   u32 spd_id = ~0;
11545   u8 is_add = 1;
11546
11547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11548     {
11549       if (unformat (i, "spd_id %d", &spd_id))
11550         ;
11551       else if (unformat (i, "del"))
11552         is_add = 0;
11553       else
11554         {
11555           clib_warning ("parse error '%U'", format_unformat_error, i);
11556           return -99;
11557         }
11558     }
11559   if (spd_id == ~0)
11560     {
11561       errmsg ("spd_id must be set\n");
11562       return -99;
11563     }
11564
11565   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11566
11567   mp->spd_id = ntohl (spd_id);
11568   mp->is_add = is_add;
11569
11570   S;
11571   W;
11572   /* NOTREACHED */
11573   return 0;
11574 }
11575
11576 static int
11577 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11578 {
11579   unformat_input_t *i = vam->input;
11580   vl_api_ipsec_interface_add_del_spd_t *mp;
11581   f64 timeout;
11582   u32 sw_if_index;
11583   u8 sw_if_index_set = 0;
11584   u32 spd_id = (u32) ~ 0;
11585   u8 is_add = 1;
11586
11587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11588     {
11589       if (unformat (i, "del"))
11590         is_add = 0;
11591       else if (unformat (i, "spd_id %d", &spd_id))
11592         ;
11593       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11594         sw_if_index_set = 1;
11595       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11596         sw_if_index_set = 1;
11597       else
11598         {
11599           clib_warning ("parse error '%U'", format_unformat_error, i);
11600           return -99;
11601         }
11602
11603     }
11604
11605   if (spd_id == (u32) ~ 0)
11606     {
11607       errmsg ("spd_id must be set\n");
11608       return -99;
11609     }
11610
11611   if (sw_if_index_set == 0)
11612     {
11613       errmsg ("missing interface name or sw_if_index\n");
11614       return -99;
11615     }
11616
11617   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11618
11619   mp->spd_id = ntohl (spd_id);
11620   mp->sw_if_index = ntohl (sw_if_index);
11621   mp->is_add = is_add;
11622
11623   S;
11624   W;
11625   /* NOTREACHED */
11626   return 0;
11627 }
11628
11629 static int
11630 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11631 {
11632   unformat_input_t *i = vam->input;
11633   vl_api_ipsec_spd_add_del_entry_t *mp;
11634   f64 timeout;
11635   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11636   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11637   i32 priority = 0;
11638   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11639   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11640   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11641   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11642
11643   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11644   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11645   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11646   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11647   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11648   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11649
11650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11651     {
11652       if (unformat (i, "del"))
11653         is_add = 0;
11654       if (unformat (i, "outbound"))
11655         is_outbound = 1;
11656       if (unformat (i, "inbound"))
11657         is_outbound = 0;
11658       else if (unformat (i, "spd_id %d", &spd_id))
11659         ;
11660       else if (unformat (i, "sa_id %d", &sa_id))
11661         ;
11662       else if (unformat (i, "priority %d", &priority))
11663         ;
11664       else if (unformat (i, "protocol %d", &protocol))
11665         ;
11666       else if (unformat (i, "lport_start %d", &lport_start))
11667         ;
11668       else if (unformat (i, "lport_stop %d", &lport_stop))
11669         ;
11670       else if (unformat (i, "rport_start %d", &rport_start))
11671         ;
11672       else if (unformat (i, "rport_stop %d", &rport_stop))
11673         ;
11674       else
11675         if (unformat
11676             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11677         {
11678           is_ipv6 = 0;
11679           is_ip_any = 0;
11680         }
11681       else
11682         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11683         {
11684           is_ipv6 = 0;
11685           is_ip_any = 0;
11686         }
11687       else
11688         if (unformat
11689             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11690         {
11691           is_ipv6 = 0;
11692           is_ip_any = 0;
11693         }
11694       else
11695         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11696         {
11697           is_ipv6 = 0;
11698           is_ip_any = 0;
11699         }
11700       else
11701         if (unformat
11702             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11703         {
11704           is_ipv6 = 1;
11705           is_ip_any = 0;
11706         }
11707       else
11708         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11709         {
11710           is_ipv6 = 1;
11711           is_ip_any = 0;
11712         }
11713       else
11714         if (unformat
11715             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11716         {
11717           is_ipv6 = 1;
11718           is_ip_any = 0;
11719         }
11720       else
11721         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11722         {
11723           is_ipv6 = 1;
11724           is_ip_any = 0;
11725         }
11726       else
11727         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11728         {
11729           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11730             {
11731               clib_warning ("unsupported action: 'resolve'");
11732               return -99;
11733             }
11734         }
11735       else
11736         {
11737           clib_warning ("parse error '%U'", format_unformat_error, i);
11738           return -99;
11739         }
11740
11741     }
11742
11743   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11744
11745   mp->spd_id = ntohl (spd_id);
11746   mp->priority = ntohl (priority);
11747   mp->is_outbound = is_outbound;
11748
11749   mp->is_ipv6 = is_ipv6;
11750   if (is_ipv6 || is_ip_any)
11751     {
11752       clib_memcpy (mp->remote_address_start, &raddr6_start,
11753                    sizeof (ip6_address_t));
11754       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11755                    sizeof (ip6_address_t));
11756       clib_memcpy (mp->local_address_start, &laddr6_start,
11757                    sizeof (ip6_address_t));
11758       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11759                    sizeof (ip6_address_t));
11760     }
11761   else
11762     {
11763       clib_memcpy (mp->remote_address_start, &raddr4_start,
11764                    sizeof (ip4_address_t));
11765       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11766                    sizeof (ip4_address_t));
11767       clib_memcpy (mp->local_address_start, &laddr4_start,
11768                    sizeof (ip4_address_t));
11769       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11770                    sizeof (ip4_address_t));
11771     }
11772   mp->protocol = (u8) protocol;
11773   mp->local_port_start = ntohs ((u16) lport_start);
11774   mp->local_port_stop = ntohs ((u16) lport_stop);
11775   mp->remote_port_start = ntohs ((u16) rport_start);
11776   mp->remote_port_stop = ntohs ((u16) rport_stop);
11777   mp->policy = (u8) policy;
11778   mp->sa_id = ntohl (sa_id);
11779   mp->is_add = is_add;
11780   mp->is_ip_any = is_ip_any;
11781   S;
11782   W;
11783   /* NOTREACHED */
11784   return 0;
11785 }
11786
11787 static int
11788 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11789 {
11790   unformat_input_t *i = vam->input;
11791   vl_api_ipsec_sad_add_del_entry_t *mp;
11792   f64 timeout;
11793   u32 sad_id = 0, spi = 0;
11794   u8 *ck = 0, *ik = 0;
11795   u8 is_add = 1;
11796
11797   u8 protocol = IPSEC_PROTOCOL_AH;
11798   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11799   u32 crypto_alg = 0, integ_alg = 0;
11800   ip4_address_t tun_src4;
11801   ip4_address_t tun_dst4;
11802   ip6_address_t tun_src6;
11803   ip6_address_t tun_dst6;
11804
11805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11806     {
11807       if (unformat (i, "del"))
11808         is_add = 0;
11809       else if (unformat (i, "sad_id %d", &sad_id))
11810         ;
11811       else if (unformat (i, "spi %d", &spi))
11812         ;
11813       else if (unformat (i, "esp"))
11814         protocol = IPSEC_PROTOCOL_ESP;
11815       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11816         {
11817           is_tunnel = 1;
11818           is_tunnel_ipv6 = 0;
11819         }
11820       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11821         {
11822           is_tunnel = 1;
11823           is_tunnel_ipv6 = 0;
11824         }
11825       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11826         {
11827           is_tunnel = 1;
11828           is_tunnel_ipv6 = 1;
11829         }
11830       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11831         {
11832           is_tunnel = 1;
11833           is_tunnel_ipv6 = 1;
11834         }
11835       else
11836         if (unformat
11837             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11838         {
11839           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11840               crypto_alg >= IPSEC_CRYPTO_N_ALG)
11841             {
11842               clib_warning ("unsupported crypto-alg: '%U'",
11843                             format_ipsec_crypto_alg, crypto_alg);
11844               return -99;
11845             }
11846         }
11847       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11848         ;
11849       else
11850         if (unformat
11851             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11852         {
11853 #if DPDK_CRYPTO==1
11854           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
11855 #else
11856           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11857 #endif
11858               integ_alg >= IPSEC_INTEG_N_ALG)
11859             {
11860               clib_warning ("unsupported integ-alg: '%U'",
11861                             format_ipsec_integ_alg, integ_alg);
11862               return -99;
11863             }
11864         }
11865       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11866         ;
11867       else
11868         {
11869           clib_warning ("parse error '%U'", format_unformat_error, i);
11870           return -99;
11871         }
11872
11873     }
11874
11875 #if DPDK_CRYPTO==1
11876   /*Special cases, aes-gcm-128 encryption */
11877   if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
11878     {
11879       if (integ_alg != IPSEC_INTEG_ALG_NONE
11880           && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
11881         {
11882           clib_warning
11883             ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
11884           return -99;
11885         }
11886       else                      /*set integ-alg internally to aes-gcm-128 */
11887         integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
11888     }
11889   else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
11890     {
11891       clib_warning ("unsupported integ-alg: aes-gcm-128");
11892       return -99;
11893     }
11894   else if (integ_alg == IPSEC_INTEG_ALG_NONE)
11895     {
11896       clib_warning ("unsupported integ-alg: none");
11897       return -99;
11898     }
11899 #endif
11900
11901
11902   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11903
11904   mp->sad_id = ntohl (sad_id);
11905   mp->is_add = is_add;
11906   mp->protocol = protocol;
11907   mp->spi = ntohl (spi);
11908   mp->is_tunnel = is_tunnel;
11909   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11910   mp->crypto_algorithm = crypto_alg;
11911   mp->integrity_algorithm = integ_alg;
11912   mp->crypto_key_length = vec_len (ck);
11913   mp->integrity_key_length = vec_len (ik);
11914
11915   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11916     mp->crypto_key_length = sizeof (mp->crypto_key);
11917
11918   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11919     mp->integrity_key_length = sizeof (mp->integrity_key);
11920
11921   if (ck)
11922     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11923   if (ik)
11924     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11925
11926   if (is_tunnel)
11927     {
11928       if (is_tunnel_ipv6)
11929         {
11930           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11931                        sizeof (ip6_address_t));
11932           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11933                        sizeof (ip6_address_t));
11934         }
11935       else
11936         {
11937           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11938                        sizeof (ip4_address_t));
11939           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11940                        sizeof (ip4_address_t));
11941         }
11942     }
11943
11944   S;
11945   W;
11946   /* NOTREACHED */
11947   return 0;
11948 }
11949
11950 static int
11951 api_ipsec_sa_set_key (vat_main_t * vam)
11952 {
11953   unformat_input_t *i = vam->input;
11954   vl_api_ipsec_sa_set_key_t *mp;
11955   f64 timeout;
11956   u32 sa_id;
11957   u8 *ck = 0, *ik = 0;
11958
11959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11960     {
11961       if (unformat (i, "sa_id %d", &sa_id))
11962         ;
11963       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11964         ;
11965       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11966         ;
11967       else
11968         {
11969           clib_warning ("parse error '%U'", format_unformat_error, i);
11970           return -99;
11971         }
11972     }
11973
11974   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11975
11976   mp->sa_id = ntohl (sa_id);
11977   mp->crypto_key_length = vec_len (ck);
11978   mp->integrity_key_length = vec_len (ik);
11979
11980   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11981     mp->crypto_key_length = sizeof (mp->crypto_key);
11982
11983   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11984     mp->integrity_key_length = sizeof (mp->integrity_key);
11985
11986   if (ck)
11987     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11988   if (ik)
11989     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11990
11991   S;
11992   W;
11993   /* NOTREACHED */
11994   return 0;
11995 }
11996
11997 static int
11998 api_ikev2_profile_add_del (vat_main_t * vam)
11999 {
12000   unformat_input_t *i = vam->input;
12001   vl_api_ikev2_profile_add_del_t *mp;
12002   f64 timeout;
12003   u8 is_add = 1;
12004   u8 *name = 0;
12005
12006   const char *valid_chars = "a-zA-Z0-9_";
12007
12008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12009     {
12010       if (unformat (i, "del"))
12011         is_add = 0;
12012       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12013         vec_add1 (name, 0);
12014       else
12015         {
12016           errmsg ("parse error '%U'", format_unformat_error, i);
12017           return -99;
12018         }
12019     }
12020
12021   if (!vec_len (name))
12022     {
12023       errmsg ("profile name must be specified");
12024       return -99;
12025     }
12026
12027   if (vec_len (name) > 64)
12028     {
12029       errmsg ("profile name too long");
12030       return -99;
12031     }
12032
12033   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12034
12035   clib_memcpy (mp->name, name, vec_len (name));
12036   mp->is_add = is_add;
12037   vec_free (name);
12038
12039   S;
12040   W;
12041   /* NOTREACHED */
12042   return 0;
12043 }
12044
12045 static int
12046 api_ikev2_profile_set_auth (vat_main_t * vam)
12047 {
12048   unformat_input_t *i = vam->input;
12049   vl_api_ikev2_profile_set_auth_t *mp;
12050   f64 timeout;
12051   u8 *name = 0;
12052   u8 *data = 0;
12053   u32 auth_method = 0;
12054   u8 is_hex = 0;
12055
12056   const char *valid_chars = "a-zA-Z0-9_";
12057
12058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12059     {
12060       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12061         vec_add1 (name, 0);
12062       else if (unformat (i, "auth_method %U",
12063                          unformat_ikev2_auth_method, &auth_method))
12064         ;
12065       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12066         is_hex = 1;
12067       else if (unformat (i, "auth_data %v", &data))
12068         ;
12069       else
12070         {
12071           errmsg ("parse error '%U'", format_unformat_error, i);
12072           return -99;
12073         }
12074     }
12075
12076   if (!vec_len (name))
12077     {
12078       errmsg ("profile name must be specified");
12079       return -99;
12080     }
12081
12082   if (vec_len (name) > 64)
12083     {
12084       errmsg ("profile name too long");
12085       return -99;
12086     }
12087
12088   if (!vec_len (data))
12089     {
12090       errmsg ("auth_data must be specified");
12091       return -99;
12092     }
12093
12094   if (!auth_method)
12095     {
12096       errmsg ("auth_method must be specified");
12097       return -99;
12098     }
12099
12100   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12101
12102   mp->is_hex = is_hex;
12103   mp->auth_method = (u8) auth_method;
12104   mp->data_len = vec_len (data);
12105   clib_memcpy (mp->name, name, vec_len (name));
12106   clib_memcpy (mp->data, data, vec_len (data));
12107   vec_free (name);
12108   vec_free (data);
12109
12110   S;
12111   W;
12112   /* NOTREACHED */
12113   return 0;
12114 }
12115
12116 static int
12117 api_ikev2_profile_set_id (vat_main_t * vam)
12118 {
12119   unformat_input_t *i = vam->input;
12120   vl_api_ikev2_profile_set_id_t *mp;
12121   f64 timeout;
12122   u8 *name = 0;
12123   u8 *data = 0;
12124   u8 is_local = 0;
12125   u32 id_type = 0;
12126   ip4_address_t ip4;
12127
12128   const char *valid_chars = "a-zA-Z0-9_";
12129
12130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12131     {
12132       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12133         vec_add1 (name, 0);
12134       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12135         ;
12136       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12137         {
12138           data = vec_new (u8, 4);
12139           clib_memcpy (data, ip4.as_u8, 4);
12140         }
12141       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12142         ;
12143       else if (unformat (i, "id_data %v", &data))
12144         ;
12145       else if (unformat (i, "local"))
12146         is_local = 1;
12147       else if (unformat (i, "remote"))
12148         is_local = 0;
12149       else
12150         {
12151           errmsg ("parse error '%U'", format_unformat_error, i);
12152           return -99;
12153         }
12154     }
12155
12156   if (!vec_len (name))
12157     {
12158       errmsg ("profile name must be specified");
12159       return -99;
12160     }
12161
12162   if (vec_len (name) > 64)
12163     {
12164       errmsg ("profile name too long");
12165       return -99;
12166     }
12167
12168   if (!vec_len (data))
12169     {
12170       errmsg ("id_data must be specified");
12171       return -99;
12172     }
12173
12174   if (!id_type)
12175     {
12176       errmsg ("id_type must be specified");
12177       return -99;
12178     }
12179
12180   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12181
12182   mp->is_local = is_local;
12183   mp->id_type = (u8) id_type;
12184   mp->data_len = vec_len (data);
12185   clib_memcpy (mp->name, name, vec_len (name));
12186   clib_memcpy (mp->data, data, vec_len (data));
12187   vec_free (name);
12188   vec_free (data);
12189
12190   S;
12191   W;
12192   /* NOTREACHED */
12193   return 0;
12194 }
12195
12196 static int
12197 api_ikev2_profile_set_ts (vat_main_t * vam)
12198 {
12199   unformat_input_t *i = vam->input;
12200   vl_api_ikev2_profile_set_ts_t *mp;
12201   f64 timeout;
12202   u8 *name = 0;
12203   u8 is_local = 0;
12204   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12205   ip4_address_t start_addr, end_addr;
12206
12207   const char *valid_chars = "a-zA-Z0-9_";
12208
12209   start_addr.as_u32 = 0;
12210   end_addr.as_u32 = (u32) ~ 0;
12211
12212   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12213     {
12214       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12215         vec_add1 (name, 0);
12216       else if (unformat (i, "protocol %d", &proto))
12217         ;
12218       else if (unformat (i, "start_port %d", &start_port))
12219         ;
12220       else if (unformat (i, "end_port %d", &end_port))
12221         ;
12222       else
12223         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12224         ;
12225       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12226         ;
12227       else if (unformat (i, "local"))
12228         is_local = 1;
12229       else if (unformat (i, "remote"))
12230         is_local = 0;
12231       else
12232         {
12233           errmsg ("parse error '%U'", format_unformat_error, i);
12234           return -99;
12235         }
12236     }
12237
12238   if (!vec_len (name))
12239     {
12240       errmsg ("profile name must be specified");
12241       return -99;
12242     }
12243
12244   if (vec_len (name) > 64)
12245     {
12246       errmsg ("profile name too long");
12247       return -99;
12248     }
12249
12250   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12251
12252   mp->is_local = is_local;
12253   mp->proto = (u8) proto;
12254   mp->start_port = (u16) start_port;
12255   mp->end_port = (u16) end_port;
12256   mp->start_addr = start_addr.as_u32;
12257   mp->end_addr = end_addr.as_u32;
12258   clib_memcpy (mp->name, name, vec_len (name));
12259   vec_free (name);
12260
12261   S;
12262   W;
12263   /* NOTREACHED */
12264   return 0;
12265 }
12266
12267 static int
12268 api_ikev2_set_local_key (vat_main_t * vam)
12269 {
12270   unformat_input_t *i = vam->input;
12271   vl_api_ikev2_set_local_key_t *mp;
12272   f64 timeout;
12273   u8 *file = 0;
12274
12275   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12276     {
12277       if (unformat (i, "file %v", &file))
12278         vec_add1 (file, 0);
12279       else
12280         {
12281           errmsg ("parse error '%U'", format_unformat_error, i);
12282           return -99;
12283         }
12284     }
12285
12286   if (!vec_len (file))
12287     {
12288       errmsg ("RSA key file must be specified");
12289       return -99;
12290     }
12291
12292   if (vec_len (file) > 256)
12293     {
12294       errmsg ("file name too long");
12295       return -99;
12296     }
12297
12298   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12299
12300   clib_memcpy (mp->key_file, file, vec_len (file));
12301   vec_free (file);
12302
12303   S;
12304   W;
12305   /* NOTREACHED */
12306   return 0;
12307 }
12308
12309 /*
12310  * MAP
12311  */
12312 static int
12313 api_map_add_domain (vat_main_t * vam)
12314 {
12315   unformat_input_t *i = vam->input;
12316   vl_api_map_add_domain_t *mp;
12317   f64 timeout;
12318
12319   ip4_address_t ip4_prefix;
12320   ip6_address_t ip6_prefix;
12321   ip6_address_t ip6_src;
12322   u32 num_m_args = 0;
12323   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12324     0, psid_length = 0;
12325   u8 is_translation = 0;
12326   u32 mtu = 0;
12327   u32 ip6_src_len = 128;
12328
12329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12330     {
12331       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12332                     &ip4_prefix, &ip4_prefix_len))
12333         num_m_args++;
12334       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12335                          &ip6_prefix, &ip6_prefix_len))
12336         num_m_args++;
12337       else
12338         if (unformat
12339             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12340              &ip6_src_len))
12341         num_m_args++;
12342       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12343         num_m_args++;
12344       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12345         num_m_args++;
12346       else if (unformat (i, "psid-offset %d", &psid_offset))
12347         num_m_args++;
12348       else if (unformat (i, "psid-len %d", &psid_length))
12349         num_m_args++;
12350       else if (unformat (i, "mtu %d", &mtu))
12351         num_m_args++;
12352       else if (unformat (i, "map-t"))
12353         is_translation = 1;
12354       else
12355         {
12356           clib_warning ("parse error '%U'", format_unformat_error, i);
12357           return -99;
12358         }
12359     }
12360
12361   if (num_m_args < 3)
12362     {
12363       errmsg ("mandatory argument(s) missing\n");
12364       return -99;
12365     }
12366
12367   /* Construct the API message */
12368   M (MAP_ADD_DOMAIN, map_add_domain);
12369
12370   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12371   mp->ip4_prefix_len = ip4_prefix_len;
12372
12373   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12374   mp->ip6_prefix_len = ip6_prefix_len;
12375
12376   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12377   mp->ip6_src_prefix_len = ip6_src_len;
12378
12379   mp->ea_bits_len = ea_bits_len;
12380   mp->psid_offset = psid_offset;
12381   mp->psid_length = psid_length;
12382   mp->is_translation = is_translation;
12383   mp->mtu = htons (mtu);
12384
12385   /* send it... */
12386   S;
12387
12388   /* Wait for a reply, return good/bad news  */
12389   W;
12390 }
12391
12392 static int
12393 api_map_del_domain (vat_main_t * vam)
12394 {
12395   unformat_input_t *i = vam->input;
12396   vl_api_map_del_domain_t *mp;
12397   f64 timeout;
12398
12399   u32 num_m_args = 0;
12400   u32 index;
12401
12402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12403     {
12404       if (unformat (i, "index %d", &index))
12405         num_m_args++;
12406       else
12407         {
12408           clib_warning ("parse error '%U'", format_unformat_error, i);
12409           return -99;
12410         }
12411     }
12412
12413   if (num_m_args != 1)
12414     {
12415       errmsg ("mandatory argument(s) missing\n");
12416       return -99;
12417     }
12418
12419   /* Construct the API message */
12420   M (MAP_DEL_DOMAIN, map_del_domain);
12421
12422   mp->index = ntohl (index);
12423
12424   /* send it... */
12425   S;
12426
12427   /* Wait for a reply, return good/bad news  */
12428   W;
12429 }
12430
12431 static int
12432 api_map_add_del_rule (vat_main_t * vam)
12433 {
12434   unformat_input_t *i = vam->input;
12435   vl_api_map_add_del_rule_t *mp;
12436   f64 timeout;
12437   u8 is_add = 1;
12438   ip6_address_t ip6_dst;
12439   u32 num_m_args = 0, index, psid = 0;
12440
12441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12442     {
12443       if (unformat (i, "index %d", &index))
12444         num_m_args++;
12445       else if (unformat (i, "psid %d", &psid))
12446         num_m_args++;
12447       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12448         num_m_args++;
12449       else if (unformat (i, "del"))
12450         {
12451           is_add = 0;
12452         }
12453       else
12454         {
12455           clib_warning ("parse error '%U'", format_unformat_error, i);
12456           return -99;
12457         }
12458     }
12459
12460   /* Construct the API message */
12461   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12462
12463   mp->index = ntohl (index);
12464   mp->is_add = is_add;
12465   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12466   mp->psid = ntohs (psid);
12467
12468   /* send it... */
12469   S;
12470
12471   /* Wait for a reply, return good/bad news  */
12472   W;
12473 }
12474
12475 static int
12476 api_map_domain_dump (vat_main_t * vam)
12477 {
12478   vl_api_map_domain_dump_t *mp;
12479   f64 timeout;
12480
12481   /* Construct the API message */
12482   M (MAP_DOMAIN_DUMP, map_domain_dump);
12483
12484   /* send it... */
12485   S;
12486
12487   /* Use a control ping for synchronization */
12488   {
12489     vl_api_control_ping_t *mp;
12490     M (CONTROL_PING, control_ping);
12491     S;
12492   }
12493   W;
12494 }
12495
12496 static int
12497 api_map_rule_dump (vat_main_t * vam)
12498 {
12499   unformat_input_t *i = vam->input;
12500   vl_api_map_rule_dump_t *mp;
12501   f64 timeout;
12502   u32 domain_index = ~0;
12503
12504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12505     {
12506       if (unformat (i, "index %u", &domain_index))
12507         ;
12508       else
12509         break;
12510     }
12511
12512   if (domain_index == ~0)
12513     {
12514       clib_warning ("parse error: domain index expected");
12515       return -99;
12516     }
12517
12518   /* Construct the API message */
12519   M (MAP_RULE_DUMP, map_rule_dump);
12520
12521   mp->domain_index = htonl (domain_index);
12522
12523   /* send it... */
12524   S;
12525
12526   /* Use a control ping for synchronization */
12527   {
12528     vl_api_control_ping_t *mp;
12529     M (CONTROL_PING, control_ping);
12530     S;
12531   }
12532   W;
12533 }
12534
12535 static void vl_api_map_add_domain_reply_t_handler
12536   (vl_api_map_add_domain_reply_t * mp)
12537 {
12538   vat_main_t *vam = &vat_main;
12539   i32 retval = ntohl (mp->retval);
12540
12541   if (vam->async_mode)
12542     {
12543       vam->async_errors += (retval < 0);
12544     }
12545   else
12546     {
12547       vam->retval = retval;
12548       vam->result_ready = 1;
12549     }
12550 }
12551
12552 static void vl_api_map_add_domain_reply_t_handler_json
12553   (vl_api_map_add_domain_reply_t * mp)
12554 {
12555   vat_main_t *vam = &vat_main;
12556   vat_json_node_t node;
12557
12558   vat_json_init_object (&node);
12559   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12560   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12561
12562   vat_json_print (vam->ofp, &node);
12563   vat_json_free (&node);
12564
12565   vam->retval = ntohl (mp->retval);
12566   vam->result_ready = 1;
12567 }
12568
12569 static int
12570 api_get_first_msg_id (vat_main_t * vam)
12571 {
12572   vl_api_get_first_msg_id_t *mp;
12573   f64 timeout;
12574   unformat_input_t *i = vam->input;
12575   u8 *name;
12576   u8 name_set = 0;
12577
12578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12579     {
12580       if (unformat (i, "client %s", &name))
12581         name_set = 1;
12582       else
12583         break;
12584     }
12585
12586   if (name_set == 0)
12587     {
12588       errmsg ("missing client name\n");
12589       return -99;
12590     }
12591   vec_add1 (name, 0);
12592
12593   if (vec_len (name) > 63)
12594     {
12595       errmsg ("client name too long\n");
12596       return -99;
12597     }
12598
12599   M (GET_FIRST_MSG_ID, get_first_msg_id);
12600   clib_memcpy (mp->name, name, vec_len (name));
12601   S;
12602   W;
12603   /* NOTREACHED */
12604   return 0;
12605 }
12606
12607 static int
12608 api_cop_interface_enable_disable (vat_main_t * vam)
12609 {
12610   unformat_input_t *line_input = vam->input;
12611   vl_api_cop_interface_enable_disable_t *mp;
12612   f64 timeout;
12613   u32 sw_if_index = ~0;
12614   u8 enable_disable = 1;
12615
12616   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12617     {
12618       if (unformat (line_input, "disable"))
12619         enable_disable = 0;
12620       if (unformat (line_input, "enable"))
12621         enable_disable = 1;
12622       else if (unformat (line_input, "%U", unformat_sw_if_index,
12623                          vam, &sw_if_index))
12624         ;
12625       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12626         ;
12627       else
12628         break;
12629     }
12630
12631   if (sw_if_index == ~0)
12632     {
12633       errmsg ("missing interface name or sw_if_index\n");
12634       return -99;
12635     }
12636
12637   /* Construct the API message */
12638   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12639   mp->sw_if_index = ntohl (sw_if_index);
12640   mp->enable_disable = enable_disable;
12641
12642   /* send it... */
12643   S;
12644   /* Wait for the reply */
12645   W;
12646 }
12647
12648 static int
12649 api_cop_whitelist_enable_disable (vat_main_t * vam)
12650 {
12651   unformat_input_t *line_input = vam->input;
12652   vl_api_cop_whitelist_enable_disable_t *mp;
12653   f64 timeout;
12654   u32 sw_if_index = ~0;
12655   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12656   u32 fib_id = 0;
12657
12658   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12659     {
12660       if (unformat (line_input, "ip4"))
12661         ip4 = 1;
12662       else if (unformat (line_input, "ip6"))
12663         ip6 = 1;
12664       else if (unformat (line_input, "default"))
12665         default_cop = 1;
12666       else if (unformat (line_input, "%U", unformat_sw_if_index,
12667                          vam, &sw_if_index))
12668         ;
12669       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12670         ;
12671       else if (unformat (line_input, "fib-id %d", &fib_id))
12672         ;
12673       else
12674         break;
12675     }
12676
12677   if (sw_if_index == ~0)
12678     {
12679       errmsg ("missing interface name or sw_if_index\n");
12680       return -99;
12681     }
12682
12683   /* Construct the API message */
12684   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12685   mp->sw_if_index = ntohl (sw_if_index);
12686   mp->fib_id = ntohl (fib_id);
12687   mp->ip4 = ip4;
12688   mp->ip6 = ip6;
12689   mp->default_cop = default_cop;
12690
12691   /* send it... */
12692   S;
12693   /* Wait for the reply */
12694   W;
12695 }
12696
12697 static int
12698 api_get_node_graph (vat_main_t * vam)
12699 {
12700   vl_api_get_node_graph_t *mp;
12701   f64 timeout;
12702
12703   M (GET_NODE_GRAPH, get_node_graph);
12704
12705   /* send it... */
12706   S;
12707   /* Wait for the reply */
12708   W;
12709 }
12710
12711 /* *INDENT-OFF* */
12712 /** Used for parsing LISP eids */
12713 typedef CLIB_PACKED(struct{
12714   u8 addr[16];   /**< eid address */
12715   u32 len;       /**< prefix length if IP */
12716   u8 type;      /**< type of eid */
12717 }) lisp_eid_vat_t;
12718 /* *INDENT-ON* */
12719
12720 static uword
12721 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12722 {
12723   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12724
12725   memset (a, 0, sizeof (a[0]));
12726
12727   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12728     {
12729       a->type = 0;              /* ipv4 type */
12730     }
12731   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12732     {
12733       a->type = 1;              /* ipv6 type */
12734     }
12735   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12736     {
12737       a->type = 2;              /* mac type */
12738     }
12739   else
12740     {
12741       return 0;
12742     }
12743
12744   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12745     {
12746       return 0;
12747     }
12748
12749   return 1;
12750 }
12751
12752 static int
12753 lisp_eid_size_vat (u8 type)
12754 {
12755   switch (type)
12756     {
12757     case 0:
12758       return 4;
12759     case 1:
12760       return 16;
12761     case 2:
12762       return 6;
12763     }
12764   return 0;
12765 }
12766
12767 static void
12768 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12769 {
12770   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12771 }
12772
12773 /* *INDENT-OFF* */
12774 /** Used for transferring locators via VPP API */
12775 typedef CLIB_PACKED(struct
12776 {
12777   u32 sw_if_index; /**< locator sw_if_index */
12778   u8 priority; /**< locator priority */
12779   u8 weight;   /**< locator weight */
12780 }) ls_locator_t;
12781 /* *INDENT-ON* */
12782
12783 static int
12784 api_lisp_add_del_locator_set (vat_main_t * vam)
12785 {
12786   unformat_input_t *input = vam->input;
12787   vl_api_lisp_add_del_locator_set_t *mp;
12788   f64 timeout = ~0;
12789   u8 is_add = 1;
12790   u8 *locator_set_name = NULL;
12791   u8 locator_set_name_set = 0;
12792   ls_locator_t locator, *locators = 0;
12793   u32 sw_if_index, priority, weight;
12794   u32 data_len = 0;
12795
12796   /* Parse args required to build the message */
12797   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12798     {
12799       if (unformat (input, "del"))
12800         {
12801           is_add = 0;
12802         }
12803       else if (unformat (input, "locator-set %s", &locator_set_name))
12804         {
12805           locator_set_name_set = 1;
12806         }
12807       else if (unformat (input, "sw_if_index %u p %u w %u",
12808                          &sw_if_index, &priority, &weight))
12809         {
12810           locator.sw_if_index = htonl (sw_if_index);
12811           locator.priority = priority;
12812           locator.weight = weight;
12813           vec_add1 (locators, locator);
12814         }
12815       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12816                          vam, &sw_if_index, &priority, &weight))
12817         {
12818           locator.sw_if_index = htonl (sw_if_index);
12819           locator.priority = priority;
12820           locator.weight = weight;
12821           vec_add1 (locators, locator);
12822         }
12823       else
12824         break;
12825     }
12826
12827   if (locator_set_name_set == 0)
12828     {
12829       errmsg ("missing locator-set name");
12830       vec_free (locators);
12831       return -99;
12832     }
12833
12834   if (vec_len (locator_set_name) > 64)
12835     {
12836       errmsg ("locator-set name too long\n");
12837       vec_free (locator_set_name);
12838       vec_free (locators);
12839       return -99;
12840     }
12841   vec_add1 (locator_set_name, 0);
12842
12843   data_len = sizeof (ls_locator_t) * vec_len (locators);
12844
12845   /* Construct the API message */
12846   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12847
12848   mp->is_add = is_add;
12849   clib_memcpy (mp->locator_set_name, locator_set_name,
12850                vec_len (locator_set_name));
12851   vec_free (locator_set_name);
12852
12853   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12854   if (locators)
12855     clib_memcpy (mp->locators, locators, data_len);
12856   vec_free (locators);
12857
12858   /* send it... */
12859   S;
12860
12861   /* Wait for a reply... */
12862   W;
12863
12864   /* NOTREACHED */
12865   return 0;
12866 }
12867
12868 static int
12869 api_lisp_add_del_locator (vat_main_t * vam)
12870 {
12871   unformat_input_t *input = vam->input;
12872   vl_api_lisp_add_del_locator_t *mp;
12873   f64 timeout = ~0;
12874   u32 tmp_if_index = ~0;
12875   u32 sw_if_index = ~0;
12876   u8 sw_if_index_set = 0;
12877   u8 sw_if_index_if_name_set = 0;
12878   u32 priority = ~0;
12879   u8 priority_set = 0;
12880   u32 weight = ~0;
12881   u8 weight_set = 0;
12882   u8 is_add = 1;
12883   u8 *locator_set_name = NULL;
12884   u8 locator_set_name_set = 0;
12885
12886   /* Parse args required to build the message */
12887   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12888     {
12889       if (unformat (input, "del"))
12890         {
12891           is_add = 0;
12892         }
12893       else if (unformat (input, "locator-set %s", &locator_set_name))
12894         {
12895           locator_set_name_set = 1;
12896         }
12897       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12898                          &tmp_if_index))
12899         {
12900           sw_if_index_if_name_set = 1;
12901           sw_if_index = tmp_if_index;
12902         }
12903       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12904         {
12905           sw_if_index_set = 1;
12906           sw_if_index = tmp_if_index;
12907         }
12908       else if (unformat (input, "p %d", &priority))
12909         {
12910           priority_set = 1;
12911         }
12912       else if (unformat (input, "w %d", &weight))
12913         {
12914           weight_set = 1;
12915         }
12916       else
12917         break;
12918     }
12919
12920   if (locator_set_name_set == 0)
12921     {
12922       errmsg ("missing locator-set name");
12923       return -99;
12924     }
12925
12926   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12927     {
12928       errmsg ("missing sw_if_index");
12929       vec_free (locator_set_name);
12930       return -99;
12931     }
12932
12933   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12934     {
12935       errmsg ("cannot use both params interface name and sw_if_index");
12936       vec_free (locator_set_name);
12937       return -99;
12938     }
12939
12940   if (priority_set == 0)
12941     {
12942       errmsg ("missing locator-set priority\n");
12943       vec_free (locator_set_name);
12944       return -99;
12945     }
12946
12947   if (weight_set == 0)
12948     {
12949       errmsg ("missing locator-set weight\n");
12950       vec_free (locator_set_name);
12951       return -99;
12952     }
12953
12954   if (vec_len (locator_set_name) > 64)
12955     {
12956       errmsg ("locator-set name too long\n");
12957       vec_free (locator_set_name);
12958       return -99;
12959     }
12960   vec_add1 (locator_set_name, 0);
12961
12962   /* Construct the API message */
12963   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12964
12965   mp->is_add = is_add;
12966   mp->sw_if_index = ntohl (sw_if_index);
12967   mp->priority = priority;
12968   mp->weight = weight;
12969   clib_memcpy (mp->locator_set_name, locator_set_name,
12970                vec_len (locator_set_name));
12971   vec_free (locator_set_name);
12972
12973   /* send it... */
12974   S;
12975
12976   /* Wait for a reply... */
12977   W;
12978
12979   /* NOTREACHED */
12980   return 0;
12981 }
12982
12983 uword
12984 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
12985 {
12986   u32 *key_id = va_arg (*args, u32 *);
12987   u8 *s = 0;
12988
12989   if (unformat (input, "%s", &s))
12990     {
12991       if (!strcmp ((char *) s, "sha1"))
12992         key_id[0] = HMAC_SHA_1_96;
12993       else if (!strcmp ((char *) s, "sha256"))
12994         key_id[0] = HMAC_SHA_256_128;
12995       else
12996         {
12997           clib_warning ("invalid key_id: '%s'", s);
12998           key_id[0] = HMAC_NO_KEY;
12999         }
13000     }
13001   else
13002     return 0;
13003
13004   vec_free (s);
13005   return 1;
13006 }
13007
13008 static int
13009 api_lisp_add_del_local_eid (vat_main_t * vam)
13010 {
13011   unformat_input_t *input = vam->input;
13012   vl_api_lisp_add_del_local_eid_t *mp;
13013   f64 timeout = ~0;
13014   u8 is_add = 1;
13015   u8 eid_set = 0;
13016   lisp_eid_vat_t _eid, *eid = &_eid;
13017   u8 *locator_set_name = 0;
13018   u8 locator_set_name_set = 0;
13019   u32 vni = 0;
13020   u16 key_id = 0;
13021   u8 *key = 0;
13022
13023   /* Parse args required to build the message */
13024   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13025     {
13026       if (unformat (input, "del"))
13027         {
13028           is_add = 0;
13029         }
13030       else if (unformat (input, "vni %d", &vni))
13031         {
13032           ;
13033         }
13034       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13035         {
13036           eid_set = 1;
13037         }
13038       else if (unformat (input, "locator-set %s", &locator_set_name))
13039         {
13040           locator_set_name_set = 1;
13041         }
13042       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13043         ;
13044       else if (unformat (input, "secret-key %_%v%_", &key))
13045         ;
13046       else
13047         break;
13048     }
13049
13050   if (locator_set_name_set == 0)
13051     {
13052       errmsg ("missing locator-set name\n");
13053       return -99;
13054     }
13055
13056   if (0 == eid_set)
13057     {
13058       errmsg ("EID address not set!");
13059       vec_free (locator_set_name);
13060       return -99;
13061     }
13062
13063   if (key && (0 == key_id))
13064     {
13065       errmsg ("invalid key_id!");
13066       return -99;
13067     }
13068
13069   if (vec_len (key) > 64)
13070     {
13071       errmsg ("key too long");
13072       vec_free (key);
13073       return -99;
13074     }
13075
13076   if (vec_len (locator_set_name) > 64)
13077     {
13078       errmsg ("locator-set name too long\n");
13079       vec_free (locator_set_name);
13080       return -99;
13081     }
13082   vec_add1 (locator_set_name, 0);
13083
13084   /* Construct the API message */
13085   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13086
13087   mp->is_add = is_add;
13088   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13089   mp->eid_type = eid->type;
13090   mp->prefix_len = eid->len;
13091   mp->vni = clib_host_to_net_u32 (vni);
13092   mp->key_id = clib_host_to_net_u16 (key_id);
13093   clib_memcpy (mp->locator_set_name, locator_set_name,
13094                vec_len (locator_set_name));
13095   clib_memcpy (mp->key, key, vec_len (key));
13096
13097   vec_free (locator_set_name);
13098   vec_free (key);
13099
13100   /* send it... */
13101   S;
13102
13103   /* Wait for a reply... */
13104   W;
13105
13106   /* NOTREACHED */
13107   return 0;
13108 }
13109
13110 /* *INDENT-OFF* */
13111 /** Used for transferring locators via VPP API */
13112 typedef CLIB_PACKED(struct
13113 {
13114   u8 is_ip4; /**< is locator an IPv4 address? */
13115   u8 priority; /**< locator priority */
13116   u8 weight;   /**< locator weight */
13117   u8 addr[16]; /**< IPv4/IPv6 address */
13118 }) rloc_t;
13119 /* *INDENT-ON* */
13120
13121 static int
13122 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13123 {
13124   unformat_input_t *input = vam->input;
13125   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13126   f64 timeout = ~0;
13127   u8 is_add = 1;
13128   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13129   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13130   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13131   u32 action = ~0, p, w;
13132   ip4_address_t rmt_rloc4, lcl_rloc4;
13133   ip6_address_t rmt_rloc6, lcl_rloc6;
13134   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13135
13136   memset (&rloc, 0, sizeof (rloc));
13137
13138   /* Parse args required to build the message */
13139   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13140     {
13141       if (unformat (input, "del"))
13142         {
13143           is_add = 0;
13144         }
13145       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
13146         {
13147           rmt_eid_set = 1;
13148         }
13149       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
13150         {
13151           lcl_eid_set = 1;
13152         }
13153       else if (unformat (input, "p %d w %d", &p, &w))
13154         {
13155           if (!curr_rloc)
13156             {
13157               errmsg ("No RLOC configured for setting priority/weight!");
13158               return -99;
13159             }
13160           curr_rloc->priority = p;
13161           curr_rloc->weight = w;
13162         }
13163       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13164                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13165         {
13166           rloc.is_ip4 = 1;
13167
13168           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13169           rloc.priority = rloc.weight = 0;
13170           vec_add1 (lcl_locs, rloc);
13171
13172           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13173           vec_add1 (rmt_locs, rloc);
13174           /* priority and weight saved in rmt loc */
13175           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13176         }
13177       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13178                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13179         {
13180           rloc.is_ip4 = 0;
13181           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13182           rloc.priority = rloc.weight = 0;
13183           vec_add1 (lcl_locs, rloc);
13184
13185           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13186           vec_add1 (rmt_locs, rloc);
13187           /* priority and weight saved in rmt loc */
13188           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13189         }
13190       else if (unformat (input, "action %d", &action))
13191         {
13192           ;
13193         }
13194       else
13195         {
13196           clib_warning ("parse error '%U'", format_unformat_error, input);
13197           return -99;
13198         }
13199     }
13200
13201   if (!rmt_eid_set)
13202     {
13203       errmsg ("remote eid addresses not set\n");
13204       return -99;
13205     }
13206
13207   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13208     {
13209       errmsg ("eid types don't match\n");
13210       return -99;
13211     }
13212
13213   if (0 == rmt_locs && (u32) ~ 0 == action)
13214     {
13215       errmsg ("action not set for negative mapping\n");
13216       return -99;
13217     }
13218
13219   /* Construct the API message */
13220   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13221
13222   mp->is_add = is_add;
13223   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13224   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13225   mp->eid_type = rmt_eid->type;
13226   mp->rmt_len = rmt_eid->len;
13227   mp->lcl_len = lcl_eid->len;
13228   mp->action = action;
13229
13230   if (0 != rmt_locs && 0 != lcl_locs)
13231     {
13232       mp->loc_num = vec_len (rmt_locs);
13233       clib_memcpy (mp->lcl_locs, lcl_locs,
13234                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13235       clib_memcpy (mp->rmt_locs, rmt_locs,
13236                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13237     }
13238   vec_free (lcl_locs);
13239   vec_free (rmt_locs);
13240
13241   /* send it... */
13242   S;
13243
13244   /* Wait for a reply... */
13245   W;
13246
13247   /* NOTREACHED */
13248   return 0;
13249 }
13250
13251 static int
13252 api_lisp_add_del_map_server (vat_main_t * vam)
13253 {
13254   unformat_input_t *input = vam->input;
13255   vl_api_lisp_add_del_map_server_t *mp;
13256   f64 timeout = ~0;
13257   u8 is_add = 1;
13258   u8 ipv4_set = 0;
13259   u8 ipv6_set = 0;
13260   ip4_address_t ipv4;
13261   ip6_address_t ipv6;
13262
13263   /* Parse args required to build the message */
13264   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13265     {
13266       if (unformat (input, "del"))
13267         {
13268           is_add = 0;
13269         }
13270       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13271         {
13272           ipv4_set = 1;
13273         }
13274       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13275         {
13276           ipv6_set = 1;
13277         }
13278       else
13279         break;
13280     }
13281
13282   if (ipv4_set && ipv6_set)
13283     {
13284       errmsg ("both eid v4 and v6 addresses set\n");
13285       return -99;
13286     }
13287
13288   if (!ipv4_set && !ipv6_set)
13289     {
13290       errmsg ("eid addresses not set\n");
13291       return -99;
13292     }
13293
13294   /* Construct the API message */
13295   M (LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server);
13296
13297   mp->is_add = is_add;
13298   if (ipv6_set)
13299     {
13300       mp->is_ipv6 = 1;
13301       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13302     }
13303   else
13304     {
13305       mp->is_ipv6 = 0;
13306       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13307     }
13308
13309   /* send it... */
13310   S;
13311
13312   /* Wait for a reply... */
13313   W;
13314
13315   /* NOTREACHED */
13316   return 0;
13317 }
13318
13319 static int
13320 api_lisp_add_del_map_resolver (vat_main_t * vam)
13321 {
13322   unformat_input_t *input = vam->input;
13323   vl_api_lisp_add_del_map_resolver_t *mp;
13324   f64 timeout = ~0;
13325   u8 is_add = 1;
13326   u8 ipv4_set = 0;
13327   u8 ipv6_set = 0;
13328   ip4_address_t ipv4;
13329   ip6_address_t ipv6;
13330
13331   /* Parse args required to build the message */
13332   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13333     {
13334       if (unformat (input, "del"))
13335         {
13336           is_add = 0;
13337         }
13338       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13339         {
13340           ipv4_set = 1;
13341         }
13342       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13343         {
13344           ipv6_set = 1;
13345         }
13346       else
13347         break;
13348     }
13349
13350   if (ipv4_set && ipv6_set)
13351     {
13352       errmsg ("both eid v4 and v6 addresses set\n");
13353       return -99;
13354     }
13355
13356   if (!ipv4_set && !ipv6_set)
13357     {
13358       errmsg ("eid addresses not set\n");
13359       return -99;
13360     }
13361
13362   /* Construct the API message */
13363   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13364
13365   mp->is_add = is_add;
13366   if (ipv6_set)
13367     {
13368       mp->is_ipv6 = 1;
13369       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13370     }
13371   else
13372     {
13373       mp->is_ipv6 = 0;
13374       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13375     }
13376
13377   /* send it... */
13378   S;
13379
13380   /* Wait for a reply... */
13381   W;
13382
13383   /* NOTREACHED */
13384   return 0;
13385 }
13386
13387 static int
13388 api_lisp_gpe_enable_disable (vat_main_t * vam)
13389 {
13390   unformat_input_t *input = vam->input;
13391   vl_api_lisp_gpe_enable_disable_t *mp;
13392   f64 timeout = ~0;
13393   u8 is_set = 0;
13394   u8 is_en = 1;
13395
13396   /* Parse args required to build the message */
13397   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13398     {
13399       if (unformat (input, "enable"))
13400         {
13401           is_set = 1;
13402           is_en = 1;
13403         }
13404       else if (unformat (input, "disable"))
13405         {
13406           is_set = 1;
13407           is_en = 0;
13408         }
13409       else
13410         break;
13411     }
13412
13413   if (is_set == 0)
13414     {
13415       errmsg ("Value not set\n");
13416       return -99;
13417     }
13418
13419   /* Construct the API message */
13420   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13421
13422   mp->is_en = is_en;
13423
13424   /* send it... */
13425   S;
13426
13427   /* Wait for a reply... */
13428   W;
13429
13430   /* NOTREACHED */
13431   return 0;
13432 }
13433
13434 static int
13435 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13436 {
13437   unformat_input_t *input = vam->input;
13438   vl_api_lisp_rloc_probe_enable_disable_t *mp;
13439   f64 timeout = ~0;
13440   u8 is_set = 0;
13441   u8 is_en = 0;
13442
13443   /* Parse args required to build the message */
13444   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13445     {
13446       if (unformat (input, "enable"))
13447         {
13448           is_set = 1;
13449           is_en = 1;
13450         }
13451       else if (unformat (input, "disable"))
13452         is_set = 1;
13453       else
13454         break;
13455     }
13456
13457   if (!is_set)
13458     {
13459       errmsg ("Value not set\n");
13460       return -99;
13461     }
13462
13463   /* Construct the API message */
13464   M (LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable);
13465
13466   mp->is_enabled = is_en;
13467
13468   /* send it... */
13469   S;
13470
13471   /* Wait for a reply... */
13472   W;
13473
13474   /* NOTREACHED */
13475   return 0;
13476 }
13477
13478 static int
13479 api_lisp_map_register_enable_disable (vat_main_t * vam)
13480 {
13481   unformat_input_t *input = vam->input;
13482   vl_api_lisp_map_register_enable_disable_t *mp;
13483   f64 timeout = ~0;
13484   u8 is_set = 0;
13485   u8 is_en = 0;
13486
13487   /* Parse args required to build the message */
13488   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13489     {
13490       if (unformat (input, "enable"))
13491         {
13492           is_set = 1;
13493           is_en = 1;
13494         }
13495       else if (unformat (input, "disable"))
13496         is_set = 1;
13497       else
13498         break;
13499     }
13500
13501   if (!is_set)
13502     {
13503       errmsg ("Value not set\n");
13504       return -99;
13505     }
13506
13507   /* Construct the API message */
13508   M (LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable);
13509
13510   mp->is_enabled = is_en;
13511
13512   /* send it... */
13513   S;
13514
13515   /* Wait for a reply... */
13516   W;
13517
13518   /* NOTREACHED */
13519   return 0;
13520 }
13521
13522 static int
13523 api_lisp_enable_disable (vat_main_t * vam)
13524 {
13525   unformat_input_t *input = vam->input;
13526   vl_api_lisp_enable_disable_t *mp;
13527   f64 timeout = ~0;
13528   u8 is_set = 0;
13529   u8 is_en = 0;
13530
13531   /* Parse args required to build the message */
13532   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13533     {
13534       if (unformat (input, "enable"))
13535         {
13536           is_set = 1;
13537           is_en = 1;
13538         }
13539       else if (unformat (input, "disable"))
13540         {
13541           is_set = 1;
13542         }
13543       else
13544         break;
13545     }
13546
13547   if (!is_set)
13548     {
13549       errmsg ("Value not set\n");
13550       return -99;
13551     }
13552
13553   /* Construct the API message */
13554   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13555
13556   mp->is_en = is_en;
13557
13558   /* send it... */
13559   S;
13560
13561   /* Wait for a reply... */
13562   W;
13563
13564   /* NOTREACHED */
13565   return 0;
13566 }
13567
13568 static int
13569 api_show_lisp_map_register_state (vat_main_t * vam)
13570 {
13571   f64 timeout = ~0;
13572   vl_api_show_lisp_map_register_state_t *mp;
13573
13574   M (SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state);
13575
13576   /* send */
13577   S;
13578
13579   /* wait for reply */
13580   W;
13581
13582   return 0;
13583 }
13584
13585 static int
13586 api_show_lisp_rloc_probe_state (vat_main_t * vam)
13587 {
13588   f64 timeout = ~0;
13589   vl_api_show_lisp_rloc_probe_state_t *mp;
13590
13591   M (SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state);
13592
13593   /* send */
13594   S;
13595
13596   /* wait for reply */
13597   W;
13598
13599   return 0;
13600 }
13601
13602 static int
13603 api_show_lisp_map_request_mode (vat_main_t * vam)
13604 {
13605   f64 timeout = ~0;
13606   vl_api_show_lisp_map_request_mode_t *mp;
13607
13608   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13609
13610   /* send */
13611   S;
13612
13613   /* wait for reply */
13614   W;
13615
13616   return 0;
13617 }
13618
13619 static int
13620 api_lisp_map_request_mode (vat_main_t * vam)
13621 {
13622   f64 timeout = ~0;
13623   unformat_input_t *input = vam->input;
13624   vl_api_lisp_map_request_mode_t *mp;
13625   u8 mode = 0;
13626
13627   /* Parse args required to build the message */
13628   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13629     {
13630       if (unformat (input, "dst-only"))
13631         mode = 0;
13632       else if (unformat (input, "src-dst"))
13633         mode = 1;
13634       else
13635         {
13636           errmsg ("parse error '%U'", format_unformat_error, input);
13637           return -99;
13638         }
13639     }
13640
13641   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13642
13643   mp->mode = mode;
13644
13645   /* send */
13646   S;
13647
13648   /* wait for reply */
13649   W;
13650
13651   /* notreached */
13652   return 0;
13653 }
13654
13655 /**
13656  * Enable/disable LISP proxy ITR.
13657  *
13658  * @param vam vpp API test context
13659  * @return return code
13660  */
13661 static int
13662 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13663 {
13664   f64 timeout = ~0;
13665   u8 ls_name_set = 0;
13666   unformat_input_t *input = vam->input;
13667   vl_api_lisp_pitr_set_locator_set_t *mp;
13668   u8 is_add = 1;
13669   u8 *ls_name = 0;
13670
13671   /* Parse args required to build the message */
13672   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13673     {
13674       if (unformat (input, "del"))
13675         is_add = 0;
13676       else if (unformat (input, "locator-set %s", &ls_name))
13677         ls_name_set = 1;
13678       else
13679         {
13680           errmsg ("parse error '%U'", format_unformat_error, input);
13681           return -99;
13682         }
13683     }
13684
13685   if (!ls_name_set)
13686     {
13687       errmsg ("locator-set name not set!");
13688       return -99;
13689     }
13690
13691   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13692
13693   mp->is_add = is_add;
13694   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13695   vec_free (ls_name);
13696
13697   /* send */
13698   S;
13699
13700   /* wait for reply */
13701   W;
13702
13703   /* notreached */
13704   return 0;
13705 }
13706
13707 static int
13708 api_show_lisp_pitr (vat_main_t * vam)
13709 {
13710   vl_api_show_lisp_pitr_t *mp;
13711   f64 timeout = ~0;
13712
13713   if (!vam->json_output)
13714     {
13715       fformat (vam->ofp, "%=20s\n", "lisp status:");
13716     }
13717
13718   M (SHOW_LISP_PITR, show_lisp_pitr);
13719   /* send it... */
13720   S;
13721
13722   /* Wait for a reply... */
13723   W;
13724
13725   /* NOTREACHED */
13726   return 0;
13727 }
13728
13729 /**
13730  * Add/delete mapping between vni and vrf
13731  */
13732 static int
13733 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13734 {
13735   f64 timeout = ~0;
13736   unformat_input_t *input = vam->input;
13737   vl_api_lisp_eid_table_add_del_map_t *mp;
13738   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13739   u32 vni, vrf, bd_index;
13740
13741   /* Parse args required to build the message */
13742   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13743     {
13744       if (unformat (input, "del"))
13745         is_add = 0;
13746       else if (unformat (input, "vrf %d", &vrf))
13747         vrf_set = 1;
13748       else if (unformat (input, "bd_index %d", &bd_index))
13749         bd_index_set = 1;
13750       else if (unformat (input, "vni %d", &vni))
13751         vni_set = 1;
13752       else
13753         break;
13754     }
13755
13756   if (!vni_set || (!vrf_set && !bd_index_set))
13757     {
13758       errmsg ("missing arguments!");
13759       return -99;
13760     }
13761
13762   if (vrf_set && bd_index_set)
13763     {
13764       errmsg ("error: both vrf and bd entered!");
13765       return -99;
13766     }
13767
13768   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13769
13770   mp->is_add = is_add;
13771   mp->vni = htonl (vni);
13772   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13773   mp->is_l2 = bd_index_set;
13774
13775   /* send */
13776   S;
13777
13778   /* wait for reply */
13779   W;
13780
13781   /* notreached */
13782   return 0;
13783 }
13784
13785 uword
13786 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13787 {
13788   u32 *action = va_arg (*args, u32 *);
13789   u8 *s = 0;
13790
13791   if (unformat (input, "%s", &s))
13792     {
13793       if (!strcmp ((char *) s, "no-action"))
13794         action[0] = 0;
13795       else if (!strcmp ((char *) s, "natively-forward"))
13796         action[0] = 1;
13797       else if (!strcmp ((char *) s, "send-map-request"))
13798         action[0] = 2;
13799       else if (!strcmp ((char *) s, "drop"))
13800         action[0] = 3;
13801       else
13802         {
13803           clib_warning ("invalid action: '%s'", s);
13804           action[0] = 3;
13805         }
13806     }
13807   else
13808     return 0;
13809
13810   vec_free (s);
13811   return 1;
13812 }
13813
13814 /**
13815  * Add/del remote mapping to/from LISP control plane
13816  *
13817  * @param vam vpp API test context
13818  * @return return code
13819  */
13820 static int
13821 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13822 {
13823   unformat_input_t *input = vam->input;
13824   vl_api_lisp_add_del_remote_mapping_t *mp;
13825   f64 timeout = ~0;
13826   u32 vni = 0;
13827   lisp_eid_vat_t _eid, *eid = &_eid;
13828   lisp_eid_vat_t _seid, *seid = &_seid;
13829   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13830   u32 action = ~0, p, w, data_len;
13831   ip4_address_t rloc4;
13832   ip6_address_t rloc6;
13833   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13834
13835   memset (&rloc, 0, sizeof (rloc));
13836
13837   /* Parse args required to build the message */
13838   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13839     {
13840       if (unformat (input, "del-all"))
13841         {
13842           del_all = 1;
13843         }
13844       else if (unformat (input, "del"))
13845         {
13846           is_add = 0;
13847         }
13848       else if (unformat (input, "add"))
13849         {
13850           is_add = 1;
13851         }
13852       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13853         {
13854           eid_set = 1;
13855         }
13856       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13857         {
13858           seid_set = 1;
13859         }
13860       else if (unformat (input, "vni %d", &vni))
13861         {
13862           ;
13863         }
13864       else if (unformat (input, "p %d w %d", &p, &w))
13865         {
13866           if (!curr_rloc)
13867             {
13868               errmsg ("No RLOC configured for setting priority/weight!");
13869               return -99;
13870             }
13871           curr_rloc->priority = p;
13872           curr_rloc->weight = w;
13873         }
13874       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13875         {
13876           rloc.is_ip4 = 1;
13877           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13878           vec_add1 (rlocs, rloc);
13879           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13880         }
13881       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13882         {
13883           rloc.is_ip4 = 0;
13884           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13885           vec_add1 (rlocs, rloc);
13886           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13887         }
13888       else if (unformat (input, "action %U",
13889                          unformat_negative_mapping_action, &action))
13890         {
13891           ;
13892         }
13893       else
13894         {
13895           clib_warning ("parse error '%U'", format_unformat_error, input);
13896           return -99;
13897         }
13898     }
13899
13900   if (0 == eid_set)
13901     {
13902       errmsg ("missing params!");
13903       return -99;
13904     }
13905
13906   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13907     {
13908       errmsg ("no action set for negative map-reply!");
13909       return -99;
13910     }
13911
13912   data_len = vec_len (rlocs) * sizeof (rloc_t);
13913
13914   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13915   mp->is_add = is_add;
13916   mp->vni = htonl (vni);
13917   mp->action = (u8) action;
13918   mp->is_src_dst = seid_set;
13919   mp->eid_len = eid->len;
13920   mp->seid_len = seid->len;
13921   mp->del_all = del_all;
13922   mp->eid_type = eid->type;
13923   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13924   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13925
13926   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13927   clib_memcpy (mp->rlocs, rlocs, data_len);
13928   vec_free (rlocs);
13929
13930   /* send it... */
13931   S;
13932
13933   /* Wait for a reply... */
13934   W;
13935
13936   /* NOTREACHED */
13937   return 0;
13938 }
13939
13940 /**
13941  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13942  * forwarding entries in data-plane accordingly.
13943  *
13944  * @param vam vpp API test context
13945  * @return return code
13946  */
13947 static int
13948 api_lisp_add_del_adjacency (vat_main_t * vam)
13949 {
13950   unformat_input_t *input = vam->input;
13951   vl_api_lisp_add_del_adjacency_t *mp;
13952   f64 timeout = ~0;
13953   u32 vni = 0;
13954   ip4_address_t leid4, reid4;
13955   ip6_address_t leid6, reid6;
13956   u8 reid_mac[6] = { 0 };
13957   u8 leid_mac[6] = { 0 };
13958   u8 reid_type, leid_type;
13959   u32 leid_len = 0, reid_len = 0, len;
13960   u8 is_add = 1;
13961
13962   leid_type = reid_type = (u8) ~ 0;
13963
13964   /* Parse args required to build the message */
13965   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13966     {
13967       if (unformat (input, "del"))
13968         {
13969           is_add = 0;
13970         }
13971       else if (unformat (input, "add"))
13972         {
13973           is_add = 1;
13974         }
13975       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13976                          &reid4, &len))
13977         {
13978           reid_type = 0;        /* ipv4 */
13979           reid_len = len;
13980         }
13981       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13982                          &reid6, &len))
13983         {
13984           reid_type = 1;        /* ipv6 */
13985           reid_len = len;
13986         }
13987       else if (unformat (input, "reid %U", unformat_ethernet_address,
13988                          reid_mac))
13989         {
13990           reid_type = 2;        /* mac */
13991         }
13992       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13993                          &leid4, &len))
13994         {
13995           leid_type = 0;        /* ipv4 */
13996           leid_len = len;
13997         }
13998       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13999                          &leid6, &len))
14000         {
14001           leid_type = 1;        /* ipv6 */
14002           leid_len = len;
14003         }
14004       else if (unformat (input, "leid %U", unformat_ethernet_address,
14005                          leid_mac))
14006         {
14007           leid_type = 2;        /* mac */
14008         }
14009       else if (unformat (input, "vni %d", &vni))
14010         {
14011           ;
14012         }
14013       else
14014         {
14015           errmsg ("parse error '%U'", format_unformat_error, input);
14016           return -99;
14017         }
14018     }
14019
14020   if ((u8) ~ 0 == reid_type)
14021     {
14022       errmsg ("missing params!");
14023       return -99;
14024     }
14025
14026   if (leid_type != reid_type)
14027     {
14028       errmsg ("remote and local EIDs are of different types!");
14029       return -99;
14030     }
14031
14032   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
14033   mp->is_add = is_add;
14034   mp->vni = htonl (vni);
14035   mp->leid_len = leid_len;
14036   mp->reid_len = reid_len;
14037   mp->eid_type = reid_type;
14038
14039   switch (mp->eid_type)
14040     {
14041     case 0:
14042       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14043       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14044       break;
14045     case 1:
14046       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14047       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14048       break;
14049     case 2:
14050       clib_memcpy (mp->leid, leid_mac, 6);
14051       clib_memcpy (mp->reid, reid_mac, 6);
14052       break;
14053     default:
14054       errmsg ("unknown EID type %d!", mp->eid_type);
14055       return 0;
14056     }
14057
14058   /* send it... */
14059   S;
14060
14061   /* Wait for a reply... */
14062   W;
14063
14064   /* NOTREACHED */
14065   return 0;
14066 }
14067
14068 static int
14069 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14070 {
14071   unformat_input_t *input = vam->input;
14072   vl_api_lisp_gpe_add_del_iface_t *mp;
14073   f64 timeout = ~0;
14074   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14075   u32 dp_table = 0, vni = 0;
14076
14077   /* Parse args required to build the message */
14078   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14079     {
14080       if (unformat (input, "up"))
14081         {
14082           action_set = 1;
14083           is_add = 1;
14084         }
14085       else if (unformat (input, "down"))
14086         {
14087           action_set = 1;
14088           is_add = 0;
14089         }
14090       else if (unformat (input, "table_id %d", &dp_table))
14091         {
14092           dp_table_set = 1;
14093         }
14094       else if (unformat (input, "bd_id %d", &dp_table))
14095         {
14096           dp_table_set = 1;
14097           is_l2 = 1;
14098         }
14099       else if (unformat (input, "vni %d", &vni))
14100         {
14101           vni_set = 1;
14102         }
14103       else
14104         break;
14105     }
14106
14107   if (action_set == 0)
14108     {
14109       errmsg ("Action not set\n");
14110       return -99;
14111     }
14112   if (dp_table_set == 0 || vni_set == 0)
14113     {
14114       errmsg ("vni and dp_table must be set\n");
14115       return -99;
14116     }
14117
14118   /* Construct the API message */
14119   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
14120
14121   mp->is_add = is_add;
14122   mp->dp_table = dp_table;
14123   mp->is_l2 = is_l2;
14124   mp->vni = vni;
14125
14126   /* send it... */
14127   S;
14128
14129   /* Wait for a reply... */
14130   W;
14131
14132   /* NOTREACHED */
14133   return 0;
14134 }
14135
14136 /**
14137  * Add/del map request itr rlocs from LISP control plane and updates
14138  *
14139  * @param vam vpp API test context
14140  * @return return code
14141  */
14142 static int
14143 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14144 {
14145   unformat_input_t *input = vam->input;
14146   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14147   f64 timeout = ~0;
14148   u8 *locator_set_name = 0;
14149   u8 locator_set_name_set = 0;
14150   u8 is_add = 1;
14151
14152   /* Parse args required to build the message */
14153   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14154     {
14155       if (unformat (input, "del"))
14156         {
14157           is_add = 0;
14158         }
14159       else if (unformat (input, "%_%v%_", &locator_set_name))
14160         {
14161           locator_set_name_set = 1;
14162         }
14163       else
14164         {
14165           clib_warning ("parse error '%U'", format_unformat_error, input);
14166           return -99;
14167         }
14168     }
14169
14170   if (is_add && !locator_set_name_set)
14171     {
14172       errmsg ("itr-rloc is not set!");
14173       return -99;
14174     }
14175
14176   if (is_add && vec_len (locator_set_name) > 64)
14177     {
14178       errmsg ("itr-rloc locator-set name too long\n");
14179       vec_free (locator_set_name);
14180       return -99;
14181     }
14182
14183   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
14184   mp->is_add = is_add;
14185   if (is_add)
14186     {
14187       clib_memcpy (mp->locator_set_name, locator_set_name,
14188                    vec_len (locator_set_name));
14189     }
14190   else
14191     {
14192       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14193     }
14194   vec_free (locator_set_name);
14195
14196   /* send it... */
14197   S;
14198
14199   /* Wait for a reply... */
14200   W;
14201
14202   /* NOTREACHED */
14203   return 0;
14204 }
14205
14206 static int
14207 api_lisp_locator_dump (vat_main_t * vam)
14208 {
14209   unformat_input_t *input = vam->input;
14210   vl_api_lisp_locator_dump_t *mp;
14211   f64 timeout = ~0;
14212   u8 is_index_set = 0, is_name_set = 0;
14213   u8 *ls_name = 0;
14214   u32 ls_index = ~0;
14215
14216   /* Parse args required to build the message */
14217   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14218     {
14219       if (unformat (input, "ls_name %_%v%_", &ls_name))
14220         {
14221           is_name_set = 1;
14222         }
14223       else if (unformat (input, "ls_index %d", &ls_index))
14224         {
14225           is_index_set = 1;
14226         }
14227       else
14228         {
14229           errmsg ("parse error '%U'", format_unformat_error, input);
14230           return -99;
14231         }
14232     }
14233
14234   if (!is_index_set && !is_name_set)
14235     {
14236       errmsg ("error: expected one of index or name!\n");
14237       return -99;
14238     }
14239
14240   if (is_index_set && is_name_set)
14241     {
14242       errmsg ("error: only one param expected!\n");
14243       return -99;
14244     }
14245
14246   if (vec_len (ls_name) > 62)
14247     {
14248       errmsg ("error: locator set name too long!");
14249       return -99;
14250     }
14251
14252   if (!vam->json_output)
14253     {
14254       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
14255                "weight");
14256     }
14257
14258   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
14259   mp->is_index_set = is_index_set;
14260
14261   if (is_index_set)
14262     mp->ls_index = clib_host_to_net_u32 (ls_index);
14263   else
14264     {
14265       vec_add1 (ls_name, 0);
14266       strncpy ((char *) mp->ls_name, (char *) ls_name,
14267                sizeof (mp->ls_name) - 1);
14268     }
14269
14270   /* send it... */
14271   S;
14272
14273   /* Use a control ping for synchronization */
14274   {
14275     vl_api_control_ping_t *mp;
14276     M (CONTROL_PING, control_ping);
14277     S;
14278   }
14279   /* Wait for a reply... */
14280   W;
14281
14282   /* NOTREACHED */
14283   return 0;
14284 }
14285
14286 static int
14287 api_lisp_locator_set_dump (vat_main_t * vam)
14288 {
14289   vl_api_lisp_locator_set_dump_t *mp;
14290   unformat_input_t *input = vam->input;
14291   f64 timeout = ~0;
14292   u8 filter = 0;
14293
14294   /* Parse args required to build the message */
14295   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14296     {
14297       if (unformat (input, "local"))
14298         {
14299           filter = 1;
14300         }
14301       else if (unformat (input, "remote"))
14302         {
14303           filter = 2;
14304         }
14305       else
14306         {
14307           errmsg ("parse error '%U'", format_unformat_error, input);
14308           return -99;
14309         }
14310     }
14311
14312   if (!vam->json_output)
14313     {
14314       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
14315     }
14316
14317   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14318
14319   mp->filter = filter;
14320
14321   /* send it... */
14322   S;
14323
14324   /* Use a control ping for synchronization */
14325   {
14326     vl_api_control_ping_t *mp;
14327     M (CONTROL_PING, control_ping);
14328     S;
14329   }
14330   /* Wait for a reply... */
14331   W;
14332
14333   /* NOTREACHED */
14334   return 0;
14335 }
14336
14337 static int
14338 api_lisp_eid_table_map_dump (vat_main_t * vam)
14339 {
14340   u8 is_l2 = 0;
14341   u8 mode_set = 0;
14342   unformat_input_t *input = vam->input;
14343   vl_api_lisp_eid_table_map_dump_t *mp;
14344   f64 timeout = ~0;
14345
14346   /* Parse args required to build the message */
14347   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14348     {
14349       if (unformat (input, "l2"))
14350         {
14351           is_l2 = 1;
14352           mode_set = 1;
14353         }
14354       else if (unformat (input, "l3"))
14355         {
14356           is_l2 = 0;
14357           mode_set = 1;
14358         }
14359       else
14360         {
14361           errmsg ("parse error '%U'", format_unformat_error, input);
14362           return -99;
14363         }
14364     }
14365
14366   if (!mode_set)
14367     {
14368       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
14369       return -99;
14370     }
14371
14372   if (!vam->json_output)
14373     {
14374       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
14375     }
14376
14377   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14378   mp->is_l2 = is_l2;
14379
14380   /* send it... */
14381   S;
14382
14383   /* Use a control ping for synchronization */
14384   {
14385     vl_api_control_ping_t *mp;
14386     M (CONTROL_PING, control_ping);
14387     S;
14388   }
14389   /* Wait for a reply... */
14390   W;
14391
14392   /* NOTREACHED */
14393   return 0;
14394 }
14395
14396 static int
14397 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14398 {
14399   vl_api_lisp_eid_table_vni_dump_t *mp;
14400   f64 timeout = ~0;
14401
14402   if (!vam->json_output)
14403     {
14404       fformat (vam->ofp, "VNI\n");
14405     }
14406
14407   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14408
14409   /* send it... */
14410   S;
14411
14412   /* Use a control ping for synchronization */
14413   {
14414     vl_api_control_ping_t *mp;
14415     M (CONTROL_PING, control_ping);
14416     S;
14417   }
14418   /* Wait for a reply... */
14419   W;
14420
14421   /* NOTREACHED */
14422   return 0;
14423 }
14424
14425 static int
14426 api_lisp_eid_table_dump (vat_main_t * vam)
14427 {
14428   unformat_input_t *i = vam->input;
14429   vl_api_lisp_eid_table_dump_t *mp;
14430   f64 timeout = ~0;
14431   struct in_addr ip4;
14432   struct in6_addr ip6;
14433   u8 mac[6];
14434   u8 eid_type = ~0, eid_set = 0;
14435   u32 prefix_length = ~0, t, vni = 0;
14436   u8 filter = 0;
14437
14438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14439     {
14440       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14441         {
14442           eid_set = 1;
14443           eid_type = 0;
14444           prefix_length = t;
14445         }
14446       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14447         {
14448           eid_set = 1;
14449           eid_type = 1;
14450           prefix_length = t;
14451         }
14452       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14453         {
14454           eid_set = 1;
14455           eid_type = 2;
14456         }
14457       else if (unformat (i, "vni %d", &t))
14458         {
14459           vni = t;
14460         }
14461       else if (unformat (i, "local"))
14462         {
14463           filter = 1;
14464         }
14465       else if (unformat (i, "remote"))
14466         {
14467           filter = 2;
14468         }
14469       else
14470         {
14471           errmsg ("parse error '%U'", format_unformat_error, i);
14472           return -99;
14473         }
14474     }
14475
14476   if (!vam->json_output)
14477     {
14478       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s\n", "EID",
14479                "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14480     }
14481
14482   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14483
14484   mp->filter = filter;
14485   if (eid_set)
14486     {
14487       mp->eid_set = 1;
14488       mp->vni = htonl (vni);
14489       mp->eid_type = eid_type;
14490       switch (eid_type)
14491         {
14492         case 0:
14493           mp->prefix_length = prefix_length;
14494           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14495           break;
14496         case 1:
14497           mp->prefix_length = prefix_length;
14498           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14499           break;
14500         case 2:
14501           clib_memcpy (mp->eid, mac, sizeof (mac));
14502           break;
14503         default:
14504           errmsg ("unknown EID type %d!", eid_type);
14505           return -99;
14506         }
14507     }
14508
14509   /* send it... */
14510   S;
14511
14512   /* Use a control ping for synchronization */
14513   {
14514     vl_api_control_ping_t *mp;
14515     M (CONTROL_PING, control_ping);
14516     S;
14517   }
14518
14519   /* Wait for a reply... */
14520   W;
14521
14522   /* NOTREACHED */
14523   return 0;
14524 }
14525
14526 static int
14527 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14528 {
14529   vl_api_lisp_gpe_tunnel_dump_t *mp;
14530   f64 timeout = ~0;
14531
14532   if (!vam->json_output)
14533     {
14534       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14535                "%=16s%=16s%=16s%=16s%=16s\n",
14536                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14537                "Decap next", "Lisp version", "Flags", "Next protocol",
14538                "ver_res", "res", "iid");
14539     }
14540
14541   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14542   /* send it... */
14543   S;
14544
14545   /* Use a control ping for synchronization */
14546   {
14547     vl_api_control_ping_t *mp;
14548     M (CONTROL_PING, control_ping);
14549     S;
14550   }
14551   /* Wait for a reply... */
14552   W;
14553
14554   /* NOTREACHED */
14555   return 0;
14556 }
14557
14558 static int
14559 api_lisp_adjacencies_get (vat_main_t * vam)
14560 {
14561   unformat_input_t *i = vam->input;
14562   vl_api_lisp_adjacencies_get_t *mp;
14563   f64 timeout = ~0;
14564   u8 vni_set = 0;
14565   u32 vni = ~0;
14566
14567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14568     {
14569       if (unformat (i, "vni %d", &vni))
14570         {
14571           vni_set = 1;
14572         }
14573       else
14574         {
14575           errmsg ("parse error '%U'\n", format_unformat_error, i);
14576           return -99;
14577         }
14578     }
14579
14580   if (!vni_set)
14581     {
14582       errmsg ("vni not set!\n");
14583       return -99;
14584     }
14585
14586   if (!vam->json_output)
14587     {
14588       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14589     }
14590
14591   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14592   mp->vni = clib_host_to_net_u32 (vni);
14593
14594   /* send it... */
14595   S;
14596
14597   /* Wait for a reply... */
14598   W;
14599
14600   /* NOTREACHED */
14601   return 0;
14602 }
14603
14604 static int
14605 api_lisp_map_server_dump (vat_main_t * vam)
14606 {
14607   vl_api_lisp_map_server_dump_t *mp;
14608   f64 timeout = ~0;
14609
14610   if (!vam->json_output)
14611     {
14612       fformat (vam->ofp, "%=20s\n", "Map server");
14613     }
14614
14615   M (LISP_MAP_SERVER_DUMP, lisp_map_server_dump);
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_lisp_map_resolver_dump (vat_main_t * vam)
14634 {
14635   vl_api_lisp_map_resolver_dump_t *mp;
14636   f64 timeout = ~0;
14637
14638   if (!vam->json_output)
14639     {
14640       fformat (vam->ofp, "%=20s\n", "Map resolver");
14641     }
14642
14643   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14644   /* send it... */
14645   S;
14646
14647   /* Use a control ping for synchronization */
14648   {
14649     vl_api_control_ping_t *mp;
14650     M (CONTROL_PING, control_ping);
14651     S;
14652   }
14653   /* Wait for a reply... */
14654   W;
14655
14656   /* NOTREACHED */
14657   return 0;
14658 }
14659
14660 static int
14661 api_show_lisp_status (vat_main_t * vam)
14662 {
14663   vl_api_show_lisp_status_t *mp;
14664   f64 timeout = ~0;
14665
14666   if (!vam->json_output)
14667     {
14668       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14669     }
14670
14671   M (SHOW_LISP_STATUS, show_lisp_status);
14672   /* send it... */
14673   S;
14674   /* Wait for a reply... */
14675   W;
14676
14677   /* NOTREACHED */
14678   return 0;
14679 }
14680
14681 static int
14682 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14683 {
14684   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14685   f64 timeout = ~0;
14686
14687   if (!vam->json_output)
14688     {
14689       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14690     }
14691
14692   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14693   /* send it... */
14694   S;
14695   /* Wait for a reply... */
14696   W;
14697
14698   /* NOTREACHED */
14699   return 0;
14700 }
14701
14702 static int
14703 api_af_packet_create (vat_main_t * vam)
14704 {
14705   unformat_input_t *i = vam->input;
14706   vl_api_af_packet_create_t *mp;
14707   f64 timeout;
14708   u8 *host_if_name = 0;
14709   u8 hw_addr[6];
14710   u8 random_hw_addr = 1;
14711
14712   memset (hw_addr, 0, sizeof (hw_addr));
14713
14714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14715     {
14716       if (unformat (i, "name %s", &host_if_name))
14717         vec_add1 (host_if_name, 0);
14718       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14719         random_hw_addr = 0;
14720       else
14721         break;
14722     }
14723
14724   if (!vec_len (host_if_name))
14725     {
14726       errmsg ("host-interface name must be specified");
14727       return -99;
14728     }
14729
14730   if (vec_len (host_if_name) > 64)
14731     {
14732       errmsg ("host-interface name too long");
14733       return -99;
14734     }
14735
14736   M (AF_PACKET_CREATE, af_packet_create);
14737
14738   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14739   clib_memcpy (mp->hw_addr, hw_addr, 6);
14740   mp->use_random_hw_addr = random_hw_addr;
14741   vec_free (host_if_name);
14742
14743   S;
14744   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14745   /* NOTREACHED */
14746   return 0;
14747 }
14748
14749 static int
14750 api_af_packet_delete (vat_main_t * vam)
14751 {
14752   unformat_input_t *i = vam->input;
14753   vl_api_af_packet_delete_t *mp;
14754   f64 timeout;
14755   u8 *host_if_name = 0;
14756
14757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14758     {
14759       if (unformat (i, "name %s", &host_if_name))
14760         vec_add1 (host_if_name, 0);
14761       else
14762         break;
14763     }
14764
14765   if (!vec_len (host_if_name))
14766     {
14767       errmsg ("host-interface name must be specified");
14768       return -99;
14769     }
14770
14771   if (vec_len (host_if_name) > 64)
14772     {
14773       errmsg ("host-interface name too long");
14774       return -99;
14775     }
14776
14777   M (AF_PACKET_DELETE, af_packet_delete);
14778
14779   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14780   vec_free (host_if_name);
14781
14782   S;
14783   W;
14784   /* NOTREACHED */
14785   return 0;
14786 }
14787
14788 static int
14789 api_policer_add_del (vat_main_t * vam)
14790 {
14791   unformat_input_t *i = vam->input;
14792   vl_api_policer_add_del_t *mp;
14793   f64 timeout;
14794   u8 is_add = 1;
14795   u8 *name = 0;
14796   u32 cir = 0;
14797   u32 eir = 0;
14798   u64 cb = 0;
14799   u64 eb = 0;
14800   u8 rate_type = 0;
14801   u8 round_type = 0;
14802   u8 type = 0;
14803   u8 color_aware = 0;
14804   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14805
14806   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14807   conform_action.dscp = 0;
14808   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14809   exceed_action.dscp = 0;
14810   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14811   violate_action.dscp = 0;
14812
14813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14814     {
14815       if (unformat (i, "del"))
14816         is_add = 0;
14817       else if (unformat (i, "name %s", &name))
14818         vec_add1 (name, 0);
14819       else if (unformat (i, "cir %u", &cir))
14820         ;
14821       else if (unformat (i, "eir %u", &eir))
14822         ;
14823       else if (unformat (i, "cb %u", &cb))
14824         ;
14825       else if (unformat (i, "eb %u", &eb))
14826         ;
14827       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14828                          &rate_type))
14829         ;
14830       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14831                          &round_type))
14832         ;
14833       else if (unformat (i, "type %U", unformat_policer_type, &type))
14834         ;
14835       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14836                          &conform_action))
14837         ;
14838       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14839                          &exceed_action))
14840         ;
14841       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14842                          &violate_action))
14843         ;
14844       else if (unformat (i, "color-aware"))
14845         color_aware = 1;
14846       else
14847         break;
14848     }
14849
14850   if (!vec_len (name))
14851     {
14852       errmsg ("policer name must be specified");
14853       return -99;
14854     }
14855
14856   if (vec_len (name) > 64)
14857     {
14858       errmsg ("policer name too long");
14859       return -99;
14860     }
14861
14862   M (POLICER_ADD_DEL, policer_add_del);
14863
14864   clib_memcpy (mp->name, name, vec_len (name));
14865   vec_free (name);
14866   mp->is_add = is_add;
14867   mp->cir = cir;
14868   mp->eir = eir;
14869   mp->cb = cb;
14870   mp->eb = eb;
14871   mp->rate_type = rate_type;
14872   mp->round_type = round_type;
14873   mp->type = type;
14874   mp->conform_action_type = conform_action.action_type;
14875   mp->conform_dscp = conform_action.dscp;
14876   mp->exceed_action_type = exceed_action.action_type;
14877   mp->exceed_dscp = exceed_action.dscp;
14878   mp->violate_action_type = violate_action.action_type;
14879   mp->violate_dscp = violate_action.dscp;
14880   mp->color_aware = color_aware;
14881
14882   S;
14883   W;
14884   /* NOTREACHED */
14885   return 0;
14886 }
14887
14888 static int
14889 api_policer_dump (vat_main_t * vam)
14890 {
14891   unformat_input_t *i = vam->input;
14892   vl_api_policer_dump_t *mp;
14893   f64 timeout = ~0;
14894   u8 *match_name = 0;
14895   u8 match_name_valid = 0;
14896
14897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14898     {
14899       if (unformat (i, "name %s", &match_name))
14900         {
14901           vec_add1 (match_name, 0);
14902           match_name_valid = 1;
14903         }
14904       else
14905         break;
14906     }
14907
14908   M (POLICER_DUMP, policer_dump);
14909   mp->match_name_valid = match_name_valid;
14910   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14911   vec_free (match_name);
14912   /* send it... */
14913   S;
14914
14915   /* Use a control ping for synchronization */
14916   {
14917     vl_api_control_ping_t *mp;
14918     M (CONTROL_PING, control_ping);
14919     S;
14920   }
14921   /* Wait for a reply... */
14922   W;
14923
14924   /* NOTREACHED */
14925   return 0;
14926 }
14927
14928 static int
14929 api_policer_classify_set_interface (vat_main_t * vam)
14930 {
14931   unformat_input_t *i = vam->input;
14932   vl_api_policer_classify_set_interface_t *mp;
14933   f64 timeout;
14934   u32 sw_if_index;
14935   int sw_if_index_set;
14936   u32 ip4_table_index = ~0;
14937   u32 ip6_table_index = ~0;
14938   u32 l2_table_index = ~0;
14939   u8 is_add = 1;
14940
14941   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14942     {
14943       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14944         sw_if_index_set = 1;
14945       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14946         sw_if_index_set = 1;
14947       else if (unformat (i, "del"))
14948         is_add = 0;
14949       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14950         ;
14951       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14952         ;
14953       else if (unformat (i, "l2-table %d", &l2_table_index))
14954         ;
14955       else
14956         {
14957           clib_warning ("parse error '%U'", format_unformat_error, i);
14958           return -99;
14959         }
14960     }
14961
14962   if (sw_if_index_set == 0)
14963     {
14964       errmsg ("missing interface name or sw_if_index\n");
14965       return -99;
14966     }
14967
14968   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14969
14970   mp->sw_if_index = ntohl (sw_if_index);
14971   mp->ip4_table_index = ntohl (ip4_table_index);
14972   mp->ip6_table_index = ntohl (ip6_table_index);
14973   mp->l2_table_index = ntohl (l2_table_index);
14974   mp->is_add = is_add;
14975
14976   S;
14977   W;
14978   /* NOTREACHED */
14979   return 0;
14980 }
14981
14982 static int
14983 api_policer_classify_dump (vat_main_t * vam)
14984 {
14985   unformat_input_t *i = vam->input;
14986   vl_api_policer_classify_dump_t *mp;
14987   f64 timeout = ~0;
14988   u8 type = POLICER_CLASSIFY_N_TABLES;
14989
14990   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14991     ;
14992   else
14993     {
14994       errmsg ("classify table type must be specified\n");
14995       return -99;
14996     }
14997
14998   if (!vam->json_output)
14999     {
15000       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
15001     }
15002
15003   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
15004   mp->type = type;
15005   /* send it... */
15006   S;
15007
15008   /* Use a control ping for synchronization */
15009   {
15010     vl_api_control_ping_t *mp;
15011     M (CONTROL_PING, control_ping);
15012     S;
15013   }
15014   /* Wait for a reply... */
15015   W;
15016
15017   /* NOTREACHED */
15018   return 0;
15019 }
15020
15021 static int
15022 api_netmap_create (vat_main_t * vam)
15023 {
15024   unformat_input_t *i = vam->input;
15025   vl_api_netmap_create_t *mp;
15026   f64 timeout;
15027   u8 *if_name = 0;
15028   u8 hw_addr[6];
15029   u8 random_hw_addr = 1;
15030   u8 is_pipe = 0;
15031   u8 is_master = 0;
15032
15033   memset (hw_addr, 0, sizeof (hw_addr));
15034
15035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15036     {
15037       if (unformat (i, "name %s", &if_name))
15038         vec_add1 (if_name, 0);
15039       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15040         random_hw_addr = 0;
15041       else if (unformat (i, "pipe"))
15042         is_pipe = 1;
15043       else if (unformat (i, "master"))
15044         is_master = 1;
15045       else if (unformat (i, "slave"))
15046         is_master = 0;
15047       else
15048         break;
15049     }
15050
15051   if (!vec_len (if_name))
15052     {
15053       errmsg ("interface name must be specified");
15054       return -99;
15055     }
15056
15057   if (vec_len (if_name) > 64)
15058     {
15059       errmsg ("interface name too long");
15060       return -99;
15061     }
15062
15063   M (NETMAP_CREATE, netmap_create);
15064
15065   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15066   clib_memcpy (mp->hw_addr, hw_addr, 6);
15067   mp->use_random_hw_addr = random_hw_addr;
15068   mp->is_pipe = is_pipe;
15069   mp->is_master = is_master;
15070   vec_free (if_name);
15071
15072   S;
15073   W;
15074   /* NOTREACHED */
15075   return 0;
15076 }
15077
15078 static int
15079 api_netmap_delete (vat_main_t * vam)
15080 {
15081   unformat_input_t *i = vam->input;
15082   vl_api_netmap_delete_t *mp;
15083   f64 timeout;
15084   u8 *if_name = 0;
15085
15086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15087     {
15088       if (unformat (i, "name %s", &if_name))
15089         vec_add1 (if_name, 0);
15090       else
15091         break;
15092     }
15093
15094   if (!vec_len (if_name))
15095     {
15096       errmsg ("interface name must be specified");
15097       return -99;
15098     }
15099
15100   if (vec_len (if_name) > 64)
15101     {
15102       errmsg ("interface name too long");
15103       return -99;
15104     }
15105
15106   M (NETMAP_DELETE, netmap_delete);
15107
15108   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15109   vec_free (if_name);
15110
15111   S;
15112   W;
15113   /* NOTREACHED */
15114   return 0;
15115 }
15116
15117 static void vl_api_mpls_tunnel_details_t_handler
15118   (vl_api_mpls_tunnel_details_t * mp)
15119 {
15120   vat_main_t *vam = &vat_main;
15121   i32 len = mp->mt_next_hop_n_labels;
15122   i32 i;
15123
15124   fformat (vam->ofp, "[%d]: via %U %d labels ",
15125            mp->tunnel_index,
15126            format_ip4_address, mp->mt_next_hop,
15127            ntohl (mp->mt_next_hop_sw_if_index));
15128   for (i = 0; i < len; i++)
15129     {
15130       fformat (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15131     }
15132   fformat (vam->ofp, "\n");
15133 }
15134
15135 static void vl_api_mpls_tunnel_details_t_handler_json
15136   (vl_api_mpls_tunnel_details_t * mp)
15137 {
15138   vat_main_t *vam = &vat_main;
15139   vat_json_node_t *node = NULL;
15140   struct in_addr ip4;
15141   i32 i;
15142   i32 len = mp->mt_next_hop_n_labels;
15143
15144   if (VAT_JSON_ARRAY != vam->json_tree.type)
15145     {
15146       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15147       vat_json_init_array (&vam->json_tree);
15148     }
15149   node = vat_json_array_add (&vam->json_tree);
15150
15151   vat_json_init_object (node);
15152   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15153   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15154   vat_json_object_add_ip4 (node, "next_hop", ip4);
15155   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15156                             ntohl (mp->mt_next_hop_sw_if_index));
15157   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15158   vat_json_object_add_uint (node, "label_count", len);
15159   for (i = 0; i < len; i++)
15160     {
15161       vat_json_object_add_uint (node, "label",
15162                                 ntohl (mp->mt_next_hop_out_labels[i]));
15163     }
15164 }
15165
15166 static int
15167 api_mpls_tunnel_dump (vat_main_t * vam)
15168 {
15169   vl_api_mpls_tunnel_dump_t *mp;
15170   f64 timeout;
15171   i32 index = -1;
15172
15173   /* Parse args required to build the message */
15174   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15175     {
15176       if (!unformat (vam->input, "tunnel_index %d", &index))
15177         {
15178           index = -1;
15179           break;
15180         }
15181     }
15182
15183   fformat (vam->ofp, "  tunnel_index %d\n", index);
15184
15185   M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
15186   mp->tunnel_index = htonl (index);
15187   S;
15188
15189   /* Use a control ping for synchronization */
15190   {
15191     vl_api_control_ping_t *mp;
15192     M (CONTROL_PING, control_ping);
15193     S;
15194   }
15195   W;
15196 }
15197
15198 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15199 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15200
15201 static void
15202 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15203 {
15204   vat_main_t *vam = &vat_main;
15205   int count = ntohl (mp->count);
15206   vl_api_fib_path_t *fp;
15207   int i;
15208
15209   fformat (vam->ofp,
15210            "table-id %d, label %u, ess_bit %u\n",
15211            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15212   fp = mp->path;
15213   for (i = 0; i < count; i++)
15214     {
15215       if (fp->afi == IP46_TYPE_IP6)
15216         fformat (vam->ofp,
15217                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15218                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15219                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15220                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15221                  format_ip6_address, fp->next_hop);
15222       else if (fp->afi == IP46_TYPE_IP4)
15223         fformat (vam->ofp,
15224                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15225                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15226                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15227                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15228                  format_ip4_address, fp->next_hop);
15229       fp++;
15230     }
15231 }
15232
15233 static void vl_api_mpls_fib_details_t_handler_json
15234   (vl_api_mpls_fib_details_t * mp)
15235 {
15236   vat_main_t *vam = &vat_main;
15237   int count = ntohl (mp->count);
15238   vat_json_node_t *node = NULL;
15239   struct in_addr ip4;
15240   struct in6_addr ip6;
15241   vl_api_fib_path_t *fp;
15242   int i;
15243
15244   if (VAT_JSON_ARRAY != vam->json_tree.type)
15245     {
15246       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15247       vat_json_init_array (&vam->json_tree);
15248     }
15249   node = vat_json_array_add (&vam->json_tree);
15250
15251   vat_json_init_object (node);
15252   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15253   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15254   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15255   vat_json_object_add_uint (node, "path_count", count);
15256   fp = mp->path;
15257   for (i = 0; i < count; i++)
15258     {
15259       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15260       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15261       vat_json_object_add_uint (node, "is_local", fp->is_local);
15262       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15263       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15264       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15265       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15266       if (fp->afi == IP46_TYPE_IP4)
15267         {
15268           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15269           vat_json_object_add_ip4 (node, "next_hop", ip4);
15270         }
15271       else if (fp->afi == IP46_TYPE_IP6)
15272         {
15273           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15274           vat_json_object_add_ip6 (node, "next_hop", ip6);
15275         }
15276     }
15277 }
15278
15279 static int
15280 api_mpls_fib_dump (vat_main_t * vam)
15281 {
15282   vl_api_mpls_fib_dump_t *mp;
15283   f64 timeout;
15284
15285   M (MPLS_FIB_DUMP, mpls_fib_dump);
15286   S;
15287
15288   /* Use a control ping for synchronization */
15289   {
15290     vl_api_control_ping_t *mp;
15291     M (CONTROL_PING, control_ping);
15292     S;
15293   }
15294   W;
15295 }
15296
15297 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15298 #define vl_api_ip_fib_details_t_print vl_noop_handler
15299
15300 static void
15301 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15302 {
15303   vat_main_t *vam = &vat_main;
15304   int count = ntohl (mp->count);
15305   vl_api_fib_path_t *fp;
15306   int i;
15307
15308   fformat (vam->ofp,
15309            "table-id %d, prefix %U/%d\n",
15310            ntohl (mp->table_id), format_ip4_address, mp->address,
15311            mp->address_length);
15312   fp = mp->path;
15313   for (i = 0; i < count; i++)
15314     {
15315       if (fp->afi == IP46_TYPE_IP6)
15316         fformat (vam->ofp,
15317                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15318                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15319                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15320                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15321                  format_ip6_address, fp->next_hop);
15322       else if (fp->afi == IP46_TYPE_IP4)
15323         fformat (vam->ofp,
15324                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15325                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15326                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15327                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15328                  format_ip4_address, fp->next_hop);
15329       fp++;
15330     }
15331 }
15332
15333 static void vl_api_ip_fib_details_t_handler_json
15334   (vl_api_ip_fib_details_t * mp)
15335 {
15336   vat_main_t *vam = &vat_main;
15337   int count = ntohl (mp->count);
15338   vat_json_node_t *node = NULL;
15339   struct in_addr ip4;
15340   struct in6_addr ip6;
15341   vl_api_fib_path_t *fp;
15342   int i;
15343
15344   if (VAT_JSON_ARRAY != vam->json_tree.type)
15345     {
15346       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15347       vat_json_init_array (&vam->json_tree);
15348     }
15349   node = vat_json_array_add (&vam->json_tree);
15350
15351   vat_json_init_object (node);
15352   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15353   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15354   vat_json_object_add_ip4 (node, "prefix", ip4);
15355   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15356   vat_json_object_add_uint (node, "path_count", count);
15357   fp = mp->path;
15358   for (i = 0; i < count; i++)
15359     {
15360       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15361       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15362       vat_json_object_add_uint (node, "is_local", fp->is_local);
15363       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15364       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15365       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15366       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15367       if (fp->afi == IP46_TYPE_IP4)
15368         {
15369           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15370           vat_json_object_add_ip4 (node, "next_hop", ip4);
15371         }
15372       else if (fp->afi == IP46_TYPE_IP6)
15373         {
15374           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15375           vat_json_object_add_ip6 (node, "next_hop", ip6);
15376         }
15377     }
15378 }
15379
15380 static int
15381 api_ip_fib_dump (vat_main_t * vam)
15382 {
15383   vl_api_ip_fib_dump_t *mp;
15384   f64 timeout;
15385
15386   M (IP_FIB_DUMP, ip_fib_dump);
15387   S;
15388
15389   /* Use a control ping for synchronization */
15390   {
15391     vl_api_control_ping_t *mp;
15392     M (CONTROL_PING, control_ping);
15393     S;
15394   }
15395   W;
15396 }
15397
15398 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15399 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15400
15401 static void
15402 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15403 {
15404   vat_main_t *vam = &vat_main;
15405   int count = ntohl (mp->count);
15406   vl_api_fib_path_t *fp;
15407   int i;
15408
15409   fformat (vam->ofp,
15410            "table-id %d, prefix %U/%d\n",
15411            ntohl (mp->table_id), format_ip6_address, mp->address,
15412            mp->address_length);
15413   fp = mp->path;
15414   for (i = 0; i < count; i++)
15415     {
15416       if (fp->afi == IP46_TYPE_IP6)
15417         fformat (vam->ofp,
15418                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15419                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15420                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15421                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15422                  format_ip6_address, fp->next_hop);
15423       else if (fp->afi == IP46_TYPE_IP4)
15424         fformat (vam->ofp,
15425                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15426                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15427                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15428                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15429                  format_ip4_address, fp->next_hop);
15430       fp++;
15431     }
15432 }
15433
15434 static void vl_api_ip6_fib_details_t_handler_json
15435   (vl_api_ip6_fib_details_t * mp)
15436 {
15437   vat_main_t *vam = &vat_main;
15438   int count = ntohl (mp->count);
15439   vat_json_node_t *node = NULL;
15440   struct in_addr ip4;
15441   struct in6_addr ip6;
15442   vl_api_fib_path_t *fp;
15443   int i;
15444
15445   if (VAT_JSON_ARRAY != vam->json_tree.type)
15446     {
15447       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15448       vat_json_init_array (&vam->json_tree);
15449     }
15450   node = vat_json_array_add (&vam->json_tree);
15451
15452   vat_json_init_object (node);
15453   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15454   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15455   vat_json_object_add_ip6 (node, "prefix", ip6);
15456   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15457   vat_json_object_add_uint (node, "path_count", count);
15458   fp = mp->path;
15459   for (i = 0; i < count; i++)
15460     {
15461       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15462       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15463       vat_json_object_add_uint (node, "is_local", fp->is_local);
15464       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15465       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15466       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15467       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15468       if (fp->afi == IP46_TYPE_IP4)
15469         {
15470           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15471           vat_json_object_add_ip4 (node, "next_hop", ip4);
15472         }
15473       else if (fp->afi == IP46_TYPE_IP6)
15474         {
15475           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15476           vat_json_object_add_ip6 (node, "next_hop", ip6);
15477         }
15478     }
15479 }
15480
15481 static int
15482 api_ip6_fib_dump (vat_main_t * vam)
15483 {
15484   vl_api_ip6_fib_dump_t *mp;
15485   f64 timeout;
15486
15487   M (IP6_FIB_DUMP, ip6_fib_dump);
15488   S;
15489
15490   /* Use a control ping for synchronization */
15491   {
15492     vl_api_control_ping_t *mp;
15493     M (CONTROL_PING, control_ping);
15494     S;
15495   }
15496   W;
15497 }
15498
15499 int
15500 api_classify_table_ids (vat_main_t * vam)
15501 {
15502   vl_api_classify_table_ids_t *mp;
15503   f64 timeout;
15504
15505   /* Construct the API message */
15506   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15507   mp->context = 0;
15508
15509   S;
15510   W;
15511   /* NOTREACHED */
15512   return 0;
15513 }
15514
15515 int
15516 api_classify_table_by_interface (vat_main_t * vam)
15517 {
15518   unformat_input_t *input = vam->input;
15519   vl_api_classify_table_by_interface_t *mp;
15520   f64 timeout;
15521
15522   u32 sw_if_index = ~0;
15523   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15524     {
15525       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15526         ;
15527       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15528         ;
15529       else
15530         break;
15531     }
15532   if (sw_if_index == ~0)
15533     {
15534       errmsg ("missing interface name or sw_if_index\n");
15535       return -99;
15536     }
15537
15538   /* Construct the API message */
15539   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15540   mp->context = 0;
15541   mp->sw_if_index = ntohl (sw_if_index);
15542
15543   S;
15544   W;
15545   /* NOTREACHED */
15546   return 0;
15547 }
15548
15549 int
15550 api_classify_table_info (vat_main_t * vam)
15551 {
15552   unformat_input_t *input = vam->input;
15553   vl_api_classify_table_info_t *mp;
15554   f64 timeout;
15555
15556   u32 table_id = ~0;
15557   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15558     {
15559       if (unformat (input, "table_id %d", &table_id))
15560         ;
15561       else
15562         break;
15563     }
15564   if (table_id == ~0)
15565     {
15566       errmsg ("missing table id\n");
15567       return -99;
15568     }
15569
15570   /* Construct the API message */
15571   M (CLASSIFY_TABLE_INFO, classify_table_info);
15572   mp->context = 0;
15573   mp->table_id = ntohl (table_id);
15574
15575   S;
15576   W;
15577   /* NOTREACHED */
15578   return 0;
15579 }
15580
15581 int
15582 api_classify_session_dump (vat_main_t * vam)
15583 {
15584   unformat_input_t *input = vam->input;
15585   vl_api_classify_session_dump_t *mp;
15586   f64 timeout;
15587
15588   u32 table_id = ~0;
15589   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15590     {
15591       if (unformat (input, "table_id %d", &table_id))
15592         ;
15593       else
15594         break;
15595     }
15596   if (table_id == ~0)
15597     {
15598       errmsg ("missing table id\n");
15599       return -99;
15600     }
15601
15602   /* Construct the API message */
15603   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15604   mp->context = 0;
15605   mp->table_id = ntohl (table_id);
15606   S;
15607
15608   /* Use a control ping for synchronization */
15609   {
15610     vl_api_control_ping_t *mp;
15611     M (CONTROL_PING, control_ping);
15612     S;
15613   }
15614   W;
15615   /* NOTREACHED */
15616   return 0;
15617 }
15618
15619 static void
15620 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15621 {
15622   vat_main_t *vam = &vat_main;
15623
15624   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15625            "src_address %U, vrf_id %d, path_mtu %u, "
15626            "template_interval %u, udp_checksum %d\n",
15627            format_ip4_address, mp->collector_address,
15628            ntohs (mp->collector_port),
15629            format_ip4_address, mp->src_address,
15630            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15631            ntohl (mp->template_interval), mp->udp_checksum);
15632
15633   vam->retval = 0;
15634   vam->result_ready = 1;
15635 }
15636
15637 static void
15638   vl_api_ipfix_exporter_details_t_handler_json
15639   (vl_api_ipfix_exporter_details_t * mp)
15640 {
15641   vat_main_t *vam = &vat_main;
15642   vat_json_node_t node;
15643   struct in_addr collector_address;
15644   struct in_addr src_address;
15645
15646   vat_json_init_object (&node);
15647   clib_memcpy (&collector_address, &mp->collector_address,
15648                sizeof (collector_address));
15649   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15650   vat_json_object_add_uint (&node, "collector_port",
15651                             ntohs (mp->collector_port));
15652   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15653   vat_json_object_add_ip4 (&node, "src_address", src_address);
15654   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15655   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15656   vat_json_object_add_uint (&node, "template_interval",
15657                             ntohl (mp->template_interval));
15658   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15659
15660   vat_json_print (vam->ofp, &node);
15661   vat_json_free (&node);
15662   vam->retval = 0;
15663   vam->result_ready = 1;
15664 }
15665
15666 int
15667 api_ipfix_exporter_dump (vat_main_t * vam)
15668 {
15669   vl_api_ipfix_exporter_dump_t *mp;
15670   f64 timeout;
15671
15672   /* Construct the API message */
15673   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15674   mp->context = 0;
15675
15676   S;
15677   W;
15678   /* NOTREACHED */
15679   return 0;
15680 }
15681
15682 static int
15683 api_ipfix_classify_stream_dump (vat_main_t * vam)
15684 {
15685   vl_api_ipfix_classify_stream_dump_t *mp;
15686   f64 timeout;
15687
15688   /* Construct the API message */
15689   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15690   mp->context = 0;
15691
15692   S;
15693   W;
15694   /* NOTREACHED */
15695   return 0;
15696 }
15697
15698 static void
15699   vl_api_ipfix_classify_stream_details_t_handler
15700   (vl_api_ipfix_classify_stream_details_t * mp)
15701 {
15702   vat_main_t *vam = &vat_main;
15703   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15704            ntohl (mp->domain_id), ntohs (mp->src_port));
15705   vam->retval = 0;
15706   vam->result_ready = 1;
15707 }
15708
15709 static void
15710   vl_api_ipfix_classify_stream_details_t_handler_json
15711   (vl_api_ipfix_classify_stream_details_t * mp)
15712 {
15713   vat_main_t *vam = &vat_main;
15714   vat_json_node_t node;
15715
15716   vat_json_init_object (&node);
15717   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15718   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15719
15720   vat_json_print (vam->ofp, &node);
15721   vat_json_free (&node);
15722   vam->retval = 0;
15723   vam->result_ready = 1;
15724 }
15725
15726 static int
15727 api_ipfix_classify_table_dump (vat_main_t * vam)
15728 {
15729   vl_api_ipfix_classify_table_dump_t *mp;
15730   f64 timeout;
15731
15732   if (!vam->json_output)
15733     {
15734       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15735                "transport_protocol");
15736     }
15737
15738   /* Construct the API message */
15739   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15740
15741   /* send it... */
15742   S;
15743
15744   /* Use a control ping for synchronization */
15745   {
15746     vl_api_control_ping_t *mp;
15747     M (CONTROL_PING, control_ping);
15748     S;
15749   }
15750   W;
15751 }
15752
15753 static void
15754   vl_api_ipfix_classify_table_details_t_handler
15755   (vl_api_ipfix_classify_table_details_t * mp)
15756 {
15757   vat_main_t *vam = &vat_main;
15758   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15759            mp->transport_protocol);
15760 }
15761
15762 static void
15763   vl_api_ipfix_classify_table_details_t_handler_json
15764   (vl_api_ipfix_classify_table_details_t * mp)
15765 {
15766   vat_json_node_t *node = NULL;
15767   vat_main_t *vam = &vat_main;
15768
15769   if (VAT_JSON_ARRAY != vam->json_tree.type)
15770     {
15771       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15772       vat_json_init_array (&vam->json_tree);
15773     }
15774
15775   node = vat_json_array_add (&vam->json_tree);
15776   vat_json_init_object (node);
15777
15778   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15779   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15780   vat_json_object_add_uint (node, "transport_protocol",
15781                             mp->transport_protocol);
15782 }
15783
15784 static int
15785 api_sw_interface_span_enable_disable (vat_main_t * vam)
15786 {
15787   unformat_input_t *i = vam->input;
15788   vl_api_sw_interface_span_enable_disable_t *mp;
15789   f64 timeout;
15790   u32 src_sw_if_index = ~0;
15791   u32 dst_sw_if_index = ~0;
15792   u8 enable = 1;
15793
15794   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15795     {
15796       if (unformat (i, "src %U", unformat_sw_if_index, vam, &src_sw_if_index))
15797         ;
15798       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15799         ;
15800       else
15801         if (unformat
15802             (i, "dst %U", unformat_sw_if_index, vam, &dst_sw_if_index))
15803         ;
15804       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15805         ;
15806       else if (unformat (i, "disable"))
15807         enable = 0;
15808       else
15809         break;
15810     }
15811
15812   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15813
15814   mp->sw_if_index_from = htonl (src_sw_if_index);
15815   mp->sw_if_index_to = htonl (dst_sw_if_index);
15816   mp->enable = enable;
15817
15818   S;
15819   W;
15820   /* NOTREACHED */
15821   return 0;
15822 }
15823
15824 static void
15825 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
15826                                             * mp)
15827 {
15828   vat_main_t *vam = &vat_main;
15829
15830   fformat (vam->ofp, "%u => %u\n",
15831            ntohl (mp->sw_if_index_from), ntohl (mp->sw_if_index_to));
15832 }
15833
15834 static void
15835   vl_api_sw_interface_span_details_t_handler_json
15836   (vl_api_sw_interface_span_details_t * mp)
15837 {
15838   vat_main_t *vam = &vat_main;
15839   vat_json_node_t *node = NULL;
15840
15841   if (VAT_JSON_ARRAY != vam->json_tree.type)
15842     {
15843       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15844       vat_json_init_array (&vam->json_tree);
15845     }
15846   node = vat_json_array_add (&vam->json_tree);
15847
15848   vat_json_init_object (node);
15849   vat_json_object_add_uint (node, "src-if-index",
15850                             ntohl (mp->sw_if_index_from));
15851   vat_json_object_add_uint (node, "dst-if-index", ntohl (mp->sw_if_index_to));
15852 }
15853
15854 static int
15855 api_sw_interface_span_dump (vat_main_t * vam)
15856 {
15857   vl_api_sw_interface_span_dump_t *mp;
15858   f64 timeout;
15859
15860   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
15861   S;
15862
15863   /* Use a control ping for synchronization */
15864   {
15865     vl_api_control_ping_t *mp;
15866     M (CONTROL_PING, control_ping);
15867     S;
15868   }
15869   W;
15870 }
15871
15872 int
15873 api_pg_create_interface (vat_main_t * vam)
15874 {
15875   unformat_input_t *input = vam->input;
15876   vl_api_pg_create_interface_t *mp;
15877   f64 timeout;
15878
15879   u32 if_id = ~0;
15880   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15881     {
15882       if (unformat (input, "if_id %d", &if_id))
15883         ;
15884       else
15885         break;
15886     }
15887   if (if_id == ~0)
15888     {
15889       errmsg ("missing pg interface index\n");
15890       return -99;
15891     }
15892
15893   /* Construct the API message */
15894   M (PG_CREATE_INTERFACE, pg_create_interface);
15895   mp->context = 0;
15896   mp->interface_id = ntohl (if_id);
15897
15898   S;
15899   W;
15900   /* NOTREACHED */
15901   return 0;
15902 }
15903
15904 int
15905 api_pg_capture (vat_main_t * vam)
15906 {
15907   unformat_input_t *input = vam->input;
15908   vl_api_pg_capture_t *mp;
15909   f64 timeout;
15910
15911   u32 if_id = ~0;
15912   u8 enable = 1;
15913   u32 count = 1;
15914   u8 pcap_file_set = 0;
15915   u8 *pcap_file = 0;
15916   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15917     {
15918       if (unformat (input, "if_id %d", &if_id))
15919         ;
15920       else if (unformat (input, "pcap %s", &pcap_file))
15921         pcap_file_set = 1;
15922       else if (unformat (input, "count %d", &count))
15923         ;
15924       else if (unformat (input, "disable"))
15925         enable = 0;
15926       else
15927         break;
15928     }
15929   if (if_id == ~0)
15930     {
15931       errmsg ("missing pg interface index\n");
15932       return -99;
15933     }
15934   if (pcap_file_set > 0)
15935     {
15936       if (vec_len (pcap_file) > 255)
15937         {
15938           errmsg ("pcap file name is too long\n");
15939           return -99;
15940         }
15941     }
15942
15943   u32 name_len = vec_len (pcap_file);
15944   /* Construct the API message */
15945   M (PG_CAPTURE, pg_capture);
15946   mp->context = 0;
15947   mp->interface_id = ntohl (if_id);
15948   mp->is_enabled = enable;
15949   mp->count = ntohl (count);
15950   mp->pcap_name_length = ntohl (name_len);
15951   if (pcap_file_set != 0)
15952     {
15953       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15954     }
15955   vec_free (pcap_file);
15956
15957   S;
15958   W;
15959   /* NOTREACHED */
15960   return 0;
15961 }
15962
15963 int
15964 api_pg_enable_disable (vat_main_t * vam)
15965 {
15966   unformat_input_t *input = vam->input;
15967   vl_api_pg_enable_disable_t *mp;
15968   f64 timeout;
15969
15970   u8 enable = 1;
15971   u8 stream_name_set = 0;
15972   u8 *stream_name = 0;
15973   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15974     {
15975       if (unformat (input, "stream %s", &stream_name))
15976         stream_name_set = 1;
15977       else if (unformat (input, "disable"))
15978         enable = 0;
15979       else
15980         break;
15981     }
15982
15983   if (stream_name_set > 0)
15984     {
15985       if (vec_len (stream_name) > 255)
15986         {
15987           errmsg ("stream name too long\n");
15988           return -99;
15989         }
15990     }
15991
15992   u32 name_len = vec_len (stream_name);
15993   /* Construct the API message */
15994   M (PG_ENABLE_DISABLE, pg_enable_disable);
15995   mp->context = 0;
15996   mp->is_enabled = enable;
15997   if (stream_name_set != 0)
15998     {
15999       mp->stream_name_length = ntohl (name_len);
16000       clib_memcpy (mp->stream_name, stream_name, name_len);
16001     }
16002   vec_free (stream_name);
16003
16004   S;
16005   W;
16006   /* NOTREACHED */
16007   return 0;
16008 }
16009
16010 int
16011 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16012 {
16013   unformat_input_t *input = vam->input;
16014   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16015   f64 timeout;
16016
16017   u16 *low_ports = 0;
16018   u16 *high_ports = 0;
16019   u16 this_low;
16020   u16 this_hi;
16021   ip4_address_t ip4_addr;
16022   ip6_address_t ip6_addr;
16023   u32 length;
16024   u32 tmp, tmp2;
16025   u8 prefix_set = 0;
16026   u32 vrf_id = ~0;
16027   u8 is_add = 1;
16028   u8 is_ipv6 = 0;
16029
16030   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16031     {
16032       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16033         {
16034           prefix_set = 1;
16035         }
16036       else
16037         if (unformat
16038             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16039         {
16040           prefix_set = 1;
16041           is_ipv6 = 1;
16042         }
16043       else if (unformat (input, "vrf %d", &vrf_id))
16044         ;
16045       else if (unformat (input, "del"))
16046         is_add = 0;
16047       else if (unformat (input, "port %d", &tmp))
16048         {
16049           if (tmp == 0 || tmp > 65535)
16050             {
16051               errmsg ("port %d out of range", tmp);
16052               return -99;
16053             }
16054           this_low = tmp;
16055           this_hi = this_low + 1;
16056           vec_add1 (low_ports, this_low);
16057           vec_add1 (high_ports, this_hi);
16058         }
16059       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16060         {
16061           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16062             {
16063               errmsg ("incorrect range parameters\n");
16064               return -99;
16065             }
16066           this_low = tmp;
16067           /* Note: in debug CLI +1 is added to high before
16068              passing to real fn that does "the work"
16069              (ip_source_and_port_range_check_add_del).
16070              This fn is a wrapper around the binary API fn a
16071              control plane will call, which expects this increment
16072              to have occurred. Hence letting the binary API control
16073              plane fn do the increment for consistency between VAT
16074              and other control planes.
16075            */
16076           this_hi = tmp2;
16077           vec_add1 (low_ports, this_low);
16078           vec_add1 (high_ports, this_hi);
16079         }
16080       else
16081         break;
16082     }
16083
16084   if (prefix_set == 0)
16085     {
16086       errmsg ("<address>/<mask> not specified\n");
16087       return -99;
16088     }
16089
16090   if (vrf_id == ~0)
16091     {
16092       errmsg ("VRF ID required, not specified\n");
16093       return -99;
16094     }
16095
16096   if (vrf_id == 0)
16097     {
16098       errmsg
16099         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
16100       return -99;
16101     }
16102
16103   if (vec_len (low_ports) == 0)
16104     {
16105       errmsg ("At least one port or port range required\n");
16106       return -99;
16107     }
16108
16109   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
16110      ip_source_and_port_range_check_add_del);
16111
16112   mp->is_add = is_add;
16113
16114   if (is_ipv6)
16115     {
16116       mp->is_ipv6 = 1;
16117       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16118     }
16119   else
16120     {
16121       mp->is_ipv6 = 0;
16122       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16123     }
16124
16125   mp->mask_length = length;
16126   mp->number_of_ranges = vec_len (low_ports);
16127
16128   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16129   vec_free (low_ports);
16130
16131   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16132   vec_free (high_ports);
16133
16134   mp->vrf_id = ntohl (vrf_id);
16135
16136   S;
16137   W;
16138   /* NOTREACHED */
16139   return 0;
16140 }
16141
16142 int
16143 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16144 {
16145   unformat_input_t *input = vam->input;
16146   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16147   f64 timeout;
16148   u32 sw_if_index = ~0;
16149   int vrf_set = 0;
16150   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16151   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16152   u8 is_add = 1;
16153
16154   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16155     {
16156       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
16157         ;
16158       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16159         ;
16160       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16161         vrf_set = 1;
16162       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16163         vrf_set = 1;
16164       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16165         vrf_set = 1;
16166       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16167         vrf_set = 1;
16168       else if (unformat (input, "del"))
16169         is_add = 0;
16170       else
16171         break;
16172     }
16173
16174   if (sw_if_index == ~0)
16175     {
16176       errmsg ("Interface required but not specified\n");
16177       return -99;
16178     }
16179
16180   if (vrf_set == 0)
16181     {
16182       errmsg ("VRF ID required but not specified\n");
16183       return -99;
16184     }
16185
16186   if (tcp_out_vrf_id == 0
16187       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16188     {
16189       errmsg
16190         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
16191       return -99;
16192     }
16193
16194   /* Construct the API message */
16195   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
16196      ip_source_and_port_range_check_interface_add_del);
16197
16198   mp->sw_if_index = ntohl (sw_if_index);
16199   mp->is_add = is_add;
16200   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16201   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16202   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16203   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16204
16205   /* send it... */
16206   S;
16207
16208   /* Wait for a reply... */
16209   W;
16210 }
16211
16212 static int
16213 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16214 {
16215   unformat_input_t *i = vam->input;
16216   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16217   f64 timeout;
16218   u32 local_sa_id = 0;
16219   u32 remote_sa_id = 0;
16220   ip4_address_t src_address;
16221   ip4_address_t dst_address;
16222   u8 is_add = 1;
16223
16224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16225     {
16226       if (unformat (i, "local_sa %d", &local_sa_id))
16227         ;
16228       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16229         ;
16230       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16231         ;
16232       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16233         ;
16234       else if (unformat (i, "del"))
16235         is_add = 0;
16236       else
16237         {
16238           clib_warning ("parse error '%U'", format_unformat_error, i);
16239           return -99;
16240         }
16241     }
16242
16243   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16244
16245   mp->local_sa_id = ntohl (local_sa_id);
16246   mp->remote_sa_id = ntohl (remote_sa_id);
16247   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16248   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16249   mp->is_add = is_add;
16250
16251   S;
16252   W;
16253   /* NOTREACHED */
16254   return 0;
16255 }
16256
16257 static int
16258 api_punt (vat_main_t * vam)
16259 {
16260   unformat_input_t *i = vam->input;
16261   vl_api_punt_t *mp;
16262   f64 timeout;
16263   u32 ipv = ~0;
16264   u32 protocol = ~0;
16265   u32 port = ~0;
16266   int is_add = 1;
16267
16268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16269     {
16270       if (unformat (i, "ip %d", &ipv))
16271         ;
16272       else if (unformat (i, "protocol %d", &protocol))
16273         ;
16274       else if (unformat (i, "port %d", &port))
16275         ;
16276       else if (unformat (i, "del"))
16277         is_add = 0;
16278       else
16279         {
16280           clib_warning ("parse error '%U'", format_unformat_error, i);
16281           return -99;
16282         }
16283     }
16284
16285   M (PUNT, punt);
16286
16287   mp->is_add = (u8) is_add;
16288   mp->ipv = (u8) ipv;
16289   mp->l4_protocol = (u8) protocol;
16290   mp->l4_port = htons ((u16) port);
16291
16292   S;
16293   W;
16294   /* NOTREACHED */
16295   return 0;
16296 }
16297
16298 static void vl_api_ipsec_gre_tunnel_details_t_handler
16299   (vl_api_ipsec_gre_tunnel_details_t * mp)
16300 {
16301   vat_main_t *vam = &vat_main;
16302
16303   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
16304            ntohl (mp->sw_if_index),
16305            format_ip4_address, &mp->src_address,
16306            format_ip4_address, &mp->dst_address,
16307            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16308 }
16309
16310 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16311   (vl_api_ipsec_gre_tunnel_details_t * mp)
16312 {
16313   vat_main_t *vam = &vat_main;
16314   vat_json_node_t *node = NULL;
16315   struct in_addr ip4;
16316
16317   if (VAT_JSON_ARRAY != vam->json_tree.type)
16318     {
16319       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16320       vat_json_init_array (&vam->json_tree);
16321     }
16322   node = vat_json_array_add (&vam->json_tree);
16323
16324   vat_json_init_object (node);
16325   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16326   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16327   vat_json_object_add_ip4 (node, "src_address", ip4);
16328   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16329   vat_json_object_add_ip4 (node, "dst_address", ip4);
16330   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16331   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16332 }
16333
16334 static int
16335 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16336 {
16337   unformat_input_t *i = vam->input;
16338   vl_api_ipsec_gre_tunnel_dump_t *mp;
16339   f64 timeout;
16340   u32 sw_if_index;
16341   u8 sw_if_index_set = 0;
16342
16343   /* Parse args required to build the message */
16344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16345     {
16346       if (unformat (i, "sw_if_index %d", &sw_if_index))
16347         sw_if_index_set = 1;
16348       else
16349         break;
16350     }
16351
16352   if (sw_if_index_set == 0)
16353     {
16354       sw_if_index = ~0;
16355     }
16356
16357   if (!vam->json_output)
16358     {
16359       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
16360                "sw_if_index", "src_address", "dst_address",
16361                "local_sa_id", "remote_sa_id");
16362     }
16363
16364   /* Get list of gre-tunnel interfaces */
16365   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16366
16367   mp->sw_if_index = htonl (sw_if_index);
16368
16369   S;
16370
16371   /* Use a control ping for synchronization */
16372   {
16373     vl_api_control_ping_t *mp;
16374     M (CONTROL_PING, control_ping);
16375     S;
16376   }
16377   W;
16378 }
16379
16380 static int
16381 api_delete_subif (vat_main_t * vam)
16382 {
16383   unformat_input_t *i = vam->input;
16384   vl_api_delete_subif_t *mp;
16385   f64 timeout;
16386   u32 sw_if_index = ~0;
16387
16388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16389     {
16390       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16391         ;
16392       if (unformat (i, "sw_if_index %d", &sw_if_index))
16393         ;
16394       else
16395         break;
16396     }
16397
16398   if (sw_if_index == ~0)
16399     {
16400       errmsg ("missing sw_if_index\n");
16401       return -99;
16402     }
16403
16404   /* Construct the API message */
16405   M (DELETE_SUBIF, delete_subif);
16406   mp->sw_if_index = ntohl (sw_if_index);
16407
16408   S;
16409   W;
16410 }
16411
16412 #define foreach_pbb_vtr_op      \
16413 _("disable",  L2_VTR_DISABLED)  \
16414 _("pop",  L2_VTR_POP_2)         \
16415 _("push",  L2_VTR_PUSH_2)
16416
16417 static int
16418 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16419 {
16420   unformat_input_t *i = vam->input;
16421   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16422   f64 timeout;
16423   u32 sw_if_index = ~0, vtr_op = ~0;
16424   u16 outer_tag = ~0;
16425   u8 dmac[6], smac[6];
16426   u8 dmac_set = 0, smac_set = 0;
16427   u16 vlanid = 0;
16428   u32 sid = ~0;
16429   u32 tmp;
16430
16431   /* Shut up coverity */
16432   memset (dmac, 0, sizeof (dmac));
16433   memset (smac, 0, sizeof (smac));
16434
16435   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16436     {
16437       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16438         ;
16439       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16440         ;
16441       else if (unformat (i, "vtr_op %d", &vtr_op))
16442         ;
16443 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16444       foreach_pbb_vtr_op
16445 #undef _
16446         else if (unformat (i, "translate_pbb_stag"))
16447         {
16448           if (unformat (i, "%d", &tmp))
16449             {
16450               vtr_op = L2_VTR_TRANSLATE_2_1;
16451               outer_tag = tmp;
16452             }
16453           else
16454             {
16455               errmsg
16456                 ("translate_pbb_stag operation requires outer tag definition\n");
16457               return -99;
16458             }
16459         }
16460       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16461         dmac_set++;
16462       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16463         smac_set++;
16464       else if (unformat (i, "sid %d", &sid))
16465         ;
16466       else if (unformat (i, "vlanid %d", &tmp))
16467         vlanid = tmp;
16468       else
16469         {
16470           clib_warning ("parse error '%U'", format_unformat_error, i);
16471           return -99;
16472         }
16473     }
16474
16475   if ((sw_if_index == ~0) || (vtr_op == ~0))
16476     {
16477       errmsg ("missing sw_if_index or vtr operation\n");
16478       return -99;
16479     }
16480   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16481       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16482     {
16483       errmsg
16484         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
16485       return -99;
16486     }
16487
16488   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16489   mp->sw_if_index = ntohl (sw_if_index);
16490   mp->vtr_op = ntohl (vtr_op);
16491   mp->outer_tag = ntohs (outer_tag);
16492   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16493   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16494   mp->b_vlanid = ntohs (vlanid);
16495   mp->i_sid = ntohl (sid);
16496
16497   S;
16498   W;
16499   /* NOTREACHED */
16500   return 0;
16501 }
16502
16503 static int
16504 api_flow_classify_set_interface (vat_main_t * vam)
16505 {
16506   unformat_input_t *i = vam->input;
16507   vl_api_flow_classify_set_interface_t *mp;
16508   f64 timeout;
16509   u32 sw_if_index;
16510   int sw_if_index_set;
16511   u32 ip4_table_index = ~0;
16512   u32 ip6_table_index = ~0;
16513   u8 is_add = 1;
16514
16515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16516     {
16517       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16518         sw_if_index_set = 1;
16519       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16520         sw_if_index_set = 1;
16521       else if (unformat (i, "del"))
16522         is_add = 0;
16523       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16524         ;
16525       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16526         ;
16527       else
16528         {
16529           clib_warning ("parse error '%U'", format_unformat_error, i);
16530           return -99;
16531         }
16532     }
16533
16534   if (sw_if_index_set == 0)
16535     {
16536       errmsg ("missing interface name or sw_if_index\n");
16537       return -99;
16538     }
16539
16540   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16541
16542   mp->sw_if_index = ntohl (sw_if_index);
16543   mp->ip4_table_index = ntohl (ip4_table_index);
16544   mp->ip6_table_index = ntohl (ip6_table_index);
16545   mp->is_add = is_add;
16546
16547   S;
16548   W;
16549   /* NOTREACHED */
16550   return 0;
16551 }
16552
16553 static int
16554 api_flow_classify_dump (vat_main_t * vam)
16555 {
16556   unformat_input_t *i = vam->input;
16557   vl_api_flow_classify_dump_t *mp;
16558   f64 timeout = ~0;
16559   u8 type = FLOW_CLASSIFY_N_TABLES;
16560
16561   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16562     ;
16563   else
16564     {
16565       errmsg ("classify table type must be specified\n");
16566       return -99;
16567     }
16568
16569   if (!vam->json_output)
16570     {
16571       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
16572     }
16573
16574   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16575   mp->type = type;
16576   /* send it... */
16577   S;
16578
16579   /* Use a control ping for synchronization */
16580   {
16581     vl_api_control_ping_t *mp;
16582     M (CONTROL_PING, control_ping);
16583     S;
16584   }
16585   /* Wait for a reply... */
16586   W;
16587
16588   /* NOTREACHED */
16589   return 0;
16590 }
16591
16592 static int
16593 api_feature_enable_disable (vat_main_t * vam)
16594 {
16595   unformat_input_t *i = vam->input;
16596   vl_api_feature_enable_disable_t *mp;
16597   f64 timeout;
16598   u8 *arc_name = 0;
16599   u8 *feature_name = 0;
16600   u32 sw_if_index = ~0;
16601   u8 enable = 1;
16602
16603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16604     {
16605       if (unformat (i, "arc_name %s", &arc_name))
16606         ;
16607       else if (unformat (i, "feature_name %s", &feature_name))
16608         ;
16609       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16610         ;
16611       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16612         ;
16613       else if (unformat (i, "disable"))
16614         enable = 0;
16615       else
16616         break;
16617     }
16618
16619   if (arc_name == 0)
16620     {
16621       errmsg ("missing arc name\n");
16622       return -99;
16623     }
16624   if (vec_len (arc_name) > 63)
16625     {
16626       errmsg ("arc name too long\n");
16627     }
16628
16629   if (feature_name == 0)
16630     {
16631       errmsg ("missing feature name\n");
16632       return -99;
16633     }
16634   if (vec_len (feature_name) > 63)
16635     {
16636       errmsg ("feature name too long\n");
16637     }
16638
16639   if (sw_if_index == ~0)
16640     {
16641       errmsg ("missing interface name or sw_if_index\n");
16642       return -99;
16643     }
16644
16645   /* Construct the API message */
16646   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16647   mp->sw_if_index = ntohl (sw_if_index);
16648   mp->enable = enable;
16649   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16650   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16651   vec_free (arc_name);
16652   vec_free (feature_name);
16653
16654   S;
16655   W;
16656 }
16657
16658 static int
16659 api_sw_interface_tag_add_del (vat_main_t * vam)
16660 {
16661   unformat_input_t *i = vam->input;
16662   vl_api_sw_interface_tag_add_del_t *mp;
16663   f64 timeout;
16664   u32 sw_if_index = ~0;
16665   u8 *tag = 0;
16666   u8 enable = 1;
16667
16668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16669     {
16670       if (unformat (i, "tag %s", &tag))
16671         ;
16672       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16673         ;
16674       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16675         ;
16676       else if (unformat (i, "del"))
16677         enable = 0;
16678       else
16679         break;
16680     }
16681
16682   if (sw_if_index == ~0)
16683     {
16684       errmsg ("missing interface name or sw_if_index\n");
16685       return -99;
16686     }
16687
16688   if (enable && (tag == 0))
16689     {
16690       errmsg ("no tag specified\n");
16691       return -99;
16692     }
16693
16694   /* Construct the API message */
16695   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
16696   mp->sw_if_index = ntohl (sw_if_index);
16697   mp->is_add = enable;
16698   if (enable)
16699     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
16700   vec_free (tag);
16701
16702   S;
16703   W;
16704 }
16705
16706 static void vl_api_l2_xconnect_details_t_handler
16707   (vl_api_l2_xconnect_details_t * mp)
16708 {
16709   vat_main_t *vam = &vat_main;
16710
16711   fformat (vam->ofp, "%15d%15d\n",
16712            ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
16713 }
16714
16715 static void vl_api_l2_xconnect_details_t_handler_json
16716   (vl_api_l2_xconnect_details_t * mp)
16717 {
16718   vat_main_t *vam = &vat_main;
16719   vat_json_node_t *node = NULL;
16720
16721   if (VAT_JSON_ARRAY != vam->json_tree.type)
16722     {
16723       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16724       vat_json_init_array (&vam->json_tree);
16725     }
16726   node = vat_json_array_add (&vam->json_tree);
16727
16728   vat_json_init_object (node);
16729   vat_json_object_add_uint (node, "rx_sw_if_index",
16730                             ntohl (mp->rx_sw_if_index));
16731   vat_json_object_add_uint (node, "tx_sw_if_index",
16732                             ntohl (mp->tx_sw_if_index));
16733 }
16734
16735 static int
16736 api_l2_xconnect_dump (vat_main_t * vam)
16737 {
16738   vl_api_l2_xconnect_dump_t *mp;
16739   f64 timeout;
16740
16741   if (!vam->json_output)
16742     {
16743       fformat (vam->ofp, "%15s%15s\n", "rx_sw_if_index", "tx_sw_if_index");
16744     }
16745
16746   M (L2_XCONNECT_DUMP, l2_xconnect_dump);
16747
16748   S;
16749
16750   /* Use a control ping for synchronization */
16751   {
16752     vl_api_control_ping_t *mp;
16753     M (CONTROL_PING, control_ping);
16754     S;
16755   }
16756   W;
16757 }
16758
16759 static int
16760 api_sw_interface_set_mtu (vat_main_t * vam)
16761 {
16762   unformat_input_t *i = vam->input;
16763   vl_api_sw_interface_set_mtu_t *mp;
16764   f64 timeout;
16765   u32 sw_if_index = ~0;
16766   u32 mtu = 0;
16767
16768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16769     {
16770       if (unformat (i, "mtu %d", &mtu))
16771         ;
16772       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16773         ;
16774       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16775         ;
16776       else
16777         break;
16778     }
16779
16780   if (sw_if_index == ~0)
16781     {
16782       errmsg ("missing interface name or sw_if_index\n");
16783       return -99;
16784     }
16785
16786   if (mtu == 0)
16787     {
16788       errmsg ("no mtu specified\n");
16789       return -99;
16790     }
16791
16792   /* Construct the API message */
16793   M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
16794   mp->sw_if_index = ntohl (sw_if_index);
16795   mp->mtu = ntohs ((u16) mtu);
16796
16797   S;
16798   W;
16799 }
16800
16801
16802 static int
16803 q_or_quit (vat_main_t * vam)
16804 {
16805   longjmp (vam->jump_buf, 1);
16806   return 0;                     /* not so much */
16807 }
16808
16809 static int
16810 q (vat_main_t * vam)
16811 {
16812   return q_or_quit (vam);
16813 }
16814
16815 static int
16816 quit (vat_main_t * vam)
16817 {
16818   return q_or_quit (vam);
16819 }
16820
16821 static int
16822 comment (vat_main_t * vam)
16823 {
16824   return 0;
16825 }
16826
16827 static int
16828 cmd_cmp (void *a1, void *a2)
16829 {
16830   u8 **c1 = a1;
16831   u8 **c2 = a2;
16832
16833   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
16834 }
16835
16836 static int
16837 help (vat_main_t * vam)
16838 {
16839   u8 **cmds = 0;
16840   u8 *name = 0;
16841   hash_pair_t *p;
16842   unformat_input_t *i = vam->input;
16843   int j;
16844
16845   if (unformat (i, "%s", &name))
16846     {
16847       uword *hs;
16848
16849       vec_add1 (name, 0);
16850
16851       hs = hash_get_mem (vam->help_by_name, name);
16852       if (hs)
16853         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
16854       else
16855         fformat (vam->ofp, "No such msg / command '%s'\n", name);
16856       vec_free (name);
16857       return 0;
16858     }
16859
16860   fformat (vam->ofp, "Help is available for the following:\n");
16861
16862     /* *INDENT-OFF* */
16863     hash_foreach_pair (p, vam->function_by_name,
16864     ({
16865       vec_add1 (cmds, (u8 *)(p->key));
16866     }));
16867     /* *INDENT-ON* */
16868
16869   vec_sort_with_function (cmds, cmd_cmp);
16870
16871   for (j = 0; j < vec_len (cmds); j++)
16872     fformat (vam->ofp, "%s\n", cmds[j]);
16873
16874   vec_free (cmds);
16875   return 0;
16876 }
16877
16878 static int
16879 set (vat_main_t * vam)
16880 {
16881   u8 *name = 0, *value = 0;
16882   unformat_input_t *i = vam->input;
16883
16884   if (unformat (i, "%s", &name))
16885     {
16886       /* The input buffer is a vector, not a string. */
16887       value = vec_dup (i->buffer);
16888       vec_delete (value, i->index, 0);
16889       /* Almost certainly has a trailing newline */
16890       if (value[vec_len (value) - 1] == '\n')
16891         value[vec_len (value) - 1] = 0;
16892       /* Make sure it's a proper string, one way or the other */
16893       vec_add1 (value, 0);
16894       (void) clib_macro_set_value (&vam->macro_main,
16895                                    (char *) name, (char *) value);
16896     }
16897   else
16898     errmsg ("usage: set <name> <value>\n");
16899
16900   vec_free (name);
16901   vec_free (value);
16902   return 0;
16903 }
16904
16905 static int
16906 unset (vat_main_t * vam)
16907 {
16908   u8 *name = 0;
16909
16910   if (unformat (vam->input, "%s", &name))
16911     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
16912       errmsg ("unset: %s wasn't set\n", name);
16913   vec_free (name);
16914   return 0;
16915 }
16916
16917 typedef struct
16918 {
16919   u8 *name;
16920   u8 *value;
16921 } macro_sort_t;
16922
16923
16924 static int
16925 macro_sort_cmp (void *a1, void *a2)
16926 {
16927   macro_sort_t *s1 = a1;
16928   macro_sort_t *s2 = a2;
16929
16930   return strcmp ((char *) (s1->name), (char *) (s2->name));
16931 }
16932
16933 static int
16934 dump_macro_table (vat_main_t * vam)
16935 {
16936   macro_sort_t *sort_me = 0, *sm;
16937   int i;
16938   hash_pair_t *p;
16939
16940     /* *INDENT-OFF* */
16941     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
16942     ({
16943       vec_add2 (sort_me, sm, 1);
16944       sm->name = (u8 *)(p->key);
16945       sm->value = (u8 *) (p->value[0]);
16946     }));
16947     /* *INDENT-ON* */
16948
16949   vec_sort_with_function (sort_me, macro_sort_cmp);
16950
16951   if (vec_len (sort_me))
16952     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
16953   else
16954     fformat (vam->ofp, "The macro table is empty...\n");
16955
16956   for (i = 0; i < vec_len (sort_me); i++)
16957     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
16958   return 0;
16959 }
16960
16961 static int
16962 dump_node_table (vat_main_t * vam)
16963 {
16964   int i, j;
16965   vlib_node_t *node, *next_node;
16966
16967   if (vec_len (vam->graph_nodes) == 0)
16968     {
16969       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16970       return 0;
16971     }
16972
16973   for (i = 0; i < vec_len (vam->graph_nodes); i++)
16974     {
16975       node = vam->graph_nodes[i];
16976       fformat (vam->ofp, "[%d] %s\n", i, node->name);
16977       for (j = 0; j < vec_len (node->next_nodes); j++)
16978         {
16979           if (node->next_nodes[j] != ~0)
16980             {
16981               next_node = vam->graph_nodes[node->next_nodes[j]];
16982               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16983             }
16984         }
16985     }
16986   return 0;
16987 }
16988
16989 static int
16990 value_sort_cmp (void *a1, void *a2)
16991 {
16992   name_sort_t *n1 = a1;
16993   name_sort_t *n2 = a2;
16994
16995   if (n1->value < n2->value)
16996     return -1;
16997   if (n1->value > n2->value)
16998     return 1;
16999   return 0;
17000 }
17001
17002
17003 static int
17004 dump_msg_api_table (vat_main_t * vam)
17005 {
17006   api_main_t *am = &api_main;
17007   name_sort_t *nses = 0, *ns;
17008   hash_pair_t *hp;
17009   int i;
17010
17011   /* *INDENT-OFF* */
17012   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17013   ({
17014     vec_add2 (nses, ns, 1);
17015     ns->name = (u8 *)(hp->key);
17016     ns->value = (u32) hp->value[0];
17017   }));
17018   /* *INDENT-ON* */
17019
17020   vec_sort_with_function (nses, value_sort_cmp);
17021
17022   for (i = 0; i < vec_len (nses); i++)
17023     fformat (vam->ofp, " [%d]: %s\n", nses[i].value, nses[i].name);
17024   vec_free (nses);
17025   return 0;
17026 }
17027
17028 static int
17029 get_msg_id (vat_main_t * vam)
17030 {
17031   u8 *name_and_crc;
17032   u32 message_index;
17033
17034   if (unformat (vam->input, "%s", &name_and_crc))
17035     {
17036       message_index = vl_api_get_msg_index (name_and_crc);
17037       if (message_index == ~0)
17038         {
17039           fformat (vam->ofp, " '%s' not found\n", name_and_crc);
17040           return 0;
17041         }
17042       fformat (vam->ofp, " '%s' has message index %d\n",
17043                name_and_crc, message_index);
17044       return 0;
17045     }
17046   errmsg ("name_and_crc required...\n");
17047   return 0;
17048 }
17049
17050 static int
17051 search_node_table (vat_main_t * vam)
17052 {
17053   unformat_input_t *line_input = vam->input;
17054   u8 *node_to_find;
17055   int j;
17056   vlib_node_t *node, *next_node;
17057   uword *p;
17058
17059   if (vam->graph_node_index_by_name == 0)
17060     {
17061       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
17062       return 0;
17063     }
17064
17065   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17066     {
17067       if (unformat (line_input, "%s", &node_to_find))
17068         {
17069           vec_add1 (node_to_find, 0);
17070           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17071           if (p == 0)
17072             {
17073               fformat (vam->ofp, "%s not found...\n", node_to_find);
17074               goto out;
17075             }
17076           node = vam->graph_nodes[p[0]];
17077           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
17078           for (j = 0; j < vec_len (node->next_nodes); j++)
17079             {
17080               if (node->next_nodes[j] != ~0)
17081                 {
17082                   next_node = vam->graph_nodes[node->next_nodes[j]];
17083                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
17084                 }
17085             }
17086         }
17087
17088       else
17089         {
17090           clib_warning ("parse error '%U'", format_unformat_error,
17091                         line_input);
17092           return -99;
17093         }
17094
17095     out:
17096       vec_free (node_to_find);
17097
17098     }
17099
17100   return 0;
17101 }
17102
17103
17104 static int
17105 script (vat_main_t * vam)
17106 {
17107   u8 *s = 0;
17108   char *save_current_file;
17109   unformat_input_t save_input;
17110   jmp_buf save_jump_buf;
17111   u32 save_line_number;
17112
17113   FILE *new_fp, *save_ifp;
17114
17115   if (unformat (vam->input, "%s", &s))
17116     {
17117       new_fp = fopen ((char *) s, "r");
17118       if (new_fp == 0)
17119         {
17120           errmsg ("Couldn't open script file %s\n", s);
17121           vec_free (s);
17122           return -99;
17123         }
17124     }
17125   else
17126     {
17127       errmsg ("Missing script name\n");
17128       return -99;
17129     }
17130
17131   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17132   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17133   save_ifp = vam->ifp;
17134   save_line_number = vam->input_line_number;
17135   save_current_file = (char *) vam->current_file;
17136
17137   vam->input_line_number = 0;
17138   vam->ifp = new_fp;
17139   vam->current_file = s;
17140   do_one_file (vam);
17141
17142   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17143   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17144   vam->ifp = save_ifp;
17145   vam->input_line_number = save_line_number;
17146   vam->current_file = (u8 *) save_current_file;
17147   vec_free (s);
17148
17149   return 0;
17150 }
17151
17152 static int
17153 echo (vat_main_t * vam)
17154 {
17155   fformat (vam->ofp, "%v", vam->input->buffer);
17156   return 0;
17157 }
17158
17159 /* List of API message constructors, CLI names map to api_xxx */
17160 #define foreach_vpe_api_msg                                             \
17161 _(create_loopback,"[mac <mac-addr>]")                                   \
17162 _(sw_interface_dump,"")                                                 \
17163 _(sw_interface_set_flags,                                               \
17164   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17165 _(sw_interface_add_del_address,                                         \
17166   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17167 _(sw_interface_set_table,                                               \
17168   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17169 _(sw_interface_set_mpls_enable,                                                \
17170   "<intfc> | sw_if_index [disable | dis]")                                \
17171 _(sw_interface_set_vpath,                                               \
17172   "<intfc> | sw_if_index <id> enable | disable")                        \
17173 _(sw_interface_set_vxlan_bypass,                                               \
17174   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")                        \
17175 _(sw_interface_set_l2_xconnect,                                         \
17176   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17177   "enable | disable")                                                   \
17178 _(sw_interface_set_l2_bridge,                                           \
17179   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
17180   "[shg <split-horizon-group>] [bvi]\n"                                 \
17181   "enable | disable")                                                   \
17182 _(sw_interface_set_dpdk_hqos_pipe,                                      \
17183   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
17184   "profile <profile-id>\n")                                             \
17185 _(sw_interface_set_dpdk_hqos_subport,                                   \
17186   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
17187   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
17188 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
17189   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
17190 _(bridge_domain_add_del,                                                \
17191   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
17192 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
17193 _(l2fib_add_del,                                                        \
17194   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17195 _(l2_flags,                                                             \
17196   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
17197 _(bridge_flags,                                                         \
17198   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17199 _(tap_connect,                                                          \
17200   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17201 _(tap_modify,                                                           \
17202   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17203 _(tap_delete,                                                           \
17204   "<vpp-if-name> | sw_if_index <id>")                                   \
17205 _(sw_interface_tap_dump, "")                                            \
17206 _(ip_add_del_route,                                                     \
17207   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17208   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17209   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17210   "[multipath] [count <n>]")                                            \
17211 _(mpls_route_add_del,                                                   \
17212   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17213   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17214   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17215   "[multipath] [count <n>]")                                            \
17216 _(mpls_ip_bind_unbind,                                                  \
17217   "<label> <addr/len>")                                                 \
17218 _(mpls_tunnel_add_del,                                                  \
17219   " via <addr> [table-id <n>]\n"                                        \
17220   "sw_if_index <id>] [l2]  [del]")                                      \
17221 _(proxy_arp_add_del,                                                    \
17222   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17223 _(proxy_arp_intfc_enable_disable,                                       \
17224   "<intfc> | sw_if_index <id> enable | disable")                        \
17225 _(sw_interface_set_unnumbered,                                          \
17226   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17227 _(ip_neighbor_add_del,                                                  \
17228   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17229   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17230 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17231 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17232 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17233   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17234   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17235   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17236 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17237 _(reset_fib, "vrf <n> [ipv6]")                                          \
17238 _(dhcp_proxy_config,                                                    \
17239   "svr <v46-address> src <v46-address>\n"                               \
17240    "insert-cid <n> [del]")                                              \
17241 _(dhcp_proxy_config_2,                                                  \
17242   "svr <v46-address> src <v46-address>\n"                               \
17243    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
17244 _(dhcp_proxy_set_vss,                                                   \
17245   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17246 _(dhcp_client_config,                                                   \
17247   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17248 _(set_ip_flow_hash,                                                     \
17249   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17250 _(sw_interface_ip6_enable_disable,                                      \
17251   "<intfc> | sw_if_index <id> enable | disable")                        \
17252 _(sw_interface_ip6_set_link_local_address,                              \
17253   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17254 _(sw_interface_ip6nd_ra_prefix,                                         \
17255   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17256   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17257   "[nolink] [isno]")                                                    \
17258 _(sw_interface_ip6nd_ra_config,                                         \
17259   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17260   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17261   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17262 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17263 _(l2_patch_add_del,                                                     \
17264   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17265   "enable | disable")                                                   \
17266 _(sr_tunnel_add_del,                                                    \
17267   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
17268   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
17269   "[policy <policy_name>]")                                             \
17270 _(sr_policy_add_del,                                                    \
17271   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
17272 _(sr_multicast_map_add_del,                                             \
17273   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
17274 _(classify_add_del_table,                                               \
17275   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17276   " [del] mask <mask-value>\n"                                          \
17277   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17278   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17279 _(classify_add_del_session,                                             \
17280   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17281   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17282   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17283   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17284 _(classify_set_interface_ip_table,                                      \
17285   "<intfc> | sw_if_index <nn> table <nn>")                              \
17286 _(classify_set_interface_l2_tables,                                     \
17287   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17288   "  [other-table <nn>]")                                               \
17289 _(get_node_index, "node <node-name")                                    \
17290 _(add_node_next, "node <node-name> next <next-node-name>")              \
17291 _(l2tpv3_create_tunnel,                                                 \
17292   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17293   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
17294   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17295 _(l2tpv3_set_tunnel_cookies,                                            \
17296   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17297   "[new_remote_cookie <nn>]\n")                                         \
17298 _(l2tpv3_interface_enable_disable,                                      \
17299   "<intfc> | sw_if_index <nn> enable | disable")                        \
17300 _(l2tpv3_set_lookup_key,                                                \
17301   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17302 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17303 _(vxlan_add_del_tunnel,                                                 \
17304   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17305   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17306   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17307 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17308 _(gre_add_del_tunnel,                                                   \
17309   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
17310 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
17311 _(l2_fib_clear_table, "")                                               \
17312 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
17313 _(l2_interface_vlan_tag_rewrite,                                        \
17314   "<intfc> | sw_if_index <nn> \n"                                       \
17315   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
17316   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
17317 _(create_vhost_user_if,                                                 \
17318         "socket <filename> [server] [renumber <dev_instance>] "         \
17319         "[mac <mac_address>]")                                          \
17320 _(modify_vhost_user_if,                                                 \
17321         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
17322         "[server] [renumber <dev_instance>]")                           \
17323 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
17324 _(sw_interface_vhost_user_dump, "")                                     \
17325 _(show_version, "")                                                     \
17326 _(vxlan_gpe_add_del_tunnel,                                             \
17327   "local <addr> remote <addr> vni <nn>\n"                               \
17328     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
17329   "[next-ethernet] [next-nsh]\n")                                       \
17330 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
17331 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
17332 _(interface_name_renumber,                                              \
17333   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
17334 _(input_acl_set_interface,                                              \
17335   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17336   "  [l2-table <nn>] [del]")                                            \
17337 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
17338 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
17339 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
17340 _(ip_dump, "ipv4 | ipv6")                                               \
17341 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
17342 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
17343   "  spid_id <n> ")                                                     \
17344 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
17345   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
17346   "  integ_alg <alg> integ_key <hex>")                                  \
17347 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
17348   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
17349   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17350   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
17351 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
17352 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
17353 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
17354   "(auth_data 0x<data> | auth_data <data>)")                            \
17355 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
17356   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
17357 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
17358   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17359   "(local|remote)")                                                     \
17360 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
17361 _(delete_loopback,"sw_if_index <nn>")                                   \
17362 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17363 _(map_add_domain,                                                       \
17364   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
17365   "ip6-src <ip6addr> "                                                  \
17366   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
17367 _(map_del_domain, "index <n>")                                          \
17368 _(map_add_del_rule,                                                     \
17369   "index <n> psid <n> dst <ip6addr> [del]")                             \
17370 _(map_domain_dump, "")                                                  \
17371 _(map_rule_dump, "index <map-domain>")                                  \
17372 _(want_interface_events,  "enable|disable")                             \
17373 _(want_stats,"enable|disable")                                          \
17374 _(get_first_msg_id, "client <name>")                                    \
17375 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17376 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
17377   "fib-id <nn> [ip4][ip6][default]")                                    \
17378 _(get_node_graph, " ")                                                  \
17379 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
17380 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
17381 _(ioam_disable, "")                                                \
17382 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
17383                             " sw_if_index <sw_if_index> p <priority> "  \
17384                             "w <weight>] [del]")                        \
17385 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
17386                         "iface <intf> | sw_if_index <sw_if_index> "     \
17387                         "p <priority> w <weight> [del]")                \
17388 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
17389                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
17390                          "locator-set <locator_name> [del]"             \
17391                          "[key-id sha1|sha256 secret-key <secret-key>]")\
17392 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
17393   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
17394 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
17395 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
17396 _(lisp_gpe_enable_disable, "enable|disable")                            \
17397 _(lisp_enable_disable, "enable|disable")                                \
17398 _(lisp_map_register_enable_disable, "enable|disable")                   \
17399 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
17400 _(lisp_gpe_add_del_iface, "up|down")                                    \
17401 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17402                                "[seid <seid>] "                         \
17403                                "rloc <locator> p <prio> "               \
17404                                "w <weight> [rloc <loc> ... ] "          \
17405                                "action <action> [del-all]")             \
17406 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17407                           "<local-eid>")                                \
17408 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
17409 _(lisp_map_request_mode, "src-dst|dst-only")                            \
17410 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
17411 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
17412 _(lisp_locator_set_dump, "[local | remote]")                            \
17413 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
17414 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
17415                        "[local] | [remote]")                            \
17416 _(lisp_eid_table_vni_dump, "")                                          \
17417 _(lisp_eid_table_map_dump, "l2|l3")                                     \
17418 _(lisp_gpe_tunnel_dump, "")                                             \
17419 _(lisp_map_resolver_dump, "")                                           \
17420 _(lisp_map_server_dump, "")                                             \
17421 _(lisp_adjacencies_get, "vni <vni>")                                    \
17422 _(show_lisp_rloc_probe_state, "")                                       \
17423 _(show_lisp_map_register_state, "")                                     \
17424 _(show_lisp_status, "")                                                 \
17425 _(lisp_get_map_request_itr_rlocs, "")                                   \
17426 _(show_lisp_pitr, "")                                                   \
17427 _(show_lisp_map_request_mode, "")                                       \
17428 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
17429 _(af_packet_delete, "name <host interface name>")                       \
17430 _(policer_add_del, "name <policer name> <params> [del]")                \
17431 _(policer_dump, "[name <policer name>]")                                \
17432 _(policer_classify_set_interface,                                       \
17433   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17434   "  [l2-table <nn>] [del]")                                            \
17435 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
17436 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
17437     "[master|slave]")                                                   \
17438 _(netmap_delete, "name <interface name>")                               \
17439 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
17440 _(mpls_fib_dump, "")                                                    \
17441 _(classify_table_ids, "")                                               \
17442 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
17443 _(classify_table_info, "table_id <nn>")                                 \
17444 _(classify_session_dump, "table_id <nn>")                               \
17445 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
17446     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
17447     "[template_interval <nn>] [udp_checksum]")                          \
17448 _(ipfix_exporter_dump, "")                                              \
17449 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17450 _(ipfix_classify_stream_dump, "")                                       \
17451 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
17452 _(ipfix_classify_table_dump, "")                                        \
17453 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [[dst <intfc> | dst_sw_if_index <id>] | disable]") \
17454 _(sw_interface_span_dump, "")                                           \
17455 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17456 _(pg_create_interface, "if_id <nn>")                                    \
17457 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17458 _(pg_enable_disable, "[stream <id>] disable")                           \
17459 _(ip_source_and_port_range_check_add_del,                               \
17460   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17461 _(ip_source_and_port_range_check_interface_add_del,                     \
17462   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17463   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17464 _(ipsec_gre_add_del_tunnel,                                             \
17465   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17466 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17467 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17468 _(l2_interface_pbb_tag_rewrite,                                         \
17469   "<intfc> | sw_if_index <nn> \n"                                       \
17470   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17471   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17472 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17473 _(flow_classify_set_interface,                                          \
17474   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17475 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17476 _(ip_fib_dump, "")                                                      \
17477 _(ip6_fib_dump, "")                                                     \
17478 _(feature_enable_disable, "arc_name <arc_name> "                        \
17479   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
17480 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
17481 "[disable]")                                                            \
17482 _(l2_xconnect_dump, "")                                                 \
17483 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")
17484
17485 /* List of command functions, CLI names map directly to functions */
17486 #define foreach_cli_function                                    \
17487 _(comment, "usage: comment <ignore-rest-of-line>")              \
17488 _(dump_interface_table, "usage: dump_interface_table")          \
17489 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17490 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17491 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17492 _(dump_stats_table, "usage: dump_stats_table")                  \
17493 _(dump_macro_table, "usage: dump_macro_table ")                 \
17494 _(dump_node_table, "usage: dump_node_table")                    \
17495 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17496 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17497 _(echo, "usage: echo <message>")                                \
17498 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17499 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17500 _(help, "usage: help")                                          \
17501 _(q, "usage: quit")                                             \
17502 _(quit, "usage: quit")                                          \
17503 _(search_node_table, "usage: search_node_table <name>...")      \
17504 _(set, "usage: set <variable-name> <value>")                    \
17505 _(script, "usage: script <file-name>")                          \
17506 _(unset, "usage: unset <variable-name>")
17507
17508 #define _(N,n)                                  \
17509     static void vl_api_##n##_t_handler_uni      \
17510     (vl_api_##n##_t * mp)                       \
17511     {                                           \
17512         vat_main_t * vam = &vat_main;           \
17513         if (vam->json_output) {                 \
17514             vl_api_##n##_t_handler_json(mp);    \
17515         } else {                                \
17516             vl_api_##n##_t_handler(mp);         \
17517         }                                       \
17518     }
17519 foreach_vpe_api_reply_msg;
17520 #undef _
17521
17522 void
17523 vat_api_hookup (vat_main_t * vam)
17524 {
17525 #define _(N,n)                                                  \
17526     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17527                            vl_api_##n##_t_handler_uni,          \
17528                            vl_noop_handler,                     \
17529                            vl_api_##n##_t_endian,               \
17530                            vl_api_##n##_t_print,                \
17531                            sizeof(vl_api_##n##_t), 1);
17532   foreach_vpe_api_reply_msg;
17533 #undef _
17534
17535   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17536
17537   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17538
17539   vam->function_by_name = hash_create_string (0, sizeof (uword));
17540
17541   vam->help_by_name = hash_create_string (0, sizeof (uword));
17542
17543   /* API messages we can send */
17544 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17545   foreach_vpe_api_msg;
17546 #undef _
17547
17548   /* Help strings */
17549 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17550   foreach_vpe_api_msg;
17551 #undef _
17552
17553   /* CLI functions */
17554 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17555   foreach_cli_function;
17556 #undef _
17557
17558   /* Help strings */
17559 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17560   foreach_cli_function;
17561 #undef _
17562 }
17563
17564 #undef vl_api_version
17565 #define vl_api_version(n,v) static u32 memory_api_version = v;
17566 #include <vlibmemory/vl_memory_api_h.h>
17567 #undef vl_api_version
17568
17569 #undef vl_api_version
17570 #define vl_api_version(n,v) static u32 vnet_interface_api_version = v;
17571 #include <vnet/interface.api.h>
17572 #undef vl_api_version
17573
17574 #undef vl_api_version
17575 #define vl_api_version(n,v) static u32 vpp_api_version = v;
17576 #include <vpp-api/vpe.api.h>
17577 #undef vl_api_version
17578
17579 static u32 *api_versions[] = {
17580   &memory_api_version,
17581   &vnet_interface_api_version,
17582   &vpp_api_version,
17583 };
17584
17585 void
17586 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
17587 {
17588   int i;
17589
17590   ASSERT (ARRAY_LEN (mp->api_versions) >= ARRAY_LEN (api_versions));
17591
17592   /*
17593    * Send the API signatures. This bit of code must
17594    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
17595    */
17596
17597   for (i = 0; i < ARRAY_LEN (api_versions); i++)
17598     mp->api_versions[i] = clib_host_to_net_u32 (*api_versions[i]);
17599 }
17600
17601 /*
17602  * fd.io coding-style-patch-verification: ON
17603  *
17604  * Local Variables:
17605  * eval: (c-set-style "gnu")
17606  * End:
17607  */