Add vxlan-bypass feature to IP4 forwarding path
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248   u32 *r = va_arg (*args, u32 *);
249
250   if (0);
251 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
252   foreach_ipsec_policy_action
253 #undef _
254     else
255     return 0;
256   return 1;
257 }
258
259 uword
260 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
261 {
262   u32 *r = va_arg (*args, u32 *);
263
264   if (0);
265 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
266   foreach_ipsec_crypto_alg
267 #undef _
268     else
269     return 0;
270   return 1;
271 }
272
273 u8 *
274 format_ipsec_crypto_alg (u8 * s, va_list * args)
275 {
276   u32 i = va_arg (*args, u32);
277   u8 *t = 0;
278
279   switch (i)
280     {
281 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
282       foreach_ipsec_crypto_alg
283 #undef _
284     default:
285       return format (s, "unknown");
286     }
287   return format (s, "%s", t);
288 }
289
290 uword
291 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
292 {
293   u32 *r = va_arg (*args, u32 *);
294
295   if (0);
296 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
297   foreach_ipsec_integ_alg
298 #undef _
299     else
300     return 0;
301   return 1;
302 }
303
304 u8 *
305 format_ipsec_integ_alg (u8 * s, va_list * args)
306 {
307   u32 i = va_arg (*args, u32);
308   u8 *t = 0;
309
310   switch (i)
311     {
312 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
313       foreach_ipsec_integ_alg
314 #undef _
315     default:
316       return format (s, "unknown");
317     }
318   return format (s, "%s", t);
319 }
320
321 uword
322 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
323 {
324   u32 *r = va_arg (*args, u32 *);
325
326   if (0);
327 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
328   foreach_ikev2_auth_method
329 #undef _
330     else
331     return 0;
332   return 1;
333 }
334
335 uword
336 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
337 {
338   u32 *r = va_arg (*args, u32 *);
339
340   if (0);
341 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
342   foreach_ikev2_id_type
343 #undef _
344     else
345     return 0;
346   return 1;
347 }
348
349 uword
350 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
351 {
352   u8 *r = va_arg (*args, u8 *);
353
354   if (unformat (input, "kbps"))
355     *r = SSE2_QOS_RATE_KBPS;
356   else if (unformat (input, "pps"))
357     *r = SSE2_QOS_RATE_PPS;
358   else
359     return 0;
360   return 1;
361 }
362
363 uword
364 unformat_policer_round_type (unformat_input_t * input, va_list * args)
365 {
366   u8 *r = va_arg (*args, u8 *);
367
368   if (unformat (input, "closest"))
369     *r = SSE2_QOS_ROUND_TO_CLOSEST;
370   else if (unformat (input, "up"))
371     *r = SSE2_QOS_ROUND_TO_UP;
372   else if (unformat (input, "down"))
373     *r = SSE2_QOS_ROUND_TO_DOWN;
374   else
375     return 0;
376   return 1;
377 }
378
379 uword
380 unformat_policer_type (unformat_input_t * input, va_list * args)
381 {
382   u8 *r = va_arg (*args, u8 *);
383
384   if (unformat (input, "1r2c"))
385     *r = SSE2_QOS_POLICER_TYPE_1R2C;
386   else if (unformat (input, "1r3c"))
387     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
388   else if (unformat (input, "2r3c-2698"))
389     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
390   else if (unformat (input, "2r3c-4115"))
391     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
392   else if (unformat (input, "2r3c-mef5cf1"))
393     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
394   else
395     return 0;
396   return 1;
397 }
398
399 uword
400 unformat_dscp (unformat_input_t * input, va_list * va)
401 {
402   u8 *r = va_arg (*va, u8 *);
403
404   if (0);
405 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
406   foreach_vnet_dscp
407 #undef _
408     else
409     return 0;
410   return 1;
411 }
412
413 uword
414 unformat_policer_action_type (unformat_input_t * input, va_list * va)
415 {
416   sse2_qos_pol_action_params_st *a
417     = va_arg (*va, sse2_qos_pol_action_params_st *);
418
419   if (unformat (input, "drop"))
420     a->action_type = SSE2_QOS_ACTION_DROP;
421   else if (unformat (input, "transmit"))
422     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
423   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
424     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
425   else
426     return 0;
427   return 1;
428 }
429
430 uword
431 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
432 {
433   u32 *r = va_arg (*va, u32 *);
434   u32 tid;
435
436   if (unformat (input, "ip4"))
437     tid = POLICER_CLASSIFY_TABLE_IP4;
438   else if (unformat (input, "ip6"))
439     tid = POLICER_CLASSIFY_TABLE_IP6;
440   else if (unformat (input, "l2"))
441     tid = POLICER_CLASSIFY_TABLE_L2;
442   else
443     return 0;
444
445   *r = tid;
446   return 1;
447 }
448
449 uword
450 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
451 {
452   u32 *r = va_arg (*va, u32 *);
453   u32 tid;
454
455   if (unformat (input, "ip4"))
456     tid = FLOW_CLASSIFY_TABLE_IP4;
457   else if (unformat (input, "ip6"))
458     tid = FLOW_CLASSIFY_TABLE_IP6;
459   else
460     return 0;
461
462   *r = tid;
463   return 1;
464 }
465
466 u8 *
467 format_ip4_address (u8 * s, va_list * args)
468 {
469   u8 *a = va_arg (*args, u8 *);
470   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
471 }
472
473 u8 *
474 format_ip6_address (u8 * s, va_list * args)
475 {
476   ip6_address_t *a = va_arg (*args, ip6_address_t *);
477   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
478
479   i_max_n_zero = ARRAY_LEN (a->as_u16);
480   max_n_zeros = 0;
481   i_first_zero = i_max_n_zero;
482   n_zeros = 0;
483   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
484     {
485       u32 is_zero = a->as_u16[i] == 0;
486       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
487         {
488           i_first_zero = i;
489           n_zeros = 0;
490         }
491       n_zeros += is_zero;
492       if ((!is_zero && n_zeros > max_n_zeros)
493           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
494         {
495           i_max_n_zero = i_first_zero;
496           max_n_zeros = n_zeros;
497           i_first_zero = ARRAY_LEN (a->as_u16);
498           n_zeros = 0;
499         }
500     }
501
502   last_double_colon = 0;
503   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
504     {
505       if (i == i_max_n_zero && max_n_zeros > 1)
506         {
507           s = format (s, "::");
508           i += max_n_zeros - 1;
509           last_double_colon = 1;
510         }
511       else
512         {
513           s = format (s, "%s%x",
514                       (last_double_colon || i == 0) ? "" : ":",
515                       clib_net_to_host_u16 (a->as_u16[i]));
516           last_double_colon = 0;
517         }
518     }
519
520   return s;
521 }
522
523 /* Format an IP46 address. */
524 u8 *
525 format_ip46_address (u8 * s, va_list * args)
526 {
527   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
528   ip46_type_t type = va_arg (*args, ip46_type_t);
529   int is_ip4 = 1;
530
531   switch (type)
532     {
533     case IP46_TYPE_ANY:
534       is_ip4 = ip46_address_is_ip4 (ip46);
535       break;
536     case IP46_TYPE_IP4:
537       is_ip4 = 1;
538       break;
539     case IP46_TYPE_IP6:
540       is_ip4 = 0;
541       break;
542     }
543
544   return is_ip4 ?
545     format (s, "%U", format_ip4_address, &ip46->ip4) :
546     format (s, "%U", format_ip6_address, &ip46->ip6);
547 }
548
549 u8 *
550 format_ethernet_address (u8 * s, va_list * args)
551 {
552   u8 *a = va_arg (*args, u8 *);
553
554   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
555                  a[0], a[1], a[2], a[3], a[4], a[5]);
556 }
557
558 void
559 increment_v4_address (ip4_address_t * a)
560 {
561   u32 v;
562
563   v = ntohl (a->as_u32) + 1;
564   a->as_u32 = ntohl (v);
565 }
566
567 void
568 increment_v6_address (ip6_address_t * a)
569 {
570   u64 v0, v1;
571
572   v0 = clib_net_to_host_u64 (a->as_u64[0]);
573   v1 = clib_net_to_host_u64 (a->as_u64[1]);
574
575   v1 += 1;
576   if (v1 == 0)
577     v0 += 1;
578   a->as_u64[0] = clib_net_to_host_u64 (v0);
579   a->as_u64[1] = clib_net_to_host_u64 (v1);
580 }
581
582 void
583 increment_mac_address (u64 * mac)
584 {
585   u64 tmp = *mac;
586
587   tmp = clib_net_to_host_u64 (tmp);
588   tmp += 1 << 16;               /* skip unused (least significant) octets */
589   tmp = clib_host_to_net_u64 (tmp);
590   *mac = tmp;
591 }
592
593 static void vl_api_create_loopback_reply_t_handler
594   (vl_api_create_loopback_reply_t * mp)
595 {
596   vat_main_t *vam = &vat_main;
597   i32 retval = ntohl (mp->retval);
598
599   vam->retval = retval;
600   vam->regenerate_interface_table = 1;
601   vam->sw_if_index = ntohl (mp->sw_if_index);
602   vam->result_ready = 1;
603 }
604
605 static void vl_api_create_loopback_reply_t_handler_json
606   (vl_api_create_loopback_reply_t * mp)
607 {
608   vat_main_t *vam = &vat_main;
609   vat_json_node_t node;
610
611   vat_json_init_object (&node);
612   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
613   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
614
615   vat_json_print (vam->ofp, &node);
616   vat_json_free (&node);
617   vam->retval = ntohl (mp->retval);
618   vam->result_ready = 1;
619 }
620
621 static void vl_api_af_packet_create_reply_t_handler
622   (vl_api_af_packet_create_reply_t * mp)
623 {
624   vat_main_t *vam = &vat_main;
625   i32 retval = ntohl (mp->retval);
626
627   vam->retval = retval;
628   vam->regenerate_interface_table = 1;
629   vam->sw_if_index = ntohl (mp->sw_if_index);
630   vam->result_ready = 1;
631 }
632
633 static void vl_api_af_packet_create_reply_t_handler_json
634   (vl_api_af_packet_create_reply_t * mp)
635 {
636   vat_main_t *vam = &vat_main;
637   vat_json_node_t node;
638
639   vat_json_init_object (&node);
640   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
641   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
642
643   vat_json_print (vam->ofp, &node);
644   vat_json_free (&node);
645
646   vam->retval = ntohl (mp->retval);
647   vam->result_ready = 1;
648 }
649
650 static void vl_api_create_vlan_subif_reply_t_handler
651   (vl_api_create_vlan_subif_reply_t * mp)
652 {
653   vat_main_t *vam = &vat_main;
654   i32 retval = ntohl (mp->retval);
655
656   vam->retval = retval;
657   vam->regenerate_interface_table = 1;
658   vam->sw_if_index = ntohl (mp->sw_if_index);
659   vam->result_ready = 1;
660 }
661
662 static void vl_api_create_vlan_subif_reply_t_handler_json
663   (vl_api_create_vlan_subif_reply_t * mp)
664 {
665   vat_main_t *vam = &vat_main;
666   vat_json_node_t node;
667
668   vat_json_init_object (&node);
669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
670   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
671
672   vat_json_print (vam->ofp, &node);
673   vat_json_free (&node);
674
675   vam->retval = ntohl (mp->retval);
676   vam->result_ready = 1;
677 }
678
679 static void vl_api_create_subif_reply_t_handler
680   (vl_api_create_subif_reply_t * mp)
681 {
682   vat_main_t *vam = &vat_main;
683   i32 retval = ntohl (mp->retval);
684
685   vam->retval = retval;
686   vam->regenerate_interface_table = 1;
687   vam->sw_if_index = ntohl (mp->sw_if_index);
688   vam->result_ready = 1;
689 }
690
691 static void vl_api_create_subif_reply_t_handler_json
692   (vl_api_create_subif_reply_t * mp)
693 {
694   vat_main_t *vam = &vat_main;
695   vat_json_node_t node;
696
697   vat_json_init_object (&node);
698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
699   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
700
701   vat_json_print (vam->ofp, &node);
702   vat_json_free (&node);
703
704   vam->retval = ntohl (mp->retval);
705   vam->result_ready = 1;
706 }
707
708 static void vl_api_interface_name_renumber_reply_t_handler
709   (vl_api_interface_name_renumber_reply_t * mp)
710 {
711   vat_main_t *vam = &vat_main;
712   i32 retval = ntohl (mp->retval);
713
714   vam->retval = retval;
715   vam->regenerate_interface_table = 1;
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler_json
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   vat_json_node_t node;
724
725   vat_json_init_object (&node);
726   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
727
728   vat_json_print (vam->ofp, &node);
729   vat_json_free (&node);
730
731   vam->retval = ntohl (mp->retval);
732   vam->result_ready = 1;
733 }
734
735 /*
736  * Special-case: build the interface table, maintain
737  * the next loopback sw_if_index vbl.
738  */
739 static void vl_api_sw_interface_details_t_handler
740   (vl_api_sw_interface_details_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   u8 *s = format (0, "%s%c", mp->interface_name, 0);
744
745   hash_set_mem (vam->sw_if_index_by_interface_name, s,
746                 ntohl (mp->sw_if_index));
747
748   /* In sub interface case, fill the sub interface table entry */
749   if (mp->sw_if_index != mp->sup_sw_if_index)
750     {
751       sw_interface_subif_t *sub = NULL;
752
753       vec_add2 (vam->sw_if_subif_table, sub, 1);
754
755       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
756       strncpy ((char *) sub->interface_name, (char *) s,
757                vec_len (sub->interface_name));
758       sub->sw_if_index = ntohl (mp->sw_if_index);
759       sub->sub_id = ntohl (mp->sub_id);
760
761       sub->sub_dot1ad = mp->sub_dot1ad;
762       sub->sub_number_of_tags = mp->sub_number_of_tags;
763       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
764       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
765       sub->sub_exact_match = mp->sub_exact_match;
766       sub->sub_default = mp->sub_default;
767       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
768       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
769
770       /* vlan tag rewrite */
771       sub->vtr_op = ntohl (mp->vtr_op);
772       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
773       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
774       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
775     }
776 }
777
778 static void vl_api_sw_interface_details_t_handler_json
779   (vl_api_sw_interface_details_t * mp)
780 {
781   vat_main_t *vam = &vat_main;
782   vat_json_node_t *node = NULL;
783
784   if (VAT_JSON_ARRAY != vam->json_tree.type)
785     {
786       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
787       vat_json_init_array (&vam->json_tree);
788     }
789   node = vat_json_array_add (&vam->json_tree);
790
791   vat_json_init_object (node);
792   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
793   vat_json_object_add_uint (node, "sup_sw_if_index",
794                             ntohl (mp->sup_sw_if_index));
795   vat_json_object_add_uint (node, "l2_address_length",
796                             ntohl (mp->l2_address_length));
797   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
798                              sizeof (mp->l2_address));
799   vat_json_object_add_string_copy (node, "interface_name",
800                                    mp->interface_name);
801   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
802   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
803   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
804   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
805   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
806   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
807   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
808   vat_json_object_add_uint (node, "sub_number_of_tags",
809                             mp->sub_number_of_tags);
810   vat_json_object_add_uint (node, "sub_outer_vlan_id",
811                             ntohs (mp->sub_outer_vlan_id));
812   vat_json_object_add_uint (node, "sub_inner_vlan_id",
813                             ntohs (mp->sub_inner_vlan_id));
814   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
815   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
816   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
817                             mp->sub_outer_vlan_id_any);
818   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
819                             mp->sub_inner_vlan_id_any);
820   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
821   vat_json_object_add_uint (node, "vtr_push_dot1q",
822                             ntohl (mp->vtr_push_dot1q));
823   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
824   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
825 }
826
827 static void vl_api_sw_interface_set_flags_t_handler
828   (vl_api_sw_interface_set_flags_t * mp)
829 {
830   vat_main_t *vam = &vat_main;
831   if (vam->interface_event_display)
832     errmsg ("interface flags: sw_if_index %d %s %s\n",
833             ntohl (mp->sw_if_index),
834             mp->admin_up_down ? "admin-up" : "admin-down",
835             mp->link_up_down ? "link-up" : "link-down");
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler_json
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   /* JSON output not supported */
842 }
843
844 static void
845 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
846 {
847   vat_main_t *vam = &vat_main;
848   i32 retval = ntohl (mp->retval);
849
850   vam->retval = retval;
851   vam->shmem_result = (u8 *) mp->reply_in_shmem;
852   vam->result_ready = 1;
853 }
854
855 static void
856 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   vat_json_node_t node;
860   api_main_t *am = &api_main;
861   void *oldheap;
862   u8 *reply;
863
864   vat_json_init_object (&node);
865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
866   vat_json_object_add_uint (&node, "reply_in_shmem",
867                             ntohl (mp->reply_in_shmem));
868   /* Toss the shared-memory original... */
869   pthread_mutex_lock (&am->vlib_rp->mutex);
870   oldheap = svm_push_data_heap (am->vlib_rp);
871
872   reply = (u8 *) (mp->reply_in_shmem);
873   vec_free (reply);
874
875   svm_pop_heap (oldheap);
876   pthread_mutex_unlock (&am->vlib_rp->mutex);
877
878   vat_json_print (vam->ofp, &node);
879   vat_json_free (&node);
880
881   vam->retval = ntohl (mp->retval);
882   vam->result_ready = 1;
883 }
884
885 static void
886 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   i32 retval = ntohl (mp->retval);
890
891   vam->retval = retval;
892   vam->cmd_reply = mp->reply;
893   vam->result_ready = 1;
894 }
895
896 static void
897 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   vat_json_node_t node;
901
902   vat_json_init_object (&node);
903   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
904   vat_json_object_add_string_copy (&node, "reply", mp->reply);
905
906   vat_json_print (vam->ofp, &node);
907   vat_json_free (&node);
908
909   vam->retval = ntohl (mp->retval);
910   vam->result_ready = 1;
911 }
912
913 static void vl_api_classify_add_del_table_reply_t_handler
914   (vl_api_classify_add_del_table_reply_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   i32 retval = ntohl (mp->retval);
918   if (vam->async_mode)
919     {
920       vam->async_errors += (retval < 0);
921     }
922   else
923     {
924       vam->retval = retval;
925       if (retval == 0 &&
926           ((mp->new_table_index != 0xFFFFFFFF) ||
927            (mp->skip_n_vectors != 0xFFFFFFFF) ||
928            (mp->match_n_vectors != 0xFFFFFFFF)))
929         /*
930          * Note: this is just barely thread-safe, depends on
931          * the main thread spinning waiting for an answer...
932          */
933         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
934                 ntohl (mp->new_table_index),
935                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
936       vam->result_ready = 1;
937     }
938 }
939
940 static void vl_api_classify_add_del_table_reply_t_handler_json
941   (vl_api_classify_add_del_table_reply_t * mp)
942 {
943   vat_main_t *vam = &vat_main;
944   vat_json_node_t node;
945
946   vat_json_init_object (&node);
947   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
948   vat_json_object_add_uint (&node, "new_table_index",
949                             ntohl (mp->new_table_index));
950   vat_json_object_add_uint (&node, "skip_n_vectors",
951                             ntohl (mp->skip_n_vectors));
952   vat_json_object_add_uint (&node, "match_n_vectors",
953                             ntohl (mp->match_n_vectors));
954
955   vat_json_print (vam->ofp, &node);
956   vat_json_free (&node);
957
958   vam->retval = ntohl (mp->retval);
959   vam->result_ready = 1;
960 }
961
962 static void vl_api_get_node_index_reply_t_handler
963   (vl_api_get_node_index_reply_t * mp)
964 {
965   vat_main_t *vam = &vat_main;
966   i32 retval = ntohl (mp->retval);
967   if (vam->async_mode)
968     {
969       vam->async_errors += (retval < 0);
970     }
971   else
972     {
973       vam->retval = retval;
974       if (retval == 0)
975         errmsg ("node index %d\n", ntohl (mp->node_index));
976       vam->result_ready = 1;
977     }
978 }
979
980 static void vl_api_get_node_index_reply_t_handler_json
981   (vl_api_get_node_index_reply_t * mp)
982 {
983   vat_main_t *vam = &vat_main;
984   vat_json_node_t node;
985
986   vat_json_init_object (&node);
987   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
988   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
989
990   vat_json_print (vam->ofp, &node);
991   vat_json_free (&node);
992
993   vam->retval = ntohl (mp->retval);
994   vam->result_ready = 1;
995 }
996
997 static void vl_api_get_next_index_reply_t_handler
998   (vl_api_get_next_index_reply_t * mp)
999 {
1000   vat_main_t *vam = &vat_main;
1001   i32 retval = ntohl (mp->retval);
1002   if (vam->async_mode)
1003     {
1004       vam->async_errors += (retval < 0);
1005     }
1006   else
1007     {
1008       vam->retval = retval;
1009       if (retval == 0)
1010         errmsg ("next node index %d\n", ntohl (mp->next_index));
1011       vam->result_ready = 1;
1012     }
1013 }
1014
1015 static void vl_api_get_next_index_reply_t_handler_json
1016   (vl_api_get_next_index_reply_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   vat_json_node_t node;
1020
1021   vat_json_init_object (&node);
1022   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1023   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1024
1025   vat_json_print (vam->ofp, &node);
1026   vat_json_free (&node);
1027
1028   vam->retval = ntohl (mp->retval);
1029   vam->result_ready = 1;
1030 }
1031
1032 static void vl_api_add_node_next_reply_t_handler
1033   (vl_api_add_node_next_reply_t * mp)
1034 {
1035   vat_main_t *vam = &vat_main;
1036   i32 retval = ntohl (mp->retval);
1037   if (vam->async_mode)
1038     {
1039       vam->async_errors += (retval < 0);
1040     }
1041   else
1042     {
1043       vam->retval = retval;
1044       if (retval == 0)
1045         errmsg ("next index %d\n", ntohl (mp->next_index));
1046       vam->result_ready = 1;
1047     }
1048 }
1049
1050 static void vl_api_add_node_next_reply_t_handler_json
1051   (vl_api_add_node_next_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   vat_json_node_t node;
1055
1056   vat_json_init_object (&node);
1057   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1058   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1059
1060   vat_json_print (vam->ofp, &node);
1061   vat_json_free (&node);
1062
1063   vam->retval = ntohl (mp->retval);
1064   vam->result_ready = 1;
1065 }
1066
1067 static void vl_api_show_version_reply_t_handler
1068   (vl_api_show_version_reply_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   i32 retval = ntohl (mp->retval);
1072
1073   if (retval >= 0)
1074     {
1075       errmsg ("        program: %s\n", mp->program);
1076       errmsg ("        version: %s\n", mp->version);
1077       errmsg ("     build date: %s\n", mp->build_date);
1078       errmsg ("build directory: %s\n", mp->build_directory);
1079     }
1080   vam->retval = retval;
1081   vam->result_ready = 1;
1082 }
1083
1084 static void vl_api_show_version_reply_t_handler_json
1085   (vl_api_show_version_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   vat_json_node_t node;
1089
1090   vat_json_init_object (&node);
1091   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1092   vat_json_object_add_string_copy (&node, "program", mp->program);
1093   vat_json_object_add_string_copy (&node, "version", mp->version);
1094   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1095   vat_json_object_add_string_copy (&node, "build_directory",
1096                                    mp->build_directory);
1097
1098   vat_json_print (vam->ofp, &node);
1099   vat_json_free (&node);
1100
1101   vam->retval = ntohl (mp->retval);
1102   vam->result_ready = 1;
1103 }
1104
1105 static void
1106 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1107 {
1108   vat_main_t *vam = &vat_main;
1109   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1110           mp->mac_ip ? "mac/ip binding" : "address resolution",
1111           format_ip4_address, &mp->address,
1112           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1113 }
1114
1115 static void
1116 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1117 {
1118   /* JSON output not supported */
1119 }
1120
1121 static void
1122 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1123 {
1124   vat_main_t *vam = &vat_main;
1125   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1126           mp->mac_ip ? "mac/ip binding" : "address resolution",
1127           format_ip6_address, mp->address,
1128           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1129 }
1130
1131 static void
1132 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1133 {
1134   /* JSON output not supported */
1135 }
1136
1137 /*
1138  * Special-case: build the bridge domain table, maintain
1139  * the next bd id vbl.
1140  */
1141 static void vl_api_bridge_domain_details_t_handler
1142   (vl_api_bridge_domain_details_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1146
1147   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1148            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1149
1150   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1151            ntohl (mp->bd_id), mp->learn, mp->forward,
1152            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1153
1154   if (n_sw_ifs)
1155     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1156              "Interface Name");
1157 }
1158
1159 static void vl_api_bridge_domain_details_t_handler_json
1160   (vl_api_bridge_domain_details_t * mp)
1161 {
1162   vat_main_t *vam = &vat_main;
1163   vat_json_node_t *node, *array = NULL;
1164
1165   if (VAT_JSON_ARRAY != vam->json_tree.type)
1166     {
1167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1168       vat_json_init_array (&vam->json_tree);
1169     }
1170   node = vat_json_array_add (&vam->json_tree);
1171
1172   vat_json_init_object (node);
1173   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1174   vat_json_object_add_uint (node, "flood", mp->flood);
1175   vat_json_object_add_uint (node, "forward", mp->forward);
1176   vat_json_object_add_uint (node, "learn", mp->learn);
1177   vat_json_object_add_uint (node, "bvi_sw_if_index",
1178                             ntohl (mp->bvi_sw_if_index));
1179   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1180   array = vat_json_object_add (node, "sw_if");
1181   vat_json_init_array (array);
1182 }
1183
1184 /*
1185  * Special-case: build the bridge domain sw if table.
1186  */
1187 static void vl_api_bridge_domain_sw_if_details_t_handler
1188   (vl_api_bridge_domain_sw_if_details_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   hash_pair_t *p;
1192   u8 *sw_if_name = 0;
1193   u32 sw_if_index;
1194
1195   sw_if_index = ntohl (mp->sw_if_index);
1196   /* *INDENT-OFF* */
1197   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1198   ({
1199     if ((u32) p->value[0] == sw_if_index)
1200       {
1201         sw_if_name = (u8 *)(p->key);
1202         break;
1203       }
1204   }));
1205   /* *INDENT-ON* */
1206
1207   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1208            mp->shg, sw_if_name ? (char *) sw_if_name :
1209            "sw_if_index not found!");
1210 }
1211
1212 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1213   (vl_api_bridge_domain_sw_if_details_t * mp)
1214 {
1215   vat_main_t *vam = &vat_main;
1216   vat_json_node_t *node = NULL;
1217   uword last_index = 0;
1218
1219   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1220   ASSERT (vec_len (vam->json_tree.array) >= 1);
1221   last_index = vec_len (vam->json_tree.array) - 1;
1222   node = &vam->json_tree.array[last_index];
1223   node = vat_json_object_get_element (node, "sw_if");
1224   ASSERT (NULL != node);
1225   node = vat_json_array_add (node);
1226
1227   vat_json_init_object (node);
1228   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1230   vat_json_object_add_uint (node, "shg", mp->shg);
1231 }
1232
1233 static void vl_api_control_ping_reply_t_handler
1234   (vl_api_control_ping_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   i32 retval = ntohl (mp->retval);
1238   if (vam->async_mode)
1239     {
1240       vam->async_errors += (retval < 0);
1241     }
1242   else
1243     {
1244       vam->retval = retval;
1245       vam->result_ready = 1;
1246     }
1247 }
1248
1249 static void vl_api_control_ping_reply_t_handler_json
1250   (vl_api_control_ping_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254
1255   if (VAT_JSON_NONE != vam->json_tree.type)
1256     {
1257       vat_json_print (vam->ofp, &vam->json_tree);
1258       vat_json_free (&vam->json_tree);
1259       vam->json_tree.type = VAT_JSON_NONE;
1260     }
1261   else
1262     {
1263       /* just print [] */
1264       vat_json_init_array (&vam->json_tree);
1265       vat_json_print (vam->ofp, &vam->json_tree);
1266       vam->json_tree.type = VAT_JSON_NONE;
1267     }
1268
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void
1274 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278   if (vam->async_mode)
1279     {
1280       vam->async_errors += (retval < 0);
1281     }
1282   else
1283     {
1284       vam->retval = retval;
1285       vam->result_ready = 1;
1286     }
1287 }
1288
1289 static void vl_api_l2_flags_reply_t_handler_json
1290   (vl_api_l2_flags_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   vat_json_node_t node;
1294
1295   vat_json_init_object (&node);
1296   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1297   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1298                             ntohl (mp->resulting_feature_bitmap));
1299
1300   vat_json_print (vam->ofp, &node);
1301   vat_json_free (&node);
1302
1303   vam->retval = ntohl (mp->retval);
1304   vam->result_ready = 1;
1305 }
1306
1307 static void vl_api_bridge_flags_reply_t_handler
1308   (vl_api_bridge_flags_reply_t * mp)
1309 {
1310   vat_main_t *vam = &vat_main;
1311   i32 retval = ntohl (mp->retval);
1312   if (vam->async_mode)
1313     {
1314       vam->async_errors += (retval < 0);
1315     }
1316   else
1317     {
1318       vam->retval = retval;
1319       vam->result_ready = 1;
1320     }
1321 }
1322
1323 static void vl_api_bridge_flags_reply_t_handler_json
1324   (vl_api_bridge_flags_reply_t * mp)
1325 {
1326   vat_main_t *vam = &vat_main;
1327   vat_json_node_t node;
1328
1329   vat_json_init_object (&node);
1330   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1331   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1332                             ntohl (mp->resulting_feature_bitmap));
1333
1334   vat_json_print (vam->ofp, &node);
1335   vat_json_free (&node);
1336
1337   vam->retval = ntohl (mp->retval);
1338   vam->result_ready = 1;
1339 }
1340
1341 static void vl_api_tap_connect_reply_t_handler
1342   (vl_api_tap_connect_reply_t * mp)
1343 {
1344   vat_main_t *vam = &vat_main;
1345   i32 retval = ntohl (mp->retval);
1346   if (vam->async_mode)
1347     {
1348       vam->async_errors += (retval < 0);
1349     }
1350   else
1351     {
1352       vam->retval = retval;
1353       vam->sw_if_index = ntohl (mp->sw_if_index);
1354       vam->result_ready = 1;
1355     }
1356
1357 }
1358
1359 static void vl_api_tap_connect_reply_t_handler_json
1360   (vl_api_tap_connect_reply_t * mp)
1361 {
1362   vat_main_t *vam = &vat_main;
1363   vat_json_node_t node;
1364
1365   vat_json_init_object (&node);
1366   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1367   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1368
1369   vat_json_print (vam->ofp, &node);
1370   vat_json_free (&node);
1371
1372   vam->retval = ntohl (mp->retval);
1373   vam->result_ready = 1;
1374
1375 }
1376
1377 static void
1378 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1379 {
1380   vat_main_t *vam = &vat_main;
1381   i32 retval = ntohl (mp->retval);
1382   if (vam->async_mode)
1383     {
1384       vam->async_errors += (retval < 0);
1385     }
1386   else
1387     {
1388       vam->retval = retval;
1389       vam->sw_if_index = ntohl (mp->sw_if_index);
1390       vam->result_ready = 1;
1391     }
1392 }
1393
1394 static void vl_api_tap_modify_reply_t_handler_json
1395   (vl_api_tap_modify_reply_t * mp)
1396 {
1397   vat_main_t *vam = &vat_main;
1398   vat_json_node_t node;
1399
1400   vat_json_init_object (&node);
1401   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1402   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1403
1404   vat_json_print (vam->ofp, &node);
1405   vat_json_free (&node);
1406
1407   vam->retval = ntohl (mp->retval);
1408   vam->result_ready = 1;
1409 }
1410
1411 static void
1412 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1413 {
1414   vat_main_t *vam = &vat_main;
1415   i32 retval = ntohl (mp->retval);
1416   if (vam->async_mode)
1417     {
1418       vam->async_errors += (retval < 0);
1419     }
1420   else
1421     {
1422       vam->retval = retval;
1423       vam->result_ready = 1;
1424     }
1425 }
1426
1427 static void vl_api_tap_delete_reply_t_handler_json
1428   (vl_api_tap_delete_reply_t * mp)
1429 {
1430   vat_main_t *vam = &vat_main;
1431   vat_json_node_t node;
1432
1433   vat_json_init_object (&node);
1434   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1435
1436   vat_json_print (vam->ofp, &node);
1437   vat_json_free (&node);
1438
1439   vam->retval = ntohl (mp->retval);
1440   vam->result_ready = 1;
1441 }
1442
1443 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1444   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   i32 retval = ntohl (mp->retval);
1448   if (vam->async_mode)
1449     {
1450       vam->async_errors += (retval < 0);
1451     }
1452   else
1453     {
1454       vam->retval = retval;
1455       vam->result_ready = 1;
1456     }
1457 }
1458
1459 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1460   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   vat_json_node_t node;
1464
1465   vat_json_init_object (&node);
1466   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1467   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1468                             ntohl (mp->tunnel_sw_if_index));
1469
1470   vat_json_print (vam->ofp, &node);
1471   vat_json_free (&node);
1472
1473   vam->retval = ntohl (mp->retval);
1474   vam->result_ready = 1;
1475 }
1476
1477 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1478   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1479 {
1480   vat_main_t *vam = &vat_main;
1481   i32 retval = ntohl (mp->retval);
1482   if (vam->async_mode)
1483     {
1484       vam->async_errors += (retval < 0);
1485     }
1486   else
1487     {
1488       vam->retval = retval;
1489       vam->sw_if_index = ntohl (mp->sw_if_index);
1490       vam->result_ready = 1;
1491     }
1492 }
1493
1494 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1495   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   vat_json_node_t node;
1499
1500   vat_json_init_object (&node);
1501   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1502   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1503
1504   vat_json_print (vam->ofp, &node);
1505   vat_json_free (&node);
1506
1507   vam->retval = ntohl (mp->retval);
1508   vam->result_ready = 1;
1509 }
1510
1511
1512 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1513   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1514 {
1515   vat_main_t *vam = &vat_main;
1516   i32 retval = ntohl (mp->retval);
1517   if (vam->async_mode)
1518     {
1519       vam->async_errors += (retval < 0);
1520     }
1521   else
1522     {
1523       vam->retval = retval;
1524       vam->result_ready = 1;
1525     }
1526 }
1527
1528 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1529   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1530 {
1531   vat_main_t *vam = &vat_main;
1532   vat_json_node_t node;
1533
1534   vat_json_init_object (&node);
1535   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1536   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1537
1538   vat_json_print (vam->ofp, &node);
1539   vat_json_free (&node);
1540
1541   vam->retval = ntohl (mp->retval);
1542   vam->result_ready = 1;
1543 }
1544
1545 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1546   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   i32 retval = ntohl (mp->retval);
1550   if (vam->async_mode)
1551     {
1552       vam->async_errors += (retval < 0);
1553     }
1554   else
1555     {
1556       vam->retval = retval;
1557       vam->sw_if_index = ntohl (mp->sw_if_index);
1558       vam->result_ready = 1;
1559     }
1560 }
1561
1562 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1563   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1564 {
1565   vat_main_t *vam = &vat_main;
1566   vat_json_node_t node;
1567
1568   vat_json_init_object (&node);
1569   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1570   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1571
1572   vat_json_print (vam->ofp, &node);
1573   vat_json_free (&node);
1574
1575   vam->retval = ntohl (mp->retval);
1576   vam->result_ready = 1;
1577 }
1578
1579 static void vl_api_gre_add_del_tunnel_reply_t_handler
1580   (vl_api_gre_add_del_tunnel_reply_t * mp)
1581 {
1582   vat_main_t *vam = &vat_main;
1583   i32 retval = ntohl (mp->retval);
1584   if (vam->async_mode)
1585     {
1586       vam->async_errors += (retval < 0);
1587     }
1588   else
1589     {
1590       vam->retval = retval;
1591       vam->sw_if_index = ntohl (mp->sw_if_index);
1592       vam->result_ready = 1;
1593     }
1594 }
1595
1596 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1597   (vl_api_gre_add_del_tunnel_reply_t * mp)
1598 {
1599   vat_main_t *vam = &vat_main;
1600   vat_json_node_t node;
1601
1602   vat_json_init_object (&node);
1603   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1604   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1605
1606   vat_json_print (vam->ofp, &node);
1607   vat_json_free (&node);
1608
1609   vam->retval = ntohl (mp->retval);
1610   vam->result_ready = 1;
1611 }
1612
1613 static void vl_api_create_vhost_user_if_reply_t_handler
1614   (vl_api_create_vhost_user_if_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   i32 retval = ntohl (mp->retval);
1618   if (vam->async_mode)
1619     {
1620       vam->async_errors += (retval < 0);
1621     }
1622   else
1623     {
1624       vam->retval = retval;
1625       vam->sw_if_index = ntohl (mp->sw_if_index);
1626       vam->result_ready = 1;
1627     }
1628 }
1629
1630 static void vl_api_create_vhost_user_if_reply_t_handler_json
1631   (vl_api_create_vhost_user_if_reply_t * mp)
1632 {
1633   vat_main_t *vam = &vat_main;
1634   vat_json_node_t node;
1635
1636   vat_json_init_object (&node);
1637   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1638   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1639
1640   vat_json_print (vam->ofp, &node);
1641   vat_json_free (&node);
1642
1643   vam->retval = ntohl (mp->retval);
1644   vam->result_ready = 1;
1645 }
1646
1647 static void vl_api_ip_address_details_t_handler
1648   (vl_api_ip_address_details_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   static ip_address_details_t empty_ip_address_details = { {0} };
1652   ip_address_details_t *address = NULL;
1653   ip_details_t *current_ip_details = NULL;
1654   ip_details_t *details = NULL;
1655
1656   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1657
1658   if (!details || vam->current_sw_if_index >= vec_len (details)
1659       || !details[vam->current_sw_if_index].present)
1660     {
1661       errmsg ("ip address details arrived but not stored\n");
1662       errmsg ("ip_dump should be called first\n");
1663       return;
1664     }
1665
1666   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1667
1668 #define addresses (current_ip_details->addr)
1669
1670   vec_validate_init_empty (addresses, vec_len (addresses),
1671                            empty_ip_address_details);
1672
1673   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1674
1675   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1676   address->prefix_length = mp->prefix_length;
1677 #undef addresses
1678 }
1679
1680 static void vl_api_ip_address_details_t_handler_json
1681   (vl_api_ip_address_details_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t *node = NULL;
1685   struct in6_addr ip6;
1686   struct in_addr ip4;
1687
1688   if (VAT_JSON_ARRAY != vam->json_tree.type)
1689     {
1690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1691       vat_json_init_array (&vam->json_tree);
1692     }
1693   node = vat_json_array_add (&vam->json_tree);
1694
1695   vat_json_init_object (node);
1696   if (vam->is_ipv6)
1697     {
1698       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1699       vat_json_object_add_ip6 (node, "ip", ip6);
1700     }
1701   else
1702     {
1703       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1704       vat_json_object_add_ip4 (node, "ip", ip4);
1705     }
1706   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1707 }
1708
1709 static void
1710 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   static ip_details_t empty_ip_details = { 0 };
1714   ip_details_t *ip = NULL;
1715   u32 sw_if_index = ~0;
1716
1717   sw_if_index = ntohl (mp->sw_if_index);
1718
1719   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1720                            sw_if_index, empty_ip_details);
1721
1722   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1723                          sw_if_index);
1724
1725   ip->present = 1;
1726 }
1727
1728 static void
1729 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732
1733   if (VAT_JSON_ARRAY != vam->json_tree.type)
1734     {
1735       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1736       vat_json_init_array (&vam->json_tree);
1737     }
1738   vat_json_array_add_uint (&vam->json_tree,
1739                            clib_net_to_host_u32 (mp->sw_if_index));
1740 }
1741
1742 static void vl_api_map_domain_details_t_handler_json
1743   (vl_api_map_domain_details_t * mp)
1744 {
1745   vat_json_node_t *node = NULL;
1746   vat_main_t *vam = &vat_main;
1747   struct in6_addr ip6;
1748   struct in_addr ip4;
1749
1750   if (VAT_JSON_ARRAY != vam->json_tree.type)
1751     {
1752       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1753       vat_json_init_array (&vam->json_tree);
1754     }
1755
1756   node = vat_json_array_add (&vam->json_tree);
1757   vat_json_init_object (node);
1758
1759   vat_json_object_add_uint (node, "domain_index",
1760                             clib_net_to_host_u32 (mp->domain_index));
1761   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1762   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1763   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1764   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1765   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1766   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1767   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1768   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1769   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1770   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1771   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1772   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1773   vat_json_object_add_uint (node, "flags", mp->flags);
1774   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1775   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1776 }
1777
1778 static void vl_api_map_domain_details_t_handler
1779   (vl_api_map_domain_details_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782
1783   if (mp->is_translation)
1784     {
1785       fformat (vam->ofp,
1786                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1787                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1788                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1789                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1790                clib_net_to_host_u32 (mp->domain_index));
1791     }
1792   else
1793     {
1794       fformat (vam->ofp,
1795                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1796                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1797                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1798                format_ip6_address, mp->ip6_src,
1799                clib_net_to_host_u32 (mp->domain_index));
1800     }
1801   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1802            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1803            mp->is_translation ? "map-t" : "");
1804 }
1805
1806 static void vl_api_map_rule_details_t_handler_json
1807   (vl_api_map_rule_details_t * mp)
1808 {
1809   struct in6_addr ip6;
1810   vat_json_node_t *node = NULL;
1811   vat_main_t *vam = &vat_main;
1812
1813   if (VAT_JSON_ARRAY != vam->json_tree.type)
1814     {
1815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1816       vat_json_init_array (&vam->json_tree);
1817     }
1818
1819   node = vat_json_array_add (&vam->json_tree);
1820   vat_json_init_object (node);
1821
1822   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1823   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1824   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1825 }
1826
1827 static void
1828 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1829 {
1830   vat_main_t *vam = &vat_main;
1831   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1832            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1833 }
1834
1835 static void
1836 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1837 {
1838   vat_main_t *vam = &vat_main;
1839   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1840           "router_addr %U host_mac %U\n",
1841           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1842           format_ip4_address, &mp->host_address,
1843           format_ip4_address, &mp->router_address,
1844           format_ethernet_address, mp->host_mac);
1845 }
1846
1847 static void vl_api_dhcp_compl_event_t_handler_json
1848   (vl_api_dhcp_compl_event_t * mp)
1849 {
1850   /* JSON output not supported */
1851 }
1852
1853 static void
1854 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1855                               u32 counter)
1856 {
1857   vat_main_t *vam = &vat_main;
1858   static u64 default_counter = 0;
1859
1860   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1861                            NULL);
1862   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1863                            sw_if_index, default_counter);
1864   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1865 }
1866
1867 static void
1868 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1869                                 interface_counter_t counter)
1870 {
1871   vat_main_t *vam = &vat_main;
1872   static interface_counter_t default_counter = { 0, };
1873
1874   vec_validate_init_empty (vam->combined_interface_counters,
1875                            vnet_counter_type, NULL);
1876   vec_validate_init_empty (vam->combined_interface_counters
1877                            [vnet_counter_type], sw_if_index, default_counter);
1878   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1879 }
1880
1881 static void vl_api_vnet_interface_counters_t_handler
1882   (vl_api_vnet_interface_counters_t * mp)
1883 {
1884   /* not supported */
1885 }
1886
1887 static void vl_api_vnet_interface_counters_t_handler_json
1888   (vl_api_vnet_interface_counters_t * mp)
1889 {
1890   interface_counter_t counter;
1891   vlib_counter_t *v;
1892   u64 *v_packets;
1893   u64 packets;
1894   u32 count;
1895   u32 first_sw_if_index;
1896   int i;
1897
1898   count = ntohl (mp->count);
1899   first_sw_if_index = ntohl (mp->first_sw_if_index);
1900
1901   if (!mp->is_combined)
1902     {
1903       v_packets = (u64 *) & mp->data;
1904       for (i = 0; i < count; i++)
1905         {
1906           packets =
1907             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1908           set_simple_interface_counter (mp->vnet_counter_type,
1909                                         first_sw_if_index + i, packets);
1910           v_packets++;
1911         }
1912     }
1913   else
1914     {
1915       v = (vlib_counter_t *) & mp->data;
1916       for (i = 0; i < count; i++)
1917         {
1918           counter.packets =
1919             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1920           counter.bytes =
1921             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1922           set_combined_interface_counter (mp->vnet_counter_type,
1923                                           first_sw_if_index + i, counter);
1924           v++;
1925         }
1926     }
1927 }
1928
1929 static u32
1930 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1931 {
1932   vat_main_t *vam = &vat_main;
1933   u32 i;
1934
1935   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1936     {
1937       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1938         {
1939           return i;
1940         }
1941     }
1942   return ~0;
1943 }
1944
1945 static u32
1946 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1947 {
1948   vat_main_t *vam = &vat_main;
1949   u32 i;
1950
1951   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1952     {
1953       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1954         {
1955           return i;
1956         }
1957     }
1958   return ~0;
1959 }
1960
1961 static void vl_api_vnet_ip4_fib_counters_t_handler
1962   (vl_api_vnet_ip4_fib_counters_t * mp)
1963 {
1964   /* not supported */
1965 }
1966
1967 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1968   (vl_api_vnet_ip4_fib_counters_t * mp)
1969 {
1970   vat_main_t *vam = &vat_main;
1971   vl_api_ip4_fib_counter_t *v;
1972   ip4_fib_counter_t *counter;
1973   struct in_addr ip4;
1974   u32 vrf_id;
1975   u32 vrf_index;
1976   u32 count;
1977   int i;
1978
1979   vrf_id = ntohl (mp->vrf_id);
1980   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
1981   if (~0 == vrf_index)
1982     {
1983       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
1984       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1985       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1986       vec_validate (vam->ip4_fib_counters, vrf_index);
1987       vam->ip4_fib_counters[vrf_index] = NULL;
1988     }
1989
1990   vec_free (vam->ip4_fib_counters[vrf_index]);
1991   v = (vl_api_ip4_fib_counter_t *) & mp->c;
1992   count = ntohl (mp->count);
1993   for (i = 0; i < count; i++)
1994     {
1995       vec_validate (vam->ip4_fib_counters[vrf_index], i);
1996       counter = &vam->ip4_fib_counters[vrf_index][i];
1997       clib_memcpy (&ip4, &v->address, sizeof (ip4));
1998       counter->address = ip4;
1999       counter->address_length = v->address_length;
2000       counter->packets = clib_net_to_host_u64 (v->packets);
2001       counter->bytes = clib_net_to_host_u64 (v->bytes);
2002       v++;
2003     }
2004 }
2005
2006 static void vl_api_vnet_ip6_fib_counters_t_handler
2007   (vl_api_vnet_ip6_fib_counters_t * mp)
2008 {
2009   /* not supported */
2010 }
2011
2012 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2013   (vl_api_vnet_ip6_fib_counters_t * mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016   vl_api_ip6_fib_counter_t *v;
2017   ip6_fib_counter_t *counter;
2018   struct in6_addr ip6;
2019   u32 vrf_id;
2020   u32 vrf_index;
2021   u32 count;
2022   int i;
2023
2024   vrf_id = ntohl (mp->vrf_id);
2025   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2026   if (~0 == vrf_index)
2027     {
2028       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2029       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2030       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2031       vec_validate (vam->ip6_fib_counters, vrf_index);
2032       vam->ip6_fib_counters[vrf_index] = NULL;
2033     }
2034
2035   vec_free (vam->ip6_fib_counters[vrf_index]);
2036   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2037   count = ntohl (mp->count);
2038   for (i = 0; i < count; i++)
2039     {
2040       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2041       counter = &vam->ip6_fib_counters[vrf_index][i];
2042       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2043       counter->address = ip6;
2044       counter->address_length = v->address_length;
2045       counter->packets = clib_net_to_host_u64 (v->packets);
2046       counter->bytes = clib_net_to_host_u64 (v->bytes);
2047       v++;
2048     }
2049 }
2050
2051 static void vl_api_get_first_msg_id_reply_t_handler
2052   (vl_api_get_first_msg_id_reply_t * mp)
2053 {
2054   vat_main_t *vam = &vat_main;
2055   i32 retval = ntohl (mp->retval);
2056
2057   if (vam->async_mode)
2058     {
2059       vam->async_errors += (retval < 0);
2060     }
2061   else
2062     {
2063       vam->retval = retval;
2064       vam->result_ready = 1;
2065     }
2066   if (retval >= 0)
2067     {
2068       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2069     }
2070 }
2071
2072 static void vl_api_get_first_msg_id_reply_t_handler_json
2073   (vl_api_get_first_msg_id_reply_t * mp)
2074 {
2075   vat_main_t *vam = &vat_main;
2076   vat_json_node_t node;
2077
2078   vat_json_init_object (&node);
2079   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2080   vat_json_object_add_uint (&node, "first_msg_id",
2081                             (uint) ntohs (mp->first_msg_id));
2082
2083   vat_json_print (vam->ofp, &node);
2084   vat_json_free (&node);
2085
2086   vam->retval = ntohl (mp->retval);
2087   vam->result_ready = 1;
2088 }
2089
2090 static void vl_api_get_node_graph_reply_t_handler
2091   (vl_api_get_node_graph_reply_t * mp)
2092 {
2093   vat_main_t *vam = &vat_main;
2094   api_main_t *am = &api_main;
2095   i32 retval = ntohl (mp->retval);
2096   u8 *pvt_copy, *reply;
2097   void *oldheap;
2098   vlib_node_t *node;
2099   int i;
2100
2101   if (vam->async_mode)
2102     {
2103       vam->async_errors += (retval < 0);
2104     }
2105   else
2106     {
2107       vam->retval = retval;
2108       vam->result_ready = 1;
2109     }
2110
2111   /* "Should never happen..." */
2112   if (retval != 0)
2113     return;
2114
2115   reply = (u8 *) (mp->reply_in_shmem);
2116   pvt_copy = vec_dup (reply);
2117
2118   /* Toss the shared-memory original... */
2119   pthread_mutex_lock (&am->vlib_rp->mutex);
2120   oldheap = svm_push_data_heap (am->vlib_rp);
2121
2122   vec_free (reply);
2123
2124   svm_pop_heap (oldheap);
2125   pthread_mutex_unlock (&am->vlib_rp->mutex);
2126
2127   if (vam->graph_nodes)
2128     {
2129       hash_free (vam->graph_node_index_by_name);
2130
2131       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2132         {
2133           node = vam->graph_nodes[i];
2134           vec_free (node->name);
2135           vec_free (node->next_nodes);
2136           vec_free (node);
2137         }
2138       vec_free (vam->graph_nodes);
2139     }
2140
2141   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2142   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2143   vec_free (pvt_copy);
2144
2145   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2146     {
2147       node = vam->graph_nodes[i];
2148       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2149     }
2150 }
2151
2152 static void vl_api_get_node_graph_reply_t_handler_json
2153   (vl_api_get_node_graph_reply_t * mp)
2154 {
2155   vat_main_t *vam = &vat_main;
2156   api_main_t *am = &api_main;
2157   void *oldheap;
2158   vat_json_node_t node;
2159   u8 *reply;
2160
2161   /* $$$$ make this real? */
2162   vat_json_init_object (&node);
2163   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2164   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2165
2166   reply = (u8 *) (mp->reply_in_shmem);
2167
2168   /* Toss the shared-memory original... */
2169   pthread_mutex_lock (&am->vlib_rp->mutex);
2170   oldheap = svm_push_data_heap (am->vlib_rp);
2171
2172   vec_free (reply);
2173
2174   svm_pop_heap (oldheap);
2175   pthread_mutex_unlock (&am->vlib_rp->mutex);
2176
2177   vat_json_print (vam->ofp, &node);
2178   vat_json_free (&node);
2179
2180   vam->retval = ntohl (mp->retval);
2181   vam->result_ready = 1;
2182 }
2183
2184 static void
2185 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2186 {
2187   vat_main_t *vam = &vat_main;
2188   u8 *s = 0;
2189
2190   if (mp->local)
2191     {
2192       s = format (s, "%=16d%=16d%=16d\n",
2193                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2194     }
2195   else
2196     {
2197       s = format (s, "%=16U%=16d%=16d\n",
2198                   mp->is_ipv6 ? format_ip6_address :
2199                   format_ip4_address,
2200                   mp->ip_address, mp->priority, mp->weight);
2201     }
2202
2203   fformat (vam->ofp, "%v", s);
2204   vec_free (s);
2205 }
2206
2207 static void
2208 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2209                                             mp)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   vat_json_node_t *node = NULL;
2213   struct in6_addr ip6;
2214   struct in_addr ip4;
2215
2216   if (VAT_JSON_ARRAY != vam->json_tree.type)
2217     {
2218       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2219       vat_json_init_array (&vam->json_tree);
2220     }
2221   node = vat_json_array_add (&vam->json_tree);
2222   vat_json_init_object (node);
2223
2224   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2225   vat_json_object_add_uint (node, "priority", mp->priority);
2226   vat_json_object_add_uint (node, "weight", mp->weight);
2227
2228   if (mp->local)
2229     vat_json_object_add_uint (node, "sw_if_index",
2230                               clib_net_to_host_u32 (mp->sw_if_index));
2231   else
2232     {
2233       if (mp->is_ipv6)
2234         {
2235           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2236           vat_json_object_add_ip6 (node, "address", ip6);
2237         }
2238       else
2239         {
2240           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2241           vat_json_object_add_ip4 (node, "address", ip4);
2242         }
2243     }
2244 }
2245
2246 static void
2247 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2248                                            mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   u8 *ls_name = 0;
2252
2253   ls_name = format (0, "%s", mp->ls_name);
2254
2255   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2256            ls_name);
2257   vec_free (ls_name);
2258 }
2259
2260 static void
2261   vl_api_lisp_locator_set_details_t_handler_json
2262   (vl_api_lisp_locator_set_details_t * mp)
2263 {
2264   vat_main_t *vam = &vat_main;
2265   vat_json_node_t *node = 0;
2266   u8 *ls_name = 0;
2267
2268   ls_name = format (0, "%s", mp->ls_name);
2269   vec_add1 (ls_name, 0);
2270
2271   if (VAT_JSON_ARRAY != vam->json_tree.type)
2272     {
2273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2274       vat_json_init_array (&vam->json_tree);
2275     }
2276   node = vat_json_array_add (&vam->json_tree);
2277
2278   vat_json_init_object (node);
2279   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2280   vat_json_object_add_uint (node, "ls_index",
2281                             clib_net_to_host_u32 (mp->ls_index));
2282   vec_free (ls_name);
2283 }
2284
2285 static u8 *
2286 format_lisp_flat_eid (u8 * s, va_list * args)
2287 {
2288   u32 type = va_arg (*args, u32);
2289   u8 *eid = va_arg (*args, u8 *);
2290   u32 eid_len = va_arg (*args, u32);
2291
2292   switch (type)
2293     {
2294     case 0:
2295       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2296     case 1:
2297       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2298     case 2:
2299       return format (s, "%U", format_ethernet_address, eid);
2300     }
2301   return 0;
2302 }
2303
2304 static u8 *
2305 format_lisp_eid_vat (u8 * s, va_list * args)
2306 {
2307   u32 type = va_arg (*args, u32);
2308   u8 *eid = va_arg (*args, u8 *);
2309   u32 eid_len = va_arg (*args, u32);
2310   u8 *seid = va_arg (*args, u8 *);
2311   u32 seid_len = va_arg (*args, u32);
2312   u32 is_src_dst = va_arg (*args, u32);
2313
2314   if (is_src_dst)
2315     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2316
2317   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2318
2319   return s;
2320 }
2321
2322 static void
2323 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2324 {
2325   vat_main_t *vam = &vat_main;
2326   u8 *s = 0, *eid = 0;
2327
2328   if (~0 == mp->locator_set_index)
2329     s = format (0, "action: %d", mp->action);
2330   else
2331     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2332
2333   eid = format (0, "%U", format_lisp_eid_vat,
2334                 mp->eid_type,
2335                 mp->eid,
2336                 mp->eid_prefix_len,
2337                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2338   vec_add1 (eid, 0);
2339
2340   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2341            clib_net_to_host_u32 (mp->vni),
2342            eid,
2343            mp->is_local ? "local" : "remote",
2344            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2345   vec_free (s);
2346   vec_free (eid);
2347 }
2348
2349 static void
2350 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2351                                               * mp)
2352 {
2353   vat_main_t *vam = &vat_main;
2354   vat_json_node_t *node = 0;
2355   u8 *eid = 0;
2356
2357   if (VAT_JSON_ARRAY != vam->json_tree.type)
2358     {
2359       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2360       vat_json_init_array (&vam->json_tree);
2361     }
2362   node = vat_json_array_add (&vam->json_tree);
2363
2364   vat_json_init_object (node);
2365   if (~0 == mp->locator_set_index)
2366     vat_json_object_add_uint (node, "action", mp->action);
2367   else
2368     vat_json_object_add_uint (node, "locator_set_index",
2369                               clib_net_to_host_u32 (mp->locator_set_index));
2370
2371   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2372   eid = format (0, "%U", format_lisp_eid_vat,
2373                 mp->eid_type,
2374                 mp->eid,
2375                 mp->eid_prefix_len,
2376                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2377   vec_add1 (eid, 0);
2378   vat_json_object_add_string_copy (node, "eid", eid);
2379   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2380   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2381   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2382   vec_free (eid);
2383 }
2384
2385 static void
2386   vl_api_lisp_eid_table_map_details_t_handler
2387   (vl_api_lisp_eid_table_map_details_t * mp)
2388 {
2389   vat_main_t *vam = &vat_main;
2390
2391   u8 *line = format (0, "%=10d%=10d",
2392                      clib_net_to_host_u32 (mp->vni),
2393                      clib_net_to_host_u32 (mp->dp_table));
2394   fformat (vam->ofp, "%v\n", line);
2395   vec_free (line);
2396 }
2397
2398 static void
2399   vl_api_lisp_eid_table_map_details_t_handler_json
2400   (vl_api_lisp_eid_table_map_details_t * mp)
2401 {
2402   vat_main_t *vam = &vat_main;
2403   vat_json_node_t *node = NULL;
2404
2405   if (VAT_JSON_ARRAY != vam->json_tree.type)
2406     {
2407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2408       vat_json_init_array (&vam->json_tree);
2409     }
2410   node = vat_json_array_add (&vam->json_tree);
2411   vat_json_init_object (node);
2412   vat_json_object_add_uint (node, "dp_table",
2413                             clib_net_to_host_u32 (mp->dp_table));
2414   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2415 }
2416
2417 static void
2418   vl_api_lisp_eid_table_vni_details_t_handler
2419   (vl_api_lisp_eid_table_vni_details_t * mp)
2420 {
2421   vat_main_t *vam = &vat_main;
2422
2423   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2424   fformat (vam->ofp, "%v\n", line);
2425   vec_free (line);
2426 }
2427
2428 static void
2429   vl_api_lisp_eid_table_vni_details_t_handler_json
2430   (vl_api_lisp_eid_table_vni_details_t * mp)
2431 {
2432   vat_main_t *vam = &vat_main;
2433   vat_json_node_t *node = NULL;
2434
2435   if (VAT_JSON_ARRAY != vam->json_tree.type)
2436     {
2437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2438       vat_json_init_array (&vam->json_tree);
2439     }
2440   node = vat_json_array_add (&vam->json_tree);
2441   vat_json_init_object (node);
2442   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2443 }
2444
2445 static u8 *
2446 format_decap_next (u8 * s, va_list * args)
2447 {
2448   u32 next_index = va_arg (*args, u32);
2449
2450   switch (next_index)
2451     {
2452     case LISP_GPE_INPUT_NEXT_DROP:
2453       return format (s, "drop");
2454     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2455       return format (s, "ip4");
2456     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2457       return format (s, "ip6");
2458     default:
2459       return format (s, "unknown %d", next_index);
2460     }
2461   return s;
2462 }
2463
2464 static void
2465 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2466                                           mp)
2467 {
2468   vat_main_t *vam = &vat_main;
2469   u8 *iid_str;
2470   u8 *flag_str = NULL;
2471
2472   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2473
2474 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2475   foreach_lisp_gpe_flag_bit;
2476 #undef _
2477
2478   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2479            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2480            mp->tunnels,
2481            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2482            mp->source_ip,
2483            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2484            mp->destination_ip,
2485            ntohl (mp->encap_fib_id),
2486            ntohl (mp->decap_fib_id),
2487            format_decap_next, ntohl (mp->dcap_next),
2488            mp->ver_res >> 6,
2489            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2490
2491   vec_free (iid_str);
2492 }
2493
2494 static void
2495   vl_api_lisp_gpe_tunnel_details_t_handler_json
2496   (vl_api_lisp_gpe_tunnel_details_t * mp)
2497 {
2498   vat_main_t *vam = &vat_main;
2499   vat_json_node_t *node = NULL;
2500   struct in6_addr ip6;
2501   struct in_addr ip4;
2502   u8 *next_decap_str;
2503
2504   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2505
2506   if (VAT_JSON_ARRAY != vam->json_tree.type)
2507     {
2508       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2509       vat_json_init_array (&vam->json_tree);
2510     }
2511   node = vat_json_array_add (&vam->json_tree);
2512
2513   vat_json_init_object (node);
2514   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2515   if (mp->is_ipv6)
2516     {
2517       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2518       vat_json_object_add_ip6 (node, "source address", ip6);
2519       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2520       vat_json_object_add_ip6 (node, "destination address", ip6);
2521     }
2522   else
2523     {
2524       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2525       vat_json_object_add_ip4 (node, "source address", ip4);
2526       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2527       vat_json_object_add_ip4 (node, "destination address", ip4);
2528     }
2529   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2530   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2531   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2532   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2533   vat_json_object_add_uint (node, "flags", mp->flags);
2534   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2535   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2536   vat_json_object_add_uint (node, "res", mp->res);
2537   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2538
2539   vec_free (next_decap_str);
2540 }
2541
2542 static void
2543   vl_api_lisp_adjacencies_get_reply_t_handler
2544   (vl_api_lisp_adjacencies_get_reply_t * mp)
2545 {
2546   vat_main_t *vam = &vat_main;
2547   u32 i, n;
2548   int retval = clib_net_to_host_u32 (mp->retval);
2549   vl_api_lisp_adjacency_t *a;
2550
2551   if (retval)
2552     goto end;
2553
2554   n = clib_net_to_host_u32 (mp->count);
2555
2556   for (i = 0; i < n; i++)
2557     {
2558       a = &mp->adjacencies[i];
2559       fformat (vam->ofp, "%U %40U\n",
2560                format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2561                format_lisp_flat_eid, a->eid_type, a->reid,
2562                a->reid_prefix_len);
2563     }
2564
2565 end:
2566   vam->retval = retval;
2567   vam->result_ready = 1;
2568 }
2569
2570 static void
2571   vl_api_lisp_adjacencies_get_reply_t_handler_json
2572   (vl_api_lisp_adjacencies_get_reply_t * mp)
2573 {
2574   u8 *s = 0;
2575   vat_main_t *vam = &vat_main;
2576   vat_json_node_t *e = 0, root;
2577   u32 i, n;
2578   int retval = clib_net_to_host_u32 (mp->retval);
2579   vl_api_lisp_adjacency_t *a;
2580
2581   if (retval)
2582     goto end;
2583
2584   n = clib_net_to_host_u32 (mp->count);
2585   vat_json_init_array (&root);
2586
2587   for (i = 0; i < n; i++)
2588     {
2589       e = vat_json_array_add (&root);
2590       a = &mp->adjacencies[i];
2591
2592       vat_json_init_object (e);
2593       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2594                   a->leid_prefix_len);
2595       vec_add1 (s, 0);
2596       vat_json_object_add_string_copy (e, "leid", s);
2597       vec_free (s);
2598
2599       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2600                   a->reid_prefix_len);
2601       vec_add1 (s, 0);
2602       vat_json_object_add_string_copy (e, "reid", s);
2603       vec_free (s);
2604     }
2605
2606   vat_json_print (vam->ofp, &root);
2607   vat_json_free (&root);
2608
2609 end:
2610   vam->retval = retval;
2611   vam->result_ready = 1;
2612 }
2613
2614 static void
2615 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2616                                             * mp)
2617 {
2618   vat_main_t *vam = &vat_main;
2619
2620   fformat (vam->ofp, "%=20U\n",
2621            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2622            mp->ip_address);
2623 }
2624
2625 static void
2626   vl_api_lisp_map_resolver_details_t_handler_json
2627   (vl_api_lisp_map_resolver_details_t * mp)
2628 {
2629   vat_main_t *vam = &vat_main;
2630   vat_json_node_t *node = NULL;
2631   struct in6_addr ip6;
2632   struct in_addr ip4;
2633
2634   if (VAT_JSON_ARRAY != vam->json_tree.type)
2635     {
2636       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2637       vat_json_init_array (&vam->json_tree);
2638     }
2639   node = vat_json_array_add (&vam->json_tree);
2640
2641   vat_json_init_object (node);
2642   if (mp->is_ipv6)
2643     {
2644       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2645       vat_json_object_add_ip6 (node, "map resolver", ip6);
2646     }
2647   else
2648     {
2649       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2650       vat_json_object_add_ip4 (node, "map resolver", ip4);
2651     }
2652 }
2653
2654 static void
2655   vl_api_show_lisp_status_reply_t_handler
2656   (vl_api_show_lisp_status_reply_t * mp)
2657 {
2658   vat_main_t *vam = &vat_main;
2659   i32 retval = ntohl (mp->retval);
2660
2661   if (0 <= retval)
2662     {
2663       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2664                mp->feature_status ? "enabled" : "disabled",
2665                mp->gpe_status ? "enabled" : "disabled");
2666     }
2667
2668   vam->retval = retval;
2669   vam->result_ready = 1;
2670 }
2671
2672 static void
2673   vl_api_show_lisp_status_reply_t_handler_json
2674   (vl_api_show_lisp_status_reply_t * mp)
2675 {
2676   vat_main_t *vam = &vat_main;
2677   vat_json_node_t node;
2678   u8 *gpe_status = NULL;
2679   u8 *feature_status = NULL;
2680
2681   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2682   feature_status = format (0, "%s",
2683                            mp->feature_status ? "enabled" : "disabled");
2684   vec_add1 (gpe_status, 0);
2685   vec_add1 (feature_status, 0);
2686
2687   vat_json_init_object (&node);
2688   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2689   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2690
2691   vec_free (gpe_status);
2692   vec_free (feature_status);
2693
2694   vat_json_print (vam->ofp, &node);
2695   vat_json_free (&node);
2696
2697   vam->retval = ntohl (mp->retval);
2698   vam->result_ready = 1;
2699 }
2700
2701 static void
2702   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2703   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2704 {
2705   vat_main_t *vam = &vat_main;
2706   i32 retval = ntohl (mp->retval);
2707
2708   if (retval >= 0)
2709     {
2710       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2711     }
2712
2713   vam->retval = retval;
2714   vam->result_ready = 1;
2715 }
2716
2717 static void
2718   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2719   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2720 {
2721   vat_main_t *vam = &vat_main;
2722   vat_json_node_t *node = NULL;
2723
2724   if (VAT_JSON_ARRAY != vam->json_tree.type)
2725     {
2726       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2727       vat_json_init_array (&vam->json_tree);
2728     }
2729   node = vat_json_array_add (&vam->json_tree);
2730
2731   vat_json_init_object (node);
2732   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2733
2734   vat_json_print (vam->ofp, node);
2735   vat_json_free (node);
2736
2737   vam->retval = ntohl (mp->retval);
2738   vam->result_ready = 1;
2739 }
2740
2741 static u8 *
2742 format_lisp_map_request_mode (u8 * s, va_list * args)
2743 {
2744   u32 mode = va_arg (*args, u32);
2745
2746   switch (mode)
2747     {
2748     case 0:
2749       return format (0, "dst-only");
2750     case 1:
2751       return format (0, "src-dst");
2752     }
2753   return 0;
2754 }
2755
2756 static void
2757   vl_api_show_lisp_map_request_mode_reply_t_handler
2758   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2759 {
2760   vat_main_t *vam = &vat_main;
2761   i32 retval = ntohl (mp->retval);
2762
2763   if (0 <= retval)
2764     {
2765       u32 mode = mp->mode;
2766       fformat (vam->ofp, "map_request_mode: %U\n",
2767                format_lisp_map_request_mode, mode);
2768     }
2769
2770   vam->retval = retval;
2771   vam->result_ready = 1;
2772 }
2773
2774 static void
2775   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2776   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2777 {
2778   vat_main_t *vam = &vat_main;
2779   vat_json_node_t node;
2780   u8 *s = 0;
2781   u32 mode;
2782
2783   mode = mp->mode;
2784   s = format (0, "%U", format_lisp_map_request_mode, mode);
2785   vec_add1 (s, 0);
2786
2787   vat_json_init_object (&node);
2788   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2789   vat_json_print (vam->ofp, &node);
2790   vat_json_free (&node);
2791
2792   vec_free (s);
2793   vam->retval = ntohl (mp->retval);
2794   vam->result_ready = 1;
2795 }
2796
2797 static void
2798 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2799 {
2800   vat_main_t *vam = &vat_main;
2801   i32 retval = ntohl (mp->retval);
2802
2803   if (0 <= retval)
2804     {
2805       fformat (vam->ofp, "%-20s%-16s\n",
2806                mp->status ? "enabled" : "disabled",
2807                mp->status ? (char *) mp->locator_set_name : "");
2808     }
2809
2810   vam->retval = retval;
2811   vam->result_ready = 1;
2812 }
2813
2814 static void
2815 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2816                                             mp)
2817 {
2818   vat_main_t *vam = &vat_main;
2819   vat_json_node_t node;
2820   u8 *status = 0;
2821
2822   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2823   vec_add1 (status, 0);
2824
2825   vat_json_init_object (&node);
2826   vat_json_object_add_string_copy (&node, "status", status);
2827   if (mp->status)
2828     {
2829       vat_json_object_add_string_copy (&node, "locator_set",
2830                                        mp->locator_set_name);
2831     }
2832
2833   vec_free (status);
2834
2835   vat_json_print (vam->ofp, &node);
2836   vat_json_free (&node);
2837
2838   vam->retval = ntohl (mp->retval);
2839   vam->result_ready = 1;
2840 }
2841
2842 static u8 *
2843 format_policer_type (u8 * s, va_list * va)
2844 {
2845   u32 i = va_arg (*va, u32);
2846
2847   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2848     s = format (s, "1r2c");
2849   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2850     s = format (s, "1r3c");
2851   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2852     s = format (s, "2r3c-2698");
2853   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2854     s = format (s, "2r3c-4115");
2855   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2856     s = format (s, "2r3c-mef5cf1");
2857   else
2858     s = format (s, "ILLEGAL");
2859   return s;
2860 }
2861
2862 static u8 *
2863 format_policer_rate_type (u8 * s, va_list * va)
2864 {
2865   u32 i = va_arg (*va, u32);
2866
2867   if (i == SSE2_QOS_RATE_KBPS)
2868     s = format (s, "kbps");
2869   else if (i == SSE2_QOS_RATE_PPS)
2870     s = format (s, "pps");
2871   else
2872     s = format (s, "ILLEGAL");
2873   return s;
2874 }
2875
2876 static u8 *
2877 format_policer_round_type (u8 * s, va_list * va)
2878 {
2879   u32 i = va_arg (*va, u32);
2880
2881   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2882     s = format (s, "closest");
2883   else if (i == SSE2_QOS_ROUND_TO_UP)
2884     s = format (s, "up");
2885   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2886     s = format (s, "down");
2887   else
2888     s = format (s, "ILLEGAL");
2889   return s;
2890 }
2891
2892 static u8 *
2893 format_policer_action_type (u8 * s, va_list * va)
2894 {
2895   u32 i = va_arg (*va, u32);
2896
2897   if (i == SSE2_QOS_ACTION_DROP)
2898     s = format (s, "drop");
2899   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2900     s = format (s, "transmit");
2901   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2902     s = format (s, "mark-and-transmit");
2903   else
2904     s = format (s, "ILLEGAL");
2905   return s;
2906 }
2907
2908 static u8 *
2909 format_dscp (u8 * s, va_list * va)
2910 {
2911   u32 i = va_arg (*va, u32);
2912   char *t = 0;
2913
2914   switch (i)
2915     {
2916 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2917       foreach_vnet_dscp
2918 #undef _
2919     default:
2920       return format (s, "ILLEGAL");
2921     }
2922   s = format (s, "%s", t);
2923   return s;
2924 }
2925
2926 static void
2927 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2928 {
2929   vat_main_t *vam = &vat_main;
2930   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2931
2932   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2933     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2934   else
2935     conform_dscp_str = format (0, "");
2936
2937   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2938     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2939   else
2940     exceed_dscp_str = format (0, "");
2941
2942   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2943     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2944   else
2945     violate_dscp_str = format (0, "");
2946
2947   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2948            "rate type %U, round type %U, %s rate, %s color-aware, "
2949            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2950            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2951            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2952            mp->name,
2953            format_policer_type, mp->type,
2954            ntohl (mp->cir),
2955            ntohl (mp->eir),
2956            clib_net_to_host_u64 (mp->cb),
2957            clib_net_to_host_u64 (mp->eb),
2958            format_policer_rate_type, mp->rate_type,
2959            format_policer_round_type, mp->round_type,
2960            mp->single_rate ? "single" : "dual",
2961            mp->color_aware ? "is" : "not",
2962            ntohl (mp->cir_tokens_per_period),
2963            ntohl (mp->pir_tokens_per_period),
2964            ntohl (mp->scale),
2965            ntohl (mp->current_limit),
2966            ntohl (mp->current_bucket),
2967            ntohl (mp->extended_limit),
2968            ntohl (mp->extended_bucket),
2969            clib_net_to_host_u64 (mp->last_update_time),
2970            format_policer_action_type, mp->conform_action_type,
2971            conform_dscp_str,
2972            format_policer_action_type, mp->exceed_action_type,
2973            exceed_dscp_str,
2974            format_policer_action_type, mp->violate_action_type,
2975            violate_dscp_str);
2976
2977   vec_free (conform_dscp_str);
2978   vec_free (exceed_dscp_str);
2979   vec_free (violate_dscp_str);
2980 }
2981
2982 static void vl_api_policer_details_t_handler_json
2983   (vl_api_policer_details_t * mp)
2984 {
2985   vat_main_t *vam = &vat_main;
2986   vat_json_node_t *node;
2987   u8 *rate_type_str, *round_type_str, *type_str;
2988   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2989
2990   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2991   round_type_str =
2992     format (0, "%U", format_policer_round_type, mp->round_type);
2993   type_str = format (0, "%U", format_policer_type, mp->type);
2994   conform_action_str = format (0, "%U", format_policer_action_type,
2995                                mp->conform_action_type);
2996   exceed_action_str = format (0, "%U", format_policer_action_type,
2997                               mp->exceed_action_type);
2998   violate_action_str = format (0, "%U", format_policer_action_type,
2999                                mp->violate_action_type);
3000
3001   if (VAT_JSON_ARRAY != vam->json_tree.type)
3002     {
3003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3004       vat_json_init_array (&vam->json_tree);
3005     }
3006   node = vat_json_array_add (&vam->json_tree);
3007
3008   vat_json_init_object (node);
3009   vat_json_object_add_string_copy (node, "name", mp->name);
3010   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3011   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3012   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3013   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3014   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3015   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3016   vat_json_object_add_string_copy (node, "type", type_str);
3017   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3018   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3019   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3020   vat_json_object_add_uint (node, "cir_tokens_per_period",
3021                             ntohl (mp->cir_tokens_per_period));
3022   vat_json_object_add_uint (node, "eir_tokens_per_period",
3023                             ntohl (mp->pir_tokens_per_period));
3024   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3025   vat_json_object_add_uint (node, "current_bucket",
3026                             ntohl (mp->current_bucket));
3027   vat_json_object_add_uint (node, "extended_limit",
3028                             ntohl (mp->extended_limit));
3029   vat_json_object_add_uint (node, "extended_bucket",
3030                             ntohl (mp->extended_bucket));
3031   vat_json_object_add_uint (node, "last_update_time",
3032                             ntohl (mp->last_update_time));
3033   vat_json_object_add_string_copy (node, "conform_action",
3034                                    conform_action_str);
3035   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3036     {
3037       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3038       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3039       vec_free (dscp_str);
3040     }
3041   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3042   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3043     {
3044       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3045       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3046       vec_free (dscp_str);
3047     }
3048   vat_json_object_add_string_copy (node, "violate_action",
3049                                    violate_action_str);
3050   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3051     {
3052       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3053       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3054       vec_free (dscp_str);
3055     }
3056
3057   vec_free (rate_type_str);
3058   vec_free (round_type_str);
3059   vec_free (type_str);
3060   vec_free (conform_action_str);
3061   vec_free (exceed_action_str);
3062   vec_free (violate_action_str);
3063 }
3064
3065 static void
3066 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3067                                            mp)
3068 {
3069   vat_main_t *vam = &vat_main;
3070   int i, count = ntohl (mp->count);
3071
3072   if (count > 0)
3073     fformat (vam->ofp, "classify table ids (%d) : ", count);
3074   for (i = 0; i < count; i++)
3075     {
3076       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3077       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3078     }
3079   vam->retval = ntohl (mp->retval);
3080   vam->result_ready = 1;
3081 }
3082
3083 static void
3084   vl_api_classify_table_ids_reply_t_handler_json
3085   (vl_api_classify_table_ids_reply_t * mp)
3086 {
3087   vat_main_t *vam = &vat_main;
3088   int i, count = ntohl (mp->count);
3089
3090   if (count > 0)
3091     {
3092       vat_json_node_t node;
3093
3094       vat_json_init_object (&node);
3095       for (i = 0; i < count; i++)
3096         {
3097           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3098         }
3099       vat_json_print (vam->ofp, &node);
3100       vat_json_free (&node);
3101     }
3102   vam->retval = ntohl (mp->retval);
3103   vam->result_ready = 1;
3104 }
3105
3106 static void
3107   vl_api_classify_table_by_interface_reply_t_handler
3108   (vl_api_classify_table_by_interface_reply_t * mp)
3109 {
3110   vat_main_t *vam = &vat_main;
3111   u32 table_id;
3112
3113   table_id = ntohl (mp->l2_table_id);
3114   if (table_id != ~0)
3115     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3116   else
3117     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3118   table_id = ntohl (mp->ip4_table_id);
3119   if (table_id != ~0)
3120     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3121   else
3122     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3123   table_id = ntohl (mp->ip6_table_id);
3124   if (table_id != ~0)
3125     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3126   else
3127     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3128   vam->retval = ntohl (mp->retval);
3129   vam->result_ready = 1;
3130 }
3131
3132 static void
3133   vl_api_classify_table_by_interface_reply_t_handler_json
3134   (vl_api_classify_table_by_interface_reply_t * mp)
3135 {
3136   vat_main_t *vam = &vat_main;
3137   vat_json_node_t node;
3138
3139   vat_json_init_object (&node);
3140
3141   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3142   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3143   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3144
3145   vat_json_print (vam->ofp, &node);
3146   vat_json_free (&node);
3147
3148   vam->retval = ntohl (mp->retval);
3149   vam->result_ready = 1;
3150 }
3151
3152 static void vl_api_policer_add_del_reply_t_handler
3153   (vl_api_policer_add_del_reply_t * mp)
3154 {
3155   vat_main_t *vam = &vat_main;
3156   i32 retval = ntohl (mp->retval);
3157   if (vam->async_mode)
3158     {
3159       vam->async_errors += (retval < 0);
3160     }
3161   else
3162     {
3163       vam->retval = retval;
3164       vam->result_ready = 1;
3165       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3166         /*
3167          * Note: this is just barely thread-safe, depends on
3168          * the main thread spinning waiting for an answer...
3169          */
3170         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3171     }
3172 }
3173
3174 static void vl_api_policer_add_del_reply_t_handler_json
3175   (vl_api_policer_add_del_reply_t * mp)
3176 {
3177   vat_main_t *vam = &vat_main;
3178   vat_json_node_t node;
3179
3180   vat_json_init_object (&node);
3181   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3182   vat_json_object_add_uint (&node, "policer_index",
3183                             ntohl (mp->policer_index));
3184
3185   vat_json_print (vam->ofp, &node);
3186   vat_json_free (&node);
3187
3188   vam->retval = ntohl (mp->retval);
3189   vam->result_ready = 1;
3190 }
3191
3192 /* Format hex dump. */
3193 u8 *
3194 format_hex_bytes (u8 * s, va_list * va)
3195 {
3196   u8 *bytes = va_arg (*va, u8 *);
3197   int n_bytes = va_arg (*va, int);
3198   uword i;
3199
3200   /* Print short or long form depending on byte count. */
3201   uword short_form = n_bytes <= 32;
3202   uword indent = format_get_indent (s);
3203
3204   if (n_bytes == 0)
3205     return s;
3206
3207   for (i = 0; i < n_bytes; i++)
3208     {
3209       if (!short_form && (i % 32) == 0)
3210         s = format (s, "%08x: ", i);
3211       s = format (s, "%02x", bytes[i]);
3212       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3213         s = format (s, "\n%U", format_white_space, indent);
3214     }
3215
3216   return s;
3217 }
3218
3219 static void
3220 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3221                                             * mp)
3222 {
3223   vat_main_t *vam = &vat_main;
3224   i32 retval = ntohl (mp->retval);
3225   if (retval == 0)
3226     {
3227       fformat (vam->ofp, "classify table info :\n");
3228       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3229                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3230                ntohl (mp->miss_next_index));
3231       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3232                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3233                ntohl (mp->match_n_vectors));
3234       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3235                ntohl (mp->mask_length));
3236     }
3237   vam->retval = retval;
3238   vam->result_ready = 1;
3239 }
3240
3241 static void
3242   vl_api_classify_table_info_reply_t_handler_json
3243   (vl_api_classify_table_info_reply_t * mp)
3244 {
3245   vat_main_t *vam = &vat_main;
3246   vat_json_node_t node;
3247
3248   i32 retval = ntohl (mp->retval);
3249   if (retval == 0)
3250     {
3251       vat_json_init_object (&node);
3252
3253       vat_json_object_add_int (&node, "sessions",
3254                                ntohl (mp->active_sessions));
3255       vat_json_object_add_int (&node, "nexttbl",
3256                                ntohl (mp->next_table_index));
3257       vat_json_object_add_int (&node, "nextnode",
3258                                ntohl (mp->miss_next_index));
3259       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3260       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3261       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3262       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3263                       ntohl (mp->mask_length), 0);
3264       vat_json_object_add_string_copy (&node, "mask", s);
3265
3266       vat_json_print (vam->ofp, &node);
3267       vat_json_free (&node);
3268     }
3269   vam->retval = ntohl (mp->retval);
3270   vam->result_ready = 1;
3271 }
3272
3273 static void
3274 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3275                                            mp)
3276 {
3277   vat_main_t *vam = &vat_main;
3278
3279   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3280            ntohl (mp->hit_next_index), ntohl (mp->advance),
3281            ntohl (mp->opaque_index));
3282   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3283            ntohl (mp->match_length));
3284 }
3285
3286 static void
3287   vl_api_classify_session_details_t_handler_json
3288   (vl_api_classify_session_details_t * mp)
3289 {
3290   vat_main_t *vam = &vat_main;
3291   vat_json_node_t *node = NULL;
3292
3293   if (VAT_JSON_ARRAY != vam->json_tree.type)
3294     {
3295       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3296       vat_json_init_array (&vam->json_tree);
3297     }
3298   node = vat_json_array_add (&vam->json_tree);
3299
3300   vat_json_init_object (node);
3301   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3302   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3303   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3304   u8 *s =
3305     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3306             0);
3307   vat_json_object_add_string_copy (node, "match", s);
3308 }
3309
3310 static void vl_api_pg_create_interface_reply_t_handler
3311   (vl_api_pg_create_interface_reply_t * mp)
3312 {
3313   vat_main_t *vam = &vat_main;
3314
3315   vam->retval = ntohl (mp->retval);
3316   vam->result_ready = 1;
3317 }
3318
3319 static void vl_api_pg_create_interface_reply_t_handler_json
3320   (vl_api_pg_create_interface_reply_t * mp)
3321 {
3322   vat_main_t *vam = &vat_main;
3323   vat_json_node_t node;
3324
3325   i32 retval = ntohl (mp->retval);
3326   if (retval == 0)
3327     {
3328       vat_json_init_object (&node);
3329
3330       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3331
3332       vat_json_print (vam->ofp, &node);
3333       vat_json_free (&node);
3334     }
3335   vam->retval = ntohl (mp->retval);
3336   vam->result_ready = 1;
3337 }
3338
3339 static void vl_api_policer_classify_details_t_handler
3340   (vl_api_policer_classify_details_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343
3344   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3345            ntohl (mp->table_index));
3346 }
3347
3348 static void vl_api_policer_classify_details_t_handler_json
3349   (vl_api_policer_classify_details_t * mp)
3350 {
3351   vat_main_t *vam = &vat_main;
3352   vat_json_node_t *node;
3353
3354   if (VAT_JSON_ARRAY != vam->json_tree.type)
3355     {
3356       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3357       vat_json_init_array (&vam->json_tree);
3358     }
3359   node = vat_json_array_add (&vam->json_tree);
3360
3361   vat_json_init_object (node);
3362   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3363   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3364 }
3365
3366 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3367   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3368 {
3369   vat_main_t *vam = &vat_main;
3370   i32 retval = ntohl (mp->retval);
3371   if (vam->async_mode)
3372     {
3373       vam->async_errors += (retval < 0);
3374     }
3375   else
3376     {
3377       vam->retval = retval;
3378       vam->sw_if_index = ntohl (mp->sw_if_index);
3379       vam->result_ready = 1;
3380     }
3381 }
3382
3383 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3384   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3385 {
3386   vat_main_t *vam = &vat_main;
3387   vat_json_node_t node;
3388
3389   vat_json_init_object (&node);
3390   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3391   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3392
3393   vat_json_print (vam->ofp, &node);
3394   vat_json_free (&node);
3395
3396   vam->retval = ntohl (mp->retval);
3397   vam->result_ready = 1;
3398 }
3399
3400 static void vl_api_flow_classify_details_t_handler
3401   (vl_api_flow_classify_details_t * mp)
3402 {
3403   vat_main_t *vam = &vat_main;
3404
3405   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3406            ntohl (mp->table_index));
3407 }
3408
3409 static void vl_api_flow_classify_details_t_handler_json
3410   (vl_api_flow_classify_details_t * mp)
3411 {
3412   vat_main_t *vam = &vat_main;
3413   vat_json_node_t *node;
3414
3415   if (VAT_JSON_ARRAY != vam->json_tree.type)
3416     {
3417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3418       vat_json_init_array (&vam->json_tree);
3419     }
3420   node = vat_json_array_add (&vam->json_tree);
3421
3422   vat_json_init_object (node);
3423   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3424   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3425 }
3426
3427
3428
3429 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3430 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3431 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3432 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3433 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3434 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3435
3436 /*
3437  * Generate boilerplate reply handlers, which
3438  * dig the return value out of the xxx_reply_t API message,
3439  * stick it into vam->retval, and set vam->result_ready
3440  *
3441  * Could also do this by pointing N message decode slots at
3442  * a single function, but that could break in subtle ways.
3443  */
3444
3445 #define foreach_standard_reply_retval_handler           \
3446 _(sw_interface_set_flags_reply)                         \
3447 _(sw_interface_add_del_address_reply)                   \
3448 _(sw_interface_set_table_reply)                         \
3449 _(sw_interface_set_mpls_enable_reply)                   \
3450 _(sw_interface_set_vpath_reply)                         \
3451 _(sw_interface_set_vxlan_bypass_reply)                  \
3452 _(sw_interface_set_l2_bridge_reply)                     \
3453 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3454 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3455 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3456 _(bridge_domain_add_del_reply)                          \
3457 _(sw_interface_set_l2_xconnect_reply)                   \
3458 _(l2fib_add_del_reply)                                  \
3459 _(ip_add_del_route_reply)                               \
3460 _(mpls_route_add_del_reply)                             \
3461 _(mpls_ip_bind_unbind_reply)                            \
3462 _(proxy_arp_add_del_reply)                              \
3463 _(proxy_arp_intfc_enable_disable_reply)                 \
3464 _(mpls_add_del_encap_reply)                             \
3465 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3466 _(sw_interface_set_unnumbered_reply)                    \
3467 _(ip_neighbor_add_del_reply)                            \
3468 _(reset_vrf_reply)                                      \
3469 _(oam_add_del_reply)                                    \
3470 _(reset_fib_reply)                                      \
3471 _(dhcp_proxy_config_reply)                              \
3472 _(dhcp_proxy_config_2_reply)                            \
3473 _(dhcp_proxy_set_vss_reply)                             \
3474 _(dhcp_client_config_reply)                             \
3475 _(set_ip_flow_hash_reply)                               \
3476 _(sw_interface_ip6_enable_disable_reply)                \
3477 _(sw_interface_ip6_set_link_local_address_reply)        \
3478 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3479 _(sw_interface_ip6nd_ra_config_reply)                   \
3480 _(set_arp_neighbor_limit_reply)                         \
3481 _(l2_patch_add_del_reply)                               \
3482 _(sr_tunnel_add_del_reply)                              \
3483 _(sr_policy_add_del_reply)                              \
3484 _(sr_multicast_map_add_del_reply)                       \
3485 _(classify_add_del_session_reply)                       \
3486 _(classify_set_interface_ip_table_reply)                \
3487 _(classify_set_interface_l2_tables_reply)               \
3488 _(l2tpv3_set_tunnel_cookies_reply)                      \
3489 _(l2tpv3_interface_enable_disable_reply)                \
3490 _(l2tpv3_set_lookup_key_reply)                          \
3491 _(l2_fib_clear_table_reply)                             \
3492 _(l2_interface_efp_filter_reply)                        \
3493 _(l2_interface_vlan_tag_rewrite_reply)                  \
3494 _(modify_vhost_user_if_reply)                           \
3495 _(delete_vhost_user_if_reply)                           \
3496 _(want_ip4_arp_events_reply)                            \
3497 _(want_ip6_nd_events_reply)                             \
3498 _(input_acl_set_interface_reply)                        \
3499 _(ipsec_spd_add_del_reply)                              \
3500 _(ipsec_interface_add_del_spd_reply)                    \
3501 _(ipsec_spd_add_del_entry_reply)                        \
3502 _(ipsec_sad_add_del_entry_reply)                        \
3503 _(ipsec_sa_set_key_reply)                               \
3504 _(ikev2_profile_add_del_reply)                          \
3505 _(ikev2_profile_set_auth_reply)                         \
3506 _(ikev2_profile_set_id_reply)                           \
3507 _(ikev2_profile_set_ts_reply)                           \
3508 _(ikev2_set_local_key_reply)                            \
3509 _(delete_loopback_reply)                                \
3510 _(bd_ip_mac_add_del_reply)                              \
3511 _(map_del_domain_reply)                                 \
3512 _(map_add_del_rule_reply)                               \
3513 _(want_interface_events_reply)                          \
3514 _(want_stats_reply)                                     \
3515 _(cop_interface_enable_disable_reply)                   \
3516 _(cop_whitelist_enable_disable_reply)                   \
3517 _(sw_interface_clear_stats_reply)                       \
3518 _(ioam_enable_reply)                              \
3519 _(ioam_disable_reply)                              \
3520 _(lisp_add_del_locator_reply)                           \
3521 _(lisp_add_del_local_eid_reply)                         \
3522 _(lisp_add_del_remote_mapping_reply)                    \
3523 _(lisp_add_del_adjacency_reply)                         \
3524 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3525 _(lisp_add_del_map_resolver_reply)                      \
3526 _(lisp_gpe_enable_disable_reply)                        \
3527 _(lisp_gpe_add_del_iface_reply)                         \
3528 _(lisp_enable_disable_reply)                            \
3529 _(lisp_pitr_set_locator_set_reply)                      \
3530 _(lisp_map_request_mode_reply)                          \
3531 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3532 _(lisp_eid_table_add_del_map_reply)                     \
3533 _(vxlan_gpe_add_del_tunnel_reply)                       \
3534 _(af_packet_delete_reply)                               \
3535 _(policer_classify_set_interface_reply)                 \
3536 _(netmap_create_reply)                                  \
3537 _(netmap_delete_reply)                                  \
3538 _(set_ipfix_exporter_reply)                             \
3539 _(set_ipfix_classify_stream_reply)                      \
3540 _(ipfix_classify_table_add_del_reply)                   \
3541 _(flow_classify_set_interface_reply)                    \
3542 _(sw_interface_span_enable_disable_reply)               \
3543 _(pg_capture_reply)                                     \
3544 _(pg_enable_disable_reply)                              \
3545 _(ip_source_and_port_range_check_add_del_reply)         \
3546 _(ip_source_and_port_range_check_interface_add_del_reply)\
3547 _(delete_subif_reply)                                   \
3548 _(l2_interface_pbb_tag_rewrite_reply)                   \
3549 _(punt_reply)                                           \
3550 _(feature_enable_disable_reply)
3551
3552 #define _(n)                                    \
3553     static void vl_api_##n##_t_handler          \
3554     (vl_api_##n##_t * mp)                       \
3555     {                                           \
3556         vat_main_t * vam = &vat_main;           \
3557         i32 retval = ntohl(mp->retval);         \
3558         if (vam->async_mode) {                  \
3559             vam->async_errors += (retval < 0);  \
3560         } else {                                \
3561             vam->retval = retval;               \
3562             vam->result_ready = 1;              \
3563         }                                       \
3564     }
3565 foreach_standard_reply_retval_handler;
3566 #undef _
3567
3568 #define _(n)                                    \
3569     static void vl_api_##n##_t_handler_json     \
3570     (vl_api_##n##_t * mp)                       \
3571     {                                           \
3572         vat_main_t * vam = &vat_main;           \
3573         vat_json_node_t node;                   \
3574         vat_json_init_object(&node);            \
3575         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3576         vat_json_print(vam->ofp, &node);        \
3577         vam->retval = ntohl(mp->retval);        \
3578         vam->result_ready = 1;                  \
3579     }
3580 foreach_standard_reply_retval_handler;
3581 #undef _
3582
3583 /*
3584  * Table of message reply handlers, must include boilerplate handlers
3585  * we just generated
3586  */
3587
3588 #define foreach_vpe_api_reply_msg                                       \
3589 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3590 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3591 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3592 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3593 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3594 _(CLI_REPLY, cli_reply)                                                 \
3595 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3596 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3597   sw_interface_add_del_address_reply)                                   \
3598 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3599 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3600 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3601 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3602 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3603   sw_interface_set_l2_xconnect_reply)                                   \
3604 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3605   sw_interface_set_l2_bridge_reply)                                     \
3606 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3607   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3608 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3609   sw_interface_set_dpdk_hqos_subport_reply)                             \
3610 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3611   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3612 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3613 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3614 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3615 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3616 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3617 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3618 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3619 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3620 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3621 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3622 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3623 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3624 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3625 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3626 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3627   proxy_arp_intfc_enable_disable_reply)                                 \
3628 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3629 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3630   mpls_ethernet_add_del_tunnel_reply)                                   \
3631 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3632   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3633 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3634   sw_interface_set_unnumbered_reply)                                    \
3635 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3636 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3637 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3638 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3639 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3640 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3641 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3642 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3643 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3644 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3645 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3646 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3647   sw_interface_ip6_enable_disable_reply)                                \
3648 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3649   sw_interface_ip6_set_link_local_address_reply)                        \
3650 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3651   sw_interface_ip6nd_ra_prefix_reply)                                   \
3652 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3653   sw_interface_ip6nd_ra_config_reply)                                   \
3654 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3655 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3656 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3657 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3658 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3659 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3660 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3661 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3662 classify_set_interface_ip_table_reply)                                  \
3663 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3664   classify_set_interface_l2_tables_reply)                               \
3665 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3666 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3667 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3668 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3669 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3670   l2tpv3_interface_enable_disable_reply)                                \
3671 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3672 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3673 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3674 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3675 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3676 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3677 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3678 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3679 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3680 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3681 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3682 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3683 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3684 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3685 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3686 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3687 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3688 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3689 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3690 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3691 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3692 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3693 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3694 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3695 _(IP_DETAILS, ip_details)                                               \
3696 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3697 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3698 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3699 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3700 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3701 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3702 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3703 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3704 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3705 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3706 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3707 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3708 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3709 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3710 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3711 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3712 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3713 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3714 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3715 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3716 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3717 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3718 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3719 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3720 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3721 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3722 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3723 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3724 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3725 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3726 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3727 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3728 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3729 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3730 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3731 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3732 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3733 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3734 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3735 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3736 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3737 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3738 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3739 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3740 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3741 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3742 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3743 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3744 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3745 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3746 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3747 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3748 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3749   lisp_add_del_map_request_itr_rlocs_reply)                             \
3750 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3751   lisp_get_map_request_itr_rlocs_reply)                                 \
3752 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3753 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3754 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3755 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3756 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3757 _(POLICER_DETAILS, policer_details)                                     \
3758 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3759 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3760 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3761 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3762 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3763 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3764 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3765 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3766 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3767 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3768 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3769 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3770 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3771 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3772 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3773 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3774 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3775 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3776 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3777 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3778 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3779 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3780 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3781 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3782 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3783 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3784  ip_source_and_port_range_check_add_del_reply)                          \
3785 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3786  ip_source_and_port_range_check_interface_add_del_reply)                \
3787 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3788 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3789 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3790 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3791 _(PUNT_REPLY, punt_reply)                                               \
3792 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3793 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3794 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)
3795
3796 /* M: construct, but don't yet send a message */
3797
3798 #define M(T,t)                                  \
3799 do {                                            \
3800     vam->result_ready = 0;                      \
3801     mp = vl_msg_api_alloc(sizeof(*mp));         \
3802     memset (mp, 0, sizeof (*mp));               \
3803     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3804     mp->client_index = vam->my_client_index;    \
3805 } while(0);
3806
3807 #define M2(T,t,n)                               \
3808 do {                                            \
3809     vam->result_ready = 0;                      \
3810     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3811     memset (mp, 0, sizeof (*mp));               \
3812     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3813     mp->client_index = vam->my_client_index;    \
3814 } while(0);
3815
3816
3817 /* S: send a message */
3818 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3819
3820 /* W: wait for results, with timeout */
3821 #define W                                       \
3822 do {                                            \
3823     timeout = vat_time_now (vam) + 1.0;         \
3824                                                 \
3825     while (vat_time_now (vam) < timeout) {      \
3826         if (vam->result_ready == 1) {           \
3827             return (vam->retval);               \
3828         }                                       \
3829     }                                           \
3830     return -99;                                 \
3831 } while(0);
3832
3833 /* W2: wait for results, with timeout */
3834 #define W2(body)                                \
3835 do {                                            \
3836     timeout = vat_time_now (vam) + 1.0;         \
3837                                                 \
3838     while (vat_time_now (vam) < timeout) {      \
3839         if (vam->result_ready == 1) {           \
3840           (body);                               \
3841           return (vam->retval);                 \
3842         }                                       \
3843     }                                           \
3844     return -99;                                 \
3845 } while(0);
3846
3847 typedef struct
3848 {
3849   u8 *name;
3850   u32 value;
3851 } name_sort_t;
3852
3853
3854 #define STR_VTR_OP_CASE(op)     \
3855     case L2_VTR_ ## op:         \
3856         return "" # op;
3857
3858 static const char *
3859 str_vtr_op (u32 vtr_op)
3860 {
3861   switch (vtr_op)
3862     {
3863       STR_VTR_OP_CASE (DISABLED);
3864       STR_VTR_OP_CASE (PUSH_1);
3865       STR_VTR_OP_CASE (PUSH_2);
3866       STR_VTR_OP_CASE (POP_1);
3867       STR_VTR_OP_CASE (POP_2);
3868       STR_VTR_OP_CASE (TRANSLATE_1_1);
3869       STR_VTR_OP_CASE (TRANSLATE_1_2);
3870       STR_VTR_OP_CASE (TRANSLATE_2_1);
3871       STR_VTR_OP_CASE (TRANSLATE_2_2);
3872     }
3873
3874   return "UNKNOWN";
3875 }
3876
3877 static int
3878 dump_sub_interface_table (vat_main_t * vam)
3879 {
3880   const sw_interface_subif_t *sub = NULL;
3881
3882   if (vam->json_output)
3883     {
3884       clib_warning
3885         ("JSON output supported only for VPE API calls and dump_stats_table");
3886       return -99;
3887     }
3888
3889   fformat (vam->ofp,
3890            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3891            "Interface", "sw_if_index",
3892            "sub id", "dot1ad", "tags", "outer id",
3893            "inner id", "exact", "default", "outer any", "inner any");
3894
3895   vec_foreach (sub, vam->sw_if_subif_table)
3896   {
3897     fformat (vam->ofp,
3898              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3899              sub->interface_name,
3900              sub->sw_if_index,
3901              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3902              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3903              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3904              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3905     if (sub->vtr_op != L2_VTR_DISABLED)
3906       {
3907         fformat (vam->ofp,
3908                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3909                  "tag1: %d tag2: %d ]\n",
3910                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3911                  sub->vtr_tag1, sub->vtr_tag2);
3912       }
3913   }
3914
3915   return 0;
3916 }
3917
3918 static int
3919 name_sort_cmp (void *a1, void *a2)
3920 {
3921   name_sort_t *n1 = a1;
3922   name_sort_t *n2 = a2;
3923
3924   return strcmp ((char *) n1->name, (char *) n2->name);
3925 }
3926
3927 static int
3928 dump_interface_table (vat_main_t * vam)
3929 {
3930   hash_pair_t *p;
3931   name_sort_t *nses = 0, *ns;
3932
3933   if (vam->json_output)
3934     {
3935       clib_warning
3936         ("JSON output supported only for VPE API calls and dump_stats_table");
3937       return -99;
3938     }
3939
3940   /* *INDENT-OFF* */
3941   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3942   ({
3943     vec_add2 (nses, ns, 1);
3944     ns->name = (u8 *)(p->key);
3945     ns->value = (u32) p->value[0];
3946   }));
3947   /* *INDENT-ON* */
3948
3949   vec_sort_with_function (nses, name_sort_cmp);
3950
3951   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3952   vec_foreach (ns, nses)
3953   {
3954     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3955   }
3956   vec_free (nses);
3957   return 0;
3958 }
3959
3960 static int
3961 dump_ip_table (vat_main_t * vam, int is_ipv6)
3962 {
3963   const ip_details_t *det = NULL;
3964   const ip_address_details_t *address = NULL;
3965   u32 i = ~0;
3966
3967   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3968
3969   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3970   {
3971     i++;
3972     if (!det->present)
3973       {
3974         continue;
3975       }
3976     fformat (vam->ofp, "%-12d\n", i);
3977     fformat (vam->ofp,
3978              "            %-30s%-13s\n", "Address", "Prefix length");
3979     if (!det->addr)
3980       {
3981         continue;
3982       }
3983     vec_foreach (address, det->addr)
3984     {
3985       fformat (vam->ofp,
3986                "            %-30U%-13d\n",
3987                is_ipv6 ? format_ip6_address : format_ip4_address,
3988                address->ip, address->prefix_length);
3989     }
3990   }
3991
3992   return 0;
3993 }
3994
3995 static int
3996 dump_ipv4_table (vat_main_t * vam)
3997 {
3998   if (vam->json_output)
3999     {
4000       clib_warning
4001         ("JSON output supported only for VPE API calls and dump_stats_table");
4002       return -99;
4003     }
4004
4005   return dump_ip_table (vam, 0);
4006 }
4007
4008 static int
4009 dump_ipv6_table (vat_main_t * vam)
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   return dump_ip_table (vam, 1);
4019 }
4020
4021 static char *
4022 counter_type_to_str (u8 counter_type, u8 is_combined)
4023 {
4024   if (!is_combined)
4025     {
4026       switch (counter_type)
4027         {
4028         case VNET_INTERFACE_COUNTER_DROP:
4029           return "drop";
4030         case VNET_INTERFACE_COUNTER_PUNT:
4031           return "punt";
4032         case VNET_INTERFACE_COUNTER_IP4:
4033           return "ip4";
4034         case VNET_INTERFACE_COUNTER_IP6:
4035           return "ip6";
4036         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4037           return "rx-no-buf";
4038         case VNET_INTERFACE_COUNTER_RX_MISS:
4039           return "rx-miss";
4040         case VNET_INTERFACE_COUNTER_RX_ERROR:
4041           return "rx-error";
4042         case VNET_INTERFACE_COUNTER_TX_ERROR:
4043           return "tx-error";
4044         default:
4045           return "INVALID-COUNTER-TYPE";
4046         }
4047     }
4048   else
4049     {
4050       switch (counter_type)
4051         {
4052         case VNET_INTERFACE_COUNTER_RX:
4053           return "rx";
4054         case VNET_INTERFACE_COUNTER_TX:
4055           return "tx";
4056         default:
4057           return "INVALID-COUNTER-TYPE";
4058         }
4059     }
4060 }
4061
4062 static int
4063 dump_stats_table (vat_main_t * vam)
4064 {
4065   vat_json_node_t node;
4066   vat_json_node_t *msg_array;
4067   vat_json_node_t *msg;
4068   vat_json_node_t *counter_array;
4069   vat_json_node_t *counter;
4070   interface_counter_t c;
4071   u64 packets;
4072   ip4_fib_counter_t *c4;
4073   ip6_fib_counter_t *c6;
4074   int i, j;
4075
4076   if (!vam->json_output)
4077     {
4078       clib_warning ("dump_stats_table supported only in JSON format");
4079       return -99;
4080     }
4081
4082   vat_json_init_object (&node);
4083
4084   /* interface counters */
4085   msg_array = vat_json_object_add (&node, "interface_counters");
4086   vat_json_init_array (msg_array);
4087   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4088     {
4089       msg = vat_json_array_add (msg_array);
4090       vat_json_init_object (msg);
4091       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4092                                        (u8 *) counter_type_to_str (i, 0));
4093       vat_json_object_add_int (msg, "is_combined", 0);
4094       counter_array = vat_json_object_add (msg, "data");
4095       vat_json_init_array (counter_array);
4096       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4097         {
4098           packets = vam->simple_interface_counters[i][j];
4099           vat_json_array_add_uint (counter_array, packets);
4100         }
4101     }
4102   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4103     {
4104       msg = vat_json_array_add (msg_array);
4105       vat_json_init_object (msg);
4106       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4107                                        (u8 *) counter_type_to_str (i, 1));
4108       vat_json_object_add_int (msg, "is_combined", 1);
4109       counter_array = vat_json_object_add (msg, "data");
4110       vat_json_init_array (counter_array);
4111       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4112         {
4113           c = vam->combined_interface_counters[i][j];
4114           counter = vat_json_array_add (counter_array);
4115           vat_json_init_object (counter);
4116           vat_json_object_add_uint (counter, "packets", c.packets);
4117           vat_json_object_add_uint (counter, "bytes", c.bytes);
4118         }
4119     }
4120
4121   /* ip4 fib counters */
4122   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4123   vat_json_init_array (msg_array);
4124   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4125     {
4126       msg = vat_json_array_add (msg_array);
4127       vat_json_init_object (msg);
4128       vat_json_object_add_uint (msg, "vrf_id",
4129                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4130       counter_array = vat_json_object_add (msg, "c");
4131       vat_json_init_array (counter_array);
4132       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4133         {
4134           counter = vat_json_array_add (counter_array);
4135           vat_json_init_object (counter);
4136           c4 = &vam->ip4_fib_counters[i][j];
4137           vat_json_object_add_ip4 (counter, "address", c4->address);
4138           vat_json_object_add_uint (counter, "address_length",
4139                                     c4->address_length);
4140           vat_json_object_add_uint (counter, "packets", c4->packets);
4141           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4142         }
4143     }
4144
4145   /* ip6 fib counters */
4146   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4147   vat_json_init_array (msg_array);
4148   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4149     {
4150       msg = vat_json_array_add (msg_array);
4151       vat_json_init_object (msg);
4152       vat_json_object_add_uint (msg, "vrf_id",
4153                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4154       counter_array = vat_json_object_add (msg, "c");
4155       vat_json_init_array (counter_array);
4156       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4157         {
4158           counter = vat_json_array_add (counter_array);
4159           vat_json_init_object (counter);
4160           c6 = &vam->ip6_fib_counters[i][j];
4161           vat_json_object_add_ip6 (counter, "address", c6->address);
4162           vat_json_object_add_uint (counter, "address_length",
4163                                     c6->address_length);
4164           vat_json_object_add_uint (counter, "packets", c6->packets);
4165           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4166         }
4167     }
4168
4169   vat_json_print (vam->ofp, &node);
4170   vat_json_free (&node);
4171
4172   return 0;
4173 }
4174
4175 int
4176 exec (vat_main_t * vam)
4177 {
4178   api_main_t *am = &api_main;
4179   vl_api_cli_request_t *mp;
4180   f64 timeout;
4181   void *oldheap;
4182   u8 *cmd = 0;
4183   unformat_input_t *i = vam->input;
4184
4185   if (vec_len (i->buffer) == 0)
4186     return -1;
4187
4188   if (vam->exec_mode == 0 && unformat (i, "mode"))
4189     {
4190       vam->exec_mode = 1;
4191       return 0;
4192     }
4193   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4194     {
4195       vam->exec_mode = 0;
4196       return 0;
4197     }
4198
4199
4200   M (CLI_REQUEST, cli_request);
4201
4202   /*
4203    * Copy cmd into shared memory.
4204    * In order for the CLI command to work, it
4205    * must be a vector ending in \n, not a C-string ending
4206    * in \n\0.
4207    */
4208   pthread_mutex_lock (&am->vlib_rp->mutex);
4209   oldheap = svm_push_data_heap (am->vlib_rp);
4210
4211   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4212   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4213
4214   svm_pop_heap (oldheap);
4215   pthread_mutex_unlock (&am->vlib_rp->mutex);
4216
4217   mp->cmd_in_shmem = (u64) cmd;
4218   S;
4219   timeout = vat_time_now (vam) + 10.0;
4220
4221   while (vat_time_now (vam) < timeout)
4222     {
4223       if (vam->result_ready == 1)
4224         {
4225           u8 *free_me;
4226           if (vam->shmem_result != NULL)
4227             fformat (vam->ofp, "%s", vam->shmem_result);
4228           pthread_mutex_lock (&am->vlib_rp->mutex);
4229           oldheap = svm_push_data_heap (am->vlib_rp);
4230
4231           free_me = (u8 *) vam->shmem_result;
4232           vec_free (free_me);
4233
4234           svm_pop_heap (oldheap);
4235           pthread_mutex_unlock (&am->vlib_rp->mutex);
4236           return 0;
4237         }
4238     }
4239   return -99;
4240 }
4241
4242 /*
4243  * Future replacement of exec() that passes CLI buffers directly in
4244  * the API messages instead of an additional shared memory area.
4245  */
4246 static int
4247 exec_inband (vat_main_t * vam)
4248 {
4249   vl_api_cli_inband_t *mp;
4250   f64 timeout;
4251   unformat_input_t *i = vam->input;
4252
4253   if (vec_len (i->buffer) == 0)
4254     return -1;
4255
4256   if (vam->exec_mode == 0 && unformat (i, "mode"))
4257     {
4258       vam->exec_mode = 1;
4259       return 0;
4260     }
4261   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4262     {
4263       vam->exec_mode = 0;
4264       return 0;
4265     }
4266
4267   /*
4268    * In order for the CLI command to work, it
4269    * must be a vector ending in \n, not a C-string ending
4270    * in \n\0.
4271    */
4272   u32 len = vec_len (vam->input->buffer);
4273   M2 (CLI_INBAND, cli_inband, len);
4274   clib_memcpy (mp->cmd, vam->input->buffer, len);
4275   mp->length = htonl (len);
4276
4277   S;
4278   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4279 }
4280
4281 static int
4282 api_create_loopback (vat_main_t * vam)
4283 {
4284   unformat_input_t *i = vam->input;
4285   vl_api_create_loopback_t *mp;
4286   f64 timeout;
4287   u8 mac_address[6];
4288   u8 mac_set = 0;
4289
4290   memset (mac_address, 0, sizeof (mac_address));
4291
4292   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4293     {
4294       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4295         mac_set = 1;
4296       else
4297         break;
4298     }
4299
4300   /* Construct the API message */
4301   M (CREATE_LOOPBACK, create_loopback);
4302   if (mac_set)
4303     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4304
4305   S;
4306   W;
4307 }
4308
4309 static int
4310 api_delete_loopback (vat_main_t * vam)
4311 {
4312   unformat_input_t *i = vam->input;
4313   vl_api_delete_loopback_t *mp;
4314   f64 timeout;
4315   u32 sw_if_index = ~0;
4316
4317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4318     {
4319       if (unformat (i, "sw_if_index %d", &sw_if_index))
4320         ;
4321       else
4322         break;
4323     }
4324
4325   if (sw_if_index == ~0)
4326     {
4327       errmsg ("missing sw_if_index\n");
4328       return -99;
4329     }
4330
4331   /* Construct the API message */
4332   M (DELETE_LOOPBACK, delete_loopback);
4333   mp->sw_if_index = ntohl (sw_if_index);
4334
4335   S;
4336   W;
4337 }
4338
4339 static int
4340 api_want_stats (vat_main_t * vam)
4341 {
4342   unformat_input_t *i = vam->input;
4343   vl_api_want_stats_t *mp;
4344   f64 timeout;
4345   int enable = -1;
4346
4347   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4348     {
4349       if (unformat (i, "enable"))
4350         enable = 1;
4351       else if (unformat (i, "disable"))
4352         enable = 0;
4353       else
4354         break;
4355     }
4356
4357   if (enable == -1)
4358     {
4359       errmsg ("missing enable|disable\n");
4360       return -99;
4361     }
4362
4363   M (WANT_STATS, want_stats);
4364   mp->enable_disable = enable;
4365
4366   S;
4367   W;
4368 }
4369
4370 static int
4371 api_want_interface_events (vat_main_t * vam)
4372 {
4373   unformat_input_t *i = vam->input;
4374   vl_api_want_interface_events_t *mp;
4375   f64 timeout;
4376   int enable = -1;
4377
4378   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4379     {
4380       if (unformat (i, "enable"))
4381         enable = 1;
4382       else if (unformat (i, "disable"))
4383         enable = 0;
4384       else
4385         break;
4386     }
4387
4388   if (enable == -1)
4389     {
4390       errmsg ("missing enable|disable\n");
4391       return -99;
4392     }
4393
4394   M (WANT_INTERFACE_EVENTS, want_interface_events);
4395   mp->enable_disable = enable;
4396
4397   vam->interface_event_display = enable;
4398
4399   S;
4400   W;
4401 }
4402
4403
4404 /* Note: non-static, called once to set up the initial intfc table */
4405 int
4406 api_sw_interface_dump (vat_main_t * vam)
4407 {
4408   vl_api_sw_interface_dump_t *mp;
4409   f64 timeout;
4410   hash_pair_t *p;
4411   name_sort_t *nses = 0, *ns;
4412   sw_interface_subif_t *sub = NULL;
4413
4414   /* Toss the old name table */
4415   /* *INDENT-OFF* */
4416   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4417   ({
4418     vec_add2 (nses, ns, 1);
4419     ns->name = (u8 *)(p->key);
4420     ns->value = (u32) p->value[0];
4421   }));
4422   /* *INDENT-ON* */
4423
4424   hash_free (vam->sw_if_index_by_interface_name);
4425
4426   vec_foreach (ns, nses) vec_free (ns->name);
4427
4428   vec_free (nses);
4429
4430   vec_foreach (sub, vam->sw_if_subif_table)
4431   {
4432     vec_free (sub->interface_name);
4433   }
4434   vec_free (vam->sw_if_subif_table);
4435
4436   /* recreate the interface name hash table */
4437   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4438
4439   /* Get list of ethernets */
4440   M (SW_INTERFACE_DUMP, sw_interface_dump);
4441   mp->name_filter_valid = 1;
4442   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4443   S;
4444
4445   /* and local / loopback interfaces */
4446   M (SW_INTERFACE_DUMP, sw_interface_dump);
4447   mp->name_filter_valid = 1;
4448   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4449   S;
4450
4451   /* and packet-generator interfaces */
4452   M (SW_INTERFACE_DUMP, sw_interface_dump);
4453   mp->name_filter_valid = 1;
4454   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4455   S;
4456
4457   /* and vxlan-gpe tunnel interfaces */
4458   M (SW_INTERFACE_DUMP, sw_interface_dump);
4459   mp->name_filter_valid = 1;
4460   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4461            sizeof (mp->name_filter) - 1);
4462   S;
4463
4464   /* and vxlan tunnel interfaces */
4465   M (SW_INTERFACE_DUMP, sw_interface_dump);
4466   mp->name_filter_valid = 1;
4467   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4468   S;
4469
4470   /* and host (af_packet) interfaces */
4471   M (SW_INTERFACE_DUMP, sw_interface_dump);
4472   mp->name_filter_valid = 1;
4473   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4474   S;
4475
4476   /* and l2tpv3 tunnel interfaces */
4477   M (SW_INTERFACE_DUMP, sw_interface_dump);
4478   mp->name_filter_valid = 1;
4479   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4480            sizeof (mp->name_filter) - 1);
4481   S;
4482
4483   /* and GRE tunnel interfaces */
4484   M (SW_INTERFACE_DUMP, sw_interface_dump);
4485   mp->name_filter_valid = 1;
4486   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4487   S;
4488
4489   /* and LISP-GPE interfaces */
4490   M (SW_INTERFACE_DUMP, sw_interface_dump);
4491   mp->name_filter_valid = 1;
4492   strncpy ((char *) mp->name_filter, "lisp_gpe",
4493            sizeof (mp->name_filter) - 1);
4494   S;
4495
4496   /* and IPSEC tunnel interfaces */
4497   M (SW_INTERFACE_DUMP, sw_interface_dump);
4498   mp->name_filter_valid = 1;
4499   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4500   S;
4501
4502   /* Use a control ping for synchronization */
4503   {
4504     vl_api_control_ping_t *mp;
4505     M (CONTROL_PING, control_ping);
4506     S;
4507   }
4508   W;
4509 }
4510
4511 static int
4512 api_sw_interface_set_flags (vat_main_t * vam)
4513 {
4514   unformat_input_t *i = vam->input;
4515   vl_api_sw_interface_set_flags_t *mp;
4516   f64 timeout;
4517   u32 sw_if_index;
4518   u8 sw_if_index_set = 0;
4519   u8 admin_up = 0, link_up = 0;
4520
4521   /* Parse args required to build the message */
4522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4523     {
4524       if (unformat (i, "admin-up"))
4525         admin_up = 1;
4526       else if (unformat (i, "admin-down"))
4527         admin_up = 0;
4528       else if (unformat (i, "link-up"))
4529         link_up = 1;
4530       else if (unformat (i, "link-down"))
4531         link_up = 0;
4532       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4533         sw_if_index_set = 1;
4534       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4535         sw_if_index_set = 1;
4536       else
4537         break;
4538     }
4539
4540   if (sw_if_index_set == 0)
4541     {
4542       errmsg ("missing interface name or sw_if_index\n");
4543       return -99;
4544     }
4545
4546   /* Construct the API message */
4547   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4548   mp->sw_if_index = ntohl (sw_if_index);
4549   mp->admin_up_down = admin_up;
4550   mp->link_up_down = link_up;
4551
4552   /* send it... */
4553   S;
4554
4555   /* Wait for a reply, return the good/bad news... */
4556   W;
4557 }
4558
4559 static int
4560 api_sw_interface_clear_stats (vat_main_t * vam)
4561 {
4562   unformat_input_t *i = vam->input;
4563   vl_api_sw_interface_clear_stats_t *mp;
4564   f64 timeout;
4565   u32 sw_if_index;
4566   u8 sw_if_index_set = 0;
4567
4568   /* Parse args required to build the message */
4569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4570     {
4571       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4572         sw_if_index_set = 1;
4573       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4574         sw_if_index_set = 1;
4575       else
4576         break;
4577     }
4578
4579   /* Construct the API message */
4580   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4581
4582   if (sw_if_index_set == 1)
4583     mp->sw_if_index = ntohl (sw_if_index);
4584   else
4585     mp->sw_if_index = ~0;
4586
4587   /* send it... */
4588   S;
4589
4590   /* Wait for a reply, return the good/bad news... */
4591   W;
4592 }
4593
4594 static int
4595 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4596 {
4597   unformat_input_t *i = vam->input;
4598   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4599   f64 timeout;
4600   u32 sw_if_index;
4601   u8 sw_if_index_set = 0;
4602   u32 subport;
4603   u8 subport_set = 0;
4604   u32 pipe;
4605   u8 pipe_set = 0;
4606   u32 profile;
4607   u8 profile_set = 0;
4608
4609   /* Parse args required to build the message */
4610   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4611     {
4612       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4613         sw_if_index_set = 1;
4614       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4615         sw_if_index_set = 1;
4616       else if (unformat (i, "subport %u", &subport))
4617         subport_set = 1;
4618       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4619         sw_if_index_set = 1;
4620       else if (unformat (i, "pipe %u", &pipe))
4621         pipe_set = 1;
4622       else if (unformat (i, "profile %u", &profile))
4623         profile_set = 1;
4624       else
4625         break;
4626     }
4627
4628   if (sw_if_index_set == 0)
4629     {
4630       errmsg ("missing interface name or sw_if_index\n");
4631       return -99;
4632     }
4633
4634   if (subport_set == 0)
4635     {
4636       errmsg ("missing subport \n");
4637       return -99;
4638     }
4639
4640   if (pipe_set == 0)
4641     {
4642       errmsg ("missing pipe\n");
4643       return -99;
4644     }
4645
4646   if (profile_set == 0)
4647     {
4648       errmsg ("missing profile\n");
4649       return -99;
4650     }
4651
4652   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4653
4654   mp->sw_if_index = ntohl (sw_if_index);
4655   mp->subport = ntohl (subport);
4656   mp->pipe = ntohl (pipe);
4657   mp->profile = ntohl (profile);
4658
4659
4660   S;
4661   W;
4662   /* NOTREACHED */
4663   return 0;
4664 }
4665
4666 static int
4667 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4668 {
4669   unformat_input_t *i = vam->input;
4670   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4671   f64 timeout;
4672   u32 sw_if_index;
4673   u8 sw_if_index_set = 0;
4674   u32 subport;
4675   u8 subport_set = 0;
4676   u32 tb_rate = 1250000000;     /* 10GbE */
4677   u32 tb_size = 1000000;
4678   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4679   u32 tc_period = 10;
4680
4681   /* Parse args required to build the message */
4682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4683     {
4684       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4685         sw_if_index_set = 1;
4686       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4687         sw_if_index_set = 1;
4688       else if (unformat (i, "subport %u", &subport))
4689         subport_set = 1;
4690       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4691         sw_if_index_set = 1;
4692       else if (unformat (i, "rate %u", &tb_rate))
4693         {
4694           u32 tc_id;
4695
4696           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4697                tc_id++)
4698             tc_rate[tc_id] = tb_rate;
4699         }
4700       else if (unformat (i, "bktsize %u", &tb_size))
4701         ;
4702       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4703         ;
4704       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4705         ;
4706       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4707         ;
4708       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4709         ;
4710       else if (unformat (i, "period %u", &tc_period))
4711         ;
4712       else
4713         break;
4714     }
4715
4716   if (sw_if_index_set == 0)
4717     {
4718       errmsg ("missing interface name or sw_if_index\n");
4719       return -99;
4720     }
4721
4722   if (subport_set == 0)
4723     {
4724       errmsg ("missing subport \n");
4725       return -99;
4726     }
4727
4728   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4729
4730   mp->sw_if_index = ntohl (sw_if_index);
4731   mp->subport = ntohl (subport);
4732   mp->tb_rate = ntohl (tb_rate);
4733   mp->tb_size = ntohl (tb_size);
4734   mp->tc_rate[0] = ntohl (tc_rate[0]);
4735   mp->tc_rate[1] = ntohl (tc_rate[1]);
4736   mp->tc_rate[2] = ntohl (tc_rate[2]);
4737   mp->tc_rate[3] = ntohl (tc_rate[3]);
4738   mp->tc_period = ntohl (tc_period);
4739
4740   S;
4741   W;
4742   /* NOTREACHED */
4743   return 0;
4744 }
4745
4746 static int
4747 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4748 {
4749   unformat_input_t *i = vam->input;
4750   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4751   f64 timeout;
4752   u32 sw_if_index;
4753   u8 sw_if_index_set = 0;
4754   u8 entry_set = 0;
4755   u8 tc_set = 0;
4756   u8 queue_set = 0;
4757   u32 entry, tc, queue;
4758
4759   /* Parse args required to build the message */
4760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4761     {
4762       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4763         sw_if_index_set = 1;
4764       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4765         sw_if_index_set = 1;
4766       else if (unformat (i, "entry %d", &entry))
4767         entry_set = 1;
4768       else if (unformat (i, "tc %d", &tc))
4769         tc_set = 1;
4770       else if (unformat (i, "queue %d", &queue))
4771         queue_set = 1;
4772       else
4773         break;
4774     }
4775
4776   if (sw_if_index_set == 0)
4777     {
4778       errmsg ("missing interface name or sw_if_index\n");
4779       return -99;
4780     }
4781
4782   if (entry_set == 0)
4783     {
4784       errmsg ("missing entry \n");
4785       return -99;
4786     }
4787
4788   if (tc_set == 0)
4789     {
4790       errmsg ("missing traffic class \n");
4791       return -99;
4792     }
4793
4794   if (queue_set == 0)
4795     {
4796       errmsg ("missing queue \n");
4797       return -99;
4798     }
4799
4800   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4801
4802   mp->sw_if_index = ntohl (sw_if_index);
4803   mp->entry = ntohl (entry);
4804   mp->tc = ntohl (tc);
4805   mp->queue = ntohl (queue);
4806
4807   S;
4808   W;
4809   /* NOTREACHED */
4810   return 0;
4811 }
4812
4813 static int
4814 api_sw_interface_add_del_address (vat_main_t * vam)
4815 {
4816   unformat_input_t *i = vam->input;
4817   vl_api_sw_interface_add_del_address_t *mp;
4818   f64 timeout;
4819   u32 sw_if_index;
4820   u8 sw_if_index_set = 0;
4821   u8 is_add = 1, del_all = 0;
4822   u32 address_length = 0;
4823   u8 v4_address_set = 0;
4824   u8 v6_address_set = 0;
4825   ip4_address_t v4address;
4826   ip6_address_t v6address;
4827
4828   /* Parse args required to build the message */
4829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4830     {
4831       if (unformat (i, "del-all"))
4832         del_all = 1;
4833       else if (unformat (i, "del"))
4834         is_add = 0;
4835       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4836         sw_if_index_set = 1;
4837       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4838         sw_if_index_set = 1;
4839       else if (unformat (i, "%U/%d",
4840                          unformat_ip4_address, &v4address, &address_length))
4841         v4_address_set = 1;
4842       else if (unformat (i, "%U/%d",
4843                          unformat_ip6_address, &v6address, &address_length))
4844         v6_address_set = 1;
4845       else
4846         break;
4847     }
4848
4849   if (sw_if_index_set == 0)
4850     {
4851       errmsg ("missing interface name or sw_if_index\n");
4852       return -99;
4853     }
4854   if (v4_address_set && v6_address_set)
4855     {
4856       errmsg ("both v4 and v6 addresses set\n");
4857       return -99;
4858     }
4859   if (!v4_address_set && !v6_address_set && !del_all)
4860     {
4861       errmsg ("no addresses set\n");
4862       return -99;
4863     }
4864
4865   /* Construct the API message */
4866   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4867
4868   mp->sw_if_index = ntohl (sw_if_index);
4869   mp->is_add = is_add;
4870   mp->del_all = del_all;
4871   if (v6_address_set)
4872     {
4873       mp->is_ipv6 = 1;
4874       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4875     }
4876   else
4877     {
4878       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4879     }
4880   mp->address_length = address_length;
4881
4882   /* send it... */
4883   S;
4884
4885   /* Wait for a reply, return good/bad news  */
4886   W;
4887 }
4888
4889 static int
4890 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4891 {
4892   unformat_input_t *i = vam->input;
4893   vl_api_sw_interface_set_mpls_enable_t *mp;
4894   f64 timeout;
4895   u32 sw_if_index;
4896   u8 sw_if_index_set = 0;
4897   u8 enable = 1;
4898
4899   /* Parse args required to build the message */
4900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4901     {
4902       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4903         sw_if_index_set = 1;
4904       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4905         sw_if_index_set = 1;
4906       else if (unformat (i, "disable"))
4907         enable = 0;
4908       else if (unformat (i, "dis"))
4909         enable = 0;
4910       else
4911         break;
4912     }
4913
4914   if (sw_if_index_set == 0)
4915     {
4916       errmsg ("missing interface name or sw_if_index\n");
4917       return -99;
4918     }
4919
4920   /* Construct the API message */
4921   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
4922
4923   mp->sw_if_index = ntohl (sw_if_index);
4924   mp->enable = enable;
4925
4926   /* send it... */
4927   S;
4928
4929   /* Wait for a reply... */
4930   W;
4931 }
4932
4933 static int
4934 api_sw_interface_set_table (vat_main_t * vam)
4935 {
4936   unformat_input_t *i = vam->input;
4937   vl_api_sw_interface_set_table_t *mp;
4938   f64 timeout;
4939   u32 sw_if_index, vrf_id = 0;
4940   u8 sw_if_index_set = 0;
4941   u8 is_ipv6 = 0;
4942
4943   /* Parse args required to build the message */
4944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4945     {
4946       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4947         sw_if_index_set = 1;
4948       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4949         sw_if_index_set = 1;
4950       else if (unformat (i, "vrf %d", &vrf_id))
4951         ;
4952       else if (unformat (i, "ipv6"))
4953         is_ipv6 = 1;
4954       else
4955         break;
4956     }
4957
4958   if (sw_if_index_set == 0)
4959     {
4960       errmsg ("missing interface name or sw_if_index\n");
4961       return -99;
4962     }
4963
4964   /* Construct the API message */
4965   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4966
4967   mp->sw_if_index = ntohl (sw_if_index);
4968   mp->is_ipv6 = is_ipv6;
4969   mp->vrf_id = ntohl (vrf_id);
4970
4971   /* send it... */
4972   S;
4973
4974   /* Wait for a reply... */
4975   W;
4976 }
4977
4978 static int
4979 api_sw_interface_set_vpath (vat_main_t * vam)
4980 {
4981   unformat_input_t *i = vam->input;
4982   vl_api_sw_interface_set_vpath_t *mp;
4983   f64 timeout;
4984   u32 sw_if_index = 0;
4985   u8 sw_if_index_set = 0;
4986   u8 is_enable = 0;
4987
4988   /* Parse args required to build the message */
4989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4990     {
4991       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4992         sw_if_index_set = 1;
4993       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4994         sw_if_index_set = 1;
4995       else if (unformat (i, "enable"))
4996         is_enable = 1;
4997       else if (unformat (i, "disable"))
4998         is_enable = 0;
4999       else
5000         break;
5001     }
5002
5003   if (sw_if_index_set == 0)
5004     {
5005       errmsg ("missing interface name or sw_if_index\n");
5006       return -99;
5007     }
5008
5009   /* Construct the API message */
5010   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5011
5012   mp->sw_if_index = ntohl (sw_if_index);
5013   mp->enable = is_enable;
5014
5015   /* send it... */
5016   S;
5017
5018   /* Wait for a reply... */
5019   W;
5020 }
5021
5022 static int
5023 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5024 {
5025   unformat_input_t *i = vam->input;
5026   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5027   f64 timeout;
5028   u32 sw_if_index = 0;
5029   u8 sw_if_index_set = 0;
5030   u8 is_enable = 0;
5031   u8 is_ipv6 = 0;
5032
5033   /* Parse args required to build the message */
5034   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5035     {
5036       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5037         sw_if_index_set = 1;
5038       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5039         sw_if_index_set = 1;
5040       else if (unformat (i, "enable"))
5041         is_enable = 1;
5042       else if (unformat (i, "disable"))
5043         is_enable = 0;
5044       else if (unformat (i, "ip4"))
5045         is_ipv6 = 0;
5046       else if (unformat (i, "ip6"))
5047         is_ipv6 = 1;
5048       else
5049         break;
5050     }
5051
5052   if (sw_if_index_set == 0)
5053     {
5054       errmsg ("missing interface name or sw_if_index\n");
5055       return -99;
5056     }
5057
5058   /* Construct the API message */
5059   M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5060
5061   mp->sw_if_index = ntohl (sw_if_index);
5062   mp->enable = is_enable;
5063   mp->is_ipv6 = is_ipv6;
5064
5065   /* send it... */
5066   S;
5067
5068   /* Wait for a reply... */
5069   W;
5070 }
5071
5072 static int
5073 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5074 {
5075   unformat_input_t *i = vam->input;
5076   vl_api_sw_interface_set_l2_xconnect_t *mp;
5077   f64 timeout;
5078   u32 rx_sw_if_index;
5079   u8 rx_sw_if_index_set = 0;
5080   u32 tx_sw_if_index;
5081   u8 tx_sw_if_index_set = 0;
5082   u8 enable = 1;
5083
5084   /* Parse args required to build the message */
5085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5086     {
5087       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5088         rx_sw_if_index_set = 1;
5089       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5090         tx_sw_if_index_set = 1;
5091       else if (unformat (i, "rx"))
5092         {
5093           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5094             {
5095               if (unformat (i, "%U", unformat_sw_if_index, vam,
5096                             &rx_sw_if_index))
5097                 rx_sw_if_index_set = 1;
5098             }
5099           else
5100             break;
5101         }
5102       else if (unformat (i, "tx"))
5103         {
5104           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5105             {
5106               if (unformat (i, "%U", unformat_sw_if_index, vam,
5107                             &tx_sw_if_index))
5108                 tx_sw_if_index_set = 1;
5109             }
5110           else
5111             break;
5112         }
5113       else if (unformat (i, "enable"))
5114         enable = 1;
5115       else if (unformat (i, "disable"))
5116         enable = 0;
5117       else
5118         break;
5119     }
5120
5121   if (rx_sw_if_index_set == 0)
5122     {
5123       errmsg ("missing rx interface name or rx_sw_if_index\n");
5124       return -99;
5125     }
5126
5127   if (enable && (tx_sw_if_index_set == 0))
5128     {
5129       errmsg ("missing tx interface name or tx_sw_if_index\n");
5130       return -99;
5131     }
5132
5133   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5134
5135   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5136   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5137   mp->enable = enable;
5138
5139   S;
5140   W;
5141   /* NOTREACHED */
5142   return 0;
5143 }
5144
5145 static int
5146 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5147 {
5148   unformat_input_t *i = vam->input;
5149   vl_api_sw_interface_set_l2_bridge_t *mp;
5150   f64 timeout;
5151   u32 rx_sw_if_index;
5152   u8 rx_sw_if_index_set = 0;
5153   u32 bd_id;
5154   u8 bd_id_set = 0;
5155   u8 bvi = 0;
5156   u32 shg = 0;
5157   u8 enable = 1;
5158
5159   /* Parse args required to build the message */
5160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5161     {
5162       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5163         rx_sw_if_index_set = 1;
5164       else if (unformat (i, "bd_id %d", &bd_id))
5165         bd_id_set = 1;
5166       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5167         rx_sw_if_index_set = 1;
5168       else if (unformat (i, "shg %d", &shg))
5169         ;
5170       else if (unformat (i, "bvi"))
5171         bvi = 1;
5172       else if (unformat (i, "enable"))
5173         enable = 1;
5174       else if (unformat (i, "disable"))
5175         enable = 0;
5176       else
5177         break;
5178     }
5179
5180   if (rx_sw_if_index_set == 0)
5181     {
5182       errmsg ("missing rx interface name or sw_if_index\n");
5183       return -99;
5184     }
5185
5186   if (enable && (bd_id_set == 0))
5187     {
5188       errmsg ("missing bridge domain\n");
5189       return -99;
5190     }
5191
5192   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5193
5194   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5195   mp->bd_id = ntohl (bd_id);
5196   mp->shg = (u8) shg;
5197   mp->bvi = bvi;
5198   mp->enable = enable;
5199
5200   S;
5201   W;
5202   /* NOTREACHED */
5203   return 0;
5204 }
5205
5206 static int
5207 api_bridge_domain_dump (vat_main_t * vam)
5208 {
5209   unformat_input_t *i = vam->input;
5210   vl_api_bridge_domain_dump_t *mp;
5211   f64 timeout;
5212   u32 bd_id = ~0;
5213
5214   /* Parse args required to build the message */
5215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5216     {
5217       if (unformat (i, "bd_id %d", &bd_id))
5218         ;
5219       else
5220         break;
5221     }
5222
5223   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5224   mp->bd_id = ntohl (bd_id);
5225   S;
5226
5227   /* Use a control ping for synchronization */
5228   {
5229     vl_api_control_ping_t *mp;
5230     M (CONTROL_PING, control_ping);
5231     S;
5232   }
5233
5234   W;
5235   /* NOTREACHED */
5236   return 0;
5237 }
5238
5239 static int
5240 api_bridge_domain_add_del (vat_main_t * vam)
5241 {
5242   unformat_input_t *i = vam->input;
5243   vl_api_bridge_domain_add_del_t *mp;
5244   f64 timeout;
5245   u32 bd_id = ~0;
5246   u8 is_add = 1;
5247   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5248
5249   /* Parse args required to build the message */
5250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5251     {
5252       if (unformat (i, "bd_id %d", &bd_id))
5253         ;
5254       else if (unformat (i, "flood %d", &flood))
5255         ;
5256       else if (unformat (i, "uu-flood %d", &uu_flood))
5257         ;
5258       else if (unformat (i, "forward %d", &forward))
5259         ;
5260       else if (unformat (i, "learn %d", &learn))
5261         ;
5262       else if (unformat (i, "arp-term %d", &arp_term))
5263         ;
5264       else if (unformat (i, "del"))
5265         {
5266           is_add = 0;
5267           flood = uu_flood = forward = learn = 0;
5268         }
5269       else
5270         break;
5271     }
5272
5273   if (bd_id == ~0)
5274     {
5275       errmsg ("missing bridge domain\n");
5276       return -99;
5277     }
5278
5279   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5280
5281   mp->bd_id = ntohl (bd_id);
5282   mp->flood = flood;
5283   mp->uu_flood = uu_flood;
5284   mp->forward = forward;
5285   mp->learn = learn;
5286   mp->arp_term = arp_term;
5287   mp->is_add = is_add;
5288
5289   S;
5290   W;
5291   /* NOTREACHED */
5292   return 0;
5293 }
5294
5295 static int
5296 api_l2fib_add_del (vat_main_t * vam)
5297 {
5298   unformat_input_t *i = vam->input;
5299   vl_api_l2fib_add_del_t *mp;
5300   f64 timeout;
5301   u64 mac = 0;
5302   u8 mac_set = 0;
5303   u32 bd_id;
5304   u8 bd_id_set = 0;
5305   u32 sw_if_index;
5306   u8 sw_if_index_set = 0;
5307   u8 is_add = 1;
5308   u8 static_mac = 0;
5309   u8 filter_mac = 0;
5310   u8 bvi_mac = 0;
5311   int count = 1;
5312   f64 before = 0;
5313   int j;
5314
5315   /* Parse args required to build the message */
5316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5317     {
5318       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5319         mac_set = 1;
5320       else if (unformat (i, "bd_id %d", &bd_id))
5321         bd_id_set = 1;
5322       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5323         sw_if_index_set = 1;
5324       else if (unformat (i, "sw_if"))
5325         {
5326           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5327             {
5328               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5329                 sw_if_index_set = 1;
5330             }
5331           else
5332             break;
5333         }
5334       else if (unformat (i, "static"))
5335         static_mac = 1;
5336       else if (unformat (i, "filter"))
5337         {
5338           filter_mac = 1;
5339           static_mac = 1;
5340         }
5341       else if (unformat (i, "bvi"))
5342         {
5343           bvi_mac = 1;
5344           static_mac = 1;
5345         }
5346       else if (unformat (i, "del"))
5347         is_add = 0;
5348       else if (unformat (i, "count %d", &count))
5349         ;
5350       else
5351         break;
5352     }
5353
5354   if (mac_set == 0)
5355     {
5356       errmsg ("missing mac address\n");
5357       return -99;
5358     }
5359
5360   if (bd_id_set == 0)
5361     {
5362       errmsg ("missing bridge domain\n");
5363       return -99;
5364     }
5365
5366   if (is_add && (sw_if_index_set == 0))
5367     {
5368       errmsg ("missing interface name or sw_if_index\n");
5369       return -99;
5370     }
5371
5372   if (count > 1)
5373     {
5374       /* Turn on async mode */
5375       vam->async_mode = 1;
5376       vam->async_errors = 0;
5377       before = vat_time_now (vam);
5378     }
5379
5380   for (j = 0; j < count; j++)
5381     {
5382       M (L2FIB_ADD_DEL, l2fib_add_del);
5383
5384       mp->mac = mac;
5385       mp->bd_id = ntohl (bd_id);
5386       mp->is_add = is_add;
5387
5388       if (is_add)
5389         {
5390           mp->sw_if_index = ntohl (sw_if_index);
5391           mp->static_mac = static_mac;
5392           mp->filter_mac = filter_mac;
5393           mp->bvi_mac = bvi_mac;
5394         }
5395       increment_mac_address (&mac);
5396       /* send it... */
5397       S;
5398     }
5399
5400   if (count > 1)
5401     {
5402       vl_api_control_ping_t *mp;
5403       f64 after;
5404
5405       /* Shut off async mode */
5406       vam->async_mode = 0;
5407
5408       M (CONTROL_PING, control_ping);
5409       S;
5410
5411       timeout = vat_time_now (vam) + 1.0;
5412       while (vat_time_now (vam) < timeout)
5413         if (vam->result_ready == 1)
5414           goto out;
5415       vam->retval = -99;
5416
5417     out:
5418       if (vam->retval == -99)
5419         errmsg ("timeout\n");
5420
5421       if (vam->async_errors > 0)
5422         {
5423           errmsg ("%d asynchronous errors\n", vam->async_errors);
5424           vam->retval = -98;
5425         }
5426       vam->async_errors = 0;
5427       after = vat_time_now (vam);
5428
5429       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5430                count, after - before, count / (after - before));
5431     }
5432   else
5433     {
5434       /* Wait for a reply... */
5435       W;
5436     }
5437   /* Return the good/bad news */
5438   return (vam->retval);
5439 }
5440
5441 static int
5442 api_l2_flags (vat_main_t * vam)
5443 {
5444   unformat_input_t *i = vam->input;
5445   vl_api_l2_flags_t *mp;
5446   f64 timeout;
5447   u32 sw_if_index;
5448   u32 feature_bitmap = 0;
5449   u8 sw_if_index_set = 0;
5450
5451   /* Parse args required to build the message */
5452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5453     {
5454       if (unformat (i, "sw_if_index %d", &sw_if_index))
5455         sw_if_index_set = 1;
5456       else if (unformat (i, "sw_if"))
5457         {
5458           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5459             {
5460               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5461                 sw_if_index_set = 1;
5462             }
5463           else
5464             break;
5465         }
5466       else if (unformat (i, "learn"))
5467         feature_bitmap |= L2INPUT_FEAT_LEARN;
5468       else if (unformat (i, "forward"))
5469         feature_bitmap |= L2INPUT_FEAT_FWD;
5470       else if (unformat (i, "flood"))
5471         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5472       else if (unformat (i, "uu-flood"))
5473         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5474       else
5475         break;
5476     }
5477
5478   if (sw_if_index_set == 0)
5479     {
5480       errmsg ("missing interface name or sw_if_index\n");
5481       return -99;
5482     }
5483
5484   M (L2_FLAGS, l2_flags);
5485
5486   mp->sw_if_index = ntohl (sw_if_index);
5487   mp->feature_bitmap = ntohl (feature_bitmap);
5488
5489   S;
5490   W;
5491   /* NOTREACHED */
5492   return 0;
5493 }
5494
5495 static int
5496 api_bridge_flags (vat_main_t * vam)
5497 {
5498   unformat_input_t *i = vam->input;
5499   vl_api_bridge_flags_t *mp;
5500   f64 timeout;
5501   u32 bd_id;
5502   u8 bd_id_set = 0;
5503   u8 is_set = 1;
5504   u32 flags = 0;
5505
5506   /* Parse args required to build the message */
5507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5508     {
5509       if (unformat (i, "bd_id %d", &bd_id))
5510         bd_id_set = 1;
5511       else if (unformat (i, "learn"))
5512         flags |= L2_LEARN;
5513       else if (unformat (i, "forward"))
5514         flags |= L2_FWD;
5515       else if (unformat (i, "flood"))
5516         flags |= L2_FLOOD;
5517       else if (unformat (i, "uu-flood"))
5518         flags |= L2_UU_FLOOD;
5519       else if (unformat (i, "arp-term"))
5520         flags |= L2_ARP_TERM;
5521       else if (unformat (i, "off"))
5522         is_set = 0;
5523       else if (unformat (i, "disable"))
5524         is_set = 0;
5525       else
5526         break;
5527     }
5528
5529   if (bd_id_set == 0)
5530     {
5531       errmsg ("missing bridge domain\n");
5532       return -99;
5533     }
5534
5535   M (BRIDGE_FLAGS, bridge_flags);
5536
5537   mp->bd_id = ntohl (bd_id);
5538   mp->feature_bitmap = ntohl (flags);
5539   mp->is_set = is_set;
5540
5541   S;
5542   W;
5543   /* NOTREACHED */
5544   return 0;
5545 }
5546
5547 static int
5548 api_bd_ip_mac_add_del (vat_main_t * vam)
5549 {
5550   unformat_input_t *i = vam->input;
5551   vl_api_bd_ip_mac_add_del_t *mp;
5552   f64 timeout;
5553   u32 bd_id;
5554   u8 is_ipv6 = 0;
5555   u8 is_add = 1;
5556   u8 bd_id_set = 0;
5557   u8 ip_set = 0;
5558   u8 mac_set = 0;
5559   ip4_address_t v4addr;
5560   ip6_address_t v6addr;
5561   u8 macaddr[6];
5562
5563
5564   /* Parse args required to build the message */
5565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5566     {
5567       if (unformat (i, "bd_id %d", &bd_id))
5568         {
5569           bd_id_set++;
5570         }
5571       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5572         {
5573           ip_set++;
5574         }
5575       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5576         {
5577           ip_set++;
5578           is_ipv6++;
5579         }
5580       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5581         {
5582           mac_set++;
5583         }
5584       else if (unformat (i, "del"))
5585         is_add = 0;
5586       else
5587         break;
5588     }
5589
5590   if (bd_id_set == 0)
5591     {
5592       errmsg ("missing bridge domain\n");
5593       return -99;
5594     }
5595   else if (ip_set == 0)
5596     {
5597       errmsg ("missing IP address\n");
5598       return -99;
5599     }
5600   else if (mac_set == 0)
5601     {
5602       errmsg ("missing MAC address\n");
5603       return -99;
5604     }
5605
5606   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5607
5608   mp->bd_id = ntohl (bd_id);
5609   mp->is_ipv6 = is_ipv6;
5610   mp->is_add = is_add;
5611   if (is_ipv6)
5612     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5613   else
5614     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5615   clib_memcpy (mp->mac_address, macaddr, 6);
5616   S;
5617   W;
5618   /* NOTREACHED */
5619   return 0;
5620 }
5621
5622 static int
5623 api_tap_connect (vat_main_t * vam)
5624 {
5625   unformat_input_t *i = vam->input;
5626   vl_api_tap_connect_t *mp;
5627   f64 timeout;
5628   u8 mac_address[6];
5629   u8 random_mac = 1;
5630   u8 name_set = 0;
5631   u8 *tap_name;
5632
5633   memset (mac_address, 0, sizeof (mac_address));
5634
5635   /* Parse args required to build the message */
5636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5637     {
5638       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5639         {
5640           random_mac = 0;
5641         }
5642       else if (unformat (i, "random-mac"))
5643         random_mac = 1;
5644       else if (unformat (i, "tapname %s", &tap_name))
5645         name_set = 1;
5646       else
5647         break;
5648     }
5649
5650   if (name_set == 0)
5651     {
5652       errmsg ("missing tap name\n");
5653       return -99;
5654     }
5655   if (vec_len (tap_name) > 63)
5656     {
5657       errmsg ("tap name too long\n");
5658     }
5659   vec_add1 (tap_name, 0);
5660
5661   /* Construct the API message */
5662   M (TAP_CONNECT, tap_connect);
5663
5664   mp->use_random_mac = random_mac;
5665   clib_memcpy (mp->mac_address, mac_address, 6);
5666   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5667   vec_free (tap_name);
5668
5669   /* send it... */
5670   S;
5671
5672   /* Wait for a reply... */
5673   W;
5674 }
5675
5676 static int
5677 api_tap_modify (vat_main_t * vam)
5678 {
5679   unformat_input_t *i = vam->input;
5680   vl_api_tap_modify_t *mp;
5681   f64 timeout;
5682   u8 mac_address[6];
5683   u8 random_mac = 1;
5684   u8 name_set = 0;
5685   u8 *tap_name;
5686   u32 sw_if_index = ~0;
5687   u8 sw_if_index_set = 0;
5688
5689   memset (mac_address, 0, sizeof (mac_address));
5690
5691   /* Parse args required to build the message */
5692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5693     {
5694       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5695         sw_if_index_set = 1;
5696       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5697         sw_if_index_set = 1;
5698       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5699         {
5700           random_mac = 0;
5701         }
5702       else if (unformat (i, "random-mac"))
5703         random_mac = 1;
5704       else if (unformat (i, "tapname %s", &tap_name))
5705         name_set = 1;
5706       else
5707         break;
5708     }
5709
5710   if (sw_if_index_set == 0)
5711     {
5712       errmsg ("missing vpp interface name");
5713       return -99;
5714     }
5715   if (name_set == 0)
5716     {
5717       errmsg ("missing tap name\n");
5718       return -99;
5719     }
5720   if (vec_len (tap_name) > 63)
5721     {
5722       errmsg ("tap name too long\n");
5723     }
5724   vec_add1 (tap_name, 0);
5725
5726   /* Construct the API message */
5727   M (TAP_MODIFY, tap_modify);
5728
5729   mp->use_random_mac = random_mac;
5730   mp->sw_if_index = ntohl (sw_if_index);
5731   clib_memcpy (mp->mac_address, mac_address, 6);
5732   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5733   vec_free (tap_name);
5734
5735   /* send it... */
5736   S;
5737
5738   /* Wait for a reply... */
5739   W;
5740 }
5741
5742 static int
5743 api_tap_delete (vat_main_t * vam)
5744 {
5745   unformat_input_t *i = vam->input;
5746   vl_api_tap_delete_t *mp;
5747   f64 timeout;
5748   u32 sw_if_index = ~0;
5749   u8 sw_if_index_set = 0;
5750
5751   /* Parse args required to build the message */
5752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5753     {
5754       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5755         sw_if_index_set = 1;
5756       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5757         sw_if_index_set = 1;
5758       else
5759         break;
5760     }
5761
5762   if (sw_if_index_set == 0)
5763     {
5764       errmsg ("missing vpp interface name");
5765       return -99;
5766     }
5767
5768   /* Construct the API message */
5769   M (TAP_DELETE, tap_delete);
5770
5771   mp->sw_if_index = ntohl (sw_if_index);
5772
5773   /* send it... */
5774   S;
5775
5776   /* Wait for a reply... */
5777   W;
5778 }
5779
5780 static int
5781 api_ip_add_del_route (vat_main_t * vam)
5782 {
5783   unformat_input_t *i = vam->input;
5784   vl_api_ip_add_del_route_t *mp;
5785   f64 timeout;
5786   u32 sw_if_index = ~0, vrf_id = 0;
5787   u8 sw_if_index_set = 0;
5788   u8 is_ipv6 = 0;
5789   u8 is_local = 0, is_drop = 0;
5790   u8 is_unreach = 0, is_prohibit = 0;
5791   u8 create_vrf_if_needed = 0;
5792   u8 is_add = 1;
5793   u32 next_hop_weight = 1;
5794   u8 not_last = 0;
5795   u8 is_multipath = 0;
5796   u8 address_set = 0;
5797   u8 address_length_set = 0;
5798   u32 next_hop_table_id = 0;
5799   u32 resolve_attempts = 0;
5800   u32 dst_address_length = 0;
5801   u8 next_hop_set = 0;
5802   ip4_address_t v4_dst_address, v4_next_hop_address;
5803   ip6_address_t v6_dst_address, v6_next_hop_address;
5804   int count = 1;
5805   int j;
5806   f64 before = 0;
5807   u32 random_add_del = 0;
5808   u32 *random_vector = 0;
5809   uword *random_hash;
5810   u32 random_seed = 0xdeaddabe;
5811   u32 classify_table_index = ~0;
5812   u8 is_classify = 0;
5813   u8 resolve_host = 0, resolve_attached = 0;
5814   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5815
5816   /* Parse args required to build the message */
5817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5818     {
5819       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5820         sw_if_index_set = 1;
5821       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5822         sw_if_index_set = 1;
5823       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5824         {
5825           address_set = 1;
5826           is_ipv6 = 0;
5827         }
5828       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5829         {
5830           address_set = 1;
5831           is_ipv6 = 1;
5832         }
5833       else if (unformat (i, "/%d", &dst_address_length))
5834         {
5835           address_length_set = 1;
5836         }
5837
5838       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5839                                          &v4_next_hop_address))
5840         {
5841           next_hop_set = 1;
5842         }
5843       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5844                                          &v6_next_hop_address))
5845         {
5846           next_hop_set = 1;
5847         }
5848       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5849         ;
5850       else if (unformat (i, "weight %d", &next_hop_weight))
5851         ;
5852       else if (unformat (i, "drop"))
5853         {
5854           is_drop = 1;
5855         }
5856       else if (unformat (i, "null-send-unreach"))
5857         {
5858           is_unreach = 1;
5859         }
5860       else if (unformat (i, "null-send-prohibit"))
5861         {
5862           is_prohibit = 1;
5863         }
5864       else if (unformat (i, "local"))
5865         {
5866           is_local = 1;
5867         }
5868       else if (unformat (i, "classify %d", &classify_table_index))
5869         {
5870           is_classify = 1;
5871         }
5872       else if (unformat (i, "del"))
5873         is_add = 0;
5874       else if (unformat (i, "add"))
5875         is_add = 1;
5876       else if (unformat (i, "not-last"))
5877         not_last = 1;
5878       else if (unformat (i, "resolve-via-host"))
5879         resolve_host = 1;
5880       else if (unformat (i, "resolve-via-attached"))
5881         resolve_attached = 1;
5882       else if (unformat (i, "multipath"))
5883         is_multipath = 1;
5884       else if (unformat (i, "vrf %d", &vrf_id))
5885         ;
5886       else if (unformat (i, "create-vrf"))
5887         create_vrf_if_needed = 1;
5888       else if (unformat (i, "count %d", &count))
5889         ;
5890       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
5891         ;
5892       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
5893         ;
5894       else if (unformat (i, "out-label %d", &next_hop_out_label))
5895         ;
5896       else if (unformat (i, "random"))
5897         random_add_del = 1;
5898       else if (unformat (i, "seed %d", &random_seed))
5899         ;
5900       else
5901         {
5902           clib_warning ("parse error '%U'", format_unformat_error, i);
5903           return -99;
5904         }
5905     }
5906
5907   if (resolve_attempts > 0 && sw_if_index_set == 0)
5908     {
5909       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5910       return -99;
5911     }
5912
5913   if (!next_hop_set && !is_drop && !is_local &&
5914       !is_classify && !is_unreach && !is_prohibit)
5915     {
5916       errmsg
5917         ("next hop / local / drop / unreach / prohibit / classify not set\n");
5918       return -99;
5919     }
5920
5921   if (address_set == 0)
5922     {
5923       errmsg ("missing addresses\n");
5924       return -99;
5925     }
5926
5927   if (address_length_set == 0)
5928     {
5929       errmsg ("missing address length\n");
5930       return -99;
5931     }
5932
5933   /* Generate a pile of unique, random routes */
5934   if (random_add_del)
5935     {
5936       u32 this_random_address;
5937       random_hash = hash_create (count, sizeof (uword));
5938
5939       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5940       for (j = 0; j <= count; j++)
5941         {
5942           do
5943             {
5944               this_random_address = random_u32 (&random_seed);
5945               this_random_address =
5946                 clib_host_to_net_u32 (this_random_address);
5947             }
5948           while (hash_get (random_hash, this_random_address));
5949           vec_add1 (random_vector, this_random_address);
5950           hash_set (random_hash, this_random_address, 1);
5951         }
5952       hash_free (random_hash);
5953       v4_dst_address.as_u32 = random_vector[0];
5954     }
5955
5956   if (count > 1)
5957     {
5958       /* Turn on async mode */
5959       vam->async_mode = 1;
5960       vam->async_errors = 0;
5961       before = vat_time_now (vam);
5962     }
5963
5964   for (j = 0; j < count; j++)
5965     {
5966       /* Construct the API message */
5967       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5968
5969       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5970       mp->table_id = ntohl (vrf_id);
5971       if (resolve_attempts > 0)
5972         {
5973           mp->resolve_attempts = ntohl (resolve_attempts);
5974           mp->resolve_if_needed = 1;
5975         }
5976       mp->create_vrf_if_needed = create_vrf_if_needed;
5977
5978       mp->is_add = is_add;
5979       mp->is_drop = is_drop;
5980       mp->is_unreach = is_unreach;
5981       mp->is_prohibit = is_prohibit;
5982       mp->is_ipv6 = is_ipv6;
5983       mp->is_local = is_local;
5984       mp->is_classify = is_classify;
5985       mp->is_multipath = is_multipath;
5986       mp->is_resolve_host = resolve_host;
5987       mp->is_resolve_attached = resolve_attached;
5988       mp->not_last = not_last;
5989       mp->next_hop_weight = next_hop_weight;
5990       mp->dst_address_length = dst_address_length;
5991       mp->next_hop_table_id = ntohl (next_hop_table_id);
5992       mp->classify_table_index = ntohl (classify_table_index);
5993       mp->next_hop_out_label = ntohl (next_hop_out_label);
5994
5995       if (is_ipv6)
5996         {
5997           clib_memcpy (mp->dst_address, &v6_dst_address,
5998                        sizeof (v6_dst_address));
5999           if (next_hop_set)
6000             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6001                          sizeof (v6_next_hop_address));
6002           increment_v6_address (&v6_dst_address);
6003         }
6004       else
6005         {
6006           clib_memcpy (mp->dst_address, &v4_dst_address,
6007                        sizeof (v4_dst_address));
6008           if (next_hop_set)
6009             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6010                          sizeof (v4_next_hop_address));
6011           if (random_add_del)
6012             v4_dst_address.as_u32 = random_vector[j + 1];
6013           else
6014             increment_v4_address (&v4_dst_address);
6015         }
6016       /* send it... */
6017       S;
6018       /* If we receive SIGTERM, stop now... */
6019       if (vam->do_exit)
6020         break;
6021     }
6022
6023   /* When testing multiple add/del ops, use a control-ping to sync */
6024   if (count > 1)
6025     {
6026       vl_api_control_ping_t *mp;
6027       f64 after;
6028
6029       /* Shut off async mode */
6030       vam->async_mode = 0;
6031
6032       M (CONTROL_PING, control_ping);
6033       S;
6034
6035       timeout = vat_time_now (vam) + 1.0;
6036       while (vat_time_now (vam) < timeout)
6037         if (vam->result_ready == 1)
6038           goto out;
6039       vam->retval = -99;
6040
6041     out:
6042       if (vam->retval == -99)
6043         errmsg ("timeout\n");
6044
6045       if (vam->async_errors > 0)
6046         {
6047           errmsg ("%d asynchronous errors\n", vam->async_errors);
6048           vam->retval = -98;
6049         }
6050       vam->async_errors = 0;
6051       after = vat_time_now (vam);
6052
6053       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6054       if (j > 0)
6055         count = j;
6056
6057       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6058                count, after - before, count / (after - before));
6059     }
6060   else
6061     {
6062       /* Wait for a reply... */
6063       W;
6064     }
6065
6066   /* Return the good/bad news */
6067   return (vam->retval);
6068 }
6069
6070 static int
6071 api_mpls_route_add_del (vat_main_t * vam)
6072 {
6073   unformat_input_t *i = vam->input;
6074   vl_api_mpls_route_add_del_t *mp;
6075   f64 timeout;
6076   u32 sw_if_index = ~0, table_id = 0;
6077   u8 create_table_if_needed = 0;
6078   u8 is_add = 1;
6079   u32 next_hop_weight = 1;
6080   u8 is_multipath = 0;
6081   u32 next_hop_table_id = 0;
6082   u8 next_hop_set = 0;
6083   ip4_address_t v4_next_hop_address = {
6084     .as_u32 = 0,
6085   };
6086   ip6_address_t v6_next_hop_address = { {0} };
6087   int count = 1;
6088   int j;
6089   f64 before = 0;
6090   u32 classify_table_index = ~0;
6091   u8 is_classify = 0;
6092   u8 resolve_host = 0, resolve_attached = 0;
6093   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6094   mpls_label_t local_label = MPLS_LABEL_INVALID;
6095   u8 is_eos = 1;
6096   u8 next_hop_proto_is_ip4 = 1;
6097
6098   /* Parse args required to build the message */
6099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6100     {
6101       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6102         ;
6103       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6104         ;
6105       else if (unformat (i, "%d", &local_label))
6106         ;
6107       else if (unformat (i, "eos"))
6108         is_eos = 1;
6109       else if (unformat (i, "non-eos"))
6110         is_eos = 0;
6111       else if (unformat (i, "via %U", unformat_ip4_address,
6112                          &v4_next_hop_address))
6113         {
6114           next_hop_set = 1;
6115           next_hop_proto_is_ip4 = 1;
6116         }
6117       else if (unformat (i, "via %U", unformat_ip6_address,
6118                          &v6_next_hop_address))
6119         {
6120           next_hop_set = 1;
6121           next_hop_proto_is_ip4 = 0;
6122         }
6123       else if (unformat (i, "weight %d", &next_hop_weight))
6124         ;
6125       else if (unformat (i, "create-table"))
6126         create_table_if_needed = 1;
6127       else if (unformat (i, "classify %d", &classify_table_index))
6128         {
6129           is_classify = 1;
6130         }
6131       else if (unformat (i, "del"))
6132         is_add = 0;
6133       else if (unformat (i, "add"))
6134         is_add = 1;
6135       else if (unformat (i, "resolve-via-host"))
6136         resolve_host = 1;
6137       else if (unformat (i, "resolve-via-attached"))
6138         resolve_attached = 1;
6139       else if (unformat (i, "multipath"))
6140         is_multipath = 1;
6141       else if (unformat (i, "count %d", &count))
6142         ;
6143       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6144         {
6145           next_hop_set = 1;
6146           next_hop_proto_is_ip4 = 1;
6147         }
6148       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6149         {
6150           next_hop_set = 1;
6151           next_hop_proto_is_ip4 = 0;
6152         }
6153       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6154         ;
6155       else if (unformat (i, "out-label %d", &next_hop_out_label))
6156         ;
6157       else
6158         {
6159           clib_warning ("parse error '%U'", format_unformat_error, i);
6160           return -99;
6161         }
6162     }
6163
6164   if (!next_hop_set && !is_classify)
6165     {
6166       errmsg ("next hop / classify not set\n");
6167       return -99;
6168     }
6169
6170   if (MPLS_LABEL_INVALID == local_label)
6171     {
6172       errmsg ("missing label\n");
6173       return -99;
6174     }
6175
6176   if (count > 1)
6177     {
6178       /* Turn on async mode */
6179       vam->async_mode = 1;
6180       vam->async_errors = 0;
6181       before = vat_time_now (vam);
6182     }
6183
6184   for (j = 0; j < count; j++)
6185     {
6186       /* Construct the API message */
6187       M (MPLS_ROUTE_ADD_DEL, mpls_route_add_del);
6188
6189       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6190       mp->mr_table_id = ntohl (table_id);
6191       mp->mr_create_table_if_needed = create_table_if_needed;
6192
6193       mp->mr_is_add = is_add;
6194       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6195       mp->mr_is_classify = is_classify;
6196       mp->mr_is_multipath = is_multipath;
6197       mp->mr_is_resolve_host = resolve_host;
6198       mp->mr_is_resolve_attached = resolve_attached;
6199       mp->mr_next_hop_weight = next_hop_weight;
6200       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6201       mp->mr_classify_table_index = ntohl (classify_table_index);
6202       mp->mr_next_hop_out_label = ntohl (next_hop_out_label);
6203       mp->mr_label = ntohl (local_label);
6204       mp->mr_eos = is_eos;
6205
6206       if (next_hop_set)
6207         {
6208           if (next_hop_proto_is_ip4)
6209             {
6210               clib_memcpy (mp->mr_next_hop,
6211                            &v4_next_hop_address,
6212                            sizeof (v4_next_hop_address));
6213             }
6214           else
6215             {
6216               clib_memcpy (mp->mr_next_hop,
6217                            &v6_next_hop_address,
6218                            sizeof (v6_next_hop_address));
6219             }
6220         }
6221       local_label++;
6222
6223       /* send it... */
6224       S;
6225       /* If we receive SIGTERM, stop now... */
6226       if (vam->do_exit)
6227         break;
6228     }
6229
6230   /* When testing multiple add/del ops, use a control-ping to sync */
6231   if (count > 1)
6232     {
6233       vl_api_control_ping_t *mp;
6234       f64 after;
6235
6236       /* Shut off async mode */
6237       vam->async_mode = 0;
6238
6239       M (CONTROL_PING, control_ping);
6240       S;
6241
6242       timeout = vat_time_now (vam) + 1.0;
6243       while (vat_time_now (vam) < timeout)
6244         if (vam->result_ready == 1)
6245           goto out;
6246       vam->retval = -99;
6247
6248     out:
6249       if (vam->retval == -99)
6250         errmsg ("timeout\n");
6251
6252       if (vam->async_errors > 0)
6253         {
6254           errmsg ("%d asynchronous errors\n", vam->async_errors);
6255           vam->retval = -98;
6256         }
6257       vam->async_errors = 0;
6258       after = vat_time_now (vam);
6259
6260       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6261       if (j > 0)
6262         count = j;
6263
6264       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6265                count, after - before, count / (after - before));
6266     }
6267   else
6268     {
6269       /* Wait for a reply... */
6270       W;
6271     }
6272
6273   /* Return the good/bad news */
6274   return (vam->retval);
6275 }
6276
6277 static int
6278 api_mpls_ip_bind_unbind (vat_main_t * vam)
6279 {
6280   unformat_input_t *i = vam->input;
6281   vl_api_mpls_ip_bind_unbind_t *mp;
6282   f64 timeout;
6283   u32 ip_table_id = 0;
6284   u8 create_table_if_needed = 0;
6285   u8 is_bind = 1;
6286   u8 is_ip4 = 1;
6287   ip4_address_t v4_address;
6288   ip6_address_t v6_address;
6289   u32 address_length;
6290   u8 address_set = 0;
6291   mpls_label_t local_label = MPLS_LABEL_INVALID;
6292
6293   /* Parse args required to build the message */
6294   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6295     {
6296       if (unformat (i, "%U/%d", unformat_ip4_address,
6297                     &v4_address, &address_length))
6298         {
6299           is_ip4 = 1;
6300           address_set = 1;
6301         }
6302       else if (unformat (i, "%U/%d", unformat_ip6_address,
6303                          &v6_address, &address_length))
6304         {
6305           is_ip4 = 0;
6306           address_set = 1;
6307         }
6308       else if (unformat (i, "%d", &local_label))
6309         ;
6310       else if (unformat (i, "create-table"))
6311         create_table_if_needed = 1;
6312       else if (unformat (i, "table-id %d", &ip_table_id))
6313         ;
6314       else if (unformat (i, "unbind"))
6315         is_bind = 0;
6316       else if (unformat (i, "bind"))
6317         is_bind = 1;
6318       else
6319         {
6320           clib_warning ("parse error '%U'", format_unformat_error, i);
6321           return -99;
6322         }
6323     }
6324
6325   if (!address_set)
6326     {
6327       errmsg ("IP addres not set\n");
6328       return -99;
6329     }
6330
6331   if (MPLS_LABEL_INVALID == local_label)
6332     {
6333       errmsg ("missing label\n");
6334       return -99;
6335     }
6336
6337   /* Construct the API message */
6338   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6339
6340   mp->mb_create_table_if_needed = create_table_if_needed;
6341   mp->mb_is_bind = is_bind;
6342   mp->mb_is_ip4 = is_ip4;
6343   mp->mb_ip_table_id = ntohl (ip_table_id);
6344   mp->mb_mpls_table_id = 0;
6345   mp->mb_label = ntohl (local_label);
6346   mp->mb_address_length = address_length;
6347
6348   if (is_ip4)
6349     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6350   else
6351     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6352
6353   /* send it... */
6354   S;
6355
6356   /* Wait for a reply... */
6357   W;
6358 }
6359
6360 static int
6361 api_proxy_arp_add_del (vat_main_t * vam)
6362 {
6363   unformat_input_t *i = vam->input;
6364   vl_api_proxy_arp_add_del_t *mp;
6365   f64 timeout;
6366   u32 vrf_id = 0;
6367   u8 is_add = 1;
6368   ip4_address_t lo, hi;
6369   u8 range_set = 0;
6370
6371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6372     {
6373       if (unformat (i, "vrf %d", &vrf_id))
6374         ;
6375       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6376                          unformat_ip4_address, &hi))
6377         range_set = 1;
6378       else if (unformat (i, "del"))
6379         is_add = 0;
6380       else
6381         {
6382           clib_warning ("parse error '%U'", format_unformat_error, i);
6383           return -99;
6384         }
6385     }
6386
6387   if (range_set == 0)
6388     {
6389       errmsg ("address range not set\n");
6390       return -99;
6391     }
6392
6393   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6394
6395   mp->vrf_id = ntohl (vrf_id);
6396   mp->is_add = is_add;
6397   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6398   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6399
6400   S;
6401   W;
6402   /* NOTREACHED */
6403   return 0;
6404 }
6405
6406 static int
6407 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6408 {
6409   unformat_input_t *i = vam->input;
6410   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6411   f64 timeout;
6412   u32 sw_if_index;
6413   u8 enable = 1;
6414   u8 sw_if_index_set = 0;
6415
6416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6417     {
6418       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6419         sw_if_index_set = 1;
6420       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6421         sw_if_index_set = 1;
6422       else if (unformat (i, "enable"))
6423         enable = 1;
6424       else if (unformat (i, "disable"))
6425         enable = 0;
6426       else
6427         {
6428           clib_warning ("parse error '%U'", format_unformat_error, i);
6429           return -99;
6430         }
6431     }
6432
6433   if (sw_if_index_set == 0)
6434     {
6435       errmsg ("missing interface name or sw_if_index\n");
6436       return -99;
6437     }
6438
6439   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6440
6441   mp->sw_if_index = ntohl (sw_if_index);
6442   mp->enable_disable = enable;
6443
6444   S;
6445   W;
6446   /* NOTREACHED */
6447   return 0;
6448 }
6449
6450 static int
6451 api_mpls_add_del_encap (vat_main_t * vam)
6452 {
6453   unformat_input_t *i = vam->input;
6454   vl_api_mpls_add_del_encap_t *mp;
6455   f64 timeout;
6456   u32 vrf_id = 0;
6457   u32 *labels = 0;
6458   u32 label;
6459   ip4_address_t dst_address;
6460   u8 is_add = 1;
6461
6462   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6463     {
6464       if (unformat (i, "vrf %d", &vrf_id))
6465         ;
6466       else if (unformat (i, "label %d", &label))
6467         vec_add1 (labels, ntohl (label));
6468       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6469         ;
6470       else if (unformat (i, "del"))
6471         is_add = 0;
6472       else
6473         {
6474           clib_warning ("parse error '%U'", format_unformat_error, i);
6475           return -99;
6476         }
6477     }
6478
6479   if (vec_len (labels) == 0)
6480     {
6481       errmsg ("missing encap label stack\n");
6482       return -99;
6483     }
6484
6485   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6486       sizeof (u32) * vec_len (labels));
6487
6488   mp->vrf_id = ntohl (vrf_id);
6489   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6490   mp->is_add = is_add;
6491   mp->nlabels = vec_len (labels);
6492   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6493
6494   vec_free (labels);
6495
6496   S;
6497   W;
6498   /* NOTREACHED */
6499   return 0;
6500 }
6501
6502 static int
6503 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6504 {
6505   unformat_input_t *i = vam->input;
6506   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6507   f64 timeout;
6508   u32 inner_vrf_id = 0;
6509   ip4_address_t intfc_address;
6510   u8 dst_mac_address[6];
6511   int dst_set = 1;
6512   u32 tmp;
6513   u8 intfc_address_length = 0;
6514   u8 is_add = 1;
6515   u8 l2_only = 0;
6516   u32 tx_sw_if_index;
6517   int tx_sw_if_index_set = 0;
6518
6519   /* Shut up coverity */
6520   memset (dst_mac_address, 0, sizeof (dst_mac_address));
6521
6522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6523     {
6524       if (unformat (i, "vrf %d", &inner_vrf_id))
6525         ;
6526       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6527                          &intfc_address, &tmp))
6528         intfc_address_length = tmp;
6529       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6530         tx_sw_if_index_set = 1;
6531       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6532         tx_sw_if_index_set = 1;
6533       else if (unformat (i, "dst %U", unformat_ethernet_address,
6534                          dst_mac_address))
6535         dst_set = 1;
6536       else if (unformat (i, "l2-only"))
6537         l2_only = 1;
6538       else if (unformat (i, "del"))
6539         is_add = 0;
6540       else
6541         {
6542           clib_warning ("parse error '%U'", format_unformat_error, i);
6543           return -99;
6544         }
6545     }
6546
6547   if (!dst_set)
6548     {
6549       errmsg ("dst (mac address) not set\n");
6550       return -99;
6551     }
6552   if (!tx_sw_if_index_set)
6553     {
6554       errmsg ("tx-intfc not set\n");
6555       return -99;
6556     }
6557
6558   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6559
6560   mp->vrf_id = ntohl (inner_vrf_id);
6561   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6562   mp->adj_address_length = intfc_address_length;
6563   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6564                sizeof (dst_mac_address));
6565   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6566   mp->l2_only = l2_only;
6567   mp->is_add = is_add;
6568
6569   S;
6570   W;
6571   /* NOTREACHED */
6572   return 0;
6573 }
6574
6575 static int
6576 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6577 {
6578   unformat_input_t *i = vam->input;
6579   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6580   f64 timeout;
6581   u32 inner_vrf_id = 0;
6582   u32 outer_vrf_id = 0;
6583   ip4_address_t adj_address;
6584   int adj_address_set = 0;
6585   ip4_address_t next_hop_address;
6586   int next_hop_address_set = 0;
6587   u32 tmp;
6588   u8 adj_address_length = 0;
6589   u8 l2_only = 0;
6590   u8 is_add = 1;
6591   u32 resolve_attempts = 5;
6592   u8 resolve_if_needed = 1;
6593
6594   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6595     {
6596       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6597         ;
6598       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6599         ;
6600       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6601                          &adj_address, &tmp))
6602         {
6603           adj_address_length = tmp;
6604           adj_address_set = 1;
6605         }
6606       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6607                          &next_hop_address))
6608         next_hop_address_set = 1;
6609       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6610         ;
6611       else if (unformat (i, "resolve-if-needed %d", &tmp))
6612         resolve_if_needed = tmp;
6613       else if (unformat (i, "l2-only"))
6614         l2_only = 1;
6615       else if (unformat (i, "del"))
6616         is_add = 0;
6617       else
6618         {
6619           clib_warning ("parse error '%U'", format_unformat_error, i);
6620           return -99;
6621         }
6622     }
6623
6624   if (!adj_address_set)
6625     {
6626       errmsg ("adjacency address/mask not set\n");
6627       return -99;
6628     }
6629   if (!next_hop_address_set)
6630     {
6631       errmsg ("ip4 next hop address (in outer fib) not set\n");
6632       return -99;
6633     }
6634
6635   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6636
6637   mp->inner_vrf_id = ntohl (inner_vrf_id);
6638   mp->outer_vrf_id = ntohl (outer_vrf_id);
6639   mp->resolve_attempts = ntohl (resolve_attempts);
6640   mp->resolve_if_needed = resolve_if_needed;
6641   mp->is_add = is_add;
6642   mp->l2_only = l2_only;
6643   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6644   mp->adj_address_length = adj_address_length;
6645   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6646                sizeof (next_hop_address));
6647
6648   S;
6649   W;
6650   /* NOTREACHED */
6651   return 0;
6652 }
6653
6654 static int
6655 api_sw_interface_set_unnumbered (vat_main_t * vam)
6656 {
6657   unformat_input_t *i = vam->input;
6658   vl_api_sw_interface_set_unnumbered_t *mp;
6659   f64 timeout;
6660   u32 sw_if_index;
6661   u32 unnum_sw_index = ~0;
6662   u8 is_add = 1;
6663   u8 sw_if_index_set = 0;
6664
6665   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6666     {
6667       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6668         sw_if_index_set = 1;
6669       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6670         sw_if_index_set = 1;
6671       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6672         ;
6673       else if (unformat (i, "del"))
6674         is_add = 0;
6675       else
6676         {
6677           clib_warning ("parse error '%U'", format_unformat_error, i);
6678           return -99;
6679         }
6680     }
6681
6682   if (sw_if_index_set == 0)
6683     {
6684       errmsg ("missing interface name or sw_if_index\n");
6685       return -99;
6686     }
6687
6688   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6689
6690   mp->sw_if_index = ntohl (sw_if_index);
6691   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6692   mp->is_add = is_add;
6693
6694   S;
6695   W;
6696   /* NOTREACHED */
6697   return 0;
6698 }
6699
6700 static int
6701 api_ip_neighbor_add_del (vat_main_t * vam)
6702 {
6703   unformat_input_t *i = vam->input;
6704   vl_api_ip_neighbor_add_del_t *mp;
6705   f64 timeout;
6706   u32 sw_if_index;
6707   u8 sw_if_index_set = 0;
6708   u32 vrf_id = 0;
6709   u8 is_add = 1;
6710   u8 is_static = 0;
6711   u8 mac_address[6];
6712   u8 mac_set = 0;
6713   u8 v4_address_set = 0;
6714   u8 v6_address_set = 0;
6715   ip4_address_t v4address;
6716   ip6_address_t v6address;
6717
6718   memset (mac_address, 0, sizeof (mac_address));
6719
6720   /* Parse args required to build the message */
6721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6722     {
6723       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6724         {
6725           mac_set = 1;
6726         }
6727       else if (unformat (i, "del"))
6728         is_add = 0;
6729       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6730         sw_if_index_set = 1;
6731       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6732         sw_if_index_set = 1;
6733       else if (unformat (i, "is_static"))
6734         is_static = 1;
6735       else if (unformat (i, "vrf %d", &vrf_id))
6736         ;
6737       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6738         v4_address_set = 1;
6739       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6740         v6_address_set = 1;
6741       else
6742         {
6743           clib_warning ("parse error '%U'", format_unformat_error, i);
6744           return -99;
6745         }
6746     }
6747
6748   if (sw_if_index_set == 0)
6749     {
6750       errmsg ("missing interface name or sw_if_index\n");
6751       return -99;
6752     }
6753   if (v4_address_set && v6_address_set)
6754     {
6755       errmsg ("both v4 and v6 addresses set\n");
6756       return -99;
6757     }
6758   if (!v4_address_set && !v6_address_set)
6759     {
6760       errmsg ("no address set\n");
6761       return -99;
6762     }
6763
6764   /* Construct the API message */
6765   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6766
6767   mp->sw_if_index = ntohl (sw_if_index);
6768   mp->is_add = is_add;
6769   mp->vrf_id = ntohl (vrf_id);
6770   mp->is_static = is_static;
6771   if (mac_set)
6772     clib_memcpy (mp->mac_address, mac_address, 6);
6773   if (v6_address_set)
6774     {
6775       mp->is_ipv6 = 1;
6776       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6777     }
6778   else
6779     {
6780       /* mp->is_ipv6 = 0; via memset in M macro above */
6781       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6782     }
6783
6784   /* send it... */
6785   S;
6786
6787   /* Wait for a reply, return good/bad news  */
6788   W;
6789
6790   /* NOTREACHED */
6791   return 0;
6792 }
6793
6794 static int
6795 api_reset_vrf (vat_main_t * vam)
6796 {
6797   unformat_input_t *i = vam->input;
6798   vl_api_reset_vrf_t *mp;
6799   f64 timeout;
6800   u32 vrf_id = 0;
6801   u8 is_ipv6 = 0;
6802   u8 vrf_id_set = 0;
6803
6804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6805     {
6806       if (unformat (i, "vrf %d", &vrf_id))
6807         vrf_id_set = 1;
6808       else if (unformat (i, "ipv6"))
6809         is_ipv6 = 1;
6810       else
6811         {
6812           clib_warning ("parse error '%U'", format_unformat_error, i);
6813           return -99;
6814         }
6815     }
6816
6817   if (vrf_id_set == 0)
6818     {
6819       errmsg ("missing vrf id\n");
6820       return -99;
6821     }
6822
6823   M (RESET_VRF, reset_vrf);
6824
6825   mp->vrf_id = ntohl (vrf_id);
6826   mp->is_ipv6 = is_ipv6;
6827
6828   S;
6829   W;
6830   /* NOTREACHED */
6831   return 0;
6832 }
6833
6834 static int
6835 api_create_vlan_subif (vat_main_t * vam)
6836 {
6837   unformat_input_t *i = vam->input;
6838   vl_api_create_vlan_subif_t *mp;
6839   f64 timeout;
6840   u32 sw_if_index;
6841   u8 sw_if_index_set = 0;
6842   u32 vlan_id;
6843   u8 vlan_id_set = 0;
6844
6845   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6846     {
6847       if (unformat (i, "sw_if_index %d", &sw_if_index))
6848         sw_if_index_set = 1;
6849       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6850         sw_if_index_set = 1;
6851       else if (unformat (i, "vlan %d", &vlan_id))
6852         vlan_id_set = 1;
6853       else
6854         {
6855           clib_warning ("parse error '%U'", format_unformat_error, i);
6856           return -99;
6857         }
6858     }
6859
6860   if (sw_if_index_set == 0)
6861     {
6862       errmsg ("missing interface name or sw_if_index\n");
6863       return -99;
6864     }
6865
6866   if (vlan_id_set == 0)
6867     {
6868       errmsg ("missing vlan_id\n");
6869       return -99;
6870     }
6871   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6872
6873   mp->sw_if_index = ntohl (sw_if_index);
6874   mp->vlan_id = ntohl (vlan_id);
6875
6876   S;
6877   W;
6878   /* NOTREACHED */
6879   return 0;
6880 }
6881
6882 #define foreach_create_subif_bit                \
6883 _(no_tags)                                      \
6884 _(one_tag)                                      \
6885 _(two_tags)                                     \
6886 _(dot1ad)                                       \
6887 _(exact_match)                                  \
6888 _(default_sub)                                  \
6889 _(outer_vlan_id_any)                            \
6890 _(inner_vlan_id_any)
6891
6892 static int
6893 api_create_subif (vat_main_t * vam)
6894 {
6895   unformat_input_t *i = vam->input;
6896   vl_api_create_subif_t *mp;
6897   f64 timeout;
6898   u32 sw_if_index;
6899   u8 sw_if_index_set = 0;
6900   u32 sub_id;
6901   u8 sub_id_set = 0;
6902   u32 no_tags = 0;
6903   u32 one_tag = 0;
6904   u32 two_tags = 0;
6905   u32 dot1ad = 0;
6906   u32 exact_match = 0;
6907   u32 default_sub = 0;
6908   u32 outer_vlan_id_any = 0;
6909   u32 inner_vlan_id_any = 0;
6910   u32 tmp;
6911   u16 outer_vlan_id = 0;
6912   u16 inner_vlan_id = 0;
6913
6914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6915     {
6916       if (unformat (i, "sw_if_index %d", &sw_if_index))
6917         sw_if_index_set = 1;
6918       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6919         sw_if_index_set = 1;
6920       else if (unformat (i, "sub_id %d", &sub_id))
6921         sub_id_set = 1;
6922       else if (unformat (i, "outer_vlan_id %d", &tmp))
6923         outer_vlan_id = tmp;
6924       else if (unformat (i, "inner_vlan_id %d", &tmp))
6925         inner_vlan_id = tmp;
6926
6927 #define _(a) else if (unformat (i, #a)) a = 1 ;
6928       foreach_create_subif_bit
6929 #undef _
6930         else
6931         {
6932           clib_warning ("parse error '%U'", format_unformat_error, i);
6933           return -99;
6934         }
6935     }
6936
6937   if (sw_if_index_set == 0)
6938     {
6939       errmsg ("missing interface name or sw_if_index\n");
6940       return -99;
6941     }
6942
6943   if (sub_id_set == 0)
6944     {
6945       errmsg ("missing sub_id\n");
6946       return -99;
6947     }
6948   M (CREATE_SUBIF, create_subif);
6949
6950   mp->sw_if_index = ntohl (sw_if_index);
6951   mp->sub_id = ntohl (sub_id);
6952
6953 #define _(a) mp->a = a;
6954   foreach_create_subif_bit;
6955 #undef _
6956
6957   mp->outer_vlan_id = ntohs (outer_vlan_id);
6958   mp->inner_vlan_id = ntohs (inner_vlan_id);
6959
6960   S;
6961   W;
6962   /* NOTREACHED */
6963   return 0;
6964 }
6965
6966 static int
6967 api_oam_add_del (vat_main_t * vam)
6968 {
6969   unformat_input_t *i = vam->input;
6970   vl_api_oam_add_del_t *mp;
6971   f64 timeout;
6972   u32 vrf_id = 0;
6973   u8 is_add = 1;
6974   ip4_address_t src, dst;
6975   u8 src_set = 0;
6976   u8 dst_set = 0;
6977
6978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6979     {
6980       if (unformat (i, "vrf %d", &vrf_id))
6981         ;
6982       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6983         src_set = 1;
6984       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6985         dst_set = 1;
6986       else if (unformat (i, "del"))
6987         is_add = 0;
6988       else
6989         {
6990           clib_warning ("parse error '%U'", format_unformat_error, i);
6991           return -99;
6992         }
6993     }
6994
6995   if (src_set == 0)
6996     {
6997       errmsg ("missing src addr\n");
6998       return -99;
6999     }
7000
7001   if (dst_set == 0)
7002     {
7003       errmsg ("missing dst addr\n");
7004       return -99;
7005     }
7006
7007   M (OAM_ADD_DEL, oam_add_del);
7008
7009   mp->vrf_id = ntohl (vrf_id);
7010   mp->is_add = is_add;
7011   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7012   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7013
7014   S;
7015   W;
7016   /* NOTREACHED */
7017   return 0;
7018 }
7019
7020 static int
7021 api_reset_fib (vat_main_t * vam)
7022 {
7023   unformat_input_t *i = vam->input;
7024   vl_api_reset_fib_t *mp;
7025   f64 timeout;
7026   u32 vrf_id = 0;
7027   u8 is_ipv6 = 0;
7028   u8 vrf_id_set = 0;
7029
7030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7031     {
7032       if (unformat (i, "vrf %d", &vrf_id))
7033         vrf_id_set = 1;
7034       else if (unformat (i, "ipv6"))
7035         is_ipv6 = 1;
7036       else
7037         {
7038           clib_warning ("parse error '%U'", format_unformat_error, i);
7039           return -99;
7040         }
7041     }
7042
7043   if (vrf_id_set == 0)
7044     {
7045       errmsg ("missing vrf id\n");
7046       return -99;
7047     }
7048
7049   M (RESET_FIB, reset_fib);
7050
7051   mp->vrf_id = ntohl (vrf_id);
7052   mp->is_ipv6 = is_ipv6;
7053
7054   S;
7055   W;
7056   /* NOTREACHED */
7057   return 0;
7058 }
7059
7060 static int
7061 api_dhcp_proxy_config (vat_main_t * vam)
7062 {
7063   unformat_input_t *i = vam->input;
7064   vl_api_dhcp_proxy_config_t *mp;
7065   f64 timeout;
7066   u32 vrf_id = 0;
7067   u8 is_add = 1;
7068   u8 insert_cid = 1;
7069   u8 v4_address_set = 0;
7070   u8 v6_address_set = 0;
7071   ip4_address_t v4address;
7072   ip6_address_t v6address;
7073   u8 v4_src_address_set = 0;
7074   u8 v6_src_address_set = 0;
7075   ip4_address_t v4srcaddress;
7076   ip6_address_t v6srcaddress;
7077
7078   /* Parse args required to build the message */
7079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7080     {
7081       if (unformat (i, "del"))
7082         is_add = 0;
7083       else if (unformat (i, "vrf %d", &vrf_id))
7084         ;
7085       else if (unformat (i, "insert-cid %d", &insert_cid))
7086         ;
7087       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7088         v4_address_set = 1;
7089       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7090         v6_address_set = 1;
7091       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7092         v4_src_address_set = 1;
7093       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7094         v6_src_address_set = 1;
7095       else
7096         break;
7097     }
7098
7099   if (v4_address_set && v6_address_set)
7100     {
7101       errmsg ("both v4 and v6 server addresses set\n");
7102       return -99;
7103     }
7104   if (!v4_address_set && !v6_address_set)
7105     {
7106       errmsg ("no server addresses set\n");
7107       return -99;
7108     }
7109
7110   if (v4_src_address_set && v6_src_address_set)
7111     {
7112       errmsg ("both v4 and v6  src addresses set\n");
7113       return -99;
7114     }
7115   if (!v4_src_address_set && !v6_src_address_set)
7116     {
7117       errmsg ("no src addresses set\n");
7118       return -99;
7119     }
7120
7121   if (!(v4_src_address_set && v4_address_set) &&
7122       !(v6_src_address_set && v6_address_set))
7123     {
7124       errmsg ("no matching server and src addresses set\n");
7125       return -99;
7126     }
7127
7128   /* Construct the API message */
7129   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7130
7131   mp->insert_circuit_id = insert_cid;
7132   mp->is_add = is_add;
7133   mp->vrf_id = ntohl (vrf_id);
7134   if (v6_address_set)
7135     {
7136       mp->is_ipv6 = 1;
7137       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7138       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7139     }
7140   else
7141     {
7142       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7143       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7144     }
7145
7146   /* send it... */
7147   S;
7148
7149   /* Wait for a reply, return good/bad news  */
7150   W;
7151   /* NOTREACHED */
7152   return 0;
7153 }
7154
7155 static int
7156 api_dhcp_proxy_config_2 (vat_main_t * vam)
7157 {
7158   unformat_input_t *i = vam->input;
7159   vl_api_dhcp_proxy_config_2_t *mp;
7160   f64 timeout;
7161   u32 rx_vrf_id = 0;
7162   u32 server_vrf_id = 0;
7163   u8 is_add = 1;
7164   u8 insert_cid = 1;
7165   u8 v4_address_set = 0;
7166   u8 v6_address_set = 0;
7167   ip4_address_t v4address;
7168   ip6_address_t v6address;
7169   u8 v4_src_address_set = 0;
7170   u8 v6_src_address_set = 0;
7171   ip4_address_t v4srcaddress;
7172   ip6_address_t v6srcaddress;
7173
7174   /* Parse args required to build the message */
7175   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7176     {
7177       if (unformat (i, "del"))
7178         is_add = 0;
7179       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7180         ;
7181       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7182         ;
7183       else if (unformat (i, "insert-cid %d", &insert_cid))
7184         ;
7185       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7186         v4_address_set = 1;
7187       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7188         v6_address_set = 1;
7189       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7190         v4_src_address_set = 1;
7191       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7192         v6_src_address_set = 1;
7193       else
7194         break;
7195     }
7196
7197   if (v4_address_set && v6_address_set)
7198     {
7199       errmsg ("both v4 and v6 server addresses set\n");
7200       return -99;
7201     }
7202   if (!v4_address_set && !v6_address_set)
7203     {
7204       errmsg ("no server addresses set\n");
7205       return -99;
7206     }
7207
7208   if (v4_src_address_set && v6_src_address_set)
7209     {
7210       errmsg ("both v4 and v6  src addresses set\n");
7211       return -99;
7212     }
7213   if (!v4_src_address_set && !v6_src_address_set)
7214     {
7215       errmsg ("no src addresses set\n");
7216       return -99;
7217     }
7218
7219   if (!(v4_src_address_set && v4_address_set) &&
7220       !(v6_src_address_set && v6_address_set))
7221     {
7222       errmsg ("no matching server and src addresses set\n");
7223       return -99;
7224     }
7225
7226   /* Construct the API message */
7227   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7228
7229   mp->insert_circuit_id = insert_cid;
7230   mp->is_add = is_add;
7231   mp->rx_vrf_id = ntohl (rx_vrf_id);
7232   mp->server_vrf_id = ntohl (server_vrf_id);
7233   if (v6_address_set)
7234     {
7235       mp->is_ipv6 = 1;
7236       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7237       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7238     }
7239   else
7240     {
7241       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7242       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7243     }
7244
7245   /* send it... */
7246   S;
7247
7248   /* Wait for a reply, return good/bad news  */
7249   W;
7250   /* NOTREACHED */
7251   return 0;
7252 }
7253
7254 static int
7255 api_dhcp_proxy_set_vss (vat_main_t * vam)
7256 {
7257   unformat_input_t *i = vam->input;
7258   vl_api_dhcp_proxy_set_vss_t *mp;
7259   f64 timeout;
7260   u8 is_ipv6 = 0;
7261   u8 is_add = 1;
7262   u32 tbl_id;
7263   u8 tbl_id_set = 0;
7264   u32 oui;
7265   u8 oui_set = 0;
7266   u32 fib_id;
7267   u8 fib_id_set = 0;
7268
7269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7270     {
7271       if (unformat (i, "tbl_id %d", &tbl_id))
7272         tbl_id_set = 1;
7273       if (unformat (i, "fib_id %d", &fib_id))
7274         fib_id_set = 1;
7275       if (unformat (i, "oui %d", &oui))
7276         oui_set = 1;
7277       else if (unformat (i, "ipv6"))
7278         is_ipv6 = 1;
7279       else if (unformat (i, "del"))
7280         is_add = 0;
7281       else
7282         {
7283           clib_warning ("parse error '%U'", format_unformat_error, i);
7284           return -99;
7285         }
7286     }
7287
7288   if (tbl_id_set == 0)
7289     {
7290       errmsg ("missing tbl id\n");
7291       return -99;
7292     }
7293
7294   if (fib_id_set == 0)
7295     {
7296       errmsg ("missing fib id\n");
7297       return -99;
7298     }
7299   if (oui_set == 0)
7300     {
7301       errmsg ("missing oui\n");
7302       return -99;
7303     }
7304
7305   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7306   mp->tbl_id = ntohl (tbl_id);
7307   mp->fib_id = ntohl (fib_id);
7308   mp->oui = ntohl (oui);
7309   mp->is_ipv6 = is_ipv6;
7310   mp->is_add = is_add;
7311
7312   S;
7313   W;
7314   /* NOTREACHED */
7315   return 0;
7316 }
7317
7318 static int
7319 api_dhcp_client_config (vat_main_t * vam)
7320 {
7321   unformat_input_t *i = vam->input;
7322   vl_api_dhcp_client_config_t *mp;
7323   f64 timeout;
7324   u32 sw_if_index;
7325   u8 sw_if_index_set = 0;
7326   u8 is_add = 1;
7327   u8 *hostname = 0;
7328   u8 disable_event = 0;
7329
7330   /* Parse args required to build the message */
7331   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7332     {
7333       if (unformat (i, "del"))
7334         is_add = 0;
7335       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7336         sw_if_index_set = 1;
7337       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7338         sw_if_index_set = 1;
7339       else if (unformat (i, "hostname %s", &hostname))
7340         ;
7341       else if (unformat (i, "disable_event"))
7342         disable_event = 1;
7343       else
7344         break;
7345     }
7346
7347   if (sw_if_index_set == 0)
7348     {
7349       errmsg ("missing interface name or sw_if_index\n");
7350       return -99;
7351     }
7352
7353   if (vec_len (hostname) > 63)
7354     {
7355       errmsg ("hostname too long\n");
7356     }
7357   vec_add1 (hostname, 0);
7358
7359   /* Construct the API message */
7360   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7361
7362   mp->sw_if_index = ntohl (sw_if_index);
7363   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7364   vec_free (hostname);
7365   mp->is_add = is_add;
7366   mp->want_dhcp_event = disable_event ? 0 : 1;
7367   mp->pid = getpid ();
7368
7369   /* send it... */
7370   S;
7371
7372   /* Wait for a reply, return good/bad news  */
7373   W;
7374   /* NOTREACHED */
7375   return 0;
7376 }
7377
7378 static int
7379 api_set_ip_flow_hash (vat_main_t * vam)
7380 {
7381   unformat_input_t *i = vam->input;
7382   vl_api_set_ip_flow_hash_t *mp;
7383   f64 timeout;
7384   u32 vrf_id = 0;
7385   u8 is_ipv6 = 0;
7386   u8 vrf_id_set = 0;
7387   u8 src = 0;
7388   u8 dst = 0;
7389   u8 sport = 0;
7390   u8 dport = 0;
7391   u8 proto = 0;
7392   u8 reverse = 0;
7393
7394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7395     {
7396       if (unformat (i, "vrf %d", &vrf_id))
7397         vrf_id_set = 1;
7398       else if (unformat (i, "ipv6"))
7399         is_ipv6 = 1;
7400       else if (unformat (i, "src"))
7401         src = 1;
7402       else if (unformat (i, "dst"))
7403         dst = 1;
7404       else if (unformat (i, "sport"))
7405         sport = 1;
7406       else if (unformat (i, "dport"))
7407         dport = 1;
7408       else if (unformat (i, "proto"))
7409         proto = 1;
7410       else if (unformat (i, "reverse"))
7411         reverse = 1;
7412
7413       else
7414         {
7415           clib_warning ("parse error '%U'", format_unformat_error, i);
7416           return -99;
7417         }
7418     }
7419
7420   if (vrf_id_set == 0)
7421     {
7422       errmsg ("missing vrf id\n");
7423       return -99;
7424     }
7425
7426   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7427   mp->src = src;
7428   mp->dst = dst;
7429   mp->sport = sport;
7430   mp->dport = dport;
7431   mp->proto = proto;
7432   mp->reverse = reverse;
7433   mp->vrf_id = ntohl (vrf_id);
7434   mp->is_ipv6 = is_ipv6;
7435
7436   S;
7437   W;
7438   /* NOTREACHED */
7439   return 0;
7440 }
7441
7442 static int
7443 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7444 {
7445   unformat_input_t *i = vam->input;
7446   vl_api_sw_interface_ip6_enable_disable_t *mp;
7447   f64 timeout;
7448   u32 sw_if_index;
7449   u8 sw_if_index_set = 0;
7450   u8 enable = 0;
7451
7452   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7453     {
7454       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7455         sw_if_index_set = 1;
7456       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7457         sw_if_index_set = 1;
7458       else if (unformat (i, "enable"))
7459         enable = 1;
7460       else if (unformat (i, "disable"))
7461         enable = 0;
7462       else
7463         {
7464           clib_warning ("parse error '%U'", format_unformat_error, i);
7465           return -99;
7466         }
7467     }
7468
7469   if (sw_if_index_set == 0)
7470     {
7471       errmsg ("missing interface name or sw_if_index\n");
7472       return -99;
7473     }
7474
7475   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7476
7477   mp->sw_if_index = ntohl (sw_if_index);
7478   mp->enable = enable;
7479
7480   S;
7481   W;
7482   /* NOTREACHED */
7483   return 0;
7484 }
7485
7486 static int
7487 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7488 {
7489   unformat_input_t *i = vam->input;
7490   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7491   f64 timeout;
7492   u32 sw_if_index;
7493   u8 sw_if_index_set = 0;
7494   u32 address_length = 0;
7495   u8 v6_address_set = 0;
7496   ip6_address_t v6address;
7497
7498   /* Parse args required to build the message */
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, "%U/%d",
7506                          unformat_ip6_address, &v6address, &address_length))
7507         v6_address_set = 1;
7508       else
7509         break;
7510     }
7511
7512   if (sw_if_index_set == 0)
7513     {
7514       errmsg ("missing interface name or sw_if_index\n");
7515       return -99;
7516     }
7517   if (!v6_address_set)
7518     {
7519       errmsg ("no address set\n");
7520       return -99;
7521     }
7522
7523   /* Construct the API message */
7524   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7525      sw_interface_ip6_set_link_local_address);
7526
7527   mp->sw_if_index = ntohl (sw_if_index);
7528   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7529   mp->address_length = address_length;
7530
7531   /* send it... */
7532   S;
7533
7534   /* Wait for a reply, return good/bad news  */
7535   W;
7536
7537   /* NOTREACHED */
7538   return 0;
7539 }
7540
7541
7542 static int
7543 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7544 {
7545   unformat_input_t *i = vam->input;
7546   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7547   f64 timeout;
7548   u32 sw_if_index;
7549   u8 sw_if_index_set = 0;
7550   u32 address_length = 0;
7551   u8 v6_address_set = 0;
7552   ip6_address_t v6address;
7553   u8 use_default = 0;
7554   u8 no_advertise = 0;
7555   u8 off_link = 0;
7556   u8 no_autoconfig = 0;
7557   u8 no_onlink = 0;
7558   u8 is_no = 0;
7559   u32 val_lifetime = 0;
7560   u32 pref_lifetime = 0;
7561
7562   /* Parse args required to build the message */
7563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7564     {
7565       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7566         sw_if_index_set = 1;
7567       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7568         sw_if_index_set = 1;
7569       else if (unformat (i, "%U/%d",
7570                          unformat_ip6_address, &v6address, &address_length))
7571         v6_address_set = 1;
7572       else if (unformat (i, "val_life %d", &val_lifetime))
7573         ;
7574       else if (unformat (i, "pref_life %d", &pref_lifetime))
7575         ;
7576       else if (unformat (i, "def"))
7577         use_default = 1;
7578       else if (unformat (i, "noadv"))
7579         no_advertise = 1;
7580       else if (unformat (i, "offl"))
7581         off_link = 1;
7582       else if (unformat (i, "noauto"))
7583         no_autoconfig = 1;
7584       else if (unformat (i, "nolink"))
7585         no_onlink = 1;
7586       else if (unformat (i, "isno"))
7587         is_no = 1;
7588       else
7589         {
7590           clib_warning ("parse error '%U'", format_unformat_error, i);
7591           return -99;
7592         }
7593     }
7594
7595   if (sw_if_index_set == 0)
7596     {
7597       errmsg ("missing interface name or sw_if_index\n");
7598       return -99;
7599     }
7600   if (!v6_address_set)
7601     {
7602       errmsg ("no address set\n");
7603       return -99;
7604     }
7605
7606   /* Construct the API message */
7607   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7608
7609   mp->sw_if_index = ntohl (sw_if_index);
7610   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7611   mp->address_length = address_length;
7612   mp->use_default = use_default;
7613   mp->no_advertise = no_advertise;
7614   mp->off_link = off_link;
7615   mp->no_autoconfig = no_autoconfig;
7616   mp->no_onlink = no_onlink;
7617   mp->is_no = is_no;
7618   mp->val_lifetime = ntohl (val_lifetime);
7619   mp->pref_lifetime = ntohl (pref_lifetime);
7620
7621   /* send it... */
7622   S;
7623
7624   /* Wait for a reply, return good/bad news  */
7625   W;
7626
7627   /* NOTREACHED */
7628   return 0;
7629 }
7630
7631 static int
7632 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7633 {
7634   unformat_input_t *i = vam->input;
7635   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7636   f64 timeout;
7637   u32 sw_if_index;
7638   u8 sw_if_index_set = 0;
7639   u8 suppress = 0;
7640   u8 managed = 0;
7641   u8 other = 0;
7642   u8 ll_option = 0;
7643   u8 send_unicast = 0;
7644   u8 cease = 0;
7645   u8 is_no = 0;
7646   u8 default_router = 0;
7647   u32 max_interval = 0;
7648   u32 min_interval = 0;
7649   u32 lifetime = 0;
7650   u32 initial_count = 0;
7651   u32 initial_interval = 0;
7652
7653
7654   /* Parse args required to build the message */
7655   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7656     {
7657       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7658         sw_if_index_set = 1;
7659       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7660         sw_if_index_set = 1;
7661       else if (unformat (i, "maxint %d", &max_interval))
7662         ;
7663       else if (unformat (i, "minint %d", &min_interval))
7664         ;
7665       else if (unformat (i, "life %d", &lifetime))
7666         ;
7667       else if (unformat (i, "count %d", &initial_count))
7668         ;
7669       else if (unformat (i, "interval %d", &initial_interval))
7670         ;
7671       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7672         suppress = 1;
7673       else if (unformat (i, "managed"))
7674         managed = 1;
7675       else if (unformat (i, "other"))
7676         other = 1;
7677       else if (unformat (i, "ll"))
7678         ll_option = 1;
7679       else if (unformat (i, "send"))
7680         send_unicast = 1;
7681       else if (unformat (i, "cease"))
7682         cease = 1;
7683       else if (unformat (i, "isno"))
7684         is_no = 1;
7685       else if (unformat (i, "def"))
7686         default_router = 1;
7687       else
7688         {
7689           clib_warning ("parse error '%U'", format_unformat_error, i);
7690           return -99;
7691         }
7692     }
7693
7694   if (sw_if_index_set == 0)
7695     {
7696       errmsg ("missing interface name or sw_if_index\n");
7697       return -99;
7698     }
7699
7700   /* Construct the API message */
7701   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7702
7703   mp->sw_if_index = ntohl (sw_if_index);
7704   mp->max_interval = ntohl (max_interval);
7705   mp->min_interval = ntohl (min_interval);
7706   mp->lifetime = ntohl (lifetime);
7707   mp->initial_count = ntohl (initial_count);
7708   mp->initial_interval = ntohl (initial_interval);
7709   mp->suppress = suppress;
7710   mp->managed = managed;
7711   mp->other = other;
7712   mp->ll_option = ll_option;
7713   mp->send_unicast = send_unicast;
7714   mp->cease = cease;
7715   mp->is_no = is_no;
7716   mp->default_router = default_router;
7717
7718   /* send it... */
7719   S;
7720
7721   /* Wait for a reply, return good/bad news  */
7722   W;
7723
7724   /* NOTREACHED */
7725   return 0;
7726 }
7727
7728 static int
7729 api_set_arp_neighbor_limit (vat_main_t * vam)
7730 {
7731   unformat_input_t *i = vam->input;
7732   vl_api_set_arp_neighbor_limit_t *mp;
7733   f64 timeout;
7734   u32 arp_nbr_limit;
7735   u8 limit_set = 0;
7736   u8 is_ipv6 = 0;
7737
7738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7739     {
7740       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7741         limit_set = 1;
7742       else if (unformat (i, "ipv6"))
7743         is_ipv6 = 1;
7744       else
7745         {
7746           clib_warning ("parse error '%U'", format_unformat_error, i);
7747           return -99;
7748         }
7749     }
7750
7751   if (limit_set == 0)
7752     {
7753       errmsg ("missing limit value\n");
7754       return -99;
7755     }
7756
7757   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7758
7759   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7760   mp->is_ipv6 = is_ipv6;
7761
7762   S;
7763   W;
7764   /* NOTREACHED */
7765   return 0;
7766 }
7767
7768 static int
7769 api_l2_patch_add_del (vat_main_t * vam)
7770 {
7771   unformat_input_t *i = vam->input;
7772   vl_api_l2_patch_add_del_t *mp;
7773   f64 timeout;
7774   u32 rx_sw_if_index;
7775   u8 rx_sw_if_index_set = 0;
7776   u32 tx_sw_if_index;
7777   u8 tx_sw_if_index_set = 0;
7778   u8 is_add = 1;
7779
7780   /* Parse args required to build the message */
7781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7782     {
7783       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7784         rx_sw_if_index_set = 1;
7785       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7786         tx_sw_if_index_set = 1;
7787       else if (unformat (i, "rx"))
7788         {
7789           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7790             {
7791               if (unformat (i, "%U", unformat_sw_if_index, vam,
7792                             &rx_sw_if_index))
7793                 rx_sw_if_index_set = 1;
7794             }
7795           else
7796             break;
7797         }
7798       else if (unformat (i, "tx"))
7799         {
7800           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7801             {
7802               if (unformat (i, "%U", unformat_sw_if_index, vam,
7803                             &tx_sw_if_index))
7804                 tx_sw_if_index_set = 1;
7805             }
7806           else
7807             break;
7808         }
7809       else if (unformat (i, "del"))
7810         is_add = 0;
7811       else
7812         break;
7813     }
7814
7815   if (rx_sw_if_index_set == 0)
7816     {
7817       errmsg ("missing rx interface name or rx_sw_if_index\n");
7818       return -99;
7819     }
7820
7821   if (tx_sw_if_index_set == 0)
7822     {
7823       errmsg ("missing tx interface name or tx_sw_if_index\n");
7824       return -99;
7825     }
7826
7827   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7828
7829   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7830   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7831   mp->is_add = is_add;
7832
7833   S;
7834   W;
7835   /* NOTREACHED */
7836   return 0;
7837 }
7838
7839 static int
7840 api_ioam_enable (vat_main_t * vam)
7841 {
7842   unformat_input_t *input = vam->input;
7843   vl_api_ioam_enable_t *mp;
7844   f64 timeout;
7845   u32 id = 0;
7846   int has_trace_option = 0;
7847   int has_pot_option = 0;
7848   int has_seqno_option = 0;
7849   int has_analyse_option = 0;
7850
7851   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7852     {
7853       if (unformat (input, "trace"))
7854         has_trace_option = 1;
7855       else if (unformat (input, "pot"))
7856         has_pot_option = 1;
7857       else if (unformat (input, "seqno"))
7858         has_seqno_option = 1;
7859       else if (unformat (input, "analyse"))
7860         has_analyse_option = 1;
7861       else
7862         break;
7863     }
7864   M (IOAM_ENABLE, ioam_enable);
7865   mp->id = htons (id);
7866   mp->seqno = has_seqno_option;
7867   mp->analyse = has_analyse_option;
7868   mp->pot_enable = has_pot_option;
7869   mp->trace_enable = has_trace_option;
7870
7871   S;
7872   W;
7873
7874   return (0);
7875
7876 }
7877
7878
7879 static int
7880 api_ioam_disable (vat_main_t * vam)
7881 {
7882   vl_api_ioam_disable_t *mp;
7883   f64 timeout;
7884
7885   M (IOAM_DISABLE, ioam_disable);
7886   S;
7887   W;
7888   return 0;
7889 }
7890
7891 static int
7892 api_sr_tunnel_add_del (vat_main_t * vam)
7893 {
7894   unformat_input_t *i = vam->input;
7895   vl_api_sr_tunnel_add_del_t *mp;
7896   f64 timeout;
7897   int is_del = 0;
7898   int pl_index;
7899   ip6_address_t src_address;
7900   int src_address_set = 0;
7901   ip6_address_t dst_address;
7902   u32 dst_mask_width;
7903   int dst_address_set = 0;
7904   u16 flags = 0;
7905   u32 rx_table_id = 0;
7906   u32 tx_table_id = 0;
7907   ip6_address_t *segments = 0;
7908   ip6_address_t *this_seg;
7909   ip6_address_t *tags = 0;
7910   ip6_address_t *this_tag;
7911   ip6_address_t next_address, tag;
7912   u8 *name = 0;
7913   u8 *policy_name = 0;
7914
7915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7916     {
7917       if (unformat (i, "del"))
7918         is_del = 1;
7919       else if (unformat (i, "name %s", &name))
7920         ;
7921       else if (unformat (i, "policy %s", &policy_name))
7922         ;
7923       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7924         ;
7925       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7926         ;
7927       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7928         src_address_set = 1;
7929       else if (unformat (i, "dst %U/%d",
7930                          unformat_ip6_address, &dst_address, &dst_mask_width))
7931         dst_address_set = 1;
7932       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7933         {
7934           vec_add2 (segments, this_seg, 1);
7935           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7936                        sizeof (*this_seg));
7937         }
7938       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7939         {
7940           vec_add2 (tags, this_tag, 1);
7941           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7942         }
7943       else if (unformat (i, "clean"))
7944         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7945       else if (unformat (i, "protected"))
7946         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7947       else if (unformat (i, "InPE %d", &pl_index))
7948         {
7949           if (pl_index <= 0 || pl_index > 4)
7950             {
7951             pl_index_range_error:
7952               errmsg ("pl index %d out of range\n", pl_index);
7953               return -99;
7954             }
7955           flags |=
7956             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7957         }
7958       else if (unformat (i, "EgPE %d", &pl_index))
7959         {
7960           if (pl_index <= 0 || pl_index > 4)
7961             goto pl_index_range_error;
7962           flags |=
7963             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7964         }
7965       else if (unformat (i, "OrgSrc %d", &pl_index))
7966         {
7967           if (pl_index <= 0 || pl_index > 4)
7968             goto pl_index_range_error;
7969           flags |=
7970             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7971         }
7972       else
7973         break;
7974     }
7975
7976   if (!src_address_set)
7977     {
7978       errmsg ("src address required\n");
7979       return -99;
7980     }
7981
7982   if (!dst_address_set)
7983     {
7984       errmsg ("dst address required\n");
7985       return -99;
7986     }
7987
7988   if (!segments)
7989     {
7990       errmsg ("at least one sr segment required\n");
7991       return -99;
7992     }
7993
7994   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7995       vec_len (segments) * sizeof (ip6_address_t)
7996       + vec_len (tags) * sizeof (ip6_address_t));
7997
7998   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7999   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8000   mp->dst_mask_width = dst_mask_width;
8001   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8002   mp->n_segments = vec_len (segments);
8003   mp->n_tags = vec_len (tags);
8004   mp->is_add = is_del == 0;
8005   clib_memcpy (mp->segs_and_tags, segments,
8006                vec_len (segments) * sizeof (ip6_address_t));
8007   clib_memcpy (mp->segs_and_tags +
8008                vec_len (segments) * sizeof (ip6_address_t), tags,
8009                vec_len (tags) * sizeof (ip6_address_t));
8010
8011   mp->outer_vrf_id = ntohl (rx_table_id);
8012   mp->inner_vrf_id = ntohl (tx_table_id);
8013   memcpy (mp->name, name, vec_len (name));
8014   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8015
8016   vec_free (segments);
8017   vec_free (tags);
8018
8019   S;
8020   W;
8021   /* NOTREACHED */
8022 }
8023
8024 static int
8025 api_sr_policy_add_del (vat_main_t * vam)
8026 {
8027   unformat_input_t *input = vam->input;
8028   vl_api_sr_policy_add_del_t *mp;
8029   f64 timeout;
8030   int is_del = 0;
8031   u8 *name = 0;
8032   u8 *tunnel_name = 0;
8033   u8 **tunnel_names = 0;
8034
8035   int name_set = 0;
8036   int tunnel_set = 0;
8037   int j = 0;
8038   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8039   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8040
8041   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8042     {
8043       if (unformat (input, "del"))
8044         is_del = 1;
8045       else if (unformat (input, "name %s", &name))
8046         name_set = 1;
8047       else if (unformat (input, "tunnel %s", &tunnel_name))
8048         {
8049           if (tunnel_name)
8050             {
8051               vec_add1 (tunnel_names, tunnel_name);
8052               /* For serializer:
8053                  - length = #bytes to store in serial vector
8054                  - +1 = byte to store that length
8055                */
8056               tunnel_names_length += (vec_len (tunnel_name) + 1);
8057               tunnel_set = 1;
8058               tunnel_name = 0;
8059             }
8060         }
8061       else
8062         break;
8063     }
8064
8065   if (!name_set)
8066     {
8067       errmsg ("policy name required\n");
8068       return -99;
8069     }
8070
8071   if ((!tunnel_set) && (!is_del))
8072     {
8073       errmsg ("tunnel name required\n");
8074       return -99;
8075     }
8076
8077   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8078
8079
8080
8081   mp->is_add = !is_del;
8082
8083   memcpy (mp->name, name, vec_len (name));
8084   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8085   u8 *serial_orig = 0;
8086   vec_validate (serial_orig, tunnel_names_length);
8087   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8088   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8089
8090   for (j = 0; j < vec_len (tunnel_names); j++)
8091     {
8092       tun_name_len = vec_len (tunnel_names[j]);
8093       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8094       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8095       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8096       serial_orig += tun_name_len;      // Advance past the copy
8097     }
8098   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8099
8100   vec_free (tunnel_names);
8101   vec_free (tunnel_name);
8102
8103   S;
8104   W;
8105   /* NOTREACHED */
8106 }
8107
8108 static int
8109 api_sr_multicast_map_add_del (vat_main_t * vam)
8110 {
8111   unformat_input_t *input = vam->input;
8112   vl_api_sr_multicast_map_add_del_t *mp;
8113   f64 timeout;
8114   int is_del = 0;
8115   ip6_address_t multicast_address;
8116   u8 *policy_name = 0;
8117   int multicast_address_set = 0;
8118
8119   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8120     {
8121       if (unformat (input, "del"))
8122         is_del = 1;
8123       else
8124         if (unformat
8125             (input, "address %U", unformat_ip6_address, &multicast_address))
8126         multicast_address_set = 1;
8127       else if (unformat (input, "sr-policy %s", &policy_name))
8128         ;
8129       else
8130         break;
8131     }
8132
8133   if (!is_del && !policy_name)
8134     {
8135       errmsg ("sr-policy name required\n");
8136       return -99;
8137     }
8138
8139
8140   if (!multicast_address_set)
8141     {
8142       errmsg ("address required\n");
8143       return -99;
8144     }
8145
8146   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8147
8148   mp->is_add = !is_del;
8149   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8150   clib_memcpy (mp->multicast_address, &multicast_address,
8151                sizeof (mp->multicast_address));
8152
8153
8154   vec_free (policy_name);
8155
8156   S;
8157   W;
8158   /* NOTREACHED */
8159 }
8160
8161
8162 #define foreach_tcp_proto_field                 \
8163 _(src_port)                                     \
8164 _(dst_port)
8165
8166 #define foreach_udp_proto_field                 \
8167 _(src_port)                                     \
8168 _(dst_port)
8169
8170 #define foreach_ip4_proto_field                 \
8171 _(src_address)                                  \
8172 _(dst_address)                                  \
8173 _(tos)                                          \
8174 _(length)                                       \
8175 _(fragment_id)                                  \
8176 _(ttl)                                          \
8177 _(protocol)                                     \
8178 _(checksum)
8179
8180 uword
8181 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8182 {
8183   u8 **maskp = va_arg (*args, u8 **);
8184   u8 *mask = 0;
8185   u8 found_something = 0;
8186   tcp_header_t *tcp;
8187
8188 #define _(a) u8 a=0;
8189   foreach_tcp_proto_field;
8190 #undef _
8191
8192   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8193     {
8194       if (0);
8195 #define _(a) else if (unformat (input, #a)) a=1;
8196       foreach_tcp_proto_field
8197 #undef _
8198         else
8199         break;
8200     }
8201
8202 #define _(a) found_something += a;
8203   foreach_tcp_proto_field;
8204 #undef _
8205
8206   if (found_something == 0)
8207     return 0;
8208
8209   vec_validate (mask, sizeof (*tcp) - 1);
8210
8211   tcp = (tcp_header_t *) mask;
8212
8213 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8214   foreach_tcp_proto_field;
8215 #undef _
8216
8217   *maskp = mask;
8218   return 1;
8219 }
8220
8221 uword
8222 unformat_udp_mask (unformat_input_t * input, va_list * args)
8223 {
8224   u8 **maskp = va_arg (*args, u8 **);
8225   u8 *mask = 0;
8226   u8 found_something = 0;
8227   udp_header_t *udp;
8228
8229 #define _(a) u8 a=0;
8230   foreach_udp_proto_field;
8231 #undef _
8232
8233   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8234     {
8235       if (0);
8236 #define _(a) else if (unformat (input, #a)) a=1;
8237       foreach_udp_proto_field
8238 #undef _
8239         else
8240         break;
8241     }
8242
8243 #define _(a) found_something += a;
8244   foreach_udp_proto_field;
8245 #undef _
8246
8247   if (found_something == 0)
8248     return 0;
8249
8250   vec_validate (mask, sizeof (*udp) - 1);
8251
8252   udp = (udp_header_t *) mask;
8253
8254 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8255   foreach_udp_proto_field;
8256 #undef _
8257
8258   *maskp = mask;
8259   return 1;
8260 }
8261
8262 typedef struct
8263 {
8264   u16 src_port, dst_port;
8265 } tcpudp_header_t;
8266
8267 uword
8268 unformat_l4_mask (unformat_input_t * input, va_list * args)
8269 {
8270   u8 **maskp = va_arg (*args, u8 **);
8271   u16 src_port = 0, dst_port = 0;
8272   tcpudp_header_t *tcpudp;
8273
8274   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8275     {
8276       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8277         return 1;
8278       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8279         return 1;
8280       else if (unformat (input, "src_port"))
8281         src_port = 0xFFFF;
8282       else if (unformat (input, "dst_port"))
8283         dst_port = 0xFFFF;
8284       else
8285         return 0;
8286     }
8287
8288   if (!src_port && !dst_port)
8289     return 0;
8290
8291   u8 *mask = 0;
8292   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8293
8294   tcpudp = (tcpudp_header_t *) mask;
8295   tcpudp->src_port = src_port;
8296   tcpudp->dst_port = dst_port;
8297
8298   *maskp = mask;
8299
8300   return 1;
8301 }
8302
8303 uword
8304 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8305 {
8306   u8 **maskp = va_arg (*args, u8 **);
8307   u8 *mask = 0;
8308   u8 found_something = 0;
8309   ip4_header_t *ip;
8310
8311 #define _(a) u8 a=0;
8312   foreach_ip4_proto_field;
8313 #undef _
8314   u8 version = 0;
8315   u8 hdr_length = 0;
8316
8317
8318   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8319     {
8320       if (unformat (input, "version"))
8321         version = 1;
8322       else if (unformat (input, "hdr_length"))
8323         hdr_length = 1;
8324       else if (unformat (input, "src"))
8325         src_address = 1;
8326       else if (unformat (input, "dst"))
8327         dst_address = 1;
8328       else if (unformat (input, "proto"))
8329         protocol = 1;
8330
8331 #define _(a) else if (unformat (input, #a)) a=1;
8332       foreach_ip4_proto_field
8333 #undef _
8334         else
8335         break;
8336     }
8337
8338 #define _(a) found_something += a;
8339   foreach_ip4_proto_field;
8340 #undef _
8341
8342   if (found_something == 0)
8343     return 0;
8344
8345   vec_validate (mask, sizeof (*ip) - 1);
8346
8347   ip = (ip4_header_t *) mask;
8348
8349 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8350   foreach_ip4_proto_field;
8351 #undef _
8352
8353   ip->ip_version_and_header_length = 0;
8354
8355   if (version)
8356     ip->ip_version_and_header_length |= 0xF0;
8357
8358   if (hdr_length)
8359     ip->ip_version_and_header_length |= 0x0F;
8360
8361   *maskp = mask;
8362   return 1;
8363 }
8364
8365 #define foreach_ip6_proto_field                 \
8366 _(src_address)                                  \
8367 _(dst_address)                                  \
8368 _(payload_length)                               \
8369 _(hop_limit)                                    \
8370 _(protocol)
8371
8372 uword
8373 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8374 {
8375   u8 **maskp = va_arg (*args, u8 **);
8376   u8 *mask = 0;
8377   u8 found_something = 0;
8378   ip6_header_t *ip;
8379   u32 ip_version_traffic_class_and_flow_label;
8380
8381 #define _(a) u8 a=0;
8382   foreach_ip6_proto_field;
8383 #undef _
8384   u8 version = 0;
8385   u8 traffic_class = 0;
8386   u8 flow_label = 0;
8387
8388   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8389     {
8390       if (unformat (input, "version"))
8391         version = 1;
8392       else if (unformat (input, "traffic-class"))
8393         traffic_class = 1;
8394       else if (unformat (input, "flow-label"))
8395         flow_label = 1;
8396       else if (unformat (input, "src"))
8397         src_address = 1;
8398       else if (unformat (input, "dst"))
8399         dst_address = 1;
8400       else if (unformat (input, "proto"))
8401         protocol = 1;
8402
8403 #define _(a) else if (unformat (input, #a)) a=1;
8404       foreach_ip6_proto_field
8405 #undef _
8406         else
8407         break;
8408     }
8409
8410 #define _(a) found_something += a;
8411   foreach_ip6_proto_field;
8412 #undef _
8413
8414   if (found_something == 0)
8415     return 0;
8416
8417   vec_validate (mask, sizeof (*ip) - 1);
8418
8419   ip = (ip6_header_t *) mask;
8420
8421 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8422   foreach_ip6_proto_field;
8423 #undef _
8424
8425   ip_version_traffic_class_and_flow_label = 0;
8426
8427   if (version)
8428     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8429
8430   if (traffic_class)
8431     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8432
8433   if (flow_label)
8434     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8435
8436   ip->ip_version_traffic_class_and_flow_label =
8437     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8438
8439   *maskp = mask;
8440   return 1;
8441 }
8442
8443 uword
8444 unformat_l3_mask (unformat_input_t * input, va_list * args)
8445 {
8446   u8 **maskp = va_arg (*args, u8 **);
8447
8448   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8449     {
8450       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8451         return 1;
8452       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8453         return 1;
8454       else
8455         break;
8456     }
8457   return 0;
8458 }
8459
8460 uword
8461 unformat_l2_mask (unformat_input_t * input, va_list * args)
8462 {
8463   u8 **maskp = va_arg (*args, u8 **);
8464   u8 *mask = 0;
8465   u8 src = 0;
8466   u8 dst = 0;
8467   u8 proto = 0;
8468   u8 tag1 = 0;
8469   u8 tag2 = 0;
8470   u8 ignore_tag1 = 0;
8471   u8 ignore_tag2 = 0;
8472   u8 cos1 = 0;
8473   u8 cos2 = 0;
8474   u8 dot1q = 0;
8475   u8 dot1ad = 0;
8476   int len = 14;
8477
8478   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8479     {
8480       if (unformat (input, "src"))
8481         src = 1;
8482       else if (unformat (input, "dst"))
8483         dst = 1;
8484       else if (unformat (input, "proto"))
8485         proto = 1;
8486       else if (unformat (input, "tag1"))
8487         tag1 = 1;
8488       else if (unformat (input, "tag2"))
8489         tag2 = 1;
8490       else if (unformat (input, "ignore-tag1"))
8491         ignore_tag1 = 1;
8492       else if (unformat (input, "ignore-tag2"))
8493         ignore_tag2 = 1;
8494       else if (unformat (input, "cos1"))
8495         cos1 = 1;
8496       else if (unformat (input, "cos2"))
8497         cos2 = 1;
8498       else if (unformat (input, "dot1q"))
8499         dot1q = 1;
8500       else if (unformat (input, "dot1ad"))
8501         dot1ad = 1;
8502       else
8503         break;
8504     }
8505   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8506        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8507     return 0;
8508
8509   if (tag1 || ignore_tag1 || cos1 || dot1q)
8510     len = 18;
8511   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8512     len = 22;
8513
8514   vec_validate (mask, len - 1);
8515
8516   if (dst)
8517     memset (mask, 0xff, 6);
8518
8519   if (src)
8520     memset (mask + 6, 0xff, 6);
8521
8522   if (tag2 || dot1ad)
8523     {
8524       /* inner vlan tag */
8525       if (tag2)
8526         {
8527           mask[19] = 0xff;
8528           mask[18] = 0x0f;
8529         }
8530       if (cos2)
8531         mask[18] |= 0xe0;
8532       if (proto)
8533         mask[21] = mask[20] = 0xff;
8534       if (tag1)
8535         {
8536           mask[15] = 0xff;
8537           mask[14] = 0x0f;
8538         }
8539       if (cos1)
8540         mask[14] |= 0xe0;
8541       *maskp = mask;
8542       return 1;
8543     }
8544   if (tag1 | dot1q)
8545     {
8546       if (tag1)
8547         {
8548           mask[15] = 0xff;
8549           mask[14] = 0x0f;
8550         }
8551       if (cos1)
8552         mask[14] |= 0xe0;
8553       if (proto)
8554         mask[16] = mask[17] = 0xff;
8555
8556       *maskp = mask;
8557       return 1;
8558     }
8559   if (cos2)
8560     mask[18] |= 0xe0;
8561   if (cos1)
8562     mask[14] |= 0xe0;
8563   if (proto)
8564     mask[12] = mask[13] = 0xff;
8565
8566   *maskp = mask;
8567   return 1;
8568 }
8569
8570 uword
8571 unformat_classify_mask (unformat_input_t * input, va_list * args)
8572 {
8573   u8 **maskp = va_arg (*args, u8 **);
8574   u32 *skipp = va_arg (*args, u32 *);
8575   u32 *matchp = va_arg (*args, u32 *);
8576   u32 match;
8577   u8 *mask = 0;
8578   u8 *l2 = 0;
8579   u8 *l3 = 0;
8580   u8 *l4 = 0;
8581   int i;
8582
8583   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8584     {
8585       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8586         ;
8587       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8588         ;
8589       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8590         ;
8591       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8592         ;
8593       else
8594         break;
8595     }
8596
8597   if (l4 && !l3)
8598     {
8599       vec_free (mask);
8600       vec_free (l2);
8601       vec_free (l4);
8602       return 0;
8603     }
8604
8605   if (mask || l2 || l3 || l4)
8606     {
8607       if (l2 || l3 || l4)
8608         {
8609           /* "With a free Ethernet header in every package" */
8610           if (l2 == 0)
8611             vec_validate (l2, 13);
8612           mask = l2;
8613           if (vec_len (l3))
8614             {
8615               vec_append (mask, l3);
8616               vec_free (l3);
8617             }
8618           if (vec_len (l4))
8619             {
8620               vec_append (mask, l4);
8621               vec_free (l4);
8622             }
8623         }
8624
8625       /* Scan forward looking for the first significant mask octet */
8626       for (i = 0; i < vec_len (mask); i++)
8627         if (mask[i])
8628           break;
8629
8630       /* compute (skip, match) params */
8631       *skipp = i / sizeof (u32x4);
8632       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8633
8634       /* Pad mask to an even multiple of the vector size */
8635       while (vec_len (mask) % sizeof (u32x4))
8636         vec_add1 (mask, 0);
8637
8638       match = vec_len (mask) / sizeof (u32x4);
8639
8640       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8641         {
8642           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8643           if (*tmp || *(tmp + 1))
8644             break;
8645           match--;
8646         }
8647       if (match == 0)
8648         clib_warning ("BUG: match 0");
8649
8650       _vec_len (mask) = match * sizeof (u32x4);
8651
8652       *matchp = match;
8653       *maskp = mask;
8654
8655       return 1;
8656     }
8657
8658   return 0;
8659 }
8660
8661 #define foreach_l2_next                         \
8662 _(drop, DROP)                                   \
8663 _(ethernet, ETHERNET_INPUT)                     \
8664 _(ip4, IP4_INPUT)                               \
8665 _(ip6, IP6_INPUT)
8666
8667 uword
8668 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8669 {
8670   u32 *miss_next_indexp = va_arg (*args, u32 *);
8671   u32 next_index = 0;
8672   u32 tmp;
8673
8674 #define _(n,N) \
8675   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8676   foreach_l2_next;
8677 #undef _
8678
8679   if (unformat (input, "%d", &tmp))
8680     {
8681       next_index = tmp;
8682       goto out;
8683     }
8684
8685   return 0;
8686
8687 out:
8688   *miss_next_indexp = next_index;
8689   return 1;
8690 }
8691
8692 #define foreach_ip_next                         \
8693 _(drop, DROP)                                   \
8694 _(local, LOCAL)                                 \
8695 _(rewrite, REWRITE)
8696
8697 uword
8698 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8699 {
8700   u32 *miss_next_indexp = va_arg (*args, u32 *);
8701   u32 next_index = 0;
8702   u32 tmp;
8703
8704 #define _(n,N) \
8705   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8706   foreach_ip_next;
8707 #undef _
8708
8709   if (unformat (input, "%d", &tmp))
8710     {
8711       next_index = tmp;
8712       goto out;
8713     }
8714
8715   return 0;
8716
8717 out:
8718   *miss_next_indexp = next_index;
8719   return 1;
8720 }
8721
8722 #define foreach_acl_next                        \
8723 _(deny, DENY)
8724
8725 uword
8726 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8727 {
8728   u32 *miss_next_indexp = va_arg (*args, u32 *);
8729   u32 next_index = 0;
8730   u32 tmp;
8731
8732 #define _(n,N) \
8733   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8734   foreach_acl_next;
8735 #undef _
8736
8737   if (unformat (input, "permit"))
8738     {
8739       next_index = ~0;
8740       goto out;
8741     }
8742   else if (unformat (input, "%d", &tmp))
8743     {
8744       next_index = tmp;
8745       goto out;
8746     }
8747
8748   return 0;
8749
8750 out:
8751   *miss_next_indexp = next_index;
8752   return 1;
8753 }
8754
8755 uword
8756 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8757 {
8758   u32 *r = va_arg (*args, u32 *);
8759
8760   if (unformat (input, "conform-color"))
8761     *r = POLICE_CONFORM;
8762   else if (unformat (input, "exceed-color"))
8763     *r = POLICE_EXCEED;
8764   else
8765     return 0;
8766
8767   return 1;
8768 }
8769
8770 static int
8771 api_classify_add_del_table (vat_main_t * vam)
8772 {
8773   unformat_input_t *i = vam->input;
8774   vl_api_classify_add_del_table_t *mp;
8775
8776   u32 nbuckets = 2;
8777   u32 skip = ~0;
8778   u32 match = ~0;
8779   int is_add = 1;
8780   u32 table_index = ~0;
8781   u32 next_table_index = ~0;
8782   u32 miss_next_index = ~0;
8783   u32 memory_size = 32 << 20;
8784   u8 *mask = 0;
8785   f64 timeout;
8786   u32 current_data_flag = 0;
8787   int current_data_offset = 0;
8788
8789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8790     {
8791       if (unformat (i, "del"))
8792         is_add = 0;
8793       else if (unformat (i, "buckets %d", &nbuckets))
8794         ;
8795       else if (unformat (i, "memory_size %d", &memory_size))
8796         ;
8797       else if (unformat (i, "skip %d", &skip))
8798         ;
8799       else if (unformat (i, "match %d", &match))
8800         ;
8801       else if (unformat (i, "table %d", &table_index))
8802         ;
8803       else if (unformat (i, "mask %U", unformat_classify_mask,
8804                          &mask, &skip, &match))
8805         ;
8806       else if (unformat (i, "next-table %d", &next_table_index))
8807         ;
8808       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8809                          &miss_next_index))
8810         ;
8811       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8812                          &miss_next_index))
8813         ;
8814       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8815                          &miss_next_index))
8816         ;
8817       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8818         ;
8819       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8820         ;
8821       else
8822         break;
8823     }
8824
8825   if (is_add && mask == 0)
8826     {
8827       errmsg ("Mask required\n");
8828       return -99;
8829     }
8830
8831   if (is_add && skip == ~0)
8832     {
8833       errmsg ("skip count required\n");
8834       return -99;
8835     }
8836
8837   if (is_add && match == ~0)
8838     {
8839       errmsg ("match count required\n");
8840       return -99;
8841     }
8842
8843   if (!is_add && table_index == ~0)
8844     {
8845       errmsg ("table index required for delete\n");
8846       return -99;
8847     }
8848
8849   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8850
8851   mp->is_add = is_add;
8852   mp->table_index = ntohl (table_index);
8853   mp->nbuckets = ntohl (nbuckets);
8854   mp->memory_size = ntohl (memory_size);
8855   mp->skip_n_vectors = ntohl (skip);
8856   mp->match_n_vectors = ntohl (match);
8857   mp->next_table_index = ntohl (next_table_index);
8858   mp->miss_next_index = ntohl (miss_next_index);
8859   mp->current_data_flag = ntohl (current_data_flag);
8860   mp->current_data_offset = ntohl (current_data_offset);
8861   clib_memcpy (mp->mask, mask, vec_len (mask));
8862
8863   vec_free (mask);
8864
8865   S;
8866   W;
8867   /* NOTREACHED */
8868 }
8869
8870 uword
8871 unformat_l4_match (unformat_input_t * input, va_list * args)
8872 {
8873   u8 **matchp = va_arg (*args, u8 **);
8874
8875   u8 *proto_header = 0;
8876   int src_port = 0;
8877   int dst_port = 0;
8878
8879   tcpudp_header_t h;
8880
8881   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8882     {
8883       if (unformat (input, "src_port %d", &src_port))
8884         ;
8885       else if (unformat (input, "dst_port %d", &dst_port))
8886         ;
8887       else
8888         return 0;
8889     }
8890
8891   h.src_port = clib_host_to_net_u16 (src_port);
8892   h.dst_port = clib_host_to_net_u16 (dst_port);
8893   vec_validate (proto_header, sizeof (h) - 1);
8894   memcpy (proto_header, &h, sizeof (h));
8895
8896   *matchp = proto_header;
8897
8898   return 1;
8899 }
8900
8901 uword
8902 unformat_ip4_match (unformat_input_t * input, va_list * args)
8903 {
8904   u8 **matchp = va_arg (*args, u8 **);
8905   u8 *match = 0;
8906   ip4_header_t *ip;
8907   int version = 0;
8908   u32 version_val;
8909   int hdr_length = 0;
8910   u32 hdr_length_val;
8911   int src = 0, dst = 0;
8912   ip4_address_t src_val, dst_val;
8913   int proto = 0;
8914   u32 proto_val;
8915   int tos = 0;
8916   u32 tos_val;
8917   int length = 0;
8918   u32 length_val;
8919   int fragment_id = 0;
8920   u32 fragment_id_val;
8921   int ttl = 0;
8922   int ttl_val;
8923   int checksum = 0;
8924   u32 checksum_val;
8925
8926   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8927     {
8928       if (unformat (input, "version %d", &version_val))
8929         version = 1;
8930       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8931         hdr_length = 1;
8932       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8933         src = 1;
8934       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8935         dst = 1;
8936       else if (unformat (input, "proto %d", &proto_val))
8937         proto = 1;
8938       else if (unformat (input, "tos %d", &tos_val))
8939         tos = 1;
8940       else if (unformat (input, "length %d", &length_val))
8941         length = 1;
8942       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8943         fragment_id = 1;
8944       else if (unformat (input, "ttl %d", &ttl_val))
8945         ttl = 1;
8946       else if (unformat (input, "checksum %d", &checksum_val))
8947         checksum = 1;
8948       else
8949         break;
8950     }
8951
8952   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8953       + ttl + checksum == 0)
8954     return 0;
8955
8956   /*
8957    * Aligned because we use the real comparison functions
8958    */
8959   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8960
8961   ip = (ip4_header_t *) match;
8962
8963   /* These are realistically matched in practice */
8964   if (src)
8965     ip->src_address.as_u32 = src_val.as_u32;
8966
8967   if (dst)
8968     ip->dst_address.as_u32 = dst_val.as_u32;
8969
8970   if (proto)
8971     ip->protocol = proto_val;
8972
8973
8974   /* These are not, but they're included for completeness */
8975   if (version)
8976     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8977
8978   if (hdr_length)
8979     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8980
8981   if (tos)
8982     ip->tos = tos_val;
8983
8984   if (length)
8985     ip->length = clib_host_to_net_u16 (length_val);
8986
8987   if (ttl)
8988     ip->ttl = ttl_val;
8989
8990   if (checksum)
8991     ip->checksum = clib_host_to_net_u16 (checksum_val);
8992
8993   *matchp = match;
8994   return 1;
8995 }
8996
8997 uword
8998 unformat_ip6_match (unformat_input_t * input, va_list * args)
8999 {
9000   u8 **matchp = va_arg (*args, u8 **);
9001   u8 *match = 0;
9002   ip6_header_t *ip;
9003   int version = 0;
9004   u32 version_val;
9005   u8 traffic_class = 0;
9006   u32 traffic_class_val = 0;
9007   u8 flow_label = 0;
9008   u8 flow_label_val;
9009   int src = 0, dst = 0;
9010   ip6_address_t src_val, dst_val;
9011   int proto = 0;
9012   u32 proto_val;
9013   int payload_length = 0;
9014   u32 payload_length_val;
9015   int hop_limit = 0;
9016   int hop_limit_val;
9017   u32 ip_version_traffic_class_and_flow_label;
9018
9019   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9020     {
9021       if (unformat (input, "version %d", &version_val))
9022         version = 1;
9023       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9024         traffic_class = 1;
9025       else if (unformat (input, "flow_label %d", &flow_label_val))
9026         flow_label = 1;
9027       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9028         src = 1;
9029       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9030         dst = 1;
9031       else if (unformat (input, "proto %d", &proto_val))
9032         proto = 1;
9033       else if (unformat (input, "payload_length %d", &payload_length_val))
9034         payload_length = 1;
9035       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9036         hop_limit = 1;
9037       else
9038         break;
9039     }
9040
9041   if (version + traffic_class + flow_label + src + dst + proto +
9042       payload_length + hop_limit == 0)
9043     return 0;
9044
9045   /*
9046    * Aligned because we use the real comparison functions
9047    */
9048   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9049
9050   ip = (ip6_header_t *) match;
9051
9052   if (src)
9053     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9054
9055   if (dst)
9056     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9057
9058   if (proto)
9059     ip->protocol = proto_val;
9060
9061   ip_version_traffic_class_and_flow_label = 0;
9062
9063   if (version)
9064     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9065
9066   if (traffic_class)
9067     ip_version_traffic_class_and_flow_label |=
9068       (traffic_class_val & 0xFF) << 20;
9069
9070   if (flow_label)
9071     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9072
9073   ip->ip_version_traffic_class_and_flow_label =
9074     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9075
9076   if (payload_length)
9077     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9078
9079   if (hop_limit)
9080     ip->hop_limit = hop_limit_val;
9081
9082   *matchp = match;
9083   return 1;
9084 }
9085
9086 uword
9087 unformat_l3_match (unformat_input_t * input, va_list * args)
9088 {
9089   u8 **matchp = va_arg (*args, u8 **);
9090
9091   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9092     {
9093       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9094         return 1;
9095       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9096         return 1;
9097       else
9098         break;
9099     }
9100   return 0;
9101 }
9102
9103 uword
9104 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9105 {
9106   u8 *tagp = va_arg (*args, u8 *);
9107   u32 tag;
9108
9109   if (unformat (input, "%d", &tag))
9110     {
9111       tagp[0] = (tag >> 8) & 0x0F;
9112       tagp[1] = tag & 0xFF;
9113       return 1;
9114     }
9115
9116   return 0;
9117 }
9118
9119 uword
9120 unformat_l2_match (unformat_input_t * input, va_list * args)
9121 {
9122   u8 **matchp = va_arg (*args, u8 **);
9123   u8 *match = 0;
9124   u8 src = 0;
9125   u8 src_val[6];
9126   u8 dst = 0;
9127   u8 dst_val[6];
9128   u8 proto = 0;
9129   u16 proto_val;
9130   u8 tag1 = 0;
9131   u8 tag1_val[2];
9132   u8 tag2 = 0;
9133   u8 tag2_val[2];
9134   int len = 14;
9135   u8 ignore_tag1 = 0;
9136   u8 ignore_tag2 = 0;
9137   u8 cos1 = 0;
9138   u8 cos2 = 0;
9139   u32 cos1_val = 0;
9140   u32 cos2_val = 0;
9141
9142   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9143     {
9144       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9145         src = 1;
9146       else
9147         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9148         dst = 1;
9149       else if (unformat (input, "proto %U",
9150                          unformat_ethernet_type_host_byte_order, &proto_val))
9151         proto = 1;
9152       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9153         tag1 = 1;
9154       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9155         tag2 = 1;
9156       else if (unformat (input, "ignore-tag1"))
9157         ignore_tag1 = 1;
9158       else if (unformat (input, "ignore-tag2"))
9159         ignore_tag2 = 1;
9160       else if (unformat (input, "cos1 %d", &cos1_val))
9161         cos1 = 1;
9162       else if (unformat (input, "cos2 %d", &cos2_val))
9163         cos2 = 1;
9164       else
9165         break;
9166     }
9167   if ((src + dst + proto + tag1 + tag2 +
9168        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9169     return 0;
9170
9171   if (tag1 || ignore_tag1 || cos1)
9172     len = 18;
9173   if (tag2 || ignore_tag2 || cos2)
9174     len = 22;
9175
9176   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9177
9178   if (dst)
9179     clib_memcpy (match, dst_val, 6);
9180
9181   if (src)
9182     clib_memcpy (match + 6, src_val, 6);
9183
9184   if (tag2)
9185     {
9186       /* inner vlan tag */
9187       match[19] = tag2_val[1];
9188       match[18] = tag2_val[0];
9189       if (cos2)
9190         match[18] |= (cos2_val & 0x7) << 5;
9191       if (proto)
9192         {
9193           match[21] = proto_val & 0xff;
9194           match[20] = proto_val >> 8;
9195         }
9196       if (tag1)
9197         {
9198           match[15] = tag1_val[1];
9199           match[14] = tag1_val[0];
9200         }
9201       if (cos1)
9202         match[14] |= (cos1_val & 0x7) << 5;
9203       *matchp = match;
9204       return 1;
9205     }
9206   if (tag1)
9207     {
9208       match[15] = tag1_val[1];
9209       match[14] = tag1_val[0];
9210       if (proto)
9211         {
9212           match[17] = proto_val & 0xff;
9213           match[16] = proto_val >> 8;
9214         }
9215       if (cos1)
9216         match[14] |= (cos1_val & 0x7) << 5;
9217
9218       *matchp = match;
9219       return 1;
9220     }
9221   if (cos2)
9222     match[18] |= (cos2_val & 0x7) << 5;
9223   if (cos1)
9224     match[14] |= (cos1_val & 0x7) << 5;
9225   if (proto)
9226     {
9227       match[13] = proto_val & 0xff;
9228       match[12] = proto_val >> 8;
9229     }
9230
9231   *matchp = match;
9232   return 1;
9233 }
9234
9235
9236 uword
9237 unformat_classify_match (unformat_input_t * input, va_list * args)
9238 {
9239   u8 **matchp = va_arg (*args, u8 **);
9240   u32 skip_n_vectors = va_arg (*args, u32);
9241   u32 match_n_vectors = va_arg (*args, u32);
9242
9243   u8 *match = 0;
9244   u8 *l2 = 0;
9245   u8 *l3 = 0;
9246   u8 *l4 = 0;
9247
9248   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9249     {
9250       if (unformat (input, "hex %U", unformat_hex_string, &match))
9251         ;
9252       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9253         ;
9254       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9255         ;
9256       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9257         ;
9258       else
9259         break;
9260     }
9261
9262   if (l4 && !l3)
9263     {
9264       vec_free (match);
9265       vec_free (l2);
9266       vec_free (l4);
9267       return 0;
9268     }
9269
9270   if (match || l2 || l3 || l4)
9271     {
9272       if (l2 || l3 || l4)
9273         {
9274           /* "Win a free Ethernet header in every packet" */
9275           if (l2 == 0)
9276             vec_validate_aligned (l2, 13, sizeof (u32x4));
9277           match = l2;
9278           if (vec_len (l3))
9279             {
9280               vec_append_aligned (match, l3, sizeof (u32x4));
9281               vec_free (l3);
9282             }
9283           if (vec_len (l4))
9284             {
9285               vec_append_aligned (match, l4, sizeof (u32x4));
9286               vec_free (l4);
9287             }
9288         }
9289
9290       /* Make sure the vector is big enough even if key is all 0's */
9291       vec_validate_aligned
9292         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9293          sizeof (u32x4));
9294
9295       /* Set size, include skipped vectors */
9296       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9297
9298       *matchp = match;
9299
9300       return 1;
9301     }
9302
9303   return 0;
9304 }
9305
9306 static int
9307 api_classify_add_del_session (vat_main_t * vam)
9308 {
9309   unformat_input_t *i = vam->input;
9310   vl_api_classify_add_del_session_t *mp;
9311   int is_add = 1;
9312   u32 table_index = ~0;
9313   u32 hit_next_index = ~0;
9314   u32 opaque_index = ~0;
9315   u8 *match = 0;
9316   i32 advance = 0;
9317   f64 timeout;
9318   u32 skip_n_vectors = 0;
9319   u32 match_n_vectors = 0;
9320   u32 action = 0;
9321   u32 metadata = 0;
9322
9323   /*
9324    * Warning: you have to supply skip_n and match_n
9325    * because the API client cant simply look at the classify
9326    * table object.
9327    */
9328
9329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9330     {
9331       if (unformat (i, "del"))
9332         is_add = 0;
9333       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9334                          &hit_next_index))
9335         ;
9336       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9337                          &hit_next_index))
9338         ;
9339       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9340                          &hit_next_index))
9341         ;
9342       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9343         ;
9344       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9345         ;
9346       else if (unformat (i, "opaque-index %d", &opaque_index))
9347         ;
9348       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9349         ;
9350       else if (unformat (i, "match_n %d", &match_n_vectors))
9351         ;
9352       else if (unformat (i, "match %U", unformat_classify_match,
9353                          &match, skip_n_vectors, match_n_vectors))
9354         ;
9355       else if (unformat (i, "advance %d", &advance))
9356         ;
9357       else if (unformat (i, "table-index %d", &table_index))
9358         ;
9359       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9360         action = 1;
9361       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9362         action = 2;
9363       else if (unformat (i, "action %d", &action))
9364         ;
9365       else if (unformat (i, "metadata %d", &metadata))
9366         ;
9367       else
9368         break;
9369     }
9370
9371   if (table_index == ~0)
9372     {
9373       errmsg ("Table index required\n");
9374       return -99;
9375     }
9376
9377   if (is_add && match == 0)
9378     {
9379       errmsg ("Match value required\n");
9380       return -99;
9381     }
9382
9383   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9384
9385   mp->is_add = is_add;
9386   mp->table_index = ntohl (table_index);
9387   mp->hit_next_index = ntohl (hit_next_index);
9388   mp->opaque_index = ntohl (opaque_index);
9389   mp->advance = ntohl (advance);
9390   mp->action = action;
9391   mp->metadata = ntohl (metadata);
9392   clib_memcpy (mp->match, match, vec_len (match));
9393   vec_free (match);
9394
9395   S;
9396   W;
9397   /* NOTREACHED */
9398 }
9399
9400 static int
9401 api_classify_set_interface_ip_table (vat_main_t * vam)
9402 {
9403   unformat_input_t *i = vam->input;
9404   vl_api_classify_set_interface_ip_table_t *mp;
9405   f64 timeout;
9406   u32 sw_if_index;
9407   int sw_if_index_set;
9408   u32 table_index = ~0;
9409   u8 is_ipv6 = 0;
9410
9411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9412     {
9413       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9414         sw_if_index_set = 1;
9415       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9416         sw_if_index_set = 1;
9417       else if (unformat (i, "table %d", &table_index))
9418         ;
9419       else
9420         {
9421           clib_warning ("parse error '%U'", format_unformat_error, i);
9422           return -99;
9423         }
9424     }
9425
9426   if (sw_if_index_set == 0)
9427     {
9428       errmsg ("missing interface name or sw_if_index\n");
9429       return -99;
9430     }
9431
9432
9433   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9434
9435   mp->sw_if_index = ntohl (sw_if_index);
9436   mp->table_index = ntohl (table_index);
9437   mp->is_ipv6 = is_ipv6;
9438
9439   S;
9440   W;
9441   /* NOTREACHED */
9442   return 0;
9443 }
9444
9445 static int
9446 api_classify_set_interface_l2_tables (vat_main_t * vam)
9447 {
9448   unformat_input_t *i = vam->input;
9449   vl_api_classify_set_interface_l2_tables_t *mp;
9450   f64 timeout;
9451   u32 sw_if_index;
9452   int sw_if_index_set;
9453   u32 ip4_table_index = ~0;
9454   u32 ip6_table_index = ~0;
9455   u32 other_table_index = ~0;
9456   u32 is_input = 1;
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, "ip4-table %d", &ip4_table_index))
9465         ;
9466       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9467         ;
9468       else if (unformat (i, "other-table %d", &other_table_index))
9469         ;
9470       else if (unformat (i, "is-input %d", &is_input))
9471         ;
9472       else
9473         {
9474           clib_warning ("parse error '%U'", format_unformat_error, i);
9475           return -99;
9476         }
9477     }
9478
9479   if (sw_if_index_set == 0)
9480     {
9481       errmsg ("missing interface name or sw_if_index\n");
9482       return -99;
9483     }
9484
9485
9486   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9487
9488   mp->sw_if_index = ntohl (sw_if_index);
9489   mp->ip4_table_index = ntohl (ip4_table_index);
9490   mp->ip6_table_index = ntohl (ip6_table_index);
9491   mp->other_table_index = ntohl (other_table_index);
9492   mp->is_input = (u8) is_input;
9493
9494   S;
9495   W;
9496   /* NOTREACHED */
9497   return 0;
9498 }
9499
9500 static int
9501 api_set_ipfix_exporter (vat_main_t * vam)
9502 {
9503   unformat_input_t *i = vam->input;
9504   vl_api_set_ipfix_exporter_t *mp;
9505   ip4_address_t collector_address;
9506   u8 collector_address_set = 0;
9507   u32 collector_port = ~0;
9508   ip4_address_t src_address;
9509   u8 src_address_set = 0;
9510   u32 vrf_id = ~0;
9511   u32 path_mtu = ~0;
9512   u32 template_interval = ~0;
9513   u8 udp_checksum = 0;
9514   f64 timeout;
9515
9516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9517     {
9518       if (unformat (i, "collector_address %U", unformat_ip4_address,
9519                     &collector_address))
9520         collector_address_set = 1;
9521       else if (unformat (i, "collector_port %d", &collector_port))
9522         ;
9523       else if (unformat (i, "src_address %U", unformat_ip4_address,
9524                          &src_address))
9525         src_address_set = 1;
9526       else if (unformat (i, "vrf_id %d", &vrf_id))
9527         ;
9528       else if (unformat (i, "path_mtu %d", &path_mtu))
9529         ;
9530       else if (unformat (i, "template_interval %d", &template_interval))
9531         ;
9532       else if (unformat (i, "udp_checksum"))
9533         udp_checksum = 1;
9534       else
9535         break;
9536     }
9537
9538   if (collector_address_set == 0)
9539     {
9540       errmsg ("collector_address required\n");
9541       return -99;
9542     }
9543
9544   if (src_address_set == 0)
9545     {
9546       errmsg ("src_address required\n");
9547       return -99;
9548     }
9549
9550   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9551
9552   memcpy (mp->collector_address, collector_address.data,
9553           sizeof (collector_address.data));
9554   mp->collector_port = htons ((u16) collector_port);
9555   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9556   mp->vrf_id = htonl (vrf_id);
9557   mp->path_mtu = htonl (path_mtu);
9558   mp->template_interval = htonl (template_interval);
9559   mp->udp_checksum = udp_checksum;
9560
9561   S;
9562   W;
9563   /* NOTREACHED */
9564 }
9565
9566 static int
9567 api_set_ipfix_classify_stream (vat_main_t * vam)
9568 {
9569   unformat_input_t *i = vam->input;
9570   vl_api_set_ipfix_classify_stream_t *mp;
9571   u32 domain_id = 0;
9572   u32 src_port = UDP_DST_PORT_ipfix;
9573   f64 timeout;
9574
9575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9576     {
9577       if (unformat (i, "domain %d", &domain_id))
9578         ;
9579       else if (unformat (i, "src_port %d", &src_port))
9580         ;
9581       else
9582         {
9583           errmsg ("unknown input `%U'", format_unformat_error, i);
9584           return -99;
9585         }
9586     }
9587
9588   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9589
9590   mp->domain_id = htonl (domain_id);
9591   mp->src_port = htons ((u16) src_port);
9592
9593   S;
9594   W;
9595   /* NOTREACHED */
9596 }
9597
9598 static int
9599 api_ipfix_classify_table_add_del (vat_main_t * vam)
9600 {
9601   unformat_input_t *i = vam->input;
9602   vl_api_ipfix_classify_table_add_del_t *mp;
9603   int is_add = -1;
9604   u32 classify_table_index = ~0;
9605   u8 ip_version = 0;
9606   u8 transport_protocol = 255;
9607   f64 timeout;
9608
9609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9610     {
9611       if (unformat (i, "add"))
9612         is_add = 1;
9613       else if (unformat (i, "del"))
9614         is_add = 0;
9615       else if (unformat (i, "table %d", &classify_table_index))
9616         ;
9617       else if (unformat (i, "ip4"))
9618         ip_version = 4;
9619       else if (unformat (i, "ip6"))
9620         ip_version = 6;
9621       else if (unformat (i, "tcp"))
9622         transport_protocol = 6;
9623       else if (unformat (i, "udp"))
9624         transport_protocol = 17;
9625       else
9626         {
9627           errmsg ("unknown input `%U'", format_unformat_error, i);
9628           return -99;
9629         }
9630     }
9631
9632   if (is_add == -1)
9633     {
9634       errmsg ("expecting: add|del");
9635       return -99;
9636     }
9637   if (classify_table_index == ~0)
9638     {
9639       errmsg ("classifier table not specified");
9640       return -99;
9641     }
9642   if (ip_version == 0)
9643     {
9644       errmsg ("IP version not specified");
9645       return -99;
9646     }
9647
9648   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9649
9650   mp->is_add = is_add;
9651   mp->table_id = htonl (classify_table_index);
9652   mp->ip_version = ip_version;
9653   mp->transport_protocol = transport_protocol;
9654
9655   S;
9656   W;
9657   /* NOTREACHED */
9658 }
9659
9660 static int
9661 api_get_node_index (vat_main_t * vam)
9662 {
9663   unformat_input_t *i = vam->input;
9664   vl_api_get_node_index_t *mp;
9665   f64 timeout;
9666   u8 *name = 0;
9667
9668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9669     {
9670       if (unformat (i, "node %s", &name))
9671         ;
9672       else
9673         break;
9674     }
9675   if (name == 0)
9676     {
9677       errmsg ("node name required\n");
9678       return -99;
9679     }
9680   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9681     {
9682       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9683       return -99;
9684     }
9685
9686   M (GET_NODE_INDEX, get_node_index);
9687   clib_memcpy (mp->node_name, name, vec_len (name));
9688   vec_free (name);
9689
9690   S;
9691   W;
9692   /* NOTREACHED */
9693   return 0;
9694 }
9695
9696 static int
9697 api_get_next_index (vat_main_t * vam)
9698 {
9699   unformat_input_t *i = vam->input;
9700   vl_api_get_next_index_t *mp;
9701   f64 timeout;
9702   u8 *node_name = 0, *next_node_name = 0;
9703
9704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9705     {
9706       if (unformat (i, "node-name %s", &node_name))
9707         ;
9708       else if (unformat (i, "next-node-name %s", &next_node_name))
9709         break;
9710     }
9711
9712   if (node_name == 0)
9713     {
9714       errmsg ("node name required\n");
9715       return -99;
9716     }
9717   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9718     {
9719       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9720       return -99;
9721     }
9722
9723   if (next_node_name == 0)
9724     {
9725       errmsg ("next node name required\n");
9726       return -99;
9727     }
9728   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9729     {
9730       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9731       return -99;
9732     }
9733
9734   M (GET_NEXT_INDEX, get_next_index);
9735   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9736   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9737   vec_free (node_name);
9738   vec_free (next_node_name);
9739
9740   S;
9741   W;
9742   /* NOTREACHED */
9743   return 0;
9744 }
9745
9746 static int
9747 api_add_node_next (vat_main_t * vam)
9748 {
9749   unformat_input_t *i = vam->input;
9750   vl_api_add_node_next_t *mp;
9751   f64 timeout;
9752   u8 *name = 0;
9753   u8 *next = 0;
9754
9755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9756     {
9757       if (unformat (i, "node %s", &name))
9758         ;
9759       else if (unformat (i, "next %s", &next))
9760         ;
9761       else
9762         break;
9763     }
9764   if (name == 0)
9765     {
9766       errmsg ("node name required\n");
9767       return -99;
9768     }
9769   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9770     {
9771       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9772       return -99;
9773     }
9774   if (next == 0)
9775     {
9776       errmsg ("next node required\n");
9777       return -99;
9778     }
9779   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9780     {
9781       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9782       return -99;
9783     }
9784
9785   M (ADD_NODE_NEXT, add_node_next);
9786   clib_memcpy (mp->node_name, name, vec_len (name));
9787   clib_memcpy (mp->next_name, next, vec_len (next));
9788   vec_free (name);
9789   vec_free (next);
9790
9791   S;
9792   W;
9793   /* NOTREACHED */
9794   return 0;
9795 }
9796
9797 static int
9798 api_l2tpv3_create_tunnel (vat_main_t * vam)
9799 {
9800   unformat_input_t *i = vam->input;
9801   ip6_address_t client_address, our_address;
9802   int client_address_set = 0;
9803   int our_address_set = 0;
9804   u32 local_session_id = 0;
9805   u32 remote_session_id = 0;
9806   u64 local_cookie = 0;
9807   u64 remote_cookie = 0;
9808   u8 l2_sublayer_present = 0;
9809   vl_api_l2tpv3_create_tunnel_t *mp;
9810   f64 timeout;
9811
9812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9813     {
9814       if (unformat (i, "client_address %U", unformat_ip6_address,
9815                     &client_address))
9816         client_address_set = 1;
9817       else if (unformat (i, "our_address %U", unformat_ip6_address,
9818                          &our_address))
9819         our_address_set = 1;
9820       else if (unformat (i, "local_session_id %d", &local_session_id))
9821         ;
9822       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9823         ;
9824       else if (unformat (i, "local_cookie %lld", &local_cookie))
9825         ;
9826       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9827         ;
9828       else if (unformat (i, "l2-sublayer-present"))
9829         l2_sublayer_present = 1;
9830       else
9831         break;
9832     }
9833
9834   if (client_address_set == 0)
9835     {
9836       errmsg ("client_address required\n");
9837       return -99;
9838     }
9839
9840   if (our_address_set == 0)
9841     {
9842       errmsg ("our_address required\n");
9843       return -99;
9844     }
9845
9846   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9847
9848   clib_memcpy (mp->client_address, client_address.as_u8,
9849                sizeof (mp->client_address));
9850
9851   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9852
9853   mp->local_session_id = ntohl (local_session_id);
9854   mp->remote_session_id = ntohl (remote_session_id);
9855   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9856   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9857   mp->l2_sublayer_present = l2_sublayer_present;
9858   mp->is_ipv6 = 1;
9859
9860   S;
9861   W;
9862   /* NOTREACHED */
9863   return 0;
9864 }
9865
9866 static int
9867 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9868 {
9869   unformat_input_t *i = vam->input;
9870   u32 sw_if_index;
9871   u8 sw_if_index_set = 0;
9872   u64 new_local_cookie = 0;
9873   u64 new_remote_cookie = 0;
9874   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9875   f64 timeout;
9876
9877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9878     {
9879       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9880         sw_if_index_set = 1;
9881       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9882         sw_if_index_set = 1;
9883       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9884         ;
9885       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9886         ;
9887       else
9888         break;
9889     }
9890
9891   if (sw_if_index_set == 0)
9892     {
9893       errmsg ("missing interface name or sw_if_index\n");
9894       return -99;
9895     }
9896
9897   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9898
9899   mp->sw_if_index = ntohl (sw_if_index);
9900   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9901   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9902
9903   S;
9904   W;
9905   /* NOTREACHED */
9906   return 0;
9907 }
9908
9909 static int
9910 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9911 {
9912   unformat_input_t *i = vam->input;
9913   vl_api_l2tpv3_interface_enable_disable_t *mp;
9914   f64 timeout;
9915   u32 sw_if_index;
9916   u8 sw_if_index_set = 0;
9917   u8 enable_disable = 1;
9918
9919   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9920     {
9921       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9922         sw_if_index_set = 1;
9923       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9924         sw_if_index_set = 1;
9925       else if (unformat (i, "enable"))
9926         enable_disable = 1;
9927       else if (unformat (i, "disable"))
9928         enable_disable = 0;
9929       else
9930         break;
9931     }
9932
9933   if (sw_if_index_set == 0)
9934     {
9935       errmsg ("missing interface name or sw_if_index\n");
9936       return -99;
9937     }
9938
9939   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9940
9941   mp->sw_if_index = ntohl (sw_if_index);
9942   mp->enable_disable = enable_disable;
9943
9944   S;
9945   W;
9946   /* NOTREACHED */
9947   return 0;
9948 }
9949
9950 static int
9951 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9952 {
9953   unformat_input_t *i = vam->input;
9954   vl_api_l2tpv3_set_lookup_key_t *mp;
9955   f64 timeout;
9956   u8 key = ~0;
9957
9958   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9959     {
9960       if (unformat (i, "lookup_v6_src"))
9961         key = L2T_LOOKUP_SRC_ADDRESS;
9962       else if (unformat (i, "lookup_v6_dst"))
9963         key = L2T_LOOKUP_DST_ADDRESS;
9964       else if (unformat (i, "lookup_session_id"))
9965         key = L2T_LOOKUP_SESSION_ID;
9966       else
9967         break;
9968     }
9969
9970   if (key == (u8) ~ 0)
9971     {
9972       errmsg ("l2tp session lookup key unset\n");
9973       return -99;
9974     }
9975
9976   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9977
9978   mp->key = key;
9979
9980   S;
9981   W;
9982   /* NOTREACHED */
9983   return 0;
9984 }
9985
9986 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9987   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9988 {
9989   vat_main_t *vam = &vat_main;
9990
9991   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9992            format_ip6_address, mp->our_address,
9993            format_ip6_address, mp->client_address,
9994            clib_net_to_host_u32 (mp->sw_if_index));
9995
9996   fformat (vam->ofp,
9997            "   local cookies %016llx %016llx remote cookie %016llx\n",
9998            clib_net_to_host_u64 (mp->local_cookie[0]),
9999            clib_net_to_host_u64 (mp->local_cookie[1]),
10000            clib_net_to_host_u64 (mp->remote_cookie));
10001
10002   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
10003            clib_net_to_host_u32 (mp->local_session_id),
10004            clib_net_to_host_u32 (mp->remote_session_id));
10005
10006   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
10007            mp->l2_sublayer_present ? "preset" : "absent");
10008
10009 }
10010
10011 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10012   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10013 {
10014   vat_main_t *vam = &vat_main;
10015   vat_json_node_t *node = NULL;
10016   struct in6_addr addr;
10017
10018   if (VAT_JSON_ARRAY != vam->json_tree.type)
10019     {
10020       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10021       vat_json_init_array (&vam->json_tree);
10022     }
10023   node = vat_json_array_add (&vam->json_tree);
10024
10025   vat_json_init_object (node);
10026
10027   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10028   vat_json_object_add_ip6 (node, "our_address", addr);
10029   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10030   vat_json_object_add_ip6 (node, "client_address", addr);
10031
10032   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10033   vat_json_init_array (lc);
10034   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10035   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10036   vat_json_object_add_uint (node, "remote_cookie",
10037                             clib_net_to_host_u64 (mp->remote_cookie));
10038
10039   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10040   vat_json_object_add_uint (node, "local_session_id",
10041                             clib_net_to_host_u32 (mp->local_session_id));
10042   vat_json_object_add_uint (node, "remote_session_id",
10043                             clib_net_to_host_u32 (mp->remote_session_id));
10044   vat_json_object_add_string_copy (node, "l2_sublayer",
10045                                    mp->l2_sublayer_present ? (u8 *) "present"
10046                                    : (u8 *) "absent");
10047 }
10048
10049 static int
10050 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10051 {
10052   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10053   f64 timeout;
10054
10055   /* Get list of l2tpv3-tunnel interfaces */
10056   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10057   S;
10058
10059   /* Use a control ping for synchronization */
10060   {
10061     vl_api_control_ping_t *mp;
10062     M (CONTROL_PING, control_ping);
10063     S;
10064   }
10065   W;
10066 }
10067
10068
10069 static void vl_api_sw_interface_tap_details_t_handler
10070   (vl_api_sw_interface_tap_details_t * mp)
10071 {
10072   vat_main_t *vam = &vat_main;
10073
10074   fformat (vam->ofp, "%-16s %d\n",
10075            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10076 }
10077
10078 static void vl_api_sw_interface_tap_details_t_handler_json
10079   (vl_api_sw_interface_tap_details_t * mp)
10080 {
10081   vat_main_t *vam = &vat_main;
10082   vat_json_node_t *node = NULL;
10083
10084   if (VAT_JSON_ARRAY != vam->json_tree.type)
10085     {
10086       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10087       vat_json_init_array (&vam->json_tree);
10088     }
10089   node = vat_json_array_add (&vam->json_tree);
10090
10091   vat_json_init_object (node);
10092   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10093   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10094 }
10095
10096 static int
10097 api_sw_interface_tap_dump (vat_main_t * vam)
10098 {
10099   vl_api_sw_interface_tap_dump_t *mp;
10100   f64 timeout;
10101
10102   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10103   /* Get list of tap interfaces */
10104   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10105   S;
10106
10107   /* Use a control ping for synchronization */
10108   {
10109     vl_api_control_ping_t *mp;
10110     M (CONTROL_PING, control_ping);
10111     S;
10112   }
10113   W;
10114 }
10115
10116 static uword unformat_vxlan_decap_next
10117   (unformat_input_t * input, va_list * args)
10118 {
10119   u32 *result = va_arg (*args, u32 *);
10120   u32 tmp;
10121
10122   if (unformat (input, "l2"))
10123     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10124   else if (unformat (input, "%d", &tmp))
10125     *result = tmp;
10126   else
10127     return 0;
10128   return 1;
10129 }
10130
10131 static int
10132 api_vxlan_add_del_tunnel (vat_main_t * vam)
10133 {
10134   unformat_input_t *line_input = vam->input;
10135   vl_api_vxlan_add_del_tunnel_t *mp;
10136   f64 timeout;
10137   ip46_address_t src, dst;
10138   u8 is_add = 1;
10139   u8 ipv4_set = 0, ipv6_set = 0;
10140   u8 src_set = 0;
10141   u8 dst_set = 0;
10142   u8 grp_set = 0;
10143   u32 mcast_sw_if_index = ~0;
10144   u32 encap_vrf_id = 0;
10145   u32 decap_next_index = ~0;
10146   u32 vni = 0;
10147
10148   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10149   memset (&src, 0, sizeof src);
10150   memset (&dst, 0, sizeof dst);
10151
10152   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10153     {
10154       if (unformat (line_input, "del"))
10155         is_add = 0;
10156       else
10157         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10158         {
10159           ipv4_set = 1;
10160           src_set = 1;
10161         }
10162       else
10163         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10164         {
10165           ipv4_set = 1;
10166           dst_set = 1;
10167         }
10168       else
10169         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10170         {
10171           ipv6_set = 1;
10172           src_set = 1;
10173         }
10174       else
10175         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10176         {
10177           ipv6_set = 1;
10178           dst_set = 1;
10179         }
10180       else if (unformat (line_input, "group %U %U",
10181                          unformat_ip4_address, &dst.ip4,
10182                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10183         {
10184           grp_set = dst_set = 1;
10185           ipv4_set = 1;
10186         }
10187       else if (unformat (line_input, "group %U",
10188                          unformat_ip4_address, &dst.ip4))
10189         {
10190           grp_set = dst_set = 1;
10191           ipv4_set = 1;
10192         }
10193       else if (unformat (line_input, "group %U %U",
10194                          unformat_ip6_address, &dst.ip6,
10195                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10196         {
10197           grp_set = dst_set = 1;
10198           ipv6_set = 1;
10199         }
10200       else if (unformat (line_input, "group %U",
10201                          unformat_ip6_address, &dst.ip6))
10202         {
10203           grp_set = dst_set = 1;
10204           ipv6_set = 1;
10205         }
10206       else
10207         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10208         ;
10209       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10210         ;
10211       else if (unformat (line_input, "decap-next %U",
10212                          unformat_vxlan_decap_next, &decap_next_index))
10213         ;
10214       else if (unformat (line_input, "vni %d", &vni))
10215         ;
10216       else
10217         {
10218           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10219           return -99;
10220         }
10221     }
10222
10223   if (src_set == 0)
10224     {
10225       errmsg ("tunnel src address not specified\n");
10226       return -99;
10227     }
10228   if (dst_set == 0)
10229     {
10230       errmsg ("tunnel dst address not specified\n");
10231       return -99;
10232     }
10233
10234   if (grp_set && !ip46_address_is_multicast (&dst))
10235     {
10236       errmsg ("tunnel group address not multicast\n");
10237       return -99;
10238     }
10239   if (grp_set && mcast_sw_if_index == ~0)
10240     {
10241       errmsg ("tunnel nonexistent multicast device\n");
10242       return -99;
10243     }
10244
10245
10246   if (ipv4_set && ipv6_set)
10247     {
10248       errmsg ("both IPv4 and IPv6 addresses specified");
10249       return -99;
10250     }
10251
10252   if ((vni == 0) || (vni >> 24))
10253     {
10254       errmsg ("vni not specified or out of range\n");
10255       return -99;
10256     }
10257
10258   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10259
10260   if (ipv6_set)
10261     {
10262       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10263       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10264     }
10265   else
10266     {
10267       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10268       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10269     }
10270   mp->encap_vrf_id = ntohl (encap_vrf_id);
10271   mp->decap_next_index = ntohl (decap_next_index);
10272   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10273   mp->vni = ntohl (vni);
10274   mp->is_add = is_add;
10275   mp->is_ipv6 = ipv6_set;
10276
10277   S;
10278   W;
10279   /* NOTREACHED */
10280   return 0;
10281 }
10282
10283 static void vl_api_vxlan_tunnel_details_t_handler
10284   (vl_api_vxlan_tunnel_details_t * mp)
10285 {
10286   vat_main_t *vam = &vat_main;
10287   ip46_address_t src, dst;
10288
10289   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10290   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10291
10292   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d\n",
10293            ntohl (mp->sw_if_index),
10294            format_ip46_address, &src, IP46_TYPE_ANY,
10295            format_ip46_address, &dst, IP46_TYPE_ANY,
10296            ntohl (mp->encap_vrf_id),
10297            ntohl (mp->decap_next_index), ntohl (mp->vni),
10298            ntohl (mp->mcast_sw_if_index));
10299 }
10300
10301 static void vl_api_vxlan_tunnel_details_t_handler_json
10302   (vl_api_vxlan_tunnel_details_t * mp)
10303 {
10304   vat_main_t *vam = &vat_main;
10305   vat_json_node_t *node = NULL;
10306
10307   if (VAT_JSON_ARRAY != vam->json_tree.type)
10308     {
10309       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10310       vat_json_init_array (&vam->json_tree);
10311     }
10312   node = vat_json_array_add (&vam->json_tree);
10313
10314   vat_json_init_object (node);
10315   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10316   if (mp->is_ipv6)
10317     {
10318       struct in6_addr ip6;
10319
10320       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10321       vat_json_object_add_ip6 (node, "src_address", ip6);
10322       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10323       vat_json_object_add_ip6 (node, "dst_address", ip6);
10324     }
10325   else
10326     {
10327       struct in_addr ip4;
10328
10329       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10330       vat_json_object_add_ip4 (node, "src_address", ip4);
10331       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10332       vat_json_object_add_ip4 (node, "dst_address", ip4);
10333     }
10334   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10335   vat_json_object_add_uint (node, "decap_next_index",
10336                             ntohl (mp->decap_next_index));
10337   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10338   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10339   vat_json_object_add_uint (node, "mcast_sw_if_index",
10340                             ntohl (mp->mcast_sw_if_index));
10341 }
10342
10343 static int
10344 api_vxlan_tunnel_dump (vat_main_t * vam)
10345 {
10346   unformat_input_t *i = vam->input;
10347   vl_api_vxlan_tunnel_dump_t *mp;
10348   f64 timeout;
10349   u32 sw_if_index;
10350   u8 sw_if_index_set = 0;
10351
10352   /* Parse args required to build the message */
10353   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10354     {
10355       if (unformat (i, "sw_if_index %d", &sw_if_index))
10356         sw_if_index_set = 1;
10357       else
10358         break;
10359     }
10360
10361   if (sw_if_index_set == 0)
10362     {
10363       sw_if_index = ~0;
10364     }
10365
10366   if (!vam->json_output)
10367     {
10368       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s\n",
10369                "sw_if_index", "src_address", "dst_address",
10370                "encap_vrf_id", "decap_next_index", "vni",
10371                "mcast_sw_if_index");
10372     }
10373
10374   /* Get list of vxlan-tunnel interfaces */
10375   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10376
10377   mp->sw_if_index = htonl (sw_if_index);
10378
10379   S;
10380
10381   /* Use a control ping for synchronization */
10382   {
10383     vl_api_control_ping_t *mp;
10384     M (CONTROL_PING, control_ping);
10385     S;
10386   }
10387   W;
10388 }
10389
10390 static int
10391 api_gre_add_del_tunnel (vat_main_t * vam)
10392 {
10393   unformat_input_t *line_input = vam->input;
10394   vl_api_gre_add_del_tunnel_t *mp;
10395   f64 timeout;
10396   ip4_address_t src4, dst4;
10397   u8 is_add = 1;
10398   u8 teb = 0;
10399   u8 src_set = 0;
10400   u8 dst_set = 0;
10401   u32 outer_fib_id = 0;
10402
10403   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10404     {
10405       if (unformat (line_input, "del"))
10406         is_add = 0;
10407       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10408         src_set = 1;
10409       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10410         dst_set = 1;
10411       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10412         ;
10413       else if (unformat (line_input, "teb"))
10414         teb = 1;
10415       else
10416         {
10417           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10418           return -99;
10419         }
10420     }
10421
10422   if (src_set == 0)
10423     {
10424       errmsg ("tunnel src address not specified\n");
10425       return -99;
10426     }
10427   if (dst_set == 0)
10428     {
10429       errmsg ("tunnel dst address not specified\n");
10430       return -99;
10431     }
10432
10433
10434   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10435
10436   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10437   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10438   mp->outer_fib_id = ntohl (outer_fib_id);
10439   mp->is_add = is_add;
10440   mp->teb = teb;
10441
10442   S;
10443   W;
10444   /* NOTREACHED */
10445   return 0;
10446 }
10447
10448 static void vl_api_gre_tunnel_details_t_handler
10449   (vl_api_gre_tunnel_details_t * mp)
10450 {
10451   vat_main_t *vam = &vat_main;
10452
10453   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10454            ntohl (mp->sw_if_index),
10455            format_ip4_address, &mp->src_address,
10456            format_ip4_address, &mp->dst_address,
10457            mp->teb, ntohl (mp->outer_fib_id));
10458 }
10459
10460 static void vl_api_gre_tunnel_details_t_handler_json
10461   (vl_api_gre_tunnel_details_t * mp)
10462 {
10463   vat_main_t *vam = &vat_main;
10464   vat_json_node_t *node = NULL;
10465   struct in_addr ip4;
10466
10467   if (VAT_JSON_ARRAY != vam->json_tree.type)
10468     {
10469       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10470       vat_json_init_array (&vam->json_tree);
10471     }
10472   node = vat_json_array_add (&vam->json_tree);
10473
10474   vat_json_init_object (node);
10475   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10476   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10477   vat_json_object_add_ip4 (node, "src_address", ip4);
10478   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10479   vat_json_object_add_ip4 (node, "dst_address", ip4);
10480   vat_json_object_add_uint (node, "teb", mp->teb);
10481   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10482 }
10483
10484 static int
10485 api_gre_tunnel_dump (vat_main_t * vam)
10486 {
10487   unformat_input_t *i = vam->input;
10488   vl_api_gre_tunnel_dump_t *mp;
10489   f64 timeout;
10490   u32 sw_if_index;
10491   u8 sw_if_index_set = 0;
10492
10493   /* Parse args required to build the message */
10494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10495     {
10496       if (unformat (i, "sw_if_index %d", &sw_if_index))
10497         sw_if_index_set = 1;
10498       else
10499         break;
10500     }
10501
10502   if (sw_if_index_set == 0)
10503     {
10504       sw_if_index = ~0;
10505     }
10506
10507   if (!vam->json_output)
10508     {
10509       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10510                "sw_if_index", "src_address", "dst_address", "teb",
10511                "outer_fib_id");
10512     }
10513
10514   /* Get list of gre-tunnel interfaces */
10515   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10516
10517   mp->sw_if_index = htonl (sw_if_index);
10518
10519   S;
10520
10521   /* Use a control ping for synchronization */
10522   {
10523     vl_api_control_ping_t *mp;
10524     M (CONTROL_PING, control_ping);
10525     S;
10526   }
10527   W;
10528 }
10529
10530 static int
10531 api_l2_fib_clear_table (vat_main_t * vam)
10532 {
10533 //  unformat_input_t * i = vam->input;
10534   vl_api_l2_fib_clear_table_t *mp;
10535   f64 timeout;
10536
10537   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10538
10539   S;
10540   W;
10541   /* NOTREACHED */
10542   return 0;
10543 }
10544
10545 static int
10546 api_l2_interface_efp_filter (vat_main_t * vam)
10547 {
10548   unformat_input_t *i = vam->input;
10549   vl_api_l2_interface_efp_filter_t *mp;
10550   f64 timeout;
10551   u32 sw_if_index;
10552   u8 enable = 1;
10553   u8 sw_if_index_set = 0;
10554
10555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10556     {
10557       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10558         sw_if_index_set = 1;
10559       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10560         sw_if_index_set = 1;
10561       else if (unformat (i, "enable"))
10562         enable = 1;
10563       else if (unformat (i, "disable"))
10564         enable = 0;
10565       else
10566         {
10567           clib_warning ("parse error '%U'", format_unformat_error, i);
10568           return -99;
10569         }
10570     }
10571
10572   if (sw_if_index_set == 0)
10573     {
10574       errmsg ("missing sw_if_index\n");
10575       return -99;
10576     }
10577
10578   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10579
10580   mp->sw_if_index = ntohl (sw_if_index);
10581   mp->enable_disable = enable;
10582
10583   S;
10584   W;
10585   /* NOTREACHED */
10586   return 0;
10587 }
10588
10589 #define foreach_vtr_op                          \
10590 _("disable",  L2_VTR_DISABLED)                  \
10591 _("push-1",  L2_VTR_PUSH_1)                     \
10592 _("push-2",  L2_VTR_PUSH_2)                     \
10593 _("pop-1",  L2_VTR_POP_1)                       \
10594 _("pop-2",  L2_VTR_POP_2)                       \
10595 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10596 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10597 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10598 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10599
10600 static int
10601 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10602 {
10603   unformat_input_t *i = vam->input;
10604   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10605   f64 timeout;
10606   u32 sw_if_index;
10607   u8 sw_if_index_set = 0;
10608   u8 vtr_op_set = 0;
10609   u32 vtr_op = 0;
10610   u32 push_dot1q = 1;
10611   u32 tag1 = ~0;
10612   u32 tag2 = ~0;
10613
10614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10615     {
10616       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10617         sw_if_index_set = 1;
10618       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10619         sw_if_index_set = 1;
10620       else if (unformat (i, "vtr_op %d", &vtr_op))
10621         vtr_op_set = 1;
10622 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10623       foreach_vtr_op
10624 #undef _
10625         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10626         ;
10627       else if (unformat (i, "tag1 %d", &tag1))
10628         ;
10629       else if (unformat (i, "tag2 %d", &tag2))
10630         ;
10631       else
10632         {
10633           clib_warning ("parse error '%U'", format_unformat_error, i);
10634           return -99;
10635         }
10636     }
10637
10638   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10639     {
10640       errmsg ("missing vtr operation or sw_if_index\n");
10641       return -99;
10642     }
10643
10644   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10645     mp->sw_if_index = ntohl (sw_if_index);
10646   mp->vtr_op = ntohl (vtr_op);
10647   mp->push_dot1q = ntohl (push_dot1q);
10648   mp->tag1 = ntohl (tag1);
10649   mp->tag2 = ntohl (tag2);
10650
10651   S;
10652   W;
10653   /* NOTREACHED */
10654   return 0;
10655 }
10656
10657 static int
10658 api_create_vhost_user_if (vat_main_t * vam)
10659 {
10660   unformat_input_t *i = vam->input;
10661   vl_api_create_vhost_user_if_t *mp;
10662   f64 timeout;
10663   u8 *file_name;
10664   u8 is_server = 0;
10665   u8 file_name_set = 0;
10666   u32 custom_dev_instance = ~0;
10667   u8 hwaddr[6];
10668   u8 use_custom_mac = 0;
10669
10670   /* Shut up coverity */
10671   memset (hwaddr, 0, sizeof (hwaddr));
10672
10673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10674     {
10675       if (unformat (i, "socket %s", &file_name))
10676         {
10677           file_name_set = 1;
10678         }
10679       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10680         ;
10681       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10682         use_custom_mac = 1;
10683       else if (unformat (i, "server"))
10684         is_server = 1;
10685       else
10686         break;
10687     }
10688
10689   if (file_name_set == 0)
10690     {
10691       errmsg ("missing socket file name\n");
10692       return -99;
10693     }
10694
10695   if (vec_len (file_name) > 255)
10696     {
10697       errmsg ("socket file name too long\n");
10698       return -99;
10699     }
10700   vec_add1 (file_name, 0);
10701
10702   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10703
10704   mp->is_server = is_server;
10705   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10706   vec_free (file_name);
10707   if (custom_dev_instance != ~0)
10708     {
10709       mp->renumber = 1;
10710       mp->custom_dev_instance = ntohl (custom_dev_instance);
10711     }
10712   mp->use_custom_mac = use_custom_mac;
10713   clib_memcpy (mp->mac_address, hwaddr, 6);
10714
10715   S;
10716   W;
10717   /* NOTREACHED */
10718   return 0;
10719 }
10720
10721 static int
10722 api_modify_vhost_user_if (vat_main_t * vam)
10723 {
10724   unformat_input_t *i = vam->input;
10725   vl_api_modify_vhost_user_if_t *mp;
10726   f64 timeout;
10727   u8 *file_name;
10728   u8 is_server = 0;
10729   u8 file_name_set = 0;
10730   u32 custom_dev_instance = ~0;
10731   u8 sw_if_index_set = 0;
10732   u32 sw_if_index = (u32) ~ 0;
10733
10734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10735     {
10736       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10737         sw_if_index_set = 1;
10738       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10739         sw_if_index_set = 1;
10740       else if (unformat (i, "socket %s", &file_name))
10741         {
10742           file_name_set = 1;
10743         }
10744       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10745         ;
10746       else if (unformat (i, "server"))
10747         is_server = 1;
10748       else
10749         break;
10750     }
10751
10752   if (sw_if_index_set == 0)
10753     {
10754       errmsg ("missing sw_if_index or interface name\n");
10755       return -99;
10756     }
10757
10758   if (file_name_set == 0)
10759     {
10760       errmsg ("missing socket file name\n");
10761       return -99;
10762     }
10763
10764   if (vec_len (file_name) > 255)
10765     {
10766       errmsg ("socket file name too long\n");
10767       return -99;
10768     }
10769   vec_add1 (file_name, 0);
10770
10771   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10772
10773   mp->sw_if_index = ntohl (sw_if_index);
10774   mp->is_server = is_server;
10775   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10776   vec_free (file_name);
10777   if (custom_dev_instance != ~0)
10778     {
10779       mp->renumber = 1;
10780       mp->custom_dev_instance = ntohl (custom_dev_instance);
10781     }
10782
10783   S;
10784   W;
10785   /* NOTREACHED */
10786   return 0;
10787 }
10788
10789 static int
10790 api_delete_vhost_user_if (vat_main_t * vam)
10791 {
10792   unformat_input_t *i = vam->input;
10793   vl_api_delete_vhost_user_if_t *mp;
10794   f64 timeout;
10795   u32 sw_if_index = ~0;
10796   u8 sw_if_index_set = 0;
10797
10798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10799     {
10800       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10801         sw_if_index_set = 1;
10802       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10803         sw_if_index_set = 1;
10804       else
10805         break;
10806     }
10807
10808   if (sw_if_index_set == 0)
10809     {
10810       errmsg ("missing sw_if_index or interface name\n");
10811       return -99;
10812     }
10813
10814
10815   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10816
10817   mp->sw_if_index = ntohl (sw_if_index);
10818
10819   S;
10820   W;
10821   /* NOTREACHED */
10822   return 0;
10823 }
10824
10825 static void vl_api_sw_interface_vhost_user_details_t_handler
10826   (vl_api_sw_interface_vhost_user_details_t * mp)
10827 {
10828   vat_main_t *vam = &vat_main;
10829
10830   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10831            (char *) mp->interface_name,
10832            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10833            clib_net_to_host_u64 (mp->features), mp->is_server,
10834            ntohl (mp->num_regions), (char *) mp->sock_filename);
10835   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10836 }
10837
10838 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10839   (vl_api_sw_interface_vhost_user_details_t * mp)
10840 {
10841   vat_main_t *vam = &vat_main;
10842   vat_json_node_t *node = NULL;
10843
10844   if (VAT_JSON_ARRAY != vam->json_tree.type)
10845     {
10846       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10847       vat_json_init_array (&vam->json_tree);
10848     }
10849   node = vat_json_array_add (&vam->json_tree);
10850
10851   vat_json_init_object (node);
10852   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10853   vat_json_object_add_string_copy (node, "interface_name",
10854                                    mp->interface_name);
10855   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10856                             ntohl (mp->virtio_net_hdr_sz));
10857   vat_json_object_add_uint (node, "features",
10858                             clib_net_to_host_u64 (mp->features));
10859   vat_json_object_add_uint (node, "is_server", mp->is_server);
10860   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10861   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10862   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10863 }
10864
10865 static int
10866 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10867 {
10868   vl_api_sw_interface_vhost_user_dump_t *mp;
10869   f64 timeout;
10870   fformat (vam->ofp,
10871            "Interface name           idx hdr_sz features server regions filename\n");
10872
10873   /* Get list of vhost-user interfaces */
10874   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10875   S;
10876
10877   /* Use a control ping for synchronization */
10878   {
10879     vl_api_control_ping_t *mp;
10880     M (CONTROL_PING, control_ping);
10881     S;
10882   }
10883   W;
10884 }
10885
10886 static int
10887 api_show_version (vat_main_t * vam)
10888 {
10889   vl_api_show_version_t *mp;
10890   f64 timeout;
10891
10892   M (SHOW_VERSION, show_version);
10893
10894   S;
10895   W;
10896   /* NOTREACHED */
10897   return 0;
10898 }
10899
10900
10901 static int
10902 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10903 {
10904   unformat_input_t *line_input = vam->input;
10905   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10906   f64 timeout;
10907   ip4_address_t local4, remote4;
10908   ip6_address_t local6, remote6;
10909   u8 is_add = 1;
10910   u8 ipv4_set = 0, ipv6_set = 0;
10911   u8 local_set = 0;
10912   u8 remote_set = 0;
10913   u32 encap_vrf_id = 0;
10914   u32 decap_vrf_id = 0;
10915   u8 protocol = ~0;
10916   u32 vni;
10917   u8 vni_set = 0;
10918
10919   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10920     {
10921       if (unformat (line_input, "del"))
10922         is_add = 0;
10923       else if (unformat (line_input, "local %U",
10924                          unformat_ip4_address, &local4))
10925         {
10926           local_set = 1;
10927           ipv4_set = 1;
10928         }
10929       else if (unformat (line_input, "remote %U",
10930                          unformat_ip4_address, &remote4))
10931         {
10932           remote_set = 1;
10933           ipv4_set = 1;
10934         }
10935       else if (unformat (line_input, "local %U",
10936                          unformat_ip6_address, &local6))
10937         {
10938           local_set = 1;
10939           ipv6_set = 1;
10940         }
10941       else if (unformat (line_input, "remote %U",
10942                          unformat_ip6_address, &remote6))
10943         {
10944           remote_set = 1;
10945           ipv6_set = 1;
10946         }
10947       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10948         ;
10949       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10950         ;
10951       else if (unformat (line_input, "vni %d", &vni))
10952         vni_set = 1;
10953       else if (unformat (line_input, "next-ip4"))
10954         protocol = 1;
10955       else if (unformat (line_input, "next-ip6"))
10956         protocol = 2;
10957       else if (unformat (line_input, "next-ethernet"))
10958         protocol = 3;
10959       else if (unformat (line_input, "next-nsh"))
10960         protocol = 4;
10961       else
10962         {
10963           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10964           return -99;
10965         }
10966     }
10967
10968   if (local_set == 0)
10969     {
10970       errmsg ("tunnel local address not specified\n");
10971       return -99;
10972     }
10973   if (remote_set == 0)
10974     {
10975       errmsg ("tunnel remote address not specified\n");
10976       return -99;
10977     }
10978   if (ipv4_set && ipv6_set)
10979     {
10980       errmsg ("both IPv4 and IPv6 addresses specified");
10981       return -99;
10982     }
10983
10984   if (vni_set == 0)
10985     {
10986       errmsg ("vni not specified\n");
10987       return -99;
10988     }
10989
10990   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10991
10992
10993   if (ipv6_set)
10994     {
10995       clib_memcpy (&mp->local, &local6, sizeof (local6));
10996       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10997     }
10998   else
10999     {
11000       clib_memcpy (&mp->local, &local4, sizeof (local4));
11001       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11002     }
11003
11004   mp->encap_vrf_id = ntohl (encap_vrf_id);
11005   mp->decap_vrf_id = ntohl (decap_vrf_id);
11006   mp->protocol = ntohl (protocol);
11007   mp->vni = ntohl (vni);
11008   mp->is_add = is_add;
11009   mp->is_ipv6 = ipv6_set;
11010
11011   S;
11012   W;
11013   /* NOTREACHED */
11014   return 0;
11015 }
11016
11017 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11018   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11019 {
11020   vat_main_t *vam = &vat_main;
11021
11022   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
11023            ntohl (mp->sw_if_index),
11024            format_ip46_address, &(mp->local[0]),
11025            format_ip46_address, &(mp->remote[0]),
11026            ntohl (mp->vni),
11027            ntohl (mp->protocol),
11028            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11029 }
11030
11031 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11032   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11033 {
11034   vat_main_t *vam = &vat_main;
11035   vat_json_node_t *node = NULL;
11036   struct in_addr ip4;
11037   struct in6_addr ip6;
11038
11039   if (VAT_JSON_ARRAY != vam->json_tree.type)
11040     {
11041       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11042       vat_json_init_array (&vam->json_tree);
11043     }
11044   node = vat_json_array_add (&vam->json_tree);
11045
11046   vat_json_init_object (node);
11047   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11048   if (mp->is_ipv6)
11049     {
11050       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11051       vat_json_object_add_ip6 (node, "local", ip6);
11052       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11053       vat_json_object_add_ip6 (node, "remote", ip6);
11054     }
11055   else
11056     {
11057       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11058       vat_json_object_add_ip4 (node, "local", ip4);
11059       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11060       vat_json_object_add_ip4 (node, "remote", ip4);
11061     }
11062   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11063   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11064   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11065   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11066   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11067 }
11068
11069 static int
11070 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11071 {
11072   unformat_input_t *i = vam->input;
11073   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11074   f64 timeout;
11075   u32 sw_if_index;
11076   u8 sw_if_index_set = 0;
11077
11078   /* Parse args required to build the message */
11079   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11080     {
11081       if (unformat (i, "sw_if_index %d", &sw_if_index))
11082         sw_if_index_set = 1;
11083       else
11084         break;
11085     }
11086
11087   if (sw_if_index_set == 0)
11088     {
11089       sw_if_index = ~0;
11090     }
11091
11092   if (!vam->json_output)
11093     {
11094       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
11095                "sw_if_index", "local", "remote", "vni",
11096                "protocol", "encap_vrf_id", "decap_vrf_id");
11097     }
11098
11099   /* Get list of vxlan-tunnel interfaces */
11100   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11101
11102   mp->sw_if_index = htonl (sw_if_index);
11103
11104   S;
11105
11106   /* Use a control ping for synchronization */
11107   {
11108     vl_api_control_ping_t *mp;
11109     M (CONTROL_PING, control_ping);
11110     S;
11111   }
11112   W;
11113 }
11114
11115 u8 *
11116 format_l2_fib_mac_address (u8 * s, va_list * args)
11117 {
11118   u8 *a = va_arg (*args, u8 *);
11119
11120   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11121                  a[2], a[3], a[4], a[5], a[6], a[7]);
11122 }
11123
11124 static void vl_api_l2_fib_table_entry_t_handler
11125   (vl_api_l2_fib_table_entry_t * mp)
11126 {
11127   vat_main_t *vam = &vat_main;
11128
11129   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11130            "       %d       %d     %d\n",
11131            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11132            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11133            mp->bvi_mac);
11134 }
11135
11136 static void vl_api_l2_fib_table_entry_t_handler_json
11137   (vl_api_l2_fib_table_entry_t * mp)
11138 {
11139   vat_main_t *vam = &vat_main;
11140   vat_json_node_t *node = NULL;
11141
11142   if (VAT_JSON_ARRAY != vam->json_tree.type)
11143     {
11144       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11145       vat_json_init_array (&vam->json_tree);
11146     }
11147   node = vat_json_array_add (&vam->json_tree);
11148
11149   vat_json_init_object (node);
11150   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11151   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11152   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11153   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11154   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11155   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11156 }
11157
11158 static int
11159 api_l2_fib_table_dump (vat_main_t * vam)
11160 {
11161   unformat_input_t *i = vam->input;
11162   vl_api_l2_fib_table_dump_t *mp;
11163   f64 timeout;
11164   u32 bd_id;
11165   u8 bd_id_set = 0;
11166
11167   /* Parse args required to build the message */
11168   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11169     {
11170       if (unformat (i, "bd_id %d", &bd_id))
11171         bd_id_set = 1;
11172       else
11173         break;
11174     }
11175
11176   if (bd_id_set == 0)
11177     {
11178       errmsg ("missing bridge domain\n");
11179       return -99;
11180     }
11181
11182   fformat (vam->ofp,
11183            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11184
11185   /* Get list of l2 fib entries */
11186   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11187
11188   mp->bd_id = ntohl (bd_id);
11189   S;
11190
11191   /* Use a control ping for synchronization */
11192   {
11193     vl_api_control_ping_t *mp;
11194     M (CONTROL_PING, control_ping);
11195     S;
11196   }
11197   W;
11198 }
11199
11200
11201 static int
11202 api_interface_name_renumber (vat_main_t * vam)
11203 {
11204   unformat_input_t *line_input = vam->input;
11205   vl_api_interface_name_renumber_t *mp;
11206   u32 sw_if_index = ~0;
11207   f64 timeout;
11208   u32 new_show_dev_instance = ~0;
11209
11210   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11211     {
11212       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11213                     &sw_if_index))
11214         ;
11215       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11216         ;
11217       else if (unformat (line_input, "new_show_dev_instance %d",
11218                          &new_show_dev_instance))
11219         ;
11220       else
11221         break;
11222     }
11223
11224   if (sw_if_index == ~0)
11225     {
11226       errmsg ("missing interface name or sw_if_index\n");
11227       return -99;
11228     }
11229
11230   if (new_show_dev_instance == ~0)
11231     {
11232       errmsg ("missing new_show_dev_instance\n");
11233       return -99;
11234     }
11235
11236   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11237
11238   mp->sw_if_index = ntohl (sw_if_index);
11239   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11240
11241   S;
11242   W;
11243 }
11244
11245 static int
11246 api_want_ip4_arp_events (vat_main_t * vam)
11247 {
11248   unformat_input_t *line_input = vam->input;
11249   vl_api_want_ip4_arp_events_t *mp;
11250   f64 timeout;
11251   ip4_address_t address;
11252   int address_set = 0;
11253   u32 enable_disable = 1;
11254
11255   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11256     {
11257       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11258         address_set = 1;
11259       else if (unformat (line_input, "del"))
11260         enable_disable = 0;
11261       else
11262         break;
11263     }
11264
11265   if (address_set == 0)
11266     {
11267       errmsg ("missing addresses\n");
11268       return -99;
11269     }
11270
11271   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11272   mp->enable_disable = enable_disable;
11273   mp->pid = getpid ();
11274   mp->address = address.as_u32;
11275
11276   S;
11277   W;
11278 }
11279
11280 static int
11281 api_want_ip6_nd_events (vat_main_t * vam)
11282 {
11283   unformat_input_t *line_input = vam->input;
11284   vl_api_want_ip6_nd_events_t *mp;
11285   f64 timeout;
11286   ip6_address_t address;
11287   int address_set = 0;
11288   u32 enable_disable = 1;
11289
11290   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11291     {
11292       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11293         address_set = 1;
11294       else if (unformat (line_input, "del"))
11295         enable_disable = 0;
11296       else
11297         break;
11298     }
11299
11300   if (address_set == 0)
11301     {
11302       errmsg ("missing addresses\n");
11303       return -99;
11304     }
11305
11306   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11307   mp->enable_disable = enable_disable;
11308   mp->pid = getpid ();
11309   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11310
11311   S;
11312   W;
11313 }
11314
11315 static int
11316 api_input_acl_set_interface (vat_main_t * vam)
11317 {
11318   unformat_input_t *i = vam->input;
11319   vl_api_input_acl_set_interface_t *mp;
11320   f64 timeout;
11321   u32 sw_if_index;
11322   int sw_if_index_set;
11323   u32 ip4_table_index = ~0;
11324   u32 ip6_table_index = ~0;
11325   u32 l2_table_index = ~0;
11326   u8 is_add = 1;
11327
11328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11329     {
11330       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11331         sw_if_index_set = 1;
11332       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11333         sw_if_index_set = 1;
11334       else if (unformat (i, "del"))
11335         is_add = 0;
11336       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11337         ;
11338       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11339         ;
11340       else if (unformat (i, "l2-table %d", &l2_table_index))
11341         ;
11342       else
11343         {
11344           clib_warning ("parse error '%U'", format_unformat_error, i);
11345           return -99;
11346         }
11347     }
11348
11349   if (sw_if_index_set == 0)
11350     {
11351       errmsg ("missing interface name or sw_if_index\n");
11352       return -99;
11353     }
11354
11355   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11356
11357   mp->sw_if_index = ntohl (sw_if_index);
11358   mp->ip4_table_index = ntohl (ip4_table_index);
11359   mp->ip6_table_index = ntohl (ip6_table_index);
11360   mp->l2_table_index = ntohl (l2_table_index);
11361   mp->is_add = is_add;
11362
11363   S;
11364   W;
11365   /* NOTREACHED */
11366   return 0;
11367 }
11368
11369 static int
11370 api_ip_address_dump (vat_main_t * vam)
11371 {
11372   unformat_input_t *i = vam->input;
11373   vl_api_ip_address_dump_t *mp;
11374   u32 sw_if_index = ~0;
11375   u8 sw_if_index_set = 0;
11376   u8 ipv4_set = 0;
11377   u8 ipv6_set = 0;
11378   f64 timeout;
11379
11380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11381     {
11382       if (unformat (i, "sw_if_index %d", &sw_if_index))
11383         sw_if_index_set = 1;
11384       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11385         sw_if_index_set = 1;
11386       else if (unformat (i, "ipv4"))
11387         ipv4_set = 1;
11388       else if (unformat (i, "ipv6"))
11389         ipv6_set = 1;
11390       else
11391         break;
11392     }
11393
11394   if (ipv4_set && ipv6_set)
11395     {
11396       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11397       return -99;
11398     }
11399
11400   if ((!ipv4_set) && (!ipv6_set))
11401     {
11402       errmsg ("no ipv4 nor ipv6 flag set\n");
11403       return -99;
11404     }
11405
11406   if (sw_if_index_set == 0)
11407     {
11408       errmsg ("missing interface name or sw_if_index\n");
11409       return -99;
11410     }
11411
11412   vam->current_sw_if_index = sw_if_index;
11413   vam->is_ipv6 = ipv6_set;
11414
11415   M (IP_ADDRESS_DUMP, ip_address_dump);
11416   mp->sw_if_index = ntohl (sw_if_index);
11417   mp->is_ipv6 = ipv6_set;
11418   S;
11419
11420   /* Use a control ping for synchronization */
11421   {
11422     vl_api_control_ping_t *mp;
11423     M (CONTROL_PING, control_ping);
11424     S;
11425   }
11426   W;
11427 }
11428
11429 static int
11430 api_ip_dump (vat_main_t * vam)
11431 {
11432   vl_api_ip_dump_t *mp;
11433   unformat_input_t *in = vam->input;
11434   int ipv4_set = 0;
11435   int ipv6_set = 0;
11436   int is_ipv6;
11437   f64 timeout;
11438   int i;
11439
11440   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11441     {
11442       if (unformat (in, "ipv4"))
11443         ipv4_set = 1;
11444       else if (unformat (in, "ipv6"))
11445         ipv6_set = 1;
11446       else
11447         break;
11448     }
11449
11450   if (ipv4_set && ipv6_set)
11451     {
11452       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11453       return -99;
11454     }
11455
11456   if ((!ipv4_set) && (!ipv6_set))
11457     {
11458       errmsg ("no ipv4 nor ipv6 flag set\n");
11459       return -99;
11460     }
11461
11462   is_ipv6 = ipv6_set;
11463   vam->is_ipv6 = is_ipv6;
11464
11465   /* free old data */
11466   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11467     {
11468       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11469     }
11470   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11471
11472   M (IP_DUMP, ip_dump);
11473   mp->is_ipv6 = ipv6_set;
11474   S;
11475
11476   /* Use a control ping for synchronization */
11477   {
11478     vl_api_control_ping_t *mp;
11479     M (CONTROL_PING, control_ping);
11480     S;
11481   }
11482   W;
11483 }
11484
11485 static int
11486 api_ipsec_spd_add_del (vat_main_t * vam)
11487 {
11488   unformat_input_t *i = vam->input;
11489   vl_api_ipsec_spd_add_del_t *mp;
11490   f64 timeout;
11491   u32 spd_id = ~0;
11492   u8 is_add = 1;
11493
11494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11495     {
11496       if (unformat (i, "spd_id %d", &spd_id))
11497         ;
11498       else if (unformat (i, "del"))
11499         is_add = 0;
11500       else
11501         {
11502           clib_warning ("parse error '%U'", format_unformat_error, i);
11503           return -99;
11504         }
11505     }
11506   if (spd_id == ~0)
11507     {
11508       errmsg ("spd_id must be set\n");
11509       return -99;
11510     }
11511
11512   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11513
11514   mp->spd_id = ntohl (spd_id);
11515   mp->is_add = is_add;
11516
11517   S;
11518   W;
11519   /* NOTREACHED */
11520   return 0;
11521 }
11522
11523 static int
11524 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11525 {
11526   unformat_input_t *i = vam->input;
11527   vl_api_ipsec_interface_add_del_spd_t *mp;
11528   f64 timeout;
11529   u32 sw_if_index;
11530   u8 sw_if_index_set = 0;
11531   u32 spd_id = (u32) ~ 0;
11532   u8 is_add = 1;
11533
11534   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11535     {
11536       if (unformat (i, "del"))
11537         is_add = 0;
11538       else if (unformat (i, "spd_id %d", &spd_id))
11539         ;
11540       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11541         sw_if_index_set = 1;
11542       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11543         sw_if_index_set = 1;
11544       else
11545         {
11546           clib_warning ("parse error '%U'", format_unformat_error, i);
11547           return -99;
11548         }
11549
11550     }
11551
11552   if (spd_id == (u32) ~ 0)
11553     {
11554       errmsg ("spd_id must be set\n");
11555       return -99;
11556     }
11557
11558   if (sw_if_index_set == 0)
11559     {
11560       errmsg ("missing interface name or sw_if_index\n");
11561       return -99;
11562     }
11563
11564   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11565
11566   mp->spd_id = ntohl (spd_id);
11567   mp->sw_if_index = ntohl (sw_if_index);
11568   mp->is_add = is_add;
11569
11570   S;
11571   W;
11572   /* NOTREACHED */
11573   return 0;
11574 }
11575
11576 static int
11577 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11578 {
11579   unformat_input_t *i = vam->input;
11580   vl_api_ipsec_spd_add_del_entry_t *mp;
11581   f64 timeout;
11582   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11583   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11584   i32 priority = 0;
11585   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11586   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11587   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11588   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11589
11590   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11591   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11592   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11593   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11594   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11595   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11596
11597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11598     {
11599       if (unformat (i, "del"))
11600         is_add = 0;
11601       if (unformat (i, "outbound"))
11602         is_outbound = 1;
11603       if (unformat (i, "inbound"))
11604         is_outbound = 0;
11605       else if (unformat (i, "spd_id %d", &spd_id))
11606         ;
11607       else if (unformat (i, "sa_id %d", &sa_id))
11608         ;
11609       else if (unformat (i, "priority %d", &priority))
11610         ;
11611       else if (unformat (i, "protocol %d", &protocol))
11612         ;
11613       else if (unformat (i, "lport_start %d", &lport_start))
11614         ;
11615       else if (unformat (i, "lport_stop %d", &lport_stop))
11616         ;
11617       else if (unformat (i, "rport_start %d", &rport_start))
11618         ;
11619       else if (unformat (i, "rport_stop %d", &rport_stop))
11620         ;
11621       else
11622         if (unformat
11623             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11624         {
11625           is_ipv6 = 0;
11626           is_ip_any = 0;
11627         }
11628       else
11629         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11630         {
11631           is_ipv6 = 0;
11632           is_ip_any = 0;
11633         }
11634       else
11635         if (unformat
11636             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11637         {
11638           is_ipv6 = 0;
11639           is_ip_any = 0;
11640         }
11641       else
11642         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11643         {
11644           is_ipv6 = 0;
11645           is_ip_any = 0;
11646         }
11647       else
11648         if (unformat
11649             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11650         {
11651           is_ipv6 = 1;
11652           is_ip_any = 0;
11653         }
11654       else
11655         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11656         {
11657           is_ipv6 = 1;
11658           is_ip_any = 0;
11659         }
11660       else
11661         if (unformat
11662             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11663         {
11664           is_ipv6 = 1;
11665           is_ip_any = 0;
11666         }
11667       else
11668         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11669         {
11670           is_ipv6 = 1;
11671           is_ip_any = 0;
11672         }
11673       else
11674         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11675         {
11676           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11677             {
11678               clib_warning ("unsupported action: 'resolve'");
11679               return -99;
11680             }
11681         }
11682       else
11683         {
11684           clib_warning ("parse error '%U'", format_unformat_error, i);
11685           return -99;
11686         }
11687
11688     }
11689
11690   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11691
11692   mp->spd_id = ntohl (spd_id);
11693   mp->priority = ntohl (priority);
11694   mp->is_outbound = is_outbound;
11695
11696   mp->is_ipv6 = is_ipv6;
11697   if (is_ipv6 || is_ip_any)
11698     {
11699       clib_memcpy (mp->remote_address_start, &raddr6_start,
11700                    sizeof (ip6_address_t));
11701       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11702                    sizeof (ip6_address_t));
11703       clib_memcpy (mp->local_address_start, &laddr6_start,
11704                    sizeof (ip6_address_t));
11705       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11706                    sizeof (ip6_address_t));
11707     }
11708   else
11709     {
11710       clib_memcpy (mp->remote_address_start, &raddr4_start,
11711                    sizeof (ip4_address_t));
11712       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11713                    sizeof (ip4_address_t));
11714       clib_memcpy (mp->local_address_start, &laddr4_start,
11715                    sizeof (ip4_address_t));
11716       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11717                    sizeof (ip4_address_t));
11718     }
11719   mp->protocol = (u8) protocol;
11720   mp->local_port_start = ntohs ((u16) lport_start);
11721   mp->local_port_stop = ntohs ((u16) lport_stop);
11722   mp->remote_port_start = ntohs ((u16) rport_start);
11723   mp->remote_port_stop = ntohs ((u16) rport_stop);
11724   mp->policy = (u8) policy;
11725   mp->sa_id = ntohl (sa_id);
11726   mp->is_add = is_add;
11727   mp->is_ip_any = is_ip_any;
11728   S;
11729   W;
11730   /* NOTREACHED */
11731   return 0;
11732 }
11733
11734 static int
11735 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11736 {
11737   unformat_input_t *i = vam->input;
11738   vl_api_ipsec_sad_add_del_entry_t *mp;
11739   f64 timeout;
11740   u32 sad_id = 0, spi = 0;
11741   u8 *ck = 0, *ik = 0;
11742   u8 is_add = 1;
11743
11744   u8 protocol = IPSEC_PROTOCOL_AH;
11745   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11746   u32 crypto_alg = 0, integ_alg = 0;
11747   ip4_address_t tun_src4;
11748   ip4_address_t tun_dst4;
11749   ip6_address_t tun_src6;
11750   ip6_address_t tun_dst6;
11751
11752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11753     {
11754       if (unformat (i, "del"))
11755         is_add = 0;
11756       else if (unformat (i, "sad_id %d", &sad_id))
11757         ;
11758       else if (unformat (i, "spi %d", &spi))
11759         ;
11760       else if (unformat (i, "esp"))
11761         protocol = IPSEC_PROTOCOL_ESP;
11762       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11763         {
11764           is_tunnel = 1;
11765           is_tunnel_ipv6 = 0;
11766         }
11767       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11768         {
11769           is_tunnel = 1;
11770           is_tunnel_ipv6 = 0;
11771         }
11772       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11773         {
11774           is_tunnel = 1;
11775           is_tunnel_ipv6 = 1;
11776         }
11777       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11778         {
11779           is_tunnel = 1;
11780           is_tunnel_ipv6 = 1;
11781         }
11782       else
11783         if (unformat
11784             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11785         {
11786           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11787               crypto_alg >= IPSEC_CRYPTO_N_ALG)
11788             {
11789               clib_warning ("unsupported crypto-alg: '%U'",
11790                             format_ipsec_crypto_alg, crypto_alg);
11791               return -99;
11792             }
11793         }
11794       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11795         ;
11796       else
11797         if (unformat
11798             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11799         {
11800 #if DPDK_CRYPTO==1
11801           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
11802 #else
11803           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11804 #endif
11805               integ_alg >= IPSEC_INTEG_N_ALG)
11806             {
11807               clib_warning ("unsupported integ-alg: '%U'",
11808                             format_ipsec_integ_alg, integ_alg);
11809               return -99;
11810             }
11811         }
11812       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11813         ;
11814       else
11815         {
11816           clib_warning ("parse error '%U'", format_unformat_error, i);
11817           return -99;
11818         }
11819
11820     }
11821
11822 #if DPDK_CRYPTO==1
11823   /*Special cases, aes-gcm-128 encryption */
11824   if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
11825     {
11826       if (integ_alg != IPSEC_INTEG_ALG_NONE
11827           && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
11828         {
11829           clib_warning
11830             ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
11831           return -99;
11832         }
11833       else                      /*set integ-alg internally to aes-gcm-128 */
11834         integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
11835     }
11836   else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
11837     {
11838       clib_warning ("unsupported integ-alg: aes-gcm-128");
11839       return -99;
11840     }
11841   else if (integ_alg == IPSEC_INTEG_ALG_NONE)
11842     {
11843       clib_warning ("unsupported integ-alg: none");
11844       return -99;
11845     }
11846 #endif
11847
11848
11849   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11850
11851   mp->sad_id = ntohl (sad_id);
11852   mp->is_add = is_add;
11853   mp->protocol = protocol;
11854   mp->spi = ntohl (spi);
11855   mp->is_tunnel = is_tunnel;
11856   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11857   mp->crypto_algorithm = crypto_alg;
11858   mp->integrity_algorithm = integ_alg;
11859   mp->crypto_key_length = vec_len (ck);
11860   mp->integrity_key_length = vec_len (ik);
11861
11862   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11863     mp->crypto_key_length = sizeof (mp->crypto_key);
11864
11865   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11866     mp->integrity_key_length = sizeof (mp->integrity_key);
11867
11868   if (ck)
11869     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11870   if (ik)
11871     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11872
11873   if (is_tunnel)
11874     {
11875       if (is_tunnel_ipv6)
11876         {
11877           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11878                        sizeof (ip6_address_t));
11879           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11880                        sizeof (ip6_address_t));
11881         }
11882       else
11883         {
11884           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11885                        sizeof (ip4_address_t));
11886           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11887                        sizeof (ip4_address_t));
11888         }
11889     }
11890
11891   S;
11892   W;
11893   /* NOTREACHED */
11894   return 0;
11895 }
11896
11897 static int
11898 api_ipsec_sa_set_key (vat_main_t * vam)
11899 {
11900   unformat_input_t *i = vam->input;
11901   vl_api_ipsec_sa_set_key_t *mp;
11902   f64 timeout;
11903   u32 sa_id;
11904   u8 *ck = 0, *ik = 0;
11905
11906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11907     {
11908       if (unformat (i, "sa_id %d", &sa_id))
11909         ;
11910       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11911         ;
11912       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11913         ;
11914       else
11915         {
11916           clib_warning ("parse error '%U'", format_unformat_error, i);
11917           return -99;
11918         }
11919     }
11920
11921   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11922
11923   mp->sa_id = ntohl (sa_id);
11924   mp->crypto_key_length = vec_len (ck);
11925   mp->integrity_key_length = vec_len (ik);
11926
11927   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11928     mp->crypto_key_length = sizeof (mp->crypto_key);
11929
11930   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11931     mp->integrity_key_length = sizeof (mp->integrity_key);
11932
11933   if (ck)
11934     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11935   if (ik)
11936     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11937
11938   S;
11939   W;
11940   /* NOTREACHED */
11941   return 0;
11942 }
11943
11944 static int
11945 api_ikev2_profile_add_del (vat_main_t * vam)
11946 {
11947   unformat_input_t *i = vam->input;
11948   vl_api_ikev2_profile_add_del_t *mp;
11949   f64 timeout;
11950   u8 is_add = 1;
11951   u8 *name = 0;
11952
11953   const char *valid_chars = "a-zA-Z0-9_";
11954
11955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11956     {
11957       if (unformat (i, "del"))
11958         is_add = 0;
11959       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11960         vec_add1 (name, 0);
11961       else
11962         {
11963           errmsg ("parse error '%U'", format_unformat_error, i);
11964           return -99;
11965         }
11966     }
11967
11968   if (!vec_len (name))
11969     {
11970       errmsg ("profile name must be specified");
11971       return -99;
11972     }
11973
11974   if (vec_len (name) > 64)
11975     {
11976       errmsg ("profile name too long");
11977       return -99;
11978     }
11979
11980   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11981
11982   clib_memcpy (mp->name, name, vec_len (name));
11983   mp->is_add = is_add;
11984   vec_free (name);
11985
11986   S;
11987   W;
11988   /* NOTREACHED */
11989   return 0;
11990 }
11991
11992 static int
11993 api_ikev2_profile_set_auth (vat_main_t * vam)
11994 {
11995   unformat_input_t *i = vam->input;
11996   vl_api_ikev2_profile_set_auth_t *mp;
11997   f64 timeout;
11998   u8 *name = 0;
11999   u8 *data = 0;
12000   u32 auth_method = 0;
12001   u8 is_hex = 0;
12002
12003   const char *valid_chars = "a-zA-Z0-9_";
12004
12005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12006     {
12007       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12008         vec_add1 (name, 0);
12009       else if (unformat (i, "auth_method %U",
12010                          unformat_ikev2_auth_method, &auth_method))
12011         ;
12012       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12013         is_hex = 1;
12014       else if (unformat (i, "auth_data %v", &data))
12015         ;
12016       else
12017         {
12018           errmsg ("parse error '%U'", format_unformat_error, i);
12019           return -99;
12020         }
12021     }
12022
12023   if (!vec_len (name))
12024     {
12025       errmsg ("profile name must be specified");
12026       return -99;
12027     }
12028
12029   if (vec_len (name) > 64)
12030     {
12031       errmsg ("profile name too long");
12032       return -99;
12033     }
12034
12035   if (!vec_len (data))
12036     {
12037       errmsg ("auth_data must be specified");
12038       return -99;
12039     }
12040
12041   if (!auth_method)
12042     {
12043       errmsg ("auth_method must be specified");
12044       return -99;
12045     }
12046
12047   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12048
12049   mp->is_hex = is_hex;
12050   mp->auth_method = (u8) auth_method;
12051   mp->data_len = vec_len (data);
12052   clib_memcpy (mp->name, name, vec_len (name));
12053   clib_memcpy (mp->data, data, vec_len (data));
12054   vec_free (name);
12055   vec_free (data);
12056
12057   S;
12058   W;
12059   /* NOTREACHED */
12060   return 0;
12061 }
12062
12063 static int
12064 api_ikev2_profile_set_id (vat_main_t * vam)
12065 {
12066   unformat_input_t *i = vam->input;
12067   vl_api_ikev2_profile_set_id_t *mp;
12068   f64 timeout;
12069   u8 *name = 0;
12070   u8 *data = 0;
12071   u8 is_local = 0;
12072   u32 id_type = 0;
12073   ip4_address_t ip4;
12074
12075   const char *valid_chars = "a-zA-Z0-9_";
12076
12077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12078     {
12079       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12080         vec_add1 (name, 0);
12081       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12082         ;
12083       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12084         {
12085           data = vec_new (u8, 4);
12086           clib_memcpy (data, ip4.as_u8, 4);
12087         }
12088       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12089         ;
12090       else if (unformat (i, "id_data %v", &data))
12091         ;
12092       else if (unformat (i, "local"))
12093         is_local = 1;
12094       else if (unformat (i, "remote"))
12095         is_local = 0;
12096       else
12097         {
12098           errmsg ("parse error '%U'", format_unformat_error, i);
12099           return -99;
12100         }
12101     }
12102
12103   if (!vec_len (name))
12104     {
12105       errmsg ("profile name must be specified");
12106       return -99;
12107     }
12108
12109   if (vec_len (name) > 64)
12110     {
12111       errmsg ("profile name too long");
12112       return -99;
12113     }
12114
12115   if (!vec_len (data))
12116     {
12117       errmsg ("id_data must be specified");
12118       return -99;
12119     }
12120
12121   if (!id_type)
12122     {
12123       errmsg ("id_type must be specified");
12124       return -99;
12125     }
12126
12127   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12128
12129   mp->is_local = is_local;
12130   mp->id_type = (u8) id_type;
12131   mp->data_len = vec_len (data);
12132   clib_memcpy (mp->name, name, vec_len (name));
12133   clib_memcpy (mp->data, data, vec_len (data));
12134   vec_free (name);
12135   vec_free (data);
12136
12137   S;
12138   W;
12139   /* NOTREACHED */
12140   return 0;
12141 }
12142
12143 static int
12144 api_ikev2_profile_set_ts (vat_main_t * vam)
12145 {
12146   unformat_input_t *i = vam->input;
12147   vl_api_ikev2_profile_set_ts_t *mp;
12148   f64 timeout;
12149   u8 *name = 0;
12150   u8 is_local = 0;
12151   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12152   ip4_address_t start_addr, end_addr;
12153
12154   const char *valid_chars = "a-zA-Z0-9_";
12155
12156   start_addr.as_u32 = 0;
12157   end_addr.as_u32 = (u32) ~ 0;
12158
12159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12160     {
12161       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12162         vec_add1 (name, 0);
12163       else if (unformat (i, "protocol %d", &proto))
12164         ;
12165       else if (unformat (i, "start_port %d", &start_port))
12166         ;
12167       else if (unformat (i, "end_port %d", &end_port))
12168         ;
12169       else
12170         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12171         ;
12172       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12173         ;
12174       else if (unformat (i, "local"))
12175         is_local = 1;
12176       else if (unformat (i, "remote"))
12177         is_local = 0;
12178       else
12179         {
12180           errmsg ("parse error '%U'", format_unformat_error, i);
12181           return -99;
12182         }
12183     }
12184
12185   if (!vec_len (name))
12186     {
12187       errmsg ("profile name must be specified");
12188       return -99;
12189     }
12190
12191   if (vec_len (name) > 64)
12192     {
12193       errmsg ("profile name too long");
12194       return -99;
12195     }
12196
12197   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12198
12199   mp->is_local = is_local;
12200   mp->proto = (u8) proto;
12201   mp->start_port = (u16) start_port;
12202   mp->end_port = (u16) end_port;
12203   mp->start_addr = start_addr.as_u32;
12204   mp->end_addr = end_addr.as_u32;
12205   clib_memcpy (mp->name, name, vec_len (name));
12206   vec_free (name);
12207
12208   S;
12209   W;
12210   /* NOTREACHED */
12211   return 0;
12212 }
12213
12214 static int
12215 api_ikev2_set_local_key (vat_main_t * vam)
12216 {
12217   unformat_input_t *i = vam->input;
12218   vl_api_ikev2_set_local_key_t *mp;
12219   f64 timeout;
12220   u8 *file = 0;
12221
12222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12223     {
12224       if (unformat (i, "file %v", &file))
12225         vec_add1 (file, 0);
12226       else
12227         {
12228           errmsg ("parse error '%U'", format_unformat_error, i);
12229           return -99;
12230         }
12231     }
12232
12233   if (!vec_len (file))
12234     {
12235       errmsg ("RSA key file must be specified");
12236       return -99;
12237     }
12238
12239   if (vec_len (file) > 256)
12240     {
12241       errmsg ("file name too long");
12242       return -99;
12243     }
12244
12245   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12246
12247   clib_memcpy (mp->key_file, file, vec_len (file));
12248   vec_free (file);
12249
12250   S;
12251   W;
12252   /* NOTREACHED */
12253   return 0;
12254 }
12255
12256 /*
12257  * MAP
12258  */
12259 static int
12260 api_map_add_domain (vat_main_t * vam)
12261 {
12262   unformat_input_t *i = vam->input;
12263   vl_api_map_add_domain_t *mp;
12264   f64 timeout;
12265
12266   ip4_address_t ip4_prefix;
12267   ip6_address_t ip6_prefix;
12268   ip6_address_t ip6_src;
12269   u32 num_m_args = 0;
12270   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12271     0, psid_length = 0;
12272   u8 is_translation = 0;
12273   u32 mtu = 0;
12274   u32 ip6_src_len = 128;
12275
12276   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12277     {
12278       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12279                     &ip4_prefix, &ip4_prefix_len))
12280         num_m_args++;
12281       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12282                          &ip6_prefix, &ip6_prefix_len))
12283         num_m_args++;
12284       else
12285         if (unformat
12286             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12287              &ip6_src_len))
12288         num_m_args++;
12289       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12290         num_m_args++;
12291       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12292         num_m_args++;
12293       else if (unformat (i, "psid-offset %d", &psid_offset))
12294         num_m_args++;
12295       else if (unformat (i, "psid-len %d", &psid_length))
12296         num_m_args++;
12297       else if (unformat (i, "mtu %d", &mtu))
12298         num_m_args++;
12299       else if (unformat (i, "map-t"))
12300         is_translation = 1;
12301       else
12302         {
12303           clib_warning ("parse error '%U'", format_unformat_error, i);
12304           return -99;
12305         }
12306     }
12307
12308   if (num_m_args < 3)
12309     {
12310       errmsg ("mandatory argument(s) missing\n");
12311       return -99;
12312     }
12313
12314   /* Construct the API message */
12315   M (MAP_ADD_DOMAIN, map_add_domain);
12316
12317   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12318   mp->ip4_prefix_len = ip4_prefix_len;
12319
12320   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12321   mp->ip6_prefix_len = ip6_prefix_len;
12322
12323   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12324   mp->ip6_src_prefix_len = ip6_src_len;
12325
12326   mp->ea_bits_len = ea_bits_len;
12327   mp->psid_offset = psid_offset;
12328   mp->psid_length = psid_length;
12329   mp->is_translation = is_translation;
12330   mp->mtu = htons (mtu);
12331
12332   /* send it... */
12333   S;
12334
12335   /* Wait for a reply, return good/bad news  */
12336   W;
12337 }
12338
12339 static int
12340 api_map_del_domain (vat_main_t * vam)
12341 {
12342   unformat_input_t *i = vam->input;
12343   vl_api_map_del_domain_t *mp;
12344   f64 timeout;
12345
12346   u32 num_m_args = 0;
12347   u32 index;
12348
12349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12350     {
12351       if (unformat (i, "index %d", &index))
12352         num_m_args++;
12353       else
12354         {
12355           clib_warning ("parse error '%U'", format_unformat_error, i);
12356           return -99;
12357         }
12358     }
12359
12360   if (num_m_args != 1)
12361     {
12362       errmsg ("mandatory argument(s) missing\n");
12363       return -99;
12364     }
12365
12366   /* Construct the API message */
12367   M (MAP_DEL_DOMAIN, map_del_domain);
12368
12369   mp->index = ntohl (index);
12370
12371   /* send it... */
12372   S;
12373
12374   /* Wait for a reply, return good/bad news  */
12375   W;
12376 }
12377
12378 static int
12379 api_map_add_del_rule (vat_main_t * vam)
12380 {
12381   unformat_input_t *i = vam->input;
12382   vl_api_map_add_del_rule_t *mp;
12383   f64 timeout;
12384   u8 is_add = 1;
12385   ip6_address_t ip6_dst;
12386   u32 num_m_args = 0, index, psid = 0;
12387
12388   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12389     {
12390       if (unformat (i, "index %d", &index))
12391         num_m_args++;
12392       else if (unformat (i, "psid %d", &psid))
12393         num_m_args++;
12394       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12395         num_m_args++;
12396       else if (unformat (i, "del"))
12397         {
12398           is_add = 0;
12399         }
12400       else
12401         {
12402           clib_warning ("parse error '%U'", format_unformat_error, i);
12403           return -99;
12404         }
12405     }
12406
12407   /* Construct the API message */
12408   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12409
12410   mp->index = ntohl (index);
12411   mp->is_add = is_add;
12412   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12413   mp->psid = ntohs (psid);
12414
12415   /* send it... */
12416   S;
12417
12418   /* Wait for a reply, return good/bad news  */
12419   W;
12420 }
12421
12422 static int
12423 api_map_domain_dump (vat_main_t * vam)
12424 {
12425   vl_api_map_domain_dump_t *mp;
12426   f64 timeout;
12427
12428   /* Construct the API message */
12429   M (MAP_DOMAIN_DUMP, map_domain_dump);
12430
12431   /* send it... */
12432   S;
12433
12434   /* Use a control ping for synchronization */
12435   {
12436     vl_api_control_ping_t *mp;
12437     M (CONTROL_PING, control_ping);
12438     S;
12439   }
12440   W;
12441 }
12442
12443 static int
12444 api_map_rule_dump (vat_main_t * vam)
12445 {
12446   unformat_input_t *i = vam->input;
12447   vl_api_map_rule_dump_t *mp;
12448   f64 timeout;
12449   u32 domain_index = ~0;
12450
12451   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12452     {
12453       if (unformat (i, "index %u", &domain_index))
12454         ;
12455       else
12456         break;
12457     }
12458
12459   if (domain_index == ~0)
12460     {
12461       clib_warning ("parse error: domain index expected");
12462       return -99;
12463     }
12464
12465   /* Construct the API message */
12466   M (MAP_RULE_DUMP, map_rule_dump);
12467
12468   mp->domain_index = htonl (domain_index);
12469
12470   /* send it... */
12471   S;
12472
12473   /* Use a control ping for synchronization */
12474   {
12475     vl_api_control_ping_t *mp;
12476     M (CONTROL_PING, control_ping);
12477     S;
12478   }
12479   W;
12480 }
12481
12482 static void vl_api_map_add_domain_reply_t_handler
12483   (vl_api_map_add_domain_reply_t * mp)
12484 {
12485   vat_main_t *vam = &vat_main;
12486   i32 retval = ntohl (mp->retval);
12487
12488   if (vam->async_mode)
12489     {
12490       vam->async_errors += (retval < 0);
12491     }
12492   else
12493     {
12494       vam->retval = retval;
12495       vam->result_ready = 1;
12496     }
12497 }
12498
12499 static void vl_api_map_add_domain_reply_t_handler_json
12500   (vl_api_map_add_domain_reply_t * mp)
12501 {
12502   vat_main_t *vam = &vat_main;
12503   vat_json_node_t node;
12504
12505   vat_json_init_object (&node);
12506   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12507   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12508
12509   vat_json_print (vam->ofp, &node);
12510   vat_json_free (&node);
12511
12512   vam->retval = ntohl (mp->retval);
12513   vam->result_ready = 1;
12514 }
12515
12516 static int
12517 api_get_first_msg_id (vat_main_t * vam)
12518 {
12519   vl_api_get_first_msg_id_t *mp;
12520   f64 timeout;
12521   unformat_input_t *i = vam->input;
12522   u8 *name;
12523   u8 name_set = 0;
12524
12525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12526     {
12527       if (unformat (i, "client %s", &name))
12528         name_set = 1;
12529       else
12530         break;
12531     }
12532
12533   if (name_set == 0)
12534     {
12535       errmsg ("missing client name\n");
12536       return -99;
12537     }
12538   vec_add1 (name, 0);
12539
12540   if (vec_len (name) > 63)
12541     {
12542       errmsg ("client name too long\n");
12543       return -99;
12544     }
12545
12546   M (GET_FIRST_MSG_ID, get_first_msg_id);
12547   clib_memcpy (mp->name, name, vec_len (name));
12548   S;
12549   W;
12550   /* NOTREACHED */
12551   return 0;
12552 }
12553
12554 static int
12555 api_cop_interface_enable_disable (vat_main_t * vam)
12556 {
12557   unformat_input_t *line_input = vam->input;
12558   vl_api_cop_interface_enable_disable_t *mp;
12559   f64 timeout;
12560   u32 sw_if_index = ~0;
12561   u8 enable_disable = 1;
12562
12563   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12564     {
12565       if (unformat (line_input, "disable"))
12566         enable_disable = 0;
12567       if (unformat (line_input, "enable"))
12568         enable_disable = 1;
12569       else if (unformat (line_input, "%U", unformat_sw_if_index,
12570                          vam, &sw_if_index))
12571         ;
12572       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12573         ;
12574       else
12575         break;
12576     }
12577
12578   if (sw_if_index == ~0)
12579     {
12580       errmsg ("missing interface name or sw_if_index\n");
12581       return -99;
12582     }
12583
12584   /* Construct the API message */
12585   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12586   mp->sw_if_index = ntohl (sw_if_index);
12587   mp->enable_disable = enable_disable;
12588
12589   /* send it... */
12590   S;
12591   /* Wait for the reply */
12592   W;
12593 }
12594
12595 static int
12596 api_cop_whitelist_enable_disable (vat_main_t * vam)
12597 {
12598   unformat_input_t *line_input = vam->input;
12599   vl_api_cop_whitelist_enable_disable_t *mp;
12600   f64 timeout;
12601   u32 sw_if_index = ~0;
12602   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12603   u32 fib_id = 0;
12604
12605   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12606     {
12607       if (unformat (line_input, "ip4"))
12608         ip4 = 1;
12609       else if (unformat (line_input, "ip6"))
12610         ip6 = 1;
12611       else if (unformat (line_input, "default"))
12612         default_cop = 1;
12613       else if (unformat (line_input, "%U", unformat_sw_if_index,
12614                          vam, &sw_if_index))
12615         ;
12616       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12617         ;
12618       else if (unformat (line_input, "fib-id %d", &fib_id))
12619         ;
12620       else
12621         break;
12622     }
12623
12624   if (sw_if_index == ~0)
12625     {
12626       errmsg ("missing interface name or sw_if_index\n");
12627       return -99;
12628     }
12629
12630   /* Construct the API message */
12631   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12632   mp->sw_if_index = ntohl (sw_if_index);
12633   mp->fib_id = ntohl (fib_id);
12634   mp->ip4 = ip4;
12635   mp->ip6 = ip6;
12636   mp->default_cop = default_cop;
12637
12638   /* send it... */
12639   S;
12640   /* Wait for the reply */
12641   W;
12642 }
12643
12644 static int
12645 api_get_node_graph (vat_main_t * vam)
12646 {
12647   vl_api_get_node_graph_t *mp;
12648   f64 timeout;
12649
12650   M (GET_NODE_GRAPH, get_node_graph);
12651
12652   /* send it... */
12653   S;
12654   /* Wait for the reply */
12655   W;
12656 }
12657
12658 /* *INDENT-OFF* */
12659 /** Used for parsing LISP eids */
12660 typedef CLIB_PACKED(struct{
12661   u8 addr[16];   /**< eid address */
12662   u32 len;       /**< prefix length if IP */
12663   u8 type;      /**< type of eid */
12664 }) lisp_eid_vat_t;
12665 /* *INDENT-ON* */
12666
12667 static uword
12668 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12669 {
12670   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12671
12672   memset (a, 0, sizeof (a[0]));
12673
12674   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12675     {
12676       a->type = 0;              /* ipv4 type */
12677     }
12678   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12679     {
12680       a->type = 1;              /* ipv6 type */
12681     }
12682   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12683     {
12684       a->type = 2;              /* mac type */
12685     }
12686   else
12687     {
12688       return 0;
12689     }
12690
12691   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12692     {
12693       return 0;
12694     }
12695
12696   return 1;
12697 }
12698
12699 static int
12700 lisp_eid_size_vat (u8 type)
12701 {
12702   switch (type)
12703     {
12704     case 0:
12705       return 4;
12706     case 1:
12707       return 16;
12708     case 2:
12709       return 6;
12710     }
12711   return 0;
12712 }
12713
12714 static void
12715 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12716 {
12717   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12718 }
12719
12720 /* *INDENT-OFF* */
12721 /** Used for transferring locators via VPP API */
12722 typedef CLIB_PACKED(struct
12723 {
12724   u32 sw_if_index; /**< locator sw_if_index */
12725   u8 priority; /**< locator priority */
12726   u8 weight;   /**< locator weight */
12727 }) ls_locator_t;
12728 /* *INDENT-ON* */
12729
12730 static int
12731 api_lisp_add_del_locator_set (vat_main_t * vam)
12732 {
12733   unformat_input_t *input = vam->input;
12734   vl_api_lisp_add_del_locator_set_t *mp;
12735   f64 timeout = ~0;
12736   u8 is_add = 1;
12737   u8 *locator_set_name = NULL;
12738   u8 locator_set_name_set = 0;
12739   ls_locator_t locator, *locators = 0;
12740   u32 sw_if_index, priority, weight;
12741   u32 data_len = 0;
12742
12743   /* Parse args required to build the message */
12744   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12745     {
12746       if (unformat (input, "del"))
12747         {
12748           is_add = 0;
12749         }
12750       else if (unformat (input, "locator-set %s", &locator_set_name))
12751         {
12752           locator_set_name_set = 1;
12753         }
12754       else if (unformat (input, "sw_if_index %u p %u w %u",
12755                          &sw_if_index, &priority, &weight))
12756         {
12757           locator.sw_if_index = htonl (sw_if_index);
12758           locator.priority = priority;
12759           locator.weight = weight;
12760           vec_add1 (locators, locator);
12761         }
12762       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12763                          vam, &sw_if_index, &priority, &weight))
12764         {
12765           locator.sw_if_index = htonl (sw_if_index);
12766           locator.priority = priority;
12767           locator.weight = weight;
12768           vec_add1 (locators, locator);
12769         }
12770       else
12771         break;
12772     }
12773
12774   if (locator_set_name_set == 0)
12775     {
12776       errmsg ("missing locator-set name");
12777       vec_free (locators);
12778       return -99;
12779     }
12780
12781   if (vec_len (locator_set_name) > 64)
12782     {
12783       errmsg ("locator-set name too long\n");
12784       vec_free (locator_set_name);
12785       vec_free (locators);
12786       return -99;
12787     }
12788   vec_add1 (locator_set_name, 0);
12789
12790   data_len = sizeof (ls_locator_t) * vec_len (locators);
12791
12792   /* Construct the API message */
12793   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12794
12795   mp->is_add = is_add;
12796   clib_memcpy (mp->locator_set_name, locator_set_name,
12797                vec_len (locator_set_name));
12798   vec_free (locator_set_name);
12799
12800   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12801   if (locators)
12802     clib_memcpy (mp->locators, locators, data_len);
12803   vec_free (locators);
12804
12805   /* send it... */
12806   S;
12807
12808   /* Wait for a reply... */
12809   W;
12810
12811   /* NOTREACHED */
12812   return 0;
12813 }
12814
12815 static int
12816 api_lisp_add_del_locator (vat_main_t * vam)
12817 {
12818   unformat_input_t *input = vam->input;
12819   vl_api_lisp_add_del_locator_t *mp;
12820   f64 timeout = ~0;
12821   u32 tmp_if_index = ~0;
12822   u32 sw_if_index = ~0;
12823   u8 sw_if_index_set = 0;
12824   u8 sw_if_index_if_name_set = 0;
12825   u32 priority = ~0;
12826   u8 priority_set = 0;
12827   u32 weight = ~0;
12828   u8 weight_set = 0;
12829   u8 is_add = 1;
12830   u8 *locator_set_name = NULL;
12831   u8 locator_set_name_set = 0;
12832
12833   /* Parse args required to build the message */
12834   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12835     {
12836       if (unformat (input, "del"))
12837         {
12838           is_add = 0;
12839         }
12840       else if (unformat (input, "locator-set %s", &locator_set_name))
12841         {
12842           locator_set_name_set = 1;
12843         }
12844       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12845                          &tmp_if_index))
12846         {
12847           sw_if_index_if_name_set = 1;
12848           sw_if_index = tmp_if_index;
12849         }
12850       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12851         {
12852           sw_if_index_set = 1;
12853           sw_if_index = tmp_if_index;
12854         }
12855       else if (unformat (input, "p %d", &priority))
12856         {
12857           priority_set = 1;
12858         }
12859       else if (unformat (input, "w %d", &weight))
12860         {
12861           weight_set = 1;
12862         }
12863       else
12864         break;
12865     }
12866
12867   if (locator_set_name_set == 0)
12868     {
12869       errmsg ("missing locator-set name");
12870       return -99;
12871     }
12872
12873   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12874     {
12875       errmsg ("missing sw_if_index");
12876       vec_free (locator_set_name);
12877       return -99;
12878     }
12879
12880   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12881     {
12882       errmsg ("cannot use both params interface name and sw_if_index");
12883       vec_free (locator_set_name);
12884       return -99;
12885     }
12886
12887   if (priority_set == 0)
12888     {
12889       errmsg ("missing locator-set priority\n");
12890       vec_free (locator_set_name);
12891       return -99;
12892     }
12893
12894   if (weight_set == 0)
12895     {
12896       errmsg ("missing locator-set weight\n");
12897       vec_free (locator_set_name);
12898       return -99;
12899     }
12900
12901   if (vec_len (locator_set_name) > 64)
12902     {
12903       errmsg ("locator-set name too long\n");
12904       vec_free (locator_set_name);
12905       return -99;
12906     }
12907   vec_add1 (locator_set_name, 0);
12908
12909   /* Construct the API message */
12910   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12911
12912   mp->is_add = is_add;
12913   mp->sw_if_index = ntohl (sw_if_index);
12914   mp->priority = priority;
12915   mp->weight = weight;
12916   clib_memcpy (mp->locator_set_name, locator_set_name,
12917                vec_len (locator_set_name));
12918   vec_free (locator_set_name);
12919
12920   /* send it... */
12921   S;
12922
12923   /* Wait for a reply... */
12924   W;
12925
12926   /* NOTREACHED */
12927   return 0;
12928 }
12929
12930 static int
12931 api_lisp_add_del_local_eid (vat_main_t * vam)
12932 {
12933   unformat_input_t *input = vam->input;
12934   vl_api_lisp_add_del_local_eid_t *mp;
12935   f64 timeout = ~0;
12936   u8 is_add = 1;
12937   u8 eid_set = 0;
12938   lisp_eid_vat_t _eid, *eid = &_eid;
12939   u8 *locator_set_name = 0;
12940   u8 locator_set_name_set = 0;
12941   u32 vni = 0;
12942
12943   /* Parse args required to build the message */
12944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12945     {
12946       if (unformat (input, "del"))
12947         {
12948           is_add = 0;
12949         }
12950       else if (unformat (input, "vni %d", &vni))
12951         {
12952           ;
12953         }
12954       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12955         {
12956           eid_set = 1;
12957         }
12958       else if (unformat (input, "locator-set %s", &locator_set_name))
12959         {
12960           locator_set_name_set = 1;
12961         }
12962       else
12963         break;
12964     }
12965
12966   if (locator_set_name_set == 0)
12967     {
12968       errmsg ("missing locator-set name\n");
12969       return -99;
12970     }
12971
12972   if (0 == eid_set)
12973     {
12974       errmsg ("EID address not set!");
12975       vec_free (locator_set_name);
12976       return -99;
12977     }
12978
12979   if (vec_len (locator_set_name) > 64)
12980     {
12981       errmsg ("locator-set name too long\n");
12982       vec_free (locator_set_name);
12983       return -99;
12984     }
12985   vec_add1 (locator_set_name, 0);
12986
12987   /* Construct the API message */
12988   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12989
12990   mp->is_add = is_add;
12991   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12992   mp->eid_type = eid->type;
12993   mp->prefix_len = eid->len;
12994   mp->vni = clib_host_to_net_u32 (vni);
12995   clib_memcpy (mp->locator_set_name, locator_set_name,
12996                vec_len (locator_set_name));
12997
12998   vec_free (locator_set_name);
12999
13000   /* send it... */
13001   S;
13002
13003   /* Wait for a reply... */
13004   W;
13005
13006   /* NOTREACHED */
13007   return 0;
13008 }
13009
13010 /* *INDENT-OFF* */
13011 /** Used for transferring locators via VPP API */
13012 typedef CLIB_PACKED(struct
13013 {
13014   u8 is_ip4; /**< is locator an IPv4 address? */
13015   u8 priority; /**< locator priority */
13016   u8 weight;   /**< locator weight */
13017   u8 addr[16]; /**< IPv4/IPv6 address */
13018 }) rloc_t;
13019 /* *INDENT-ON* */
13020
13021 static int
13022 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13023 {
13024   unformat_input_t *input = vam->input;
13025   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13026   f64 timeout = ~0;
13027   u8 is_add = 1;
13028   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13029   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13030   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13031   u32 action = ~0, p, w;
13032   ip4_address_t rmt_rloc4, lcl_rloc4;
13033   ip6_address_t rmt_rloc6, lcl_rloc6;
13034   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13035
13036   memset (&rloc, 0, sizeof (rloc));
13037
13038   /* Parse args required to build the message */
13039   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13040     {
13041       if (unformat (input, "del"))
13042         {
13043           is_add = 0;
13044         }
13045       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
13046         {
13047           rmt_eid_set = 1;
13048         }
13049       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
13050         {
13051           lcl_eid_set = 1;
13052         }
13053       else if (unformat (input, "p %d w %d", &p, &w))
13054         {
13055           if (!curr_rloc)
13056             {
13057               errmsg ("No RLOC configured for setting priority/weight!");
13058               return -99;
13059             }
13060           curr_rloc->priority = p;
13061           curr_rloc->weight = w;
13062         }
13063       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13064                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13065         {
13066           rloc.is_ip4 = 1;
13067
13068           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13069           rloc.priority = rloc.weight = 0;
13070           vec_add1 (lcl_locs, rloc);
13071
13072           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13073           vec_add1 (rmt_locs, rloc);
13074           /* priority and weight saved in rmt loc */
13075           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13076         }
13077       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13078                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13079         {
13080           rloc.is_ip4 = 0;
13081           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13082           rloc.priority = rloc.weight = 0;
13083           vec_add1 (lcl_locs, rloc);
13084
13085           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13086           vec_add1 (rmt_locs, rloc);
13087           /* priority and weight saved in rmt loc */
13088           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13089         }
13090       else if (unformat (input, "action %d", &action))
13091         {
13092           ;
13093         }
13094       else
13095         {
13096           clib_warning ("parse error '%U'", format_unformat_error, input);
13097           return -99;
13098         }
13099     }
13100
13101   if (!rmt_eid_set)
13102     {
13103       errmsg ("remote eid addresses not set\n");
13104       return -99;
13105     }
13106
13107   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13108     {
13109       errmsg ("eid types don't match\n");
13110       return -99;
13111     }
13112
13113   if (0 == rmt_locs && (u32) ~ 0 == action)
13114     {
13115       errmsg ("action not set for negative mapping\n");
13116       return -99;
13117     }
13118
13119   /* Construct the API message */
13120   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13121
13122   mp->is_add = is_add;
13123   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13124   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13125   mp->eid_type = rmt_eid->type;
13126   mp->rmt_len = rmt_eid->len;
13127   mp->lcl_len = lcl_eid->len;
13128   mp->action = action;
13129
13130   if (0 != rmt_locs && 0 != lcl_locs)
13131     {
13132       mp->loc_num = vec_len (rmt_locs);
13133       clib_memcpy (mp->lcl_locs, lcl_locs,
13134                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13135       clib_memcpy (mp->rmt_locs, rmt_locs,
13136                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13137     }
13138   vec_free (lcl_locs);
13139   vec_free (rmt_locs);
13140
13141   /* send it... */
13142   S;
13143
13144   /* Wait for a reply... */
13145   W;
13146
13147   /* NOTREACHED */
13148   return 0;
13149 }
13150
13151 static int
13152 api_lisp_add_del_map_resolver (vat_main_t * vam)
13153 {
13154   unformat_input_t *input = vam->input;
13155   vl_api_lisp_add_del_map_resolver_t *mp;
13156   f64 timeout = ~0;
13157   u8 is_add = 1;
13158   u8 ipv4_set = 0;
13159   u8 ipv6_set = 0;
13160   ip4_address_t ipv4;
13161   ip6_address_t ipv6;
13162
13163   /* Parse args required to build the message */
13164   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13165     {
13166       if (unformat (input, "del"))
13167         {
13168           is_add = 0;
13169         }
13170       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13171         {
13172           ipv4_set = 1;
13173         }
13174       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13175         {
13176           ipv6_set = 1;
13177         }
13178       else
13179         break;
13180     }
13181
13182   if (ipv4_set && ipv6_set)
13183     {
13184       errmsg ("both eid v4 and v6 addresses set\n");
13185       return -99;
13186     }
13187
13188   if (!ipv4_set && !ipv6_set)
13189     {
13190       errmsg ("eid addresses not set\n");
13191       return -99;
13192     }
13193
13194   /* Construct the API message */
13195   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13196
13197   mp->is_add = is_add;
13198   if (ipv6_set)
13199     {
13200       mp->is_ipv6 = 1;
13201       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13202     }
13203   else
13204     {
13205       mp->is_ipv6 = 0;
13206       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13207     }
13208
13209   /* send it... */
13210   S;
13211
13212   /* Wait for a reply... */
13213   W;
13214
13215   /* NOTREACHED */
13216   return 0;
13217 }
13218
13219 static int
13220 api_lisp_gpe_enable_disable (vat_main_t * vam)
13221 {
13222   unformat_input_t *input = vam->input;
13223   vl_api_lisp_gpe_enable_disable_t *mp;
13224   f64 timeout = ~0;
13225   u8 is_set = 0;
13226   u8 is_en = 1;
13227
13228   /* Parse args required to build the message */
13229   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13230     {
13231       if (unformat (input, "enable"))
13232         {
13233           is_set = 1;
13234           is_en = 1;
13235         }
13236       else if (unformat (input, "disable"))
13237         {
13238           is_set = 1;
13239           is_en = 0;
13240         }
13241       else
13242         break;
13243     }
13244
13245   if (is_set == 0)
13246     {
13247       errmsg ("Value not set\n");
13248       return -99;
13249     }
13250
13251   /* Construct the API message */
13252   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13253
13254   mp->is_en = is_en;
13255
13256   /* send it... */
13257   S;
13258
13259   /* Wait for a reply... */
13260   W;
13261
13262   /* NOTREACHED */
13263   return 0;
13264 }
13265
13266 static int
13267 api_lisp_enable_disable (vat_main_t * vam)
13268 {
13269   unformat_input_t *input = vam->input;
13270   vl_api_lisp_enable_disable_t *mp;
13271   f64 timeout = ~0;
13272   u8 is_set = 0;
13273   u8 is_en = 0;
13274
13275   /* Parse args required to build the message */
13276   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13277     {
13278       if (unformat (input, "enable"))
13279         {
13280           is_set = 1;
13281           is_en = 1;
13282         }
13283       else if (unformat (input, "disable"))
13284         {
13285           is_set = 1;
13286         }
13287       else
13288         break;
13289     }
13290
13291   if (!is_set)
13292     {
13293       errmsg ("Value not set\n");
13294       return -99;
13295     }
13296
13297   /* Construct the API message */
13298   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13299
13300   mp->is_en = is_en;
13301
13302   /* send it... */
13303   S;
13304
13305   /* Wait for a reply... */
13306   W;
13307
13308   /* NOTREACHED */
13309   return 0;
13310 }
13311
13312 static int
13313 api_show_lisp_map_request_mode (vat_main_t * vam)
13314 {
13315   f64 timeout = ~0;
13316   vl_api_show_lisp_map_request_mode_t *mp;
13317
13318   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13319
13320   /* send */
13321   S;
13322
13323   /* wait for reply */
13324   W;
13325
13326   return 0;
13327 }
13328
13329 static int
13330 api_lisp_map_request_mode (vat_main_t * vam)
13331 {
13332   f64 timeout = ~0;
13333   unformat_input_t *input = vam->input;
13334   vl_api_lisp_map_request_mode_t *mp;
13335   u8 mode = 0;
13336
13337   /* Parse args required to build the message */
13338   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13339     {
13340       if (unformat (input, "dst-only"))
13341         mode = 0;
13342       else if (unformat (input, "src-dst"))
13343         mode = 1;
13344       else
13345         {
13346           errmsg ("parse error '%U'", format_unformat_error, input);
13347           return -99;
13348         }
13349     }
13350
13351   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13352
13353   mp->mode = mode;
13354
13355   /* send */
13356   S;
13357
13358   /* wait for reply */
13359   W;
13360
13361   /* notreached */
13362   return 0;
13363 }
13364
13365 /**
13366  * Enable/disable LISP proxy ITR.
13367  *
13368  * @param vam vpp API test context
13369  * @return return code
13370  */
13371 static int
13372 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13373 {
13374   f64 timeout = ~0;
13375   u8 ls_name_set = 0;
13376   unformat_input_t *input = vam->input;
13377   vl_api_lisp_pitr_set_locator_set_t *mp;
13378   u8 is_add = 1;
13379   u8 *ls_name = 0;
13380
13381   /* Parse args required to build the message */
13382   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13383     {
13384       if (unformat (input, "del"))
13385         is_add = 0;
13386       else if (unformat (input, "locator-set %s", &ls_name))
13387         ls_name_set = 1;
13388       else
13389         {
13390           errmsg ("parse error '%U'", format_unformat_error, input);
13391           return -99;
13392         }
13393     }
13394
13395   if (!ls_name_set)
13396     {
13397       errmsg ("locator-set name not set!");
13398       return -99;
13399     }
13400
13401   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13402
13403   mp->is_add = is_add;
13404   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13405   vec_free (ls_name);
13406
13407   /* send */
13408   S;
13409
13410   /* wait for reply */
13411   W;
13412
13413   /* notreached */
13414   return 0;
13415 }
13416
13417 static int
13418 api_show_lisp_pitr (vat_main_t * vam)
13419 {
13420   vl_api_show_lisp_pitr_t *mp;
13421   f64 timeout = ~0;
13422
13423   if (!vam->json_output)
13424     {
13425       fformat (vam->ofp, "%=20s\n", "lisp status:");
13426     }
13427
13428   M (SHOW_LISP_PITR, show_lisp_pitr);
13429   /* send it... */
13430   S;
13431
13432   /* Wait for a reply... */
13433   W;
13434
13435   /* NOTREACHED */
13436   return 0;
13437 }
13438
13439 /**
13440  * Add/delete mapping between vni and vrf
13441  */
13442 static int
13443 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13444 {
13445   f64 timeout = ~0;
13446   unformat_input_t *input = vam->input;
13447   vl_api_lisp_eid_table_add_del_map_t *mp;
13448   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13449   u32 vni, vrf, bd_index;
13450
13451   /* Parse args required to build the message */
13452   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13453     {
13454       if (unformat (input, "del"))
13455         is_add = 0;
13456       else if (unformat (input, "vrf %d", &vrf))
13457         vrf_set = 1;
13458       else if (unformat (input, "bd_index %d", &bd_index))
13459         bd_index_set = 1;
13460       else if (unformat (input, "vni %d", &vni))
13461         vni_set = 1;
13462       else
13463         break;
13464     }
13465
13466   if (!vni_set || (!vrf_set && !bd_index_set))
13467     {
13468       errmsg ("missing arguments!");
13469       return -99;
13470     }
13471
13472   if (vrf_set && bd_index_set)
13473     {
13474       errmsg ("error: both vrf and bd entered!");
13475       return -99;
13476     }
13477
13478   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13479
13480   mp->is_add = is_add;
13481   mp->vni = htonl (vni);
13482   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13483   mp->is_l2 = bd_index_set;
13484
13485   /* send */
13486   S;
13487
13488   /* wait for reply */
13489   W;
13490
13491   /* notreached */
13492   return 0;
13493 }
13494
13495 uword
13496 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13497 {
13498   u32 *action = va_arg (*args, u32 *);
13499   u8 *s = 0;
13500
13501   if (unformat (input, "%s", &s))
13502     {
13503       if (!strcmp ((char *) s, "no-action"))
13504         action[0] = 0;
13505       else if (!strcmp ((char *) s, "natively-forward"))
13506         action[0] = 1;
13507       else if (!strcmp ((char *) s, "send-map-request"))
13508         action[0] = 2;
13509       else if (!strcmp ((char *) s, "drop"))
13510         action[0] = 3;
13511       else
13512         {
13513           clib_warning ("invalid action: '%s'", s);
13514           action[0] = 3;
13515         }
13516     }
13517   else
13518     return 0;
13519
13520   vec_free (s);
13521   return 1;
13522 }
13523
13524 /**
13525  * Add/del remote mapping to/from LISP control plane
13526  *
13527  * @param vam vpp API test context
13528  * @return return code
13529  */
13530 static int
13531 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13532 {
13533   unformat_input_t *input = vam->input;
13534   vl_api_lisp_add_del_remote_mapping_t *mp;
13535   f64 timeout = ~0;
13536   u32 vni = 0;
13537   lisp_eid_vat_t _eid, *eid = &_eid;
13538   lisp_eid_vat_t _seid, *seid = &_seid;
13539   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13540   u32 action = ~0, p, w, data_len;
13541   ip4_address_t rloc4;
13542   ip6_address_t rloc6;
13543   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13544
13545   memset (&rloc, 0, sizeof (rloc));
13546
13547   /* Parse args required to build the message */
13548   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13549     {
13550       if (unformat (input, "del-all"))
13551         {
13552           del_all = 1;
13553         }
13554       else if (unformat (input, "del"))
13555         {
13556           is_add = 0;
13557         }
13558       else if (unformat (input, "add"))
13559         {
13560           is_add = 1;
13561         }
13562       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13563         {
13564           eid_set = 1;
13565         }
13566       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13567         {
13568           seid_set = 1;
13569         }
13570       else if (unformat (input, "vni %d", &vni))
13571         {
13572           ;
13573         }
13574       else if (unformat (input, "p %d w %d", &p, &w))
13575         {
13576           if (!curr_rloc)
13577             {
13578               errmsg ("No RLOC configured for setting priority/weight!");
13579               return -99;
13580             }
13581           curr_rloc->priority = p;
13582           curr_rloc->weight = w;
13583         }
13584       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13585         {
13586           rloc.is_ip4 = 1;
13587           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13588           vec_add1 (rlocs, rloc);
13589           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13590         }
13591       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13592         {
13593           rloc.is_ip4 = 0;
13594           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13595           vec_add1 (rlocs, rloc);
13596           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13597         }
13598       else if (unformat (input, "action %U",
13599                          unformat_negative_mapping_action, &action))
13600         {
13601           ;
13602         }
13603       else
13604         {
13605           clib_warning ("parse error '%U'", format_unformat_error, input);
13606           return -99;
13607         }
13608     }
13609
13610   if (0 == eid_set)
13611     {
13612       errmsg ("missing params!");
13613       return -99;
13614     }
13615
13616   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13617     {
13618       errmsg ("no action set for negative map-reply!");
13619       return -99;
13620     }
13621
13622   data_len = vec_len (rlocs) * sizeof (rloc_t);
13623
13624   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13625   mp->is_add = is_add;
13626   mp->vni = htonl (vni);
13627   mp->action = (u8) action;
13628   mp->is_src_dst = seid_set;
13629   mp->eid_len = eid->len;
13630   mp->seid_len = seid->len;
13631   mp->del_all = del_all;
13632   mp->eid_type = eid->type;
13633   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13634   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13635
13636   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13637   clib_memcpy (mp->rlocs, rlocs, data_len);
13638   vec_free (rlocs);
13639
13640   /* send it... */
13641   S;
13642
13643   /* Wait for a reply... */
13644   W;
13645
13646   /* NOTREACHED */
13647   return 0;
13648 }
13649
13650 /**
13651  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13652  * forwarding entries in data-plane accordingly.
13653  *
13654  * @param vam vpp API test context
13655  * @return return code
13656  */
13657 static int
13658 api_lisp_add_del_adjacency (vat_main_t * vam)
13659 {
13660   unformat_input_t *input = vam->input;
13661   vl_api_lisp_add_del_adjacency_t *mp;
13662   f64 timeout = ~0;
13663   u32 vni = 0;
13664   ip4_address_t leid4, reid4;
13665   ip6_address_t leid6, reid6;
13666   u8 reid_mac[6] = { 0 };
13667   u8 leid_mac[6] = { 0 };
13668   u8 reid_type, leid_type;
13669   u32 leid_len = 0, reid_len = 0, len;
13670   u8 is_add = 1;
13671
13672   leid_type = reid_type = (u8) ~ 0;
13673
13674   /* Parse args required to build the message */
13675   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13676     {
13677       if (unformat (input, "del"))
13678         {
13679           is_add = 0;
13680         }
13681       else if (unformat (input, "add"))
13682         {
13683           is_add = 1;
13684         }
13685       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13686                          &reid4, &len))
13687         {
13688           reid_type = 0;        /* ipv4 */
13689           reid_len = len;
13690         }
13691       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13692                          &reid6, &len))
13693         {
13694           reid_type = 1;        /* ipv6 */
13695           reid_len = len;
13696         }
13697       else if (unformat (input, "reid %U", unformat_ethernet_address,
13698                          reid_mac))
13699         {
13700           reid_type = 2;        /* mac */
13701         }
13702       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13703                          &leid4, &len))
13704         {
13705           leid_type = 0;        /* ipv4 */
13706           leid_len = len;
13707         }
13708       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13709                          &leid6, &len))
13710         {
13711           leid_type = 1;        /* ipv6 */
13712           leid_len = len;
13713         }
13714       else if (unformat (input, "leid %U", unformat_ethernet_address,
13715                          leid_mac))
13716         {
13717           leid_type = 2;        /* mac */
13718         }
13719       else if (unformat (input, "vni %d", &vni))
13720         {
13721           ;
13722         }
13723       else
13724         {
13725           errmsg ("parse error '%U'", format_unformat_error, input);
13726           return -99;
13727         }
13728     }
13729
13730   if ((u8) ~ 0 == reid_type)
13731     {
13732       errmsg ("missing params!");
13733       return -99;
13734     }
13735
13736   if (leid_type != reid_type)
13737     {
13738       errmsg ("remote and local EIDs are of different types!");
13739       return -99;
13740     }
13741
13742   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13743   mp->is_add = is_add;
13744   mp->vni = htonl (vni);
13745   mp->leid_len = leid_len;
13746   mp->reid_len = reid_len;
13747   mp->eid_type = reid_type;
13748
13749   switch (mp->eid_type)
13750     {
13751     case 0:
13752       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13753       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13754       break;
13755     case 1:
13756       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13757       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13758       break;
13759     case 2:
13760       clib_memcpy (mp->leid, leid_mac, 6);
13761       clib_memcpy (mp->reid, reid_mac, 6);
13762       break;
13763     default:
13764       errmsg ("unknown EID type %d!", mp->eid_type);
13765       return 0;
13766     }
13767
13768   /* send it... */
13769   S;
13770
13771   /* Wait for a reply... */
13772   W;
13773
13774   /* NOTREACHED */
13775   return 0;
13776 }
13777
13778 static int
13779 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13780 {
13781   unformat_input_t *input = vam->input;
13782   vl_api_lisp_gpe_add_del_iface_t *mp;
13783   f64 timeout = ~0;
13784   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13785   u32 dp_table = 0, vni = 0;
13786
13787   /* Parse args required to build the message */
13788   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13789     {
13790       if (unformat (input, "up"))
13791         {
13792           action_set = 1;
13793           is_add = 1;
13794         }
13795       else if (unformat (input, "down"))
13796         {
13797           action_set = 1;
13798           is_add = 0;
13799         }
13800       else if (unformat (input, "table_id %d", &dp_table))
13801         {
13802           dp_table_set = 1;
13803         }
13804       else if (unformat (input, "bd_id %d", &dp_table))
13805         {
13806           dp_table_set = 1;
13807           is_l2 = 1;
13808         }
13809       else if (unformat (input, "vni %d", &vni))
13810         {
13811           vni_set = 1;
13812         }
13813       else
13814         break;
13815     }
13816
13817   if (action_set == 0)
13818     {
13819       errmsg ("Action not set\n");
13820       return -99;
13821     }
13822   if (dp_table_set == 0 || vni_set == 0)
13823     {
13824       errmsg ("vni and dp_table must be set\n");
13825       return -99;
13826     }
13827
13828   /* Construct the API message */
13829   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13830
13831   mp->is_add = is_add;
13832   mp->dp_table = dp_table;
13833   mp->is_l2 = is_l2;
13834   mp->vni = vni;
13835
13836   /* send it... */
13837   S;
13838
13839   /* Wait for a reply... */
13840   W;
13841
13842   /* NOTREACHED */
13843   return 0;
13844 }
13845
13846 /**
13847  * Add/del map request itr rlocs from LISP control plane and updates
13848  *
13849  * @param vam vpp API test context
13850  * @return return code
13851  */
13852 static int
13853 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13854 {
13855   unformat_input_t *input = vam->input;
13856   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13857   f64 timeout = ~0;
13858   u8 *locator_set_name = 0;
13859   u8 locator_set_name_set = 0;
13860   u8 is_add = 1;
13861
13862   /* Parse args required to build the message */
13863   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13864     {
13865       if (unformat (input, "del"))
13866         {
13867           is_add = 0;
13868         }
13869       else if (unformat (input, "%_%v%_", &locator_set_name))
13870         {
13871           locator_set_name_set = 1;
13872         }
13873       else
13874         {
13875           clib_warning ("parse error '%U'", format_unformat_error, input);
13876           return -99;
13877         }
13878     }
13879
13880   if (is_add && !locator_set_name_set)
13881     {
13882       errmsg ("itr-rloc is not set!");
13883       return -99;
13884     }
13885
13886   if (is_add && vec_len (locator_set_name) > 64)
13887     {
13888       errmsg ("itr-rloc locator-set name too long\n");
13889       vec_free (locator_set_name);
13890       return -99;
13891     }
13892
13893   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13894   mp->is_add = is_add;
13895   if (is_add)
13896     {
13897       clib_memcpy (mp->locator_set_name, locator_set_name,
13898                    vec_len (locator_set_name));
13899     }
13900   else
13901     {
13902       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13903     }
13904   vec_free (locator_set_name);
13905
13906   /* send it... */
13907   S;
13908
13909   /* Wait for a reply... */
13910   W;
13911
13912   /* NOTREACHED */
13913   return 0;
13914 }
13915
13916 static int
13917 api_lisp_locator_dump (vat_main_t * vam)
13918 {
13919   unformat_input_t *input = vam->input;
13920   vl_api_lisp_locator_dump_t *mp;
13921   f64 timeout = ~0;
13922   u8 is_index_set = 0, is_name_set = 0;
13923   u8 *ls_name = 0;
13924   u32 ls_index = ~0;
13925
13926   /* Parse args required to build the message */
13927   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13928     {
13929       if (unformat (input, "ls_name %_%v%_", &ls_name))
13930         {
13931           is_name_set = 1;
13932         }
13933       else if (unformat (input, "ls_index %d", &ls_index))
13934         {
13935           is_index_set = 1;
13936         }
13937       else
13938         {
13939           errmsg ("parse error '%U'", format_unformat_error, input);
13940           return -99;
13941         }
13942     }
13943
13944   if (!is_index_set && !is_name_set)
13945     {
13946       errmsg ("error: expected one of index or name!\n");
13947       return -99;
13948     }
13949
13950   if (is_index_set && is_name_set)
13951     {
13952       errmsg ("error: only one param expected!\n");
13953       return -99;
13954     }
13955
13956   if (vec_len (ls_name) > 62)
13957     {
13958       errmsg ("error: locator set name too long!");
13959       return -99;
13960     }
13961
13962   if (!vam->json_output)
13963     {
13964       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13965                "weight");
13966     }
13967
13968   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13969   mp->is_index_set = is_index_set;
13970
13971   if (is_index_set)
13972     mp->ls_index = clib_host_to_net_u32 (ls_index);
13973   else
13974     {
13975       vec_add1 (ls_name, 0);
13976       strncpy ((char *) mp->ls_name, (char *) ls_name,
13977                sizeof (mp->ls_name) - 1);
13978     }
13979
13980   /* send it... */
13981   S;
13982
13983   /* Use a control ping for synchronization */
13984   {
13985     vl_api_control_ping_t *mp;
13986     M (CONTROL_PING, control_ping);
13987     S;
13988   }
13989   /* Wait for a reply... */
13990   W;
13991
13992   /* NOTREACHED */
13993   return 0;
13994 }
13995
13996 static int
13997 api_lisp_locator_set_dump (vat_main_t * vam)
13998 {
13999   vl_api_lisp_locator_set_dump_t *mp;
14000   unformat_input_t *input = vam->input;
14001   f64 timeout = ~0;
14002   u8 filter = 0;
14003
14004   /* Parse args required to build the message */
14005   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14006     {
14007       if (unformat (input, "local"))
14008         {
14009           filter = 1;
14010         }
14011       else if (unformat (input, "remote"))
14012         {
14013           filter = 2;
14014         }
14015       else
14016         {
14017           errmsg ("parse error '%U'", format_unformat_error, input);
14018           return -99;
14019         }
14020     }
14021
14022   if (!vam->json_output)
14023     {
14024       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
14025     }
14026
14027   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14028
14029   mp->filter = filter;
14030
14031   /* send it... */
14032   S;
14033
14034   /* Use a control ping for synchronization */
14035   {
14036     vl_api_control_ping_t *mp;
14037     M (CONTROL_PING, control_ping);
14038     S;
14039   }
14040   /* Wait for a reply... */
14041   W;
14042
14043   /* NOTREACHED */
14044   return 0;
14045 }
14046
14047 static int
14048 api_lisp_eid_table_map_dump (vat_main_t * vam)
14049 {
14050   u8 is_l2 = 0;
14051   u8 mode_set = 0;
14052   unformat_input_t *input = vam->input;
14053   vl_api_lisp_eid_table_map_dump_t *mp;
14054   f64 timeout = ~0;
14055
14056   /* Parse args required to build the message */
14057   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14058     {
14059       if (unformat (input, "l2"))
14060         {
14061           is_l2 = 1;
14062           mode_set = 1;
14063         }
14064       else if (unformat (input, "l3"))
14065         {
14066           is_l2 = 0;
14067           mode_set = 1;
14068         }
14069       else
14070         {
14071           errmsg ("parse error '%U'", format_unformat_error, input);
14072           return -99;
14073         }
14074     }
14075
14076   if (!mode_set)
14077     {
14078       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
14079       return -99;
14080     }
14081
14082   if (!vam->json_output)
14083     {
14084       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
14085     }
14086
14087   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14088   mp->is_l2 = is_l2;
14089
14090   /* send it... */
14091   S;
14092
14093   /* Use a control ping for synchronization */
14094   {
14095     vl_api_control_ping_t *mp;
14096     M (CONTROL_PING, control_ping);
14097     S;
14098   }
14099   /* Wait for a reply... */
14100   W;
14101
14102   /* NOTREACHED */
14103   return 0;
14104 }
14105
14106 static int
14107 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14108 {
14109   vl_api_lisp_eid_table_vni_dump_t *mp;
14110   f64 timeout = ~0;
14111
14112   if (!vam->json_output)
14113     {
14114       fformat (vam->ofp, "VNI\n");
14115     }
14116
14117   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14118
14119   /* send it... */
14120   S;
14121
14122   /* Use a control ping for synchronization */
14123   {
14124     vl_api_control_ping_t *mp;
14125     M (CONTROL_PING, control_ping);
14126     S;
14127   }
14128   /* Wait for a reply... */
14129   W;
14130
14131   /* NOTREACHED */
14132   return 0;
14133 }
14134
14135 static int
14136 api_lisp_eid_table_dump (vat_main_t * vam)
14137 {
14138   unformat_input_t *i = vam->input;
14139   vl_api_lisp_eid_table_dump_t *mp;
14140   f64 timeout = ~0;
14141   struct in_addr ip4;
14142   struct in6_addr ip6;
14143   u8 mac[6];
14144   u8 eid_type = ~0, eid_set = 0;
14145   u32 prefix_length = ~0, t, vni = 0;
14146   u8 filter = 0;
14147
14148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14149     {
14150       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14151         {
14152           eid_set = 1;
14153           eid_type = 0;
14154           prefix_length = t;
14155         }
14156       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14157         {
14158           eid_set = 1;
14159           eid_type = 1;
14160           prefix_length = t;
14161         }
14162       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14163         {
14164           eid_set = 1;
14165           eid_type = 2;
14166         }
14167       else if (unformat (i, "vni %d", &t))
14168         {
14169           vni = t;
14170         }
14171       else if (unformat (i, "local"))
14172         {
14173           filter = 1;
14174         }
14175       else if (unformat (i, "remote"))
14176         {
14177           filter = 2;
14178         }
14179       else
14180         {
14181           errmsg ("parse error '%U'", format_unformat_error, i);
14182           return -99;
14183         }
14184     }
14185
14186   if (!vam->json_output)
14187     {
14188       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
14189                "ls_index", "ttl", "authoritative");
14190     }
14191
14192   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14193
14194   mp->filter = filter;
14195   if (eid_set)
14196     {
14197       mp->eid_set = 1;
14198       mp->vni = htonl (vni);
14199       mp->eid_type = eid_type;
14200       switch (eid_type)
14201         {
14202         case 0:
14203           mp->prefix_length = prefix_length;
14204           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14205           break;
14206         case 1:
14207           mp->prefix_length = prefix_length;
14208           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14209           break;
14210         case 2:
14211           clib_memcpy (mp->eid, mac, sizeof (mac));
14212           break;
14213         default:
14214           errmsg ("unknown EID type %d!", eid_type);
14215           return -99;
14216         }
14217     }
14218
14219   /* send it... */
14220   S;
14221
14222   /* Use a control ping for synchronization */
14223   {
14224     vl_api_control_ping_t *mp;
14225     M (CONTROL_PING, control_ping);
14226     S;
14227   }
14228
14229   /* Wait for a reply... */
14230   W;
14231
14232   /* NOTREACHED */
14233   return 0;
14234 }
14235
14236 static int
14237 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14238 {
14239   vl_api_lisp_gpe_tunnel_dump_t *mp;
14240   f64 timeout = ~0;
14241
14242   if (!vam->json_output)
14243     {
14244       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14245                "%=16s%=16s%=16s%=16s%=16s\n",
14246                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14247                "Decap next", "Lisp version", "Flags", "Next protocol",
14248                "ver_res", "res", "iid");
14249     }
14250
14251   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14252   /* send it... */
14253   S;
14254
14255   /* Use a control ping for synchronization */
14256   {
14257     vl_api_control_ping_t *mp;
14258     M (CONTROL_PING, control_ping);
14259     S;
14260   }
14261   /* Wait for a reply... */
14262   W;
14263
14264   /* NOTREACHED */
14265   return 0;
14266 }
14267
14268 static int
14269 api_lisp_adjacencies_get (vat_main_t * vam)
14270 {
14271   unformat_input_t *i = vam->input;
14272   vl_api_lisp_adjacencies_get_t *mp;
14273   f64 timeout = ~0;
14274   u8 vni_set = 0;
14275   u32 vni = ~0;
14276
14277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14278     {
14279       if (unformat (i, "vni %d", &vni))
14280         {
14281           vni_set = 1;
14282         }
14283       else
14284         {
14285           errmsg ("parse error '%U'\n", format_unformat_error, i);
14286           return -99;
14287         }
14288     }
14289
14290   if (!vni_set)
14291     {
14292       errmsg ("vni not set!\n");
14293       return -99;
14294     }
14295
14296   if (!vam->json_output)
14297     {
14298       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14299     }
14300
14301   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14302   mp->vni = clib_host_to_net_u32 (vni);
14303
14304   /* send it... */
14305   S;
14306
14307   /* Wait for a reply... */
14308   W;
14309
14310   /* NOTREACHED */
14311   return 0;
14312 }
14313
14314 static int
14315 api_lisp_map_resolver_dump (vat_main_t * vam)
14316 {
14317   vl_api_lisp_map_resolver_dump_t *mp;
14318   f64 timeout = ~0;
14319
14320   if (!vam->json_output)
14321     {
14322       fformat (vam->ofp, "%=20s\n", "Map resolver");
14323     }
14324
14325   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14326   /* send it... */
14327   S;
14328
14329   /* Use a control ping for synchronization */
14330   {
14331     vl_api_control_ping_t *mp;
14332     M (CONTROL_PING, control_ping);
14333     S;
14334   }
14335   /* Wait for a reply... */
14336   W;
14337
14338   /* NOTREACHED */
14339   return 0;
14340 }
14341
14342 static int
14343 api_show_lisp_status (vat_main_t * vam)
14344 {
14345   vl_api_show_lisp_status_t *mp;
14346   f64 timeout = ~0;
14347
14348   if (!vam->json_output)
14349     {
14350       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14351     }
14352
14353   M (SHOW_LISP_STATUS, show_lisp_status);
14354   /* send it... */
14355   S;
14356   /* Wait for a reply... */
14357   W;
14358
14359   /* NOTREACHED */
14360   return 0;
14361 }
14362
14363 static int
14364 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14365 {
14366   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14367   f64 timeout = ~0;
14368
14369   if (!vam->json_output)
14370     {
14371       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14372     }
14373
14374   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14375   /* send it... */
14376   S;
14377   /* Wait for a reply... */
14378   W;
14379
14380   /* NOTREACHED */
14381   return 0;
14382 }
14383
14384 static int
14385 api_af_packet_create (vat_main_t * vam)
14386 {
14387   unformat_input_t *i = vam->input;
14388   vl_api_af_packet_create_t *mp;
14389   f64 timeout;
14390   u8 *host_if_name = 0;
14391   u8 hw_addr[6];
14392   u8 random_hw_addr = 1;
14393
14394   memset (hw_addr, 0, sizeof (hw_addr));
14395
14396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14397     {
14398       if (unformat (i, "name %s", &host_if_name))
14399         vec_add1 (host_if_name, 0);
14400       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14401         random_hw_addr = 0;
14402       else
14403         break;
14404     }
14405
14406   if (!vec_len (host_if_name))
14407     {
14408       errmsg ("host-interface name must be specified");
14409       return -99;
14410     }
14411
14412   if (vec_len (host_if_name) > 64)
14413     {
14414       errmsg ("host-interface name too long");
14415       return -99;
14416     }
14417
14418   M (AF_PACKET_CREATE, af_packet_create);
14419
14420   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14421   clib_memcpy (mp->hw_addr, hw_addr, 6);
14422   mp->use_random_hw_addr = random_hw_addr;
14423   vec_free (host_if_name);
14424
14425   S;
14426   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14427   /* NOTREACHED */
14428   return 0;
14429 }
14430
14431 static int
14432 api_af_packet_delete (vat_main_t * vam)
14433 {
14434   unformat_input_t *i = vam->input;
14435   vl_api_af_packet_delete_t *mp;
14436   f64 timeout;
14437   u8 *host_if_name = 0;
14438
14439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14440     {
14441       if (unformat (i, "name %s", &host_if_name))
14442         vec_add1 (host_if_name, 0);
14443       else
14444         break;
14445     }
14446
14447   if (!vec_len (host_if_name))
14448     {
14449       errmsg ("host-interface name must be specified");
14450       return -99;
14451     }
14452
14453   if (vec_len (host_if_name) > 64)
14454     {
14455       errmsg ("host-interface name too long");
14456       return -99;
14457     }
14458
14459   M (AF_PACKET_DELETE, af_packet_delete);
14460
14461   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14462   vec_free (host_if_name);
14463
14464   S;
14465   W;
14466   /* NOTREACHED */
14467   return 0;
14468 }
14469
14470 static int
14471 api_policer_add_del (vat_main_t * vam)
14472 {
14473   unformat_input_t *i = vam->input;
14474   vl_api_policer_add_del_t *mp;
14475   f64 timeout;
14476   u8 is_add = 1;
14477   u8 *name = 0;
14478   u32 cir = 0;
14479   u32 eir = 0;
14480   u64 cb = 0;
14481   u64 eb = 0;
14482   u8 rate_type = 0;
14483   u8 round_type = 0;
14484   u8 type = 0;
14485   u8 color_aware = 0;
14486   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14487
14488   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14489   conform_action.dscp = 0;
14490   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14491   exceed_action.dscp = 0;
14492   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14493   violate_action.dscp = 0;
14494
14495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14496     {
14497       if (unformat (i, "del"))
14498         is_add = 0;
14499       else if (unformat (i, "name %s", &name))
14500         vec_add1 (name, 0);
14501       else if (unformat (i, "cir %u", &cir))
14502         ;
14503       else if (unformat (i, "eir %u", &eir))
14504         ;
14505       else if (unformat (i, "cb %u", &cb))
14506         ;
14507       else if (unformat (i, "eb %u", &eb))
14508         ;
14509       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14510                          &rate_type))
14511         ;
14512       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14513                          &round_type))
14514         ;
14515       else if (unformat (i, "type %U", unformat_policer_type, &type))
14516         ;
14517       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14518                          &conform_action))
14519         ;
14520       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14521                          &exceed_action))
14522         ;
14523       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14524                          &violate_action))
14525         ;
14526       else if (unformat (i, "color-aware"))
14527         color_aware = 1;
14528       else
14529         break;
14530     }
14531
14532   if (!vec_len (name))
14533     {
14534       errmsg ("policer name must be specified");
14535       return -99;
14536     }
14537
14538   if (vec_len (name) > 64)
14539     {
14540       errmsg ("policer name too long");
14541       return -99;
14542     }
14543
14544   M (POLICER_ADD_DEL, policer_add_del);
14545
14546   clib_memcpy (mp->name, name, vec_len (name));
14547   vec_free (name);
14548   mp->is_add = is_add;
14549   mp->cir = cir;
14550   mp->eir = eir;
14551   mp->cb = cb;
14552   mp->eb = eb;
14553   mp->rate_type = rate_type;
14554   mp->round_type = round_type;
14555   mp->type = type;
14556   mp->conform_action_type = conform_action.action_type;
14557   mp->conform_dscp = conform_action.dscp;
14558   mp->exceed_action_type = exceed_action.action_type;
14559   mp->exceed_dscp = exceed_action.dscp;
14560   mp->violate_action_type = violate_action.action_type;
14561   mp->violate_dscp = violate_action.dscp;
14562   mp->color_aware = color_aware;
14563
14564   S;
14565   W;
14566   /* NOTREACHED */
14567   return 0;
14568 }
14569
14570 static int
14571 api_policer_dump (vat_main_t * vam)
14572 {
14573   unformat_input_t *i = vam->input;
14574   vl_api_policer_dump_t *mp;
14575   f64 timeout = ~0;
14576   u8 *match_name = 0;
14577   u8 match_name_valid = 0;
14578
14579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14580     {
14581       if (unformat (i, "name %s", &match_name))
14582         {
14583           vec_add1 (match_name, 0);
14584           match_name_valid = 1;
14585         }
14586       else
14587         break;
14588     }
14589
14590   M (POLICER_DUMP, policer_dump);
14591   mp->match_name_valid = match_name_valid;
14592   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14593   vec_free (match_name);
14594   /* send it... */
14595   S;
14596
14597   /* Use a control ping for synchronization */
14598   {
14599     vl_api_control_ping_t *mp;
14600     M (CONTROL_PING, control_ping);
14601     S;
14602   }
14603   /* Wait for a reply... */
14604   W;
14605
14606   /* NOTREACHED */
14607   return 0;
14608 }
14609
14610 static int
14611 api_policer_classify_set_interface (vat_main_t * vam)
14612 {
14613   unformat_input_t *i = vam->input;
14614   vl_api_policer_classify_set_interface_t *mp;
14615   f64 timeout;
14616   u32 sw_if_index;
14617   int sw_if_index_set;
14618   u32 ip4_table_index = ~0;
14619   u32 ip6_table_index = ~0;
14620   u32 l2_table_index = ~0;
14621   u8 is_add = 1;
14622
14623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14624     {
14625       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14626         sw_if_index_set = 1;
14627       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14628         sw_if_index_set = 1;
14629       else if (unformat (i, "del"))
14630         is_add = 0;
14631       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14632         ;
14633       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14634         ;
14635       else if (unformat (i, "l2-table %d", &l2_table_index))
14636         ;
14637       else
14638         {
14639           clib_warning ("parse error '%U'", format_unformat_error, i);
14640           return -99;
14641         }
14642     }
14643
14644   if (sw_if_index_set == 0)
14645     {
14646       errmsg ("missing interface name or sw_if_index\n");
14647       return -99;
14648     }
14649
14650   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14651
14652   mp->sw_if_index = ntohl (sw_if_index);
14653   mp->ip4_table_index = ntohl (ip4_table_index);
14654   mp->ip6_table_index = ntohl (ip6_table_index);
14655   mp->l2_table_index = ntohl (l2_table_index);
14656   mp->is_add = is_add;
14657
14658   S;
14659   W;
14660   /* NOTREACHED */
14661   return 0;
14662 }
14663
14664 static int
14665 api_policer_classify_dump (vat_main_t * vam)
14666 {
14667   unformat_input_t *i = vam->input;
14668   vl_api_policer_classify_dump_t *mp;
14669   f64 timeout = ~0;
14670   u8 type = POLICER_CLASSIFY_N_TABLES;
14671
14672   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14673     ;
14674   else
14675     {
14676       errmsg ("classify table type must be specified\n");
14677       return -99;
14678     }
14679
14680   if (!vam->json_output)
14681     {
14682       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14683     }
14684
14685   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14686   mp->type = type;
14687   /* send it... */
14688   S;
14689
14690   /* Use a control ping for synchronization */
14691   {
14692     vl_api_control_ping_t *mp;
14693     M (CONTROL_PING, control_ping);
14694     S;
14695   }
14696   /* Wait for a reply... */
14697   W;
14698
14699   /* NOTREACHED */
14700   return 0;
14701 }
14702
14703 static int
14704 api_netmap_create (vat_main_t * vam)
14705 {
14706   unformat_input_t *i = vam->input;
14707   vl_api_netmap_create_t *mp;
14708   f64 timeout;
14709   u8 *if_name = 0;
14710   u8 hw_addr[6];
14711   u8 random_hw_addr = 1;
14712   u8 is_pipe = 0;
14713   u8 is_master = 0;
14714
14715   memset (hw_addr, 0, sizeof (hw_addr));
14716
14717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14718     {
14719       if (unformat (i, "name %s", &if_name))
14720         vec_add1 (if_name, 0);
14721       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14722         random_hw_addr = 0;
14723       else if (unformat (i, "pipe"))
14724         is_pipe = 1;
14725       else if (unformat (i, "master"))
14726         is_master = 1;
14727       else if (unformat (i, "slave"))
14728         is_master = 0;
14729       else
14730         break;
14731     }
14732
14733   if (!vec_len (if_name))
14734     {
14735       errmsg ("interface name must be specified");
14736       return -99;
14737     }
14738
14739   if (vec_len (if_name) > 64)
14740     {
14741       errmsg ("interface name too long");
14742       return -99;
14743     }
14744
14745   M (NETMAP_CREATE, netmap_create);
14746
14747   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14748   clib_memcpy (mp->hw_addr, hw_addr, 6);
14749   mp->use_random_hw_addr = random_hw_addr;
14750   mp->is_pipe = is_pipe;
14751   mp->is_master = is_master;
14752   vec_free (if_name);
14753
14754   S;
14755   W;
14756   /* NOTREACHED */
14757   return 0;
14758 }
14759
14760 static int
14761 api_netmap_delete (vat_main_t * vam)
14762 {
14763   unformat_input_t *i = vam->input;
14764   vl_api_netmap_delete_t *mp;
14765   f64 timeout;
14766   u8 *if_name = 0;
14767
14768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14769     {
14770       if (unformat (i, "name %s", &if_name))
14771         vec_add1 (if_name, 0);
14772       else
14773         break;
14774     }
14775
14776   if (!vec_len (if_name))
14777     {
14778       errmsg ("interface name must be specified");
14779       return -99;
14780     }
14781
14782   if (vec_len (if_name) > 64)
14783     {
14784       errmsg ("interface name too long");
14785       return -99;
14786     }
14787
14788   M (NETMAP_DELETE, netmap_delete);
14789
14790   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14791   vec_free (if_name);
14792
14793   S;
14794   W;
14795   /* NOTREACHED */
14796   return 0;
14797 }
14798
14799 static void vl_api_mpls_eth_tunnel_details_t_handler
14800   (vl_api_mpls_eth_tunnel_details_t * mp)
14801 {
14802   vat_main_t *vam = &vat_main;
14803   i32 i;
14804   i32 len = ntohl (mp->nlabels);
14805
14806   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14807            ntohl (mp->tunnel_index),
14808            format_ethernet_address, &mp->tunnel_dst_mac,
14809            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14810   for (i = 0; i < len; i++)
14811     {
14812       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14813     }
14814   fformat (vam->ofp, "\n");
14815   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14816            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14817 }
14818
14819 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14820   (vl_api_mpls_eth_tunnel_details_t * mp)
14821 {
14822   vat_main_t *vam = &vat_main;
14823   vat_json_node_t *node = NULL;
14824   struct in_addr ip4;
14825   i32 i;
14826   i32 len = ntohl (mp->nlabels);
14827
14828   if (VAT_JSON_ARRAY != vam->json_tree.type)
14829     {
14830       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14831       vat_json_init_array (&vam->json_tree);
14832     }
14833   node = vat_json_array_add (&vam->json_tree);
14834
14835   vat_json_init_object (node);
14836   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14837   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14838   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14839   vat_json_object_add_uint (node, "inner_fib_index",
14840                             ntohl (mp->inner_fib_index));
14841   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14842   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14843   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14844   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14845   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14846                                    format (0, "%U", format_ethernet_address,
14847                                            &mp->tunnel_dst_mac));
14848   vat_json_object_add_uint (node, "tx_sw_if_index",
14849                             ntohl (mp->tx_sw_if_index));
14850   vat_json_object_add_uint (node, "label_count", len);
14851   for (i = 0; i < len; i++)
14852     {
14853       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14854     }
14855 }
14856
14857 static int
14858 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14859 {
14860   vl_api_mpls_eth_tunnel_dump_t *mp;
14861   f64 timeout;
14862   i32 index = -1;
14863
14864   /* Parse args required to build the message */
14865   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14866     {
14867       if (!unformat (vam->input, "tunnel_index %d", &index))
14868         {
14869           index = -1;
14870           break;
14871         }
14872     }
14873
14874   fformat (vam->ofp, "  tunnel_index %d\n", index);
14875
14876   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14877   mp->tunnel_index = htonl (index);
14878   S;
14879
14880   /* Use a control ping for synchronization */
14881   {
14882     vl_api_control_ping_t *mp;
14883     M (CONTROL_PING, control_ping);
14884     S;
14885   }
14886   W;
14887 }
14888
14889 static void vl_api_mpls_fib_encap_details_t_handler
14890   (vl_api_mpls_fib_encap_details_t * mp)
14891 {
14892   vat_main_t *vam = &vat_main;
14893   i32 i;
14894   i32 len = ntohl (mp->nlabels);
14895
14896   fformat (vam->ofp, "table %d, dest %U, label ",
14897            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14898   for (i = 0; i < len; i++)
14899     {
14900       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14901     }
14902   fformat (vam->ofp, "\n");
14903 }
14904
14905 static void vl_api_mpls_fib_encap_details_t_handler_json
14906   (vl_api_mpls_fib_encap_details_t * mp)
14907 {
14908   vat_main_t *vam = &vat_main;
14909   vat_json_node_t *node = NULL;
14910   i32 i;
14911   i32 len = ntohl (mp->nlabels);
14912   struct in_addr ip4;
14913
14914   if (VAT_JSON_ARRAY != vam->json_tree.type)
14915     {
14916       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14917       vat_json_init_array (&vam->json_tree);
14918     }
14919   node = vat_json_array_add (&vam->json_tree);
14920
14921   vat_json_init_object (node);
14922   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14923   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14924   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14925   vat_json_object_add_ip4 (node, "dest", ip4);
14926   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14927   vat_json_object_add_uint (node, "label_count", len);
14928   for (i = 0; i < len; i++)
14929     {
14930       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14931     }
14932 }
14933
14934 static int
14935 api_mpls_fib_encap_dump (vat_main_t * vam)
14936 {
14937   vl_api_mpls_fib_encap_dump_t *mp;
14938   f64 timeout;
14939
14940   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14941   S;
14942
14943   /* Use a control ping for synchronization */
14944   {
14945     vl_api_control_ping_t *mp;
14946     M (CONTROL_PING, control_ping);
14947     S;
14948   }
14949   W;
14950 }
14951
14952 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
14953 #define vl_api_mpls_fib_details_t_print vl_noop_handler
14954
14955 static void
14956 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
14957 {
14958   vat_main_t *vam = &vat_main;
14959   int count = ntohl (mp->count);
14960   vl_api_fib_path_t *fp;
14961   int i;
14962
14963   fformat (vam->ofp,
14964            "table-id %d, label %u, ess_bit %u\n",
14965            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
14966   fp = mp->path;
14967   for (i = 0; i < count; i++)
14968     {
14969       if (fp->afi == IP46_TYPE_IP6)
14970         fformat (vam->ofp,
14971                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14972                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14973                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14974                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14975                  format_ip6_address, fp->next_hop);
14976       else if (fp->afi == IP46_TYPE_IP4)
14977         fformat (vam->ofp,
14978                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14979                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14980                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14981                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14982                  format_ip4_address, fp->next_hop);
14983       fp++;
14984     }
14985 }
14986
14987 static void vl_api_mpls_fib_details_t_handler_json
14988   (vl_api_mpls_fib_details_t * mp)
14989 {
14990   vat_main_t *vam = &vat_main;
14991   int count = ntohl (mp->count);
14992   vat_json_node_t *node = NULL;
14993   struct in_addr ip4;
14994   struct in6_addr ip6;
14995   vl_api_fib_path_t *fp;
14996   int i;
14997
14998   if (VAT_JSON_ARRAY != vam->json_tree.type)
14999     {
15000       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15001       vat_json_init_array (&vam->json_tree);
15002     }
15003   node = vat_json_array_add (&vam->json_tree);
15004
15005   vat_json_init_object (node);
15006   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15007   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15008   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15009   vat_json_object_add_uint (node, "path_count", count);
15010   fp = mp->path;
15011   for (i = 0; i < count; i++)
15012     {
15013       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15014       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15015       vat_json_object_add_uint (node, "is_local", fp->is_local);
15016       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15017       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15018       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15019       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15020       if (fp->afi == IP46_TYPE_IP4)
15021         {
15022           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15023           vat_json_object_add_ip4 (node, "next_hop", ip4);
15024         }
15025       else if (fp->afi == IP46_TYPE_IP6)
15026         {
15027           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15028           vat_json_object_add_ip6 (node, "next_hop", ip6);
15029         }
15030     }
15031 }
15032
15033 static int
15034 api_mpls_fib_dump (vat_main_t * vam)
15035 {
15036   vl_api_mpls_fib_dump_t *mp;
15037   f64 timeout;
15038
15039   M (MPLS_FIB_DUMP, mpls_fib_dump);
15040   S;
15041
15042   /* Use a control ping for synchronization */
15043   {
15044     vl_api_control_ping_t *mp;
15045     M (CONTROL_PING, control_ping);
15046     S;
15047   }
15048   W;
15049 }
15050
15051 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15052 #define vl_api_ip_fib_details_t_print vl_noop_handler
15053
15054 static void
15055 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15056 {
15057   vat_main_t *vam = &vat_main;
15058   int count = ntohl (mp->count);
15059   vl_api_fib_path_t *fp;
15060   int i;
15061
15062   fformat (vam->ofp,
15063            "table-id %d, prefix %U/%d\n",
15064            ntohl (mp->table_id), format_ip4_address, mp->address,
15065            mp->address_length);
15066   fp = mp->path;
15067   for (i = 0; i < count; i++)
15068     {
15069       if (fp->afi == IP46_TYPE_IP6)
15070         fformat (vam->ofp,
15071                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15072                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15073                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15074                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15075                  format_ip6_address, fp->next_hop);
15076       else if (fp->afi == IP46_TYPE_IP4)
15077         fformat (vam->ofp,
15078                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15079                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15080                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15081                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15082                  format_ip4_address, fp->next_hop);
15083       fp++;
15084     }
15085 }
15086
15087 static void vl_api_ip_fib_details_t_handler_json
15088   (vl_api_ip_fib_details_t * mp)
15089 {
15090   vat_main_t *vam = &vat_main;
15091   int count = ntohl (mp->count);
15092   vat_json_node_t *node = NULL;
15093   struct in_addr ip4;
15094   struct in6_addr ip6;
15095   vl_api_fib_path_t *fp;
15096   int i;
15097
15098   if (VAT_JSON_ARRAY != vam->json_tree.type)
15099     {
15100       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15101       vat_json_init_array (&vam->json_tree);
15102     }
15103   node = vat_json_array_add (&vam->json_tree);
15104
15105   vat_json_init_object (node);
15106   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15107   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15108   vat_json_object_add_ip4 (node, "prefix", ip4);
15109   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15110   vat_json_object_add_uint (node, "path_count", count);
15111   fp = mp->path;
15112   for (i = 0; i < count; i++)
15113     {
15114       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15115       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15116       vat_json_object_add_uint (node, "is_local", fp->is_local);
15117       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15118       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15119       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15120       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15121       if (fp->afi == IP46_TYPE_IP4)
15122         {
15123           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15124           vat_json_object_add_ip4 (node, "next_hop", ip4);
15125         }
15126       else if (fp->afi == IP46_TYPE_IP6)
15127         {
15128           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15129           vat_json_object_add_ip6 (node, "next_hop", ip6);
15130         }
15131     }
15132 }
15133
15134 static int
15135 api_ip_fib_dump (vat_main_t * vam)
15136 {
15137   vl_api_ip_fib_dump_t *mp;
15138   f64 timeout;
15139
15140   M (IP_FIB_DUMP, ip_fib_dump);
15141   S;
15142
15143   /* Use a control ping for synchronization */
15144   {
15145     vl_api_control_ping_t *mp;
15146     M (CONTROL_PING, control_ping);
15147     S;
15148   }
15149   W;
15150 }
15151
15152 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15153 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15154
15155 static void
15156 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15157 {
15158   vat_main_t *vam = &vat_main;
15159   int count = ntohl (mp->count);
15160   vl_api_fib_path_t *fp;
15161   int i;
15162
15163   fformat (vam->ofp,
15164            "table-id %d, prefix %U/%d\n",
15165            ntohl (mp->table_id), format_ip6_address, mp->address,
15166            mp->address_length);
15167   fp = mp->path;
15168   for (i = 0; i < count; i++)
15169     {
15170       if (fp->afi == IP46_TYPE_IP6)
15171         fformat (vam->ofp,
15172                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15173                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15174                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15175                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15176                  format_ip6_address, fp->next_hop);
15177       else if (fp->afi == IP46_TYPE_IP4)
15178         fformat (vam->ofp,
15179                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15180                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15181                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15182                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15183                  format_ip4_address, fp->next_hop);
15184       fp++;
15185     }
15186 }
15187
15188 static void vl_api_ip6_fib_details_t_handler_json
15189   (vl_api_ip6_fib_details_t * mp)
15190 {
15191   vat_main_t *vam = &vat_main;
15192   int count = ntohl (mp->count);
15193   vat_json_node_t *node = NULL;
15194   struct in_addr ip4;
15195   struct in6_addr ip6;
15196   vl_api_fib_path_t *fp;
15197   int i;
15198
15199   if (VAT_JSON_ARRAY != vam->json_tree.type)
15200     {
15201       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15202       vat_json_init_array (&vam->json_tree);
15203     }
15204   node = vat_json_array_add (&vam->json_tree);
15205
15206   vat_json_init_object (node);
15207   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15208   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15209   vat_json_object_add_ip6 (node, "prefix", ip6);
15210   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15211   vat_json_object_add_uint (node, "path_count", count);
15212   fp = mp->path;
15213   for (i = 0; i < count; i++)
15214     {
15215       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15216       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15217       vat_json_object_add_uint (node, "is_local", fp->is_local);
15218       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15219       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15220       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15221       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15222       if (fp->afi == IP46_TYPE_IP4)
15223         {
15224           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15225           vat_json_object_add_ip4 (node, "next_hop", ip4);
15226         }
15227       else if (fp->afi == IP46_TYPE_IP6)
15228         {
15229           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15230           vat_json_object_add_ip6 (node, "next_hop", ip6);
15231         }
15232     }
15233 }
15234
15235 static int
15236 api_ip6_fib_dump (vat_main_t * vam)
15237 {
15238   vl_api_ip6_fib_dump_t *mp;
15239   f64 timeout;
15240
15241   M (IP6_FIB_DUMP, ip6_fib_dump);
15242   S;
15243
15244   /* Use a control ping for synchronization */
15245   {
15246     vl_api_control_ping_t *mp;
15247     M (CONTROL_PING, control_ping);
15248     S;
15249   }
15250   W;
15251 }
15252
15253 int
15254 api_classify_table_ids (vat_main_t * vam)
15255 {
15256   vl_api_classify_table_ids_t *mp;
15257   f64 timeout;
15258
15259   /* Construct the API message */
15260   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15261   mp->context = 0;
15262
15263   S;
15264   W;
15265   /* NOTREACHED */
15266   return 0;
15267 }
15268
15269 int
15270 api_classify_table_by_interface (vat_main_t * vam)
15271 {
15272   unformat_input_t *input = vam->input;
15273   vl_api_classify_table_by_interface_t *mp;
15274   f64 timeout;
15275
15276   u32 sw_if_index = ~0;
15277   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15278     {
15279       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15280         ;
15281       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15282         ;
15283       else
15284         break;
15285     }
15286   if (sw_if_index == ~0)
15287     {
15288       errmsg ("missing interface name or sw_if_index\n");
15289       return -99;
15290     }
15291
15292   /* Construct the API message */
15293   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15294   mp->context = 0;
15295   mp->sw_if_index = ntohl (sw_if_index);
15296
15297   S;
15298   W;
15299   /* NOTREACHED */
15300   return 0;
15301 }
15302
15303 int
15304 api_classify_table_info (vat_main_t * vam)
15305 {
15306   unformat_input_t *input = vam->input;
15307   vl_api_classify_table_info_t *mp;
15308   f64 timeout;
15309
15310   u32 table_id = ~0;
15311   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15312     {
15313       if (unformat (input, "table_id %d", &table_id))
15314         ;
15315       else
15316         break;
15317     }
15318   if (table_id == ~0)
15319     {
15320       errmsg ("missing table id\n");
15321       return -99;
15322     }
15323
15324   /* Construct the API message */
15325   M (CLASSIFY_TABLE_INFO, classify_table_info);
15326   mp->context = 0;
15327   mp->table_id = ntohl (table_id);
15328
15329   S;
15330   W;
15331   /* NOTREACHED */
15332   return 0;
15333 }
15334
15335 int
15336 api_classify_session_dump (vat_main_t * vam)
15337 {
15338   unformat_input_t *input = vam->input;
15339   vl_api_classify_session_dump_t *mp;
15340   f64 timeout;
15341
15342   u32 table_id = ~0;
15343   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15344     {
15345       if (unformat (input, "table_id %d", &table_id))
15346         ;
15347       else
15348         break;
15349     }
15350   if (table_id == ~0)
15351     {
15352       errmsg ("missing table id\n");
15353       return -99;
15354     }
15355
15356   /* Construct the API message */
15357   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15358   mp->context = 0;
15359   mp->table_id = ntohl (table_id);
15360   S;
15361
15362   /* Use a control ping for synchronization */
15363   {
15364     vl_api_control_ping_t *mp;
15365     M (CONTROL_PING, control_ping);
15366     S;
15367   }
15368   W;
15369   /* NOTREACHED */
15370   return 0;
15371 }
15372
15373 static void
15374 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15375 {
15376   vat_main_t *vam = &vat_main;
15377
15378   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15379            "src_address %U, vrf_id %d, path_mtu %u, "
15380            "template_interval %u, udp_checksum %d\n",
15381            format_ip4_address, mp->collector_address,
15382            ntohs (mp->collector_port),
15383            format_ip4_address, mp->src_address,
15384            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15385            ntohl (mp->template_interval), mp->udp_checksum);
15386
15387   vam->retval = 0;
15388   vam->result_ready = 1;
15389 }
15390
15391 static void
15392   vl_api_ipfix_exporter_details_t_handler_json
15393   (vl_api_ipfix_exporter_details_t * mp)
15394 {
15395   vat_main_t *vam = &vat_main;
15396   vat_json_node_t node;
15397   struct in_addr collector_address;
15398   struct in_addr src_address;
15399
15400   vat_json_init_object (&node);
15401   clib_memcpy (&collector_address, &mp->collector_address,
15402                sizeof (collector_address));
15403   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15404   vat_json_object_add_uint (&node, "collector_port",
15405                             ntohs (mp->collector_port));
15406   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15407   vat_json_object_add_ip4 (&node, "src_address", src_address);
15408   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15409   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15410   vat_json_object_add_uint (&node, "template_interval",
15411                             ntohl (mp->template_interval));
15412   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15413
15414   vat_json_print (vam->ofp, &node);
15415   vat_json_free (&node);
15416   vam->retval = 0;
15417   vam->result_ready = 1;
15418 }
15419
15420 int
15421 api_ipfix_exporter_dump (vat_main_t * vam)
15422 {
15423   vl_api_ipfix_exporter_dump_t *mp;
15424   f64 timeout;
15425
15426   /* Construct the API message */
15427   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15428   mp->context = 0;
15429
15430   S;
15431   W;
15432   /* NOTREACHED */
15433   return 0;
15434 }
15435
15436 static int
15437 api_ipfix_classify_stream_dump (vat_main_t * vam)
15438 {
15439   vl_api_ipfix_classify_stream_dump_t *mp;
15440   f64 timeout;
15441
15442   /* Construct the API message */
15443   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15444   mp->context = 0;
15445
15446   S;
15447   W;
15448   /* NOTREACHED */
15449   return 0;
15450 }
15451
15452 static void
15453   vl_api_ipfix_classify_stream_details_t_handler
15454   (vl_api_ipfix_classify_stream_details_t * mp)
15455 {
15456   vat_main_t *vam = &vat_main;
15457   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15458            ntohl (mp->domain_id), ntohs (mp->src_port));
15459   vam->retval = 0;
15460   vam->result_ready = 1;
15461 }
15462
15463 static void
15464   vl_api_ipfix_classify_stream_details_t_handler_json
15465   (vl_api_ipfix_classify_stream_details_t * mp)
15466 {
15467   vat_main_t *vam = &vat_main;
15468   vat_json_node_t node;
15469
15470   vat_json_init_object (&node);
15471   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15472   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15473
15474   vat_json_print (vam->ofp, &node);
15475   vat_json_free (&node);
15476   vam->retval = 0;
15477   vam->result_ready = 1;
15478 }
15479
15480 static int
15481 api_ipfix_classify_table_dump (vat_main_t * vam)
15482 {
15483   vl_api_ipfix_classify_table_dump_t *mp;
15484   f64 timeout;
15485
15486   if (!vam->json_output)
15487     {
15488       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15489                "transport_protocol");
15490     }
15491
15492   /* Construct the API message */
15493   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15494
15495   /* send it... */
15496   S;
15497
15498   /* Use a control ping for synchronization */
15499   {
15500     vl_api_control_ping_t *mp;
15501     M (CONTROL_PING, control_ping);
15502     S;
15503   }
15504   W;
15505 }
15506
15507 static void
15508   vl_api_ipfix_classify_table_details_t_handler
15509   (vl_api_ipfix_classify_table_details_t * mp)
15510 {
15511   vat_main_t *vam = &vat_main;
15512   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15513            mp->transport_protocol);
15514 }
15515
15516 static void
15517   vl_api_ipfix_classify_table_details_t_handler_json
15518   (vl_api_ipfix_classify_table_details_t * mp)
15519 {
15520   vat_json_node_t *node = NULL;
15521   vat_main_t *vam = &vat_main;
15522
15523   if (VAT_JSON_ARRAY != vam->json_tree.type)
15524     {
15525       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15526       vat_json_init_array (&vam->json_tree);
15527     }
15528
15529   node = vat_json_array_add (&vam->json_tree);
15530   vat_json_init_object (node);
15531
15532   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15533   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15534   vat_json_object_add_uint (node, "transport_protocol",
15535                             mp->transport_protocol);
15536 }
15537
15538 static int
15539 api_sw_interface_span_enable_disable (vat_main_t * vam)
15540 {
15541   unformat_input_t *i = vam->input;
15542   vl_api_sw_interface_span_enable_disable_t *mp;
15543   f64 timeout;
15544   u32 src_sw_if_index = ~0;
15545   u32 dst_sw_if_index = ~0;
15546   u8 enable = 1;
15547
15548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15549     {
15550       if (unformat (i, "src %U", unformat_sw_if_index, vam, &src_sw_if_index))
15551         ;
15552       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15553         ;
15554       else
15555         if (unformat
15556             (i, "dst %U", unformat_sw_if_index, vam, &dst_sw_if_index))
15557         ;
15558       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15559         ;
15560       else if (unformat (i, "disable"))
15561         enable = 0;
15562       else
15563         break;
15564     }
15565
15566   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15567
15568   mp->sw_if_index_from = htonl (src_sw_if_index);
15569   mp->sw_if_index_to = htonl (dst_sw_if_index);
15570   mp->enable = enable;
15571
15572   S;
15573   W;
15574   /* NOTREACHED */
15575   return 0;
15576 }
15577
15578 static void
15579 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
15580                                             * mp)
15581 {
15582   vat_main_t *vam = &vat_main;
15583
15584   fformat (vam->ofp, "%u => %u\n",
15585            ntohl (mp->sw_if_index_from), ntohl (mp->sw_if_index_to));
15586 }
15587
15588 static void
15589   vl_api_sw_interface_span_details_t_handler_json
15590   (vl_api_sw_interface_span_details_t * mp)
15591 {
15592   vat_main_t *vam = &vat_main;
15593   vat_json_node_t *node = NULL;
15594
15595   if (VAT_JSON_ARRAY != vam->json_tree.type)
15596     {
15597       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15598       vat_json_init_array (&vam->json_tree);
15599     }
15600   node = vat_json_array_add (&vam->json_tree);
15601
15602   vat_json_init_object (node);
15603   vat_json_object_add_uint (node, "src-if-index",
15604                             ntohl (mp->sw_if_index_from));
15605   vat_json_object_add_uint (node, "dst-if-index", ntohl (mp->sw_if_index_to));
15606 }
15607
15608 static int
15609 api_sw_interface_span_dump (vat_main_t * vam)
15610 {
15611   vl_api_sw_interface_span_dump_t *mp;
15612   f64 timeout;
15613
15614   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
15615   S;
15616
15617   /* Use a control ping for synchronization */
15618   {
15619     vl_api_control_ping_t *mp;
15620     M (CONTROL_PING, control_ping);
15621     S;
15622   }
15623   W;
15624 }
15625
15626 int
15627 api_pg_create_interface (vat_main_t * vam)
15628 {
15629   unformat_input_t *input = vam->input;
15630   vl_api_pg_create_interface_t *mp;
15631   f64 timeout;
15632
15633   u32 if_id = ~0;
15634   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15635     {
15636       if (unformat (input, "if_id %d", &if_id))
15637         ;
15638       else
15639         break;
15640     }
15641   if (if_id == ~0)
15642     {
15643       errmsg ("missing pg interface index\n");
15644       return -99;
15645     }
15646
15647   /* Construct the API message */
15648   M (PG_CREATE_INTERFACE, pg_create_interface);
15649   mp->context = 0;
15650   mp->interface_id = ntohl (if_id);
15651
15652   S;
15653   W;
15654   /* NOTREACHED */
15655   return 0;
15656 }
15657
15658 int
15659 api_pg_capture (vat_main_t * vam)
15660 {
15661   unformat_input_t *input = vam->input;
15662   vl_api_pg_capture_t *mp;
15663   f64 timeout;
15664
15665   u32 if_id = ~0;
15666   u8 enable = 1;
15667   u32 count = 1;
15668   u8 pcap_file_set = 0;
15669   u8 *pcap_file = 0;
15670   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15671     {
15672       if (unformat (input, "if_id %d", &if_id))
15673         ;
15674       else if (unformat (input, "pcap %s", &pcap_file))
15675         pcap_file_set = 1;
15676       else if (unformat (input, "count %d", &count))
15677         ;
15678       else if (unformat (input, "disable"))
15679         enable = 0;
15680       else
15681         break;
15682     }
15683   if (if_id == ~0)
15684     {
15685       errmsg ("missing pg interface index\n");
15686       return -99;
15687     }
15688   if (pcap_file_set > 0)
15689     {
15690       if (vec_len (pcap_file) > 255)
15691         {
15692           errmsg ("pcap file name is too long\n");
15693           return -99;
15694         }
15695     }
15696
15697   u32 name_len = vec_len (pcap_file);
15698   /* Construct the API message */
15699   M (PG_CAPTURE, pg_capture);
15700   mp->context = 0;
15701   mp->interface_id = ntohl (if_id);
15702   mp->is_enabled = enable;
15703   mp->count = ntohl (count);
15704   mp->pcap_name_length = ntohl (name_len);
15705   if (pcap_file_set != 0)
15706     {
15707       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15708     }
15709   vec_free (pcap_file);
15710
15711   S;
15712   W;
15713   /* NOTREACHED */
15714   return 0;
15715 }
15716
15717 int
15718 api_pg_enable_disable (vat_main_t * vam)
15719 {
15720   unformat_input_t *input = vam->input;
15721   vl_api_pg_enable_disable_t *mp;
15722   f64 timeout;
15723
15724   u8 enable = 1;
15725   u8 stream_name_set = 0;
15726   u8 *stream_name = 0;
15727   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15728     {
15729       if (unformat (input, "stream %s", &stream_name))
15730         stream_name_set = 1;
15731       else if (unformat (input, "disable"))
15732         enable = 0;
15733       else
15734         break;
15735     }
15736
15737   if (stream_name_set > 0)
15738     {
15739       if (vec_len (stream_name) > 255)
15740         {
15741           errmsg ("stream name too long\n");
15742           return -99;
15743         }
15744     }
15745
15746   u32 name_len = vec_len (stream_name);
15747   /* Construct the API message */
15748   M (PG_ENABLE_DISABLE, pg_enable_disable);
15749   mp->context = 0;
15750   mp->is_enabled = enable;
15751   if (stream_name_set != 0)
15752     {
15753       mp->stream_name_length = ntohl (name_len);
15754       clib_memcpy (mp->stream_name, stream_name, name_len);
15755     }
15756   vec_free (stream_name);
15757
15758   S;
15759   W;
15760   /* NOTREACHED */
15761   return 0;
15762 }
15763
15764 int
15765 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15766 {
15767   unformat_input_t *input = vam->input;
15768   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15769   f64 timeout;
15770
15771   u16 *low_ports = 0;
15772   u16 *high_ports = 0;
15773   u16 this_low;
15774   u16 this_hi;
15775   ip4_address_t ip4_addr;
15776   ip6_address_t ip6_addr;
15777   u32 length;
15778   u32 tmp, tmp2;
15779   u8 prefix_set = 0;
15780   u32 vrf_id = ~0;
15781   u8 is_add = 1;
15782   u8 is_ipv6 = 0;
15783
15784   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15785     {
15786       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15787         {
15788           prefix_set = 1;
15789         }
15790       else
15791         if (unformat
15792             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15793         {
15794           prefix_set = 1;
15795           is_ipv6 = 1;
15796         }
15797       else if (unformat (input, "vrf %d", &vrf_id))
15798         ;
15799       else if (unformat (input, "del"))
15800         is_add = 0;
15801       else if (unformat (input, "port %d", &tmp))
15802         {
15803           if (tmp == 0 || tmp > 65535)
15804             {
15805               errmsg ("port %d out of range", tmp);
15806               return -99;
15807             }
15808           this_low = tmp;
15809           this_hi = this_low + 1;
15810           vec_add1 (low_ports, this_low);
15811           vec_add1 (high_ports, this_hi);
15812         }
15813       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15814         {
15815           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15816             {
15817               errmsg ("incorrect range parameters\n");
15818               return -99;
15819             }
15820           this_low = tmp;
15821           /* Note: in debug CLI +1 is added to high before
15822              passing to real fn that does "the work"
15823              (ip_source_and_port_range_check_add_del).
15824              This fn is a wrapper around the binary API fn a
15825              control plane will call, which expects this increment
15826              to have occurred. Hence letting the binary API control
15827              plane fn do the increment for consistency between VAT
15828              and other control planes.
15829            */
15830           this_hi = tmp2;
15831           vec_add1 (low_ports, this_low);
15832           vec_add1 (high_ports, this_hi);
15833         }
15834       else
15835         break;
15836     }
15837
15838   if (prefix_set == 0)
15839     {
15840       errmsg ("<address>/<mask> not specified\n");
15841       return -99;
15842     }
15843
15844   if (vrf_id == ~0)
15845     {
15846       errmsg ("VRF ID required, not specified\n");
15847       return -99;
15848     }
15849
15850   if (vrf_id == 0)
15851     {
15852       errmsg
15853         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15854       return -99;
15855     }
15856
15857   if (vec_len (low_ports) == 0)
15858     {
15859       errmsg ("At least one port or port range required\n");
15860       return -99;
15861     }
15862
15863   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15864      ip_source_and_port_range_check_add_del);
15865
15866   mp->is_add = is_add;
15867
15868   if (is_ipv6)
15869     {
15870       mp->is_ipv6 = 1;
15871       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15872     }
15873   else
15874     {
15875       mp->is_ipv6 = 0;
15876       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15877     }
15878
15879   mp->mask_length = length;
15880   mp->number_of_ranges = vec_len (low_ports);
15881
15882   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15883   vec_free (low_ports);
15884
15885   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15886   vec_free (high_ports);
15887
15888   mp->vrf_id = ntohl (vrf_id);
15889
15890   S;
15891   W;
15892   /* NOTREACHED */
15893   return 0;
15894 }
15895
15896 int
15897 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15898 {
15899   unformat_input_t *input = vam->input;
15900   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15901   f64 timeout;
15902   u32 sw_if_index = ~0;
15903   int vrf_set = 0;
15904   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15905   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15906   u8 is_add = 1;
15907
15908   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15909     {
15910       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15911         ;
15912       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15913         ;
15914       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15915         vrf_set = 1;
15916       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15917         vrf_set = 1;
15918       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15919         vrf_set = 1;
15920       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15921         vrf_set = 1;
15922       else if (unformat (input, "del"))
15923         is_add = 0;
15924       else
15925         break;
15926     }
15927
15928   if (sw_if_index == ~0)
15929     {
15930       errmsg ("Interface required but not specified\n");
15931       return -99;
15932     }
15933
15934   if (vrf_set == 0)
15935     {
15936       errmsg ("VRF ID required but not specified\n");
15937       return -99;
15938     }
15939
15940   if (tcp_out_vrf_id == 0
15941       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15942     {
15943       errmsg
15944         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15945       return -99;
15946     }
15947
15948   /* Construct the API message */
15949   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15950      ip_source_and_port_range_check_interface_add_del);
15951
15952   mp->sw_if_index = ntohl (sw_if_index);
15953   mp->is_add = is_add;
15954   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15955   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15956   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15957   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15958
15959   /* send it... */
15960   S;
15961
15962   /* Wait for a reply... */
15963   W;
15964 }
15965
15966 static int
15967 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15968 {
15969   unformat_input_t *i = vam->input;
15970   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15971   f64 timeout;
15972   u32 local_sa_id = 0;
15973   u32 remote_sa_id = 0;
15974   ip4_address_t src_address;
15975   ip4_address_t dst_address;
15976   u8 is_add = 1;
15977
15978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15979     {
15980       if (unformat (i, "local_sa %d", &local_sa_id))
15981         ;
15982       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15983         ;
15984       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15985         ;
15986       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15987         ;
15988       else if (unformat (i, "del"))
15989         is_add = 0;
15990       else
15991         {
15992           clib_warning ("parse error '%U'", format_unformat_error, i);
15993           return -99;
15994         }
15995     }
15996
15997   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15998
15999   mp->local_sa_id = ntohl (local_sa_id);
16000   mp->remote_sa_id = ntohl (remote_sa_id);
16001   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16002   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16003   mp->is_add = is_add;
16004
16005   S;
16006   W;
16007   /* NOTREACHED */
16008   return 0;
16009 }
16010
16011 static int
16012 api_punt (vat_main_t * vam)
16013 {
16014   unformat_input_t *i = vam->input;
16015   vl_api_punt_t *mp;
16016   f64 timeout;
16017   u32 ipv = ~0;
16018   u32 protocol = ~0;
16019   u32 port = ~0;
16020   int is_add = 1;
16021
16022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16023     {
16024       if (unformat (i, "ip %d", &ipv))
16025         ;
16026       else if (unformat (i, "protocol %d", &protocol))
16027         ;
16028       else if (unformat (i, "port %d", &port))
16029         ;
16030       else if (unformat (i, "del"))
16031         is_add = 0;
16032       else
16033         {
16034           clib_warning ("parse error '%U'", format_unformat_error, i);
16035           return -99;
16036         }
16037     }
16038
16039   M (PUNT, punt);
16040
16041   mp->is_add = (u8) is_add;
16042   mp->ipv = (u8) ipv;
16043   mp->l4_protocol = (u8) protocol;
16044   mp->l4_port = htons ((u16) port);
16045
16046   S;
16047   W;
16048   /* NOTREACHED */
16049   return 0;
16050 }
16051
16052 static void vl_api_ipsec_gre_tunnel_details_t_handler
16053   (vl_api_ipsec_gre_tunnel_details_t * mp)
16054 {
16055   vat_main_t *vam = &vat_main;
16056
16057   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
16058            ntohl (mp->sw_if_index),
16059            format_ip4_address, &mp->src_address,
16060            format_ip4_address, &mp->dst_address,
16061            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16062 }
16063
16064 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16065   (vl_api_ipsec_gre_tunnel_details_t * mp)
16066 {
16067   vat_main_t *vam = &vat_main;
16068   vat_json_node_t *node = NULL;
16069   struct in_addr ip4;
16070
16071   if (VAT_JSON_ARRAY != vam->json_tree.type)
16072     {
16073       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16074       vat_json_init_array (&vam->json_tree);
16075     }
16076   node = vat_json_array_add (&vam->json_tree);
16077
16078   vat_json_init_object (node);
16079   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16080   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16081   vat_json_object_add_ip4 (node, "src_address", ip4);
16082   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16083   vat_json_object_add_ip4 (node, "dst_address", ip4);
16084   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16085   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16086 }
16087
16088 static int
16089 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16090 {
16091   unformat_input_t *i = vam->input;
16092   vl_api_ipsec_gre_tunnel_dump_t *mp;
16093   f64 timeout;
16094   u32 sw_if_index;
16095   u8 sw_if_index_set = 0;
16096
16097   /* Parse args required to build the message */
16098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16099     {
16100       if (unformat (i, "sw_if_index %d", &sw_if_index))
16101         sw_if_index_set = 1;
16102       else
16103         break;
16104     }
16105
16106   if (sw_if_index_set == 0)
16107     {
16108       sw_if_index = ~0;
16109     }
16110
16111   if (!vam->json_output)
16112     {
16113       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
16114                "sw_if_index", "src_address", "dst_address",
16115                "local_sa_id", "remote_sa_id");
16116     }
16117
16118   /* Get list of gre-tunnel interfaces */
16119   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16120
16121   mp->sw_if_index = htonl (sw_if_index);
16122
16123   S;
16124
16125   /* Use a control ping for synchronization */
16126   {
16127     vl_api_control_ping_t *mp;
16128     M (CONTROL_PING, control_ping);
16129     S;
16130   }
16131   W;
16132 }
16133
16134 static int
16135 api_delete_subif (vat_main_t * vam)
16136 {
16137   unformat_input_t *i = vam->input;
16138   vl_api_delete_subif_t *mp;
16139   f64 timeout;
16140   u32 sw_if_index = ~0;
16141
16142   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16143     {
16144       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16145         ;
16146       if (unformat (i, "sw_if_index %d", &sw_if_index))
16147         ;
16148       else
16149         break;
16150     }
16151
16152   if (sw_if_index == ~0)
16153     {
16154       errmsg ("missing sw_if_index\n");
16155       return -99;
16156     }
16157
16158   /* Construct the API message */
16159   M (DELETE_SUBIF, delete_subif);
16160   mp->sw_if_index = ntohl (sw_if_index);
16161
16162   S;
16163   W;
16164 }
16165
16166 #define foreach_pbb_vtr_op      \
16167 _("disable",  L2_VTR_DISABLED)  \
16168 _("pop",  L2_VTR_POP_2)         \
16169 _("push",  L2_VTR_PUSH_2)
16170
16171 static int
16172 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16173 {
16174   unformat_input_t *i = vam->input;
16175   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16176   f64 timeout;
16177   u32 sw_if_index = ~0, vtr_op = ~0;
16178   u16 outer_tag = ~0;
16179   u8 dmac[6], smac[6];
16180   u8 dmac_set = 0, smac_set = 0;
16181   u16 vlanid = 0;
16182   u32 sid = ~0;
16183   u32 tmp;
16184
16185   /* Shut up coverity */
16186   memset (dmac, 0, sizeof (dmac));
16187   memset (smac, 0, sizeof (smac));
16188
16189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16190     {
16191       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16192         ;
16193       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16194         ;
16195       else if (unformat (i, "vtr_op %d", &vtr_op))
16196         ;
16197 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16198       foreach_pbb_vtr_op
16199 #undef _
16200         else if (unformat (i, "translate_pbb_stag"))
16201         {
16202           if (unformat (i, "%d", &tmp))
16203             {
16204               vtr_op = L2_VTR_TRANSLATE_2_1;
16205               outer_tag = tmp;
16206             }
16207           else
16208             {
16209               errmsg
16210                 ("translate_pbb_stag operation requires outer tag definition\n");
16211               return -99;
16212             }
16213         }
16214       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16215         dmac_set++;
16216       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16217         smac_set++;
16218       else if (unformat (i, "sid %d", &sid))
16219         ;
16220       else if (unformat (i, "vlanid %d", &tmp))
16221         vlanid = tmp;
16222       else
16223         {
16224           clib_warning ("parse error '%U'", format_unformat_error, i);
16225           return -99;
16226         }
16227     }
16228
16229   if ((sw_if_index == ~0) || (vtr_op == ~0))
16230     {
16231       errmsg ("missing sw_if_index or vtr operation\n");
16232       return -99;
16233     }
16234   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16235       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16236     {
16237       errmsg
16238         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
16239       return -99;
16240     }
16241
16242   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16243   mp->sw_if_index = ntohl (sw_if_index);
16244   mp->vtr_op = ntohl (vtr_op);
16245   mp->outer_tag = ntohs (outer_tag);
16246   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16247   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16248   mp->b_vlanid = ntohs (vlanid);
16249   mp->i_sid = ntohl (sid);
16250
16251   S;
16252   W;
16253   /* NOTREACHED */
16254   return 0;
16255 }
16256
16257 static int
16258 api_flow_classify_set_interface (vat_main_t * vam)
16259 {
16260   unformat_input_t *i = vam->input;
16261   vl_api_flow_classify_set_interface_t *mp;
16262   f64 timeout;
16263   u32 sw_if_index;
16264   int sw_if_index_set;
16265   u32 ip4_table_index = ~0;
16266   u32 ip6_table_index = ~0;
16267   u8 is_add = 1;
16268
16269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16270     {
16271       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16272         sw_if_index_set = 1;
16273       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16274         sw_if_index_set = 1;
16275       else if (unformat (i, "del"))
16276         is_add = 0;
16277       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16278         ;
16279       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16280         ;
16281       else
16282         {
16283           clib_warning ("parse error '%U'", format_unformat_error, i);
16284           return -99;
16285         }
16286     }
16287
16288   if (sw_if_index_set == 0)
16289     {
16290       errmsg ("missing interface name or sw_if_index\n");
16291       return -99;
16292     }
16293
16294   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16295
16296   mp->sw_if_index = ntohl (sw_if_index);
16297   mp->ip4_table_index = ntohl (ip4_table_index);
16298   mp->ip6_table_index = ntohl (ip6_table_index);
16299   mp->is_add = is_add;
16300
16301   S;
16302   W;
16303   /* NOTREACHED */
16304   return 0;
16305 }
16306
16307 static int
16308 api_flow_classify_dump (vat_main_t * vam)
16309 {
16310   unformat_input_t *i = vam->input;
16311   vl_api_flow_classify_dump_t *mp;
16312   f64 timeout = ~0;
16313   u8 type = FLOW_CLASSIFY_N_TABLES;
16314
16315   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16316     ;
16317   else
16318     {
16319       errmsg ("classify table type must be specified\n");
16320       return -99;
16321     }
16322
16323   if (!vam->json_output)
16324     {
16325       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
16326     }
16327
16328   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16329   mp->type = type;
16330   /* send it... */
16331   S;
16332
16333   /* Use a control ping for synchronization */
16334   {
16335     vl_api_control_ping_t *mp;
16336     M (CONTROL_PING, control_ping);
16337     S;
16338   }
16339   /* Wait for a reply... */
16340   W;
16341
16342   /* NOTREACHED */
16343   return 0;
16344 }
16345
16346 static int
16347 api_feature_enable_disable (vat_main_t * vam)
16348 {
16349   unformat_input_t *i = vam->input;
16350   vl_api_feature_enable_disable_t *mp;
16351   f64 timeout;
16352   u8 *arc_name = 0;
16353   u8 *feature_name = 0;
16354   u32 sw_if_index = ~0;
16355   u8 enable = 1;
16356
16357   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16358     {
16359       if (unformat (i, "arc_name %s", &arc_name))
16360         ;
16361       else if (unformat (i, "feature_name %s", &feature_name))
16362         ;
16363       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16364         ;
16365       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16366         ;
16367       else if (unformat (i, "disable"))
16368         enable = 0;
16369       else
16370         break;
16371     }
16372
16373   if (arc_name == 0)
16374     {
16375       errmsg ("missing arc name\n");
16376       return -99;
16377     }
16378   if (vec_len (arc_name) > 63)
16379     {
16380       errmsg ("arc name too long\n");
16381     }
16382
16383   if (feature_name == 0)
16384     {
16385       errmsg ("missing feature name\n");
16386       return -99;
16387     }
16388   if (vec_len (feature_name) > 63)
16389     {
16390       errmsg ("feature name too long\n");
16391     }
16392
16393   if (sw_if_index == ~0)
16394     {
16395       errmsg ("missing interface name or sw_if_index\n");
16396       return -99;
16397     }
16398
16399   /* Construct the API message */
16400   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16401   mp->sw_if_index = ntohl (sw_if_index);
16402   mp->enable = enable;
16403   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16404   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16405   vec_free (arc_name);
16406   vec_free (feature_name);
16407
16408   S;
16409   W;
16410 }
16411
16412 static int
16413 q_or_quit (vat_main_t * vam)
16414 {
16415   longjmp (vam->jump_buf, 1);
16416   return 0;                     /* not so much */
16417 }
16418
16419 static int
16420 q (vat_main_t * vam)
16421 {
16422   return q_or_quit (vam);
16423 }
16424
16425 static int
16426 quit (vat_main_t * vam)
16427 {
16428   return q_or_quit (vam);
16429 }
16430
16431 static int
16432 comment (vat_main_t * vam)
16433 {
16434   return 0;
16435 }
16436
16437 static int
16438 cmd_cmp (void *a1, void *a2)
16439 {
16440   u8 **c1 = a1;
16441   u8 **c2 = a2;
16442
16443   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
16444 }
16445
16446 static int
16447 help (vat_main_t * vam)
16448 {
16449   u8 **cmds = 0;
16450   u8 *name = 0;
16451   hash_pair_t *p;
16452   unformat_input_t *i = vam->input;
16453   int j;
16454
16455   if (unformat (i, "%s", &name))
16456     {
16457       uword *hs;
16458
16459       vec_add1 (name, 0);
16460
16461       hs = hash_get_mem (vam->help_by_name, name);
16462       if (hs)
16463         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
16464       else
16465         fformat (vam->ofp, "No such msg / command '%s'\n", name);
16466       vec_free (name);
16467       return 0;
16468     }
16469
16470   fformat (vam->ofp, "Help is available for the following:\n");
16471
16472     /* *INDENT-OFF* */
16473     hash_foreach_pair (p, vam->function_by_name,
16474     ({
16475       vec_add1 (cmds, (u8 *)(p->key));
16476     }));
16477     /* *INDENT-ON* */
16478
16479   vec_sort_with_function (cmds, cmd_cmp);
16480
16481   for (j = 0; j < vec_len (cmds); j++)
16482     fformat (vam->ofp, "%s\n", cmds[j]);
16483
16484   vec_free (cmds);
16485   return 0;
16486 }
16487
16488 static int
16489 set (vat_main_t * vam)
16490 {
16491   u8 *name = 0, *value = 0;
16492   unformat_input_t *i = vam->input;
16493
16494   if (unformat (i, "%s", &name))
16495     {
16496       /* The input buffer is a vector, not a string. */
16497       value = vec_dup (i->buffer);
16498       vec_delete (value, i->index, 0);
16499       /* Almost certainly has a trailing newline */
16500       if (value[vec_len (value) - 1] == '\n')
16501         value[vec_len (value) - 1] = 0;
16502       /* Make sure it's a proper string, one way or the other */
16503       vec_add1 (value, 0);
16504       (void) clib_macro_set_value (&vam->macro_main,
16505                                    (char *) name, (char *) value);
16506     }
16507   else
16508     errmsg ("usage: set <name> <value>\n");
16509
16510   vec_free (name);
16511   vec_free (value);
16512   return 0;
16513 }
16514
16515 static int
16516 unset (vat_main_t * vam)
16517 {
16518   u8 *name = 0;
16519
16520   if (unformat (vam->input, "%s", &name))
16521     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
16522       errmsg ("unset: %s wasn't set\n", name);
16523   vec_free (name);
16524   return 0;
16525 }
16526
16527 typedef struct
16528 {
16529   u8 *name;
16530   u8 *value;
16531 } macro_sort_t;
16532
16533
16534 static int
16535 macro_sort_cmp (void *a1, void *a2)
16536 {
16537   macro_sort_t *s1 = a1;
16538   macro_sort_t *s2 = a2;
16539
16540   return strcmp ((char *) (s1->name), (char *) (s2->name));
16541 }
16542
16543 static int
16544 dump_macro_table (vat_main_t * vam)
16545 {
16546   macro_sort_t *sort_me = 0, *sm;
16547   int i;
16548   hash_pair_t *p;
16549
16550     /* *INDENT-OFF* */
16551     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
16552     ({
16553       vec_add2 (sort_me, sm, 1);
16554       sm->name = (u8 *)(p->key);
16555       sm->value = (u8 *) (p->value[0]);
16556     }));
16557     /* *INDENT-ON* */
16558
16559   vec_sort_with_function (sort_me, macro_sort_cmp);
16560
16561   if (vec_len (sort_me))
16562     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
16563   else
16564     fformat (vam->ofp, "The macro table is empty...\n");
16565
16566   for (i = 0; i < vec_len (sort_me); i++)
16567     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
16568   return 0;
16569 }
16570
16571 static int
16572 dump_node_table (vat_main_t * vam)
16573 {
16574   int i, j;
16575   vlib_node_t *node, *next_node;
16576
16577   if (vec_len (vam->graph_nodes) == 0)
16578     {
16579       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16580       return 0;
16581     }
16582
16583   for (i = 0; i < vec_len (vam->graph_nodes); i++)
16584     {
16585       node = vam->graph_nodes[i];
16586       fformat (vam->ofp, "[%d] %s\n", i, node->name);
16587       for (j = 0; j < vec_len (node->next_nodes); j++)
16588         {
16589           if (node->next_nodes[j] != ~0)
16590             {
16591               next_node = vam->graph_nodes[node->next_nodes[j]];
16592               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16593             }
16594         }
16595     }
16596   return 0;
16597 }
16598
16599 static int
16600 value_sort_cmp (void *a1, void *a2)
16601 {
16602   name_sort_t *n1 = a1;
16603   name_sort_t *n2 = a2;
16604
16605   if (n1->value < n2->value)
16606     return -1;
16607   if (n1->value > n2->value)
16608     return 1;
16609   return 0;
16610 }
16611
16612
16613 static int
16614 dump_msg_api_table (vat_main_t * vam)
16615 {
16616   api_main_t *am = &api_main;
16617   name_sort_t *nses = 0, *ns;
16618   hash_pair_t *hp;
16619   int i;
16620
16621   /* *INDENT-OFF* */
16622   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
16623   ({
16624     vec_add2 (nses, ns, 1);
16625     ns->name = (u8 *)(hp->key);
16626     ns->value = (u32) hp->value[0];
16627   }));
16628   /* *INDENT-ON* */
16629
16630   vec_sort_with_function (nses, value_sort_cmp);
16631
16632   for (i = 0; i < vec_len (nses); i++)
16633     fformat (vam->ofp, " [%d]: %s\n", nses[i].value, nses[i].name);
16634   vec_free (nses);
16635   return 0;
16636 }
16637
16638 static int
16639 get_msg_id (vat_main_t * vam)
16640 {
16641   u8 *name_and_crc;
16642   u32 message_index;
16643
16644   if (unformat (vam->input, "%s", &name_and_crc))
16645     {
16646       message_index = vl_api_get_msg_index (name_and_crc);
16647       if (message_index == ~0)
16648         {
16649           fformat (vam->ofp, " '%s' not found\n", name_and_crc);
16650           return 0;
16651         }
16652       fformat (vam->ofp, " '%s' has message index %d\n",
16653                name_and_crc, message_index);
16654       return 0;
16655     }
16656   errmsg ("name_and_crc required...\n");
16657   return 0;
16658 }
16659
16660 static int
16661 search_node_table (vat_main_t * vam)
16662 {
16663   unformat_input_t *line_input = vam->input;
16664   u8 *node_to_find;
16665   int j;
16666   vlib_node_t *node, *next_node;
16667   uword *p;
16668
16669   if (vam->graph_node_index_by_name == 0)
16670     {
16671       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16672       return 0;
16673     }
16674
16675   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16676     {
16677       if (unformat (line_input, "%s", &node_to_find))
16678         {
16679           vec_add1 (node_to_find, 0);
16680           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
16681           if (p == 0)
16682             {
16683               fformat (vam->ofp, "%s not found...\n", node_to_find);
16684               goto out;
16685             }
16686           node = vam->graph_nodes[p[0]];
16687           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
16688           for (j = 0; j < vec_len (node->next_nodes); j++)
16689             {
16690               if (node->next_nodes[j] != ~0)
16691                 {
16692                   next_node = vam->graph_nodes[node->next_nodes[j]];
16693                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16694                 }
16695             }
16696         }
16697
16698       else
16699         {
16700           clib_warning ("parse error '%U'", format_unformat_error,
16701                         line_input);
16702           return -99;
16703         }
16704
16705     out:
16706       vec_free (node_to_find);
16707
16708     }
16709
16710   return 0;
16711 }
16712
16713
16714 static int
16715 script (vat_main_t * vam)
16716 {
16717   u8 *s = 0;
16718   char *save_current_file;
16719   unformat_input_t save_input;
16720   jmp_buf save_jump_buf;
16721   u32 save_line_number;
16722
16723   FILE *new_fp, *save_ifp;
16724
16725   if (unformat (vam->input, "%s", &s))
16726     {
16727       new_fp = fopen ((char *) s, "r");
16728       if (new_fp == 0)
16729         {
16730           errmsg ("Couldn't open script file %s\n", s);
16731           vec_free (s);
16732           return -99;
16733         }
16734     }
16735   else
16736     {
16737       errmsg ("Missing script name\n");
16738       return -99;
16739     }
16740
16741   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
16742   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
16743   save_ifp = vam->ifp;
16744   save_line_number = vam->input_line_number;
16745   save_current_file = (char *) vam->current_file;
16746
16747   vam->input_line_number = 0;
16748   vam->ifp = new_fp;
16749   vam->current_file = s;
16750   do_one_file (vam);
16751
16752   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
16753   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
16754   vam->ifp = save_ifp;
16755   vam->input_line_number = save_line_number;
16756   vam->current_file = (u8 *) save_current_file;
16757   vec_free (s);
16758
16759   return 0;
16760 }
16761
16762 static int
16763 echo (vat_main_t * vam)
16764 {
16765   fformat (vam->ofp, "%v", vam->input->buffer);
16766   return 0;
16767 }
16768
16769 /* List of API message constructors, CLI names map to api_xxx */
16770 #define foreach_vpe_api_msg                                             \
16771 _(create_loopback,"[mac <mac-addr>]")                                   \
16772 _(sw_interface_dump,"")                                                 \
16773 _(sw_interface_set_flags,                                               \
16774   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
16775 _(sw_interface_add_del_address,                                         \
16776   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
16777 _(sw_interface_set_table,                                               \
16778   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
16779 _(sw_interface_set_mpls_enable,                                                \
16780   "<intfc> | sw_if_index [disable | dis]")                                \
16781 _(sw_interface_set_vpath,                                               \
16782   "<intfc> | sw_if_index <id> enable | disable")                        \
16783 _(sw_interface_set_vxlan_bypass,                                               \
16784   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")                        \
16785 _(sw_interface_set_l2_xconnect,                                         \
16786   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16787   "enable | disable")                                                   \
16788 _(sw_interface_set_l2_bridge,                                           \
16789   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16790   "[shg <split-horizon-group>] [bvi]\n"                                 \
16791   "enable | disable")                                                   \
16792 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16793   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16794   "profile <profile-id>\n")                                             \
16795 _(sw_interface_set_dpdk_hqos_subport,                                   \
16796   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16797   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16798 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16799   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16800 _(bridge_domain_add_del,                                                \
16801   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16802 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16803 _(l2fib_add_del,                                                        \
16804   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16805 _(l2_flags,                                                             \
16806   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16807 _(bridge_flags,                                                         \
16808   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16809 _(tap_connect,                                                          \
16810   "tapname <name> mac <mac-addr> | random-mac")                         \
16811 _(tap_modify,                                                           \
16812   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16813 _(tap_delete,                                                           \
16814   "<vpp-if-name> | sw_if_index <id>")                                   \
16815 _(sw_interface_tap_dump, "")                                            \
16816 _(ip_add_del_route,                                                     \
16817   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
16818   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16819   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16820   "[multipath] [count <n>]")                                            \
16821 _(mpls_route_add_del,                                                   \
16822   "<label> <eos> via <addr> [table-id <n>]\n"                           \
16823   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16824   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16825   "[multipath] [count <n>]")                                            \
16826 _(mpls_ip_bind_unbind,                                                  \
16827   "<label> <addr/len>")                                                 \
16828 _(proxy_arp_add_del,                                                    \
16829   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16830 _(proxy_arp_intfc_enable_disable,                                       \
16831   "<intfc> | sw_if_index <id> enable | disable")                        \
16832 _(mpls_add_del_encap,                                                   \
16833   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
16834 _(sw_interface_set_unnumbered,                                          \
16835   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16836 _(ip_neighbor_add_del,                                                  \
16837   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16838   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16839 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16840 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16841 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16842   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16843   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16844   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16845 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16846 _(reset_fib, "vrf <n> [ipv6]")                                          \
16847 _(dhcp_proxy_config,                                                    \
16848   "svr <v46-address> src <v46-address>\n"                               \
16849    "insert-cid <n> [del]")                                              \
16850 _(dhcp_proxy_config_2,                                                  \
16851   "svr <v46-address> src <v46-address>\n"                               \
16852    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16853 _(dhcp_proxy_set_vss,                                                   \
16854   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16855 _(dhcp_client_config,                                                   \
16856   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16857 _(set_ip_flow_hash,                                                     \
16858   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16859 _(sw_interface_ip6_enable_disable,                                      \
16860   "<intfc> | sw_if_index <id> enable | disable")                        \
16861 _(sw_interface_ip6_set_link_local_address,                              \
16862   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16863 _(sw_interface_ip6nd_ra_prefix,                                         \
16864   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16865   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16866   "[nolink] [isno]")                                                    \
16867 _(sw_interface_ip6nd_ra_config,                                         \
16868   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16869   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16870   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16871 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16872 _(l2_patch_add_del,                                                     \
16873   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16874   "enable | disable")                                                   \
16875 _(mpls_ethernet_add_del_tunnel,                                         \
16876   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
16877   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
16878 _(mpls_ethernet_add_del_tunnel_2,                                       \
16879   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
16880   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
16881 _(sr_tunnel_add_del,                                                    \
16882   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16883   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16884   "[policy <policy_name>]")                                             \
16885 _(sr_policy_add_del,                                                    \
16886   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16887 _(sr_multicast_map_add_del,                                             \
16888   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16889 _(classify_add_del_table,                                               \
16890   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16891   " [del] mask <mask-value>\n"                                          \
16892   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
16893   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
16894 _(classify_add_del_session,                                             \
16895   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16896   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16897   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
16898   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
16899 _(classify_set_interface_ip_table,                                      \
16900   "<intfc> | sw_if_index <nn> table <nn>")                              \
16901 _(classify_set_interface_l2_tables,                                     \
16902   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16903   "  [other-table <nn>]")                                               \
16904 _(get_node_index, "node <node-name")                                    \
16905 _(add_node_next, "node <node-name> next <next-node-name>")              \
16906 _(l2tpv3_create_tunnel,                                                 \
16907   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16908   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16909   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16910 _(l2tpv3_set_tunnel_cookies,                                            \
16911   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16912   "[new_remote_cookie <nn>]\n")                                         \
16913 _(l2tpv3_interface_enable_disable,                                      \
16914   "<intfc> | sw_if_index <nn> enable | disable")                        \
16915 _(l2tpv3_set_lookup_key,                                                \
16916   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16917 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16918 _(vxlan_add_del_tunnel,                                                 \
16919   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
16920   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
16921   "vni <vni> [encap-vrf-id <nn>] [decap-next l2|ip4|ip6] [del]")        \
16922 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16923 _(gre_add_del_tunnel,                                                   \
16924   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16925 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16926 _(l2_fib_clear_table, "")                                               \
16927 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16928 _(l2_interface_vlan_tag_rewrite,                                        \
16929   "<intfc> | sw_if_index <nn> \n"                                       \
16930   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
16931   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
16932 _(create_vhost_user_if,                                                 \
16933         "socket <filename> [server] [renumber <dev_instance>] "         \
16934         "[mac <mac_address>]")                                          \
16935 _(modify_vhost_user_if,                                                 \
16936         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
16937         "[server] [renumber <dev_instance>]")                           \
16938 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
16939 _(sw_interface_vhost_user_dump, "")                                     \
16940 _(show_version, "")                                                     \
16941 _(vxlan_gpe_add_del_tunnel,                                             \
16942   "local <addr> remote <addr> vni <nn>\n"                               \
16943     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
16944   "[next-ethernet] [next-nsh]\n")                                       \
16945 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
16946 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
16947 _(interface_name_renumber,                                              \
16948   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
16949 _(input_acl_set_interface,                                              \
16950   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16951   "  [l2-table <nn>] [del]")                                            \
16952 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
16953 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
16954 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
16955 _(ip_dump, "ipv4 | ipv6")                                               \
16956 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
16957 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
16958   "  spid_id <n> ")                                                     \
16959 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
16960   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
16961   "  integ_alg <alg> integ_key <hex>")                                  \
16962 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
16963   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
16964   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
16965   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
16966 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
16967 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
16968 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
16969   "(auth_data 0x<data> | auth_data <data>)")                            \
16970 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
16971   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
16972 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16973   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16974   "(local|remote)")                                                     \
16975 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16976 _(delete_loopback,"sw_if_index <nn>")                                   \
16977 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16978 _(map_add_domain,                                                       \
16979   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16980   "ip6-src <ip6addr> "                                                  \
16981   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16982 _(map_del_domain, "index <n>")                                          \
16983 _(map_add_del_rule,                                                     \
16984   "index <n> psid <n> dst <ip6addr> [del]")                             \
16985 _(map_domain_dump, "")                                                  \
16986 _(map_rule_dump, "index <map-domain>")                                  \
16987 _(want_interface_events,  "enable|disable")                             \
16988 _(want_stats,"enable|disable")                                          \
16989 _(get_first_msg_id, "client <name>")                                    \
16990 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16991 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16992   "fib-id <nn> [ip4][ip6][default]")                                    \
16993 _(get_node_graph, " ")                                                  \
16994 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16995 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16996 _(ioam_disable, "")                                                \
16997 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16998                             " sw_if_index <sw_if_index> p <priority> "  \
16999                             "w <weight>] [del]")                        \
17000 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
17001                         "iface <intf> | sw_if_index <sw_if_index> "     \
17002                         "p <priority> w <weight> [del]")                \
17003 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
17004                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
17005                           "locator-set <locator_name> [del]")           \
17006 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
17007   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
17008 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
17009 _(lisp_gpe_enable_disable, "enable|disable")                            \
17010 _(lisp_enable_disable, "enable|disable")                                \
17011 _(lisp_gpe_add_del_iface, "up|down")                                    \
17012 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17013                                "[seid <seid>] "                         \
17014                                "rloc <locator> p <prio> "               \
17015                                "w <weight> [rloc <loc> ... ] "          \
17016                                "action <action> [del-all]")             \
17017 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17018                           "<local-eid>")                                \
17019 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
17020 _(lisp_map_request_mode, "src-dst|dst-only")                            \
17021 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
17022 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
17023 _(lisp_locator_set_dump, "[local | remote]")                            \
17024 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
17025 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
17026                        "[local] | [remote]")                            \
17027 _(lisp_eid_table_vni_dump, "")                                          \
17028 _(lisp_eid_table_map_dump, "l2|l3")                                     \
17029 _(lisp_gpe_tunnel_dump, "")                                             \
17030 _(lisp_map_resolver_dump, "")                                           \
17031 _(lisp_adjacencies_get, "vni <vni>")                                    \
17032 _(show_lisp_status, "")                                                 \
17033 _(lisp_get_map_request_itr_rlocs, "")                                   \
17034 _(show_lisp_pitr, "")                                                   \
17035 _(show_lisp_map_request_mode, "")                                       \
17036 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
17037 _(af_packet_delete, "name <host interface name>")                       \
17038 _(policer_add_del, "name <policer name> <params> [del]")                \
17039 _(policer_dump, "[name <policer name>]")                                \
17040 _(policer_classify_set_interface,                                       \
17041   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17042   "  [l2-table <nn>] [del]")                                            \
17043 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
17044 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
17045     "[master|slave]")                                                   \
17046 _(netmap_delete, "name <interface name>")                               \
17047 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
17048 _(mpls_fib_encap_dump, "")                                              \
17049 _(mpls_fib_dump, "")                                                    \
17050 _(classify_table_ids, "")                                               \
17051 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
17052 _(classify_table_info, "table_id <nn>")                                 \
17053 _(classify_session_dump, "table_id <nn>")                               \
17054 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
17055     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
17056     "[template_interval <nn>] [udp_checksum]")                          \
17057 _(ipfix_exporter_dump, "")                                              \
17058 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17059 _(ipfix_classify_stream_dump, "")                                       \
17060 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
17061 _(ipfix_classify_table_dump, "")                                        \
17062 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [[dst <intfc> | dst_sw_if_index <id>] | disable]") \
17063 _(sw_interface_span_dump, "")                                           \
17064 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17065 _(pg_create_interface, "if_id <nn>")                                    \
17066 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17067 _(pg_enable_disable, "[stream <id>] disable")                           \
17068 _(ip_source_and_port_range_check_add_del,                               \
17069   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17070 _(ip_source_and_port_range_check_interface_add_del,                     \
17071   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17072   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17073 _(ipsec_gre_add_del_tunnel,                                             \
17074   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17075 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17076 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17077 _(l2_interface_pbb_tag_rewrite,                                         \
17078   "<intfc> | sw_if_index <nn> \n"                                       \
17079   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17080   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17081 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17082 _(flow_classify_set_interface,                                          \
17083   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17084 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17085 _(ip_fib_dump, "")                                                      \
17086 _(ip6_fib_dump, "")                                                     \
17087 _(feature_enable_disable, "arc_name <arc_name> "                        \
17088   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")
17089
17090 /* List of command functions, CLI names map directly to functions */
17091 #define foreach_cli_function                                    \
17092 _(comment, "usage: comment <ignore-rest-of-line>")              \
17093 _(dump_interface_table, "usage: dump_interface_table")          \
17094 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17095 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17096 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17097 _(dump_stats_table, "usage: dump_stats_table")                  \
17098 _(dump_macro_table, "usage: dump_macro_table ")                 \
17099 _(dump_node_table, "usage: dump_node_table")                    \
17100 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17101 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17102 _(echo, "usage: echo <message>")                                \
17103 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17104 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17105 _(help, "usage: help")                                          \
17106 _(q, "usage: quit")                                             \
17107 _(quit, "usage: quit")                                          \
17108 _(search_node_table, "usage: search_node_table <name>...")      \
17109 _(set, "usage: set <variable-name> <value>")                    \
17110 _(script, "usage: script <file-name>")                          \
17111 _(unset, "usage: unset <variable-name>")
17112
17113 #define _(N,n)                                  \
17114     static void vl_api_##n##_t_handler_uni      \
17115     (vl_api_##n##_t * mp)                       \
17116     {                                           \
17117         vat_main_t * vam = &vat_main;           \
17118         if (vam->json_output) {                 \
17119             vl_api_##n##_t_handler_json(mp);    \
17120         } else {                                \
17121             vl_api_##n##_t_handler(mp);         \
17122         }                                       \
17123     }
17124 foreach_vpe_api_reply_msg;
17125 #undef _
17126
17127 void
17128 vat_api_hookup (vat_main_t * vam)
17129 {
17130 #define _(N,n)                                                  \
17131     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17132                            vl_api_##n##_t_handler_uni,          \
17133                            vl_noop_handler,                     \
17134                            vl_api_##n##_t_endian,               \
17135                            vl_api_##n##_t_print,                \
17136                            sizeof(vl_api_##n##_t), 1);
17137   foreach_vpe_api_reply_msg;
17138 #undef _
17139
17140   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17141
17142   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17143
17144   vam->function_by_name = hash_create_string (0, sizeof (uword));
17145
17146   vam->help_by_name = hash_create_string (0, sizeof (uword));
17147
17148   /* API messages we can send */
17149 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17150   foreach_vpe_api_msg;
17151 #undef _
17152
17153   /* Help strings */
17154 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17155   foreach_vpe_api_msg;
17156 #undef _
17157
17158   /* CLI functions */
17159 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17160   foreach_cli_function;
17161 #undef _
17162
17163   /* Help strings */
17164 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17165   foreach_cli_function;
17166 #undef _
17167 }
17168
17169 #undef vl_api_version
17170 #define vl_api_version(n,v) static u32 memory_api_version = v;
17171 #include <vlibmemory/vl_memory_api_h.h>
17172 #undef vl_api_version
17173
17174 #undef vl_api_version
17175 #define vl_api_version(n,v) static u32 vnet_interface_api_version = v;
17176 #include <vnet/interface.api.h>
17177 #undef vl_api_version
17178
17179 #undef vl_api_version
17180 #define vl_api_version(n,v) static u32 vpp_api_version = v;
17181 #include <vpp-api/vpe.api.h>
17182 #undef vl_api_version
17183
17184 static u32 *api_versions[] = {
17185   &memory_api_version,
17186   &vnet_interface_api_version,
17187   &vpp_api_version,
17188 };
17189
17190 void
17191 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
17192 {
17193   int i;
17194
17195   ASSERT (ARRAY_LEN (mp->api_versions) >= ARRAY_LEN (api_versions));
17196
17197   /*
17198    * Send the API signatures. This bit of code must
17199    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
17200    */
17201
17202   for (i = 0; i < ARRAY_LEN (api_versions); i++)
17203     mp->api_versions[i] = clib_host_to_net_u32 (*api_versions[i]);
17204 }
17205
17206 /*
17207  * fd.io coding-style-patch-verification: ON
17208  *
17209  * Local Variables:
17210  * eval: (c-set-style "gnu")
17211  * End:
17212  */