api: fix inconsistent behaviour when adding l2fib filter entry (VPP-147)
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248   u32 *r = va_arg (*args, u32 *);
249
250   if (0);
251 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
252   foreach_ipsec_policy_action
253 #undef _
254     else
255     return 0;
256   return 1;
257 }
258
259 uword
260 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
261 {
262   u32 *r = va_arg (*args, u32 *);
263
264   if (0);
265 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
266   foreach_ipsec_crypto_alg
267 #undef _
268     else
269     return 0;
270   return 1;
271 }
272
273 u8 *
274 format_ipsec_crypto_alg (u8 * s, va_list * args)
275 {
276   u32 i = va_arg (*args, u32);
277   u8 *t = 0;
278
279   switch (i)
280     {
281 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
282       foreach_ipsec_crypto_alg
283 #undef _
284     default:
285       return format (s, "unknown");
286     }
287   return format (s, "%s", t);
288 }
289
290 uword
291 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
292 {
293   u32 *r = va_arg (*args, u32 *);
294
295   if (0);
296 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
297   foreach_ipsec_integ_alg
298 #undef _
299     else
300     return 0;
301   return 1;
302 }
303
304 u8 *
305 format_ipsec_integ_alg (u8 * s, va_list * args)
306 {
307   u32 i = va_arg (*args, u32);
308   u8 *t = 0;
309
310   switch (i)
311     {
312 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
313       foreach_ipsec_integ_alg
314 #undef _
315     default:
316       return format (s, "unknown");
317     }
318   return format (s, "%s", t);
319 }
320
321 uword
322 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
323 {
324   u32 *r = va_arg (*args, u32 *);
325
326   if (0);
327 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
328   foreach_ikev2_auth_method
329 #undef _
330     else
331     return 0;
332   return 1;
333 }
334
335 uword
336 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
337 {
338   u32 *r = va_arg (*args, u32 *);
339
340   if (0);
341 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
342   foreach_ikev2_id_type
343 #undef _
344     else
345     return 0;
346   return 1;
347 }
348
349 uword
350 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
351 {
352   u8 *r = va_arg (*args, u8 *);
353
354   if (unformat (input, "kbps"))
355     *r = SSE2_QOS_RATE_KBPS;
356   else if (unformat (input, "pps"))
357     *r = SSE2_QOS_RATE_PPS;
358   else
359     return 0;
360   return 1;
361 }
362
363 uword
364 unformat_policer_round_type (unformat_input_t * input, va_list * args)
365 {
366   u8 *r = va_arg (*args, u8 *);
367
368   if (unformat (input, "closest"))
369     *r = SSE2_QOS_ROUND_TO_CLOSEST;
370   else if (unformat (input, "up"))
371     *r = SSE2_QOS_ROUND_TO_UP;
372   else if (unformat (input, "down"))
373     *r = SSE2_QOS_ROUND_TO_DOWN;
374   else
375     return 0;
376   return 1;
377 }
378
379 uword
380 unformat_policer_type (unformat_input_t * input, va_list * args)
381 {
382   u8 *r = va_arg (*args, u8 *);
383
384   if (unformat (input, "1r2c"))
385     *r = SSE2_QOS_POLICER_TYPE_1R2C;
386   else if (unformat (input, "1r3c"))
387     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
388   else if (unformat (input, "2r3c-2698"))
389     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
390   else if (unformat (input, "2r3c-4115"))
391     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
392   else if (unformat (input, "2r3c-mef5cf1"))
393     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
394   else
395     return 0;
396   return 1;
397 }
398
399 uword
400 unformat_dscp (unformat_input_t * input, va_list * va)
401 {
402   u8 *r = va_arg (*va, u8 *);
403
404   if (0);
405 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
406   foreach_vnet_dscp
407 #undef _
408     else
409     return 0;
410   return 1;
411 }
412
413 uword
414 unformat_policer_action_type (unformat_input_t * input, va_list * va)
415 {
416   sse2_qos_pol_action_params_st *a
417     = va_arg (*va, sse2_qos_pol_action_params_st *);
418
419   if (unformat (input, "drop"))
420     a->action_type = SSE2_QOS_ACTION_DROP;
421   else if (unformat (input, "transmit"))
422     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
423   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
424     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
425   else
426     return 0;
427   return 1;
428 }
429
430 uword
431 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
432 {
433   u32 *r = va_arg (*va, u32 *);
434   u32 tid;
435
436   if (unformat (input, "ip4"))
437     tid = POLICER_CLASSIFY_TABLE_IP4;
438   else if (unformat (input, "ip6"))
439     tid = POLICER_CLASSIFY_TABLE_IP6;
440   else if (unformat (input, "l2"))
441     tid = POLICER_CLASSIFY_TABLE_L2;
442   else
443     return 0;
444
445   *r = tid;
446   return 1;
447 }
448
449 uword
450 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
451 {
452   u32 *r = va_arg (*va, u32 *);
453   u32 tid;
454
455   if (unformat (input, "ip4"))
456     tid = FLOW_CLASSIFY_TABLE_IP4;
457   else if (unformat (input, "ip6"))
458     tid = FLOW_CLASSIFY_TABLE_IP6;
459   else
460     return 0;
461
462   *r = tid;
463   return 1;
464 }
465
466 u8 *
467 format_ip4_address (u8 * s, va_list * args)
468 {
469   u8 *a = va_arg (*args, u8 *);
470   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
471 }
472
473 u8 *
474 format_ip6_address (u8 * s, va_list * args)
475 {
476   ip6_address_t *a = va_arg (*args, ip6_address_t *);
477   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
478
479   i_max_n_zero = ARRAY_LEN (a->as_u16);
480   max_n_zeros = 0;
481   i_first_zero = i_max_n_zero;
482   n_zeros = 0;
483   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
484     {
485       u32 is_zero = a->as_u16[i] == 0;
486       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
487         {
488           i_first_zero = i;
489           n_zeros = 0;
490         }
491       n_zeros += is_zero;
492       if ((!is_zero && n_zeros > max_n_zeros)
493           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
494         {
495           i_max_n_zero = i_first_zero;
496           max_n_zeros = n_zeros;
497           i_first_zero = ARRAY_LEN (a->as_u16);
498           n_zeros = 0;
499         }
500     }
501
502   last_double_colon = 0;
503   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
504     {
505       if (i == i_max_n_zero && max_n_zeros > 1)
506         {
507           s = format (s, "::");
508           i += max_n_zeros - 1;
509           last_double_colon = 1;
510         }
511       else
512         {
513           s = format (s, "%s%x",
514                       (last_double_colon || i == 0) ? "" : ":",
515                       clib_net_to_host_u16 (a->as_u16[i]));
516           last_double_colon = 0;
517         }
518     }
519
520   return s;
521 }
522
523 /* Format an IP46 address. */
524 u8 *
525 format_ip46_address (u8 * s, va_list * args)
526 {
527   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
528   ip46_type_t type = va_arg (*args, ip46_type_t);
529   int is_ip4 = 1;
530
531   switch (type)
532     {
533     case IP46_TYPE_ANY:
534       is_ip4 = ip46_address_is_ip4 (ip46);
535       break;
536     case IP46_TYPE_IP4:
537       is_ip4 = 1;
538       break;
539     case IP46_TYPE_IP6:
540       is_ip4 = 0;
541       break;
542     }
543
544   return is_ip4 ?
545     format (s, "%U", format_ip4_address, &ip46->ip4) :
546     format (s, "%U", format_ip6_address, &ip46->ip6);
547 }
548
549 u8 *
550 format_ethernet_address (u8 * s, va_list * args)
551 {
552   u8 *a = va_arg (*args, u8 *);
553
554   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
555                  a[0], a[1], a[2], a[3], a[4], a[5]);
556 }
557
558 void
559 increment_v4_address (ip4_address_t * a)
560 {
561   u32 v;
562
563   v = ntohl (a->as_u32) + 1;
564   a->as_u32 = ntohl (v);
565 }
566
567 void
568 increment_v6_address (ip6_address_t * a)
569 {
570   u64 v0, v1;
571
572   v0 = clib_net_to_host_u64 (a->as_u64[0]);
573   v1 = clib_net_to_host_u64 (a->as_u64[1]);
574
575   v1 += 1;
576   if (v1 == 0)
577     v0 += 1;
578   a->as_u64[0] = clib_net_to_host_u64 (v0);
579   a->as_u64[1] = clib_net_to_host_u64 (v1);
580 }
581
582 void
583 increment_mac_address (u64 * mac)
584 {
585   u64 tmp = *mac;
586
587   tmp = clib_net_to_host_u64 (tmp);
588   tmp += 1 << 16;               /* skip unused (least significant) octets */
589   tmp = clib_host_to_net_u64 (tmp);
590   *mac = tmp;
591 }
592
593 static void vl_api_create_loopback_reply_t_handler
594   (vl_api_create_loopback_reply_t * mp)
595 {
596   vat_main_t *vam = &vat_main;
597   i32 retval = ntohl (mp->retval);
598
599   vam->retval = retval;
600   vam->regenerate_interface_table = 1;
601   vam->sw_if_index = ntohl (mp->sw_if_index);
602   vam->result_ready = 1;
603 }
604
605 static void vl_api_create_loopback_reply_t_handler_json
606   (vl_api_create_loopback_reply_t * mp)
607 {
608   vat_main_t *vam = &vat_main;
609   vat_json_node_t node;
610
611   vat_json_init_object (&node);
612   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
613   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
614
615   vat_json_print (vam->ofp, &node);
616   vat_json_free (&node);
617   vam->retval = ntohl (mp->retval);
618   vam->result_ready = 1;
619 }
620
621 static void vl_api_af_packet_create_reply_t_handler
622   (vl_api_af_packet_create_reply_t * mp)
623 {
624   vat_main_t *vam = &vat_main;
625   i32 retval = ntohl (mp->retval);
626
627   vam->retval = retval;
628   vam->regenerate_interface_table = 1;
629   vam->sw_if_index = ntohl (mp->sw_if_index);
630   vam->result_ready = 1;
631 }
632
633 static void vl_api_af_packet_create_reply_t_handler_json
634   (vl_api_af_packet_create_reply_t * mp)
635 {
636   vat_main_t *vam = &vat_main;
637   vat_json_node_t node;
638
639   vat_json_init_object (&node);
640   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
641   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
642
643   vat_json_print (vam->ofp, &node);
644   vat_json_free (&node);
645
646   vam->retval = ntohl (mp->retval);
647   vam->result_ready = 1;
648 }
649
650 static void vl_api_create_vlan_subif_reply_t_handler
651   (vl_api_create_vlan_subif_reply_t * mp)
652 {
653   vat_main_t *vam = &vat_main;
654   i32 retval = ntohl (mp->retval);
655
656   vam->retval = retval;
657   vam->regenerate_interface_table = 1;
658   vam->sw_if_index = ntohl (mp->sw_if_index);
659   vam->result_ready = 1;
660 }
661
662 static void vl_api_create_vlan_subif_reply_t_handler_json
663   (vl_api_create_vlan_subif_reply_t * mp)
664 {
665   vat_main_t *vam = &vat_main;
666   vat_json_node_t node;
667
668   vat_json_init_object (&node);
669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
670   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
671
672   vat_json_print (vam->ofp, &node);
673   vat_json_free (&node);
674
675   vam->retval = ntohl (mp->retval);
676   vam->result_ready = 1;
677 }
678
679 static void vl_api_create_subif_reply_t_handler
680   (vl_api_create_subif_reply_t * mp)
681 {
682   vat_main_t *vam = &vat_main;
683   i32 retval = ntohl (mp->retval);
684
685   vam->retval = retval;
686   vam->regenerate_interface_table = 1;
687   vam->sw_if_index = ntohl (mp->sw_if_index);
688   vam->result_ready = 1;
689 }
690
691 static void vl_api_create_subif_reply_t_handler_json
692   (vl_api_create_subif_reply_t * mp)
693 {
694   vat_main_t *vam = &vat_main;
695   vat_json_node_t node;
696
697   vat_json_init_object (&node);
698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
699   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
700
701   vat_json_print (vam->ofp, &node);
702   vat_json_free (&node);
703
704   vam->retval = ntohl (mp->retval);
705   vam->result_ready = 1;
706 }
707
708 static void vl_api_interface_name_renumber_reply_t_handler
709   (vl_api_interface_name_renumber_reply_t * mp)
710 {
711   vat_main_t *vam = &vat_main;
712   i32 retval = ntohl (mp->retval);
713
714   vam->retval = retval;
715   vam->regenerate_interface_table = 1;
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler_json
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   vat_json_node_t node;
724
725   vat_json_init_object (&node);
726   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
727
728   vat_json_print (vam->ofp, &node);
729   vat_json_free (&node);
730
731   vam->retval = ntohl (mp->retval);
732   vam->result_ready = 1;
733 }
734
735 /*
736  * Special-case: build the interface table, maintain
737  * the next loopback sw_if_index vbl.
738  */
739 static void vl_api_sw_interface_details_t_handler
740   (vl_api_sw_interface_details_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   u8 *s = format (0, "%s%c", mp->interface_name, 0);
744
745   hash_set_mem (vam->sw_if_index_by_interface_name, s,
746                 ntohl (mp->sw_if_index));
747
748   /* In sub interface case, fill the sub interface table entry */
749   if (mp->sw_if_index != mp->sup_sw_if_index)
750     {
751       sw_interface_subif_t *sub = NULL;
752
753       vec_add2 (vam->sw_if_subif_table, sub, 1);
754
755       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
756       strncpy ((char *) sub->interface_name, (char *) s,
757                vec_len (sub->interface_name));
758       sub->sw_if_index = ntohl (mp->sw_if_index);
759       sub->sub_id = ntohl (mp->sub_id);
760
761       sub->sub_dot1ad = mp->sub_dot1ad;
762       sub->sub_number_of_tags = mp->sub_number_of_tags;
763       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
764       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
765       sub->sub_exact_match = mp->sub_exact_match;
766       sub->sub_default = mp->sub_default;
767       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
768       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
769
770       /* vlan tag rewrite */
771       sub->vtr_op = ntohl (mp->vtr_op);
772       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
773       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
774       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
775     }
776 }
777
778 static void vl_api_sw_interface_details_t_handler_json
779   (vl_api_sw_interface_details_t * mp)
780 {
781   vat_main_t *vam = &vat_main;
782   vat_json_node_t *node = NULL;
783
784   if (VAT_JSON_ARRAY != vam->json_tree.type)
785     {
786       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
787       vat_json_init_array (&vam->json_tree);
788     }
789   node = vat_json_array_add (&vam->json_tree);
790
791   vat_json_init_object (node);
792   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
793   vat_json_object_add_uint (node, "sup_sw_if_index",
794                             ntohl (mp->sup_sw_if_index));
795   vat_json_object_add_uint (node, "l2_address_length",
796                             ntohl (mp->l2_address_length));
797   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
798                              sizeof (mp->l2_address));
799   vat_json_object_add_string_copy (node, "interface_name",
800                                    mp->interface_name);
801   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
802   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
803   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
804   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
805   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
806   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
807   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
808   vat_json_object_add_uint (node, "sub_number_of_tags",
809                             mp->sub_number_of_tags);
810   vat_json_object_add_uint (node, "sub_outer_vlan_id",
811                             ntohs (mp->sub_outer_vlan_id));
812   vat_json_object_add_uint (node, "sub_inner_vlan_id",
813                             ntohs (mp->sub_inner_vlan_id));
814   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
815   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
816   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
817                             mp->sub_outer_vlan_id_any);
818   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
819                             mp->sub_inner_vlan_id_any);
820   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
821   vat_json_object_add_uint (node, "vtr_push_dot1q",
822                             ntohl (mp->vtr_push_dot1q));
823   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
824   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
825 }
826
827 static void vl_api_sw_interface_set_flags_t_handler
828   (vl_api_sw_interface_set_flags_t * mp)
829 {
830   vat_main_t *vam = &vat_main;
831   if (vam->interface_event_display)
832     errmsg ("interface flags: sw_if_index %d %s %s\n",
833             ntohl (mp->sw_if_index),
834             mp->admin_up_down ? "admin-up" : "admin-down",
835             mp->link_up_down ? "link-up" : "link-down");
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler_json
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   /* JSON output not supported */
842 }
843
844 static void
845 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
846 {
847   vat_main_t *vam = &vat_main;
848   i32 retval = ntohl (mp->retval);
849
850   vam->retval = retval;
851   vam->shmem_result = (u8 *) mp->reply_in_shmem;
852   vam->result_ready = 1;
853 }
854
855 static void
856 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   vat_json_node_t node;
860   api_main_t *am = &api_main;
861   void *oldheap;
862   u8 *reply;
863
864   vat_json_init_object (&node);
865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
866   vat_json_object_add_uint (&node, "reply_in_shmem",
867                             ntohl (mp->reply_in_shmem));
868   /* Toss the shared-memory original... */
869   pthread_mutex_lock (&am->vlib_rp->mutex);
870   oldheap = svm_push_data_heap (am->vlib_rp);
871
872   reply = (u8 *) (mp->reply_in_shmem);
873   vec_free (reply);
874
875   svm_pop_heap (oldheap);
876   pthread_mutex_unlock (&am->vlib_rp->mutex);
877
878   vat_json_print (vam->ofp, &node);
879   vat_json_free (&node);
880
881   vam->retval = ntohl (mp->retval);
882   vam->result_ready = 1;
883 }
884
885 static void
886 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   i32 retval = ntohl (mp->retval);
890
891   vam->retval = retval;
892   vam->cmd_reply = mp->reply;
893   vam->result_ready = 1;
894 }
895
896 static void
897 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   vat_json_node_t node;
901
902   vat_json_init_object (&node);
903   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
904   vat_json_object_add_string_copy (&node, "reply", mp->reply);
905
906   vat_json_print (vam->ofp, &node);
907   vat_json_free (&node);
908
909   vam->retval = ntohl (mp->retval);
910   vam->result_ready = 1;
911 }
912
913 static void vl_api_classify_add_del_table_reply_t_handler
914   (vl_api_classify_add_del_table_reply_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   i32 retval = ntohl (mp->retval);
918   if (vam->async_mode)
919     {
920       vam->async_errors += (retval < 0);
921     }
922   else
923     {
924       vam->retval = retval;
925       if (retval == 0 &&
926           ((mp->new_table_index != 0xFFFFFFFF) ||
927            (mp->skip_n_vectors != 0xFFFFFFFF) ||
928            (mp->match_n_vectors != 0xFFFFFFFF)))
929         /*
930          * Note: this is just barely thread-safe, depends on
931          * the main thread spinning waiting for an answer...
932          */
933         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
934                 ntohl (mp->new_table_index),
935                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
936       vam->result_ready = 1;
937     }
938 }
939
940 static void vl_api_classify_add_del_table_reply_t_handler_json
941   (vl_api_classify_add_del_table_reply_t * mp)
942 {
943   vat_main_t *vam = &vat_main;
944   vat_json_node_t node;
945
946   vat_json_init_object (&node);
947   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
948   vat_json_object_add_uint (&node, "new_table_index",
949                             ntohl (mp->new_table_index));
950   vat_json_object_add_uint (&node, "skip_n_vectors",
951                             ntohl (mp->skip_n_vectors));
952   vat_json_object_add_uint (&node, "match_n_vectors",
953                             ntohl (mp->match_n_vectors));
954
955   vat_json_print (vam->ofp, &node);
956   vat_json_free (&node);
957
958   vam->retval = ntohl (mp->retval);
959   vam->result_ready = 1;
960 }
961
962 static void vl_api_get_node_index_reply_t_handler
963   (vl_api_get_node_index_reply_t * mp)
964 {
965   vat_main_t *vam = &vat_main;
966   i32 retval = ntohl (mp->retval);
967   if (vam->async_mode)
968     {
969       vam->async_errors += (retval < 0);
970     }
971   else
972     {
973       vam->retval = retval;
974       if (retval == 0)
975         errmsg ("node index %d\n", ntohl (mp->node_index));
976       vam->result_ready = 1;
977     }
978 }
979
980 static void vl_api_get_node_index_reply_t_handler_json
981   (vl_api_get_node_index_reply_t * mp)
982 {
983   vat_main_t *vam = &vat_main;
984   vat_json_node_t node;
985
986   vat_json_init_object (&node);
987   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
988   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
989
990   vat_json_print (vam->ofp, &node);
991   vat_json_free (&node);
992
993   vam->retval = ntohl (mp->retval);
994   vam->result_ready = 1;
995 }
996
997 static void vl_api_get_next_index_reply_t_handler
998   (vl_api_get_next_index_reply_t * mp)
999 {
1000   vat_main_t *vam = &vat_main;
1001   i32 retval = ntohl (mp->retval);
1002   if (vam->async_mode)
1003     {
1004       vam->async_errors += (retval < 0);
1005     }
1006   else
1007     {
1008       vam->retval = retval;
1009       if (retval == 0)
1010         errmsg ("next node index %d\n", ntohl (mp->next_index));
1011       vam->result_ready = 1;
1012     }
1013 }
1014
1015 static void vl_api_get_next_index_reply_t_handler_json
1016   (vl_api_get_next_index_reply_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   vat_json_node_t node;
1020
1021   vat_json_init_object (&node);
1022   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1023   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1024
1025   vat_json_print (vam->ofp, &node);
1026   vat_json_free (&node);
1027
1028   vam->retval = ntohl (mp->retval);
1029   vam->result_ready = 1;
1030 }
1031
1032 static void vl_api_add_node_next_reply_t_handler
1033   (vl_api_add_node_next_reply_t * mp)
1034 {
1035   vat_main_t *vam = &vat_main;
1036   i32 retval = ntohl (mp->retval);
1037   if (vam->async_mode)
1038     {
1039       vam->async_errors += (retval < 0);
1040     }
1041   else
1042     {
1043       vam->retval = retval;
1044       if (retval == 0)
1045         errmsg ("next index %d\n", ntohl (mp->next_index));
1046       vam->result_ready = 1;
1047     }
1048 }
1049
1050 static void vl_api_add_node_next_reply_t_handler_json
1051   (vl_api_add_node_next_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   vat_json_node_t node;
1055
1056   vat_json_init_object (&node);
1057   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1058   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1059
1060   vat_json_print (vam->ofp, &node);
1061   vat_json_free (&node);
1062
1063   vam->retval = ntohl (mp->retval);
1064   vam->result_ready = 1;
1065 }
1066
1067 static void vl_api_show_version_reply_t_handler
1068   (vl_api_show_version_reply_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   i32 retval = ntohl (mp->retval);
1072
1073   if (retval >= 0)
1074     {
1075       errmsg ("        program: %s\n", mp->program);
1076       errmsg ("        version: %s\n", mp->version);
1077       errmsg ("     build date: %s\n", mp->build_date);
1078       errmsg ("build directory: %s\n", mp->build_directory);
1079     }
1080   vam->retval = retval;
1081   vam->result_ready = 1;
1082 }
1083
1084 static void vl_api_show_version_reply_t_handler_json
1085   (vl_api_show_version_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   vat_json_node_t node;
1089
1090   vat_json_init_object (&node);
1091   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1092   vat_json_object_add_string_copy (&node, "program", mp->program);
1093   vat_json_object_add_string_copy (&node, "version", mp->version);
1094   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1095   vat_json_object_add_string_copy (&node, "build_directory",
1096                                    mp->build_directory);
1097
1098   vat_json_print (vam->ofp, &node);
1099   vat_json_free (&node);
1100
1101   vam->retval = ntohl (mp->retval);
1102   vam->result_ready = 1;
1103 }
1104
1105 static void
1106 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1107 {
1108   vat_main_t *vam = &vat_main;
1109   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1110           mp->mac_ip ? "mac/ip binding" : "address resolution",
1111           format_ip4_address, &mp->address,
1112           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1113 }
1114
1115 static void
1116 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1117 {
1118   /* JSON output not supported */
1119 }
1120
1121 static void
1122 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1123 {
1124   vat_main_t *vam = &vat_main;
1125   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1126           mp->mac_ip ? "mac/ip binding" : "address resolution",
1127           format_ip6_address, mp->address,
1128           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1129 }
1130
1131 static void
1132 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1133 {
1134   /* JSON output not supported */
1135 }
1136
1137 /*
1138  * Special-case: build the bridge domain table, maintain
1139  * the next bd id vbl.
1140  */
1141 static void vl_api_bridge_domain_details_t_handler
1142   (vl_api_bridge_domain_details_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1146
1147   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1148            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1149
1150   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1151            ntohl (mp->bd_id), mp->learn, mp->forward,
1152            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1153
1154   if (n_sw_ifs)
1155     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1156              "Interface Name");
1157 }
1158
1159 static void vl_api_bridge_domain_details_t_handler_json
1160   (vl_api_bridge_domain_details_t * mp)
1161 {
1162   vat_main_t *vam = &vat_main;
1163   vat_json_node_t *node, *array = NULL;
1164
1165   if (VAT_JSON_ARRAY != vam->json_tree.type)
1166     {
1167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1168       vat_json_init_array (&vam->json_tree);
1169     }
1170   node = vat_json_array_add (&vam->json_tree);
1171
1172   vat_json_init_object (node);
1173   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1174   vat_json_object_add_uint (node, "flood", mp->flood);
1175   vat_json_object_add_uint (node, "forward", mp->forward);
1176   vat_json_object_add_uint (node, "learn", mp->learn);
1177   vat_json_object_add_uint (node, "bvi_sw_if_index",
1178                             ntohl (mp->bvi_sw_if_index));
1179   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1180   array = vat_json_object_add (node, "sw_if");
1181   vat_json_init_array (array);
1182 }
1183
1184 /*
1185  * Special-case: build the bridge domain sw if table.
1186  */
1187 static void vl_api_bridge_domain_sw_if_details_t_handler
1188   (vl_api_bridge_domain_sw_if_details_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   hash_pair_t *p;
1192   u8 *sw_if_name = 0;
1193   u32 sw_if_index;
1194
1195   sw_if_index = ntohl (mp->sw_if_index);
1196   /* *INDENT-OFF* */
1197   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1198   ({
1199     if ((u32) p->value[0] == sw_if_index)
1200       {
1201         sw_if_name = (u8 *)(p->key);
1202         break;
1203       }
1204   }));
1205   /* *INDENT-ON* */
1206
1207   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1208            mp->shg, sw_if_name ? (char *) sw_if_name :
1209            "sw_if_index not found!");
1210 }
1211
1212 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1213   (vl_api_bridge_domain_sw_if_details_t * mp)
1214 {
1215   vat_main_t *vam = &vat_main;
1216   vat_json_node_t *node = NULL;
1217   uword last_index = 0;
1218
1219   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1220   ASSERT (vec_len (vam->json_tree.array) >= 1);
1221   last_index = vec_len (vam->json_tree.array) - 1;
1222   node = &vam->json_tree.array[last_index];
1223   node = vat_json_object_get_element (node, "sw_if");
1224   ASSERT (NULL != node);
1225   node = vat_json_array_add (node);
1226
1227   vat_json_init_object (node);
1228   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1230   vat_json_object_add_uint (node, "shg", mp->shg);
1231 }
1232
1233 static void vl_api_control_ping_reply_t_handler
1234   (vl_api_control_ping_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   i32 retval = ntohl (mp->retval);
1238   if (vam->async_mode)
1239     {
1240       vam->async_errors += (retval < 0);
1241     }
1242   else
1243     {
1244       vam->retval = retval;
1245       vam->result_ready = 1;
1246     }
1247 }
1248
1249 static void vl_api_control_ping_reply_t_handler_json
1250   (vl_api_control_ping_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254
1255   if (VAT_JSON_NONE != vam->json_tree.type)
1256     {
1257       vat_json_print (vam->ofp, &vam->json_tree);
1258       vat_json_free (&vam->json_tree);
1259       vam->json_tree.type = VAT_JSON_NONE;
1260     }
1261   else
1262     {
1263       /* just print [] */
1264       vat_json_init_array (&vam->json_tree);
1265       vat_json_print (vam->ofp, &vam->json_tree);
1266       vam->json_tree.type = VAT_JSON_NONE;
1267     }
1268
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void
1274 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278   if (vam->async_mode)
1279     {
1280       vam->async_errors += (retval < 0);
1281     }
1282   else
1283     {
1284       vam->retval = retval;
1285       vam->result_ready = 1;
1286     }
1287 }
1288
1289 static void vl_api_l2_flags_reply_t_handler_json
1290   (vl_api_l2_flags_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   vat_json_node_t node;
1294
1295   vat_json_init_object (&node);
1296   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1297   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1298                             ntohl (mp->resulting_feature_bitmap));
1299
1300   vat_json_print (vam->ofp, &node);
1301   vat_json_free (&node);
1302
1303   vam->retval = ntohl (mp->retval);
1304   vam->result_ready = 1;
1305 }
1306
1307 static void vl_api_bridge_flags_reply_t_handler
1308   (vl_api_bridge_flags_reply_t * mp)
1309 {
1310   vat_main_t *vam = &vat_main;
1311   i32 retval = ntohl (mp->retval);
1312   if (vam->async_mode)
1313     {
1314       vam->async_errors += (retval < 0);
1315     }
1316   else
1317     {
1318       vam->retval = retval;
1319       vam->result_ready = 1;
1320     }
1321 }
1322
1323 static void vl_api_bridge_flags_reply_t_handler_json
1324   (vl_api_bridge_flags_reply_t * mp)
1325 {
1326   vat_main_t *vam = &vat_main;
1327   vat_json_node_t node;
1328
1329   vat_json_init_object (&node);
1330   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1331   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1332                             ntohl (mp->resulting_feature_bitmap));
1333
1334   vat_json_print (vam->ofp, &node);
1335   vat_json_free (&node);
1336
1337   vam->retval = ntohl (mp->retval);
1338   vam->result_ready = 1;
1339 }
1340
1341 static void vl_api_tap_connect_reply_t_handler
1342   (vl_api_tap_connect_reply_t * mp)
1343 {
1344   vat_main_t *vam = &vat_main;
1345   i32 retval = ntohl (mp->retval);
1346   if (vam->async_mode)
1347     {
1348       vam->async_errors += (retval < 0);
1349     }
1350   else
1351     {
1352       vam->retval = retval;
1353       vam->sw_if_index = ntohl (mp->sw_if_index);
1354       vam->result_ready = 1;
1355     }
1356
1357 }
1358
1359 static void vl_api_tap_connect_reply_t_handler_json
1360   (vl_api_tap_connect_reply_t * mp)
1361 {
1362   vat_main_t *vam = &vat_main;
1363   vat_json_node_t node;
1364
1365   vat_json_init_object (&node);
1366   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1367   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1368
1369   vat_json_print (vam->ofp, &node);
1370   vat_json_free (&node);
1371
1372   vam->retval = ntohl (mp->retval);
1373   vam->result_ready = 1;
1374
1375 }
1376
1377 static void
1378 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1379 {
1380   vat_main_t *vam = &vat_main;
1381   i32 retval = ntohl (mp->retval);
1382   if (vam->async_mode)
1383     {
1384       vam->async_errors += (retval < 0);
1385     }
1386   else
1387     {
1388       vam->retval = retval;
1389       vam->sw_if_index = ntohl (mp->sw_if_index);
1390       vam->result_ready = 1;
1391     }
1392 }
1393
1394 static void vl_api_tap_modify_reply_t_handler_json
1395   (vl_api_tap_modify_reply_t * mp)
1396 {
1397   vat_main_t *vam = &vat_main;
1398   vat_json_node_t node;
1399
1400   vat_json_init_object (&node);
1401   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1402   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1403
1404   vat_json_print (vam->ofp, &node);
1405   vat_json_free (&node);
1406
1407   vam->retval = ntohl (mp->retval);
1408   vam->result_ready = 1;
1409 }
1410
1411 static void
1412 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1413 {
1414   vat_main_t *vam = &vat_main;
1415   i32 retval = ntohl (mp->retval);
1416   if (vam->async_mode)
1417     {
1418       vam->async_errors += (retval < 0);
1419     }
1420   else
1421     {
1422       vam->retval = retval;
1423       vam->result_ready = 1;
1424     }
1425 }
1426
1427 static void vl_api_tap_delete_reply_t_handler_json
1428   (vl_api_tap_delete_reply_t * mp)
1429 {
1430   vat_main_t *vam = &vat_main;
1431   vat_json_node_t node;
1432
1433   vat_json_init_object (&node);
1434   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1435
1436   vat_json_print (vam->ofp, &node);
1437   vat_json_free (&node);
1438
1439   vam->retval = ntohl (mp->retval);
1440   vam->result_ready = 1;
1441 }
1442
1443 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1444   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   i32 retval = ntohl (mp->retval);
1448   if (vam->async_mode)
1449     {
1450       vam->async_errors += (retval < 0);
1451     }
1452   else
1453     {
1454       vam->retval = retval;
1455       vam->result_ready = 1;
1456     }
1457 }
1458
1459 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1460   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   vat_json_node_t node;
1464
1465   vat_json_init_object (&node);
1466   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1467   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1468                             ntohl (mp->sw_if_index));
1469
1470   vat_json_print (vam->ofp, &node);
1471   vat_json_free (&node);
1472
1473   vam->retval = ntohl (mp->retval);
1474   vam->result_ready = 1;
1475 }
1476
1477 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1478   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1479 {
1480   vat_main_t *vam = &vat_main;
1481   i32 retval = ntohl (mp->retval);
1482   if (vam->async_mode)
1483     {
1484       vam->async_errors += (retval < 0);
1485     }
1486   else
1487     {
1488       vam->retval = retval;
1489       vam->sw_if_index = ntohl (mp->sw_if_index);
1490       vam->result_ready = 1;
1491     }
1492 }
1493
1494 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1495   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   vat_json_node_t node;
1499
1500   vat_json_init_object (&node);
1501   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1502   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1503
1504   vat_json_print (vam->ofp, &node);
1505   vat_json_free (&node);
1506
1507   vam->retval = ntohl (mp->retval);
1508   vam->result_ready = 1;
1509 }
1510
1511
1512 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1513   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1514 {
1515   vat_main_t *vam = &vat_main;
1516   i32 retval = ntohl (mp->retval);
1517   if (vam->async_mode)
1518     {
1519       vam->async_errors += (retval < 0);
1520     }
1521   else
1522     {
1523       vam->retval = retval;
1524       vam->result_ready = 1;
1525     }
1526 }
1527
1528 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1529   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1530 {
1531   vat_main_t *vam = &vat_main;
1532   vat_json_node_t node;
1533
1534   vat_json_init_object (&node);
1535   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1536   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1537
1538   vat_json_print (vam->ofp, &node);
1539   vat_json_free (&node);
1540
1541   vam->retval = ntohl (mp->retval);
1542   vam->result_ready = 1;
1543 }
1544
1545 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1546   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   i32 retval = ntohl (mp->retval);
1550   if (vam->async_mode)
1551     {
1552       vam->async_errors += (retval < 0);
1553     }
1554   else
1555     {
1556       vam->retval = retval;
1557       vam->sw_if_index = ntohl (mp->sw_if_index);
1558       vam->result_ready = 1;
1559     }
1560 }
1561
1562 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1563   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1564 {
1565   vat_main_t *vam = &vat_main;
1566   vat_json_node_t node;
1567
1568   vat_json_init_object (&node);
1569   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1570   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1571
1572   vat_json_print (vam->ofp, &node);
1573   vat_json_free (&node);
1574
1575   vam->retval = ntohl (mp->retval);
1576   vam->result_ready = 1;
1577 }
1578
1579 static void vl_api_gre_add_del_tunnel_reply_t_handler
1580   (vl_api_gre_add_del_tunnel_reply_t * mp)
1581 {
1582   vat_main_t *vam = &vat_main;
1583   i32 retval = ntohl (mp->retval);
1584   if (vam->async_mode)
1585     {
1586       vam->async_errors += (retval < 0);
1587     }
1588   else
1589     {
1590       vam->retval = retval;
1591       vam->sw_if_index = ntohl (mp->sw_if_index);
1592       vam->result_ready = 1;
1593     }
1594 }
1595
1596 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1597   (vl_api_gre_add_del_tunnel_reply_t * mp)
1598 {
1599   vat_main_t *vam = &vat_main;
1600   vat_json_node_t node;
1601
1602   vat_json_init_object (&node);
1603   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1604   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1605
1606   vat_json_print (vam->ofp, &node);
1607   vat_json_free (&node);
1608
1609   vam->retval = ntohl (mp->retval);
1610   vam->result_ready = 1;
1611 }
1612
1613 static void vl_api_create_vhost_user_if_reply_t_handler
1614   (vl_api_create_vhost_user_if_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   i32 retval = ntohl (mp->retval);
1618   if (vam->async_mode)
1619     {
1620       vam->async_errors += (retval < 0);
1621     }
1622   else
1623     {
1624       vam->retval = retval;
1625       vam->sw_if_index = ntohl (mp->sw_if_index);
1626       vam->result_ready = 1;
1627     }
1628 }
1629
1630 static void vl_api_create_vhost_user_if_reply_t_handler_json
1631   (vl_api_create_vhost_user_if_reply_t * mp)
1632 {
1633   vat_main_t *vam = &vat_main;
1634   vat_json_node_t node;
1635
1636   vat_json_init_object (&node);
1637   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1638   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1639
1640   vat_json_print (vam->ofp, &node);
1641   vat_json_free (&node);
1642
1643   vam->retval = ntohl (mp->retval);
1644   vam->result_ready = 1;
1645 }
1646
1647 static void vl_api_ip_address_details_t_handler
1648   (vl_api_ip_address_details_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   static ip_address_details_t empty_ip_address_details = { {0} };
1652   ip_address_details_t *address = NULL;
1653   ip_details_t *current_ip_details = NULL;
1654   ip_details_t *details = NULL;
1655
1656   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1657
1658   if (!details || vam->current_sw_if_index >= vec_len (details)
1659       || !details[vam->current_sw_if_index].present)
1660     {
1661       errmsg ("ip address details arrived but not stored\n");
1662       errmsg ("ip_dump should be called first\n");
1663       return;
1664     }
1665
1666   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1667
1668 #define addresses (current_ip_details->addr)
1669
1670   vec_validate_init_empty (addresses, vec_len (addresses),
1671                            empty_ip_address_details);
1672
1673   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1674
1675   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1676   address->prefix_length = mp->prefix_length;
1677 #undef addresses
1678 }
1679
1680 static void vl_api_ip_address_details_t_handler_json
1681   (vl_api_ip_address_details_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t *node = NULL;
1685   struct in6_addr ip6;
1686   struct in_addr ip4;
1687
1688   if (VAT_JSON_ARRAY != vam->json_tree.type)
1689     {
1690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1691       vat_json_init_array (&vam->json_tree);
1692     }
1693   node = vat_json_array_add (&vam->json_tree);
1694
1695   vat_json_init_object (node);
1696   if (vam->is_ipv6)
1697     {
1698       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1699       vat_json_object_add_ip6 (node, "ip", ip6);
1700     }
1701   else
1702     {
1703       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1704       vat_json_object_add_ip4 (node, "ip", ip4);
1705     }
1706   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1707 }
1708
1709 static void
1710 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   static ip_details_t empty_ip_details = { 0 };
1714   ip_details_t *ip = NULL;
1715   u32 sw_if_index = ~0;
1716
1717   sw_if_index = ntohl (mp->sw_if_index);
1718
1719   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1720                            sw_if_index, empty_ip_details);
1721
1722   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1723                          sw_if_index);
1724
1725   ip->present = 1;
1726 }
1727
1728 static void
1729 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732
1733   if (VAT_JSON_ARRAY != vam->json_tree.type)
1734     {
1735       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1736       vat_json_init_array (&vam->json_tree);
1737     }
1738   vat_json_array_add_uint (&vam->json_tree,
1739                            clib_net_to_host_u32 (mp->sw_if_index));
1740 }
1741
1742 static void vl_api_map_domain_details_t_handler_json
1743   (vl_api_map_domain_details_t * mp)
1744 {
1745   vat_json_node_t *node = NULL;
1746   vat_main_t *vam = &vat_main;
1747   struct in6_addr ip6;
1748   struct in_addr ip4;
1749
1750   if (VAT_JSON_ARRAY != vam->json_tree.type)
1751     {
1752       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1753       vat_json_init_array (&vam->json_tree);
1754     }
1755
1756   node = vat_json_array_add (&vam->json_tree);
1757   vat_json_init_object (node);
1758
1759   vat_json_object_add_uint (node, "domain_index",
1760                             clib_net_to_host_u32 (mp->domain_index));
1761   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1762   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1763   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1764   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1765   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1766   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1767   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1768   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1769   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1770   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1771   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1772   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1773   vat_json_object_add_uint (node, "flags", mp->flags);
1774   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1775   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1776 }
1777
1778 static void vl_api_map_domain_details_t_handler
1779   (vl_api_map_domain_details_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782
1783   if (mp->is_translation)
1784     {
1785       fformat (vam->ofp,
1786                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1787                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1788                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1789                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1790                clib_net_to_host_u32 (mp->domain_index));
1791     }
1792   else
1793     {
1794       fformat (vam->ofp,
1795                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1796                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1797                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1798                format_ip6_address, mp->ip6_src,
1799                clib_net_to_host_u32 (mp->domain_index));
1800     }
1801   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1802            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1803            mp->is_translation ? "map-t" : "");
1804 }
1805
1806 static void vl_api_map_rule_details_t_handler_json
1807   (vl_api_map_rule_details_t * mp)
1808 {
1809   struct in6_addr ip6;
1810   vat_json_node_t *node = NULL;
1811   vat_main_t *vam = &vat_main;
1812
1813   if (VAT_JSON_ARRAY != vam->json_tree.type)
1814     {
1815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1816       vat_json_init_array (&vam->json_tree);
1817     }
1818
1819   node = vat_json_array_add (&vam->json_tree);
1820   vat_json_init_object (node);
1821
1822   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1823   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1824   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1825 }
1826
1827 static void
1828 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1829 {
1830   vat_main_t *vam = &vat_main;
1831   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1832            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1833 }
1834
1835 static void
1836 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1837 {
1838   vat_main_t *vam = &vat_main;
1839   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1840           "router_addr %U host_mac %U\n",
1841           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1842           format_ip4_address, &mp->host_address,
1843           format_ip4_address, &mp->router_address,
1844           format_ethernet_address, mp->host_mac);
1845 }
1846
1847 static void vl_api_dhcp_compl_event_t_handler_json
1848   (vl_api_dhcp_compl_event_t * mp)
1849 {
1850   /* JSON output not supported */
1851 }
1852
1853 static void
1854 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1855                               u32 counter)
1856 {
1857   vat_main_t *vam = &vat_main;
1858   static u64 default_counter = 0;
1859
1860   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1861                            NULL);
1862   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1863                            sw_if_index, default_counter);
1864   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1865 }
1866
1867 static void
1868 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1869                                 interface_counter_t counter)
1870 {
1871   vat_main_t *vam = &vat_main;
1872   static interface_counter_t default_counter = { 0, };
1873
1874   vec_validate_init_empty (vam->combined_interface_counters,
1875                            vnet_counter_type, NULL);
1876   vec_validate_init_empty (vam->combined_interface_counters
1877                            [vnet_counter_type], sw_if_index, default_counter);
1878   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1879 }
1880
1881 static void vl_api_vnet_interface_counters_t_handler
1882   (vl_api_vnet_interface_counters_t * mp)
1883 {
1884   /* not supported */
1885 }
1886
1887 static void vl_api_vnet_interface_counters_t_handler_json
1888   (vl_api_vnet_interface_counters_t * mp)
1889 {
1890   interface_counter_t counter;
1891   vlib_counter_t *v;
1892   u64 *v_packets;
1893   u64 packets;
1894   u32 count;
1895   u32 first_sw_if_index;
1896   int i;
1897
1898   count = ntohl (mp->count);
1899   first_sw_if_index = ntohl (mp->first_sw_if_index);
1900
1901   if (!mp->is_combined)
1902     {
1903       v_packets = (u64 *) & mp->data;
1904       for (i = 0; i < count; i++)
1905         {
1906           packets =
1907             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1908           set_simple_interface_counter (mp->vnet_counter_type,
1909                                         first_sw_if_index + i, packets);
1910           v_packets++;
1911         }
1912     }
1913   else
1914     {
1915       v = (vlib_counter_t *) & mp->data;
1916       for (i = 0; i < count; i++)
1917         {
1918           counter.packets =
1919             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1920           counter.bytes =
1921             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1922           set_combined_interface_counter (mp->vnet_counter_type,
1923                                           first_sw_if_index + i, counter);
1924           v++;
1925         }
1926     }
1927 }
1928
1929 static u32
1930 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1931 {
1932   vat_main_t *vam = &vat_main;
1933   u32 i;
1934
1935   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1936     {
1937       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1938         {
1939           return i;
1940         }
1941     }
1942   return ~0;
1943 }
1944
1945 static u32
1946 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1947 {
1948   vat_main_t *vam = &vat_main;
1949   u32 i;
1950
1951   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1952     {
1953       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1954         {
1955           return i;
1956         }
1957     }
1958   return ~0;
1959 }
1960
1961 static void vl_api_vnet_ip4_fib_counters_t_handler
1962   (vl_api_vnet_ip4_fib_counters_t * mp)
1963 {
1964   /* not supported */
1965 }
1966
1967 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1968   (vl_api_vnet_ip4_fib_counters_t * mp)
1969 {
1970   vat_main_t *vam = &vat_main;
1971   vl_api_ip4_fib_counter_t *v;
1972   ip4_fib_counter_t *counter;
1973   struct in_addr ip4;
1974   u32 vrf_id;
1975   u32 vrf_index;
1976   u32 count;
1977   int i;
1978
1979   vrf_id = ntohl (mp->vrf_id);
1980   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
1981   if (~0 == vrf_index)
1982     {
1983       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
1984       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1985       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1986       vec_validate (vam->ip4_fib_counters, vrf_index);
1987       vam->ip4_fib_counters[vrf_index] = NULL;
1988     }
1989
1990   vec_free (vam->ip4_fib_counters[vrf_index]);
1991   v = (vl_api_ip4_fib_counter_t *) & mp->c;
1992   count = ntohl (mp->count);
1993   for (i = 0; i < count; i++)
1994     {
1995       vec_validate (vam->ip4_fib_counters[vrf_index], i);
1996       counter = &vam->ip4_fib_counters[vrf_index][i];
1997       clib_memcpy (&ip4, &v->address, sizeof (ip4));
1998       counter->address = ip4;
1999       counter->address_length = v->address_length;
2000       counter->packets = clib_net_to_host_u64 (v->packets);
2001       counter->bytes = clib_net_to_host_u64 (v->bytes);
2002       v++;
2003     }
2004 }
2005
2006 static void vl_api_vnet_ip6_fib_counters_t_handler
2007   (vl_api_vnet_ip6_fib_counters_t * mp)
2008 {
2009   /* not supported */
2010 }
2011
2012 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2013   (vl_api_vnet_ip6_fib_counters_t * mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016   vl_api_ip6_fib_counter_t *v;
2017   ip6_fib_counter_t *counter;
2018   struct in6_addr ip6;
2019   u32 vrf_id;
2020   u32 vrf_index;
2021   u32 count;
2022   int i;
2023
2024   vrf_id = ntohl (mp->vrf_id);
2025   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2026   if (~0 == vrf_index)
2027     {
2028       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2029       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2030       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2031       vec_validate (vam->ip6_fib_counters, vrf_index);
2032       vam->ip6_fib_counters[vrf_index] = NULL;
2033     }
2034
2035   vec_free (vam->ip6_fib_counters[vrf_index]);
2036   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2037   count = ntohl (mp->count);
2038   for (i = 0; i < count; i++)
2039     {
2040       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2041       counter = &vam->ip6_fib_counters[vrf_index][i];
2042       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2043       counter->address = ip6;
2044       counter->address_length = v->address_length;
2045       counter->packets = clib_net_to_host_u64 (v->packets);
2046       counter->bytes = clib_net_to_host_u64 (v->bytes);
2047       v++;
2048     }
2049 }
2050
2051 static void vl_api_get_first_msg_id_reply_t_handler
2052   (vl_api_get_first_msg_id_reply_t * mp)
2053 {
2054   vat_main_t *vam = &vat_main;
2055   i32 retval = ntohl (mp->retval);
2056
2057   if (vam->async_mode)
2058     {
2059       vam->async_errors += (retval < 0);
2060     }
2061   else
2062     {
2063       vam->retval = retval;
2064       vam->result_ready = 1;
2065     }
2066   if (retval >= 0)
2067     {
2068       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2069     }
2070 }
2071
2072 static void vl_api_get_first_msg_id_reply_t_handler_json
2073   (vl_api_get_first_msg_id_reply_t * mp)
2074 {
2075   vat_main_t *vam = &vat_main;
2076   vat_json_node_t node;
2077
2078   vat_json_init_object (&node);
2079   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2080   vat_json_object_add_uint (&node, "first_msg_id",
2081                             (uint) ntohs (mp->first_msg_id));
2082
2083   vat_json_print (vam->ofp, &node);
2084   vat_json_free (&node);
2085
2086   vam->retval = ntohl (mp->retval);
2087   vam->result_ready = 1;
2088 }
2089
2090 static void vl_api_get_node_graph_reply_t_handler
2091   (vl_api_get_node_graph_reply_t * mp)
2092 {
2093   vat_main_t *vam = &vat_main;
2094   api_main_t *am = &api_main;
2095   i32 retval = ntohl (mp->retval);
2096   u8 *pvt_copy, *reply;
2097   void *oldheap;
2098   vlib_node_t *node;
2099   int i;
2100
2101   if (vam->async_mode)
2102     {
2103       vam->async_errors += (retval < 0);
2104     }
2105   else
2106     {
2107       vam->retval = retval;
2108       vam->result_ready = 1;
2109     }
2110
2111   /* "Should never happen..." */
2112   if (retval != 0)
2113     return;
2114
2115   reply = (u8 *) (mp->reply_in_shmem);
2116   pvt_copy = vec_dup (reply);
2117
2118   /* Toss the shared-memory original... */
2119   pthread_mutex_lock (&am->vlib_rp->mutex);
2120   oldheap = svm_push_data_heap (am->vlib_rp);
2121
2122   vec_free (reply);
2123
2124   svm_pop_heap (oldheap);
2125   pthread_mutex_unlock (&am->vlib_rp->mutex);
2126
2127   if (vam->graph_nodes)
2128     {
2129       hash_free (vam->graph_node_index_by_name);
2130
2131       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2132         {
2133           node = vam->graph_nodes[i];
2134           vec_free (node->name);
2135           vec_free (node->next_nodes);
2136           vec_free (node);
2137         }
2138       vec_free (vam->graph_nodes);
2139     }
2140
2141   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2142   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2143   vec_free (pvt_copy);
2144
2145   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2146     {
2147       node = vam->graph_nodes[i];
2148       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2149     }
2150 }
2151
2152 static void vl_api_get_node_graph_reply_t_handler_json
2153   (vl_api_get_node_graph_reply_t * mp)
2154 {
2155   vat_main_t *vam = &vat_main;
2156   api_main_t *am = &api_main;
2157   void *oldheap;
2158   vat_json_node_t node;
2159   u8 *reply;
2160
2161   /* $$$$ make this real? */
2162   vat_json_init_object (&node);
2163   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2164   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2165
2166   reply = (u8 *) (mp->reply_in_shmem);
2167
2168   /* Toss the shared-memory original... */
2169   pthread_mutex_lock (&am->vlib_rp->mutex);
2170   oldheap = svm_push_data_heap (am->vlib_rp);
2171
2172   vec_free (reply);
2173
2174   svm_pop_heap (oldheap);
2175   pthread_mutex_unlock (&am->vlib_rp->mutex);
2176
2177   vat_json_print (vam->ofp, &node);
2178   vat_json_free (&node);
2179
2180   vam->retval = ntohl (mp->retval);
2181   vam->result_ready = 1;
2182 }
2183
2184 static void
2185 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2186 {
2187   vat_main_t *vam = &vat_main;
2188   u8 *s = 0;
2189
2190   if (mp->local)
2191     {
2192       s = format (s, "%=16d%=16d%=16d\n",
2193                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2194     }
2195   else
2196     {
2197       s = format (s, "%=16U%=16d%=16d\n",
2198                   mp->is_ipv6 ? format_ip6_address :
2199                   format_ip4_address,
2200                   mp->ip_address, mp->priority, mp->weight);
2201     }
2202
2203   fformat (vam->ofp, "%v", s);
2204   vec_free (s);
2205 }
2206
2207 static void
2208 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2209                                             mp)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   vat_json_node_t *node = NULL;
2213   struct in6_addr ip6;
2214   struct in_addr ip4;
2215
2216   if (VAT_JSON_ARRAY != vam->json_tree.type)
2217     {
2218       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2219       vat_json_init_array (&vam->json_tree);
2220     }
2221   node = vat_json_array_add (&vam->json_tree);
2222   vat_json_init_object (node);
2223
2224   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2225   vat_json_object_add_uint (node, "priority", mp->priority);
2226   vat_json_object_add_uint (node, "weight", mp->weight);
2227
2228   if (mp->local)
2229     vat_json_object_add_uint (node, "sw_if_index",
2230                               clib_net_to_host_u32 (mp->sw_if_index));
2231   else
2232     {
2233       if (mp->is_ipv6)
2234         {
2235           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2236           vat_json_object_add_ip6 (node, "address", ip6);
2237         }
2238       else
2239         {
2240           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2241           vat_json_object_add_ip4 (node, "address", ip4);
2242         }
2243     }
2244 }
2245
2246 static void
2247 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2248                                            mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   u8 *ls_name = 0;
2252
2253   ls_name = format (0, "%s", mp->ls_name);
2254
2255   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2256            ls_name);
2257   vec_free (ls_name);
2258 }
2259
2260 static void
2261   vl_api_lisp_locator_set_details_t_handler_json
2262   (vl_api_lisp_locator_set_details_t * mp)
2263 {
2264   vat_main_t *vam = &vat_main;
2265   vat_json_node_t *node = 0;
2266   u8 *ls_name = 0;
2267
2268   ls_name = format (0, "%s", mp->ls_name);
2269   vec_add1 (ls_name, 0);
2270
2271   if (VAT_JSON_ARRAY != vam->json_tree.type)
2272     {
2273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2274       vat_json_init_array (&vam->json_tree);
2275     }
2276   node = vat_json_array_add (&vam->json_tree);
2277
2278   vat_json_init_object (node);
2279   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2280   vat_json_object_add_uint (node, "ls_index",
2281                             clib_net_to_host_u32 (mp->ls_index));
2282   vec_free (ls_name);
2283 }
2284
2285 static u8 *
2286 format_lisp_flat_eid (u8 * s, va_list * args)
2287 {
2288   u32 type = va_arg (*args, u32);
2289   u8 *eid = va_arg (*args, u8 *);
2290   u32 eid_len = va_arg (*args, u32);
2291
2292   switch (type)
2293     {
2294     case 0:
2295       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2296     case 1:
2297       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2298     case 2:
2299       return format (s, "%U", format_ethernet_address, eid);
2300     }
2301   return 0;
2302 }
2303
2304 static u8 *
2305 format_lisp_eid_vat (u8 * s, va_list * args)
2306 {
2307   u32 type = va_arg (*args, u32);
2308   u8 *eid = va_arg (*args, u8 *);
2309   u32 eid_len = va_arg (*args, u32);
2310   u8 *seid = va_arg (*args, u8 *);
2311   u32 seid_len = va_arg (*args, u32);
2312   u32 is_src_dst = va_arg (*args, u32);
2313
2314   if (is_src_dst)
2315     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2316
2317   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2318
2319   return s;
2320 }
2321
2322 static void
2323 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2324 {
2325   vat_main_t *vam = &vat_main;
2326   u8 *s = 0, *eid = 0;
2327
2328   if (~0 == mp->locator_set_index)
2329     s = format (0, "action: %d", mp->action);
2330   else
2331     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2332
2333   eid = format (0, "%U", format_lisp_eid_vat,
2334                 mp->eid_type,
2335                 mp->eid,
2336                 mp->eid_prefix_len,
2337                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2338   vec_add1 (eid, 0);
2339
2340   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2341            clib_net_to_host_u32 (mp->vni),
2342            eid,
2343            mp->is_local ? "local" : "remote",
2344            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2345   vec_free (s);
2346   vec_free (eid);
2347 }
2348
2349 static void
2350 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2351                                               * mp)
2352 {
2353   vat_main_t *vam = &vat_main;
2354   vat_json_node_t *node = 0;
2355   u8 *eid = 0;
2356
2357   if (VAT_JSON_ARRAY != vam->json_tree.type)
2358     {
2359       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2360       vat_json_init_array (&vam->json_tree);
2361     }
2362   node = vat_json_array_add (&vam->json_tree);
2363
2364   vat_json_init_object (node);
2365   if (~0 == mp->locator_set_index)
2366     vat_json_object_add_uint (node, "action", mp->action);
2367   else
2368     vat_json_object_add_uint (node, "locator_set_index",
2369                               clib_net_to_host_u32 (mp->locator_set_index));
2370
2371   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2372   eid = format (0, "%U", format_lisp_eid_vat,
2373                 mp->eid_type,
2374                 mp->eid,
2375                 mp->eid_prefix_len,
2376                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2377   vec_add1 (eid, 0);
2378   vat_json_object_add_string_copy (node, "eid", eid);
2379   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2380   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2381   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2382   vec_free (eid);
2383 }
2384
2385 static void
2386   vl_api_lisp_eid_table_map_details_t_handler
2387   (vl_api_lisp_eid_table_map_details_t * mp)
2388 {
2389   vat_main_t *vam = &vat_main;
2390
2391   u8 *line = format (0, "%=10d%=10d",
2392                      clib_net_to_host_u32 (mp->vni),
2393                      clib_net_to_host_u32 (mp->dp_table));
2394   fformat (vam->ofp, "%v\n", line);
2395   vec_free (line);
2396 }
2397
2398 static void
2399   vl_api_lisp_eid_table_map_details_t_handler_json
2400   (vl_api_lisp_eid_table_map_details_t * mp)
2401 {
2402   vat_main_t *vam = &vat_main;
2403   vat_json_node_t *node = NULL;
2404
2405   if (VAT_JSON_ARRAY != vam->json_tree.type)
2406     {
2407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2408       vat_json_init_array (&vam->json_tree);
2409     }
2410   node = vat_json_array_add (&vam->json_tree);
2411   vat_json_init_object (node);
2412   vat_json_object_add_uint (node, "dp_table",
2413                             clib_net_to_host_u32 (mp->dp_table));
2414   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2415 }
2416
2417 static void
2418   vl_api_lisp_eid_table_vni_details_t_handler
2419   (vl_api_lisp_eid_table_vni_details_t * mp)
2420 {
2421   vat_main_t *vam = &vat_main;
2422
2423   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2424   fformat (vam->ofp, "%v\n", line);
2425   vec_free (line);
2426 }
2427
2428 static void
2429   vl_api_lisp_eid_table_vni_details_t_handler_json
2430   (vl_api_lisp_eid_table_vni_details_t * mp)
2431 {
2432   vat_main_t *vam = &vat_main;
2433   vat_json_node_t *node = NULL;
2434
2435   if (VAT_JSON_ARRAY != vam->json_tree.type)
2436     {
2437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2438       vat_json_init_array (&vam->json_tree);
2439     }
2440   node = vat_json_array_add (&vam->json_tree);
2441   vat_json_init_object (node);
2442   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2443 }
2444
2445 static u8 *
2446 format_decap_next (u8 * s, va_list * args)
2447 {
2448   u32 next_index = va_arg (*args, u32);
2449
2450   switch (next_index)
2451     {
2452     case LISP_GPE_INPUT_NEXT_DROP:
2453       return format (s, "drop");
2454     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2455       return format (s, "ip4");
2456     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2457       return format (s, "ip6");
2458     default:
2459       return format (s, "unknown %d", next_index);
2460     }
2461   return s;
2462 }
2463
2464 static void
2465 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2466                                           mp)
2467 {
2468   vat_main_t *vam = &vat_main;
2469   u8 *iid_str;
2470   u8 *flag_str = NULL;
2471
2472   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2473
2474 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2475   foreach_lisp_gpe_flag_bit;
2476 #undef _
2477
2478   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2479            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2480            mp->tunnels,
2481            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2482            mp->source_ip,
2483            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2484            mp->destination_ip,
2485            ntohl (mp->encap_fib_id),
2486            ntohl (mp->decap_fib_id),
2487            format_decap_next, ntohl (mp->dcap_next),
2488            mp->ver_res >> 6,
2489            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2490
2491   vec_free (iid_str);
2492 }
2493
2494 static void
2495   vl_api_lisp_gpe_tunnel_details_t_handler_json
2496   (vl_api_lisp_gpe_tunnel_details_t * mp)
2497 {
2498   vat_main_t *vam = &vat_main;
2499   vat_json_node_t *node = NULL;
2500   struct in6_addr ip6;
2501   struct in_addr ip4;
2502   u8 *next_decap_str;
2503
2504   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2505
2506   if (VAT_JSON_ARRAY != vam->json_tree.type)
2507     {
2508       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2509       vat_json_init_array (&vam->json_tree);
2510     }
2511   node = vat_json_array_add (&vam->json_tree);
2512
2513   vat_json_init_object (node);
2514   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2515   if (mp->is_ipv6)
2516     {
2517       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2518       vat_json_object_add_ip6 (node, "source address", ip6);
2519       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2520       vat_json_object_add_ip6 (node, "destination address", ip6);
2521     }
2522   else
2523     {
2524       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2525       vat_json_object_add_ip4 (node, "source address", ip4);
2526       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2527       vat_json_object_add_ip4 (node, "destination address", ip4);
2528     }
2529   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2530   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2531   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2532   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2533   vat_json_object_add_uint (node, "flags", mp->flags);
2534   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2535   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2536   vat_json_object_add_uint (node, "res", mp->res);
2537   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2538
2539   vec_free (next_decap_str);
2540 }
2541
2542 static void
2543   vl_api_lisp_adjacencies_get_reply_t_handler
2544   (vl_api_lisp_adjacencies_get_reply_t * mp)
2545 {
2546   vat_main_t *vam = &vat_main;
2547   u32 i, n;
2548   int retval = clib_net_to_host_u32 (mp->retval);
2549   vl_api_lisp_adjacency_t *a;
2550
2551   if (retval)
2552     goto end;
2553
2554   n = clib_net_to_host_u32 (mp->count);
2555
2556   for (i = 0; i < n; i++)
2557     {
2558       a = &mp->adjacencies[i];
2559       fformat (vam->ofp, "%U %40U\n",
2560                format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2561                format_lisp_flat_eid, a->eid_type, a->reid,
2562                a->reid_prefix_len);
2563     }
2564
2565 end:
2566   vam->retval = retval;
2567   vam->result_ready = 1;
2568 }
2569
2570 static void
2571   vl_api_lisp_adjacencies_get_reply_t_handler_json
2572   (vl_api_lisp_adjacencies_get_reply_t * mp)
2573 {
2574   u8 *s = 0;
2575   vat_main_t *vam = &vat_main;
2576   vat_json_node_t *e = 0, root;
2577   u32 i, n;
2578   int retval = clib_net_to_host_u32 (mp->retval);
2579   vl_api_lisp_adjacency_t *a;
2580
2581   if (retval)
2582     goto end;
2583
2584   n = clib_net_to_host_u32 (mp->count);
2585   vat_json_init_array (&root);
2586
2587   for (i = 0; i < n; i++)
2588     {
2589       e = vat_json_array_add (&root);
2590       a = &mp->adjacencies[i];
2591
2592       vat_json_init_object (e);
2593       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2594                   a->leid_prefix_len);
2595       vec_add1 (s, 0);
2596       vat_json_object_add_string_copy (e, "leid", s);
2597       vec_free (s);
2598
2599       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2600                   a->reid_prefix_len);
2601       vec_add1 (s, 0);
2602       vat_json_object_add_string_copy (e, "reid", s);
2603       vec_free (s);
2604     }
2605
2606   vat_json_print (vam->ofp, &root);
2607   vat_json_free (&root);
2608
2609 end:
2610   vam->retval = retval;
2611   vam->result_ready = 1;
2612 }
2613
2614 static void
2615 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2616                                             * mp)
2617 {
2618   vat_main_t *vam = &vat_main;
2619
2620   fformat (vam->ofp, "%=20U\n",
2621            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2622            mp->ip_address);
2623 }
2624
2625 static void
2626   vl_api_lisp_map_resolver_details_t_handler_json
2627   (vl_api_lisp_map_resolver_details_t * mp)
2628 {
2629   vat_main_t *vam = &vat_main;
2630   vat_json_node_t *node = NULL;
2631   struct in6_addr ip6;
2632   struct in_addr ip4;
2633
2634   if (VAT_JSON_ARRAY != vam->json_tree.type)
2635     {
2636       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2637       vat_json_init_array (&vam->json_tree);
2638     }
2639   node = vat_json_array_add (&vam->json_tree);
2640
2641   vat_json_init_object (node);
2642   if (mp->is_ipv6)
2643     {
2644       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2645       vat_json_object_add_ip6 (node, "map resolver", ip6);
2646     }
2647   else
2648     {
2649       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2650       vat_json_object_add_ip4 (node, "map resolver", ip4);
2651     }
2652 }
2653
2654 static void
2655   vl_api_show_lisp_status_reply_t_handler
2656   (vl_api_show_lisp_status_reply_t * mp)
2657 {
2658   vat_main_t *vam = &vat_main;
2659   i32 retval = ntohl (mp->retval);
2660
2661   if (0 <= retval)
2662     {
2663       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2664                mp->feature_status ? "enabled" : "disabled",
2665                mp->gpe_status ? "enabled" : "disabled");
2666     }
2667
2668   vam->retval = retval;
2669   vam->result_ready = 1;
2670 }
2671
2672 static void
2673   vl_api_show_lisp_status_reply_t_handler_json
2674   (vl_api_show_lisp_status_reply_t * mp)
2675 {
2676   vat_main_t *vam = &vat_main;
2677   vat_json_node_t node;
2678   u8 *gpe_status = NULL;
2679   u8 *feature_status = NULL;
2680
2681   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2682   feature_status = format (0, "%s",
2683                            mp->feature_status ? "enabled" : "disabled");
2684   vec_add1 (gpe_status, 0);
2685   vec_add1 (feature_status, 0);
2686
2687   vat_json_init_object (&node);
2688   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2689   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2690
2691   vec_free (gpe_status);
2692   vec_free (feature_status);
2693
2694   vat_json_print (vam->ofp, &node);
2695   vat_json_free (&node);
2696
2697   vam->retval = ntohl (mp->retval);
2698   vam->result_ready = 1;
2699 }
2700
2701 static void
2702   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2703   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2704 {
2705   vat_main_t *vam = &vat_main;
2706   i32 retval = ntohl (mp->retval);
2707
2708   if (retval >= 0)
2709     {
2710       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2711     }
2712
2713   vam->retval = retval;
2714   vam->result_ready = 1;
2715 }
2716
2717 static void
2718   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2719   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2720 {
2721   vat_main_t *vam = &vat_main;
2722   vat_json_node_t *node = NULL;
2723
2724   if (VAT_JSON_ARRAY != vam->json_tree.type)
2725     {
2726       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2727       vat_json_init_array (&vam->json_tree);
2728     }
2729   node = vat_json_array_add (&vam->json_tree);
2730
2731   vat_json_init_object (node);
2732   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2733
2734   vat_json_print (vam->ofp, node);
2735   vat_json_free (node);
2736
2737   vam->retval = ntohl (mp->retval);
2738   vam->result_ready = 1;
2739 }
2740
2741 static u8 *
2742 format_lisp_map_request_mode (u8 * s, va_list * args)
2743 {
2744   u32 mode = va_arg (*args, u32);
2745
2746   switch (mode)
2747     {
2748     case 0:
2749       return format (0, "dst-only");
2750     case 1:
2751       return format (0, "src-dst");
2752     }
2753   return 0;
2754 }
2755
2756 static void
2757   vl_api_show_lisp_map_request_mode_reply_t_handler
2758   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2759 {
2760   vat_main_t *vam = &vat_main;
2761   i32 retval = ntohl (mp->retval);
2762
2763   if (0 <= retval)
2764     {
2765       u32 mode = mp->mode;
2766       fformat (vam->ofp, "map_request_mode: %U\n",
2767                format_lisp_map_request_mode, mode);
2768     }
2769
2770   vam->retval = retval;
2771   vam->result_ready = 1;
2772 }
2773
2774 static void
2775   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2776   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2777 {
2778   vat_main_t *vam = &vat_main;
2779   vat_json_node_t node;
2780   u8 *s = 0;
2781   u32 mode;
2782
2783   mode = mp->mode;
2784   s = format (0, "%U", format_lisp_map_request_mode, mode);
2785   vec_add1 (s, 0);
2786
2787   vat_json_init_object (&node);
2788   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2789   vat_json_print (vam->ofp, &node);
2790   vat_json_free (&node);
2791
2792   vec_free (s);
2793   vam->retval = ntohl (mp->retval);
2794   vam->result_ready = 1;
2795 }
2796
2797 static void
2798 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2799 {
2800   vat_main_t *vam = &vat_main;
2801   i32 retval = ntohl (mp->retval);
2802
2803   if (0 <= retval)
2804     {
2805       fformat (vam->ofp, "%-20s%-16s\n",
2806                mp->status ? "enabled" : "disabled",
2807                mp->status ? (char *) mp->locator_set_name : "");
2808     }
2809
2810   vam->retval = retval;
2811   vam->result_ready = 1;
2812 }
2813
2814 static void
2815 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2816                                             mp)
2817 {
2818   vat_main_t *vam = &vat_main;
2819   vat_json_node_t node;
2820   u8 *status = 0;
2821
2822   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2823   vec_add1 (status, 0);
2824
2825   vat_json_init_object (&node);
2826   vat_json_object_add_string_copy (&node, "status", status);
2827   if (mp->status)
2828     {
2829       vat_json_object_add_string_copy (&node, "locator_set",
2830                                        mp->locator_set_name);
2831     }
2832
2833   vec_free (status);
2834
2835   vat_json_print (vam->ofp, &node);
2836   vat_json_free (&node);
2837
2838   vam->retval = ntohl (mp->retval);
2839   vam->result_ready = 1;
2840 }
2841
2842 static u8 *
2843 format_policer_type (u8 * s, va_list * va)
2844 {
2845   u32 i = va_arg (*va, u32);
2846
2847   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2848     s = format (s, "1r2c");
2849   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2850     s = format (s, "1r3c");
2851   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2852     s = format (s, "2r3c-2698");
2853   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2854     s = format (s, "2r3c-4115");
2855   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2856     s = format (s, "2r3c-mef5cf1");
2857   else
2858     s = format (s, "ILLEGAL");
2859   return s;
2860 }
2861
2862 static u8 *
2863 format_policer_rate_type (u8 * s, va_list * va)
2864 {
2865   u32 i = va_arg (*va, u32);
2866
2867   if (i == SSE2_QOS_RATE_KBPS)
2868     s = format (s, "kbps");
2869   else if (i == SSE2_QOS_RATE_PPS)
2870     s = format (s, "pps");
2871   else
2872     s = format (s, "ILLEGAL");
2873   return s;
2874 }
2875
2876 static u8 *
2877 format_policer_round_type (u8 * s, va_list * va)
2878 {
2879   u32 i = va_arg (*va, u32);
2880
2881   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2882     s = format (s, "closest");
2883   else if (i == SSE2_QOS_ROUND_TO_UP)
2884     s = format (s, "up");
2885   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2886     s = format (s, "down");
2887   else
2888     s = format (s, "ILLEGAL");
2889   return s;
2890 }
2891
2892 static u8 *
2893 format_policer_action_type (u8 * s, va_list * va)
2894 {
2895   u32 i = va_arg (*va, u32);
2896
2897   if (i == SSE2_QOS_ACTION_DROP)
2898     s = format (s, "drop");
2899   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2900     s = format (s, "transmit");
2901   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2902     s = format (s, "mark-and-transmit");
2903   else
2904     s = format (s, "ILLEGAL");
2905   return s;
2906 }
2907
2908 static u8 *
2909 format_dscp (u8 * s, va_list * va)
2910 {
2911   u32 i = va_arg (*va, u32);
2912   char *t = 0;
2913
2914   switch (i)
2915     {
2916 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2917       foreach_vnet_dscp
2918 #undef _
2919     default:
2920       return format (s, "ILLEGAL");
2921     }
2922   s = format (s, "%s", t);
2923   return s;
2924 }
2925
2926 static void
2927 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2928 {
2929   vat_main_t *vam = &vat_main;
2930   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2931
2932   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2933     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2934   else
2935     conform_dscp_str = format (0, "");
2936
2937   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2938     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2939   else
2940     exceed_dscp_str = format (0, "");
2941
2942   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2943     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2944   else
2945     violate_dscp_str = format (0, "");
2946
2947   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2948            "rate type %U, round type %U, %s rate, %s color-aware, "
2949            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2950            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2951            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2952            mp->name,
2953            format_policer_type, mp->type,
2954            ntohl (mp->cir),
2955            ntohl (mp->eir),
2956            clib_net_to_host_u64 (mp->cb),
2957            clib_net_to_host_u64 (mp->eb),
2958            format_policer_rate_type, mp->rate_type,
2959            format_policer_round_type, mp->round_type,
2960            mp->single_rate ? "single" : "dual",
2961            mp->color_aware ? "is" : "not",
2962            ntohl (mp->cir_tokens_per_period),
2963            ntohl (mp->pir_tokens_per_period),
2964            ntohl (mp->scale),
2965            ntohl (mp->current_limit),
2966            ntohl (mp->current_bucket),
2967            ntohl (mp->extended_limit),
2968            ntohl (mp->extended_bucket),
2969            clib_net_to_host_u64 (mp->last_update_time),
2970            format_policer_action_type, mp->conform_action_type,
2971            conform_dscp_str,
2972            format_policer_action_type, mp->exceed_action_type,
2973            exceed_dscp_str,
2974            format_policer_action_type, mp->violate_action_type,
2975            violate_dscp_str);
2976
2977   vec_free (conform_dscp_str);
2978   vec_free (exceed_dscp_str);
2979   vec_free (violate_dscp_str);
2980 }
2981
2982 static void vl_api_policer_details_t_handler_json
2983   (vl_api_policer_details_t * mp)
2984 {
2985   vat_main_t *vam = &vat_main;
2986   vat_json_node_t *node;
2987   u8 *rate_type_str, *round_type_str, *type_str;
2988   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2989
2990   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2991   round_type_str =
2992     format (0, "%U", format_policer_round_type, mp->round_type);
2993   type_str = format (0, "%U", format_policer_type, mp->type);
2994   conform_action_str = format (0, "%U", format_policer_action_type,
2995                                mp->conform_action_type);
2996   exceed_action_str = format (0, "%U", format_policer_action_type,
2997                               mp->exceed_action_type);
2998   violate_action_str = format (0, "%U", format_policer_action_type,
2999                                mp->violate_action_type);
3000
3001   if (VAT_JSON_ARRAY != vam->json_tree.type)
3002     {
3003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3004       vat_json_init_array (&vam->json_tree);
3005     }
3006   node = vat_json_array_add (&vam->json_tree);
3007
3008   vat_json_init_object (node);
3009   vat_json_object_add_string_copy (node, "name", mp->name);
3010   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3011   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3012   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3013   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3014   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3015   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3016   vat_json_object_add_string_copy (node, "type", type_str);
3017   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3018   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3019   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3020   vat_json_object_add_uint (node, "cir_tokens_per_period",
3021                             ntohl (mp->cir_tokens_per_period));
3022   vat_json_object_add_uint (node, "eir_tokens_per_period",
3023                             ntohl (mp->pir_tokens_per_period));
3024   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3025   vat_json_object_add_uint (node, "current_bucket",
3026                             ntohl (mp->current_bucket));
3027   vat_json_object_add_uint (node, "extended_limit",
3028                             ntohl (mp->extended_limit));
3029   vat_json_object_add_uint (node, "extended_bucket",
3030                             ntohl (mp->extended_bucket));
3031   vat_json_object_add_uint (node, "last_update_time",
3032                             ntohl (mp->last_update_time));
3033   vat_json_object_add_string_copy (node, "conform_action",
3034                                    conform_action_str);
3035   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3036     {
3037       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3038       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3039       vec_free (dscp_str);
3040     }
3041   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3042   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3043     {
3044       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3045       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3046       vec_free (dscp_str);
3047     }
3048   vat_json_object_add_string_copy (node, "violate_action",
3049                                    violate_action_str);
3050   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3051     {
3052       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3053       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3054       vec_free (dscp_str);
3055     }
3056
3057   vec_free (rate_type_str);
3058   vec_free (round_type_str);
3059   vec_free (type_str);
3060   vec_free (conform_action_str);
3061   vec_free (exceed_action_str);
3062   vec_free (violate_action_str);
3063 }
3064
3065 static void
3066 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3067                                            mp)
3068 {
3069   vat_main_t *vam = &vat_main;
3070   int i, count = ntohl (mp->count);
3071
3072   if (count > 0)
3073     fformat (vam->ofp, "classify table ids (%d) : ", count);
3074   for (i = 0; i < count; i++)
3075     {
3076       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3077       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3078     }
3079   vam->retval = ntohl (mp->retval);
3080   vam->result_ready = 1;
3081 }
3082
3083 static void
3084   vl_api_classify_table_ids_reply_t_handler_json
3085   (vl_api_classify_table_ids_reply_t * mp)
3086 {
3087   vat_main_t *vam = &vat_main;
3088   int i, count = ntohl (mp->count);
3089
3090   if (count > 0)
3091     {
3092       vat_json_node_t node;
3093
3094       vat_json_init_object (&node);
3095       for (i = 0; i < count; i++)
3096         {
3097           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3098         }
3099       vat_json_print (vam->ofp, &node);
3100       vat_json_free (&node);
3101     }
3102   vam->retval = ntohl (mp->retval);
3103   vam->result_ready = 1;
3104 }
3105
3106 static void
3107   vl_api_classify_table_by_interface_reply_t_handler
3108   (vl_api_classify_table_by_interface_reply_t * mp)
3109 {
3110   vat_main_t *vam = &vat_main;
3111   u32 table_id;
3112
3113   table_id = ntohl (mp->l2_table_id);
3114   if (table_id != ~0)
3115     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3116   else
3117     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3118   table_id = ntohl (mp->ip4_table_id);
3119   if (table_id != ~0)
3120     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3121   else
3122     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3123   table_id = ntohl (mp->ip6_table_id);
3124   if (table_id != ~0)
3125     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3126   else
3127     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3128   vam->retval = ntohl (mp->retval);
3129   vam->result_ready = 1;
3130 }
3131
3132 static void
3133   vl_api_classify_table_by_interface_reply_t_handler_json
3134   (vl_api_classify_table_by_interface_reply_t * mp)
3135 {
3136   vat_main_t *vam = &vat_main;
3137   vat_json_node_t node;
3138
3139   vat_json_init_object (&node);
3140
3141   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3142   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3143   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3144
3145   vat_json_print (vam->ofp, &node);
3146   vat_json_free (&node);
3147
3148   vam->retval = ntohl (mp->retval);
3149   vam->result_ready = 1;
3150 }
3151
3152 static void vl_api_policer_add_del_reply_t_handler
3153   (vl_api_policer_add_del_reply_t * mp)
3154 {
3155   vat_main_t *vam = &vat_main;
3156   i32 retval = ntohl (mp->retval);
3157   if (vam->async_mode)
3158     {
3159       vam->async_errors += (retval < 0);
3160     }
3161   else
3162     {
3163       vam->retval = retval;
3164       vam->result_ready = 1;
3165       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3166         /*
3167          * Note: this is just barely thread-safe, depends on
3168          * the main thread spinning waiting for an answer...
3169          */
3170         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3171     }
3172 }
3173
3174 static void vl_api_policer_add_del_reply_t_handler_json
3175   (vl_api_policer_add_del_reply_t * mp)
3176 {
3177   vat_main_t *vam = &vat_main;
3178   vat_json_node_t node;
3179
3180   vat_json_init_object (&node);
3181   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3182   vat_json_object_add_uint (&node, "policer_index",
3183                             ntohl (mp->policer_index));
3184
3185   vat_json_print (vam->ofp, &node);
3186   vat_json_free (&node);
3187
3188   vam->retval = ntohl (mp->retval);
3189   vam->result_ready = 1;
3190 }
3191
3192 /* Format hex dump. */
3193 u8 *
3194 format_hex_bytes (u8 * s, va_list * va)
3195 {
3196   u8 *bytes = va_arg (*va, u8 *);
3197   int n_bytes = va_arg (*va, int);
3198   uword i;
3199
3200   /* Print short or long form depending on byte count. */
3201   uword short_form = n_bytes <= 32;
3202   uword indent = format_get_indent (s);
3203
3204   if (n_bytes == 0)
3205     return s;
3206
3207   for (i = 0; i < n_bytes; i++)
3208     {
3209       if (!short_form && (i % 32) == 0)
3210         s = format (s, "%08x: ", i);
3211       s = format (s, "%02x", bytes[i]);
3212       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3213         s = format (s, "\n%U", format_white_space, indent);
3214     }
3215
3216   return s;
3217 }
3218
3219 static void
3220 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3221                                             * mp)
3222 {
3223   vat_main_t *vam = &vat_main;
3224   i32 retval = ntohl (mp->retval);
3225   if (retval == 0)
3226     {
3227       fformat (vam->ofp, "classify table info :\n");
3228       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3229                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3230                ntohl (mp->miss_next_index));
3231       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3232                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3233                ntohl (mp->match_n_vectors));
3234       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3235                ntohl (mp->mask_length));
3236     }
3237   vam->retval = retval;
3238   vam->result_ready = 1;
3239 }
3240
3241 static void
3242   vl_api_classify_table_info_reply_t_handler_json
3243   (vl_api_classify_table_info_reply_t * mp)
3244 {
3245   vat_main_t *vam = &vat_main;
3246   vat_json_node_t node;
3247
3248   i32 retval = ntohl (mp->retval);
3249   if (retval == 0)
3250     {
3251       vat_json_init_object (&node);
3252
3253       vat_json_object_add_int (&node, "sessions",
3254                                ntohl (mp->active_sessions));
3255       vat_json_object_add_int (&node, "nexttbl",
3256                                ntohl (mp->next_table_index));
3257       vat_json_object_add_int (&node, "nextnode",
3258                                ntohl (mp->miss_next_index));
3259       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3260       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3261       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3262       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3263                       ntohl (mp->mask_length), 0);
3264       vat_json_object_add_string_copy (&node, "mask", s);
3265
3266       vat_json_print (vam->ofp, &node);
3267       vat_json_free (&node);
3268     }
3269   vam->retval = ntohl (mp->retval);
3270   vam->result_ready = 1;
3271 }
3272
3273 static void
3274 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3275                                            mp)
3276 {
3277   vat_main_t *vam = &vat_main;
3278
3279   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3280            ntohl (mp->hit_next_index), ntohl (mp->advance),
3281            ntohl (mp->opaque_index));
3282   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3283            ntohl (mp->match_length));
3284 }
3285
3286 static void
3287   vl_api_classify_session_details_t_handler_json
3288   (vl_api_classify_session_details_t * mp)
3289 {
3290   vat_main_t *vam = &vat_main;
3291   vat_json_node_t *node = NULL;
3292
3293   if (VAT_JSON_ARRAY != vam->json_tree.type)
3294     {
3295       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3296       vat_json_init_array (&vam->json_tree);
3297     }
3298   node = vat_json_array_add (&vam->json_tree);
3299
3300   vat_json_init_object (node);
3301   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3302   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3303   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3304   u8 *s =
3305     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3306             0);
3307   vat_json_object_add_string_copy (node, "match", s);
3308 }
3309
3310 static void vl_api_pg_create_interface_reply_t_handler
3311   (vl_api_pg_create_interface_reply_t * mp)
3312 {
3313   vat_main_t *vam = &vat_main;
3314
3315   vam->retval = ntohl (mp->retval);
3316   vam->result_ready = 1;
3317 }
3318
3319 static void vl_api_pg_create_interface_reply_t_handler_json
3320   (vl_api_pg_create_interface_reply_t * mp)
3321 {
3322   vat_main_t *vam = &vat_main;
3323   vat_json_node_t node;
3324
3325   i32 retval = ntohl (mp->retval);
3326   if (retval == 0)
3327     {
3328       vat_json_init_object (&node);
3329
3330       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3331
3332       vat_json_print (vam->ofp, &node);
3333       vat_json_free (&node);
3334     }
3335   vam->retval = ntohl (mp->retval);
3336   vam->result_ready = 1;
3337 }
3338
3339 static void vl_api_policer_classify_details_t_handler
3340   (vl_api_policer_classify_details_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343
3344   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3345            ntohl (mp->table_index));
3346 }
3347
3348 static void vl_api_policer_classify_details_t_handler_json
3349   (vl_api_policer_classify_details_t * mp)
3350 {
3351   vat_main_t *vam = &vat_main;
3352   vat_json_node_t *node;
3353
3354   if (VAT_JSON_ARRAY != vam->json_tree.type)
3355     {
3356       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3357       vat_json_init_array (&vam->json_tree);
3358     }
3359   node = vat_json_array_add (&vam->json_tree);
3360
3361   vat_json_init_object (node);
3362   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3363   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3364 }
3365
3366 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3367   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3368 {
3369   vat_main_t *vam = &vat_main;
3370   i32 retval = ntohl (mp->retval);
3371   if (vam->async_mode)
3372     {
3373       vam->async_errors += (retval < 0);
3374     }
3375   else
3376     {
3377       vam->retval = retval;
3378       vam->sw_if_index = ntohl (mp->sw_if_index);
3379       vam->result_ready = 1;
3380     }
3381 }
3382
3383 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3384   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3385 {
3386   vat_main_t *vam = &vat_main;
3387   vat_json_node_t node;
3388
3389   vat_json_init_object (&node);
3390   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3391   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3392
3393   vat_json_print (vam->ofp, &node);
3394   vat_json_free (&node);
3395
3396   vam->retval = ntohl (mp->retval);
3397   vam->result_ready = 1;
3398 }
3399
3400 static void vl_api_flow_classify_details_t_handler
3401   (vl_api_flow_classify_details_t * mp)
3402 {
3403   vat_main_t *vam = &vat_main;
3404
3405   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3406            ntohl (mp->table_index));
3407 }
3408
3409 static void vl_api_flow_classify_details_t_handler_json
3410   (vl_api_flow_classify_details_t * mp)
3411 {
3412   vat_main_t *vam = &vat_main;
3413   vat_json_node_t *node;
3414
3415   if (VAT_JSON_ARRAY != vam->json_tree.type)
3416     {
3417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3418       vat_json_init_array (&vam->json_tree);
3419     }
3420   node = vat_json_array_add (&vam->json_tree);
3421
3422   vat_json_init_object (node);
3423   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3424   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3425 }
3426
3427
3428
3429 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3430 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3431 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3432 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3433 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3434 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3435
3436 /*
3437  * Generate boilerplate reply handlers, which
3438  * dig the return value out of the xxx_reply_t API message,
3439  * stick it into vam->retval, and set vam->result_ready
3440  *
3441  * Could also do this by pointing N message decode slots at
3442  * a single function, but that could break in subtle ways.
3443  */
3444
3445 #define foreach_standard_reply_retval_handler           \
3446 _(sw_interface_set_flags_reply)                         \
3447 _(sw_interface_add_del_address_reply)                   \
3448 _(sw_interface_set_table_reply)                         \
3449 _(sw_interface_set_mpls_enable_reply)                   \
3450 _(sw_interface_set_vpath_reply)                         \
3451 _(sw_interface_set_vxlan_bypass_reply)                  \
3452 _(sw_interface_set_l2_bridge_reply)                     \
3453 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3454 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3455 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3456 _(bridge_domain_add_del_reply)                          \
3457 _(sw_interface_set_l2_xconnect_reply)                   \
3458 _(l2fib_add_del_reply)                                  \
3459 _(ip_add_del_route_reply)                               \
3460 _(mpls_route_add_del_reply)                             \
3461 _(mpls_ip_bind_unbind_reply)                            \
3462 _(proxy_arp_add_del_reply)                              \
3463 _(proxy_arp_intfc_enable_disable_reply)                 \
3464 _(sw_interface_set_unnumbered_reply)                    \
3465 _(ip_neighbor_add_del_reply)                            \
3466 _(reset_vrf_reply)                                      \
3467 _(oam_add_del_reply)                                    \
3468 _(reset_fib_reply)                                      \
3469 _(dhcp_proxy_config_reply)                              \
3470 _(dhcp_proxy_config_2_reply)                            \
3471 _(dhcp_proxy_set_vss_reply)                             \
3472 _(dhcp_client_config_reply)                             \
3473 _(set_ip_flow_hash_reply)                               \
3474 _(sw_interface_ip6_enable_disable_reply)                \
3475 _(sw_interface_ip6_set_link_local_address_reply)        \
3476 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3477 _(sw_interface_ip6nd_ra_config_reply)                   \
3478 _(set_arp_neighbor_limit_reply)                         \
3479 _(l2_patch_add_del_reply)                               \
3480 _(sr_tunnel_add_del_reply)                              \
3481 _(sr_policy_add_del_reply)                              \
3482 _(sr_multicast_map_add_del_reply)                       \
3483 _(classify_add_del_session_reply)                       \
3484 _(classify_set_interface_ip_table_reply)                \
3485 _(classify_set_interface_l2_tables_reply)               \
3486 _(l2tpv3_set_tunnel_cookies_reply)                      \
3487 _(l2tpv3_interface_enable_disable_reply)                \
3488 _(l2tpv3_set_lookup_key_reply)                          \
3489 _(l2_fib_clear_table_reply)                             \
3490 _(l2_interface_efp_filter_reply)                        \
3491 _(l2_interface_vlan_tag_rewrite_reply)                  \
3492 _(modify_vhost_user_if_reply)                           \
3493 _(delete_vhost_user_if_reply)                           \
3494 _(want_ip4_arp_events_reply)                            \
3495 _(want_ip6_nd_events_reply)                             \
3496 _(input_acl_set_interface_reply)                        \
3497 _(ipsec_spd_add_del_reply)                              \
3498 _(ipsec_interface_add_del_spd_reply)                    \
3499 _(ipsec_spd_add_del_entry_reply)                        \
3500 _(ipsec_sad_add_del_entry_reply)                        \
3501 _(ipsec_sa_set_key_reply)                               \
3502 _(ikev2_profile_add_del_reply)                          \
3503 _(ikev2_profile_set_auth_reply)                         \
3504 _(ikev2_profile_set_id_reply)                           \
3505 _(ikev2_profile_set_ts_reply)                           \
3506 _(ikev2_set_local_key_reply)                            \
3507 _(delete_loopback_reply)                                \
3508 _(bd_ip_mac_add_del_reply)                              \
3509 _(map_del_domain_reply)                                 \
3510 _(map_add_del_rule_reply)                               \
3511 _(want_interface_events_reply)                          \
3512 _(want_stats_reply)                                     \
3513 _(cop_interface_enable_disable_reply)                   \
3514 _(cop_whitelist_enable_disable_reply)                   \
3515 _(sw_interface_clear_stats_reply)                       \
3516 _(ioam_enable_reply)                              \
3517 _(ioam_disable_reply)                              \
3518 _(lisp_add_del_locator_reply)                           \
3519 _(lisp_add_del_local_eid_reply)                         \
3520 _(lisp_add_del_remote_mapping_reply)                    \
3521 _(lisp_add_del_adjacency_reply)                         \
3522 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3523 _(lisp_add_del_map_resolver_reply)                      \
3524 _(lisp_gpe_enable_disable_reply)                        \
3525 _(lisp_gpe_add_del_iface_reply)                         \
3526 _(lisp_enable_disable_reply)                            \
3527 _(lisp_pitr_set_locator_set_reply)                      \
3528 _(lisp_map_request_mode_reply)                          \
3529 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3530 _(lisp_eid_table_add_del_map_reply)                     \
3531 _(vxlan_gpe_add_del_tunnel_reply)                       \
3532 _(af_packet_delete_reply)                               \
3533 _(policer_classify_set_interface_reply)                 \
3534 _(netmap_create_reply)                                  \
3535 _(netmap_delete_reply)                                  \
3536 _(set_ipfix_exporter_reply)                             \
3537 _(set_ipfix_classify_stream_reply)                      \
3538 _(ipfix_classify_table_add_del_reply)                   \
3539 _(flow_classify_set_interface_reply)                    \
3540 _(sw_interface_span_enable_disable_reply)               \
3541 _(pg_capture_reply)                                     \
3542 _(pg_enable_disable_reply)                              \
3543 _(ip_source_and_port_range_check_add_del_reply)         \
3544 _(ip_source_and_port_range_check_interface_add_del_reply)\
3545 _(delete_subif_reply)                                   \
3546 _(l2_interface_pbb_tag_rewrite_reply)                   \
3547 _(punt_reply)                                           \
3548 _(feature_enable_disable_reply)                         \
3549 _(sw_interface_tag_add_del_reply)
3550
3551 #define _(n)                                    \
3552     static void vl_api_##n##_t_handler          \
3553     (vl_api_##n##_t * mp)                       \
3554     {                                           \
3555         vat_main_t * vam = &vat_main;           \
3556         i32 retval = ntohl(mp->retval);         \
3557         if (vam->async_mode) {                  \
3558             vam->async_errors += (retval < 0);  \
3559         } else {                                \
3560             vam->retval = retval;               \
3561             vam->result_ready = 1;              \
3562         }                                       \
3563     }
3564 foreach_standard_reply_retval_handler;
3565 #undef _
3566
3567 #define _(n)                                    \
3568     static void vl_api_##n##_t_handler_json     \
3569     (vl_api_##n##_t * mp)                       \
3570     {                                           \
3571         vat_main_t * vam = &vat_main;           \
3572         vat_json_node_t node;                   \
3573         vat_json_init_object(&node);            \
3574         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3575         vat_json_print(vam->ofp, &node);        \
3576         vam->retval = ntohl(mp->retval);        \
3577         vam->result_ready = 1;                  \
3578     }
3579 foreach_standard_reply_retval_handler;
3580 #undef _
3581
3582 /*
3583  * Table of message reply handlers, must include boilerplate handlers
3584  * we just generated
3585  */
3586
3587 #define foreach_vpe_api_reply_msg                                       \
3588 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3589 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3590 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3591 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3592 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3593 _(CLI_REPLY, cli_reply)                                                 \
3594 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3595 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3596   sw_interface_add_del_address_reply)                                   \
3597 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3598 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3599 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3600 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3601 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3602   sw_interface_set_l2_xconnect_reply)                                   \
3603 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3604   sw_interface_set_l2_bridge_reply)                                     \
3605 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3606   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3607 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3608   sw_interface_set_dpdk_hqos_subport_reply)                             \
3609 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3610   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3611 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3612 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3613 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3614 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3615 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3616 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3617 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3618 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3619 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3620 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3621 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3622 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3623 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3624 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3625 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3626   proxy_arp_intfc_enable_disable_reply)                                 \
3627 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
3628 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3629   sw_interface_set_unnumbered_reply)                                    \
3630 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3631 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3632 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3633 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3634 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3635 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3636 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3637 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3638 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3639 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3640 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3641 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3642   sw_interface_ip6_enable_disable_reply)                                \
3643 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3644   sw_interface_ip6_set_link_local_address_reply)                        \
3645 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3646   sw_interface_ip6nd_ra_prefix_reply)                                   \
3647 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3648   sw_interface_ip6nd_ra_config_reply)                                   \
3649 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3650 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3651 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3652 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3653 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3654 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3655 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3656 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3657 classify_set_interface_ip_table_reply)                                  \
3658 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3659   classify_set_interface_l2_tables_reply)                               \
3660 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3661 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3662 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3663 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3664 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3665   l2tpv3_interface_enable_disable_reply)                                \
3666 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3667 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3668 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3669 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3670 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3671 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3672 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3673 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3674 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3675 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3676 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3677 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3678 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3679 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3680 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3681 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3682 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3683 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3684 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3685 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3686 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3687 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3688 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3689 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3690 _(IP_DETAILS, ip_details)                                               \
3691 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3692 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3693 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3694 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3695 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3696 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3697 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3698 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3699 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3700 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3701 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3702 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3703 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3704 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3705 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3706 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3707 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3708 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3709 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3710 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3711 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3712 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3713 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3714 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3715 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3716 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3717 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3718 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3719 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3720 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3721 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3722 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3723 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3724 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3725 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3726 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3727 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3728 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3729 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3730 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3731 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3732 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3733 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3734 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3735 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3736 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3737 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3738 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3739 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3740 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3741 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3742 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3743 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3744   lisp_add_del_map_request_itr_rlocs_reply)                             \
3745 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3746   lisp_get_map_request_itr_rlocs_reply)                                 \
3747 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3748 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3749 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3750 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3751 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3752 _(POLICER_DETAILS, policer_details)                                     \
3753 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3754 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3755 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3756 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3757 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
3758 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3759 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3760 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3761 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3762 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3763 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3764 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3765 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3766 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3767 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3768 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3769 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3770 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3771 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3772 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3773 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3774 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3775 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3776 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3777 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3778  ip_source_and_port_range_check_add_del_reply)                          \
3779 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3780  ip_source_and_port_range_check_interface_add_del_reply)                \
3781 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3782 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3783 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3784 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3785 _(PUNT_REPLY, punt_reply)                                               \
3786 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3787 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3788 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
3789 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)
3790
3791 /* M: construct, but don't yet send a message */
3792
3793 #define M(T,t)                                  \
3794 do {                                            \
3795     vam->result_ready = 0;                      \
3796     mp = vl_msg_api_alloc(sizeof(*mp));         \
3797     memset (mp, 0, sizeof (*mp));               \
3798     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3799     mp->client_index = vam->my_client_index;    \
3800 } while(0);
3801
3802 #define M2(T,t,n)                               \
3803 do {                                            \
3804     vam->result_ready = 0;                      \
3805     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3806     memset (mp, 0, sizeof (*mp));               \
3807     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3808     mp->client_index = vam->my_client_index;    \
3809 } while(0);
3810
3811
3812 /* S: send a message */
3813 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3814
3815 /* W: wait for results, with timeout */
3816 #define W                                       \
3817 do {                                            \
3818     timeout = vat_time_now (vam) + 1.0;         \
3819                                                 \
3820     while (vat_time_now (vam) < timeout) {      \
3821         if (vam->result_ready == 1) {           \
3822             return (vam->retval);               \
3823         }                                       \
3824     }                                           \
3825     return -99;                                 \
3826 } while(0);
3827
3828 /* W2: wait for results, with timeout */
3829 #define W2(body)                                \
3830 do {                                            \
3831     timeout = vat_time_now (vam) + 1.0;         \
3832                                                 \
3833     while (vat_time_now (vam) < timeout) {      \
3834         if (vam->result_ready == 1) {           \
3835           (body);                               \
3836           return (vam->retval);                 \
3837         }                                       \
3838     }                                           \
3839     return -99;                                 \
3840 } while(0);
3841
3842 typedef struct
3843 {
3844   u8 *name;
3845   u32 value;
3846 } name_sort_t;
3847
3848
3849 #define STR_VTR_OP_CASE(op)     \
3850     case L2_VTR_ ## op:         \
3851         return "" # op;
3852
3853 static const char *
3854 str_vtr_op (u32 vtr_op)
3855 {
3856   switch (vtr_op)
3857     {
3858       STR_VTR_OP_CASE (DISABLED);
3859       STR_VTR_OP_CASE (PUSH_1);
3860       STR_VTR_OP_CASE (PUSH_2);
3861       STR_VTR_OP_CASE (POP_1);
3862       STR_VTR_OP_CASE (POP_2);
3863       STR_VTR_OP_CASE (TRANSLATE_1_1);
3864       STR_VTR_OP_CASE (TRANSLATE_1_2);
3865       STR_VTR_OP_CASE (TRANSLATE_2_1);
3866       STR_VTR_OP_CASE (TRANSLATE_2_2);
3867     }
3868
3869   return "UNKNOWN";
3870 }
3871
3872 static int
3873 dump_sub_interface_table (vat_main_t * vam)
3874 {
3875   const sw_interface_subif_t *sub = NULL;
3876
3877   if (vam->json_output)
3878     {
3879       clib_warning
3880         ("JSON output supported only for VPE API calls and dump_stats_table");
3881       return -99;
3882     }
3883
3884   fformat (vam->ofp,
3885            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3886            "Interface", "sw_if_index",
3887            "sub id", "dot1ad", "tags", "outer id",
3888            "inner id", "exact", "default", "outer any", "inner any");
3889
3890   vec_foreach (sub, vam->sw_if_subif_table)
3891   {
3892     fformat (vam->ofp,
3893              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3894              sub->interface_name,
3895              sub->sw_if_index,
3896              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3897              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3898              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3899              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3900     if (sub->vtr_op != L2_VTR_DISABLED)
3901       {
3902         fformat (vam->ofp,
3903                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3904                  "tag1: %d tag2: %d ]\n",
3905                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3906                  sub->vtr_tag1, sub->vtr_tag2);
3907       }
3908   }
3909
3910   return 0;
3911 }
3912
3913 static int
3914 name_sort_cmp (void *a1, void *a2)
3915 {
3916   name_sort_t *n1 = a1;
3917   name_sort_t *n2 = a2;
3918
3919   return strcmp ((char *) n1->name, (char *) n2->name);
3920 }
3921
3922 static int
3923 dump_interface_table (vat_main_t * vam)
3924 {
3925   hash_pair_t *p;
3926   name_sort_t *nses = 0, *ns;
3927
3928   if (vam->json_output)
3929     {
3930       clib_warning
3931         ("JSON output supported only for VPE API calls and dump_stats_table");
3932       return -99;
3933     }
3934
3935   /* *INDENT-OFF* */
3936   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3937   ({
3938     vec_add2 (nses, ns, 1);
3939     ns->name = (u8 *)(p->key);
3940     ns->value = (u32) p->value[0];
3941   }));
3942   /* *INDENT-ON* */
3943
3944   vec_sort_with_function (nses, name_sort_cmp);
3945
3946   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3947   vec_foreach (ns, nses)
3948   {
3949     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3950   }
3951   vec_free (nses);
3952   return 0;
3953 }
3954
3955 static int
3956 dump_ip_table (vat_main_t * vam, int is_ipv6)
3957 {
3958   const ip_details_t *det = NULL;
3959   const ip_address_details_t *address = NULL;
3960   u32 i = ~0;
3961
3962   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3963
3964   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3965   {
3966     i++;
3967     if (!det->present)
3968       {
3969         continue;
3970       }
3971     fformat (vam->ofp, "%-12d\n", i);
3972     fformat (vam->ofp,
3973              "            %-30s%-13s\n", "Address", "Prefix length");
3974     if (!det->addr)
3975       {
3976         continue;
3977       }
3978     vec_foreach (address, det->addr)
3979     {
3980       fformat (vam->ofp,
3981                "            %-30U%-13d\n",
3982                is_ipv6 ? format_ip6_address : format_ip4_address,
3983                address->ip, address->prefix_length);
3984     }
3985   }
3986
3987   return 0;
3988 }
3989
3990 static int
3991 dump_ipv4_table (vat_main_t * vam)
3992 {
3993   if (vam->json_output)
3994     {
3995       clib_warning
3996         ("JSON output supported only for VPE API calls and dump_stats_table");
3997       return -99;
3998     }
3999
4000   return dump_ip_table (vam, 0);
4001 }
4002
4003 static int
4004 dump_ipv6_table (vat_main_t * vam)
4005 {
4006   if (vam->json_output)
4007     {
4008       clib_warning
4009         ("JSON output supported only for VPE API calls and dump_stats_table");
4010       return -99;
4011     }
4012
4013   return dump_ip_table (vam, 1);
4014 }
4015
4016 static char *
4017 counter_type_to_str (u8 counter_type, u8 is_combined)
4018 {
4019   if (!is_combined)
4020     {
4021       switch (counter_type)
4022         {
4023         case VNET_INTERFACE_COUNTER_DROP:
4024           return "drop";
4025         case VNET_INTERFACE_COUNTER_PUNT:
4026           return "punt";
4027         case VNET_INTERFACE_COUNTER_IP4:
4028           return "ip4";
4029         case VNET_INTERFACE_COUNTER_IP6:
4030           return "ip6";
4031         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4032           return "rx-no-buf";
4033         case VNET_INTERFACE_COUNTER_RX_MISS:
4034           return "rx-miss";
4035         case VNET_INTERFACE_COUNTER_RX_ERROR:
4036           return "rx-error";
4037         case VNET_INTERFACE_COUNTER_TX_ERROR:
4038           return "tx-error";
4039         default:
4040           return "INVALID-COUNTER-TYPE";
4041         }
4042     }
4043   else
4044     {
4045       switch (counter_type)
4046         {
4047         case VNET_INTERFACE_COUNTER_RX:
4048           return "rx";
4049         case VNET_INTERFACE_COUNTER_TX:
4050           return "tx";
4051         default:
4052           return "INVALID-COUNTER-TYPE";
4053         }
4054     }
4055 }
4056
4057 static int
4058 dump_stats_table (vat_main_t * vam)
4059 {
4060   vat_json_node_t node;
4061   vat_json_node_t *msg_array;
4062   vat_json_node_t *msg;
4063   vat_json_node_t *counter_array;
4064   vat_json_node_t *counter;
4065   interface_counter_t c;
4066   u64 packets;
4067   ip4_fib_counter_t *c4;
4068   ip6_fib_counter_t *c6;
4069   int i, j;
4070
4071   if (!vam->json_output)
4072     {
4073       clib_warning ("dump_stats_table supported only in JSON format");
4074       return -99;
4075     }
4076
4077   vat_json_init_object (&node);
4078
4079   /* interface counters */
4080   msg_array = vat_json_object_add (&node, "interface_counters");
4081   vat_json_init_array (msg_array);
4082   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4083     {
4084       msg = vat_json_array_add (msg_array);
4085       vat_json_init_object (msg);
4086       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4087                                        (u8 *) counter_type_to_str (i, 0));
4088       vat_json_object_add_int (msg, "is_combined", 0);
4089       counter_array = vat_json_object_add (msg, "data");
4090       vat_json_init_array (counter_array);
4091       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4092         {
4093           packets = vam->simple_interface_counters[i][j];
4094           vat_json_array_add_uint (counter_array, packets);
4095         }
4096     }
4097   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4098     {
4099       msg = vat_json_array_add (msg_array);
4100       vat_json_init_object (msg);
4101       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4102                                        (u8 *) counter_type_to_str (i, 1));
4103       vat_json_object_add_int (msg, "is_combined", 1);
4104       counter_array = vat_json_object_add (msg, "data");
4105       vat_json_init_array (counter_array);
4106       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4107         {
4108           c = vam->combined_interface_counters[i][j];
4109           counter = vat_json_array_add (counter_array);
4110           vat_json_init_object (counter);
4111           vat_json_object_add_uint (counter, "packets", c.packets);
4112           vat_json_object_add_uint (counter, "bytes", c.bytes);
4113         }
4114     }
4115
4116   /* ip4 fib counters */
4117   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4118   vat_json_init_array (msg_array);
4119   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4120     {
4121       msg = vat_json_array_add (msg_array);
4122       vat_json_init_object (msg);
4123       vat_json_object_add_uint (msg, "vrf_id",
4124                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4125       counter_array = vat_json_object_add (msg, "c");
4126       vat_json_init_array (counter_array);
4127       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4128         {
4129           counter = vat_json_array_add (counter_array);
4130           vat_json_init_object (counter);
4131           c4 = &vam->ip4_fib_counters[i][j];
4132           vat_json_object_add_ip4 (counter, "address", c4->address);
4133           vat_json_object_add_uint (counter, "address_length",
4134                                     c4->address_length);
4135           vat_json_object_add_uint (counter, "packets", c4->packets);
4136           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4137         }
4138     }
4139
4140   /* ip6 fib counters */
4141   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4142   vat_json_init_array (msg_array);
4143   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4144     {
4145       msg = vat_json_array_add (msg_array);
4146       vat_json_init_object (msg);
4147       vat_json_object_add_uint (msg, "vrf_id",
4148                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4149       counter_array = vat_json_object_add (msg, "c");
4150       vat_json_init_array (counter_array);
4151       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4152         {
4153           counter = vat_json_array_add (counter_array);
4154           vat_json_init_object (counter);
4155           c6 = &vam->ip6_fib_counters[i][j];
4156           vat_json_object_add_ip6 (counter, "address", c6->address);
4157           vat_json_object_add_uint (counter, "address_length",
4158                                     c6->address_length);
4159           vat_json_object_add_uint (counter, "packets", c6->packets);
4160           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4161         }
4162     }
4163
4164   vat_json_print (vam->ofp, &node);
4165   vat_json_free (&node);
4166
4167   return 0;
4168 }
4169
4170 int
4171 exec (vat_main_t * vam)
4172 {
4173   api_main_t *am = &api_main;
4174   vl_api_cli_request_t *mp;
4175   f64 timeout;
4176   void *oldheap;
4177   u8 *cmd = 0;
4178   unformat_input_t *i = vam->input;
4179
4180   if (vec_len (i->buffer) == 0)
4181     return -1;
4182
4183   if (vam->exec_mode == 0 && unformat (i, "mode"))
4184     {
4185       vam->exec_mode = 1;
4186       return 0;
4187     }
4188   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4189     {
4190       vam->exec_mode = 0;
4191       return 0;
4192     }
4193
4194
4195   M (CLI_REQUEST, cli_request);
4196
4197   /*
4198    * Copy cmd into shared memory.
4199    * In order for the CLI command to work, it
4200    * must be a vector ending in \n, not a C-string ending
4201    * in \n\0.
4202    */
4203   pthread_mutex_lock (&am->vlib_rp->mutex);
4204   oldheap = svm_push_data_heap (am->vlib_rp);
4205
4206   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4207   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4208
4209   svm_pop_heap (oldheap);
4210   pthread_mutex_unlock (&am->vlib_rp->mutex);
4211
4212   mp->cmd_in_shmem = (u64) cmd;
4213   S;
4214   timeout = vat_time_now (vam) + 10.0;
4215
4216   while (vat_time_now (vam) < timeout)
4217     {
4218       if (vam->result_ready == 1)
4219         {
4220           u8 *free_me;
4221           if (vam->shmem_result != NULL)
4222             fformat (vam->ofp, "%s", vam->shmem_result);
4223           pthread_mutex_lock (&am->vlib_rp->mutex);
4224           oldheap = svm_push_data_heap (am->vlib_rp);
4225
4226           free_me = (u8 *) vam->shmem_result;
4227           vec_free (free_me);
4228
4229           svm_pop_heap (oldheap);
4230           pthread_mutex_unlock (&am->vlib_rp->mutex);
4231           return 0;
4232         }
4233     }
4234   return -99;
4235 }
4236
4237 /*
4238  * Future replacement of exec() that passes CLI buffers directly in
4239  * the API messages instead of an additional shared memory area.
4240  */
4241 static int
4242 exec_inband (vat_main_t * vam)
4243 {
4244   vl_api_cli_inband_t *mp;
4245   f64 timeout;
4246   unformat_input_t *i = vam->input;
4247
4248   if (vec_len (i->buffer) == 0)
4249     return -1;
4250
4251   if (vam->exec_mode == 0 && unformat (i, "mode"))
4252     {
4253       vam->exec_mode = 1;
4254       return 0;
4255     }
4256   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4257     {
4258       vam->exec_mode = 0;
4259       return 0;
4260     }
4261
4262   /*
4263    * In order for the CLI command to work, it
4264    * must be a vector ending in \n, not a C-string ending
4265    * in \n\0.
4266    */
4267   u32 len = vec_len (vam->input->buffer);
4268   M2 (CLI_INBAND, cli_inband, len);
4269   clib_memcpy (mp->cmd, vam->input->buffer, len);
4270   mp->length = htonl (len);
4271
4272   S;
4273   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4274 }
4275
4276 static int
4277 api_create_loopback (vat_main_t * vam)
4278 {
4279   unformat_input_t *i = vam->input;
4280   vl_api_create_loopback_t *mp;
4281   f64 timeout;
4282   u8 mac_address[6];
4283   u8 mac_set = 0;
4284
4285   memset (mac_address, 0, sizeof (mac_address));
4286
4287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4288     {
4289       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4290         mac_set = 1;
4291       else
4292         break;
4293     }
4294
4295   /* Construct the API message */
4296   M (CREATE_LOOPBACK, create_loopback);
4297   if (mac_set)
4298     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4299
4300   S;
4301   W;
4302 }
4303
4304 static int
4305 api_delete_loopback (vat_main_t * vam)
4306 {
4307   unformat_input_t *i = vam->input;
4308   vl_api_delete_loopback_t *mp;
4309   f64 timeout;
4310   u32 sw_if_index = ~0;
4311
4312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4313     {
4314       if (unformat (i, "sw_if_index %d", &sw_if_index))
4315         ;
4316       else
4317         break;
4318     }
4319
4320   if (sw_if_index == ~0)
4321     {
4322       errmsg ("missing sw_if_index\n");
4323       return -99;
4324     }
4325
4326   /* Construct the API message */
4327   M (DELETE_LOOPBACK, delete_loopback);
4328   mp->sw_if_index = ntohl (sw_if_index);
4329
4330   S;
4331   W;
4332 }
4333
4334 static int
4335 api_want_stats (vat_main_t * vam)
4336 {
4337   unformat_input_t *i = vam->input;
4338   vl_api_want_stats_t *mp;
4339   f64 timeout;
4340   int enable = -1;
4341
4342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4343     {
4344       if (unformat (i, "enable"))
4345         enable = 1;
4346       else if (unformat (i, "disable"))
4347         enable = 0;
4348       else
4349         break;
4350     }
4351
4352   if (enable == -1)
4353     {
4354       errmsg ("missing enable|disable\n");
4355       return -99;
4356     }
4357
4358   M (WANT_STATS, want_stats);
4359   mp->enable_disable = enable;
4360
4361   S;
4362   W;
4363 }
4364
4365 static int
4366 api_want_interface_events (vat_main_t * vam)
4367 {
4368   unformat_input_t *i = vam->input;
4369   vl_api_want_interface_events_t *mp;
4370   f64 timeout;
4371   int enable = -1;
4372
4373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4374     {
4375       if (unformat (i, "enable"))
4376         enable = 1;
4377       else if (unformat (i, "disable"))
4378         enable = 0;
4379       else
4380         break;
4381     }
4382
4383   if (enable == -1)
4384     {
4385       errmsg ("missing enable|disable\n");
4386       return -99;
4387     }
4388
4389   M (WANT_INTERFACE_EVENTS, want_interface_events);
4390   mp->enable_disable = enable;
4391
4392   vam->interface_event_display = enable;
4393
4394   S;
4395   W;
4396 }
4397
4398
4399 /* Note: non-static, called once to set up the initial intfc table */
4400 int
4401 api_sw_interface_dump (vat_main_t * vam)
4402 {
4403   vl_api_sw_interface_dump_t *mp;
4404   f64 timeout;
4405   hash_pair_t *p;
4406   name_sort_t *nses = 0, *ns;
4407   sw_interface_subif_t *sub = NULL;
4408
4409   /* Toss the old name table */
4410   /* *INDENT-OFF* */
4411   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4412   ({
4413     vec_add2 (nses, ns, 1);
4414     ns->name = (u8 *)(p->key);
4415     ns->value = (u32) p->value[0];
4416   }));
4417   /* *INDENT-ON* */
4418
4419   hash_free (vam->sw_if_index_by_interface_name);
4420
4421   vec_foreach (ns, nses) vec_free (ns->name);
4422
4423   vec_free (nses);
4424
4425   vec_foreach (sub, vam->sw_if_subif_table)
4426   {
4427     vec_free (sub->interface_name);
4428   }
4429   vec_free (vam->sw_if_subif_table);
4430
4431   /* recreate the interface name hash table */
4432   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4433
4434   /* Get list of ethernets */
4435   M (SW_INTERFACE_DUMP, sw_interface_dump);
4436   mp->name_filter_valid = 1;
4437   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4438   S;
4439
4440   /* and local / loopback interfaces */
4441   M (SW_INTERFACE_DUMP, sw_interface_dump);
4442   mp->name_filter_valid = 1;
4443   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4444   S;
4445
4446   /* and packet-generator interfaces */
4447   M (SW_INTERFACE_DUMP, sw_interface_dump);
4448   mp->name_filter_valid = 1;
4449   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4450   S;
4451
4452   /* and vxlan-gpe tunnel interfaces */
4453   M (SW_INTERFACE_DUMP, sw_interface_dump);
4454   mp->name_filter_valid = 1;
4455   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4456            sizeof (mp->name_filter) - 1);
4457   S;
4458
4459   /* and vxlan tunnel interfaces */
4460   M (SW_INTERFACE_DUMP, sw_interface_dump);
4461   mp->name_filter_valid = 1;
4462   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4463   S;
4464
4465   /* and host (af_packet) interfaces */
4466   M (SW_INTERFACE_DUMP, sw_interface_dump);
4467   mp->name_filter_valid = 1;
4468   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4469   S;
4470
4471   /* and l2tpv3 tunnel interfaces */
4472   M (SW_INTERFACE_DUMP, sw_interface_dump);
4473   mp->name_filter_valid = 1;
4474   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4475            sizeof (mp->name_filter) - 1);
4476   S;
4477
4478   /* and GRE tunnel interfaces */
4479   M (SW_INTERFACE_DUMP, sw_interface_dump);
4480   mp->name_filter_valid = 1;
4481   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4482   S;
4483
4484   /* and LISP-GPE interfaces */
4485   M (SW_INTERFACE_DUMP, sw_interface_dump);
4486   mp->name_filter_valid = 1;
4487   strncpy ((char *) mp->name_filter, "lisp_gpe",
4488            sizeof (mp->name_filter) - 1);
4489   S;
4490
4491   /* and IPSEC tunnel interfaces */
4492   M (SW_INTERFACE_DUMP, sw_interface_dump);
4493   mp->name_filter_valid = 1;
4494   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4495   S;
4496
4497   /* Use a control ping for synchronization */
4498   {
4499     vl_api_control_ping_t *mp;
4500     M (CONTROL_PING, control_ping);
4501     S;
4502   }
4503   W;
4504 }
4505
4506 static int
4507 api_sw_interface_set_flags (vat_main_t * vam)
4508 {
4509   unformat_input_t *i = vam->input;
4510   vl_api_sw_interface_set_flags_t *mp;
4511   f64 timeout;
4512   u32 sw_if_index;
4513   u8 sw_if_index_set = 0;
4514   u8 admin_up = 0, link_up = 0;
4515
4516   /* Parse args required to build the message */
4517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4518     {
4519       if (unformat (i, "admin-up"))
4520         admin_up = 1;
4521       else if (unformat (i, "admin-down"))
4522         admin_up = 0;
4523       else if (unformat (i, "link-up"))
4524         link_up = 1;
4525       else if (unformat (i, "link-down"))
4526         link_up = 0;
4527       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4528         sw_if_index_set = 1;
4529       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4530         sw_if_index_set = 1;
4531       else
4532         break;
4533     }
4534
4535   if (sw_if_index_set == 0)
4536     {
4537       errmsg ("missing interface name or sw_if_index\n");
4538       return -99;
4539     }
4540
4541   /* Construct the API message */
4542   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4543   mp->sw_if_index = ntohl (sw_if_index);
4544   mp->admin_up_down = admin_up;
4545   mp->link_up_down = link_up;
4546
4547   /* send it... */
4548   S;
4549
4550   /* Wait for a reply, return the good/bad news... */
4551   W;
4552 }
4553
4554 static int
4555 api_sw_interface_clear_stats (vat_main_t * vam)
4556 {
4557   unformat_input_t *i = vam->input;
4558   vl_api_sw_interface_clear_stats_t *mp;
4559   f64 timeout;
4560   u32 sw_if_index;
4561   u8 sw_if_index_set = 0;
4562
4563   /* Parse args required to build the message */
4564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4565     {
4566       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4567         sw_if_index_set = 1;
4568       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4569         sw_if_index_set = 1;
4570       else
4571         break;
4572     }
4573
4574   /* Construct the API message */
4575   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4576
4577   if (sw_if_index_set == 1)
4578     mp->sw_if_index = ntohl (sw_if_index);
4579   else
4580     mp->sw_if_index = ~0;
4581
4582   /* send it... */
4583   S;
4584
4585   /* Wait for a reply, return the good/bad news... */
4586   W;
4587 }
4588
4589 static int
4590 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4591 {
4592   unformat_input_t *i = vam->input;
4593   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4594   f64 timeout;
4595   u32 sw_if_index;
4596   u8 sw_if_index_set = 0;
4597   u32 subport;
4598   u8 subport_set = 0;
4599   u32 pipe;
4600   u8 pipe_set = 0;
4601   u32 profile;
4602   u8 profile_set = 0;
4603
4604   /* Parse args required to build the message */
4605   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4606     {
4607       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4608         sw_if_index_set = 1;
4609       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4610         sw_if_index_set = 1;
4611       else if (unformat (i, "subport %u", &subport))
4612         subport_set = 1;
4613       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4614         sw_if_index_set = 1;
4615       else if (unformat (i, "pipe %u", &pipe))
4616         pipe_set = 1;
4617       else if (unformat (i, "profile %u", &profile))
4618         profile_set = 1;
4619       else
4620         break;
4621     }
4622
4623   if (sw_if_index_set == 0)
4624     {
4625       errmsg ("missing interface name or sw_if_index\n");
4626       return -99;
4627     }
4628
4629   if (subport_set == 0)
4630     {
4631       errmsg ("missing subport \n");
4632       return -99;
4633     }
4634
4635   if (pipe_set == 0)
4636     {
4637       errmsg ("missing pipe\n");
4638       return -99;
4639     }
4640
4641   if (profile_set == 0)
4642     {
4643       errmsg ("missing profile\n");
4644       return -99;
4645     }
4646
4647   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4648
4649   mp->sw_if_index = ntohl (sw_if_index);
4650   mp->subport = ntohl (subport);
4651   mp->pipe = ntohl (pipe);
4652   mp->profile = ntohl (profile);
4653
4654
4655   S;
4656   W;
4657   /* NOTREACHED */
4658   return 0;
4659 }
4660
4661 static int
4662 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4663 {
4664   unformat_input_t *i = vam->input;
4665   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4666   f64 timeout;
4667   u32 sw_if_index;
4668   u8 sw_if_index_set = 0;
4669   u32 subport;
4670   u8 subport_set = 0;
4671   u32 tb_rate = 1250000000;     /* 10GbE */
4672   u32 tb_size = 1000000;
4673   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4674   u32 tc_period = 10;
4675
4676   /* Parse args required to build the message */
4677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4678     {
4679       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4680         sw_if_index_set = 1;
4681       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4682         sw_if_index_set = 1;
4683       else if (unformat (i, "subport %u", &subport))
4684         subport_set = 1;
4685       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4686         sw_if_index_set = 1;
4687       else if (unformat (i, "rate %u", &tb_rate))
4688         {
4689           u32 tc_id;
4690
4691           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4692                tc_id++)
4693             tc_rate[tc_id] = tb_rate;
4694         }
4695       else if (unformat (i, "bktsize %u", &tb_size))
4696         ;
4697       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4698         ;
4699       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4700         ;
4701       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4702         ;
4703       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4704         ;
4705       else if (unformat (i, "period %u", &tc_period))
4706         ;
4707       else
4708         break;
4709     }
4710
4711   if (sw_if_index_set == 0)
4712     {
4713       errmsg ("missing interface name or sw_if_index\n");
4714       return -99;
4715     }
4716
4717   if (subport_set == 0)
4718     {
4719       errmsg ("missing subport \n");
4720       return -99;
4721     }
4722
4723   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4724
4725   mp->sw_if_index = ntohl (sw_if_index);
4726   mp->subport = ntohl (subport);
4727   mp->tb_rate = ntohl (tb_rate);
4728   mp->tb_size = ntohl (tb_size);
4729   mp->tc_rate[0] = ntohl (tc_rate[0]);
4730   mp->tc_rate[1] = ntohl (tc_rate[1]);
4731   mp->tc_rate[2] = ntohl (tc_rate[2]);
4732   mp->tc_rate[3] = ntohl (tc_rate[3]);
4733   mp->tc_period = ntohl (tc_period);
4734
4735   S;
4736   W;
4737   /* NOTREACHED */
4738   return 0;
4739 }
4740
4741 static int
4742 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4743 {
4744   unformat_input_t *i = vam->input;
4745   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4746   f64 timeout;
4747   u32 sw_if_index;
4748   u8 sw_if_index_set = 0;
4749   u8 entry_set = 0;
4750   u8 tc_set = 0;
4751   u8 queue_set = 0;
4752   u32 entry, tc, queue;
4753
4754   /* Parse args required to build the message */
4755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4756     {
4757       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4758         sw_if_index_set = 1;
4759       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4760         sw_if_index_set = 1;
4761       else if (unformat (i, "entry %d", &entry))
4762         entry_set = 1;
4763       else if (unformat (i, "tc %d", &tc))
4764         tc_set = 1;
4765       else if (unformat (i, "queue %d", &queue))
4766         queue_set = 1;
4767       else
4768         break;
4769     }
4770
4771   if (sw_if_index_set == 0)
4772     {
4773       errmsg ("missing interface name or sw_if_index\n");
4774       return -99;
4775     }
4776
4777   if (entry_set == 0)
4778     {
4779       errmsg ("missing entry \n");
4780       return -99;
4781     }
4782
4783   if (tc_set == 0)
4784     {
4785       errmsg ("missing traffic class \n");
4786       return -99;
4787     }
4788
4789   if (queue_set == 0)
4790     {
4791       errmsg ("missing queue \n");
4792       return -99;
4793     }
4794
4795   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4796
4797   mp->sw_if_index = ntohl (sw_if_index);
4798   mp->entry = ntohl (entry);
4799   mp->tc = ntohl (tc);
4800   mp->queue = ntohl (queue);
4801
4802   S;
4803   W;
4804   /* NOTREACHED */
4805   return 0;
4806 }
4807
4808 static int
4809 api_sw_interface_add_del_address (vat_main_t * vam)
4810 {
4811   unformat_input_t *i = vam->input;
4812   vl_api_sw_interface_add_del_address_t *mp;
4813   f64 timeout;
4814   u32 sw_if_index;
4815   u8 sw_if_index_set = 0;
4816   u8 is_add = 1, del_all = 0;
4817   u32 address_length = 0;
4818   u8 v4_address_set = 0;
4819   u8 v6_address_set = 0;
4820   ip4_address_t v4address;
4821   ip6_address_t v6address;
4822
4823   /* Parse args required to build the message */
4824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4825     {
4826       if (unformat (i, "del-all"))
4827         del_all = 1;
4828       else if (unformat (i, "del"))
4829         is_add = 0;
4830       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4831         sw_if_index_set = 1;
4832       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4833         sw_if_index_set = 1;
4834       else if (unformat (i, "%U/%d",
4835                          unformat_ip4_address, &v4address, &address_length))
4836         v4_address_set = 1;
4837       else if (unformat (i, "%U/%d",
4838                          unformat_ip6_address, &v6address, &address_length))
4839         v6_address_set = 1;
4840       else
4841         break;
4842     }
4843
4844   if (sw_if_index_set == 0)
4845     {
4846       errmsg ("missing interface name or sw_if_index\n");
4847       return -99;
4848     }
4849   if (v4_address_set && v6_address_set)
4850     {
4851       errmsg ("both v4 and v6 addresses set\n");
4852       return -99;
4853     }
4854   if (!v4_address_set && !v6_address_set && !del_all)
4855     {
4856       errmsg ("no addresses set\n");
4857       return -99;
4858     }
4859
4860   /* Construct the API message */
4861   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4862
4863   mp->sw_if_index = ntohl (sw_if_index);
4864   mp->is_add = is_add;
4865   mp->del_all = del_all;
4866   if (v6_address_set)
4867     {
4868       mp->is_ipv6 = 1;
4869       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4870     }
4871   else
4872     {
4873       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4874     }
4875   mp->address_length = address_length;
4876
4877   /* send it... */
4878   S;
4879
4880   /* Wait for a reply, return good/bad news  */
4881   W;
4882 }
4883
4884 static int
4885 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4886 {
4887   unformat_input_t *i = vam->input;
4888   vl_api_sw_interface_set_mpls_enable_t *mp;
4889   f64 timeout;
4890   u32 sw_if_index;
4891   u8 sw_if_index_set = 0;
4892   u8 enable = 1;
4893
4894   /* Parse args required to build the message */
4895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4896     {
4897       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4898         sw_if_index_set = 1;
4899       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4900         sw_if_index_set = 1;
4901       else if (unformat (i, "disable"))
4902         enable = 0;
4903       else if (unformat (i, "dis"))
4904         enable = 0;
4905       else
4906         break;
4907     }
4908
4909   if (sw_if_index_set == 0)
4910     {
4911       errmsg ("missing interface name or sw_if_index\n");
4912       return -99;
4913     }
4914
4915   /* Construct the API message */
4916   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
4917
4918   mp->sw_if_index = ntohl (sw_if_index);
4919   mp->enable = enable;
4920
4921   /* send it... */
4922   S;
4923
4924   /* Wait for a reply... */
4925   W;
4926 }
4927
4928 static int
4929 api_sw_interface_set_table (vat_main_t * vam)
4930 {
4931   unformat_input_t *i = vam->input;
4932   vl_api_sw_interface_set_table_t *mp;
4933   f64 timeout;
4934   u32 sw_if_index, vrf_id = 0;
4935   u8 sw_if_index_set = 0;
4936   u8 is_ipv6 = 0;
4937
4938   /* Parse args required to build the message */
4939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4940     {
4941       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4942         sw_if_index_set = 1;
4943       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4944         sw_if_index_set = 1;
4945       else if (unformat (i, "vrf %d", &vrf_id))
4946         ;
4947       else if (unformat (i, "ipv6"))
4948         is_ipv6 = 1;
4949       else
4950         break;
4951     }
4952
4953   if (sw_if_index_set == 0)
4954     {
4955       errmsg ("missing interface name or sw_if_index\n");
4956       return -99;
4957     }
4958
4959   /* Construct the API message */
4960   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4961
4962   mp->sw_if_index = ntohl (sw_if_index);
4963   mp->is_ipv6 = is_ipv6;
4964   mp->vrf_id = ntohl (vrf_id);
4965
4966   /* send it... */
4967   S;
4968
4969   /* Wait for a reply... */
4970   W;
4971 }
4972
4973 static int
4974 api_sw_interface_set_vpath (vat_main_t * vam)
4975 {
4976   unformat_input_t *i = vam->input;
4977   vl_api_sw_interface_set_vpath_t *mp;
4978   f64 timeout;
4979   u32 sw_if_index = 0;
4980   u8 sw_if_index_set = 0;
4981   u8 is_enable = 0;
4982
4983   /* Parse args required to build the message */
4984   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4985     {
4986       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4987         sw_if_index_set = 1;
4988       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4989         sw_if_index_set = 1;
4990       else if (unformat (i, "enable"))
4991         is_enable = 1;
4992       else if (unformat (i, "disable"))
4993         is_enable = 0;
4994       else
4995         break;
4996     }
4997
4998   if (sw_if_index_set == 0)
4999     {
5000       errmsg ("missing interface name or sw_if_index\n");
5001       return -99;
5002     }
5003
5004   /* Construct the API message */
5005   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5006
5007   mp->sw_if_index = ntohl (sw_if_index);
5008   mp->enable = is_enable;
5009
5010   /* send it... */
5011   S;
5012
5013   /* Wait for a reply... */
5014   W;
5015 }
5016
5017 static int
5018 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5019 {
5020   unformat_input_t *i = vam->input;
5021   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5022   f64 timeout;
5023   u32 sw_if_index = 0;
5024   u8 sw_if_index_set = 0;
5025   u8 is_enable = 0;
5026   u8 is_ipv6 = 0;
5027
5028   /* Parse args required to build the message */
5029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5030     {
5031       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5032         sw_if_index_set = 1;
5033       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5034         sw_if_index_set = 1;
5035       else if (unformat (i, "enable"))
5036         is_enable = 1;
5037       else if (unformat (i, "disable"))
5038         is_enable = 0;
5039       else if (unformat (i, "ip4"))
5040         is_ipv6 = 0;
5041       else if (unformat (i, "ip6"))
5042         is_ipv6 = 1;
5043       else
5044         break;
5045     }
5046
5047   if (sw_if_index_set == 0)
5048     {
5049       errmsg ("missing interface name or sw_if_index\n");
5050       return -99;
5051     }
5052
5053   /* Construct the API message */
5054   M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5055
5056   mp->sw_if_index = ntohl (sw_if_index);
5057   mp->enable = is_enable;
5058   mp->is_ipv6 = is_ipv6;
5059
5060   /* send it... */
5061   S;
5062
5063   /* Wait for a reply... */
5064   W;
5065 }
5066
5067 static int
5068 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5069 {
5070   unformat_input_t *i = vam->input;
5071   vl_api_sw_interface_set_l2_xconnect_t *mp;
5072   f64 timeout;
5073   u32 rx_sw_if_index;
5074   u8 rx_sw_if_index_set = 0;
5075   u32 tx_sw_if_index;
5076   u8 tx_sw_if_index_set = 0;
5077   u8 enable = 1;
5078
5079   /* Parse args required to build the message */
5080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5081     {
5082       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5083         rx_sw_if_index_set = 1;
5084       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5085         tx_sw_if_index_set = 1;
5086       else if (unformat (i, "rx"))
5087         {
5088           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5089             {
5090               if (unformat (i, "%U", unformat_sw_if_index, vam,
5091                             &rx_sw_if_index))
5092                 rx_sw_if_index_set = 1;
5093             }
5094           else
5095             break;
5096         }
5097       else if (unformat (i, "tx"))
5098         {
5099           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5100             {
5101               if (unformat (i, "%U", unformat_sw_if_index, vam,
5102                             &tx_sw_if_index))
5103                 tx_sw_if_index_set = 1;
5104             }
5105           else
5106             break;
5107         }
5108       else if (unformat (i, "enable"))
5109         enable = 1;
5110       else if (unformat (i, "disable"))
5111         enable = 0;
5112       else
5113         break;
5114     }
5115
5116   if (rx_sw_if_index_set == 0)
5117     {
5118       errmsg ("missing rx interface name or rx_sw_if_index\n");
5119       return -99;
5120     }
5121
5122   if (enable && (tx_sw_if_index_set == 0))
5123     {
5124       errmsg ("missing tx interface name or tx_sw_if_index\n");
5125       return -99;
5126     }
5127
5128   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5129
5130   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5131   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5132   mp->enable = enable;
5133
5134   S;
5135   W;
5136   /* NOTREACHED */
5137   return 0;
5138 }
5139
5140 static int
5141 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5142 {
5143   unformat_input_t *i = vam->input;
5144   vl_api_sw_interface_set_l2_bridge_t *mp;
5145   f64 timeout;
5146   u32 rx_sw_if_index;
5147   u8 rx_sw_if_index_set = 0;
5148   u32 bd_id;
5149   u8 bd_id_set = 0;
5150   u8 bvi = 0;
5151   u32 shg = 0;
5152   u8 enable = 1;
5153
5154   /* Parse args required to build the message */
5155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5156     {
5157       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5158         rx_sw_if_index_set = 1;
5159       else if (unformat (i, "bd_id %d", &bd_id))
5160         bd_id_set = 1;
5161       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5162         rx_sw_if_index_set = 1;
5163       else if (unformat (i, "shg %d", &shg))
5164         ;
5165       else if (unformat (i, "bvi"))
5166         bvi = 1;
5167       else if (unformat (i, "enable"))
5168         enable = 1;
5169       else if (unformat (i, "disable"))
5170         enable = 0;
5171       else
5172         break;
5173     }
5174
5175   if (rx_sw_if_index_set == 0)
5176     {
5177       errmsg ("missing rx interface name or sw_if_index\n");
5178       return -99;
5179     }
5180
5181   if (enable && (bd_id_set == 0))
5182     {
5183       errmsg ("missing bridge domain\n");
5184       return -99;
5185     }
5186
5187   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5188
5189   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5190   mp->bd_id = ntohl (bd_id);
5191   mp->shg = (u8) shg;
5192   mp->bvi = bvi;
5193   mp->enable = enable;
5194
5195   S;
5196   W;
5197   /* NOTREACHED */
5198   return 0;
5199 }
5200
5201 static int
5202 api_bridge_domain_dump (vat_main_t * vam)
5203 {
5204   unformat_input_t *i = vam->input;
5205   vl_api_bridge_domain_dump_t *mp;
5206   f64 timeout;
5207   u32 bd_id = ~0;
5208
5209   /* Parse args required to build the message */
5210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5211     {
5212       if (unformat (i, "bd_id %d", &bd_id))
5213         ;
5214       else
5215         break;
5216     }
5217
5218   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5219   mp->bd_id = ntohl (bd_id);
5220   S;
5221
5222   /* Use a control ping for synchronization */
5223   {
5224     vl_api_control_ping_t *mp;
5225     M (CONTROL_PING, control_ping);
5226     S;
5227   }
5228
5229   W;
5230   /* NOTREACHED */
5231   return 0;
5232 }
5233
5234 static int
5235 api_bridge_domain_add_del (vat_main_t * vam)
5236 {
5237   unformat_input_t *i = vam->input;
5238   vl_api_bridge_domain_add_del_t *mp;
5239   f64 timeout;
5240   u32 bd_id = ~0;
5241   u8 is_add = 1;
5242   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5243
5244   /* Parse args required to build the message */
5245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5246     {
5247       if (unformat (i, "bd_id %d", &bd_id))
5248         ;
5249       else if (unformat (i, "flood %d", &flood))
5250         ;
5251       else if (unformat (i, "uu-flood %d", &uu_flood))
5252         ;
5253       else if (unformat (i, "forward %d", &forward))
5254         ;
5255       else if (unformat (i, "learn %d", &learn))
5256         ;
5257       else if (unformat (i, "arp-term %d", &arp_term))
5258         ;
5259       else if (unformat (i, "del"))
5260         {
5261           is_add = 0;
5262           flood = uu_flood = forward = learn = 0;
5263         }
5264       else
5265         break;
5266     }
5267
5268   if (bd_id == ~0)
5269     {
5270       errmsg ("missing bridge domain\n");
5271       return -99;
5272     }
5273
5274   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5275
5276   mp->bd_id = ntohl (bd_id);
5277   mp->flood = flood;
5278   mp->uu_flood = uu_flood;
5279   mp->forward = forward;
5280   mp->learn = learn;
5281   mp->arp_term = arp_term;
5282   mp->is_add = is_add;
5283
5284   S;
5285   W;
5286   /* NOTREACHED */
5287   return 0;
5288 }
5289
5290 static int
5291 api_l2fib_add_del (vat_main_t * vam)
5292 {
5293   unformat_input_t *i = vam->input;
5294   vl_api_l2fib_add_del_t *mp;
5295   f64 timeout;
5296   u64 mac = 0;
5297   u8 mac_set = 0;
5298   u32 bd_id;
5299   u8 bd_id_set = 0;
5300   u32 sw_if_index = ~0;
5301   u8 sw_if_index_set = 0;
5302   u8 is_add = 1;
5303   u8 static_mac = 0;
5304   u8 filter_mac = 0;
5305   u8 bvi_mac = 0;
5306   int count = 1;
5307   f64 before = 0;
5308   int j;
5309
5310   /* Parse args required to build the message */
5311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5312     {
5313       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5314         mac_set = 1;
5315       else if (unformat (i, "bd_id %d", &bd_id))
5316         bd_id_set = 1;
5317       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5318         sw_if_index_set = 1;
5319       else if (unformat (i, "sw_if"))
5320         {
5321           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5322             {
5323               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5324                 sw_if_index_set = 1;
5325             }
5326           else
5327             break;
5328         }
5329       else if (unformat (i, "static"))
5330         static_mac = 1;
5331       else if (unformat (i, "filter"))
5332         {
5333           filter_mac = 1;
5334           static_mac = 1;
5335         }
5336       else if (unformat (i, "bvi"))
5337         {
5338           bvi_mac = 1;
5339           static_mac = 1;
5340         }
5341       else if (unformat (i, "del"))
5342         is_add = 0;
5343       else if (unformat (i, "count %d", &count))
5344         ;
5345       else
5346         break;
5347     }
5348
5349   if (mac_set == 0)
5350     {
5351       errmsg ("missing mac address\n");
5352       return -99;
5353     }
5354
5355   if (bd_id_set == 0)
5356     {
5357       errmsg ("missing bridge domain\n");
5358       return -99;
5359     }
5360
5361   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5362     {
5363       errmsg ("missing interface name or sw_if_index\n");
5364       return -99;
5365     }
5366
5367   if (count > 1)
5368     {
5369       /* Turn on async mode */
5370       vam->async_mode = 1;
5371       vam->async_errors = 0;
5372       before = vat_time_now (vam);
5373     }
5374
5375   for (j = 0; j < count; j++)
5376     {
5377       M (L2FIB_ADD_DEL, l2fib_add_del);
5378
5379       mp->mac = mac;
5380       mp->bd_id = ntohl (bd_id);
5381       mp->is_add = is_add;
5382
5383       if (is_add)
5384         {
5385           mp->sw_if_index = ntohl (sw_if_index);
5386           mp->static_mac = static_mac;
5387           mp->filter_mac = filter_mac;
5388           mp->bvi_mac = bvi_mac;
5389         }
5390       increment_mac_address (&mac);
5391       /* send it... */
5392       S;
5393     }
5394
5395   if (count > 1)
5396     {
5397       vl_api_control_ping_t *mp;
5398       f64 after;
5399
5400       /* Shut off async mode */
5401       vam->async_mode = 0;
5402
5403       M (CONTROL_PING, control_ping);
5404       S;
5405
5406       timeout = vat_time_now (vam) + 1.0;
5407       while (vat_time_now (vam) < timeout)
5408         if (vam->result_ready == 1)
5409           goto out;
5410       vam->retval = -99;
5411
5412     out:
5413       if (vam->retval == -99)
5414         errmsg ("timeout\n");
5415
5416       if (vam->async_errors > 0)
5417         {
5418           errmsg ("%d asynchronous errors\n", vam->async_errors);
5419           vam->retval = -98;
5420         }
5421       vam->async_errors = 0;
5422       after = vat_time_now (vam);
5423
5424       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5425                count, after - before, count / (after - before));
5426     }
5427   else
5428     {
5429       /* Wait for a reply... */
5430       W;
5431     }
5432   /* Return the good/bad news */
5433   return (vam->retval);
5434 }
5435
5436 static int
5437 api_l2_flags (vat_main_t * vam)
5438 {
5439   unformat_input_t *i = vam->input;
5440   vl_api_l2_flags_t *mp;
5441   f64 timeout;
5442   u32 sw_if_index;
5443   u32 feature_bitmap = 0;
5444   u8 sw_if_index_set = 0;
5445
5446   /* Parse args required to build the message */
5447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5448     {
5449       if (unformat (i, "sw_if_index %d", &sw_if_index))
5450         sw_if_index_set = 1;
5451       else if (unformat (i, "sw_if"))
5452         {
5453           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5454             {
5455               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5456                 sw_if_index_set = 1;
5457             }
5458           else
5459             break;
5460         }
5461       else if (unformat (i, "learn"))
5462         feature_bitmap |= L2INPUT_FEAT_LEARN;
5463       else if (unformat (i, "forward"))
5464         feature_bitmap |= L2INPUT_FEAT_FWD;
5465       else if (unformat (i, "flood"))
5466         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5467       else if (unformat (i, "uu-flood"))
5468         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5469       else
5470         break;
5471     }
5472
5473   if (sw_if_index_set == 0)
5474     {
5475       errmsg ("missing interface name or sw_if_index\n");
5476       return -99;
5477     }
5478
5479   M (L2_FLAGS, l2_flags);
5480
5481   mp->sw_if_index = ntohl (sw_if_index);
5482   mp->feature_bitmap = ntohl (feature_bitmap);
5483
5484   S;
5485   W;
5486   /* NOTREACHED */
5487   return 0;
5488 }
5489
5490 static int
5491 api_bridge_flags (vat_main_t * vam)
5492 {
5493   unformat_input_t *i = vam->input;
5494   vl_api_bridge_flags_t *mp;
5495   f64 timeout;
5496   u32 bd_id;
5497   u8 bd_id_set = 0;
5498   u8 is_set = 1;
5499   u32 flags = 0;
5500
5501   /* Parse args required to build the message */
5502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5503     {
5504       if (unformat (i, "bd_id %d", &bd_id))
5505         bd_id_set = 1;
5506       else if (unformat (i, "learn"))
5507         flags |= L2_LEARN;
5508       else if (unformat (i, "forward"))
5509         flags |= L2_FWD;
5510       else if (unformat (i, "flood"))
5511         flags |= L2_FLOOD;
5512       else if (unformat (i, "uu-flood"))
5513         flags |= L2_UU_FLOOD;
5514       else if (unformat (i, "arp-term"))
5515         flags |= L2_ARP_TERM;
5516       else if (unformat (i, "off"))
5517         is_set = 0;
5518       else if (unformat (i, "disable"))
5519         is_set = 0;
5520       else
5521         break;
5522     }
5523
5524   if (bd_id_set == 0)
5525     {
5526       errmsg ("missing bridge domain\n");
5527       return -99;
5528     }
5529
5530   M (BRIDGE_FLAGS, bridge_flags);
5531
5532   mp->bd_id = ntohl (bd_id);
5533   mp->feature_bitmap = ntohl (flags);
5534   mp->is_set = is_set;
5535
5536   S;
5537   W;
5538   /* NOTREACHED */
5539   return 0;
5540 }
5541
5542 static int
5543 api_bd_ip_mac_add_del (vat_main_t * vam)
5544 {
5545   unformat_input_t *i = vam->input;
5546   vl_api_bd_ip_mac_add_del_t *mp;
5547   f64 timeout;
5548   u32 bd_id;
5549   u8 is_ipv6 = 0;
5550   u8 is_add = 1;
5551   u8 bd_id_set = 0;
5552   u8 ip_set = 0;
5553   u8 mac_set = 0;
5554   ip4_address_t v4addr;
5555   ip6_address_t v6addr;
5556   u8 macaddr[6];
5557
5558
5559   /* Parse args required to build the message */
5560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5561     {
5562       if (unformat (i, "bd_id %d", &bd_id))
5563         {
5564           bd_id_set++;
5565         }
5566       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5567         {
5568           ip_set++;
5569         }
5570       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5571         {
5572           ip_set++;
5573           is_ipv6++;
5574         }
5575       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5576         {
5577           mac_set++;
5578         }
5579       else if (unformat (i, "del"))
5580         is_add = 0;
5581       else
5582         break;
5583     }
5584
5585   if (bd_id_set == 0)
5586     {
5587       errmsg ("missing bridge domain\n");
5588       return -99;
5589     }
5590   else if (ip_set == 0)
5591     {
5592       errmsg ("missing IP address\n");
5593       return -99;
5594     }
5595   else if (mac_set == 0)
5596     {
5597       errmsg ("missing MAC address\n");
5598       return -99;
5599     }
5600
5601   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5602
5603   mp->bd_id = ntohl (bd_id);
5604   mp->is_ipv6 = is_ipv6;
5605   mp->is_add = is_add;
5606   if (is_ipv6)
5607     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5608   else
5609     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5610   clib_memcpy (mp->mac_address, macaddr, 6);
5611   S;
5612   W;
5613   /* NOTREACHED */
5614   return 0;
5615 }
5616
5617 static int
5618 api_tap_connect (vat_main_t * vam)
5619 {
5620   unformat_input_t *i = vam->input;
5621   vl_api_tap_connect_t *mp;
5622   f64 timeout;
5623   u8 mac_address[6];
5624   u8 random_mac = 1;
5625   u8 name_set = 0;
5626   u8 *tap_name;
5627   u8 *tag = 0;
5628
5629   memset (mac_address, 0, sizeof (mac_address));
5630
5631   /* Parse args required to build the message */
5632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5633     {
5634       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5635         {
5636           random_mac = 0;
5637         }
5638       else if (unformat (i, "random-mac"))
5639         random_mac = 1;
5640       else if (unformat (i, "tapname %s", &tap_name))
5641         name_set = 1;
5642       else if (unformat (i, "tag %s", &tag));
5643       else
5644         break;
5645     }
5646
5647   if (name_set == 0)
5648     {
5649       errmsg ("missing tap name\n");
5650       return -99;
5651     }
5652   if (vec_len (tap_name) > 63)
5653     {
5654       errmsg ("tap name too long\n");
5655       return -99;
5656     }
5657   vec_add1 (tap_name, 0);
5658
5659   if (vec_len (tag) > 63)
5660     {
5661       errmsg ("tag too long\n");
5662       return -99;
5663     }
5664   vec_add1 (tag, 0);
5665
5666   /* Construct the API message */
5667   M (TAP_CONNECT, tap_connect);
5668
5669   mp->use_random_mac = random_mac;
5670   clib_memcpy (mp->mac_address, mac_address, 6);
5671   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5672   if (tag)
5673     clib_memcpy (mp->tag, tag, vec_len (tag));
5674
5675   vec_free (tap_name);
5676   vec_free (tag);
5677
5678   /* send it... */
5679   S;
5680
5681   /* Wait for a reply... */
5682   W;
5683 }
5684
5685 static int
5686 api_tap_modify (vat_main_t * vam)
5687 {
5688   unformat_input_t *i = vam->input;
5689   vl_api_tap_modify_t *mp;
5690   f64 timeout;
5691   u8 mac_address[6];
5692   u8 random_mac = 1;
5693   u8 name_set = 0;
5694   u8 *tap_name;
5695   u32 sw_if_index = ~0;
5696   u8 sw_if_index_set = 0;
5697
5698   memset (mac_address, 0, sizeof (mac_address));
5699
5700   /* Parse args required to build the message */
5701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5702     {
5703       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5704         sw_if_index_set = 1;
5705       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5706         sw_if_index_set = 1;
5707       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5708         {
5709           random_mac = 0;
5710         }
5711       else if (unformat (i, "random-mac"))
5712         random_mac = 1;
5713       else if (unformat (i, "tapname %s", &tap_name))
5714         name_set = 1;
5715       else
5716         break;
5717     }
5718
5719   if (sw_if_index_set == 0)
5720     {
5721       errmsg ("missing vpp interface name");
5722       return -99;
5723     }
5724   if (name_set == 0)
5725     {
5726       errmsg ("missing tap name\n");
5727       return -99;
5728     }
5729   if (vec_len (tap_name) > 63)
5730     {
5731       errmsg ("tap name too long\n");
5732     }
5733   vec_add1 (tap_name, 0);
5734
5735   /* Construct the API message */
5736   M (TAP_MODIFY, tap_modify);
5737
5738   mp->use_random_mac = random_mac;
5739   mp->sw_if_index = ntohl (sw_if_index);
5740   clib_memcpy (mp->mac_address, mac_address, 6);
5741   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5742   vec_free (tap_name);
5743
5744   /* send it... */
5745   S;
5746
5747   /* Wait for a reply... */
5748   W;
5749 }
5750
5751 static int
5752 api_tap_delete (vat_main_t * vam)
5753 {
5754   unformat_input_t *i = vam->input;
5755   vl_api_tap_delete_t *mp;
5756   f64 timeout;
5757   u32 sw_if_index = ~0;
5758   u8 sw_if_index_set = 0;
5759
5760   /* Parse args required to build the message */
5761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5762     {
5763       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5764         sw_if_index_set = 1;
5765       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5766         sw_if_index_set = 1;
5767       else
5768         break;
5769     }
5770
5771   if (sw_if_index_set == 0)
5772     {
5773       errmsg ("missing vpp interface name");
5774       return -99;
5775     }
5776
5777   /* Construct the API message */
5778   M (TAP_DELETE, tap_delete);
5779
5780   mp->sw_if_index = ntohl (sw_if_index);
5781
5782   /* send it... */
5783   S;
5784
5785   /* Wait for a reply... */
5786   W;
5787 }
5788
5789 static int
5790 api_ip_add_del_route (vat_main_t * vam)
5791 {
5792   unformat_input_t *i = vam->input;
5793   vl_api_ip_add_del_route_t *mp;
5794   f64 timeout;
5795   u32 sw_if_index = ~0, vrf_id = 0;
5796   u8 is_ipv6 = 0;
5797   u8 is_local = 0, is_drop = 0;
5798   u8 is_unreach = 0, is_prohibit = 0;
5799   u8 create_vrf_if_needed = 0;
5800   u8 is_add = 1;
5801   u32 next_hop_weight = 1;
5802   u8 not_last = 0;
5803   u8 is_multipath = 0;
5804   u8 address_set = 0;
5805   u8 address_length_set = 0;
5806   u32 next_hop_table_id = 0;
5807   u32 resolve_attempts = 0;
5808   u32 dst_address_length = 0;
5809   u8 next_hop_set = 0;
5810   ip4_address_t v4_dst_address, v4_next_hop_address;
5811   ip6_address_t v6_dst_address, v6_next_hop_address;
5812   int count = 1;
5813   int j;
5814   f64 before = 0;
5815   u32 random_add_del = 0;
5816   u32 *random_vector = 0;
5817   uword *random_hash;
5818   u32 random_seed = 0xdeaddabe;
5819   u32 classify_table_index = ~0;
5820   u8 is_classify = 0;
5821   u8 resolve_host = 0, resolve_attached = 0;
5822   mpls_label_t *next_hop_out_label_stack = NULL;
5823   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5824   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
5825
5826   /* Parse args required to build the message */
5827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5828     {
5829       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5830         ;
5831       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5832         ;
5833       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5834         {
5835           address_set = 1;
5836           is_ipv6 = 0;
5837         }
5838       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5839         {
5840           address_set = 1;
5841           is_ipv6 = 1;
5842         }
5843       else if (unformat (i, "/%d", &dst_address_length))
5844         {
5845           address_length_set = 1;
5846         }
5847
5848       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5849                                          &v4_next_hop_address))
5850         {
5851           next_hop_set = 1;
5852         }
5853       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5854                                          &v6_next_hop_address))
5855         {
5856           next_hop_set = 1;
5857         }
5858       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5859         ;
5860       else if (unformat (i, "weight %d", &next_hop_weight))
5861         ;
5862       else if (unformat (i, "drop"))
5863         {
5864           is_drop = 1;
5865         }
5866       else if (unformat (i, "null-send-unreach"))
5867         {
5868           is_unreach = 1;
5869         }
5870       else if (unformat (i, "null-send-prohibit"))
5871         {
5872           is_prohibit = 1;
5873         }
5874       else if (unformat (i, "local"))
5875         {
5876           is_local = 1;
5877         }
5878       else if (unformat (i, "classify %d", &classify_table_index))
5879         {
5880           is_classify = 1;
5881         }
5882       else if (unformat (i, "del"))
5883         is_add = 0;
5884       else if (unformat (i, "add"))
5885         is_add = 1;
5886       else if (unformat (i, "not-last"))
5887         not_last = 1;
5888       else if (unformat (i, "resolve-via-host"))
5889         resolve_host = 1;
5890       else if (unformat (i, "resolve-via-attached"))
5891         resolve_attached = 1;
5892       else if (unformat (i, "multipath"))
5893         is_multipath = 1;
5894       else if (unformat (i, "vrf %d", &vrf_id))
5895         ;
5896       else if (unformat (i, "create-vrf"))
5897         create_vrf_if_needed = 1;
5898       else if (unformat (i, "count %d", &count))
5899         ;
5900       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
5901         ;
5902       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
5903         ;
5904       else if (unformat (i, "out-label %d", &next_hop_out_label))
5905         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
5906       else if (unformat (i, "via-label %d", &next_hop_via_label))
5907         ;
5908       else if (unformat (i, "random"))
5909         random_add_del = 1;
5910       else if (unformat (i, "seed %d", &random_seed))
5911         ;
5912       else
5913         {
5914           clib_warning ("parse error '%U'", format_unformat_error, i);
5915           return -99;
5916         }
5917     }
5918
5919   if (!next_hop_set && !is_drop && !is_local &&
5920       !is_classify && !is_unreach && !is_prohibit &&
5921       MPLS_LABEL_INVALID == next_hop_via_label)
5922     {
5923       errmsg
5924         ("next hop / local / drop / unreach / prohibit / classify not set\n");
5925       return -99;
5926     }
5927
5928   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
5929     {
5930       errmsg ("next hop and next-hop via label set\n");
5931       return -99;
5932     }
5933   if (address_set == 0)
5934     {
5935       errmsg ("missing addresses\n");
5936       return -99;
5937     }
5938
5939   if (address_length_set == 0)
5940     {
5941       errmsg ("missing address length\n");
5942       return -99;
5943     }
5944
5945   /* Generate a pile of unique, random routes */
5946   if (random_add_del)
5947     {
5948       u32 this_random_address;
5949       random_hash = hash_create (count, sizeof (uword));
5950
5951       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5952       for (j = 0; j <= count; j++)
5953         {
5954           do
5955             {
5956               this_random_address = random_u32 (&random_seed);
5957               this_random_address =
5958                 clib_host_to_net_u32 (this_random_address);
5959             }
5960           while (hash_get (random_hash, this_random_address));
5961           vec_add1 (random_vector, this_random_address);
5962           hash_set (random_hash, this_random_address, 1);
5963         }
5964       hash_free (random_hash);
5965       v4_dst_address.as_u32 = random_vector[0];
5966     }
5967
5968   if (count > 1)
5969     {
5970       /* Turn on async mode */
5971       vam->async_mode = 1;
5972       vam->async_errors = 0;
5973       before = vat_time_now (vam);
5974     }
5975
5976   for (j = 0; j < count; j++)
5977     {
5978       /* Construct the API message */
5979       M2 (IP_ADD_DEL_ROUTE, ip_add_del_route,
5980           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
5981
5982       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5983       mp->table_id = ntohl (vrf_id);
5984       mp->create_vrf_if_needed = create_vrf_if_needed;
5985
5986       mp->is_add = is_add;
5987       mp->is_drop = is_drop;
5988       mp->is_unreach = is_unreach;
5989       mp->is_prohibit = is_prohibit;
5990       mp->is_ipv6 = is_ipv6;
5991       mp->is_local = is_local;
5992       mp->is_classify = is_classify;
5993       mp->is_multipath = is_multipath;
5994       mp->is_resolve_host = resolve_host;
5995       mp->is_resolve_attached = resolve_attached;
5996       mp->not_last = not_last;
5997       mp->next_hop_weight = next_hop_weight;
5998       mp->dst_address_length = dst_address_length;
5999       mp->next_hop_table_id = ntohl (next_hop_table_id);
6000       mp->classify_table_index = ntohl (classify_table_index);
6001       mp->next_hop_via_label = ntohl (next_hop_via_label);
6002       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6003       if (0 != mp->next_hop_n_out_labels)
6004         {
6005           memcpy (mp->next_hop_out_label_stack,
6006                   next_hop_out_label_stack,
6007                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6008           vec_free (next_hop_out_label_stack);
6009         }
6010
6011       if (is_ipv6)
6012         {
6013           clib_memcpy (mp->dst_address, &v6_dst_address,
6014                        sizeof (v6_dst_address));
6015           if (next_hop_set)
6016             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6017                          sizeof (v6_next_hop_address));
6018           increment_v6_address (&v6_dst_address);
6019         }
6020       else
6021         {
6022           clib_memcpy (mp->dst_address, &v4_dst_address,
6023                        sizeof (v4_dst_address));
6024           if (next_hop_set)
6025             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6026                          sizeof (v4_next_hop_address));
6027           if (random_add_del)
6028             v4_dst_address.as_u32 = random_vector[j + 1];
6029           else
6030             increment_v4_address (&v4_dst_address);
6031         }
6032       /* send it... */
6033       S;
6034       /* If we receive SIGTERM, stop now... */
6035       if (vam->do_exit)
6036         break;
6037     }
6038
6039   /* When testing multiple add/del ops, use a control-ping to sync */
6040   if (count > 1)
6041     {
6042       vl_api_control_ping_t *mp;
6043       f64 after;
6044
6045       /* Shut off async mode */
6046       vam->async_mode = 0;
6047
6048       M (CONTROL_PING, control_ping);
6049       S;
6050
6051       timeout = vat_time_now (vam) + 1.0;
6052       while (vat_time_now (vam) < timeout)
6053         if (vam->result_ready == 1)
6054           goto out;
6055       vam->retval = -99;
6056
6057     out:
6058       if (vam->retval == -99)
6059         errmsg ("timeout\n");
6060
6061       if (vam->async_errors > 0)
6062         {
6063           errmsg ("%d asynchronous errors\n", vam->async_errors);
6064           vam->retval = -98;
6065         }
6066       vam->async_errors = 0;
6067       after = vat_time_now (vam);
6068
6069       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6070       if (j > 0)
6071         count = j;
6072
6073       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6074                count, after - before, count / (after - before));
6075     }
6076   else
6077     {
6078       /* Wait for a reply... */
6079       W;
6080     }
6081
6082   /* Return the good/bad news */
6083   return (vam->retval);
6084 }
6085
6086 static int
6087 api_mpls_route_add_del (vat_main_t * vam)
6088 {
6089   unformat_input_t *i = vam->input;
6090   vl_api_mpls_route_add_del_t *mp;
6091   f64 timeout;
6092   u32 sw_if_index = ~0, table_id = 0;
6093   u8 create_table_if_needed = 0;
6094   u8 is_add = 1;
6095   u32 next_hop_weight = 1;
6096   u8 is_multipath = 0;
6097   u32 next_hop_table_id = 0;
6098   u8 next_hop_set = 0;
6099   ip4_address_t v4_next_hop_address = {
6100     .as_u32 = 0,
6101   };
6102   ip6_address_t v6_next_hop_address = { {0} };
6103   int count = 1;
6104   int j;
6105   f64 before = 0;
6106   u32 classify_table_index = ~0;
6107   u8 is_classify = 0;
6108   u8 resolve_host = 0, resolve_attached = 0;
6109   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6110   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6111   mpls_label_t *next_hop_out_label_stack = NULL;
6112   mpls_label_t local_label = MPLS_LABEL_INVALID;
6113   u8 is_eos = 0;
6114   u8 next_hop_proto_is_ip4 = 1;
6115
6116   /* Parse args required to build the message */
6117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6118     {
6119       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6120         ;
6121       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6122         ;
6123       else if (unformat (i, "%d", &local_label))
6124         ;
6125       else if (unformat (i, "eos"))
6126         is_eos = 1;
6127       else if (unformat (i, "non-eos"))
6128         is_eos = 0;
6129       else if (unformat (i, "via %U", unformat_ip4_address,
6130                          &v4_next_hop_address))
6131         {
6132           next_hop_set = 1;
6133           next_hop_proto_is_ip4 = 1;
6134         }
6135       else if (unformat (i, "via %U", unformat_ip6_address,
6136                          &v6_next_hop_address))
6137         {
6138           next_hop_set = 1;
6139           next_hop_proto_is_ip4 = 0;
6140         }
6141       else if (unformat (i, "weight %d", &next_hop_weight))
6142         ;
6143       else if (unformat (i, "create-table"))
6144         create_table_if_needed = 1;
6145       else if (unformat (i, "classify %d", &classify_table_index))
6146         {
6147           is_classify = 1;
6148         }
6149       else if (unformat (i, "del"))
6150         is_add = 0;
6151       else if (unformat (i, "add"))
6152         is_add = 1;
6153       else if (unformat (i, "resolve-via-host"))
6154         resolve_host = 1;
6155       else if (unformat (i, "resolve-via-attached"))
6156         resolve_attached = 1;
6157       else if (unformat (i, "multipath"))
6158         is_multipath = 1;
6159       else if (unformat (i, "count %d", &count))
6160         ;
6161       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6162         {
6163           next_hop_set = 1;
6164           next_hop_proto_is_ip4 = 1;
6165         }
6166       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6167         {
6168           next_hop_set = 1;
6169           next_hop_proto_is_ip4 = 0;
6170         }
6171       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6172         ;
6173       else if (unformat (i, "via-label %d", &next_hop_via_label))
6174         ;
6175       else if (unformat (i, "out-label %d", &next_hop_out_label))
6176         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6177       else
6178         {
6179           clib_warning ("parse error '%U'", format_unformat_error, i);
6180           return -99;
6181         }
6182     }
6183
6184   if (!next_hop_set && !is_classify)
6185     {
6186       errmsg ("next hop / classify not set\n");
6187       return -99;
6188     }
6189
6190   if (MPLS_LABEL_INVALID == local_label)
6191     {
6192       errmsg ("missing label\n");
6193       return -99;
6194     }
6195
6196   if (count > 1)
6197     {
6198       /* Turn on async mode */
6199       vam->async_mode = 1;
6200       vam->async_errors = 0;
6201       before = vat_time_now (vam);
6202     }
6203
6204   for (j = 0; j < count; j++)
6205     {
6206       /* Construct the API message */
6207       M2 (MPLS_ROUTE_ADD_DEL, mpls_route_add_del,
6208           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6209
6210       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6211       mp->mr_table_id = ntohl (table_id);
6212       mp->mr_create_table_if_needed = create_table_if_needed;
6213
6214       mp->mr_is_add = is_add;
6215       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6216       mp->mr_is_classify = is_classify;
6217       mp->mr_is_multipath = is_multipath;
6218       mp->mr_is_resolve_host = resolve_host;
6219       mp->mr_is_resolve_attached = resolve_attached;
6220       mp->mr_next_hop_weight = next_hop_weight;
6221       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6222       mp->mr_classify_table_index = ntohl (classify_table_index);
6223       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6224       mp->mr_label = ntohl (local_label);
6225       mp->mr_eos = is_eos;
6226
6227       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6228       if (0 != mp->mr_next_hop_n_out_labels)
6229         {
6230           memcpy (mp->mr_next_hop_out_label_stack,
6231                   next_hop_out_label_stack,
6232                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6233           vec_free (next_hop_out_label_stack);
6234         }
6235
6236       if (next_hop_set)
6237         {
6238           if (next_hop_proto_is_ip4)
6239             {
6240               clib_memcpy (mp->mr_next_hop,
6241                            &v4_next_hop_address,
6242                            sizeof (v4_next_hop_address));
6243             }
6244           else
6245             {
6246               clib_memcpy (mp->mr_next_hop,
6247                            &v6_next_hop_address,
6248                            sizeof (v6_next_hop_address));
6249             }
6250         }
6251       local_label++;
6252
6253       /* send it... */
6254       S;
6255       /* If we receive SIGTERM, stop now... */
6256       if (vam->do_exit)
6257         break;
6258     }
6259
6260   /* When testing multiple add/del ops, use a control-ping to sync */
6261   if (count > 1)
6262     {
6263       vl_api_control_ping_t *mp;
6264       f64 after;
6265
6266       /* Shut off async mode */
6267       vam->async_mode = 0;
6268
6269       M (CONTROL_PING, control_ping);
6270       S;
6271
6272       timeout = vat_time_now (vam) + 1.0;
6273       while (vat_time_now (vam) < timeout)
6274         if (vam->result_ready == 1)
6275           goto out;
6276       vam->retval = -99;
6277
6278     out:
6279       if (vam->retval == -99)
6280         errmsg ("timeout\n");
6281
6282       if (vam->async_errors > 0)
6283         {
6284           errmsg ("%d asynchronous errors\n", vam->async_errors);
6285           vam->retval = -98;
6286         }
6287       vam->async_errors = 0;
6288       after = vat_time_now (vam);
6289
6290       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6291       if (j > 0)
6292         count = j;
6293
6294       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6295                count, after - before, count / (after - before));
6296     }
6297   else
6298     {
6299       /* Wait for a reply... */
6300       W;
6301     }
6302
6303   /* Return the good/bad news */
6304   return (vam->retval);
6305 }
6306
6307 static int
6308 api_mpls_ip_bind_unbind (vat_main_t * vam)
6309 {
6310   unformat_input_t *i = vam->input;
6311   vl_api_mpls_ip_bind_unbind_t *mp;
6312   f64 timeout;
6313   u32 ip_table_id = 0;
6314   u8 create_table_if_needed = 0;
6315   u8 is_bind = 1;
6316   u8 is_ip4 = 1;
6317   ip4_address_t v4_address;
6318   ip6_address_t v6_address;
6319   u32 address_length;
6320   u8 address_set = 0;
6321   mpls_label_t local_label = MPLS_LABEL_INVALID;
6322
6323   /* Parse args required to build the message */
6324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6325     {
6326       if (unformat (i, "%U/%d", unformat_ip4_address,
6327                     &v4_address, &address_length))
6328         {
6329           is_ip4 = 1;
6330           address_set = 1;
6331         }
6332       else if (unformat (i, "%U/%d", unformat_ip6_address,
6333                          &v6_address, &address_length))
6334         {
6335           is_ip4 = 0;
6336           address_set = 1;
6337         }
6338       else if (unformat (i, "%d", &local_label))
6339         ;
6340       else if (unformat (i, "create-table"))
6341         create_table_if_needed = 1;
6342       else if (unformat (i, "table-id %d", &ip_table_id))
6343         ;
6344       else if (unformat (i, "unbind"))
6345         is_bind = 0;
6346       else if (unformat (i, "bind"))
6347         is_bind = 1;
6348       else
6349         {
6350           clib_warning ("parse error '%U'", format_unformat_error, i);
6351           return -99;
6352         }
6353     }
6354
6355   if (!address_set)
6356     {
6357       errmsg ("IP addres not set\n");
6358       return -99;
6359     }
6360
6361   if (MPLS_LABEL_INVALID == local_label)
6362     {
6363       errmsg ("missing label\n");
6364       return -99;
6365     }
6366
6367   /* Construct the API message */
6368   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6369
6370   mp->mb_create_table_if_needed = create_table_if_needed;
6371   mp->mb_is_bind = is_bind;
6372   mp->mb_is_ip4 = is_ip4;
6373   mp->mb_ip_table_id = ntohl (ip_table_id);
6374   mp->mb_mpls_table_id = 0;
6375   mp->mb_label = ntohl (local_label);
6376   mp->mb_address_length = address_length;
6377
6378   if (is_ip4)
6379     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6380   else
6381     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6382
6383   /* send it... */
6384   S;
6385
6386   /* Wait for a reply... */
6387   W;
6388 }
6389
6390 static int
6391 api_proxy_arp_add_del (vat_main_t * vam)
6392 {
6393   unformat_input_t *i = vam->input;
6394   vl_api_proxy_arp_add_del_t *mp;
6395   f64 timeout;
6396   u32 vrf_id = 0;
6397   u8 is_add = 1;
6398   ip4_address_t lo, hi;
6399   u8 range_set = 0;
6400
6401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6402     {
6403       if (unformat (i, "vrf %d", &vrf_id))
6404         ;
6405       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6406                          unformat_ip4_address, &hi))
6407         range_set = 1;
6408       else if (unformat (i, "del"))
6409         is_add = 0;
6410       else
6411         {
6412           clib_warning ("parse error '%U'", format_unformat_error, i);
6413           return -99;
6414         }
6415     }
6416
6417   if (range_set == 0)
6418     {
6419       errmsg ("address range not set\n");
6420       return -99;
6421     }
6422
6423   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6424
6425   mp->vrf_id = ntohl (vrf_id);
6426   mp->is_add = is_add;
6427   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6428   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6429
6430   S;
6431   W;
6432   /* NOTREACHED */
6433   return 0;
6434 }
6435
6436 static int
6437 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6438 {
6439   unformat_input_t *i = vam->input;
6440   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6441   f64 timeout;
6442   u32 sw_if_index;
6443   u8 enable = 1;
6444   u8 sw_if_index_set = 0;
6445
6446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6447     {
6448       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6449         sw_if_index_set = 1;
6450       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6451         sw_if_index_set = 1;
6452       else if (unformat (i, "enable"))
6453         enable = 1;
6454       else if (unformat (i, "disable"))
6455         enable = 0;
6456       else
6457         {
6458           clib_warning ("parse error '%U'", format_unformat_error, i);
6459           return -99;
6460         }
6461     }
6462
6463   if (sw_if_index_set == 0)
6464     {
6465       errmsg ("missing interface name or sw_if_index\n");
6466       return -99;
6467     }
6468
6469   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6470
6471   mp->sw_if_index = ntohl (sw_if_index);
6472   mp->enable_disable = enable;
6473
6474   S;
6475   W;
6476   /* NOTREACHED */
6477   return 0;
6478 }
6479
6480 static int
6481 api_mpls_tunnel_add_del (vat_main_t * vam)
6482 {
6483   unformat_input_t *i = vam->input;
6484   vl_api_mpls_tunnel_add_del_t *mp;
6485   f64 timeout;
6486
6487   u8 is_add = 1;
6488   u8 l2_only = 0;
6489   u32 sw_if_index = ~0;
6490   u32 next_hop_sw_if_index = ~0;
6491   u32 next_hop_proto_is_ip4 = 1;
6492
6493   u32 next_hop_table_id = 0;
6494   ip4_address_t v4_next_hop_address = {
6495     .as_u32 = 0,
6496   };
6497   ip6_address_t v6_next_hop_address = { {0} };
6498   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6499
6500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6501     {
6502       if (unformat (i, "add"))
6503         is_add = 1;
6504       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6505         is_add = 0;
6506       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6507         ;
6508       else if (unformat (i, "via %U",
6509                          unformat_ip4_address, &v4_next_hop_address))
6510         {
6511           next_hop_proto_is_ip4 = 1;
6512         }
6513       else if (unformat (i, "via %U",
6514                          unformat_ip6_address, &v6_next_hop_address))
6515         {
6516           next_hop_proto_is_ip4 = 0;
6517         }
6518       else if (unformat (i, "l2-only"))
6519         l2_only = 1;
6520       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6521         ;
6522       else if (unformat (i, "out-label %d", &next_hop_out_label))
6523         vec_add1 (labels, ntohl (next_hop_out_label));
6524       else
6525         {
6526           clib_warning ("parse error '%U'", format_unformat_error, i);
6527           return -99;
6528         }
6529     }
6530
6531   M2 (MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del,
6532       sizeof (mpls_label_t) * vec_len (labels));
6533
6534   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
6535   mp->mt_sw_if_index = ntohl (sw_if_index);
6536   mp->mt_is_add = is_add;
6537   mp->mt_l2_only = l2_only;
6538   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
6539   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6540
6541   mp->mt_next_hop_n_out_labels = vec_len (labels);
6542
6543   if (0 != mp->mt_next_hop_n_out_labels)
6544     {
6545       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
6546                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
6547       vec_free (labels);
6548     }
6549
6550   if (next_hop_proto_is_ip4)
6551     {
6552       clib_memcpy (mp->mt_next_hop,
6553                    &v4_next_hop_address, sizeof (v4_next_hop_address));
6554     }
6555   else
6556     {
6557       clib_memcpy (mp->mt_next_hop,
6558                    &v6_next_hop_address, sizeof (v6_next_hop_address));
6559     }
6560
6561   S;
6562   W;
6563   /* NOTREACHED */
6564   return 0;
6565 }
6566
6567 static int
6568 api_sw_interface_set_unnumbered (vat_main_t * vam)
6569 {
6570   unformat_input_t *i = vam->input;
6571   vl_api_sw_interface_set_unnumbered_t *mp;
6572   f64 timeout;
6573   u32 sw_if_index;
6574   u32 unnum_sw_index = ~0;
6575   u8 is_add = 1;
6576   u8 sw_if_index_set = 0;
6577
6578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6579     {
6580       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6581         sw_if_index_set = 1;
6582       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6583         sw_if_index_set = 1;
6584       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6585         ;
6586       else if (unformat (i, "del"))
6587         is_add = 0;
6588       else
6589         {
6590           clib_warning ("parse error '%U'", format_unformat_error, i);
6591           return -99;
6592         }
6593     }
6594
6595   if (sw_if_index_set == 0)
6596     {
6597       errmsg ("missing interface name or sw_if_index\n");
6598       return -99;
6599     }
6600
6601   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6602
6603   mp->sw_if_index = ntohl (sw_if_index);
6604   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6605   mp->is_add = is_add;
6606
6607   S;
6608   W;
6609   /* NOTREACHED */
6610   return 0;
6611 }
6612
6613 static int
6614 api_ip_neighbor_add_del (vat_main_t * vam)
6615 {
6616   unformat_input_t *i = vam->input;
6617   vl_api_ip_neighbor_add_del_t *mp;
6618   f64 timeout;
6619   u32 sw_if_index;
6620   u8 sw_if_index_set = 0;
6621   u32 vrf_id = 0;
6622   u8 is_add = 1;
6623   u8 is_static = 0;
6624   u8 mac_address[6];
6625   u8 mac_set = 0;
6626   u8 v4_address_set = 0;
6627   u8 v6_address_set = 0;
6628   ip4_address_t v4address;
6629   ip6_address_t v6address;
6630
6631   memset (mac_address, 0, sizeof (mac_address));
6632
6633   /* Parse args required to build the message */
6634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6635     {
6636       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6637         {
6638           mac_set = 1;
6639         }
6640       else if (unformat (i, "del"))
6641         is_add = 0;
6642       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6643         sw_if_index_set = 1;
6644       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6645         sw_if_index_set = 1;
6646       else if (unformat (i, "is_static"))
6647         is_static = 1;
6648       else if (unformat (i, "vrf %d", &vrf_id))
6649         ;
6650       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6651         v4_address_set = 1;
6652       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6653         v6_address_set = 1;
6654       else
6655         {
6656           clib_warning ("parse error '%U'", format_unformat_error, i);
6657           return -99;
6658         }
6659     }
6660
6661   if (sw_if_index_set == 0)
6662     {
6663       errmsg ("missing interface name or sw_if_index\n");
6664       return -99;
6665     }
6666   if (v4_address_set && v6_address_set)
6667     {
6668       errmsg ("both v4 and v6 addresses set\n");
6669       return -99;
6670     }
6671   if (!v4_address_set && !v6_address_set)
6672     {
6673       errmsg ("no address set\n");
6674       return -99;
6675     }
6676
6677   /* Construct the API message */
6678   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6679
6680   mp->sw_if_index = ntohl (sw_if_index);
6681   mp->is_add = is_add;
6682   mp->vrf_id = ntohl (vrf_id);
6683   mp->is_static = is_static;
6684   if (mac_set)
6685     clib_memcpy (mp->mac_address, mac_address, 6);
6686   if (v6_address_set)
6687     {
6688       mp->is_ipv6 = 1;
6689       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6690     }
6691   else
6692     {
6693       /* mp->is_ipv6 = 0; via memset in M macro above */
6694       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6695     }
6696
6697   /* send it... */
6698   S;
6699
6700   /* Wait for a reply, return good/bad news  */
6701   W;
6702
6703   /* NOTREACHED */
6704   return 0;
6705 }
6706
6707 static int
6708 api_reset_vrf (vat_main_t * vam)
6709 {
6710   unformat_input_t *i = vam->input;
6711   vl_api_reset_vrf_t *mp;
6712   f64 timeout;
6713   u32 vrf_id = 0;
6714   u8 is_ipv6 = 0;
6715   u8 vrf_id_set = 0;
6716
6717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6718     {
6719       if (unformat (i, "vrf %d", &vrf_id))
6720         vrf_id_set = 1;
6721       else if (unformat (i, "ipv6"))
6722         is_ipv6 = 1;
6723       else
6724         {
6725           clib_warning ("parse error '%U'", format_unformat_error, i);
6726           return -99;
6727         }
6728     }
6729
6730   if (vrf_id_set == 0)
6731     {
6732       errmsg ("missing vrf id\n");
6733       return -99;
6734     }
6735
6736   M (RESET_VRF, reset_vrf);
6737
6738   mp->vrf_id = ntohl (vrf_id);
6739   mp->is_ipv6 = is_ipv6;
6740
6741   S;
6742   W;
6743   /* NOTREACHED */
6744   return 0;
6745 }
6746
6747 static int
6748 api_create_vlan_subif (vat_main_t * vam)
6749 {
6750   unformat_input_t *i = vam->input;
6751   vl_api_create_vlan_subif_t *mp;
6752   f64 timeout;
6753   u32 sw_if_index;
6754   u8 sw_if_index_set = 0;
6755   u32 vlan_id;
6756   u8 vlan_id_set = 0;
6757
6758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6759     {
6760       if (unformat (i, "sw_if_index %d", &sw_if_index))
6761         sw_if_index_set = 1;
6762       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6763         sw_if_index_set = 1;
6764       else if (unformat (i, "vlan %d", &vlan_id))
6765         vlan_id_set = 1;
6766       else
6767         {
6768           clib_warning ("parse error '%U'", format_unformat_error, i);
6769           return -99;
6770         }
6771     }
6772
6773   if (sw_if_index_set == 0)
6774     {
6775       errmsg ("missing interface name or sw_if_index\n");
6776       return -99;
6777     }
6778
6779   if (vlan_id_set == 0)
6780     {
6781       errmsg ("missing vlan_id\n");
6782       return -99;
6783     }
6784   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6785
6786   mp->sw_if_index = ntohl (sw_if_index);
6787   mp->vlan_id = ntohl (vlan_id);
6788
6789   S;
6790   W;
6791   /* NOTREACHED */
6792   return 0;
6793 }
6794
6795 #define foreach_create_subif_bit                \
6796 _(no_tags)                                      \
6797 _(one_tag)                                      \
6798 _(two_tags)                                     \
6799 _(dot1ad)                                       \
6800 _(exact_match)                                  \
6801 _(default_sub)                                  \
6802 _(outer_vlan_id_any)                            \
6803 _(inner_vlan_id_any)
6804
6805 static int
6806 api_create_subif (vat_main_t * vam)
6807 {
6808   unformat_input_t *i = vam->input;
6809   vl_api_create_subif_t *mp;
6810   f64 timeout;
6811   u32 sw_if_index;
6812   u8 sw_if_index_set = 0;
6813   u32 sub_id;
6814   u8 sub_id_set = 0;
6815   u32 no_tags = 0;
6816   u32 one_tag = 0;
6817   u32 two_tags = 0;
6818   u32 dot1ad = 0;
6819   u32 exact_match = 0;
6820   u32 default_sub = 0;
6821   u32 outer_vlan_id_any = 0;
6822   u32 inner_vlan_id_any = 0;
6823   u32 tmp;
6824   u16 outer_vlan_id = 0;
6825   u16 inner_vlan_id = 0;
6826
6827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6828     {
6829       if (unformat (i, "sw_if_index %d", &sw_if_index))
6830         sw_if_index_set = 1;
6831       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6832         sw_if_index_set = 1;
6833       else if (unformat (i, "sub_id %d", &sub_id))
6834         sub_id_set = 1;
6835       else if (unformat (i, "outer_vlan_id %d", &tmp))
6836         outer_vlan_id = tmp;
6837       else if (unformat (i, "inner_vlan_id %d", &tmp))
6838         inner_vlan_id = tmp;
6839
6840 #define _(a) else if (unformat (i, #a)) a = 1 ;
6841       foreach_create_subif_bit
6842 #undef _
6843         else
6844         {
6845           clib_warning ("parse error '%U'", format_unformat_error, i);
6846           return -99;
6847         }
6848     }
6849
6850   if (sw_if_index_set == 0)
6851     {
6852       errmsg ("missing interface name or sw_if_index\n");
6853       return -99;
6854     }
6855
6856   if (sub_id_set == 0)
6857     {
6858       errmsg ("missing sub_id\n");
6859       return -99;
6860     }
6861   M (CREATE_SUBIF, create_subif);
6862
6863   mp->sw_if_index = ntohl (sw_if_index);
6864   mp->sub_id = ntohl (sub_id);
6865
6866 #define _(a) mp->a = a;
6867   foreach_create_subif_bit;
6868 #undef _
6869
6870   mp->outer_vlan_id = ntohs (outer_vlan_id);
6871   mp->inner_vlan_id = ntohs (inner_vlan_id);
6872
6873   S;
6874   W;
6875   /* NOTREACHED */
6876   return 0;
6877 }
6878
6879 static int
6880 api_oam_add_del (vat_main_t * vam)
6881 {
6882   unformat_input_t *i = vam->input;
6883   vl_api_oam_add_del_t *mp;
6884   f64 timeout;
6885   u32 vrf_id = 0;
6886   u8 is_add = 1;
6887   ip4_address_t src, dst;
6888   u8 src_set = 0;
6889   u8 dst_set = 0;
6890
6891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6892     {
6893       if (unformat (i, "vrf %d", &vrf_id))
6894         ;
6895       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6896         src_set = 1;
6897       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6898         dst_set = 1;
6899       else if (unformat (i, "del"))
6900         is_add = 0;
6901       else
6902         {
6903           clib_warning ("parse error '%U'", format_unformat_error, i);
6904           return -99;
6905         }
6906     }
6907
6908   if (src_set == 0)
6909     {
6910       errmsg ("missing src addr\n");
6911       return -99;
6912     }
6913
6914   if (dst_set == 0)
6915     {
6916       errmsg ("missing dst addr\n");
6917       return -99;
6918     }
6919
6920   M (OAM_ADD_DEL, oam_add_del);
6921
6922   mp->vrf_id = ntohl (vrf_id);
6923   mp->is_add = is_add;
6924   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6925   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6926
6927   S;
6928   W;
6929   /* NOTREACHED */
6930   return 0;
6931 }
6932
6933 static int
6934 api_reset_fib (vat_main_t * vam)
6935 {
6936   unformat_input_t *i = vam->input;
6937   vl_api_reset_fib_t *mp;
6938   f64 timeout;
6939   u32 vrf_id = 0;
6940   u8 is_ipv6 = 0;
6941   u8 vrf_id_set = 0;
6942
6943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6944     {
6945       if (unformat (i, "vrf %d", &vrf_id))
6946         vrf_id_set = 1;
6947       else if (unformat (i, "ipv6"))
6948         is_ipv6 = 1;
6949       else
6950         {
6951           clib_warning ("parse error '%U'", format_unformat_error, i);
6952           return -99;
6953         }
6954     }
6955
6956   if (vrf_id_set == 0)
6957     {
6958       errmsg ("missing vrf id\n");
6959       return -99;
6960     }
6961
6962   M (RESET_FIB, reset_fib);
6963
6964   mp->vrf_id = ntohl (vrf_id);
6965   mp->is_ipv6 = is_ipv6;
6966
6967   S;
6968   W;
6969   /* NOTREACHED */
6970   return 0;
6971 }
6972
6973 static int
6974 api_dhcp_proxy_config (vat_main_t * vam)
6975 {
6976   unformat_input_t *i = vam->input;
6977   vl_api_dhcp_proxy_config_t *mp;
6978   f64 timeout;
6979   u32 vrf_id = 0;
6980   u8 is_add = 1;
6981   u8 insert_cid = 1;
6982   u8 v4_address_set = 0;
6983   u8 v6_address_set = 0;
6984   ip4_address_t v4address;
6985   ip6_address_t v6address;
6986   u8 v4_src_address_set = 0;
6987   u8 v6_src_address_set = 0;
6988   ip4_address_t v4srcaddress;
6989   ip6_address_t v6srcaddress;
6990
6991   /* Parse args required to build the message */
6992   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6993     {
6994       if (unformat (i, "del"))
6995         is_add = 0;
6996       else if (unformat (i, "vrf %d", &vrf_id))
6997         ;
6998       else if (unformat (i, "insert-cid %d", &insert_cid))
6999         ;
7000       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7001         v4_address_set = 1;
7002       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7003         v6_address_set = 1;
7004       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7005         v4_src_address_set = 1;
7006       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7007         v6_src_address_set = 1;
7008       else
7009         break;
7010     }
7011
7012   if (v4_address_set && v6_address_set)
7013     {
7014       errmsg ("both v4 and v6 server addresses set\n");
7015       return -99;
7016     }
7017   if (!v4_address_set && !v6_address_set)
7018     {
7019       errmsg ("no server addresses set\n");
7020       return -99;
7021     }
7022
7023   if (v4_src_address_set && v6_src_address_set)
7024     {
7025       errmsg ("both v4 and v6  src addresses set\n");
7026       return -99;
7027     }
7028   if (!v4_src_address_set && !v6_src_address_set)
7029     {
7030       errmsg ("no src addresses set\n");
7031       return -99;
7032     }
7033
7034   if (!(v4_src_address_set && v4_address_set) &&
7035       !(v6_src_address_set && v6_address_set))
7036     {
7037       errmsg ("no matching server and src addresses set\n");
7038       return -99;
7039     }
7040
7041   /* Construct the API message */
7042   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7043
7044   mp->insert_circuit_id = insert_cid;
7045   mp->is_add = is_add;
7046   mp->vrf_id = ntohl (vrf_id);
7047   if (v6_address_set)
7048     {
7049       mp->is_ipv6 = 1;
7050       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7051       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7052     }
7053   else
7054     {
7055       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7056       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7057     }
7058
7059   /* send it... */
7060   S;
7061
7062   /* Wait for a reply, return good/bad news  */
7063   W;
7064   /* NOTREACHED */
7065   return 0;
7066 }
7067
7068 static int
7069 api_dhcp_proxy_config_2 (vat_main_t * vam)
7070 {
7071   unformat_input_t *i = vam->input;
7072   vl_api_dhcp_proxy_config_2_t *mp;
7073   f64 timeout;
7074   u32 rx_vrf_id = 0;
7075   u32 server_vrf_id = 0;
7076   u8 is_add = 1;
7077   u8 insert_cid = 1;
7078   u8 v4_address_set = 0;
7079   u8 v6_address_set = 0;
7080   ip4_address_t v4address;
7081   ip6_address_t v6address;
7082   u8 v4_src_address_set = 0;
7083   u8 v6_src_address_set = 0;
7084   ip4_address_t v4srcaddress;
7085   ip6_address_t v6srcaddress;
7086
7087   /* Parse args required to build the message */
7088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7089     {
7090       if (unformat (i, "del"))
7091         is_add = 0;
7092       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7093         ;
7094       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7095         ;
7096       else if (unformat (i, "insert-cid %d", &insert_cid))
7097         ;
7098       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7099         v4_address_set = 1;
7100       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7101         v6_address_set = 1;
7102       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7103         v4_src_address_set = 1;
7104       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7105         v6_src_address_set = 1;
7106       else
7107         break;
7108     }
7109
7110   if (v4_address_set && v6_address_set)
7111     {
7112       errmsg ("both v4 and v6 server addresses set\n");
7113       return -99;
7114     }
7115   if (!v4_address_set && !v6_address_set)
7116     {
7117       errmsg ("no server addresses set\n");
7118       return -99;
7119     }
7120
7121   if (v4_src_address_set && v6_src_address_set)
7122     {
7123       errmsg ("both v4 and v6  src addresses set\n");
7124       return -99;
7125     }
7126   if (!v4_src_address_set && !v6_src_address_set)
7127     {
7128       errmsg ("no src addresses set\n");
7129       return -99;
7130     }
7131
7132   if (!(v4_src_address_set && v4_address_set) &&
7133       !(v6_src_address_set && v6_address_set))
7134     {
7135       errmsg ("no matching server and src addresses set\n");
7136       return -99;
7137     }
7138
7139   /* Construct the API message */
7140   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7141
7142   mp->insert_circuit_id = insert_cid;
7143   mp->is_add = is_add;
7144   mp->rx_vrf_id = ntohl (rx_vrf_id);
7145   mp->server_vrf_id = ntohl (server_vrf_id);
7146   if (v6_address_set)
7147     {
7148       mp->is_ipv6 = 1;
7149       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7150       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7151     }
7152   else
7153     {
7154       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7155       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7156     }
7157
7158   /* send it... */
7159   S;
7160
7161   /* Wait for a reply, return good/bad news  */
7162   W;
7163   /* NOTREACHED */
7164   return 0;
7165 }
7166
7167 static int
7168 api_dhcp_proxy_set_vss (vat_main_t * vam)
7169 {
7170   unformat_input_t *i = vam->input;
7171   vl_api_dhcp_proxy_set_vss_t *mp;
7172   f64 timeout;
7173   u8 is_ipv6 = 0;
7174   u8 is_add = 1;
7175   u32 tbl_id;
7176   u8 tbl_id_set = 0;
7177   u32 oui;
7178   u8 oui_set = 0;
7179   u32 fib_id;
7180   u8 fib_id_set = 0;
7181
7182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7183     {
7184       if (unformat (i, "tbl_id %d", &tbl_id))
7185         tbl_id_set = 1;
7186       if (unformat (i, "fib_id %d", &fib_id))
7187         fib_id_set = 1;
7188       if (unformat (i, "oui %d", &oui))
7189         oui_set = 1;
7190       else if (unformat (i, "ipv6"))
7191         is_ipv6 = 1;
7192       else if (unformat (i, "del"))
7193         is_add = 0;
7194       else
7195         {
7196           clib_warning ("parse error '%U'", format_unformat_error, i);
7197           return -99;
7198         }
7199     }
7200
7201   if (tbl_id_set == 0)
7202     {
7203       errmsg ("missing tbl id\n");
7204       return -99;
7205     }
7206
7207   if (fib_id_set == 0)
7208     {
7209       errmsg ("missing fib id\n");
7210       return -99;
7211     }
7212   if (oui_set == 0)
7213     {
7214       errmsg ("missing oui\n");
7215       return -99;
7216     }
7217
7218   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7219   mp->tbl_id = ntohl (tbl_id);
7220   mp->fib_id = ntohl (fib_id);
7221   mp->oui = ntohl (oui);
7222   mp->is_ipv6 = is_ipv6;
7223   mp->is_add = is_add;
7224
7225   S;
7226   W;
7227   /* NOTREACHED */
7228   return 0;
7229 }
7230
7231 static int
7232 api_dhcp_client_config (vat_main_t * vam)
7233 {
7234   unformat_input_t *i = vam->input;
7235   vl_api_dhcp_client_config_t *mp;
7236   f64 timeout;
7237   u32 sw_if_index;
7238   u8 sw_if_index_set = 0;
7239   u8 is_add = 1;
7240   u8 *hostname = 0;
7241   u8 disable_event = 0;
7242
7243   /* Parse args required to build the message */
7244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7245     {
7246       if (unformat (i, "del"))
7247         is_add = 0;
7248       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7249         sw_if_index_set = 1;
7250       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7251         sw_if_index_set = 1;
7252       else if (unformat (i, "hostname %s", &hostname))
7253         ;
7254       else if (unformat (i, "disable_event"))
7255         disable_event = 1;
7256       else
7257         break;
7258     }
7259
7260   if (sw_if_index_set == 0)
7261     {
7262       errmsg ("missing interface name or sw_if_index\n");
7263       return -99;
7264     }
7265
7266   if (vec_len (hostname) > 63)
7267     {
7268       errmsg ("hostname too long\n");
7269     }
7270   vec_add1 (hostname, 0);
7271
7272   /* Construct the API message */
7273   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7274
7275   mp->sw_if_index = ntohl (sw_if_index);
7276   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7277   vec_free (hostname);
7278   mp->is_add = is_add;
7279   mp->want_dhcp_event = disable_event ? 0 : 1;
7280   mp->pid = getpid ();
7281
7282   /* send it... */
7283   S;
7284
7285   /* Wait for a reply, return good/bad news  */
7286   W;
7287   /* NOTREACHED */
7288   return 0;
7289 }
7290
7291 static int
7292 api_set_ip_flow_hash (vat_main_t * vam)
7293 {
7294   unformat_input_t *i = vam->input;
7295   vl_api_set_ip_flow_hash_t *mp;
7296   f64 timeout;
7297   u32 vrf_id = 0;
7298   u8 is_ipv6 = 0;
7299   u8 vrf_id_set = 0;
7300   u8 src = 0;
7301   u8 dst = 0;
7302   u8 sport = 0;
7303   u8 dport = 0;
7304   u8 proto = 0;
7305   u8 reverse = 0;
7306
7307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7308     {
7309       if (unformat (i, "vrf %d", &vrf_id))
7310         vrf_id_set = 1;
7311       else if (unformat (i, "ipv6"))
7312         is_ipv6 = 1;
7313       else if (unformat (i, "src"))
7314         src = 1;
7315       else if (unformat (i, "dst"))
7316         dst = 1;
7317       else if (unformat (i, "sport"))
7318         sport = 1;
7319       else if (unformat (i, "dport"))
7320         dport = 1;
7321       else if (unformat (i, "proto"))
7322         proto = 1;
7323       else if (unformat (i, "reverse"))
7324         reverse = 1;
7325
7326       else
7327         {
7328           clib_warning ("parse error '%U'", format_unformat_error, i);
7329           return -99;
7330         }
7331     }
7332
7333   if (vrf_id_set == 0)
7334     {
7335       errmsg ("missing vrf id\n");
7336       return -99;
7337     }
7338
7339   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7340   mp->src = src;
7341   mp->dst = dst;
7342   mp->sport = sport;
7343   mp->dport = dport;
7344   mp->proto = proto;
7345   mp->reverse = reverse;
7346   mp->vrf_id = ntohl (vrf_id);
7347   mp->is_ipv6 = is_ipv6;
7348
7349   S;
7350   W;
7351   /* NOTREACHED */
7352   return 0;
7353 }
7354
7355 static int
7356 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7357 {
7358   unformat_input_t *i = vam->input;
7359   vl_api_sw_interface_ip6_enable_disable_t *mp;
7360   f64 timeout;
7361   u32 sw_if_index;
7362   u8 sw_if_index_set = 0;
7363   u8 enable = 0;
7364
7365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7366     {
7367       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7368         sw_if_index_set = 1;
7369       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7370         sw_if_index_set = 1;
7371       else if (unformat (i, "enable"))
7372         enable = 1;
7373       else if (unformat (i, "disable"))
7374         enable = 0;
7375       else
7376         {
7377           clib_warning ("parse error '%U'", format_unformat_error, i);
7378           return -99;
7379         }
7380     }
7381
7382   if (sw_if_index_set == 0)
7383     {
7384       errmsg ("missing interface name or sw_if_index\n");
7385       return -99;
7386     }
7387
7388   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7389
7390   mp->sw_if_index = ntohl (sw_if_index);
7391   mp->enable = enable;
7392
7393   S;
7394   W;
7395   /* NOTREACHED */
7396   return 0;
7397 }
7398
7399 static int
7400 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7401 {
7402   unformat_input_t *i = vam->input;
7403   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7404   f64 timeout;
7405   u32 sw_if_index;
7406   u8 sw_if_index_set = 0;
7407   u32 address_length = 0;
7408   u8 v6_address_set = 0;
7409   ip6_address_t v6address;
7410
7411   /* Parse args required to build the message */
7412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7413     {
7414       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7415         sw_if_index_set = 1;
7416       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7417         sw_if_index_set = 1;
7418       else if (unformat (i, "%U/%d",
7419                          unformat_ip6_address, &v6address, &address_length))
7420         v6_address_set = 1;
7421       else
7422         break;
7423     }
7424
7425   if (sw_if_index_set == 0)
7426     {
7427       errmsg ("missing interface name or sw_if_index\n");
7428       return -99;
7429     }
7430   if (!v6_address_set)
7431     {
7432       errmsg ("no address set\n");
7433       return -99;
7434     }
7435
7436   /* Construct the API message */
7437   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7438      sw_interface_ip6_set_link_local_address);
7439
7440   mp->sw_if_index = ntohl (sw_if_index);
7441   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7442   mp->address_length = address_length;
7443
7444   /* send it... */
7445   S;
7446
7447   /* Wait for a reply, return good/bad news  */
7448   W;
7449
7450   /* NOTREACHED */
7451   return 0;
7452 }
7453
7454
7455 static int
7456 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7457 {
7458   unformat_input_t *i = vam->input;
7459   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7460   f64 timeout;
7461   u32 sw_if_index;
7462   u8 sw_if_index_set = 0;
7463   u32 address_length = 0;
7464   u8 v6_address_set = 0;
7465   ip6_address_t v6address;
7466   u8 use_default = 0;
7467   u8 no_advertise = 0;
7468   u8 off_link = 0;
7469   u8 no_autoconfig = 0;
7470   u8 no_onlink = 0;
7471   u8 is_no = 0;
7472   u32 val_lifetime = 0;
7473   u32 pref_lifetime = 0;
7474
7475   /* Parse args required to build the message */
7476   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7477     {
7478       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7479         sw_if_index_set = 1;
7480       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7481         sw_if_index_set = 1;
7482       else if (unformat (i, "%U/%d",
7483                          unformat_ip6_address, &v6address, &address_length))
7484         v6_address_set = 1;
7485       else if (unformat (i, "val_life %d", &val_lifetime))
7486         ;
7487       else if (unformat (i, "pref_life %d", &pref_lifetime))
7488         ;
7489       else if (unformat (i, "def"))
7490         use_default = 1;
7491       else if (unformat (i, "noadv"))
7492         no_advertise = 1;
7493       else if (unformat (i, "offl"))
7494         off_link = 1;
7495       else if (unformat (i, "noauto"))
7496         no_autoconfig = 1;
7497       else if (unformat (i, "nolink"))
7498         no_onlink = 1;
7499       else if (unformat (i, "isno"))
7500         is_no = 1;
7501       else
7502         {
7503           clib_warning ("parse error '%U'", format_unformat_error, i);
7504           return -99;
7505         }
7506     }
7507
7508   if (sw_if_index_set == 0)
7509     {
7510       errmsg ("missing interface name or sw_if_index\n");
7511       return -99;
7512     }
7513   if (!v6_address_set)
7514     {
7515       errmsg ("no address set\n");
7516       return -99;
7517     }
7518
7519   /* Construct the API message */
7520   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7521
7522   mp->sw_if_index = ntohl (sw_if_index);
7523   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7524   mp->address_length = address_length;
7525   mp->use_default = use_default;
7526   mp->no_advertise = no_advertise;
7527   mp->off_link = off_link;
7528   mp->no_autoconfig = no_autoconfig;
7529   mp->no_onlink = no_onlink;
7530   mp->is_no = is_no;
7531   mp->val_lifetime = ntohl (val_lifetime);
7532   mp->pref_lifetime = ntohl (pref_lifetime);
7533
7534   /* send it... */
7535   S;
7536
7537   /* Wait for a reply, return good/bad news  */
7538   W;
7539
7540   /* NOTREACHED */
7541   return 0;
7542 }
7543
7544 static int
7545 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7546 {
7547   unformat_input_t *i = vam->input;
7548   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7549   f64 timeout;
7550   u32 sw_if_index;
7551   u8 sw_if_index_set = 0;
7552   u8 suppress = 0;
7553   u8 managed = 0;
7554   u8 other = 0;
7555   u8 ll_option = 0;
7556   u8 send_unicast = 0;
7557   u8 cease = 0;
7558   u8 is_no = 0;
7559   u8 default_router = 0;
7560   u32 max_interval = 0;
7561   u32 min_interval = 0;
7562   u32 lifetime = 0;
7563   u32 initial_count = 0;
7564   u32 initial_interval = 0;
7565
7566
7567   /* Parse args required to build the message */
7568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7569     {
7570       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7571         sw_if_index_set = 1;
7572       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7573         sw_if_index_set = 1;
7574       else if (unformat (i, "maxint %d", &max_interval))
7575         ;
7576       else if (unformat (i, "minint %d", &min_interval))
7577         ;
7578       else if (unformat (i, "life %d", &lifetime))
7579         ;
7580       else if (unformat (i, "count %d", &initial_count))
7581         ;
7582       else if (unformat (i, "interval %d", &initial_interval))
7583         ;
7584       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7585         suppress = 1;
7586       else if (unformat (i, "managed"))
7587         managed = 1;
7588       else if (unformat (i, "other"))
7589         other = 1;
7590       else if (unformat (i, "ll"))
7591         ll_option = 1;
7592       else if (unformat (i, "send"))
7593         send_unicast = 1;
7594       else if (unformat (i, "cease"))
7595         cease = 1;
7596       else if (unformat (i, "isno"))
7597         is_no = 1;
7598       else if (unformat (i, "def"))
7599         default_router = 1;
7600       else
7601         {
7602           clib_warning ("parse error '%U'", format_unformat_error, i);
7603           return -99;
7604         }
7605     }
7606
7607   if (sw_if_index_set == 0)
7608     {
7609       errmsg ("missing interface name or sw_if_index\n");
7610       return -99;
7611     }
7612
7613   /* Construct the API message */
7614   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7615
7616   mp->sw_if_index = ntohl (sw_if_index);
7617   mp->max_interval = ntohl (max_interval);
7618   mp->min_interval = ntohl (min_interval);
7619   mp->lifetime = ntohl (lifetime);
7620   mp->initial_count = ntohl (initial_count);
7621   mp->initial_interval = ntohl (initial_interval);
7622   mp->suppress = suppress;
7623   mp->managed = managed;
7624   mp->other = other;
7625   mp->ll_option = ll_option;
7626   mp->send_unicast = send_unicast;
7627   mp->cease = cease;
7628   mp->is_no = is_no;
7629   mp->default_router = default_router;
7630
7631   /* send it... */
7632   S;
7633
7634   /* Wait for a reply, return good/bad news  */
7635   W;
7636
7637   /* NOTREACHED */
7638   return 0;
7639 }
7640
7641 static int
7642 api_set_arp_neighbor_limit (vat_main_t * vam)
7643 {
7644   unformat_input_t *i = vam->input;
7645   vl_api_set_arp_neighbor_limit_t *mp;
7646   f64 timeout;
7647   u32 arp_nbr_limit;
7648   u8 limit_set = 0;
7649   u8 is_ipv6 = 0;
7650
7651   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7652     {
7653       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7654         limit_set = 1;
7655       else if (unformat (i, "ipv6"))
7656         is_ipv6 = 1;
7657       else
7658         {
7659           clib_warning ("parse error '%U'", format_unformat_error, i);
7660           return -99;
7661         }
7662     }
7663
7664   if (limit_set == 0)
7665     {
7666       errmsg ("missing limit value\n");
7667       return -99;
7668     }
7669
7670   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7671
7672   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7673   mp->is_ipv6 = is_ipv6;
7674
7675   S;
7676   W;
7677   /* NOTREACHED */
7678   return 0;
7679 }
7680
7681 static int
7682 api_l2_patch_add_del (vat_main_t * vam)
7683 {
7684   unformat_input_t *i = vam->input;
7685   vl_api_l2_patch_add_del_t *mp;
7686   f64 timeout;
7687   u32 rx_sw_if_index;
7688   u8 rx_sw_if_index_set = 0;
7689   u32 tx_sw_if_index;
7690   u8 tx_sw_if_index_set = 0;
7691   u8 is_add = 1;
7692
7693   /* Parse args required to build the message */
7694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7695     {
7696       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7697         rx_sw_if_index_set = 1;
7698       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7699         tx_sw_if_index_set = 1;
7700       else if (unformat (i, "rx"))
7701         {
7702           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7703             {
7704               if (unformat (i, "%U", unformat_sw_if_index, vam,
7705                             &rx_sw_if_index))
7706                 rx_sw_if_index_set = 1;
7707             }
7708           else
7709             break;
7710         }
7711       else if (unformat (i, "tx"))
7712         {
7713           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7714             {
7715               if (unformat (i, "%U", unformat_sw_if_index, vam,
7716                             &tx_sw_if_index))
7717                 tx_sw_if_index_set = 1;
7718             }
7719           else
7720             break;
7721         }
7722       else if (unformat (i, "del"))
7723         is_add = 0;
7724       else
7725         break;
7726     }
7727
7728   if (rx_sw_if_index_set == 0)
7729     {
7730       errmsg ("missing rx interface name or rx_sw_if_index\n");
7731       return -99;
7732     }
7733
7734   if (tx_sw_if_index_set == 0)
7735     {
7736       errmsg ("missing tx interface name or tx_sw_if_index\n");
7737       return -99;
7738     }
7739
7740   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7741
7742   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7743   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7744   mp->is_add = is_add;
7745
7746   S;
7747   W;
7748   /* NOTREACHED */
7749   return 0;
7750 }
7751
7752 static int
7753 api_ioam_enable (vat_main_t * vam)
7754 {
7755   unformat_input_t *input = vam->input;
7756   vl_api_ioam_enable_t *mp;
7757   f64 timeout;
7758   u32 id = 0;
7759   int has_trace_option = 0;
7760   int has_pot_option = 0;
7761   int has_seqno_option = 0;
7762   int has_analyse_option = 0;
7763
7764   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7765     {
7766       if (unformat (input, "trace"))
7767         has_trace_option = 1;
7768       else if (unformat (input, "pot"))
7769         has_pot_option = 1;
7770       else if (unformat (input, "seqno"))
7771         has_seqno_option = 1;
7772       else if (unformat (input, "analyse"))
7773         has_analyse_option = 1;
7774       else
7775         break;
7776     }
7777   M (IOAM_ENABLE, ioam_enable);
7778   mp->id = htons (id);
7779   mp->seqno = has_seqno_option;
7780   mp->analyse = has_analyse_option;
7781   mp->pot_enable = has_pot_option;
7782   mp->trace_enable = has_trace_option;
7783
7784   S;
7785   W;
7786
7787   return (0);
7788
7789 }
7790
7791
7792 static int
7793 api_ioam_disable (vat_main_t * vam)
7794 {
7795   vl_api_ioam_disable_t *mp;
7796   f64 timeout;
7797
7798   M (IOAM_DISABLE, ioam_disable);
7799   S;
7800   W;
7801   return 0;
7802 }
7803
7804 static int
7805 api_sr_tunnel_add_del (vat_main_t * vam)
7806 {
7807   unformat_input_t *i = vam->input;
7808   vl_api_sr_tunnel_add_del_t *mp;
7809   f64 timeout;
7810   int is_del = 0;
7811   int pl_index;
7812   ip6_address_t src_address;
7813   int src_address_set = 0;
7814   ip6_address_t dst_address;
7815   u32 dst_mask_width;
7816   int dst_address_set = 0;
7817   u16 flags = 0;
7818   u32 rx_table_id = 0;
7819   u32 tx_table_id = 0;
7820   ip6_address_t *segments = 0;
7821   ip6_address_t *this_seg;
7822   ip6_address_t *tags = 0;
7823   ip6_address_t *this_tag;
7824   ip6_address_t next_address, tag;
7825   u8 *name = 0;
7826   u8 *policy_name = 0;
7827
7828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7829     {
7830       if (unformat (i, "del"))
7831         is_del = 1;
7832       else if (unformat (i, "name %s", &name))
7833         ;
7834       else if (unformat (i, "policy %s", &policy_name))
7835         ;
7836       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7837         ;
7838       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7839         ;
7840       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7841         src_address_set = 1;
7842       else if (unformat (i, "dst %U/%d",
7843                          unformat_ip6_address, &dst_address, &dst_mask_width))
7844         dst_address_set = 1;
7845       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7846         {
7847           vec_add2 (segments, this_seg, 1);
7848           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7849                        sizeof (*this_seg));
7850         }
7851       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7852         {
7853           vec_add2 (tags, this_tag, 1);
7854           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7855         }
7856       else if (unformat (i, "clean"))
7857         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7858       else if (unformat (i, "protected"))
7859         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7860       else if (unformat (i, "InPE %d", &pl_index))
7861         {
7862           if (pl_index <= 0 || pl_index > 4)
7863             {
7864             pl_index_range_error:
7865               errmsg ("pl index %d out of range\n", pl_index);
7866               return -99;
7867             }
7868           flags |=
7869             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7870         }
7871       else if (unformat (i, "EgPE %d", &pl_index))
7872         {
7873           if (pl_index <= 0 || pl_index > 4)
7874             goto pl_index_range_error;
7875           flags |=
7876             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7877         }
7878       else if (unformat (i, "OrgSrc %d", &pl_index))
7879         {
7880           if (pl_index <= 0 || pl_index > 4)
7881             goto pl_index_range_error;
7882           flags |=
7883             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7884         }
7885       else
7886         break;
7887     }
7888
7889   if (!src_address_set)
7890     {
7891       errmsg ("src address required\n");
7892       return -99;
7893     }
7894
7895   if (!dst_address_set)
7896     {
7897       errmsg ("dst address required\n");
7898       return -99;
7899     }
7900
7901   if (!segments)
7902     {
7903       errmsg ("at least one sr segment required\n");
7904       return -99;
7905     }
7906
7907   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7908       vec_len (segments) * sizeof (ip6_address_t)
7909       + vec_len (tags) * sizeof (ip6_address_t));
7910
7911   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7912   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7913   mp->dst_mask_width = dst_mask_width;
7914   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7915   mp->n_segments = vec_len (segments);
7916   mp->n_tags = vec_len (tags);
7917   mp->is_add = is_del == 0;
7918   clib_memcpy (mp->segs_and_tags, segments,
7919                vec_len (segments) * sizeof (ip6_address_t));
7920   clib_memcpy (mp->segs_and_tags +
7921                vec_len (segments) * sizeof (ip6_address_t), tags,
7922                vec_len (tags) * sizeof (ip6_address_t));
7923
7924   mp->outer_vrf_id = ntohl (rx_table_id);
7925   mp->inner_vrf_id = ntohl (tx_table_id);
7926   memcpy (mp->name, name, vec_len (name));
7927   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7928
7929   vec_free (segments);
7930   vec_free (tags);
7931
7932   S;
7933   W;
7934   /* NOTREACHED */
7935 }
7936
7937 static int
7938 api_sr_policy_add_del (vat_main_t * vam)
7939 {
7940   unformat_input_t *input = vam->input;
7941   vl_api_sr_policy_add_del_t *mp;
7942   f64 timeout;
7943   int is_del = 0;
7944   u8 *name = 0;
7945   u8 *tunnel_name = 0;
7946   u8 **tunnel_names = 0;
7947
7948   int name_set = 0;
7949   int tunnel_set = 0;
7950   int j = 0;
7951   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7952   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7953
7954   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7955     {
7956       if (unformat (input, "del"))
7957         is_del = 1;
7958       else if (unformat (input, "name %s", &name))
7959         name_set = 1;
7960       else if (unformat (input, "tunnel %s", &tunnel_name))
7961         {
7962           if (tunnel_name)
7963             {
7964               vec_add1 (tunnel_names, tunnel_name);
7965               /* For serializer:
7966                  - length = #bytes to store in serial vector
7967                  - +1 = byte to store that length
7968                */
7969               tunnel_names_length += (vec_len (tunnel_name) + 1);
7970               tunnel_set = 1;
7971               tunnel_name = 0;
7972             }
7973         }
7974       else
7975         break;
7976     }
7977
7978   if (!name_set)
7979     {
7980       errmsg ("policy name required\n");
7981       return -99;
7982     }
7983
7984   if ((!tunnel_set) && (!is_del))
7985     {
7986       errmsg ("tunnel name required\n");
7987       return -99;
7988     }
7989
7990   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
7991
7992
7993
7994   mp->is_add = !is_del;
7995
7996   memcpy (mp->name, name, vec_len (name));
7997   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
7998   u8 *serial_orig = 0;
7999   vec_validate (serial_orig, tunnel_names_length);
8000   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8001   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8002
8003   for (j = 0; j < vec_len (tunnel_names); j++)
8004     {
8005       tun_name_len = vec_len (tunnel_names[j]);
8006       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8007       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8008       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8009       serial_orig += tun_name_len;      // Advance past the copy
8010     }
8011   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8012
8013   vec_free (tunnel_names);
8014   vec_free (tunnel_name);
8015
8016   S;
8017   W;
8018   /* NOTREACHED */
8019 }
8020
8021 static int
8022 api_sr_multicast_map_add_del (vat_main_t * vam)
8023 {
8024   unformat_input_t *input = vam->input;
8025   vl_api_sr_multicast_map_add_del_t *mp;
8026   f64 timeout;
8027   int is_del = 0;
8028   ip6_address_t multicast_address;
8029   u8 *policy_name = 0;
8030   int multicast_address_set = 0;
8031
8032   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8033     {
8034       if (unformat (input, "del"))
8035         is_del = 1;
8036       else
8037         if (unformat
8038             (input, "address %U", unformat_ip6_address, &multicast_address))
8039         multicast_address_set = 1;
8040       else if (unformat (input, "sr-policy %s", &policy_name))
8041         ;
8042       else
8043         break;
8044     }
8045
8046   if (!is_del && !policy_name)
8047     {
8048       errmsg ("sr-policy name required\n");
8049       return -99;
8050     }
8051
8052
8053   if (!multicast_address_set)
8054     {
8055       errmsg ("address required\n");
8056       return -99;
8057     }
8058
8059   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8060
8061   mp->is_add = !is_del;
8062   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8063   clib_memcpy (mp->multicast_address, &multicast_address,
8064                sizeof (mp->multicast_address));
8065
8066
8067   vec_free (policy_name);
8068
8069   S;
8070   W;
8071   /* NOTREACHED */
8072 }
8073
8074
8075 #define foreach_tcp_proto_field                 \
8076 _(src_port)                                     \
8077 _(dst_port)
8078
8079 #define foreach_udp_proto_field                 \
8080 _(src_port)                                     \
8081 _(dst_port)
8082
8083 #define foreach_ip4_proto_field                 \
8084 _(src_address)                                  \
8085 _(dst_address)                                  \
8086 _(tos)                                          \
8087 _(length)                                       \
8088 _(fragment_id)                                  \
8089 _(ttl)                                          \
8090 _(protocol)                                     \
8091 _(checksum)
8092
8093 uword
8094 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8095 {
8096   u8 **maskp = va_arg (*args, u8 **);
8097   u8 *mask = 0;
8098   u8 found_something = 0;
8099   tcp_header_t *tcp;
8100
8101 #define _(a) u8 a=0;
8102   foreach_tcp_proto_field;
8103 #undef _
8104
8105   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8106     {
8107       if (0);
8108 #define _(a) else if (unformat (input, #a)) a=1;
8109       foreach_tcp_proto_field
8110 #undef _
8111         else
8112         break;
8113     }
8114
8115 #define _(a) found_something += a;
8116   foreach_tcp_proto_field;
8117 #undef _
8118
8119   if (found_something == 0)
8120     return 0;
8121
8122   vec_validate (mask, sizeof (*tcp) - 1);
8123
8124   tcp = (tcp_header_t *) mask;
8125
8126 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8127   foreach_tcp_proto_field;
8128 #undef _
8129
8130   *maskp = mask;
8131   return 1;
8132 }
8133
8134 uword
8135 unformat_udp_mask (unformat_input_t * input, va_list * args)
8136 {
8137   u8 **maskp = va_arg (*args, u8 **);
8138   u8 *mask = 0;
8139   u8 found_something = 0;
8140   udp_header_t *udp;
8141
8142 #define _(a) u8 a=0;
8143   foreach_udp_proto_field;
8144 #undef _
8145
8146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8147     {
8148       if (0);
8149 #define _(a) else if (unformat (input, #a)) a=1;
8150       foreach_udp_proto_field
8151 #undef _
8152         else
8153         break;
8154     }
8155
8156 #define _(a) found_something += a;
8157   foreach_udp_proto_field;
8158 #undef _
8159
8160   if (found_something == 0)
8161     return 0;
8162
8163   vec_validate (mask, sizeof (*udp) - 1);
8164
8165   udp = (udp_header_t *) mask;
8166
8167 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8168   foreach_udp_proto_field;
8169 #undef _
8170
8171   *maskp = mask;
8172   return 1;
8173 }
8174
8175 typedef struct
8176 {
8177   u16 src_port, dst_port;
8178 } tcpudp_header_t;
8179
8180 uword
8181 unformat_l4_mask (unformat_input_t * input, va_list * args)
8182 {
8183   u8 **maskp = va_arg (*args, u8 **);
8184   u16 src_port = 0, dst_port = 0;
8185   tcpudp_header_t *tcpudp;
8186
8187   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8188     {
8189       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8190         return 1;
8191       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8192         return 1;
8193       else if (unformat (input, "src_port"))
8194         src_port = 0xFFFF;
8195       else if (unformat (input, "dst_port"))
8196         dst_port = 0xFFFF;
8197       else
8198         return 0;
8199     }
8200
8201   if (!src_port && !dst_port)
8202     return 0;
8203
8204   u8 *mask = 0;
8205   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8206
8207   tcpudp = (tcpudp_header_t *) mask;
8208   tcpudp->src_port = src_port;
8209   tcpudp->dst_port = dst_port;
8210
8211   *maskp = mask;
8212
8213   return 1;
8214 }
8215
8216 uword
8217 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8218 {
8219   u8 **maskp = va_arg (*args, u8 **);
8220   u8 *mask = 0;
8221   u8 found_something = 0;
8222   ip4_header_t *ip;
8223
8224 #define _(a) u8 a=0;
8225   foreach_ip4_proto_field;
8226 #undef _
8227   u8 version = 0;
8228   u8 hdr_length = 0;
8229
8230
8231   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8232     {
8233       if (unformat (input, "version"))
8234         version = 1;
8235       else if (unformat (input, "hdr_length"))
8236         hdr_length = 1;
8237       else if (unformat (input, "src"))
8238         src_address = 1;
8239       else if (unformat (input, "dst"))
8240         dst_address = 1;
8241       else if (unformat (input, "proto"))
8242         protocol = 1;
8243
8244 #define _(a) else if (unformat (input, #a)) a=1;
8245       foreach_ip4_proto_field
8246 #undef _
8247         else
8248         break;
8249     }
8250
8251 #define _(a) found_something += a;
8252   foreach_ip4_proto_field;
8253 #undef _
8254
8255   if (found_something == 0)
8256     return 0;
8257
8258   vec_validate (mask, sizeof (*ip) - 1);
8259
8260   ip = (ip4_header_t *) mask;
8261
8262 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8263   foreach_ip4_proto_field;
8264 #undef _
8265
8266   ip->ip_version_and_header_length = 0;
8267
8268   if (version)
8269     ip->ip_version_and_header_length |= 0xF0;
8270
8271   if (hdr_length)
8272     ip->ip_version_and_header_length |= 0x0F;
8273
8274   *maskp = mask;
8275   return 1;
8276 }
8277
8278 #define foreach_ip6_proto_field                 \
8279 _(src_address)                                  \
8280 _(dst_address)                                  \
8281 _(payload_length)                               \
8282 _(hop_limit)                                    \
8283 _(protocol)
8284
8285 uword
8286 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8287 {
8288   u8 **maskp = va_arg (*args, u8 **);
8289   u8 *mask = 0;
8290   u8 found_something = 0;
8291   ip6_header_t *ip;
8292   u32 ip_version_traffic_class_and_flow_label;
8293
8294 #define _(a) u8 a=0;
8295   foreach_ip6_proto_field;
8296 #undef _
8297   u8 version = 0;
8298   u8 traffic_class = 0;
8299   u8 flow_label = 0;
8300
8301   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8302     {
8303       if (unformat (input, "version"))
8304         version = 1;
8305       else if (unformat (input, "traffic-class"))
8306         traffic_class = 1;
8307       else if (unformat (input, "flow-label"))
8308         flow_label = 1;
8309       else if (unformat (input, "src"))
8310         src_address = 1;
8311       else if (unformat (input, "dst"))
8312         dst_address = 1;
8313       else if (unformat (input, "proto"))
8314         protocol = 1;
8315
8316 #define _(a) else if (unformat (input, #a)) a=1;
8317       foreach_ip6_proto_field
8318 #undef _
8319         else
8320         break;
8321     }
8322
8323 #define _(a) found_something += a;
8324   foreach_ip6_proto_field;
8325 #undef _
8326
8327   if (found_something == 0)
8328     return 0;
8329
8330   vec_validate (mask, sizeof (*ip) - 1);
8331
8332   ip = (ip6_header_t *) mask;
8333
8334 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8335   foreach_ip6_proto_field;
8336 #undef _
8337
8338   ip_version_traffic_class_and_flow_label = 0;
8339
8340   if (version)
8341     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8342
8343   if (traffic_class)
8344     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8345
8346   if (flow_label)
8347     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8348
8349   ip->ip_version_traffic_class_and_flow_label =
8350     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8351
8352   *maskp = mask;
8353   return 1;
8354 }
8355
8356 uword
8357 unformat_l3_mask (unformat_input_t * input, va_list * args)
8358 {
8359   u8 **maskp = va_arg (*args, u8 **);
8360
8361   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8362     {
8363       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8364         return 1;
8365       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8366         return 1;
8367       else
8368         break;
8369     }
8370   return 0;
8371 }
8372
8373 uword
8374 unformat_l2_mask (unformat_input_t * input, va_list * args)
8375 {
8376   u8 **maskp = va_arg (*args, u8 **);
8377   u8 *mask = 0;
8378   u8 src = 0;
8379   u8 dst = 0;
8380   u8 proto = 0;
8381   u8 tag1 = 0;
8382   u8 tag2 = 0;
8383   u8 ignore_tag1 = 0;
8384   u8 ignore_tag2 = 0;
8385   u8 cos1 = 0;
8386   u8 cos2 = 0;
8387   u8 dot1q = 0;
8388   u8 dot1ad = 0;
8389   int len = 14;
8390
8391   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8392     {
8393       if (unformat (input, "src"))
8394         src = 1;
8395       else if (unformat (input, "dst"))
8396         dst = 1;
8397       else if (unformat (input, "proto"))
8398         proto = 1;
8399       else if (unformat (input, "tag1"))
8400         tag1 = 1;
8401       else if (unformat (input, "tag2"))
8402         tag2 = 1;
8403       else if (unformat (input, "ignore-tag1"))
8404         ignore_tag1 = 1;
8405       else if (unformat (input, "ignore-tag2"))
8406         ignore_tag2 = 1;
8407       else if (unformat (input, "cos1"))
8408         cos1 = 1;
8409       else if (unformat (input, "cos2"))
8410         cos2 = 1;
8411       else if (unformat (input, "dot1q"))
8412         dot1q = 1;
8413       else if (unformat (input, "dot1ad"))
8414         dot1ad = 1;
8415       else
8416         break;
8417     }
8418   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8419        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8420     return 0;
8421
8422   if (tag1 || ignore_tag1 || cos1 || dot1q)
8423     len = 18;
8424   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8425     len = 22;
8426
8427   vec_validate (mask, len - 1);
8428
8429   if (dst)
8430     memset (mask, 0xff, 6);
8431
8432   if (src)
8433     memset (mask + 6, 0xff, 6);
8434
8435   if (tag2 || dot1ad)
8436     {
8437       /* inner vlan tag */
8438       if (tag2)
8439         {
8440           mask[19] = 0xff;
8441           mask[18] = 0x0f;
8442         }
8443       if (cos2)
8444         mask[18] |= 0xe0;
8445       if (proto)
8446         mask[21] = mask[20] = 0xff;
8447       if (tag1)
8448         {
8449           mask[15] = 0xff;
8450           mask[14] = 0x0f;
8451         }
8452       if (cos1)
8453         mask[14] |= 0xe0;
8454       *maskp = mask;
8455       return 1;
8456     }
8457   if (tag1 | dot1q)
8458     {
8459       if (tag1)
8460         {
8461           mask[15] = 0xff;
8462           mask[14] = 0x0f;
8463         }
8464       if (cos1)
8465         mask[14] |= 0xe0;
8466       if (proto)
8467         mask[16] = mask[17] = 0xff;
8468
8469       *maskp = mask;
8470       return 1;
8471     }
8472   if (cos2)
8473     mask[18] |= 0xe0;
8474   if (cos1)
8475     mask[14] |= 0xe0;
8476   if (proto)
8477     mask[12] = mask[13] = 0xff;
8478
8479   *maskp = mask;
8480   return 1;
8481 }
8482
8483 uword
8484 unformat_classify_mask (unformat_input_t * input, va_list * args)
8485 {
8486   u8 **maskp = va_arg (*args, u8 **);
8487   u32 *skipp = va_arg (*args, u32 *);
8488   u32 *matchp = va_arg (*args, u32 *);
8489   u32 match;
8490   u8 *mask = 0;
8491   u8 *l2 = 0;
8492   u8 *l3 = 0;
8493   u8 *l4 = 0;
8494   int i;
8495
8496   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8497     {
8498       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8499         ;
8500       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8501         ;
8502       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8503         ;
8504       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8505         ;
8506       else
8507         break;
8508     }
8509
8510   if (l4 && !l3)
8511     {
8512       vec_free (mask);
8513       vec_free (l2);
8514       vec_free (l4);
8515       return 0;
8516     }
8517
8518   if (mask || l2 || l3 || l4)
8519     {
8520       if (l2 || l3 || l4)
8521         {
8522           /* "With a free Ethernet header in every package" */
8523           if (l2 == 0)
8524             vec_validate (l2, 13);
8525           mask = l2;
8526           if (vec_len (l3))
8527             {
8528               vec_append (mask, l3);
8529               vec_free (l3);
8530             }
8531           if (vec_len (l4))
8532             {
8533               vec_append (mask, l4);
8534               vec_free (l4);
8535             }
8536         }
8537
8538       /* Scan forward looking for the first significant mask octet */
8539       for (i = 0; i < vec_len (mask); i++)
8540         if (mask[i])
8541           break;
8542
8543       /* compute (skip, match) params */
8544       *skipp = i / sizeof (u32x4);
8545       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8546
8547       /* Pad mask to an even multiple of the vector size */
8548       while (vec_len (mask) % sizeof (u32x4))
8549         vec_add1 (mask, 0);
8550
8551       match = vec_len (mask) / sizeof (u32x4);
8552
8553       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8554         {
8555           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8556           if (*tmp || *(tmp + 1))
8557             break;
8558           match--;
8559         }
8560       if (match == 0)
8561         clib_warning ("BUG: match 0");
8562
8563       _vec_len (mask) = match * sizeof (u32x4);
8564
8565       *matchp = match;
8566       *maskp = mask;
8567
8568       return 1;
8569     }
8570
8571   return 0;
8572 }
8573
8574 #define foreach_l2_next                         \
8575 _(drop, DROP)                                   \
8576 _(ethernet, ETHERNET_INPUT)                     \
8577 _(ip4, IP4_INPUT)                               \
8578 _(ip6, IP6_INPUT)
8579
8580 uword
8581 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8582 {
8583   u32 *miss_next_indexp = va_arg (*args, u32 *);
8584   u32 next_index = 0;
8585   u32 tmp;
8586
8587 #define _(n,N) \
8588   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8589   foreach_l2_next;
8590 #undef _
8591
8592   if (unformat (input, "%d", &tmp))
8593     {
8594       next_index = tmp;
8595       goto out;
8596     }
8597
8598   return 0;
8599
8600 out:
8601   *miss_next_indexp = next_index;
8602   return 1;
8603 }
8604
8605 #define foreach_ip_next                         \
8606 _(drop, DROP)                                   \
8607 _(local, LOCAL)                                 \
8608 _(rewrite, REWRITE)
8609
8610 uword
8611 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8612 {
8613   u32 *miss_next_indexp = va_arg (*args, u32 *);
8614   u32 next_index = 0;
8615   u32 tmp;
8616
8617 #define _(n,N) \
8618   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8619   foreach_ip_next;
8620 #undef _
8621
8622   if (unformat (input, "%d", &tmp))
8623     {
8624       next_index = tmp;
8625       goto out;
8626     }
8627
8628   return 0;
8629
8630 out:
8631   *miss_next_indexp = next_index;
8632   return 1;
8633 }
8634
8635 #define foreach_acl_next                        \
8636 _(deny, DENY)
8637
8638 uword
8639 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8640 {
8641   u32 *miss_next_indexp = va_arg (*args, u32 *);
8642   u32 next_index = 0;
8643   u32 tmp;
8644
8645 #define _(n,N) \
8646   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8647   foreach_acl_next;
8648 #undef _
8649
8650   if (unformat (input, "permit"))
8651     {
8652       next_index = ~0;
8653       goto out;
8654     }
8655   else if (unformat (input, "%d", &tmp))
8656     {
8657       next_index = tmp;
8658       goto out;
8659     }
8660
8661   return 0;
8662
8663 out:
8664   *miss_next_indexp = next_index;
8665   return 1;
8666 }
8667
8668 uword
8669 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8670 {
8671   u32 *r = va_arg (*args, u32 *);
8672
8673   if (unformat (input, "conform-color"))
8674     *r = POLICE_CONFORM;
8675   else if (unformat (input, "exceed-color"))
8676     *r = POLICE_EXCEED;
8677   else
8678     return 0;
8679
8680   return 1;
8681 }
8682
8683 static int
8684 api_classify_add_del_table (vat_main_t * vam)
8685 {
8686   unformat_input_t *i = vam->input;
8687   vl_api_classify_add_del_table_t *mp;
8688
8689   u32 nbuckets = 2;
8690   u32 skip = ~0;
8691   u32 match = ~0;
8692   int is_add = 1;
8693   u32 table_index = ~0;
8694   u32 next_table_index = ~0;
8695   u32 miss_next_index = ~0;
8696   u32 memory_size = 32 << 20;
8697   u8 *mask = 0;
8698   f64 timeout;
8699   u32 current_data_flag = 0;
8700   int current_data_offset = 0;
8701
8702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8703     {
8704       if (unformat (i, "del"))
8705         is_add = 0;
8706       else if (unformat (i, "buckets %d", &nbuckets))
8707         ;
8708       else if (unformat (i, "memory_size %d", &memory_size))
8709         ;
8710       else if (unformat (i, "skip %d", &skip))
8711         ;
8712       else if (unformat (i, "match %d", &match))
8713         ;
8714       else if (unformat (i, "table %d", &table_index))
8715         ;
8716       else if (unformat (i, "mask %U", unformat_classify_mask,
8717                          &mask, &skip, &match))
8718         ;
8719       else if (unformat (i, "next-table %d", &next_table_index))
8720         ;
8721       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8722                          &miss_next_index))
8723         ;
8724       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8725                          &miss_next_index))
8726         ;
8727       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8728                          &miss_next_index))
8729         ;
8730       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8731         ;
8732       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8733         ;
8734       else
8735         break;
8736     }
8737
8738   if (is_add && mask == 0)
8739     {
8740       errmsg ("Mask required\n");
8741       return -99;
8742     }
8743
8744   if (is_add && skip == ~0)
8745     {
8746       errmsg ("skip count required\n");
8747       return -99;
8748     }
8749
8750   if (is_add && match == ~0)
8751     {
8752       errmsg ("match count required\n");
8753       return -99;
8754     }
8755
8756   if (!is_add && table_index == ~0)
8757     {
8758       errmsg ("table index required for delete\n");
8759       return -99;
8760     }
8761
8762   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8763
8764   mp->is_add = is_add;
8765   mp->table_index = ntohl (table_index);
8766   mp->nbuckets = ntohl (nbuckets);
8767   mp->memory_size = ntohl (memory_size);
8768   mp->skip_n_vectors = ntohl (skip);
8769   mp->match_n_vectors = ntohl (match);
8770   mp->next_table_index = ntohl (next_table_index);
8771   mp->miss_next_index = ntohl (miss_next_index);
8772   mp->current_data_flag = ntohl (current_data_flag);
8773   mp->current_data_offset = ntohl (current_data_offset);
8774   clib_memcpy (mp->mask, mask, vec_len (mask));
8775
8776   vec_free (mask);
8777
8778   S;
8779   W;
8780   /* NOTREACHED */
8781 }
8782
8783 uword
8784 unformat_l4_match (unformat_input_t * input, va_list * args)
8785 {
8786   u8 **matchp = va_arg (*args, u8 **);
8787
8788   u8 *proto_header = 0;
8789   int src_port = 0;
8790   int dst_port = 0;
8791
8792   tcpudp_header_t h;
8793
8794   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8795     {
8796       if (unformat (input, "src_port %d", &src_port))
8797         ;
8798       else if (unformat (input, "dst_port %d", &dst_port))
8799         ;
8800       else
8801         return 0;
8802     }
8803
8804   h.src_port = clib_host_to_net_u16 (src_port);
8805   h.dst_port = clib_host_to_net_u16 (dst_port);
8806   vec_validate (proto_header, sizeof (h) - 1);
8807   memcpy (proto_header, &h, sizeof (h));
8808
8809   *matchp = proto_header;
8810
8811   return 1;
8812 }
8813
8814 uword
8815 unformat_ip4_match (unformat_input_t * input, va_list * args)
8816 {
8817   u8 **matchp = va_arg (*args, u8 **);
8818   u8 *match = 0;
8819   ip4_header_t *ip;
8820   int version = 0;
8821   u32 version_val;
8822   int hdr_length = 0;
8823   u32 hdr_length_val;
8824   int src = 0, dst = 0;
8825   ip4_address_t src_val, dst_val;
8826   int proto = 0;
8827   u32 proto_val;
8828   int tos = 0;
8829   u32 tos_val;
8830   int length = 0;
8831   u32 length_val;
8832   int fragment_id = 0;
8833   u32 fragment_id_val;
8834   int ttl = 0;
8835   int ttl_val;
8836   int checksum = 0;
8837   u32 checksum_val;
8838
8839   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8840     {
8841       if (unformat (input, "version %d", &version_val))
8842         version = 1;
8843       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8844         hdr_length = 1;
8845       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8846         src = 1;
8847       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8848         dst = 1;
8849       else if (unformat (input, "proto %d", &proto_val))
8850         proto = 1;
8851       else if (unformat (input, "tos %d", &tos_val))
8852         tos = 1;
8853       else if (unformat (input, "length %d", &length_val))
8854         length = 1;
8855       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8856         fragment_id = 1;
8857       else if (unformat (input, "ttl %d", &ttl_val))
8858         ttl = 1;
8859       else if (unformat (input, "checksum %d", &checksum_val))
8860         checksum = 1;
8861       else
8862         break;
8863     }
8864
8865   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8866       + ttl + checksum == 0)
8867     return 0;
8868
8869   /*
8870    * Aligned because we use the real comparison functions
8871    */
8872   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8873
8874   ip = (ip4_header_t *) match;
8875
8876   /* These are realistically matched in practice */
8877   if (src)
8878     ip->src_address.as_u32 = src_val.as_u32;
8879
8880   if (dst)
8881     ip->dst_address.as_u32 = dst_val.as_u32;
8882
8883   if (proto)
8884     ip->protocol = proto_val;
8885
8886
8887   /* These are not, but they're included for completeness */
8888   if (version)
8889     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8890
8891   if (hdr_length)
8892     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8893
8894   if (tos)
8895     ip->tos = tos_val;
8896
8897   if (length)
8898     ip->length = clib_host_to_net_u16 (length_val);
8899
8900   if (ttl)
8901     ip->ttl = ttl_val;
8902
8903   if (checksum)
8904     ip->checksum = clib_host_to_net_u16 (checksum_val);
8905
8906   *matchp = match;
8907   return 1;
8908 }
8909
8910 uword
8911 unformat_ip6_match (unformat_input_t * input, va_list * args)
8912 {
8913   u8 **matchp = va_arg (*args, u8 **);
8914   u8 *match = 0;
8915   ip6_header_t *ip;
8916   int version = 0;
8917   u32 version_val;
8918   u8 traffic_class = 0;
8919   u32 traffic_class_val = 0;
8920   u8 flow_label = 0;
8921   u8 flow_label_val;
8922   int src = 0, dst = 0;
8923   ip6_address_t src_val, dst_val;
8924   int proto = 0;
8925   u32 proto_val;
8926   int payload_length = 0;
8927   u32 payload_length_val;
8928   int hop_limit = 0;
8929   int hop_limit_val;
8930   u32 ip_version_traffic_class_and_flow_label;
8931
8932   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8933     {
8934       if (unformat (input, "version %d", &version_val))
8935         version = 1;
8936       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8937         traffic_class = 1;
8938       else if (unformat (input, "flow_label %d", &flow_label_val))
8939         flow_label = 1;
8940       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8941         src = 1;
8942       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8943         dst = 1;
8944       else if (unformat (input, "proto %d", &proto_val))
8945         proto = 1;
8946       else if (unformat (input, "payload_length %d", &payload_length_val))
8947         payload_length = 1;
8948       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8949         hop_limit = 1;
8950       else
8951         break;
8952     }
8953
8954   if (version + traffic_class + flow_label + src + dst + proto +
8955       payload_length + hop_limit == 0)
8956     return 0;
8957
8958   /*
8959    * Aligned because we use the real comparison functions
8960    */
8961   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8962
8963   ip = (ip6_header_t *) match;
8964
8965   if (src)
8966     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8967
8968   if (dst)
8969     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8970
8971   if (proto)
8972     ip->protocol = proto_val;
8973
8974   ip_version_traffic_class_and_flow_label = 0;
8975
8976   if (version)
8977     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8978
8979   if (traffic_class)
8980     ip_version_traffic_class_and_flow_label |=
8981       (traffic_class_val & 0xFF) << 20;
8982
8983   if (flow_label)
8984     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8985
8986   ip->ip_version_traffic_class_and_flow_label =
8987     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8988
8989   if (payload_length)
8990     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8991
8992   if (hop_limit)
8993     ip->hop_limit = hop_limit_val;
8994
8995   *matchp = match;
8996   return 1;
8997 }
8998
8999 uword
9000 unformat_l3_match (unformat_input_t * input, va_list * args)
9001 {
9002   u8 **matchp = va_arg (*args, u8 **);
9003
9004   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9005     {
9006       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9007         return 1;
9008       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9009         return 1;
9010       else
9011         break;
9012     }
9013   return 0;
9014 }
9015
9016 uword
9017 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9018 {
9019   u8 *tagp = va_arg (*args, u8 *);
9020   u32 tag;
9021
9022   if (unformat (input, "%d", &tag))
9023     {
9024       tagp[0] = (tag >> 8) & 0x0F;
9025       tagp[1] = tag & 0xFF;
9026       return 1;
9027     }
9028
9029   return 0;
9030 }
9031
9032 uword
9033 unformat_l2_match (unformat_input_t * input, va_list * args)
9034 {
9035   u8 **matchp = va_arg (*args, u8 **);
9036   u8 *match = 0;
9037   u8 src = 0;
9038   u8 src_val[6];
9039   u8 dst = 0;
9040   u8 dst_val[6];
9041   u8 proto = 0;
9042   u16 proto_val;
9043   u8 tag1 = 0;
9044   u8 tag1_val[2];
9045   u8 tag2 = 0;
9046   u8 tag2_val[2];
9047   int len = 14;
9048   u8 ignore_tag1 = 0;
9049   u8 ignore_tag2 = 0;
9050   u8 cos1 = 0;
9051   u8 cos2 = 0;
9052   u32 cos1_val = 0;
9053   u32 cos2_val = 0;
9054
9055   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9056     {
9057       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9058         src = 1;
9059       else
9060         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9061         dst = 1;
9062       else if (unformat (input, "proto %U",
9063                          unformat_ethernet_type_host_byte_order, &proto_val))
9064         proto = 1;
9065       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9066         tag1 = 1;
9067       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9068         tag2 = 1;
9069       else if (unformat (input, "ignore-tag1"))
9070         ignore_tag1 = 1;
9071       else if (unformat (input, "ignore-tag2"))
9072         ignore_tag2 = 1;
9073       else if (unformat (input, "cos1 %d", &cos1_val))
9074         cos1 = 1;
9075       else if (unformat (input, "cos2 %d", &cos2_val))
9076         cos2 = 1;
9077       else
9078         break;
9079     }
9080   if ((src + dst + proto + tag1 + tag2 +
9081        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9082     return 0;
9083
9084   if (tag1 || ignore_tag1 || cos1)
9085     len = 18;
9086   if (tag2 || ignore_tag2 || cos2)
9087     len = 22;
9088
9089   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9090
9091   if (dst)
9092     clib_memcpy (match, dst_val, 6);
9093
9094   if (src)
9095     clib_memcpy (match + 6, src_val, 6);
9096
9097   if (tag2)
9098     {
9099       /* inner vlan tag */
9100       match[19] = tag2_val[1];
9101       match[18] = tag2_val[0];
9102       if (cos2)
9103         match[18] |= (cos2_val & 0x7) << 5;
9104       if (proto)
9105         {
9106           match[21] = proto_val & 0xff;
9107           match[20] = proto_val >> 8;
9108         }
9109       if (tag1)
9110         {
9111           match[15] = tag1_val[1];
9112           match[14] = tag1_val[0];
9113         }
9114       if (cos1)
9115         match[14] |= (cos1_val & 0x7) << 5;
9116       *matchp = match;
9117       return 1;
9118     }
9119   if (tag1)
9120     {
9121       match[15] = tag1_val[1];
9122       match[14] = tag1_val[0];
9123       if (proto)
9124         {
9125           match[17] = proto_val & 0xff;
9126           match[16] = proto_val >> 8;
9127         }
9128       if (cos1)
9129         match[14] |= (cos1_val & 0x7) << 5;
9130
9131       *matchp = match;
9132       return 1;
9133     }
9134   if (cos2)
9135     match[18] |= (cos2_val & 0x7) << 5;
9136   if (cos1)
9137     match[14] |= (cos1_val & 0x7) << 5;
9138   if (proto)
9139     {
9140       match[13] = proto_val & 0xff;
9141       match[12] = proto_val >> 8;
9142     }
9143
9144   *matchp = match;
9145   return 1;
9146 }
9147
9148
9149 uword
9150 unformat_classify_match (unformat_input_t * input, va_list * args)
9151 {
9152   u8 **matchp = va_arg (*args, u8 **);
9153   u32 skip_n_vectors = va_arg (*args, u32);
9154   u32 match_n_vectors = va_arg (*args, u32);
9155
9156   u8 *match = 0;
9157   u8 *l2 = 0;
9158   u8 *l3 = 0;
9159   u8 *l4 = 0;
9160
9161   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9162     {
9163       if (unformat (input, "hex %U", unformat_hex_string, &match))
9164         ;
9165       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9166         ;
9167       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9168         ;
9169       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9170         ;
9171       else
9172         break;
9173     }
9174
9175   if (l4 && !l3)
9176     {
9177       vec_free (match);
9178       vec_free (l2);
9179       vec_free (l4);
9180       return 0;
9181     }
9182
9183   if (match || l2 || l3 || l4)
9184     {
9185       if (l2 || l3 || l4)
9186         {
9187           /* "Win a free Ethernet header in every packet" */
9188           if (l2 == 0)
9189             vec_validate_aligned (l2, 13, sizeof (u32x4));
9190           match = l2;
9191           if (vec_len (l3))
9192             {
9193               vec_append_aligned (match, l3, sizeof (u32x4));
9194               vec_free (l3);
9195             }
9196           if (vec_len (l4))
9197             {
9198               vec_append_aligned (match, l4, sizeof (u32x4));
9199               vec_free (l4);
9200             }
9201         }
9202
9203       /* Make sure the vector is big enough even if key is all 0's */
9204       vec_validate_aligned
9205         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9206          sizeof (u32x4));
9207
9208       /* Set size, include skipped vectors */
9209       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9210
9211       *matchp = match;
9212
9213       return 1;
9214     }
9215
9216   return 0;
9217 }
9218
9219 static int
9220 api_classify_add_del_session (vat_main_t * vam)
9221 {
9222   unformat_input_t *i = vam->input;
9223   vl_api_classify_add_del_session_t *mp;
9224   int is_add = 1;
9225   u32 table_index = ~0;
9226   u32 hit_next_index = ~0;
9227   u32 opaque_index = ~0;
9228   u8 *match = 0;
9229   i32 advance = 0;
9230   f64 timeout;
9231   u32 skip_n_vectors = 0;
9232   u32 match_n_vectors = 0;
9233   u32 action = 0;
9234   u32 metadata = 0;
9235
9236   /*
9237    * Warning: you have to supply skip_n and match_n
9238    * because the API client cant simply look at the classify
9239    * table object.
9240    */
9241
9242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9243     {
9244       if (unformat (i, "del"))
9245         is_add = 0;
9246       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9247                          &hit_next_index))
9248         ;
9249       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9250                          &hit_next_index))
9251         ;
9252       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9253                          &hit_next_index))
9254         ;
9255       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9256         ;
9257       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9258         ;
9259       else if (unformat (i, "opaque-index %d", &opaque_index))
9260         ;
9261       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9262         ;
9263       else if (unformat (i, "match_n %d", &match_n_vectors))
9264         ;
9265       else if (unformat (i, "match %U", unformat_classify_match,
9266                          &match, skip_n_vectors, match_n_vectors))
9267         ;
9268       else if (unformat (i, "advance %d", &advance))
9269         ;
9270       else if (unformat (i, "table-index %d", &table_index))
9271         ;
9272       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9273         action = 1;
9274       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9275         action = 2;
9276       else if (unformat (i, "action %d", &action))
9277         ;
9278       else if (unformat (i, "metadata %d", &metadata))
9279         ;
9280       else
9281         break;
9282     }
9283
9284   if (table_index == ~0)
9285     {
9286       errmsg ("Table index required\n");
9287       return -99;
9288     }
9289
9290   if (is_add && match == 0)
9291     {
9292       errmsg ("Match value required\n");
9293       return -99;
9294     }
9295
9296   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9297
9298   mp->is_add = is_add;
9299   mp->table_index = ntohl (table_index);
9300   mp->hit_next_index = ntohl (hit_next_index);
9301   mp->opaque_index = ntohl (opaque_index);
9302   mp->advance = ntohl (advance);
9303   mp->action = action;
9304   mp->metadata = ntohl (metadata);
9305   clib_memcpy (mp->match, match, vec_len (match));
9306   vec_free (match);
9307
9308   S;
9309   W;
9310   /* NOTREACHED */
9311 }
9312
9313 static int
9314 api_classify_set_interface_ip_table (vat_main_t * vam)
9315 {
9316   unformat_input_t *i = vam->input;
9317   vl_api_classify_set_interface_ip_table_t *mp;
9318   f64 timeout;
9319   u32 sw_if_index;
9320   int sw_if_index_set;
9321   u32 table_index = ~0;
9322   u8 is_ipv6 = 0;
9323
9324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9325     {
9326       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9327         sw_if_index_set = 1;
9328       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9329         sw_if_index_set = 1;
9330       else if (unformat (i, "table %d", &table_index))
9331         ;
9332       else
9333         {
9334           clib_warning ("parse error '%U'", format_unformat_error, i);
9335           return -99;
9336         }
9337     }
9338
9339   if (sw_if_index_set == 0)
9340     {
9341       errmsg ("missing interface name or sw_if_index\n");
9342       return -99;
9343     }
9344
9345
9346   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9347
9348   mp->sw_if_index = ntohl (sw_if_index);
9349   mp->table_index = ntohl (table_index);
9350   mp->is_ipv6 = is_ipv6;
9351
9352   S;
9353   W;
9354   /* NOTREACHED */
9355   return 0;
9356 }
9357
9358 static int
9359 api_classify_set_interface_l2_tables (vat_main_t * vam)
9360 {
9361   unformat_input_t *i = vam->input;
9362   vl_api_classify_set_interface_l2_tables_t *mp;
9363   f64 timeout;
9364   u32 sw_if_index;
9365   int sw_if_index_set;
9366   u32 ip4_table_index = ~0;
9367   u32 ip6_table_index = ~0;
9368   u32 other_table_index = ~0;
9369   u32 is_input = 1;
9370
9371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9372     {
9373       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9374         sw_if_index_set = 1;
9375       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9376         sw_if_index_set = 1;
9377       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9378         ;
9379       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9380         ;
9381       else if (unformat (i, "other-table %d", &other_table_index))
9382         ;
9383       else if (unformat (i, "is-input %d", &is_input))
9384         ;
9385       else
9386         {
9387           clib_warning ("parse error '%U'", format_unformat_error, i);
9388           return -99;
9389         }
9390     }
9391
9392   if (sw_if_index_set == 0)
9393     {
9394       errmsg ("missing interface name or sw_if_index\n");
9395       return -99;
9396     }
9397
9398
9399   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9400
9401   mp->sw_if_index = ntohl (sw_if_index);
9402   mp->ip4_table_index = ntohl (ip4_table_index);
9403   mp->ip6_table_index = ntohl (ip6_table_index);
9404   mp->other_table_index = ntohl (other_table_index);
9405   mp->is_input = (u8) is_input;
9406
9407   S;
9408   W;
9409   /* NOTREACHED */
9410   return 0;
9411 }
9412
9413 static int
9414 api_set_ipfix_exporter (vat_main_t * vam)
9415 {
9416   unformat_input_t *i = vam->input;
9417   vl_api_set_ipfix_exporter_t *mp;
9418   ip4_address_t collector_address;
9419   u8 collector_address_set = 0;
9420   u32 collector_port = ~0;
9421   ip4_address_t src_address;
9422   u8 src_address_set = 0;
9423   u32 vrf_id = ~0;
9424   u32 path_mtu = ~0;
9425   u32 template_interval = ~0;
9426   u8 udp_checksum = 0;
9427   f64 timeout;
9428
9429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9430     {
9431       if (unformat (i, "collector_address %U", unformat_ip4_address,
9432                     &collector_address))
9433         collector_address_set = 1;
9434       else if (unformat (i, "collector_port %d", &collector_port))
9435         ;
9436       else if (unformat (i, "src_address %U", unformat_ip4_address,
9437                          &src_address))
9438         src_address_set = 1;
9439       else if (unformat (i, "vrf_id %d", &vrf_id))
9440         ;
9441       else if (unformat (i, "path_mtu %d", &path_mtu))
9442         ;
9443       else if (unformat (i, "template_interval %d", &template_interval))
9444         ;
9445       else if (unformat (i, "udp_checksum"))
9446         udp_checksum = 1;
9447       else
9448         break;
9449     }
9450
9451   if (collector_address_set == 0)
9452     {
9453       errmsg ("collector_address required\n");
9454       return -99;
9455     }
9456
9457   if (src_address_set == 0)
9458     {
9459       errmsg ("src_address required\n");
9460       return -99;
9461     }
9462
9463   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9464
9465   memcpy (mp->collector_address, collector_address.data,
9466           sizeof (collector_address.data));
9467   mp->collector_port = htons ((u16) collector_port);
9468   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9469   mp->vrf_id = htonl (vrf_id);
9470   mp->path_mtu = htonl (path_mtu);
9471   mp->template_interval = htonl (template_interval);
9472   mp->udp_checksum = udp_checksum;
9473
9474   S;
9475   W;
9476   /* NOTREACHED */
9477 }
9478
9479 static int
9480 api_set_ipfix_classify_stream (vat_main_t * vam)
9481 {
9482   unformat_input_t *i = vam->input;
9483   vl_api_set_ipfix_classify_stream_t *mp;
9484   u32 domain_id = 0;
9485   u32 src_port = UDP_DST_PORT_ipfix;
9486   f64 timeout;
9487
9488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9489     {
9490       if (unformat (i, "domain %d", &domain_id))
9491         ;
9492       else if (unformat (i, "src_port %d", &src_port))
9493         ;
9494       else
9495         {
9496           errmsg ("unknown input `%U'", format_unformat_error, i);
9497           return -99;
9498         }
9499     }
9500
9501   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9502
9503   mp->domain_id = htonl (domain_id);
9504   mp->src_port = htons ((u16) src_port);
9505
9506   S;
9507   W;
9508   /* NOTREACHED */
9509 }
9510
9511 static int
9512 api_ipfix_classify_table_add_del (vat_main_t * vam)
9513 {
9514   unformat_input_t *i = vam->input;
9515   vl_api_ipfix_classify_table_add_del_t *mp;
9516   int is_add = -1;
9517   u32 classify_table_index = ~0;
9518   u8 ip_version = 0;
9519   u8 transport_protocol = 255;
9520   f64 timeout;
9521
9522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9523     {
9524       if (unformat (i, "add"))
9525         is_add = 1;
9526       else if (unformat (i, "del"))
9527         is_add = 0;
9528       else if (unformat (i, "table %d", &classify_table_index))
9529         ;
9530       else if (unformat (i, "ip4"))
9531         ip_version = 4;
9532       else if (unformat (i, "ip6"))
9533         ip_version = 6;
9534       else if (unformat (i, "tcp"))
9535         transport_protocol = 6;
9536       else if (unformat (i, "udp"))
9537         transport_protocol = 17;
9538       else
9539         {
9540           errmsg ("unknown input `%U'", format_unformat_error, i);
9541           return -99;
9542         }
9543     }
9544
9545   if (is_add == -1)
9546     {
9547       errmsg ("expecting: add|del");
9548       return -99;
9549     }
9550   if (classify_table_index == ~0)
9551     {
9552       errmsg ("classifier table not specified");
9553       return -99;
9554     }
9555   if (ip_version == 0)
9556     {
9557       errmsg ("IP version not specified");
9558       return -99;
9559     }
9560
9561   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9562
9563   mp->is_add = is_add;
9564   mp->table_id = htonl (classify_table_index);
9565   mp->ip_version = ip_version;
9566   mp->transport_protocol = transport_protocol;
9567
9568   S;
9569   W;
9570   /* NOTREACHED */
9571 }
9572
9573 static int
9574 api_get_node_index (vat_main_t * vam)
9575 {
9576   unformat_input_t *i = vam->input;
9577   vl_api_get_node_index_t *mp;
9578   f64 timeout;
9579   u8 *name = 0;
9580
9581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9582     {
9583       if (unformat (i, "node %s", &name))
9584         ;
9585       else
9586         break;
9587     }
9588   if (name == 0)
9589     {
9590       errmsg ("node name required\n");
9591       return -99;
9592     }
9593   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9594     {
9595       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9596       return -99;
9597     }
9598
9599   M (GET_NODE_INDEX, get_node_index);
9600   clib_memcpy (mp->node_name, name, vec_len (name));
9601   vec_free (name);
9602
9603   S;
9604   W;
9605   /* NOTREACHED */
9606   return 0;
9607 }
9608
9609 static int
9610 api_get_next_index (vat_main_t * vam)
9611 {
9612   unformat_input_t *i = vam->input;
9613   vl_api_get_next_index_t *mp;
9614   f64 timeout;
9615   u8 *node_name = 0, *next_node_name = 0;
9616
9617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9618     {
9619       if (unformat (i, "node-name %s", &node_name))
9620         ;
9621       else if (unformat (i, "next-node-name %s", &next_node_name))
9622         break;
9623     }
9624
9625   if (node_name == 0)
9626     {
9627       errmsg ("node name required\n");
9628       return -99;
9629     }
9630   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9631     {
9632       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9633       return -99;
9634     }
9635
9636   if (next_node_name == 0)
9637     {
9638       errmsg ("next node name required\n");
9639       return -99;
9640     }
9641   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9642     {
9643       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9644       return -99;
9645     }
9646
9647   M (GET_NEXT_INDEX, get_next_index);
9648   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9649   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9650   vec_free (node_name);
9651   vec_free (next_node_name);
9652
9653   S;
9654   W;
9655   /* NOTREACHED */
9656   return 0;
9657 }
9658
9659 static int
9660 api_add_node_next (vat_main_t * vam)
9661 {
9662   unformat_input_t *i = vam->input;
9663   vl_api_add_node_next_t *mp;
9664   f64 timeout;
9665   u8 *name = 0;
9666   u8 *next = 0;
9667
9668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9669     {
9670       if (unformat (i, "node %s", &name))
9671         ;
9672       else if (unformat (i, "next %s", &next))
9673         ;
9674       else
9675         break;
9676     }
9677   if (name == 0)
9678     {
9679       errmsg ("node name required\n");
9680       return -99;
9681     }
9682   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9683     {
9684       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9685       return -99;
9686     }
9687   if (next == 0)
9688     {
9689       errmsg ("next node required\n");
9690       return -99;
9691     }
9692   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9693     {
9694       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9695       return -99;
9696     }
9697
9698   M (ADD_NODE_NEXT, add_node_next);
9699   clib_memcpy (mp->node_name, name, vec_len (name));
9700   clib_memcpy (mp->next_name, next, vec_len (next));
9701   vec_free (name);
9702   vec_free (next);
9703
9704   S;
9705   W;
9706   /* NOTREACHED */
9707   return 0;
9708 }
9709
9710 static int
9711 api_l2tpv3_create_tunnel (vat_main_t * vam)
9712 {
9713   unformat_input_t *i = vam->input;
9714   ip6_address_t client_address, our_address;
9715   int client_address_set = 0;
9716   int our_address_set = 0;
9717   u32 local_session_id = 0;
9718   u32 remote_session_id = 0;
9719   u64 local_cookie = 0;
9720   u64 remote_cookie = 0;
9721   u8 l2_sublayer_present = 0;
9722   vl_api_l2tpv3_create_tunnel_t *mp;
9723   f64 timeout;
9724
9725   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9726     {
9727       if (unformat (i, "client_address %U", unformat_ip6_address,
9728                     &client_address))
9729         client_address_set = 1;
9730       else if (unformat (i, "our_address %U", unformat_ip6_address,
9731                          &our_address))
9732         our_address_set = 1;
9733       else if (unformat (i, "local_session_id %d", &local_session_id))
9734         ;
9735       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9736         ;
9737       else if (unformat (i, "local_cookie %lld", &local_cookie))
9738         ;
9739       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9740         ;
9741       else if (unformat (i, "l2-sublayer-present"))
9742         l2_sublayer_present = 1;
9743       else
9744         break;
9745     }
9746
9747   if (client_address_set == 0)
9748     {
9749       errmsg ("client_address required\n");
9750       return -99;
9751     }
9752
9753   if (our_address_set == 0)
9754     {
9755       errmsg ("our_address required\n");
9756       return -99;
9757     }
9758
9759   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9760
9761   clib_memcpy (mp->client_address, client_address.as_u8,
9762                sizeof (mp->client_address));
9763
9764   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9765
9766   mp->local_session_id = ntohl (local_session_id);
9767   mp->remote_session_id = ntohl (remote_session_id);
9768   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9769   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9770   mp->l2_sublayer_present = l2_sublayer_present;
9771   mp->is_ipv6 = 1;
9772
9773   S;
9774   W;
9775   /* NOTREACHED */
9776   return 0;
9777 }
9778
9779 static int
9780 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9781 {
9782   unformat_input_t *i = vam->input;
9783   u32 sw_if_index;
9784   u8 sw_if_index_set = 0;
9785   u64 new_local_cookie = 0;
9786   u64 new_remote_cookie = 0;
9787   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9788   f64 timeout;
9789
9790   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9791     {
9792       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9793         sw_if_index_set = 1;
9794       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9795         sw_if_index_set = 1;
9796       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9797         ;
9798       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9799         ;
9800       else
9801         break;
9802     }
9803
9804   if (sw_if_index_set == 0)
9805     {
9806       errmsg ("missing interface name or sw_if_index\n");
9807       return -99;
9808     }
9809
9810   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9811
9812   mp->sw_if_index = ntohl (sw_if_index);
9813   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9814   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9815
9816   S;
9817   W;
9818   /* NOTREACHED */
9819   return 0;
9820 }
9821
9822 static int
9823 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9824 {
9825   unformat_input_t *i = vam->input;
9826   vl_api_l2tpv3_interface_enable_disable_t *mp;
9827   f64 timeout;
9828   u32 sw_if_index;
9829   u8 sw_if_index_set = 0;
9830   u8 enable_disable = 1;
9831
9832   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9833     {
9834       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9835         sw_if_index_set = 1;
9836       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9837         sw_if_index_set = 1;
9838       else if (unformat (i, "enable"))
9839         enable_disable = 1;
9840       else if (unformat (i, "disable"))
9841         enable_disable = 0;
9842       else
9843         break;
9844     }
9845
9846   if (sw_if_index_set == 0)
9847     {
9848       errmsg ("missing interface name or sw_if_index\n");
9849       return -99;
9850     }
9851
9852   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9853
9854   mp->sw_if_index = ntohl (sw_if_index);
9855   mp->enable_disable = enable_disable;
9856
9857   S;
9858   W;
9859   /* NOTREACHED */
9860   return 0;
9861 }
9862
9863 static int
9864 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9865 {
9866   unformat_input_t *i = vam->input;
9867   vl_api_l2tpv3_set_lookup_key_t *mp;
9868   f64 timeout;
9869   u8 key = ~0;
9870
9871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9872     {
9873       if (unformat (i, "lookup_v6_src"))
9874         key = L2T_LOOKUP_SRC_ADDRESS;
9875       else if (unformat (i, "lookup_v6_dst"))
9876         key = L2T_LOOKUP_DST_ADDRESS;
9877       else if (unformat (i, "lookup_session_id"))
9878         key = L2T_LOOKUP_SESSION_ID;
9879       else
9880         break;
9881     }
9882
9883   if (key == (u8) ~ 0)
9884     {
9885       errmsg ("l2tp session lookup key unset\n");
9886       return -99;
9887     }
9888
9889   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9890
9891   mp->key = key;
9892
9893   S;
9894   W;
9895   /* NOTREACHED */
9896   return 0;
9897 }
9898
9899 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9900   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9901 {
9902   vat_main_t *vam = &vat_main;
9903
9904   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9905            format_ip6_address, mp->our_address,
9906            format_ip6_address, mp->client_address,
9907            clib_net_to_host_u32 (mp->sw_if_index));
9908
9909   fformat (vam->ofp,
9910            "   local cookies %016llx %016llx remote cookie %016llx\n",
9911            clib_net_to_host_u64 (mp->local_cookie[0]),
9912            clib_net_to_host_u64 (mp->local_cookie[1]),
9913            clib_net_to_host_u64 (mp->remote_cookie));
9914
9915   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9916            clib_net_to_host_u32 (mp->local_session_id),
9917            clib_net_to_host_u32 (mp->remote_session_id));
9918
9919   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9920            mp->l2_sublayer_present ? "preset" : "absent");
9921
9922 }
9923
9924 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9925   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9926 {
9927   vat_main_t *vam = &vat_main;
9928   vat_json_node_t *node = NULL;
9929   struct in6_addr addr;
9930
9931   if (VAT_JSON_ARRAY != vam->json_tree.type)
9932     {
9933       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9934       vat_json_init_array (&vam->json_tree);
9935     }
9936   node = vat_json_array_add (&vam->json_tree);
9937
9938   vat_json_init_object (node);
9939
9940   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9941   vat_json_object_add_ip6 (node, "our_address", addr);
9942   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9943   vat_json_object_add_ip6 (node, "client_address", addr);
9944
9945   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9946   vat_json_init_array (lc);
9947   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9948   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9949   vat_json_object_add_uint (node, "remote_cookie",
9950                             clib_net_to_host_u64 (mp->remote_cookie));
9951
9952   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9953   vat_json_object_add_uint (node, "local_session_id",
9954                             clib_net_to_host_u32 (mp->local_session_id));
9955   vat_json_object_add_uint (node, "remote_session_id",
9956                             clib_net_to_host_u32 (mp->remote_session_id));
9957   vat_json_object_add_string_copy (node, "l2_sublayer",
9958                                    mp->l2_sublayer_present ? (u8 *) "present"
9959                                    : (u8 *) "absent");
9960 }
9961
9962 static int
9963 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9964 {
9965   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
9966   f64 timeout;
9967
9968   /* Get list of l2tpv3-tunnel interfaces */
9969   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
9970   S;
9971
9972   /* Use a control ping for synchronization */
9973   {
9974     vl_api_control_ping_t *mp;
9975     M (CONTROL_PING, control_ping);
9976     S;
9977   }
9978   W;
9979 }
9980
9981
9982 static void vl_api_sw_interface_tap_details_t_handler
9983   (vl_api_sw_interface_tap_details_t * mp)
9984 {
9985   vat_main_t *vam = &vat_main;
9986
9987   fformat (vam->ofp, "%-16s %d\n",
9988            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
9989 }
9990
9991 static void vl_api_sw_interface_tap_details_t_handler_json
9992   (vl_api_sw_interface_tap_details_t * mp)
9993 {
9994   vat_main_t *vam = &vat_main;
9995   vat_json_node_t *node = NULL;
9996
9997   if (VAT_JSON_ARRAY != vam->json_tree.type)
9998     {
9999       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10000       vat_json_init_array (&vam->json_tree);
10001     }
10002   node = vat_json_array_add (&vam->json_tree);
10003
10004   vat_json_init_object (node);
10005   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10006   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10007 }
10008
10009 static int
10010 api_sw_interface_tap_dump (vat_main_t * vam)
10011 {
10012   vl_api_sw_interface_tap_dump_t *mp;
10013   f64 timeout;
10014
10015   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10016   /* Get list of tap interfaces */
10017   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10018   S;
10019
10020   /* Use a control ping for synchronization */
10021   {
10022     vl_api_control_ping_t *mp;
10023     M (CONTROL_PING, control_ping);
10024     S;
10025   }
10026   W;
10027 }
10028
10029 static uword unformat_vxlan_decap_next
10030   (unformat_input_t * input, va_list * args)
10031 {
10032   u32 *result = va_arg (*args, u32 *);
10033   u32 tmp;
10034
10035   if (unformat (input, "l2"))
10036     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10037   else if (unformat (input, "%d", &tmp))
10038     *result = tmp;
10039   else
10040     return 0;
10041   return 1;
10042 }
10043
10044 static int
10045 api_vxlan_add_del_tunnel (vat_main_t * vam)
10046 {
10047   unformat_input_t *line_input = vam->input;
10048   vl_api_vxlan_add_del_tunnel_t *mp;
10049   f64 timeout;
10050   ip46_address_t src, dst;
10051   u8 is_add = 1;
10052   u8 ipv4_set = 0, ipv6_set = 0;
10053   u8 src_set = 0;
10054   u8 dst_set = 0;
10055   u8 grp_set = 0;
10056   u32 mcast_sw_if_index = ~0;
10057   u32 encap_vrf_id = 0;
10058   u32 decap_next_index = ~0;
10059   u32 vni = 0;
10060
10061   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10062   memset (&src, 0, sizeof src);
10063   memset (&dst, 0, sizeof dst);
10064
10065   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10066     {
10067       if (unformat (line_input, "del"))
10068         is_add = 0;
10069       else
10070         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10071         {
10072           ipv4_set = 1;
10073           src_set = 1;
10074         }
10075       else
10076         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10077         {
10078           ipv4_set = 1;
10079           dst_set = 1;
10080         }
10081       else
10082         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10083         {
10084           ipv6_set = 1;
10085           src_set = 1;
10086         }
10087       else
10088         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10089         {
10090           ipv6_set = 1;
10091           dst_set = 1;
10092         }
10093       else if (unformat (line_input, "group %U %U",
10094                          unformat_ip4_address, &dst.ip4,
10095                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10096         {
10097           grp_set = dst_set = 1;
10098           ipv4_set = 1;
10099         }
10100       else if (unformat (line_input, "group %U",
10101                          unformat_ip4_address, &dst.ip4))
10102         {
10103           grp_set = dst_set = 1;
10104           ipv4_set = 1;
10105         }
10106       else if (unformat (line_input, "group %U %U",
10107                          unformat_ip6_address, &dst.ip6,
10108                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10109         {
10110           grp_set = dst_set = 1;
10111           ipv6_set = 1;
10112         }
10113       else if (unformat (line_input, "group %U",
10114                          unformat_ip6_address, &dst.ip6))
10115         {
10116           grp_set = dst_set = 1;
10117           ipv6_set = 1;
10118         }
10119       else
10120         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10121         ;
10122       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10123         ;
10124       else if (unformat (line_input, "decap-next %U",
10125                          unformat_vxlan_decap_next, &decap_next_index))
10126         ;
10127       else if (unformat (line_input, "vni %d", &vni))
10128         ;
10129       else
10130         {
10131           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10132           return -99;
10133         }
10134     }
10135
10136   if (src_set == 0)
10137     {
10138       errmsg ("tunnel src address not specified\n");
10139       return -99;
10140     }
10141   if (dst_set == 0)
10142     {
10143       errmsg ("tunnel dst address not specified\n");
10144       return -99;
10145     }
10146
10147   if (grp_set && !ip46_address_is_multicast (&dst))
10148     {
10149       errmsg ("tunnel group address not multicast\n");
10150       return -99;
10151     }
10152   if (grp_set && mcast_sw_if_index == ~0)
10153     {
10154       errmsg ("tunnel nonexistent multicast device\n");
10155       return -99;
10156     }
10157
10158
10159   if (ipv4_set && ipv6_set)
10160     {
10161       errmsg ("both IPv4 and IPv6 addresses specified");
10162       return -99;
10163     }
10164
10165   if ((vni == 0) || (vni >> 24))
10166     {
10167       errmsg ("vni not specified or out of range\n");
10168       return -99;
10169     }
10170
10171   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10172
10173   if (ipv6_set)
10174     {
10175       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10176       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10177     }
10178   else
10179     {
10180       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10181       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10182     }
10183   mp->encap_vrf_id = ntohl (encap_vrf_id);
10184   mp->decap_next_index = ntohl (decap_next_index);
10185   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10186   mp->vni = ntohl (vni);
10187   mp->is_add = is_add;
10188   mp->is_ipv6 = ipv6_set;
10189
10190   S;
10191   W;
10192   /* NOTREACHED */
10193   return 0;
10194 }
10195
10196 static void vl_api_vxlan_tunnel_details_t_handler
10197   (vl_api_vxlan_tunnel_details_t * mp)
10198 {
10199   vat_main_t *vam = &vat_main;
10200   ip46_address_t src, dst;
10201
10202   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10203   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10204
10205   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d\n",
10206            ntohl (mp->sw_if_index),
10207            format_ip46_address, &src, IP46_TYPE_ANY,
10208            format_ip46_address, &dst, IP46_TYPE_ANY,
10209            ntohl (mp->encap_vrf_id),
10210            ntohl (mp->decap_next_index), ntohl (mp->vni),
10211            ntohl (mp->mcast_sw_if_index));
10212 }
10213
10214 static void vl_api_vxlan_tunnel_details_t_handler_json
10215   (vl_api_vxlan_tunnel_details_t * mp)
10216 {
10217   vat_main_t *vam = &vat_main;
10218   vat_json_node_t *node = NULL;
10219
10220   if (VAT_JSON_ARRAY != vam->json_tree.type)
10221     {
10222       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10223       vat_json_init_array (&vam->json_tree);
10224     }
10225   node = vat_json_array_add (&vam->json_tree);
10226
10227   vat_json_init_object (node);
10228   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10229   if (mp->is_ipv6)
10230     {
10231       struct in6_addr ip6;
10232
10233       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10234       vat_json_object_add_ip6 (node, "src_address", ip6);
10235       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10236       vat_json_object_add_ip6 (node, "dst_address", ip6);
10237     }
10238   else
10239     {
10240       struct in_addr ip4;
10241
10242       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10243       vat_json_object_add_ip4 (node, "src_address", ip4);
10244       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10245       vat_json_object_add_ip4 (node, "dst_address", ip4);
10246     }
10247   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10248   vat_json_object_add_uint (node, "decap_next_index",
10249                             ntohl (mp->decap_next_index));
10250   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10251   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10252   vat_json_object_add_uint (node, "mcast_sw_if_index",
10253                             ntohl (mp->mcast_sw_if_index));
10254 }
10255
10256 static int
10257 api_vxlan_tunnel_dump (vat_main_t * vam)
10258 {
10259   unformat_input_t *i = vam->input;
10260   vl_api_vxlan_tunnel_dump_t *mp;
10261   f64 timeout;
10262   u32 sw_if_index;
10263   u8 sw_if_index_set = 0;
10264
10265   /* Parse args required to build the message */
10266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10267     {
10268       if (unformat (i, "sw_if_index %d", &sw_if_index))
10269         sw_if_index_set = 1;
10270       else
10271         break;
10272     }
10273
10274   if (sw_if_index_set == 0)
10275     {
10276       sw_if_index = ~0;
10277     }
10278
10279   if (!vam->json_output)
10280     {
10281       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s\n",
10282                "sw_if_index", "src_address", "dst_address",
10283                "encap_vrf_id", "decap_next_index", "vni",
10284                "mcast_sw_if_index");
10285     }
10286
10287   /* Get list of vxlan-tunnel interfaces */
10288   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10289
10290   mp->sw_if_index = htonl (sw_if_index);
10291
10292   S;
10293
10294   /* Use a control ping for synchronization */
10295   {
10296     vl_api_control_ping_t *mp;
10297     M (CONTROL_PING, control_ping);
10298     S;
10299   }
10300   W;
10301 }
10302
10303 static int
10304 api_gre_add_del_tunnel (vat_main_t * vam)
10305 {
10306   unformat_input_t *line_input = vam->input;
10307   vl_api_gre_add_del_tunnel_t *mp;
10308   f64 timeout;
10309   ip4_address_t src4, dst4;
10310   u8 is_add = 1;
10311   u8 teb = 0;
10312   u8 src_set = 0;
10313   u8 dst_set = 0;
10314   u32 outer_fib_id = 0;
10315
10316   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10317     {
10318       if (unformat (line_input, "del"))
10319         is_add = 0;
10320       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10321         src_set = 1;
10322       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10323         dst_set = 1;
10324       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10325         ;
10326       else if (unformat (line_input, "teb"))
10327         teb = 1;
10328       else
10329         {
10330           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10331           return -99;
10332         }
10333     }
10334
10335   if (src_set == 0)
10336     {
10337       errmsg ("tunnel src address not specified\n");
10338       return -99;
10339     }
10340   if (dst_set == 0)
10341     {
10342       errmsg ("tunnel dst address not specified\n");
10343       return -99;
10344     }
10345
10346
10347   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10348
10349   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10350   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10351   mp->outer_fib_id = ntohl (outer_fib_id);
10352   mp->is_add = is_add;
10353   mp->teb = teb;
10354
10355   S;
10356   W;
10357   /* NOTREACHED */
10358   return 0;
10359 }
10360
10361 static void vl_api_gre_tunnel_details_t_handler
10362   (vl_api_gre_tunnel_details_t * mp)
10363 {
10364   vat_main_t *vam = &vat_main;
10365
10366   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10367            ntohl (mp->sw_if_index),
10368            format_ip4_address, &mp->src_address,
10369            format_ip4_address, &mp->dst_address,
10370            mp->teb, ntohl (mp->outer_fib_id));
10371 }
10372
10373 static void vl_api_gre_tunnel_details_t_handler_json
10374   (vl_api_gre_tunnel_details_t * mp)
10375 {
10376   vat_main_t *vam = &vat_main;
10377   vat_json_node_t *node = NULL;
10378   struct in_addr ip4;
10379
10380   if (VAT_JSON_ARRAY != vam->json_tree.type)
10381     {
10382       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10383       vat_json_init_array (&vam->json_tree);
10384     }
10385   node = vat_json_array_add (&vam->json_tree);
10386
10387   vat_json_init_object (node);
10388   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10389   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10390   vat_json_object_add_ip4 (node, "src_address", ip4);
10391   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10392   vat_json_object_add_ip4 (node, "dst_address", ip4);
10393   vat_json_object_add_uint (node, "teb", mp->teb);
10394   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10395 }
10396
10397 static int
10398 api_gre_tunnel_dump (vat_main_t * vam)
10399 {
10400   unformat_input_t *i = vam->input;
10401   vl_api_gre_tunnel_dump_t *mp;
10402   f64 timeout;
10403   u32 sw_if_index;
10404   u8 sw_if_index_set = 0;
10405
10406   /* Parse args required to build the message */
10407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10408     {
10409       if (unformat (i, "sw_if_index %d", &sw_if_index))
10410         sw_if_index_set = 1;
10411       else
10412         break;
10413     }
10414
10415   if (sw_if_index_set == 0)
10416     {
10417       sw_if_index = ~0;
10418     }
10419
10420   if (!vam->json_output)
10421     {
10422       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10423                "sw_if_index", "src_address", "dst_address", "teb",
10424                "outer_fib_id");
10425     }
10426
10427   /* Get list of gre-tunnel interfaces */
10428   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10429
10430   mp->sw_if_index = htonl (sw_if_index);
10431
10432   S;
10433
10434   /* Use a control ping for synchronization */
10435   {
10436     vl_api_control_ping_t *mp;
10437     M (CONTROL_PING, control_ping);
10438     S;
10439   }
10440   W;
10441 }
10442
10443 static int
10444 api_l2_fib_clear_table (vat_main_t * vam)
10445 {
10446 //  unformat_input_t * i = vam->input;
10447   vl_api_l2_fib_clear_table_t *mp;
10448   f64 timeout;
10449
10450   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10451
10452   S;
10453   W;
10454   /* NOTREACHED */
10455   return 0;
10456 }
10457
10458 static int
10459 api_l2_interface_efp_filter (vat_main_t * vam)
10460 {
10461   unformat_input_t *i = vam->input;
10462   vl_api_l2_interface_efp_filter_t *mp;
10463   f64 timeout;
10464   u32 sw_if_index;
10465   u8 enable = 1;
10466   u8 sw_if_index_set = 0;
10467
10468   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10469     {
10470       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10471         sw_if_index_set = 1;
10472       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10473         sw_if_index_set = 1;
10474       else if (unformat (i, "enable"))
10475         enable = 1;
10476       else if (unformat (i, "disable"))
10477         enable = 0;
10478       else
10479         {
10480           clib_warning ("parse error '%U'", format_unformat_error, i);
10481           return -99;
10482         }
10483     }
10484
10485   if (sw_if_index_set == 0)
10486     {
10487       errmsg ("missing sw_if_index\n");
10488       return -99;
10489     }
10490
10491   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10492
10493   mp->sw_if_index = ntohl (sw_if_index);
10494   mp->enable_disable = enable;
10495
10496   S;
10497   W;
10498   /* NOTREACHED */
10499   return 0;
10500 }
10501
10502 #define foreach_vtr_op                          \
10503 _("disable",  L2_VTR_DISABLED)                  \
10504 _("push-1",  L2_VTR_PUSH_1)                     \
10505 _("push-2",  L2_VTR_PUSH_2)                     \
10506 _("pop-1",  L2_VTR_POP_1)                       \
10507 _("pop-2",  L2_VTR_POP_2)                       \
10508 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10509 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10510 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10511 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10512
10513 static int
10514 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10515 {
10516   unformat_input_t *i = vam->input;
10517   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10518   f64 timeout;
10519   u32 sw_if_index;
10520   u8 sw_if_index_set = 0;
10521   u8 vtr_op_set = 0;
10522   u32 vtr_op = 0;
10523   u32 push_dot1q = 1;
10524   u32 tag1 = ~0;
10525   u32 tag2 = ~0;
10526
10527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10528     {
10529       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10530         sw_if_index_set = 1;
10531       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10532         sw_if_index_set = 1;
10533       else if (unformat (i, "vtr_op %d", &vtr_op))
10534         vtr_op_set = 1;
10535 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10536       foreach_vtr_op
10537 #undef _
10538         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10539         ;
10540       else if (unformat (i, "tag1 %d", &tag1))
10541         ;
10542       else if (unformat (i, "tag2 %d", &tag2))
10543         ;
10544       else
10545         {
10546           clib_warning ("parse error '%U'", format_unformat_error, i);
10547           return -99;
10548         }
10549     }
10550
10551   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10552     {
10553       errmsg ("missing vtr operation or sw_if_index\n");
10554       return -99;
10555     }
10556
10557   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10558     mp->sw_if_index = ntohl (sw_if_index);
10559   mp->vtr_op = ntohl (vtr_op);
10560   mp->push_dot1q = ntohl (push_dot1q);
10561   mp->tag1 = ntohl (tag1);
10562   mp->tag2 = ntohl (tag2);
10563
10564   S;
10565   W;
10566   /* NOTREACHED */
10567   return 0;
10568 }
10569
10570 static int
10571 api_create_vhost_user_if (vat_main_t * vam)
10572 {
10573   unformat_input_t *i = vam->input;
10574   vl_api_create_vhost_user_if_t *mp;
10575   f64 timeout;
10576   u8 *file_name;
10577   u8 is_server = 0;
10578   u8 file_name_set = 0;
10579   u32 custom_dev_instance = ~0;
10580   u8 hwaddr[6];
10581   u8 use_custom_mac = 0;
10582   u8 *tag = 0;
10583
10584   /* Shut up coverity */
10585   memset (hwaddr, 0, sizeof (hwaddr));
10586
10587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10588     {
10589       if (unformat (i, "socket %s", &file_name))
10590         {
10591           file_name_set = 1;
10592         }
10593       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10594         ;
10595       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10596         use_custom_mac = 1;
10597       else if (unformat (i, "server"))
10598         is_server = 1;
10599       else if (unformat (i, "tag %s", &tag))
10600         ;
10601       else
10602         break;
10603     }
10604
10605   if (file_name_set == 0)
10606     {
10607       errmsg ("missing socket file name\n");
10608       return -99;
10609     }
10610
10611   if (vec_len (file_name) > 255)
10612     {
10613       errmsg ("socket file name too long\n");
10614       return -99;
10615     }
10616   vec_add1 (file_name, 0);
10617
10618   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10619
10620   mp->is_server = is_server;
10621   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10622   vec_free (file_name);
10623   if (custom_dev_instance != ~0)
10624     {
10625       mp->renumber = 1;
10626       mp->custom_dev_instance = ntohl (custom_dev_instance);
10627     }
10628   mp->use_custom_mac = use_custom_mac;
10629   clib_memcpy (mp->mac_address, hwaddr, 6);
10630   if (tag)
10631     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10632   vec_free (tag);
10633
10634   S;
10635   W;
10636   /* NOTREACHED */
10637   return 0;
10638 }
10639
10640 static int
10641 api_modify_vhost_user_if (vat_main_t * vam)
10642 {
10643   unformat_input_t *i = vam->input;
10644   vl_api_modify_vhost_user_if_t *mp;
10645   f64 timeout;
10646   u8 *file_name;
10647   u8 is_server = 0;
10648   u8 file_name_set = 0;
10649   u32 custom_dev_instance = ~0;
10650   u8 sw_if_index_set = 0;
10651   u32 sw_if_index = (u32) ~ 0;
10652
10653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10654     {
10655       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10656         sw_if_index_set = 1;
10657       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10658         sw_if_index_set = 1;
10659       else if (unformat (i, "socket %s", &file_name))
10660         {
10661           file_name_set = 1;
10662         }
10663       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10664         ;
10665       else if (unformat (i, "server"))
10666         is_server = 1;
10667       else
10668         break;
10669     }
10670
10671   if (sw_if_index_set == 0)
10672     {
10673       errmsg ("missing sw_if_index or interface name\n");
10674       return -99;
10675     }
10676
10677   if (file_name_set == 0)
10678     {
10679       errmsg ("missing socket file name\n");
10680       return -99;
10681     }
10682
10683   if (vec_len (file_name) > 255)
10684     {
10685       errmsg ("socket file name too long\n");
10686       return -99;
10687     }
10688   vec_add1 (file_name, 0);
10689
10690   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10691
10692   mp->sw_if_index = ntohl (sw_if_index);
10693   mp->is_server = is_server;
10694   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10695   vec_free (file_name);
10696   if (custom_dev_instance != ~0)
10697     {
10698       mp->renumber = 1;
10699       mp->custom_dev_instance = ntohl (custom_dev_instance);
10700     }
10701
10702   S;
10703   W;
10704   /* NOTREACHED */
10705   return 0;
10706 }
10707
10708 static int
10709 api_delete_vhost_user_if (vat_main_t * vam)
10710 {
10711   unformat_input_t *i = vam->input;
10712   vl_api_delete_vhost_user_if_t *mp;
10713   f64 timeout;
10714   u32 sw_if_index = ~0;
10715   u8 sw_if_index_set = 0;
10716
10717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10718     {
10719       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10720         sw_if_index_set = 1;
10721       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10722         sw_if_index_set = 1;
10723       else
10724         break;
10725     }
10726
10727   if (sw_if_index_set == 0)
10728     {
10729       errmsg ("missing sw_if_index or interface name\n");
10730       return -99;
10731     }
10732
10733
10734   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10735
10736   mp->sw_if_index = ntohl (sw_if_index);
10737
10738   S;
10739   W;
10740   /* NOTREACHED */
10741   return 0;
10742 }
10743
10744 static void vl_api_sw_interface_vhost_user_details_t_handler
10745   (vl_api_sw_interface_vhost_user_details_t * mp)
10746 {
10747   vat_main_t *vam = &vat_main;
10748
10749   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10750            (char *) mp->interface_name,
10751            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10752            clib_net_to_host_u64 (mp->features), mp->is_server,
10753            ntohl (mp->num_regions), (char *) mp->sock_filename);
10754   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10755 }
10756
10757 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10758   (vl_api_sw_interface_vhost_user_details_t * mp)
10759 {
10760   vat_main_t *vam = &vat_main;
10761   vat_json_node_t *node = NULL;
10762
10763   if (VAT_JSON_ARRAY != vam->json_tree.type)
10764     {
10765       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10766       vat_json_init_array (&vam->json_tree);
10767     }
10768   node = vat_json_array_add (&vam->json_tree);
10769
10770   vat_json_init_object (node);
10771   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10772   vat_json_object_add_string_copy (node, "interface_name",
10773                                    mp->interface_name);
10774   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10775                             ntohl (mp->virtio_net_hdr_sz));
10776   vat_json_object_add_uint (node, "features",
10777                             clib_net_to_host_u64 (mp->features));
10778   vat_json_object_add_uint (node, "is_server", mp->is_server);
10779   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10780   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10781   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10782 }
10783
10784 static int
10785 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10786 {
10787   vl_api_sw_interface_vhost_user_dump_t *mp;
10788   f64 timeout;
10789   fformat (vam->ofp,
10790            "Interface name           idx hdr_sz features server regions filename\n");
10791
10792   /* Get list of vhost-user interfaces */
10793   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10794   S;
10795
10796   /* Use a control ping for synchronization */
10797   {
10798     vl_api_control_ping_t *mp;
10799     M (CONTROL_PING, control_ping);
10800     S;
10801   }
10802   W;
10803 }
10804
10805 static int
10806 api_show_version (vat_main_t * vam)
10807 {
10808   vl_api_show_version_t *mp;
10809   f64 timeout;
10810
10811   M (SHOW_VERSION, show_version);
10812
10813   S;
10814   W;
10815   /* NOTREACHED */
10816   return 0;
10817 }
10818
10819
10820 static int
10821 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10822 {
10823   unformat_input_t *line_input = vam->input;
10824   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10825   f64 timeout;
10826   ip4_address_t local4, remote4;
10827   ip6_address_t local6, remote6;
10828   u8 is_add = 1;
10829   u8 ipv4_set = 0, ipv6_set = 0;
10830   u8 local_set = 0;
10831   u8 remote_set = 0;
10832   u32 encap_vrf_id = 0;
10833   u32 decap_vrf_id = 0;
10834   u8 protocol = ~0;
10835   u32 vni;
10836   u8 vni_set = 0;
10837
10838   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10839     {
10840       if (unformat (line_input, "del"))
10841         is_add = 0;
10842       else if (unformat (line_input, "local %U",
10843                          unformat_ip4_address, &local4))
10844         {
10845           local_set = 1;
10846           ipv4_set = 1;
10847         }
10848       else if (unformat (line_input, "remote %U",
10849                          unformat_ip4_address, &remote4))
10850         {
10851           remote_set = 1;
10852           ipv4_set = 1;
10853         }
10854       else if (unformat (line_input, "local %U",
10855                          unformat_ip6_address, &local6))
10856         {
10857           local_set = 1;
10858           ipv6_set = 1;
10859         }
10860       else if (unformat (line_input, "remote %U",
10861                          unformat_ip6_address, &remote6))
10862         {
10863           remote_set = 1;
10864           ipv6_set = 1;
10865         }
10866       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10867         ;
10868       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10869         ;
10870       else if (unformat (line_input, "vni %d", &vni))
10871         vni_set = 1;
10872       else if (unformat (line_input, "next-ip4"))
10873         protocol = 1;
10874       else if (unformat (line_input, "next-ip6"))
10875         protocol = 2;
10876       else if (unformat (line_input, "next-ethernet"))
10877         protocol = 3;
10878       else if (unformat (line_input, "next-nsh"))
10879         protocol = 4;
10880       else
10881         {
10882           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10883           return -99;
10884         }
10885     }
10886
10887   if (local_set == 0)
10888     {
10889       errmsg ("tunnel local address not specified\n");
10890       return -99;
10891     }
10892   if (remote_set == 0)
10893     {
10894       errmsg ("tunnel remote address not specified\n");
10895       return -99;
10896     }
10897   if (ipv4_set && ipv6_set)
10898     {
10899       errmsg ("both IPv4 and IPv6 addresses specified");
10900       return -99;
10901     }
10902
10903   if (vni_set == 0)
10904     {
10905       errmsg ("vni not specified\n");
10906       return -99;
10907     }
10908
10909   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10910
10911
10912   if (ipv6_set)
10913     {
10914       clib_memcpy (&mp->local, &local6, sizeof (local6));
10915       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10916     }
10917   else
10918     {
10919       clib_memcpy (&mp->local, &local4, sizeof (local4));
10920       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10921     }
10922
10923   mp->encap_vrf_id = ntohl (encap_vrf_id);
10924   mp->decap_vrf_id = ntohl (decap_vrf_id);
10925   mp->protocol = ntohl (protocol);
10926   mp->vni = ntohl (vni);
10927   mp->is_add = is_add;
10928   mp->is_ipv6 = ipv6_set;
10929
10930   S;
10931   W;
10932   /* NOTREACHED */
10933   return 0;
10934 }
10935
10936 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10937   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10938 {
10939   vat_main_t *vam = &vat_main;
10940
10941   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10942            ntohl (mp->sw_if_index),
10943            format_ip46_address, &(mp->local[0]),
10944            format_ip46_address, &(mp->remote[0]),
10945            ntohl (mp->vni),
10946            ntohl (mp->protocol),
10947            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10948 }
10949
10950 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10951   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10952 {
10953   vat_main_t *vam = &vat_main;
10954   vat_json_node_t *node = NULL;
10955   struct in_addr ip4;
10956   struct in6_addr ip6;
10957
10958   if (VAT_JSON_ARRAY != vam->json_tree.type)
10959     {
10960       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10961       vat_json_init_array (&vam->json_tree);
10962     }
10963   node = vat_json_array_add (&vam->json_tree);
10964
10965   vat_json_init_object (node);
10966   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10967   if (mp->is_ipv6)
10968     {
10969       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10970       vat_json_object_add_ip6 (node, "local", ip6);
10971       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10972       vat_json_object_add_ip6 (node, "remote", ip6);
10973     }
10974   else
10975     {
10976       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10977       vat_json_object_add_ip4 (node, "local", ip4);
10978       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10979       vat_json_object_add_ip4 (node, "remote", ip4);
10980     }
10981   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10982   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10983   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10984   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10985   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10986 }
10987
10988 static int
10989 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10990 {
10991   unformat_input_t *i = vam->input;
10992   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10993   f64 timeout;
10994   u32 sw_if_index;
10995   u8 sw_if_index_set = 0;
10996
10997   /* Parse args required to build the message */
10998   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10999     {
11000       if (unformat (i, "sw_if_index %d", &sw_if_index))
11001         sw_if_index_set = 1;
11002       else
11003         break;
11004     }
11005
11006   if (sw_if_index_set == 0)
11007     {
11008       sw_if_index = ~0;
11009     }
11010
11011   if (!vam->json_output)
11012     {
11013       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
11014                "sw_if_index", "local", "remote", "vni",
11015                "protocol", "encap_vrf_id", "decap_vrf_id");
11016     }
11017
11018   /* Get list of vxlan-tunnel interfaces */
11019   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11020
11021   mp->sw_if_index = htonl (sw_if_index);
11022
11023   S;
11024
11025   /* Use a control ping for synchronization */
11026   {
11027     vl_api_control_ping_t *mp;
11028     M (CONTROL_PING, control_ping);
11029     S;
11030   }
11031   W;
11032 }
11033
11034 u8 *
11035 format_l2_fib_mac_address (u8 * s, va_list * args)
11036 {
11037   u8 *a = va_arg (*args, u8 *);
11038
11039   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11040                  a[2], a[3], a[4], a[5], a[6], a[7]);
11041 }
11042
11043 static void vl_api_l2_fib_table_entry_t_handler
11044   (vl_api_l2_fib_table_entry_t * mp)
11045 {
11046   vat_main_t *vam = &vat_main;
11047
11048   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11049            "       %d       %d     %d\n",
11050            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11051            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11052            mp->bvi_mac);
11053 }
11054
11055 static void vl_api_l2_fib_table_entry_t_handler_json
11056   (vl_api_l2_fib_table_entry_t * mp)
11057 {
11058   vat_main_t *vam = &vat_main;
11059   vat_json_node_t *node = NULL;
11060
11061   if (VAT_JSON_ARRAY != vam->json_tree.type)
11062     {
11063       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11064       vat_json_init_array (&vam->json_tree);
11065     }
11066   node = vat_json_array_add (&vam->json_tree);
11067
11068   vat_json_init_object (node);
11069   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11070   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11071   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11072   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11073   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11074   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11075 }
11076
11077 static int
11078 api_l2_fib_table_dump (vat_main_t * vam)
11079 {
11080   unformat_input_t *i = vam->input;
11081   vl_api_l2_fib_table_dump_t *mp;
11082   f64 timeout;
11083   u32 bd_id;
11084   u8 bd_id_set = 0;
11085
11086   /* Parse args required to build the message */
11087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11088     {
11089       if (unformat (i, "bd_id %d", &bd_id))
11090         bd_id_set = 1;
11091       else
11092         break;
11093     }
11094
11095   if (bd_id_set == 0)
11096     {
11097       errmsg ("missing bridge domain\n");
11098       return -99;
11099     }
11100
11101   fformat (vam->ofp,
11102            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11103
11104   /* Get list of l2 fib entries */
11105   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11106
11107   mp->bd_id = ntohl (bd_id);
11108   S;
11109
11110   /* Use a control ping for synchronization */
11111   {
11112     vl_api_control_ping_t *mp;
11113     M (CONTROL_PING, control_ping);
11114     S;
11115   }
11116   W;
11117 }
11118
11119
11120 static int
11121 api_interface_name_renumber (vat_main_t * vam)
11122 {
11123   unformat_input_t *line_input = vam->input;
11124   vl_api_interface_name_renumber_t *mp;
11125   u32 sw_if_index = ~0;
11126   f64 timeout;
11127   u32 new_show_dev_instance = ~0;
11128
11129   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11130     {
11131       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11132                     &sw_if_index))
11133         ;
11134       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11135         ;
11136       else if (unformat (line_input, "new_show_dev_instance %d",
11137                          &new_show_dev_instance))
11138         ;
11139       else
11140         break;
11141     }
11142
11143   if (sw_if_index == ~0)
11144     {
11145       errmsg ("missing interface name or sw_if_index\n");
11146       return -99;
11147     }
11148
11149   if (new_show_dev_instance == ~0)
11150     {
11151       errmsg ("missing new_show_dev_instance\n");
11152       return -99;
11153     }
11154
11155   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11156
11157   mp->sw_if_index = ntohl (sw_if_index);
11158   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11159
11160   S;
11161   W;
11162 }
11163
11164 static int
11165 api_want_ip4_arp_events (vat_main_t * vam)
11166 {
11167   unformat_input_t *line_input = vam->input;
11168   vl_api_want_ip4_arp_events_t *mp;
11169   f64 timeout;
11170   ip4_address_t address;
11171   int address_set = 0;
11172   u32 enable_disable = 1;
11173
11174   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11175     {
11176       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11177         address_set = 1;
11178       else if (unformat (line_input, "del"))
11179         enable_disable = 0;
11180       else
11181         break;
11182     }
11183
11184   if (address_set == 0)
11185     {
11186       errmsg ("missing addresses\n");
11187       return -99;
11188     }
11189
11190   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11191   mp->enable_disable = enable_disable;
11192   mp->pid = getpid ();
11193   mp->address = address.as_u32;
11194
11195   S;
11196   W;
11197 }
11198
11199 static int
11200 api_want_ip6_nd_events (vat_main_t * vam)
11201 {
11202   unformat_input_t *line_input = vam->input;
11203   vl_api_want_ip6_nd_events_t *mp;
11204   f64 timeout;
11205   ip6_address_t address;
11206   int address_set = 0;
11207   u32 enable_disable = 1;
11208
11209   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11210     {
11211       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11212         address_set = 1;
11213       else if (unformat (line_input, "del"))
11214         enable_disable = 0;
11215       else
11216         break;
11217     }
11218
11219   if (address_set == 0)
11220     {
11221       errmsg ("missing addresses\n");
11222       return -99;
11223     }
11224
11225   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11226   mp->enable_disable = enable_disable;
11227   mp->pid = getpid ();
11228   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11229
11230   S;
11231   W;
11232 }
11233
11234 static int
11235 api_input_acl_set_interface (vat_main_t * vam)
11236 {
11237   unformat_input_t *i = vam->input;
11238   vl_api_input_acl_set_interface_t *mp;
11239   f64 timeout;
11240   u32 sw_if_index;
11241   int sw_if_index_set;
11242   u32 ip4_table_index = ~0;
11243   u32 ip6_table_index = ~0;
11244   u32 l2_table_index = ~0;
11245   u8 is_add = 1;
11246
11247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11248     {
11249       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11250         sw_if_index_set = 1;
11251       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11252         sw_if_index_set = 1;
11253       else if (unformat (i, "del"))
11254         is_add = 0;
11255       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11256         ;
11257       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11258         ;
11259       else if (unformat (i, "l2-table %d", &l2_table_index))
11260         ;
11261       else
11262         {
11263           clib_warning ("parse error '%U'", format_unformat_error, i);
11264           return -99;
11265         }
11266     }
11267
11268   if (sw_if_index_set == 0)
11269     {
11270       errmsg ("missing interface name or sw_if_index\n");
11271       return -99;
11272     }
11273
11274   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11275
11276   mp->sw_if_index = ntohl (sw_if_index);
11277   mp->ip4_table_index = ntohl (ip4_table_index);
11278   mp->ip6_table_index = ntohl (ip6_table_index);
11279   mp->l2_table_index = ntohl (l2_table_index);
11280   mp->is_add = is_add;
11281
11282   S;
11283   W;
11284   /* NOTREACHED */
11285   return 0;
11286 }
11287
11288 static int
11289 api_ip_address_dump (vat_main_t * vam)
11290 {
11291   unformat_input_t *i = vam->input;
11292   vl_api_ip_address_dump_t *mp;
11293   u32 sw_if_index = ~0;
11294   u8 sw_if_index_set = 0;
11295   u8 ipv4_set = 0;
11296   u8 ipv6_set = 0;
11297   f64 timeout;
11298
11299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11300     {
11301       if (unformat (i, "sw_if_index %d", &sw_if_index))
11302         sw_if_index_set = 1;
11303       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11304         sw_if_index_set = 1;
11305       else if (unformat (i, "ipv4"))
11306         ipv4_set = 1;
11307       else if (unformat (i, "ipv6"))
11308         ipv6_set = 1;
11309       else
11310         break;
11311     }
11312
11313   if (ipv4_set && ipv6_set)
11314     {
11315       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11316       return -99;
11317     }
11318
11319   if ((!ipv4_set) && (!ipv6_set))
11320     {
11321       errmsg ("no ipv4 nor ipv6 flag set\n");
11322       return -99;
11323     }
11324
11325   if (sw_if_index_set == 0)
11326     {
11327       errmsg ("missing interface name or sw_if_index\n");
11328       return -99;
11329     }
11330
11331   vam->current_sw_if_index = sw_if_index;
11332   vam->is_ipv6 = ipv6_set;
11333
11334   M (IP_ADDRESS_DUMP, ip_address_dump);
11335   mp->sw_if_index = ntohl (sw_if_index);
11336   mp->is_ipv6 = ipv6_set;
11337   S;
11338
11339   /* Use a control ping for synchronization */
11340   {
11341     vl_api_control_ping_t *mp;
11342     M (CONTROL_PING, control_ping);
11343     S;
11344   }
11345   W;
11346 }
11347
11348 static int
11349 api_ip_dump (vat_main_t * vam)
11350 {
11351   vl_api_ip_dump_t *mp;
11352   unformat_input_t *in = vam->input;
11353   int ipv4_set = 0;
11354   int ipv6_set = 0;
11355   int is_ipv6;
11356   f64 timeout;
11357   int i;
11358
11359   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11360     {
11361       if (unformat (in, "ipv4"))
11362         ipv4_set = 1;
11363       else if (unformat (in, "ipv6"))
11364         ipv6_set = 1;
11365       else
11366         break;
11367     }
11368
11369   if (ipv4_set && ipv6_set)
11370     {
11371       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11372       return -99;
11373     }
11374
11375   if ((!ipv4_set) && (!ipv6_set))
11376     {
11377       errmsg ("no ipv4 nor ipv6 flag set\n");
11378       return -99;
11379     }
11380
11381   is_ipv6 = ipv6_set;
11382   vam->is_ipv6 = is_ipv6;
11383
11384   /* free old data */
11385   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11386     {
11387       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11388     }
11389   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11390
11391   M (IP_DUMP, ip_dump);
11392   mp->is_ipv6 = ipv6_set;
11393   S;
11394
11395   /* Use a control ping for synchronization */
11396   {
11397     vl_api_control_ping_t *mp;
11398     M (CONTROL_PING, control_ping);
11399     S;
11400   }
11401   W;
11402 }
11403
11404 static int
11405 api_ipsec_spd_add_del (vat_main_t * vam)
11406 {
11407   unformat_input_t *i = vam->input;
11408   vl_api_ipsec_spd_add_del_t *mp;
11409   f64 timeout;
11410   u32 spd_id = ~0;
11411   u8 is_add = 1;
11412
11413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11414     {
11415       if (unformat (i, "spd_id %d", &spd_id))
11416         ;
11417       else if (unformat (i, "del"))
11418         is_add = 0;
11419       else
11420         {
11421           clib_warning ("parse error '%U'", format_unformat_error, i);
11422           return -99;
11423         }
11424     }
11425   if (spd_id == ~0)
11426     {
11427       errmsg ("spd_id must be set\n");
11428       return -99;
11429     }
11430
11431   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11432
11433   mp->spd_id = ntohl (spd_id);
11434   mp->is_add = is_add;
11435
11436   S;
11437   W;
11438   /* NOTREACHED */
11439   return 0;
11440 }
11441
11442 static int
11443 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11444 {
11445   unformat_input_t *i = vam->input;
11446   vl_api_ipsec_interface_add_del_spd_t *mp;
11447   f64 timeout;
11448   u32 sw_if_index;
11449   u8 sw_if_index_set = 0;
11450   u32 spd_id = (u32) ~ 0;
11451   u8 is_add = 1;
11452
11453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11454     {
11455       if (unformat (i, "del"))
11456         is_add = 0;
11457       else if (unformat (i, "spd_id %d", &spd_id))
11458         ;
11459       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11460         sw_if_index_set = 1;
11461       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11462         sw_if_index_set = 1;
11463       else
11464         {
11465           clib_warning ("parse error '%U'", format_unformat_error, i);
11466           return -99;
11467         }
11468
11469     }
11470
11471   if (spd_id == (u32) ~ 0)
11472     {
11473       errmsg ("spd_id must be set\n");
11474       return -99;
11475     }
11476
11477   if (sw_if_index_set == 0)
11478     {
11479       errmsg ("missing interface name or sw_if_index\n");
11480       return -99;
11481     }
11482
11483   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11484
11485   mp->spd_id = ntohl (spd_id);
11486   mp->sw_if_index = ntohl (sw_if_index);
11487   mp->is_add = is_add;
11488
11489   S;
11490   W;
11491   /* NOTREACHED */
11492   return 0;
11493 }
11494
11495 static int
11496 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11497 {
11498   unformat_input_t *i = vam->input;
11499   vl_api_ipsec_spd_add_del_entry_t *mp;
11500   f64 timeout;
11501   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11502   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11503   i32 priority = 0;
11504   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11505   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11506   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11507   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11508
11509   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11510   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11511   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11512   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11513   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11514   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11515
11516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11517     {
11518       if (unformat (i, "del"))
11519         is_add = 0;
11520       if (unformat (i, "outbound"))
11521         is_outbound = 1;
11522       if (unformat (i, "inbound"))
11523         is_outbound = 0;
11524       else if (unformat (i, "spd_id %d", &spd_id))
11525         ;
11526       else if (unformat (i, "sa_id %d", &sa_id))
11527         ;
11528       else if (unformat (i, "priority %d", &priority))
11529         ;
11530       else if (unformat (i, "protocol %d", &protocol))
11531         ;
11532       else if (unformat (i, "lport_start %d", &lport_start))
11533         ;
11534       else if (unformat (i, "lport_stop %d", &lport_stop))
11535         ;
11536       else if (unformat (i, "rport_start %d", &rport_start))
11537         ;
11538       else if (unformat (i, "rport_stop %d", &rport_stop))
11539         ;
11540       else
11541         if (unformat
11542             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11543         {
11544           is_ipv6 = 0;
11545           is_ip_any = 0;
11546         }
11547       else
11548         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11549         {
11550           is_ipv6 = 0;
11551           is_ip_any = 0;
11552         }
11553       else
11554         if (unformat
11555             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11556         {
11557           is_ipv6 = 0;
11558           is_ip_any = 0;
11559         }
11560       else
11561         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11562         {
11563           is_ipv6 = 0;
11564           is_ip_any = 0;
11565         }
11566       else
11567         if (unformat
11568             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11569         {
11570           is_ipv6 = 1;
11571           is_ip_any = 0;
11572         }
11573       else
11574         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11575         {
11576           is_ipv6 = 1;
11577           is_ip_any = 0;
11578         }
11579       else
11580         if (unformat
11581             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11582         {
11583           is_ipv6 = 1;
11584           is_ip_any = 0;
11585         }
11586       else
11587         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11588         {
11589           is_ipv6 = 1;
11590           is_ip_any = 0;
11591         }
11592       else
11593         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11594         {
11595           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11596             {
11597               clib_warning ("unsupported action: 'resolve'");
11598               return -99;
11599             }
11600         }
11601       else
11602         {
11603           clib_warning ("parse error '%U'", format_unformat_error, i);
11604           return -99;
11605         }
11606
11607     }
11608
11609   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11610
11611   mp->spd_id = ntohl (spd_id);
11612   mp->priority = ntohl (priority);
11613   mp->is_outbound = is_outbound;
11614
11615   mp->is_ipv6 = is_ipv6;
11616   if (is_ipv6 || is_ip_any)
11617     {
11618       clib_memcpy (mp->remote_address_start, &raddr6_start,
11619                    sizeof (ip6_address_t));
11620       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11621                    sizeof (ip6_address_t));
11622       clib_memcpy (mp->local_address_start, &laddr6_start,
11623                    sizeof (ip6_address_t));
11624       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11625                    sizeof (ip6_address_t));
11626     }
11627   else
11628     {
11629       clib_memcpy (mp->remote_address_start, &raddr4_start,
11630                    sizeof (ip4_address_t));
11631       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11632                    sizeof (ip4_address_t));
11633       clib_memcpy (mp->local_address_start, &laddr4_start,
11634                    sizeof (ip4_address_t));
11635       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11636                    sizeof (ip4_address_t));
11637     }
11638   mp->protocol = (u8) protocol;
11639   mp->local_port_start = ntohs ((u16) lport_start);
11640   mp->local_port_stop = ntohs ((u16) lport_stop);
11641   mp->remote_port_start = ntohs ((u16) rport_start);
11642   mp->remote_port_stop = ntohs ((u16) rport_stop);
11643   mp->policy = (u8) policy;
11644   mp->sa_id = ntohl (sa_id);
11645   mp->is_add = is_add;
11646   mp->is_ip_any = is_ip_any;
11647   S;
11648   W;
11649   /* NOTREACHED */
11650   return 0;
11651 }
11652
11653 static int
11654 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11655 {
11656   unformat_input_t *i = vam->input;
11657   vl_api_ipsec_sad_add_del_entry_t *mp;
11658   f64 timeout;
11659   u32 sad_id = 0, spi = 0;
11660   u8 *ck = 0, *ik = 0;
11661   u8 is_add = 1;
11662
11663   u8 protocol = IPSEC_PROTOCOL_AH;
11664   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11665   u32 crypto_alg = 0, integ_alg = 0;
11666   ip4_address_t tun_src4;
11667   ip4_address_t tun_dst4;
11668   ip6_address_t tun_src6;
11669   ip6_address_t tun_dst6;
11670
11671   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11672     {
11673       if (unformat (i, "del"))
11674         is_add = 0;
11675       else if (unformat (i, "sad_id %d", &sad_id))
11676         ;
11677       else if (unformat (i, "spi %d", &spi))
11678         ;
11679       else if (unformat (i, "esp"))
11680         protocol = IPSEC_PROTOCOL_ESP;
11681       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11682         {
11683           is_tunnel = 1;
11684           is_tunnel_ipv6 = 0;
11685         }
11686       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11687         {
11688           is_tunnel = 1;
11689           is_tunnel_ipv6 = 0;
11690         }
11691       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11692         {
11693           is_tunnel = 1;
11694           is_tunnel_ipv6 = 1;
11695         }
11696       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11697         {
11698           is_tunnel = 1;
11699           is_tunnel_ipv6 = 1;
11700         }
11701       else
11702         if (unformat
11703             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11704         {
11705           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11706               crypto_alg >= IPSEC_CRYPTO_N_ALG)
11707             {
11708               clib_warning ("unsupported crypto-alg: '%U'",
11709                             format_ipsec_crypto_alg, crypto_alg);
11710               return -99;
11711             }
11712         }
11713       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11714         ;
11715       else
11716         if (unformat
11717             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11718         {
11719 #if DPDK_CRYPTO==1
11720           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
11721 #else
11722           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11723 #endif
11724               integ_alg >= IPSEC_INTEG_N_ALG)
11725             {
11726               clib_warning ("unsupported integ-alg: '%U'",
11727                             format_ipsec_integ_alg, integ_alg);
11728               return -99;
11729             }
11730         }
11731       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11732         ;
11733       else
11734         {
11735           clib_warning ("parse error '%U'", format_unformat_error, i);
11736           return -99;
11737         }
11738
11739     }
11740
11741 #if DPDK_CRYPTO==1
11742   /*Special cases, aes-gcm-128 encryption */
11743   if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
11744     {
11745       if (integ_alg != IPSEC_INTEG_ALG_NONE
11746           && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
11747         {
11748           clib_warning
11749             ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
11750           return -99;
11751         }
11752       else                      /*set integ-alg internally to aes-gcm-128 */
11753         integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
11754     }
11755   else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
11756     {
11757       clib_warning ("unsupported integ-alg: aes-gcm-128");
11758       return -99;
11759     }
11760   else if (integ_alg == IPSEC_INTEG_ALG_NONE)
11761     {
11762       clib_warning ("unsupported integ-alg: none");
11763       return -99;
11764     }
11765 #endif
11766
11767
11768   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11769
11770   mp->sad_id = ntohl (sad_id);
11771   mp->is_add = is_add;
11772   mp->protocol = protocol;
11773   mp->spi = ntohl (spi);
11774   mp->is_tunnel = is_tunnel;
11775   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11776   mp->crypto_algorithm = crypto_alg;
11777   mp->integrity_algorithm = integ_alg;
11778   mp->crypto_key_length = vec_len (ck);
11779   mp->integrity_key_length = vec_len (ik);
11780
11781   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11782     mp->crypto_key_length = sizeof (mp->crypto_key);
11783
11784   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11785     mp->integrity_key_length = sizeof (mp->integrity_key);
11786
11787   if (ck)
11788     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11789   if (ik)
11790     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11791
11792   if (is_tunnel)
11793     {
11794       if (is_tunnel_ipv6)
11795         {
11796           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11797                        sizeof (ip6_address_t));
11798           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11799                        sizeof (ip6_address_t));
11800         }
11801       else
11802         {
11803           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11804                        sizeof (ip4_address_t));
11805           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11806                        sizeof (ip4_address_t));
11807         }
11808     }
11809
11810   S;
11811   W;
11812   /* NOTREACHED */
11813   return 0;
11814 }
11815
11816 static int
11817 api_ipsec_sa_set_key (vat_main_t * vam)
11818 {
11819   unformat_input_t *i = vam->input;
11820   vl_api_ipsec_sa_set_key_t *mp;
11821   f64 timeout;
11822   u32 sa_id;
11823   u8 *ck = 0, *ik = 0;
11824
11825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11826     {
11827       if (unformat (i, "sa_id %d", &sa_id))
11828         ;
11829       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11830         ;
11831       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11832         ;
11833       else
11834         {
11835           clib_warning ("parse error '%U'", format_unformat_error, i);
11836           return -99;
11837         }
11838     }
11839
11840   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11841
11842   mp->sa_id = ntohl (sa_id);
11843   mp->crypto_key_length = vec_len (ck);
11844   mp->integrity_key_length = vec_len (ik);
11845
11846   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11847     mp->crypto_key_length = sizeof (mp->crypto_key);
11848
11849   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11850     mp->integrity_key_length = sizeof (mp->integrity_key);
11851
11852   if (ck)
11853     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11854   if (ik)
11855     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11856
11857   S;
11858   W;
11859   /* NOTREACHED */
11860   return 0;
11861 }
11862
11863 static int
11864 api_ikev2_profile_add_del (vat_main_t * vam)
11865 {
11866   unformat_input_t *i = vam->input;
11867   vl_api_ikev2_profile_add_del_t *mp;
11868   f64 timeout;
11869   u8 is_add = 1;
11870   u8 *name = 0;
11871
11872   const char *valid_chars = "a-zA-Z0-9_";
11873
11874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11875     {
11876       if (unformat (i, "del"))
11877         is_add = 0;
11878       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11879         vec_add1 (name, 0);
11880       else
11881         {
11882           errmsg ("parse error '%U'", format_unformat_error, i);
11883           return -99;
11884         }
11885     }
11886
11887   if (!vec_len (name))
11888     {
11889       errmsg ("profile name must be specified");
11890       return -99;
11891     }
11892
11893   if (vec_len (name) > 64)
11894     {
11895       errmsg ("profile name too long");
11896       return -99;
11897     }
11898
11899   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11900
11901   clib_memcpy (mp->name, name, vec_len (name));
11902   mp->is_add = is_add;
11903   vec_free (name);
11904
11905   S;
11906   W;
11907   /* NOTREACHED */
11908   return 0;
11909 }
11910
11911 static int
11912 api_ikev2_profile_set_auth (vat_main_t * vam)
11913 {
11914   unformat_input_t *i = vam->input;
11915   vl_api_ikev2_profile_set_auth_t *mp;
11916   f64 timeout;
11917   u8 *name = 0;
11918   u8 *data = 0;
11919   u32 auth_method = 0;
11920   u8 is_hex = 0;
11921
11922   const char *valid_chars = "a-zA-Z0-9_";
11923
11924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11925     {
11926       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11927         vec_add1 (name, 0);
11928       else if (unformat (i, "auth_method %U",
11929                          unformat_ikev2_auth_method, &auth_method))
11930         ;
11931       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11932         is_hex = 1;
11933       else if (unformat (i, "auth_data %v", &data))
11934         ;
11935       else
11936         {
11937           errmsg ("parse error '%U'", format_unformat_error, i);
11938           return -99;
11939         }
11940     }
11941
11942   if (!vec_len (name))
11943     {
11944       errmsg ("profile name must be specified");
11945       return -99;
11946     }
11947
11948   if (vec_len (name) > 64)
11949     {
11950       errmsg ("profile name too long");
11951       return -99;
11952     }
11953
11954   if (!vec_len (data))
11955     {
11956       errmsg ("auth_data must be specified");
11957       return -99;
11958     }
11959
11960   if (!auth_method)
11961     {
11962       errmsg ("auth_method must be specified");
11963       return -99;
11964     }
11965
11966   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11967
11968   mp->is_hex = is_hex;
11969   mp->auth_method = (u8) auth_method;
11970   mp->data_len = vec_len (data);
11971   clib_memcpy (mp->name, name, vec_len (name));
11972   clib_memcpy (mp->data, data, vec_len (data));
11973   vec_free (name);
11974   vec_free (data);
11975
11976   S;
11977   W;
11978   /* NOTREACHED */
11979   return 0;
11980 }
11981
11982 static int
11983 api_ikev2_profile_set_id (vat_main_t * vam)
11984 {
11985   unformat_input_t *i = vam->input;
11986   vl_api_ikev2_profile_set_id_t *mp;
11987   f64 timeout;
11988   u8 *name = 0;
11989   u8 *data = 0;
11990   u8 is_local = 0;
11991   u32 id_type = 0;
11992   ip4_address_t ip4;
11993
11994   const char *valid_chars = "a-zA-Z0-9_";
11995
11996   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11997     {
11998       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11999         vec_add1 (name, 0);
12000       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12001         ;
12002       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12003         {
12004           data = vec_new (u8, 4);
12005           clib_memcpy (data, ip4.as_u8, 4);
12006         }
12007       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12008         ;
12009       else if (unformat (i, "id_data %v", &data))
12010         ;
12011       else if (unformat (i, "local"))
12012         is_local = 1;
12013       else if (unformat (i, "remote"))
12014         is_local = 0;
12015       else
12016         {
12017           errmsg ("parse error '%U'", format_unformat_error, i);
12018           return -99;
12019         }
12020     }
12021
12022   if (!vec_len (name))
12023     {
12024       errmsg ("profile name must be specified");
12025       return -99;
12026     }
12027
12028   if (vec_len (name) > 64)
12029     {
12030       errmsg ("profile name too long");
12031       return -99;
12032     }
12033
12034   if (!vec_len (data))
12035     {
12036       errmsg ("id_data must be specified");
12037       return -99;
12038     }
12039
12040   if (!id_type)
12041     {
12042       errmsg ("id_type must be specified");
12043       return -99;
12044     }
12045
12046   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12047
12048   mp->is_local = is_local;
12049   mp->id_type = (u8) id_type;
12050   mp->data_len = vec_len (data);
12051   clib_memcpy (mp->name, name, vec_len (name));
12052   clib_memcpy (mp->data, data, vec_len (data));
12053   vec_free (name);
12054   vec_free (data);
12055
12056   S;
12057   W;
12058   /* NOTREACHED */
12059   return 0;
12060 }
12061
12062 static int
12063 api_ikev2_profile_set_ts (vat_main_t * vam)
12064 {
12065   unformat_input_t *i = vam->input;
12066   vl_api_ikev2_profile_set_ts_t *mp;
12067   f64 timeout;
12068   u8 *name = 0;
12069   u8 is_local = 0;
12070   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12071   ip4_address_t start_addr, end_addr;
12072
12073   const char *valid_chars = "a-zA-Z0-9_";
12074
12075   start_addr.as_u32 = 0;
12076   end_addr.as_u32 = (u32) ~ 0;
12077
12078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12079     {
12080       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12081         vec_add1 (name, 0);
12082       else if (unformat (i, "protocol %d", &proto))
12083         ;
12084       else if (unformat (i, "start_port %d", &start_port))
12085         ;
12086       else if (unformat (i, "end_port %d", &end_port))
12087         ;
12088       else
12089         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12090         ;
12091       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12092         ;
12093       else if (unformat (i, "local"))
12094         is_local = 1;
12095       else if (unformat (i, "remote"))
12096         is_local = 0;
12097       else
12098         {
12099           errmsg ("parse error '%U'", format_unformat_error, i);
12100           return -99;
12101         }
12102     }
12103
12104   if (!vec_len (name))
12105     {
12106       errmsg ("profile name must be specified");
12107       return -99;
12108     }
12109
12110   if (vec_len (name) > 64)
12111     {
12112       errmsg ("profile name too long");
12113       return -99;
12114     }
12115
12116   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12117
12118   mp->is_local = is_local;
12119   mp->proto = (u8) proto;
12120   mp->start_port = (u16) start_port;
12121   mp->end_port = (u16) end_port;
12122   mp->start_addr = start_addr.as_u32;
12123   mp->end_addr = end_addr.as_u32;
12124   clib_memcpy (mp->name, name, vec_len (name));
12125   vec_free (name);
12126
12127   S;
12128   W;
12129   /* NOTREACHED */
12130   return 0;
12131 }
12132
12133 static int
12134 api_ikev2_set_local_key (vat_main_t * vam)
12135 {
12136   unformat_input_t *i = vam->input;
12137   vl_api_ikev2_set_local_key_t *mp;
12138   f64 timeout;
12139   u8 *file = 0;
12140
12141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12142     {
12143       if (unformat (i, "file %v", &file))
12144         vec_add1 (file, 0);
12145       else
12146         {
12147           errmsg ("parse error '%U'", format_unformat_error, i);
12148           return -99;
12149         }
12150     }
12151
12152   if (!vec_len (file))
12153     {
12154       errmsg ("RSA key file must be specified");
12155       return -99;
12156     }
12157
12158   if (vec_len (file) > 256)
12159     {
12160       errmsg ("file name too long");
12161       return -99;
12162     }
12163
12164   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12165
12166   clib_memcpy (mp->key_file, file, vec_len (file));
12167   vec_free (file);
12168
12169   S;
12170   W;
12171   /* NOTREACHED */
12172   return 0;
12173 }
12174
12175 /*
12176  * MAP
12177  */
12178 static int
12179 api_map_add_domain (vat_main_t * vam)
12180 {
12181   unformat_input_t *i = vam->input;
12182   vl_api_map_add_domain_t *mp;
12183   f64 timeout;
12184
12185   ip4_address_t ip4_prefix;
12186   ip6_address_t ip6_prefix;
12187   ip6_address_t ip6_src;
12188   u32 num_m_args = 0;
12189   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12190     0, psid_length = 0;
12191   u8 is_translation = 0;
12192   u32 mtu = 0;
12193   u32 ip6_src_len = 128;
12194
12195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12196     {
12197       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12198                     &ip4_prefix, &ip4_prefix_len))
12199         num_m_args++;
12200       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12201                          &ip6_prefix, &ip6_prefix_len))
12202         num_m_args++;
12203       else
12204         if (unformat
12205             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12206              &ip6_src_len))
12207         num_m_args++;
12208       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12209         num_m_args++;
12210       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12211         num_m_args++;
12212       else if (unformat (i, "psid-offset %d", &psid_offset))
12213         num_m_args++;
12214       else if (unformat (i, "psid-len %d", &psid_length))
12215         num_m_args++;
12216       else if (unformat (i, "mtu %d", &mtu))
12217         num_m_args++;
12218       else if (unformat (i, "map-t"))
12219         is_translation = 1;
12220       else
12221         {
12222           clib_warning ("parse error '%U'", format_unformat_error, i);
12223           return -99;
12224         }
12225     }
12226
12227   if (num_m_args < 3)
12228     {
12229       errmsg ("mandatory argument(s) missing\n");
12230       return -99;
12231     }
12232
12233   /* Construct the API message */
12234   M (MAP_ADD_DOMAIN, map_add_domain);
12235
12236   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12237   mp->ip4_prefix_len = ip4_prefix_len;
12238
12239   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12240   mp->ip6_prefix_len = ip6_prefix_len;
12241
12242   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12243   mp->ip6_src_prefix_len = ip6_src_len;
12244
12245   mp->ea_bits_len = ea_bits_len;
12246   mp->psid_offset = psid_offset;
12247   mp->psid_length = psid_length;
12248   mp->is_translation = is_translation;
12249   mp->mtu = htons (mtu);
12250
12251   /* send it... */
12252   S;
12253
12254   /* Wait for a reply, return good/bad news  */
12255   W;
12256 }
12257
12258 static int
12259 api_map_del_domain (vat_main_t * vam)
12260 {
12261   unformat_input_t *i = vam->input;
12262   vl_api_map_del_domain_t *mp;
12263   f64 timeout;
12264
12265   u32 num_m_args = 0;
12266   u32 index;
12267
12268   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12269     {
12270       if (unformat (i, "index %d", &index))
12271         num_m_args++;
12272       else
12273         {
12274           clib_warning ("parse error '%U'", format_unformat_error, i);
12275           return -99;
12276         }
12277     }
12278
12279   if (num_m_args != 1)
12280     {
12281       errmsg ("mandatory argument(s) missing\n");
12282       return -99;
12283     }
12284
12285   /* Construct the API message */
12286   M (MAP_DEL_DOMAIN, map_del_domain);
12287
12288   mp->index = ntohl (index);
12289
12290   /* send it... */
12291   S;
12292
12293   /* Wait for a reply, return good/bad news  */
12294   W;
12295 }
12296
12297 static int
12298 api_map_add_del_rule (vat_main_t * vam)
12299 {
12300   unformat_input_t *i = vam->input;
12301   vl_api_map_add_del_rule_t *mp;
12302   f64 timeout;
12303   u8 is_add = 1;
12304   ip6_address_t ip6_dst;
12305   u32 num_m_args = 0, index, psid = 0;
12306
12307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12308     {
12309       if (unformat (i, "index %d", &index))
12310         num_m_args++;
12311       else if (unformat (i, "psid %d", &psid))
12312         num_m_args++;
12313       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12314         num_m_args++;
12315       else if (unformat (i, "del"))
12316         {
12317           is_add = 0;
12318         }
12319       else
12320         {
12321           clib_warning ("parse error '%U'", format_unformat_error, i);
12322           return -99;
12323         }
12324     }
12325
12326   /* Construct the API message */
12327   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12328
12329   mp->index = ntohl (index);
12330   mp->is_add = is_add;
12331   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12332   mp->psid = ntohs (psid);
12333
12334   /* send it... */
12335   S;
12336
12337   /* Wait for a reply, return good/bad news  */
12338   W;
12339 }
12340
12341 static int
12342 api_map_domain_dump (vat_main_t * vam)
12343 {
12344   vl_api_map_domain_dump_t *mp;
12345   f64 timeout;
12346
12347   /* Construct the API message */
12348   M (MAP_DOMAIN_DUMP, map_domain_dump);
12349
12350   /* send it... */
12351   S;
12352
12353   /* Use a control ping for synchronization */
12354   {
12355     vl_api_control_ping_t *mp;
12356     M (CONTROL_PING, control_ping);
12357     S;
12358   }
12359   W;
12360 }
12361
12362 static int
12363 api_map_rule_dump (vat_main_t * vam)
12364 {
12365   unformat_input_t *i = vam->input;
12366   vl_api_map_rule_dump_t *mp;
12367   f64 timeout;
12368   u32 domain_index = ~0;
12369
12370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12371     {
12372       if (unformat (i, "index %u", &domain_index))
12373         ;
12374       else
12375         break;
12376     }
12377
12378   if (domain_index == ~0)
12379     {
12380       clib_warning ("parse error: domain index expected");
12381       return -99;
12382     }
12383
12384   /* Construct the API message */
12385   M (MAP_RULE_DUMP, map_rule_dump);
12386
12387   mp->domain_index = htonl (domain_index);
12388
12389   /* send it... */
12390   S;
12391
12392   /* Use a control ping for synchronization */
12393   {
12394     vl_api_control_ping_t *mp;
12395     M (CONTROL_PING, control_ping);
12396     S;
12397   }
12398   W;
12399 }
12400
12401 static void vl_api_map_add_domain_reply_t_handler
12402   (vl_api_map_add_domain_reply_t * mp)
12403 {
12404   vat_main_t *vam = &vat_main;
12405   i32 retval = ntohl (mp->retval);
12406
12407   if (vam->async_mode)
12408     {
12409       vam->async_errors += (retval < 0);
12410     }
12411   else
12412     {
12413       vam->retval = retval;
12414       vam->result_ready = 1;
12415     }
12416 }
12417
12418 static void vl_api_map_add_domain_reply_t_handler_json
12419   (vl_api_map_add_domain_reply_t * mp)
12420 {
12421   vat_main_t *vam = &vat_main;
12422   vat_json_node_t node;
12423
12424   vat_json_init_object (&node);
12425   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12426   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12427
12428   vat_json_print (vam->ofp, &node);
12429   vat_json_free (&node);
12430
12431   vam->retval = ntohl (mp->retval);
12432   vam->result_ready = 1;
12433 }
12434
12435 static int
12436 api_get_first_msg_id (vat_main_t * vam)
12437 {
12438   vl_api_get_first_msg_id_t *mp;
12439   f64 timeout;
12440   unformat_input_t *i = vam->input;
12441   u8 *name;
12442   u8 name_set = 0;
12443
12444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12445     {
12446       if (unformat (i, "client %s", &name))
12447         name_set = 1;
12448       else
12449         break;
12450     }
12451
12452   if (name_set == 0)
12453     {
12454       errmsg ("missing client name\n");
12455       return -99;
12456     }
12457   vec_add1 (name, 0);
12458
12459   if (vec_len (name) > 63)
12460     {
12461       errmsg ("client name too long\n");
12462       return -99;
12463     }
12464
12465   M (GET_FIRST_MSG_ID, get_first_msg_id);
12466   clib_memcpy (mp->name, name, vec_len (name));
12467   S;
12468   W;
12469   /* NOTREACHED */
12470   return 0;
12471 }
12472
12473 static int
12474 api_cop_interface_enable_disable (vat_main_t * vam)
12475 {
12476   unformat_input_t *line_input = vam->input;
12477   vl_api_cop_interface_enable_disable_t *mp;
12478   f64 timeout;
12479   u32 sw_if_index = ~0;
12480   u8 enable_disable = 1;
12481
12482   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12483     {
12484       if (unformat (line_input, "disable"))
12485         enable_disable = 0;
12486       if (unformat (line_input, "enable"))
12487         enable_disable = 1;
12488       else if (unformat (line_input, "%U", unformat_sw_if_index,
12489                          vam, &sw_if_index))
12490         ;
12491       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12492         ;
12493       else
12494         break;
12495     }
12496
12497   if (sw_if_index == ~0)
12498     {
12499       errmsg ("missing interface name or sw_if_index\n");
12500       return -99;
12501     }
12502
12503   /* Construct the API message */
12504   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12505   mp->sw_if_index = ntohl (sw_if_index);
12506   mp->enable_disable = enable_disable;
12507
12508   /* send it... */
12509   S;
12510   /* Wait for the reply */
12511   W;
12512 }
12513
12514 static int
12515 api_cop_whitelist_enable_disable (vat_main_t * vam)
12516 {
12517   unformat_input_t *line_input = vam->input;
12518   vl_api_cop_whitelist_enable_disable_t *mp;
12519   f64 timeout;
12520   u32 sw_if_index = ~0;
12521   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12522   u32 fib_id = 0;
12523
12524   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12525     {
12526       if (unformat (line_input, "ip4"))
12527         ip4 = 1;
12528       else if (unformat (line_input, "ip6"))
12529         ip6 = 1;
12530       else if (unformat (line_input, "default"))
12531         default_cop = 1;
12532       else if (unformat (line_input, "%U", unformat_sw_if_index,
12533                          vam, &sw_if_index))
12534         ;
12535       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12536         ;
12537       else if (unformat (line_input, "fib-id %d", &fib_id))
12538         ;
12539       else
12540         break;
12541     }
12542
12543   if (sw_if_index == ~0)
12544     {
12545       errmsg ("missing interface name or sw_if_index\n");
12546       return -99;
12547     }
12548
12549   /* Construct the API message */
12550   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12551   mp->sw_if_index = ntohl (sw_if_index);
12552   mp->fib_id = ntohl (fib_id);
12553   mp->ip4 = ip4;
12554   mp->ip6 = ip6;
12555   mp->default_cop = default_cop;
12556
12557   /* send it... */
12558   S;
12559   /* Wait for the reply */
12560   W;
12561 }
12562
12563 static int
12564 api_get_node_graph (vat_main_t * vam)
12565 {
12566   vl_api_get_node_graph_t *mp;
12567   f64 timeout;
12568
12569   M (GET_NODE_GRAPH, get_node_graph);
12570
12571   /* send it... */
12572   S;
12573   /* Wait for the reply */
12574   W;
12575 }
12576
12577 /* *INDENT-OFF* */
12578 /** Used for parsing LISP eids */
12579 typedef CLIB_PACKED(struct{
12580   u8 addr[16];   /**< eid address */
12581   u32 len;       /**< prefix length if IP */
12582   u8 type;      /**< type of eid */
12583 }) lisp_eid_vat_t;
12584 /* *INDENT-ON* */
12585
12586 static uword
12587 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12588 {
12589   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12590
12591   memset (a, 0, sizeof (a[0]));
12592
12593   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12594     {
12595       a->type = 0;              /* ipv4 type */
12596     }
12597   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12598     {
12599       a->type = 1;              /* ipv6 type */
12600     }
12601   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12602     {
12603       a->type = 2;              /* mac type */
12604     }
12605   else
12606     {
12607       return 0;
12608     }
12609
12610   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12611     {
12612       return 0;
12613     }
12614
12615   return 1;
12616 }
12617
12618 static int
12619 lisp_eid_size_vat (u8 type)
12620 {
12621   switch (type)
12622     {
12623     case 0:
12624       return 4;
12625     case 1:
12626       return 16;
12627     case 2:
12628       return 6;
12629     }
12630   return 0;
12631 }
12632
12633 static void
12634 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12635 {
12636   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12637 }
12638
12639 /* *INDENT-OFF* */
12640 /** Used for transferring locators via VPP API */
12641 typedef CLIB_PACKED(struct
12642 {
12643   u32 sw_if_index; /**< locator sw_if_index */
12644   u8 priority; /**< locator priority */
12645   u8 weight;   /**< locator weight */
12646 }) ls_locator_t;
12647 /* *INDENT-ON* */
12648
12649 static int
12650 api_lisp_add_del_locator_set (vat_main_t * vam)
12651 {
12652   unformat_input_t *input = vam->input;
12653   vl_api_lisp_add_del_locator_set_t *mp;
12654   f64 timeout = ~0;
12655   u8 is_add = 1;
12656   u8 *locator_set_name = NULL;
12657   u8 locator_set_name_set = 0;
12658   ls_locator_t locator, *locators = 0;
12659   u32 sw_if_index, priority, weight;
12660   u32 data_len = 0;
12661
12662   /* Parse args required to build the message */
12663   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12664     {
12665       if (unformat (input, "del"))
12666         {
12667           is_add = 0;
12668         }
12669       else if (unformat (input, "locator-set %s", &locator_set_name))
12670         {
12671           locator_set_name_set = 1;
12672         }
12673       else if (unformat (input, "sw_if_index %u p %u w %u",
12674                          &sw_if_index, &priority, &weight))
12675         {
12676           locator.sw_if_index = htonl (sw_if_index);
12677           locator.priority = priority;
12678           locator.weight = weight;
12679           vec_add1 (locators, locator);
12680         }
12681       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12682                          vam, &sw_if_index, &priority, &weight))
12683         {
12684           locator.sw_if_index = htonl (sw_if_index);
12685           locator.priority = priority;
12686           locator.weight = weight;
12687           vec_add1 (locators, locator);
12688         }
12689       else
12690         break;
12691     }
12692
12693   if (locator_set_name_set == 0)
12694     {
12695       errmsg ("missing locator-set name");
12696       vec_free (locators);
12697       return -99;
12698     }
12699
12700   if (vec_len (locator_set_name) > 64)
12701     {
12702       errmsg ("locator-set name too long\n");
12703       vec_free (locator_set_name);
12704       vec_free (locators);
12705       return -99;
12706     }
12707   vec_add1 (locator_set_name, 0);
12708
12709   data_len = sizeof (ls_locator_t) * vec_len (locators);
12710
12711   /* Construct the API message */
12712   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12713
12714   mp->is_add = is_add;
12715   clib_memcpy (mp->locator_set_name, locator_set_name,
12716                vec_len (locator_set_name));
12717   vec_free (locator_set_name);
12718
12719   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12720   if (locators)
12721     clib_memcpy (mp->locators, locators, data_len);
12722   vec_free (locators);
12723
12724   /* send it... */
12725   S;
12726
12727   /* Wait for a reply... */
12728   W;
12729
12730   /* NOTREACHED */
12731   return 0;
12732 }
12733
12734 static int
12735 api_lisp_add_del_locator (vat_main_t * vam)
12736 {
12737   unformat_input_t *input = vam->input;
12738   vl_api_lisp_add_del_locator_t *mp;
12739   f64 timeout = ~0;
12740   u32 tmp_if_index = ~0;
12741   u32 sw_if_index = ~0;
12742   u8 sw_if_index_set = 0;
12743   u8 sw_if_index_if_name_set = 0;
12744   u32 priority = ~0;
12745   u8 priority_set = 0;
12746   u32 weight = ~0;
12747   u8 weight_set = 0;
12748   u8 is_add = 1;
12749   u8 *locator_set_name = NULL;
12750   u8 locator_set_name_set = 0;
12751
12752   /* Parse args required to build the message */
12753   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12754     {
12755       if (unformat (input, "del"))
12756         {
12757           is_add = 0;
12758         }
12759       else if (unformat (input, "locator-set %s", &locator_set_name))
12760         {
12761           locator_set_name_set = 1;
12762         }
12763       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12764                          &tmp_if_index))
12765         {
12766           sw_if_index_if_name_set = 1;
12767           sw_if_index = tmp_if_index;
12768         }
12769       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12770         {
12771           sw_if_index_set = 1;
12772           sw_if_index = tmp_if_index;
12773         }
12774       else if (unformat (input, "p %d", &priority))
12775         {
12776           priority_set = 1;
12777         }
12778       else if (unformat (input, "w %d", &weight))
12779         {
12780           weight_set = 1;
12781         }
12782       else
12783         break;
12784     }
12785
12786   if (locator_set_name_set == 0)
12787     {
12788       errmsg ("missing locator-set name");
12789       return -99;
12790     }
12791
12792   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12793     {
12794       errmsg ("missing sw_if_index");
12795       vec_free (locator_set_name);
12796       return -99;
12797     }
12798
12799   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12800     {
12801       errmsg ("cannot use both params interface name and sw_if_index");
12802       vec_free (locator_set_name);
12803       return -99;
12804     }
12805
12806   if (priority_set == 0)
12807     {
12808       errmsg ("missing locator-set priority\n");
12809       vec_free (locator_set_name);
12810       return -99;
12811     }
12812
12813   if (weight_set == 0)
12814     {
12815       errmsg ("missing locator-set weight\n");
12816       vec_free (locator_set_name);
12817       return -99;
12818     }
12819
12820   if (vec_len (locator_set_name) > 64)
12821     {
12822       errmsg ("locator-set name too long\n");
12823       vec_free (locator_set_name);
12824       return -99;
12825     }
12826   vec_add1 (locator_set_name, 0);
12827
12828   /* Construct the API message */
12829   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12830
12831   mp->is_add = is_add;
12832   mp->sw_if_index = ntohl (sw_if_index);
12833   mp->priority = priority;
12834   mp->weight = weight;
12835   clib_memcpy (mp->locator_set_name, locator_set_name,
12836                vec_len (locator_set_name));
12837   vec_free (locator_set_name);
12838
12839   /* send it... */
12840   S;
12841
12842   /* Wait for a reply... */
12843   W;
12844
12845   /* NOTREACHED */
12846   return 0;
12847 }
12848
12849 static int
12850 api_lisp_add_del_local_eid (vat_main_t * vam)
12851 {
12852   unformat_input_t *input = vam->input;
12853   vl_api_lisp_add_del_local_eid_t *mp;
12854   f64 timeout = ~0;
12855   u8 is_add = 1;
12856   u8 eid_set = 0;
12857   lisp_eid_vat_t _eid, *eid = &_eid;
12858   u8 *locator_set_name = 0;
12859   u8 locator_set_name_set = 0;
12860   u32 vni = 0;
12861
12862   /* Parse args required to build the message */
12863   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12864     {
12865       if (unformat (input, "del"))
12866         {
12867           is_add = 0;
12868         }
12869       else if (unformat (input, "vni %d", &vni))
12870         {
12871           ;
12872         }
12873       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12874         {
12875           eid_set = 1;
12876         }
12877       else if (unformat (input, "locator-set %s", &locator_set_name))
12878         {
12879           locator_set_name_set = 1;
12880         }
12881       else
12882         break;
12883     }
12884
12885   if (locator_set_name_set == 0)
12886     {
12887       errmsg ("missing locator-set name\n");
12888       return -99;
12889     }
12890
12891   if (0 == eid_set)
12892     {
12893       errmsg ("EID address not set!");
12894       vec_free (locator_set_name);
12895       return -99;
12896     }
12897
12898   if (vec_len (locator_set_name) > 64)
12899     {
12900       errmsg ("locator-set name too long\n");
12901       vec_free (locator_set_name);
12902       return -99;
12903     }
12904   vec_add1 (locator_set_name, 0);
12905
12906   /* Construct the API message */
12907   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12908
12909   mp->is_add = is_add;
12910   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12911   mp->eid_type = eid->type;
12912   mp->prefix_len = eid->len;
12913   mp->vni = clib_host_to_net_u32 (vni);
12914   clib_memcpy (mp->locator_set_name, locator_set_name,
12915                vec_len (locator_set_name));
12916
12917   vec_free (locator_set_name);
12918
12919   /* send it... */
12920   S;
12921
12922   /* Wait for a reply... */
12923   W;
12924
12925   /* NOTREACHED */
12926   return 0;
12927 }
12928
12929 /* *INDENT-OFF* */
12930 /** Used for transferring locators via VPP API */
12931 typedef CLIB_PACKED(struct
12932 {
12933   u8 is_ip4; /**< is locator an IPv4 address? */
12934   u8 priority; /**< locator priority */
12935   u8 weight;   /**< locator weight */
12936   u8 addr[16]; /**< IPv4/IPv6 address */
12937 }) rloc_t;
12938 /* *INDENT-ON* */
12939
12940 static int
12941 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12942 {
12943   unformat_input_t *input = vam->input;
12944   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12945   f64 timeout = ~0;
12946   u8 is_add = 1;
12947   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12948   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12949   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12950   u32 action = ~0, p, w;
12951   ip4_address_t rmt_rloc4, lcl_rloc4;
12952   ip6_address_t rmt_rloc6, lcl_rloc6;
12953   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12954
12955   memset (&rloc, 0, sizeof (rloc));
12956
12957   /* Parse args required to build the message */
12958   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12959     {
12960       if (unformat (input, "del"))
12961         {
12962           is_add = 0;
12963         }
12964       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12965         {
12966           rmt_eid_set = 1;
12967         }
12968       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12969         {
12970           lcl_eid_set = 1;
12971         }
12972       else if (unformat (input, "p %d w %d", &p, &w))
12973         {
12974           if (!curr_rloc)
12975             {
12976               errmsg ("No RLOC configured for setting priority/weight!");
12977               return -99;
12978             }
12979           curr_rloc->priority = p;
12980           curr_rloc->weight = w;
12981         }
12982       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12983                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12984         {
12985           rloc.is_ip4 = 1;
12986
12987           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12988           rloc.priority = rloc.weight = 0;
12989           vec_add1 (lcl_locs, rloc);
12990
12991           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12992           vec_add1 (rmt_locs, rloc);
12993           /* priority and weight saved in rmt loc */
12994           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12995         }
12996       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12997                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12998         {
12999           rloc.is_ip4 = 0;
13000           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13001           rloc.priority = rloc.weight = 0;
13002           vec_add1 (lcl_locs, rloc);
13003
13004           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13005           vec_add1 (rmt_locs, rloc);
13006           /* priority and weight saved in rmt loc */
13007           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13008         }
13009       else if (unformat (input, "action %d", &action))
13010         {
13011           ;
13012         }
13013       else
13014         {
13015           clib_warning ("parse error '%U'", format_unformat_error, input);
13016           return -99;
13017         }
13018     }
13019
13020   if (!rmt_eid_set)
13021     {
13022       errmsg ("remote eid addresses not set\n");
13023       return -99;
13024     }
13025
13026   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13027     {
13028       errmsg ("eid types don't match\n");
13029       return -99;
13030     }
13031
13032   if (0 == rmt_locs && (u32) ~ 0 == action)
13033     {
13034       errmsg ("action not set for negative mapping\n");
13035       return -99;
13036     }
13037
13038   /* Construct the API message */
13039   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13040
13041   mp->is_add = is_add;
13042   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13043   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13044   mp->eid_type = rmt_eid->type;
13045   mp->rmt_len = rmt_eid->len;
13046   mp->lcl_len = lcl_eid->len;
13047   mp->action = action;
13048
13049   if (0 != rmt_locs && 0 != lcl_locs)
13050     {
13051       mp->loc_num = vec_len (rmt_locs);
13052       clib_memcpy (mp->lcl_locs, lcl_locs,
13053                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13054       clib_memcpy (mp->rmt_locs, rmt_locs,
13055                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13056     }
13057   vec_free (lcl_locs);
13058   vec_free (rmt_locs);
13059
13060   /* send it... */
13061   S;
13062
13063   /* Wait for a reply... */
13064   W;
13065
13066   /* NOTREACHED */
13067   return 0;
13068 }
13069
13070 static int
13071 api_lisp_add_del_map_resolver (vat_main_t * vam)
13072 {
13073   unformat_input_t *input = vam->input;
13074   vl_api_lisp_add_del_map_resolver_t *mp;
13075   f64 timeout = ~0;
13076   u8 is_add = 1;
13077   u8 ipv4_set = 0;
13078   u8 ipv6_set = 0;
13079   ip4_address_t ipv4;
13080   ip6_address_t ipv6;
13081
13082   /* Parse args required to build the message */
13083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13084     {
13085       if (unformat (input, "del"))
13086         {
13087           is_add = 0;
13088         }
13089       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13090         {
13091           ipv4_set = 1;
13092         }
13093       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13094         {
13095           ipv6_set = 1;
13096         }
13097       else
13098         break;
13099     }
13100
13101   if (ipv4_set && ipv6_set)
13102     {
13103       errmsg ("both eid v4 and v6 addresses set\n");
13104       return -99;
13105     }
13106
13107   if (!ipv4_set && !ipv6_set)
13108     {
13109       errmsg ("eid addresses not set\n");
13110       return -99;
13111     }
13112
13113   /* Construct the API message */
13114   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13115
13116   mp->is_add = is_add;
13117   if (ipv6_set)
13118     {
13119       mp->is_ipv6 = 1;
13120       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13121     }
13122   else
13123     {
13124       mp->is_ipv6 = 0;
13125       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13126     }
13127
13128   /* send it... */
13129   S;
13130
13131   /* Wait for a reply... */
13132   W;
13133
13134   /* NOTREACHED */
13135   return 0;
13136 }
13137
13138 static int
13139 api_lisp_gpe_enable_disable (vat_main_t * vam)
13140 {
13141   unformat_input_t *input = vam->input;
13142   vl_api_lisp_gpe_enable_disable_t *mp;
13143   f64 timeout = ~0;
13144   u8 is_set = 0;
13145   u8 is_en = 1;
13146
13147   /* Parse args required to build the message */
13148   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13149     {
13150       if (unformat (input, "enable"))
13151         {
13152           is_set = 1;
13153           is_en = 1;
13154         }
13155       else if (unformat (input, "disable"))
13156         {
13157           is_set = 1;
13158           is_en = 0;
13159         }
13160       else
13161         break;
13162     }
13163
13164   if (is_set == 0)
13165     {
13166       errmsg ("Value not set\n");
13167       return -99;
13168     }
13169
13170   /* Construct the API message */
13171   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13172
13173   mp->is_en = is_en;
13174
13175   /* send it... */
13176   S;
13177
13178   /* Wait for a reply... */
13179   W;
13180
13181   /* NOTREACHED */
13182   return 0;
13183 }
13184
13185 static int
13186 api_lisp_enable_disable (vat_main_t * vam)
13187 {
13188   unformat_input_t *input = vam->input;
13189   vl_api_lisp_enable_disable_t *mp;
13190   f64 timeout = ~0;
13191   u8 is_set = 0;
13192   u8 is_en = 0;
13193
13194   /* Parse args required to build the message */
13195   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13196     {
13197       if (unformat (input, "enable"))
13198         {
13199           is_set = 1;
13200           is_en = 1;
13201         }
13202       else if (unformat (input, "disable"))
13203         {
13204           is_set = 1;
13205         }
13206       else
13207         break;
13208     }
13209
13210   if (!is_set)
13211     {
13212       errmsg ("Value not set\n");
13213       return -99;
13214     }
13215
13216   /* Construct the API message */
13217   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13218
13219   mp->is_en = is_en;
13220
13221   /* send it... */
13222   S;
13223
13224   /* Wait for a reply... */
13225   W;
13226
13227   /* NOTREACHED */
13228   return 0;
13229 }
13230
13231 static int
13232 api_show_lisp_map_request_mode (vat_main_t * vam)
13233 {
13234   f64 timeout = ~0;
13235   vl_api_show_lisp_map_request_mode_t *mp;
13236
13237   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13238
13239   /* send */
13240   S;
13241
13242   /* wait for reply */
13243   W;
13244
13245   return 0;
13246 }
13247
13248 static int
13249 api_lisp_map_request_mode (vat_main_t * vam)
13250 {
13251   f64 timeout = ~0;
13252   unformat_input_t *input = vam->input;
13253   vl_api_lisp_map_request_mode_t *mp;
13254   u8 mode = 0;
13255
13256   /* Parse args required to build the message */
13257   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13258     {
13259       if (unformat (input, "dst-only"))
13260         mode = 0;
13261       else if (unformat (input, "src-dst"))
13262         mode = 1;
13263       else
13264         {
13265           errmsg ("parse error '%U'", format_unformat_error, input);
13266           return -99;
13267         }
13268     }
13269
13270   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13271
13272   mp->mode = mode;
13273
13274   /* send */
13275   S;
13276
13277   /* wait for reply */
13278   W;
13279
13280   /* notreached */
13281   return 0;
13282 }
13283
13284 /**
13285  * Enable/disable LISP proxy ITR.
13286  *
13287  * @param vam vpp API test context
13288  * @return return code
13289  */
13290 static int
13291 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13292 {
13293   f64 timeout = ~0;
13294   u8 ls_name_set = 0;
13295   unformat_input_t *input = vam->input;
13296   vl_api_lisp_pitr_set_locator_set_t *mp;
13297   u8 is_add = 1;
13298   u8 *ls_name = 0;
13299
13300   /* Parse args required to build the message */
13301   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13302     {
13303       if (unformat (input, "del"))
13304         is_add = 0;
13305       else if (unformat (input, "locator-set %s", &ls_name))
13306         ls_name_set = 1;
13307       else
13308         {
13309           errmsg ("parse error '%U'", format_unformat_error, input);
13310           return -99;
13311         }
13312     }
13313
13314   if (!ls_name_set)
13315     {
13316       errmsg ("locator-set name not set!");
13317       return -99;
13318     }
13319
13320   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13321
13322   mp->is_add = is_add;
13323   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13324   vec_free (ls_name);
13325
13326   /* send */
13327   S;
13328
13329   /* wait for reply */
13330   W;
13331
13332   /* notreached */
13333   return 0;
13334 }
13335
13336 static int
13337 api_show_lisp_pitr (vat_main_t * vam)
13338 {
13339   vl_api_show_lisp_pitr_t *mp;
13340   f64 timeout = ~0;
13341
13342   if (!vam->json_output)
13343     {
13344       fformat (vam->ofp, "%=20s\n", "lisp status:");
13345     }
13346
13347   M (SHOW_LISP_PITR, show_lisp_pitr);
13348   /* send it... */
13349   S;
13350
13351   /* Wait for a reply... */
13352   W;
13353
13354   /* NOTREACHED */
13355   return 0;
13356 }
13357
13358 /**
13359  * Add/delete mapping between vni and vrf
13360  */
13361 static int
13362 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13363 {
13364   f64 timeout = ~0;
13365   unformat_input_t *input = vam->input;
13366   vl_api_lisp_eid_table_add_del_map_t *mp;
13367   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13368   u32 vni, vrf, bd_index;
13369
13370   /* Parse args required to build the message */
13371   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13372     {
13373       if (unformat (input, "del"))
13374         is_add = 0;
13375       else if (unformat (input, "vrf %d", &vrf))
13376         vrf_set = 1;
13377       else if (unformat (input, "bd_index %d", &bd_index))
13378         bd_index_set = 1;
13379       else if (unformat (input, "vni %d", &vni))
13380         vni_set = 1;
13381       else
13382         break;
13383     }
13384
13385   if (!vni_set || (!vrf_set && !bd_index_set))
13386     {
13387       errmsg ("missing arguments!");
13388       return -99;
13389     }
13390
13391   if (vrf_set && bd_index_set)
13392     {
13393       errmsg ("error: both vrf and bd entered!");
13394       return -99;
13395     }
13396
13397   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13398
13399   mp->is_add = is_add;
13400   mp->vni = htonl (vni);
13401   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13402   mp->is_l2 = bd_index_set;
13403
13404   /* send */
13405   S;
13406
13407   /* wait for reply */
13408   W;
13409
13410   /* notreached */
13411   return 0;
13412 }
13413
13414 uword
13415 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13416 {
13417   u32 *action = va_arg (*args, u32 *);
13418   u8 *s = 0;
13419
13420   if (unformat (input, "%s", &s))
13421     {
13422       if (!strcmp ((char *) s, "no-action"))
13423         action[0] = 0;
13424       else if (!strcmp ((char *) s, "natively-forward"))
13425         action[0] = 1;
13426       else if (!strcmp ((char *) s, "send-map-request"))
13427         action[0] = 2;
13428       else if (!strcmp ((char *) s, "drop"))
13429         action[0] = 3;
13430       else
13431         {
13432           clib_warning ("invalid action: '%s'", s);
13433           action[0] = 3;
13434         }
13435     }
13436   else
13437     return 0;
13438
13439   vec_free (s);
13440   return 1;
13441 }
13442
13443 /**
13444  * Add/del remote mapping to/from LISP control plane
13445  *
13446  * @param vam vpp API test context
13447  * @return return code
13448  */
13449 static int
13450 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13451 {
13452   unformat_input_t *input = vam->input;
13453   vl_api_lisp_add_del_remote_mapping_t *mp;
13454   f64 timeout = ~0;
13455   u32 vni = 0;
13456   lisp_eid_vat_t _eid, *eid = &_eid;
13457   lisp_eid_vat_t _seid, *seid = &_seid;
13458   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13459   u32 action = ~0, p, w, data_len;
13460   ip4_address_t rloc4;
13461   ip6_address_t rloc6;
13462   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13463
13464   memset (&rloc, 0, sizeof (rloc));
13465
13466   /* Parse args required to build the message */
13467   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13468     {
13469       if (unformat (input, "del-all"))
13470         {
13471           del_all = 1;
13472         }
13473       else if (unformat (input, "del"))
13474         {
13475           is_add = 0;
13476         }
13477       else if (unformat (input, "add"))
13478         {
13479           is_add = 1;
13480         }
13481       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13482         {
13483           eid_set = 1;
13484         }
13485       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13486         {
13487           seid_set = 1;
13488         }
13489       else if (unformat (input, "vni %d", &vni))
13490         {
13491           ;
13492         }
13493       else if (unformat (input, "p %d w %d", &p, &w))
13494         {
13495           if (!curr_rloc)
13496             {
13497               errmsg ("No RLOC configured for setting priority/weight!");
13498               return -99;
13499             }
13500           curr_rloc->priority = p;
13501           curr_rloc->weight = w;
13502         }
13503       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13504         {
13505           rloc.is_ip4 = 1;
13506           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13507           vec_add1 (rlocs, rloc);
13508           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13509         }
13510       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13511         {
13512           rloc.is_ip4 = 0;
13513           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13514           vec_add1 (rlocs, rloc);
13515           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13516         }
13517       else if (unformat (input, "action %U",
13518                          unformat_negative_mapping_action, &action))
13519         {
13520           ;
13521         }
13522       else
13523         {
13524           clib_warning ("parse error '%U'", format_unformat_error, input);
13525           return -99;
13526         }
13527     }
13528
13529   if (0 == eid_set)
13530     {
13531       errmsg ("missing params!");
13532       return -99;
13533     }
13534
13535   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13536     {
13537       errmsg ("no action set for negative map-reply!");
13538       return -99;
13539     }
13540
13541   data_len = vec_len (rlocs) * sizeof (rloc_t);
13542
13543   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13544   mp->is_add = is_add;
13545   mp->vni = htonl (vni);
13546   mp->action = (u8) action;
13547   mp->is_src_dst = seid_set;
13548   mp->eid_len = eid->len;
13549   mp->seid_len = seid->len;
13550   mp->del_all = del_all;
13551   mp->eid_type = eid->type;
13552   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13553   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13554
13555   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13556   clib_memcpy (mp->rlocs, rlocs, data_len);
13557   vec_free (rlocs);
13558
13559   /* send it... */
13560   S;
13561
13562   /* Wait for a reply... */
13563   W;
13564
13565   /* NOTREACHED */
13566   return 0;
13567 }
13568
13569 /**
13570  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13571  * forwarding entries in data-plane accordingly.
13572  *
13573  * @param vam vpp API test context
13574  * @return return code
13575  */
13576 static int
13577 api_lisp_add_del_adjacency (vat_main_t * vam)
13578 {
13579   unformat_input_t *input = vam->input;
13580   vl_api_lisp_add_del_adjacency_t *mp;
13581   f64 timeout = ~0;
13582   u32 vni = 0;
13583   ip4_address_t leid4, reid4;
13584   ip6_address_t leid6, reid6;
13585   u8 reid_mac[6] = { 0 };
13586   u8 leid_mac[6] = { 0 };
13587   u8 reid_type, leid_type;
13588   u32 leid_len = 0, reid_len = 0, len;
13589   u8 is_add = 1;
13590
13591   leid_type = reid_type = (u8) ~ 0;
13592
13593   /* Parse args required to build the message */
13594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13595     {
13596       if (unformat (input, "del"))
13597         {
13598           is_add = 0;
13599         }
13600       else if (unformat (input, "add"))
13601         {
13602           is_add = 1;
13603         }
13604       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13605                          &reid4, &len))
13606         {
13607           reid_type = 0;        /* ipv4 */
13608           reid_len = len;
13609         }
13610       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13611                          &reid6, &len))
13612         {
13613           reid_type = 1;        /* ipv6 */
13614           reid_len = len;
13615         }
13616       else if (unformat (input, "reid %U", unformat_ethernet_address,
13617                          reid_mac))
13618         {
13619           reid_type = 2;        /* mac */
13620         }
13621       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13622                          &leid4, &len))
13623         {
13624           leid_type = 0;        /* ipv4 */
13625           leid_len = len;
13626         }
13627       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13628                          &leid6, &len))
13629         {
13630           leid_type = 1;        /* ipv6 */
13631           leid_len = len;
13632         }
13633       else if (unformat (input, "leid %U", unformat_ethernet_address,
13634                          leid_mac))
13635         {
13636           leid_type = 2;        /* mac */
13637         }
13638       else if (unformat (input, "vni %d", &vni))
13639         {
13640           ;
13641         }
13642       else
13643         {
13644           errmsg ("parse error '%U'", format_unformat_error, input);
13645           return -99;
13646         }
13647     }
13648
13649   if ((u8) ~ 0 == reid_type)
13650     {
13651       errmsg ("missing params!");
13652       return -99;
13653     }
13654
13655   if (leid_type != reid_type)
13656     {
13657       errmsg ("remote and local EIDs are of different types!");
13658       return -99;
13659     }
13660
13661   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13662   mp->is_add = is_add;
13663   mp->vni = htonl (vni);
13664   mp->leid_len = leid_len;
13665   mp->reid_len = reid_len;
13666   mp->eid_type = reid_type;
13667
13668   switch (mp->eid_type)
13669     {
13670     case 0:
13671       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13672       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13673       break;
13674     case 1:
13675       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13676       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13677       break;
13678     case 2:
13679       clib_memcpy (mp->leid, leid_mac, 6);
13680       clib_memcpy (mp->reid, reid_mac, 6);
13681       break;
13682     default:
13683       errmsg ("unknown EID type %d!", mp->eid_type);
13684       return 0;
13685     }
13686
13687   /* send it... */
13688   S;
13689
13690   /* Wait for a reply... */
13691   W;
13692
13693   /* NOTREACHED */
13694   return 0;
13695 }
13696
13697 static int
13698 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13699 {
13700   unformat_input_t *input = vam->input;
13701   vl_api_lisp_gpe_add_del_iface_t *mp;
13702   f64 timeout = ~0;
13703   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13704   u32 dp_table = 0, vni = 0;
13705
13706   /* Parse args required to build the message */
13707   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13708     {
13709       if (unformat (input, "up"))
13710         {
13711           action_set = 1;
13712           is_add = 1;
13713         }
13714       else if (unformat (input, "down"))
13715         {
13716           action_set = 1;
13717           is_add = 0;
13718         }
13719       else if (unformat (input, "table_id %d", &dp_table))
13720         {
13721           dp_table_set = 1;
13722         }
13723       else if (unformat (input, "bd_id %d", &dp_table))
13724         {
13725           dp_table_set = 1;
13726           is_l2 = 1;
13727         }
13728       else if (unformat (input, "vni %d", &vni))
13729         {
13730           vni_set = 1;
13731         }
13732       else
13733         break;
13734     }
13735
13736   if (action_set == 0)
13737     {
13738       errmsg ("Action not set\n");
13739       return -99;
13740     }
13741   if (dp_table_set == 0 || vni_set == 0)
13742     {
13743       errmsg ("vni and dp_table must be set\n");
13744       return -99;
13745     }
13746
13747   /* Construct the API message */
13748   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13749
13750   mp->is_add = is_add;
13751   mp->dp_table = dp_table;
13752   mp->is_l2 = is_l2;
13753   mp->vni = vni;
13754
13755   /* send it... */
13756   S;
13757
13758   /* Wait for a reply... */
13759   W;
13760
13761   /* NOTREACHED */
13762   return 0;
13763 }
13764
13765 /**
13766  * Add/del map request itr rlocs from LISP control plane and updates
13767  *
13768  * @param vam vpp API test context
13769  * @return return code
13770  */
13771 static int
13772 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13773 {
13774   unformat_input_t *input = vam->input;
13775   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13776   f64 timeout = ~0;
13777   u8 *locator_set_name = 0;
13778   u8 locator_set_name_set = 0;
13779   u8 is_add = 1;
13780
13781   /* Parse args required to build the message */
13782   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13783     {
13784       if (unformat (input, "del"))
13785         {
13786           is_add = 0;
13787         }
13788       else if (unformat (input, "%_%v%_", &locator_set_name))
13789         {
13790           locator_set_name_set = 1;
13791         }
13792       else
13793         {
13794           clib_warning ("parse error '%U'", format_unformat_error, input);
13795           return -99;
13796         }
13797     }
13798
13799   if (is_add && !locator_set_name_set)
13800     {
13801       errmsg ("itr-rloc is not set!");
13802       return -99;
13803     }
13804
13805   if (is_add && vec_len (locator_set_name) > 64)
13806     {
13807       errmsg ("itr-rloc locator-set name too long\n");
13808       vec_free (locator_set_name);
13809       return -99;
13810     }
13811
13812   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13813   mp->is_add = is_add;
13814   if (is_add)
13815     {
13816       clib_memcpy (mp->locator_set_name, locator_set_name,
13817                    vec_len (locator_set_name));
13818     }
13819   else
13820     {
13821       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13822     }
13823   vec_free (locator_set_name);
13824
13825   /* send it... */
13826   S;
13827
13828   /* Wait for a reply... */
13829   W;
13830
13831   /* NOTREACHED */
13832   return 0;
13833 }
13834
13835 static int
13836 api_lisp_locator_dump (vat_main_t * vam)
13837 {
13838   unformat_input_t *input = vam->input;
13839   vl_api_lisp_locator_dump_t *mp;
13840   f64 timeout = ~0;
13841   u8 is_index_set = 0, is_name_set = 0;
13842   u8 *ls_name = 0;
13843   u32 ls_index = ~0;
13844
13845   /* Parse args required to build the message */
13846   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13847     {
13848       if (unformat (input, "ls_name %_%v%_", &ls_name))
13849         {
13850           is_name_set = 1;
13851         }
13852       else if (unformat (input, "ls_index %d", &ls_index))
13853         {
13854           is_index_set = 1;
13855         }
13856       else
13857         {
13858           errmsg ("parse error '%U'", format_unformat_error, input);
13859           return -99;
13860         }
13861     }
13862
13863   if (!is_index_set && !is_name_set)
13864     {
13865       errmsg ("error: expected one of index or name!\n");
13866       return -99;
13867     }
13868
13869   if (is_index_set && is_name_set)
13870     {
13871       errmsg ("error: only one param expected!\n");
13872       return -99;
13873     }
13874
13875   if (vec_len (ls_name) > 62)
13876     {
13877       errmsg ("error: locator set name too long!");
13878       return -99;
13879     }
13880
13881   if (!vam->json_output)
13882     {
13883       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13884                "weight");
13885     }
13886
13887   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13888   mp->is_index_set = is_index_set;
13889
13890   if (is_index_set)
13891     mp->ls_index = clib_host_to_net_u32 (ls_index);
13892   else
13893     {
13894       vec_add1 (ls_name, 0);
13895       strncpy ((char *) mp->ls_name, (char *) ls_name,
13896                sizeof (mp->ls_name) - 1);
13897     }
13898
13899   /* send it... */
13900   S;
13901
13902   /* Use a control ping for synchronization */
13903   {
13904     vl_api_control_ping_t *mp;
13905     M (CONTROL_PING, control_ping);
13906     S;
13907   }
13908   /* Wait for a reply... */
13909   W;
13910
13911   /* NOTREACHED */
13912   return 0;
13913 }
13914
13915 static int
13916 api_lisp_locator_set_dump (vat_main_t * vam)
13917 {
13918   vl_api_lisp_locator_set_dump_t *mp;
13919   unformat_input_t *input = vam->input;
13920   f64 timeout = ~0;
13921   u8 filter = 0;
13922
13923   /* Parse args required to build the message */
13924   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13925     {
13926       if (unformat (input, "local"))
13927         {
13928           filter = 1;
13929         }
13930       else if (unformat (input, "remote"))
13931         {
13932           filter = 2;
13933         }
13934       else
13935         {
13936           errmsg ("parse error '%U'", format_unformat_error, input);
13937           return -99;
13938         }
13939     }
13940
13941   if (!vam->json_output)
13942     {
13943       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13944     }
13945
13946   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13947
13948   mp->filter = filter;
13949
13950   /* send it... */
13951   S;
13952
13953   /* Use a control ping for synchronization */
13954   {
13955     vl_api_control_ping_t *mp;
13956     M (CONTROL_PING, control_ping);
13957     S;
13958   }
13959   /* Wait for a reply... */
13960   W;
13961
13962   /* NOTREACHED */
13963   return 0;
13964 }
13965
13966 static int
13967 api_lisp_eid_table_map_dump (vat_main_t * vam)
13968 {
13969   u8 is_l2 = 0;
13970   u8 mode_set = 0;
13971   unformat_input_t *input = vam->input;
13972   vl_api_lisp_eid_table_map_dump_t *mp;
13973   f64 timeout = ~0;
13974
13975   /* Parse args required to build the message */
13976   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13977     {
13978       if (unformat (input, "l2"))
13979         {
13980           is_l2 = 1;
13981           mode_set = 1;
13982         }
13983       else if (unformat (input, "l3"))
13984         {
13985           is_l2 = 0;
13986           mode_set = 1;
13987         }
13988       else
13989         {
13990           errmsg ("parse error '%U'", format_unformat_error, input);
13991           return -99;
13992         }
13993     }
13994
13995   if (!mode_set)
13996     {
13997       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13998       return -99;
13999     }
14000
14001   if (!vam->json_output)
14002     {
14003       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
14004     }
14005
14006   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14007   mp->is_l2 = is_l2;
14008
14009   /* send it... */
14010   S;
14011
14012   /* Use a control ping for synchronization */
14013   {
14014     vl_api_control_ping_t *mp;
14015     M (CONTROL_PING, control_ping);
14016     S;
14017   }
14018   /* Wait for a reply... */
14019   W;
14020
14021   /* NOTREACHED */
14022   return 0;
14023 }
14024
14025 static int
14026 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14027 {
14028   vl_api_lisp_eid_table_vni_dump_t *mp;
14029   f64 timeout = ~0;
14030
14031   if (!vam->json_output)
14032     {
14033       fformat (vam->ofp, "VNI\n");
14034     }
14035
14036   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14037
14038   /* send it... */
14039   S;
14040
14041   /* Use a control ping for synchronization */
14042   {
14043     vl_api_control_ping_t *mp;
14044     M (CONTROL_PING, control_ping);
14045     S;
14046   }
14047   /* Wait for a reply... */
14048   W;
14049
14050   /* NOTREACHED */
14051   return 0;
14052 }
14053
14054 static int
14055 api_lisp_eid_table_dump (vat_main_t * vam)
14056 {
14057   unformat_input_t *i = vam->input;
14058   vl_api_lisp_eid_table_dump_t *mp;
14059   f64 timeout = ~0;
14060   struct in_addr ip4;
14061   struct in6_addr ip6;
14062   u8 mac[6];
14063   u8 eid_type = ~0, eid_set = 0;
14064   u32 prefix_length = ~0, t, vni = 0;
14065   u8 filter = 0;
14066
14067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14068     {
14069       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14070         {
14071           eid_set = 1;
14072           eid_type = 0;
14073           prefix_length = t;
14074         }
14075       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14076         {
14077           eid_set = 1;
14078           eid_type = 1;
14079           prefix_length = t;
14080         }
14081       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14082         {
14083           eid_set = 1;
14084           eid_type = 2;
14085         }
14086       else if (unformat (i, "vni %d", &t))
14087         {
14088           vni = t;
14089         }
14090       else if (unformat (i, "local"))
14091         {
14092           filter = 1;
14093         }
14094       else if (unformat (i, "remote"))
14095         {
14096           filter = 2;
14097         }
14098       else
14099         {
14100           errmsg ("parse error '%U'", format_unformat_error, i);
14101           return -99;
14102         }
14103     }
14104
14105   if (!vam->json_output)
14106     {
14107       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
14108                "ls_index", "ttl", "authoritative");
14109     }
14110
14111   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14112
14113   mp->filter = filter;
14114   if (eid_set)
14115     {
14116       mp->eid_set = 1;
14117       mp->vni = htonl (vni);
14118       mp->eid_type = eid_type;
14119       switch (eid_type)
14120         {
14121         case 0:
14122           mp->prefix_length = prefix_length;
14123           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14124           break;
14125         case 1:
14126           mp->prefix_length = prefix_length;
14127           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14128           break;
14129         case 2:
14130           clib_memcpy (mp->eid, mac, sizeof (mac));
14131           break;
14132         default:
14133           errmsg ("unknown EID type %d!", eid_type);
14134           return -99;
14135         }
14136     }
14137
14138   /* send it... */
14139   S;
14140
14141   /* Use a control ping for synchronization */
14142   {
14143     vl_api_control_ping_t *mp;
14144     M (CONTROL_PING, control_ping);
14145     S;
14146   }
14147
14148   /* Wait for a reply... */
14149   W;
14150
14151   /* NOTREACHED */
14152   return 0;
14153 }
14154
14155 static int
14156 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14157 {
14158   vl_api_lisp_gpe_tunnel_dump_t *mp;
14159   f64 timeout = ~0;
14160
14161   if (!vam->json_output)
14162     {
14163       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14164                "%=16s%=16s%=16s%=16s%=16s\n",
14165                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14166                "Decap next", "Lisp version", "Flags", "Next protocol",
14167                "ver_res", "res", "iid");
14168     }
14169
14170   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14171   /* send it... */
14172   S;
14173
14174   /* Use a control ping for synchronization */
14175   {
14176     vl_api_control_ping_t *mp;
14177     M (CONTROL_PING, control_ping);
14178     S;
14179   }
14180   /* Wait for a reply... */
14181   W;
14182
14183   /* NOTREACHED */
14184   return 0;
14185 }
14186
14187 static int
14188 api_lisp_adjacencies_get (vat_main_t * vam)
14189 {
14190   unformat_input_t *i = vam->input;
14191   vl_api_lisp_adjacencies_get_t *mp;
14192   f64 timeout = ~0;
14193   u8 vni_set = 0;
14194   u32 vni = ~0;
14195
14196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14197     {
14198       if (unformat (i, "vni %d", &vni))
14199         {
14200           vni_set = 1;
14201         }
14202       else
14203         {
14204           errmsg ("parse error '%U'\n", format_unformat_error, i);
14205           return -99;
14206         }
14207     }
14208
14209   if (!vni_set)
14210     {
14211       errmsg ("vni not set!\n");
14212       return -99;
14213     }
14214
14215   if (!vam->json_output)
14216     {
14217       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14218     }
14219
14220   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14221   mp->vni = clib_host_to_net_u32 (vni);
14222
14223   /* send it... */
14224   S;
14225
14226   /* Wait for a reply... */
14227   W;
14228
14229   /* NOTREACHED */
14230   return 0;
14231 }
14232
14233 static int
14234 api_lisp_map_resolver_dump (vat_main_t * vam)
14235 {
14236   vl_api_lisp_map_resolver_dump_t *mp;
14237   f64 timeout = ~0;
14238
14239   if (!vam->json_output)
14240     {
14241       fformat (vam->ofp, "%=20s\n", "Map resolver");
14242     }
14243
14244   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14245   /* send it... */
14246   S;
14247
14248   /* Use a control ping for synchronization */
14249   {
14250     vl_api_control_ping_t *mp;
14251     M (CONTROL_PING, control_ping);
14252     S;
14253   }
14254   /* Wait for a reply... */
14255   W;
14256
14257   /* NOTREACHED */
14258   return 0;
14259 }
14260
14261 static int
14262 api_show_lisp_status (vat_main_t * vam)
14263 {
14264   vl_api_show_lisp_status_t *mp;
14265   f64 timeout = ~0;
14266
14267   if (!vam->json_output)
14268     {
14269       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14270     }
14271
14272   M (SHOW_LISP_STATUS, show_lisp_status);
14273   /* send it... */
14274   S;
14275   /* Wait for a reply... */
14276   W;
14277
14278   /* NOTREACHED */
14279   return 0;
14280 }
14281
14282 static int
14283 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14284 {
14285   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14286   f64 timeout = ~0;
14287
14288   if (!vam->json_output)
14289     {
14290       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14291     }
14292
14293   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14294   /* send it... */
14295   S;
14296   /* Wait for a reply... */
14297   W;
14298
14299   /* NOTREACHED */
14300   return 0;
14301 }
14302
14303 static int
14304 api_af_packet_create (vat_main_t * vam)
14305 {
14306   unformat_input_t *i = vam->input;
14307   vl_api_af_packet_create_t *mp;
14308   f64 timeout;
14309   u8 *host_if_name = 0;
14310   u8 hw_addr[6];
14311   u8 random_hw_addr = 1;
14312
14313   memset (hw_addr, 0, sizeof (hw_addr));
14314
14315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14316     {
14317       if (unformat (i, "name %s", &host_if_name))
14318         vec_add1 (host_if_name, 0);
14319       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14320         random_hw_addr = 0;
14321       else
14322         break;
14323     }
14324
14325   if (!vec_len (host_if_name))
14326     {
14327       errmsg ("host-interface name must be specified");
14328       return -99;
14329     }
14330
14331   if (vec_len (host_if_name) > 64)
14332     {
14333       errmsg ("host-interface name too long");
14334       return -99;
14335     }
14336
14337   M (AF_PACKET_CREATE, af_packet_create);
14338
14339   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14340   clib_memcpy (mp->hw_addr, hw_addr, 6);
14341   mp->use_random_hw_addr = random_hw_addr;
14342   vec_free (host_if_name);
14343
14344   S;
14345   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14346   /* NOTREACHED */
14347   return 0;
14348 }
14349
14350 static int
14351 api_af_packet_delete (vat_main_t * vam)
14352 {
14353   unformat_input_t *i = vam->input;
14354   vl_api_af_packet_delete_t *mp;
14355   f64 timeout;
14356   u8 *host_if_name = 0;
14357
14358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14359     {
14360       if (unformat (i, "name %s", &host_if_name))
14361         vec_add1 (host_if_name, 0);
14362       else
14363         break;
14364     }
14365
14366   if (!vec_len (host_if_name))
14367     {
14368       errmsg ("host-interface name must be specified");
14369       return -99;
14370     }
14371
14372   if (vec_len (host_if_name) > 64)
14373     {
14374       errmsg ("host-interface name too long");
14375       return -99;
14376     }
14377
14378   M (AF_PACKET_DELETE, af_packet_delete);
14379
14380   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14381   vec_free (host_if_name);
14382
14383   S;
14384   W;
14385   /* NOTREACHED */
14386   return 0;
14387 }
14388
14389 static int
14390 api_policer_add_del (vat_main_t * vam)
14391 {
14392   unformat_input_t *i = vam->input;
14393   vl_api_policer_add_del_t *mp;
14394   f64 timeout;
14395   u8 is_add = 1;
14396   u8 *name = 0;
14397   u32 cir = 0;
14398   u32 eir = 0;
14399   u64 cb = 0;
14400   u64 eb = 0;
14401   u8 rate_type = 0;
14402   u8 round_type = 0;
14403   u8 type = 0;
14404   u8 color_aware = 0;
14405   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14406
14407   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14408   conform_action.dscp = 0;
14409   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14410   exceed_action.dscp = 0;
14411   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14412   violate_action.dscp = 0;
14413
14414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14415     {
14416       if (unformat (i, "del"))
14417         is_add = 0;
14418       else if (unformat (i, "name %s", &name))
14419         vec_add1 (name, 0);
14420       else if (unformat (i, "cir %u", &cir))
14421         ;
14422       else if (unformat (i, "eir %u", &eir))
14423         ;
14424       else if (unformat (i, "cb %u", &cb))
14425         ;
14426       else if (unformat (i, "eb %u", &eb))
14427         ;
14428       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14429                          &rate_type))
14430         ;
14431       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14432                          &round_type))
14433         ;
14434       else if (unformat (i, "type %U", unformat_policer_type, &type))
14435         ;
14436       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14437                          &conform_action))
14438         ;
14439       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14440                          &exceed_action))
14441         ;
14442       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14443                          &violate_action))
14444         ;
14445       else if (unformat (i, "color-aware"))
14446         color_aware = 1;
14447       else
14448         break;
14449     }
14450
14451   if (!vec_len (name))
14452     {
14453       errmsg ("policer name must be specified");
14454       return -99;
14455     }
14456
14457   if (vec_len (name) > 64)
14458     {
14459       errmsg ("policer name too long");
14460       return -99;
14461     }
14462
14463   M (POLICER_ADD_DEL, policer_add_del);
14464
14465   clib_memcpy (mp->name, name, vec_len (name));
14466   vec_free (name);
14467   mp->is_add = is_add;
14468   mp->cir = cir;
14469   mp->eir = eir;
14470   mp->cb = cb;
14471   mp->eb = eb;
14472   mp->rate_type = rate_type;
14473   mp->round_type = round_type;
14474   mp->type = type;
14475   mp->conform_action_type = conform_action.action_type;
14476   mp->conform_dscp = conform_action.dscp;
14477   mp->exceed_action_type = exceed_action.action_type;
14478   mp->exceed_dscp = exceed_action.dscp;
14479   mp->violate_action_type = violate_action.action_type;
14480   mp->violate_dscp = violate_action.dscp;
14481   mp->color_aware = color_aware;
14482
14483   S;
14484   W;
14485   /* NOTREACHED */
14486   return 0;
14487 }
14488
14489 static int
14490 api_policer_dump (vat_main_t * vam)
14491 {
14492   unformat_input_t *i = vam->input;
14493   vl_api_policer_dump_t *mp;
14494   f64 timeout = ~0;
14495   u8 *match_name = 0;
14496   u8 match_name_valid = 0;
14497
14498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14499     {
14500       if (unformat (i, "name %s", &match_name))
14501         {
14502           vec_add1 (match_name, 0);
14503           match_name_valid = 1;
14504         }
14505       else
14506         break;
14507     }
14508
14509   M (POLICER_DUMP, policer_dump);
14510   mp->match_name_valid = match_name_valid;
14511   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14512   vec_free (match_name);
14513   /* send it... */
14514   S;
14515
14516   /* Use a control ping for synchronization */
14517   {
14518     vl_api_control_ping_t *mp;
14519     M (CONTROL_PING, control_ping);
14520     S;
14521   }
14522   /* Wait for a reply... */
14523   W;
14524
14525   /* NOTREACHED */
14526   return 0;
14527 }
14528
14529 static int
14530 api_policer_classify_set_interface (vat_main_t * vam)
14531 {
14532   unformat_input_t *i = vam->input;
14533   vl_api_policer_classify_set_interface_t *mp;
14534   f64 timeout;
14535   u32 sw_if_index;
14536   int sw_if_index_set;
14537   u32 ip4_table_index = ~0;
14538   u32 ip6_table_index = ~0;
14539   u32 l2_table_index = ~0;
14540   u8 is_add = 1;
14541
14542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14543     {
14544       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14545         sw_if_index_set = 1;
14546       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14547         sw_if_index_set = 1;
14548       else if (unformat (i, "del"))
14549         is_add = 0;
14550       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14551         ;
14552       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14553         ;
14554       else if (unformat (i, "l2-table %d", &l2_table_index))
14555         ;
14556       else
14557         {
14558           clib_warning ("parse error '%U'", format_unformat_error, i);
14559           return -99;
14560         }
14561     }
14562
14563   if (sw_if_index_set == 0)
14564     {
14565       errmsg ("missing interface name or sw_if_index\n");
14566       return -99;
14567     }
14568
14569   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14570
14571   mp->sw_if_index = ntohl (sw_if_index);
14572   mp->ip4_table_index = ntohl (ip4_table_index);
14573   mp->ip6_table_index = ntohl (ip6_table_index);
14574   mp->l2_table_index = ntohl (l2_table_index);
14575   mp->is_add = is_add;
14576
14577   S;
14578   W;
14579   /* NOTREACHED */
14580   return 0;
14581 }
14582
14583 static int
14584 api_policer_classify_dump (vat_main_t * vam)
14585 {
14586   unformat_input_t *i = vam->input;
14587   vl_api_policer_classify_dump_t *mp;
14588   f64 timeout = ~0;
14589   u8 type = POLICER_CLASSIFY_N_TABLES;
14590
14591   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14592     ;
14593   else
14594     {
14595       errmsg ("classify table type must be specified\n");
14596       return -99;
14597     }
14598
14599   if (!vam->json_output)
14600     {
14601       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14602     }
14603
14604   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14605   mp->type = type;
14606   /* send it... */
14607   S;
14608
14609   /* Use a control ping for synchronization */
14610   {
14611     vl_api_control_ping_t *mp;
14612     M (CONTROL_PING, control_ping);
14613     S;
14614   }
14615   /* Wait for a reply... */
14616   W;
14617
14618   /* NOTREACHED */
14619   return 0;
14620 }
14621
14622 static int
14623 api_netmap_create (vat_main_t * vam)
14624 {
14625   unformat_input_t *i = vam->input;
14626   vl_api_netmap_create_t *mp;
14627   f64 timeout;
14628   u8 *if_name = 0;
14629   u8 hw_addr[6];
14630   u8 random_hw_addr = 1;
14631   u8 is_pipe = 0;
14632   u8 is_master = 0;
14633
14634   memset (hw_addr, 0, sizeof (hw_addr));
14635
14636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14637     {
14638       if (unformat (i, "name %s", &if_name))
14639         vec_add1 (if_name, 0);
14640       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14641         random_hw_addr = 0;
14642       else if (unformat (i, "pipe"))
14643         is_pipe = 1;
14644       else if (unformat (i, "master"))
14645         is_master = 1;
14646       else if (unformat (i, "slave"))
14647         is_master = 0;
14648       else
14649         break;
14650     }
14651
14652   if (!vec_len (if_name))
14653     {
14654       errmsg ("interface name must be specified");
14655       return -99;
14656     }
14657
14658   if (vec_len (if_name) > 64)
14659     {
14660       errmsg ("interface name too long");
14661       return -99;
14662     }
14663
14664   M (NETMAP_CREATE, netmap_create);
14665
14666   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14667   clib_memcpy (mp->hw_addr, hw_addr, 6);
14668   mp->use_random_hw_addr = random_hw_addr;
14669   mp->is_pipe = is_pipe;
14670   mp->is_master = is_master;
14671   vec_free (if_name);
14672
14673   S;
14674   W;
14675   /* NOTREACHED */
14676   return 0;
14677 }
14678
14679 static int
14680 api_netmap_delete (vat_main_t * vam)
14681 {
14682   unformat_input_t *i = vam->input;
14683   vl_api_netmap_delete_t *mp;
14684   f64 timeout;
14685   u8 *if_name = 0;
14686
14687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14688     {
14689       if (unformat (i, "name %s", &if_name))
14690         vec_add1 (if_name, 0);
14691       else
14692         break;
14693     }
14694
14695   if (!vec_len (if_name))
14696     {
14697       errmsg ("interface name must be specified");
14698       return -99;
14699     }
14700
14701   if (vec_len (if_name) > 64)
14702     {
14703       errmsg ("interface name too long");
14704       return -99;
14705     }
14706
14707   M (NETMAP_DELETE, netmap_delete);
14708
14709   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14710   vec_free (if_name);
14711
14712   S;
14713   W;
14714   /* NOTREACHED */
14715   return 0;
14716 }
14717
14718 static void vl_api_mpls_tunnel_details_t_handler
14719   (vl_api_mpls_tunnel_details_t * mp)
14720 {
14721   vat_main_t *vam = &vat_main;
14722   i32 len = mp->mt_next_hop_n_labels;
14723   i32 i;
14724
14725   fformat (vam->ofp, "[%d]: via %U %d labels ",
14726            mp->tunnel_index,
14727            format_ip4_address, mp->mt_next_hop,
14728            ntohl (mp->mt_next_hop_sw_if_index));
14729   for (i = 0; i < len; i++)
14730     {
14731       fformat (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
14732     }
14733   fformat (vam->ofp, "\n");
14734 }
14735
14736 static void vl_api_mpls_tunnel_details_t_handler_json
14737   (vl_api_mpls_tunnel_details_t * mp)
14738 {
14739   vat_main_t *vam = &vat_main;
14740   vat_json_node_t *node = NULL;
14741   struct in_addr ip4;
14742   i32 i;
14743   i32 len = mp->mt_next_hop_n_labels;
14744
14745   if (VAT_JSON_ARRAY != vam->json_tree.type)
14746     {
14747       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14748       vat_json_init_array (&vam->json_tree);
14749     }
14750   node = vat_json_array_add (&vam->json_tree);
14751
14752   vat_json_init_object (node);
14753   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14754   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
14755   vat_json_object_add_ip4 (node, "next_hop", ip4);
14756   vat_json_object_add_uint (node, "next_hop_sw_if_index",
14757                             ntohl (mp->mt_next_hop_sw_if_index));
14758   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
14759   vat_json_object_add_uint (node, "label_count", len);
14760   for (i = 0; i < len; i++)
14761     {
14762       vat_json_object_add_uint (node, "label",
14763                                 ntohl (mp->mt_next_hop_out_labels[i]));
14764     }
14765 }
14766
14767 static int
14768 api_mpls_tunnel_dump (vat_main_t * vam)
14769 {
14770   vl_api_mpls_tunnel_dump_t *mp;
14771   f64 timeout;
14772   i32 index = -1;
14773
14774   /* Parse args required to build the message */
14775   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14776     {
14777       if (!unformat (vam->input, "tunnel_index %d", &index))
14778         {
14779           index = -1;
14780           break;
14781         }
14782     }
14783
14784   fformat (vam->ofp, "  tunnel_index %d\n", index);
14785
14786   M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
14787   mp->tunnel_index = htonl (index);
14788   S;
14789
14790   /* Use a control ping for synchronization */
14791   {
14792     vl_api_control_ping_t *mp;
14793     M (CONTROL_PING, control_ping);
14794     S;
14795   }
14796   W;
14797 }
14798
14799 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
14800 #define vl_api_mpls_fib_details_t_print vl_noop_handler
14801
14802 static void
14803 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
14804 {
14805   vat_main_t *vam = &vat_main;
14806   int count = ntohl (mp->count);
14807   vl_api_fib_path_t *fp;
14808   int i;
14809
14810   fformat (vam->ofp,
14811            "table-id %d, label %u, ess_bit %u\n",
14812            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
14813   fp = mp->path;
14814   for (i = 0; i < count; i++)
14815     {
14816       if (fp->afi == IP46_TYPE_IP6)
14817         fformat (vam->ofp,
14818                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14819                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14820                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14821                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14822                  format_ip6_address, fp->next_hop);
14823       else if (fp->afi == IP46_TYPE_IP4)
14824         fformat (vam->ofp,
14825                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14826                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14827                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14828                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14829                  format_ip4_address, fp->next_hop);
14830       fp++;
14831     }
14832 }
14833
14834 static void vl_api_mpls_fib_details_t_handler_json
14835   (vl_api_mpls_fib_details_t * mp)
14836 {
14837   vat_main_t *vam = &vat_main;
14838   int count = ntohl (mp->count);
14839   vat_json_node_t *node = NULL;
14840   struct in_addr ip4;
14841   struct in6_addr ip6;
14842   vl_api_fib_path_t *fp;
14843   int i;
14844
14845   if (VAT_JSON_ARRAY != vam->json_tree.type)
14846     {
14847       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14848       vat_json_init_array (&vam->json_tree);
14849     }
14850   node = vat_json_array_add (&vam->json_tree);
14851
14852   vat_json_init_object (node);
14853   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14854   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
14855   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14856   vat_json_object_add_uint (node, "path_count", count);
14857   fp = mp->path;
14858   for (i = 0; i < count; i++)
14859     {
14860       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
14861       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
14862       vat_json_object_add_uint (node, "is_local", fp->is_local);
14863       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
14864       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
14865       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
14866       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
14867       if (fp->afi == IP46_TYPE_IP4)
14868         {
14869           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
14870           vat_json_object_add_ip4 (node, "next_hop", ip4);
14871         }
14872       else if (fp->afi == IP46_TYPE_IP6)
14873         {
14874           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
14875           vat_json_object_add_ip6 (node, "next_hop", ip6);
14876         }
14877     }
14878 }
14879
14880 static int
14881 api_mpls_fib_dump (vat_main_t * vam)
14882 {
14883   vl_api_mpls_fib_dump_t *mp;
14884   f64 timeout;
14885
14886   M (MPLS_FIB_DUMP, mpls_fib_dump);
14887   S;
14888
14889   /* Use a control ping for synchronization */
14890   {
14891     vl_api_control_ping_t *mp;
14892     M (CONTROL_PING, control_ping);
14893     S;
14894   }
14895   W;
14896 }
14897
14898 #define vl_api_ip_fib_details_t_endian vl_noop_handler
14899 #define vl_api_ip_fib_details_t_print vl_noop_handler
14900
14901 static void
14902 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
14903 {
14904   vat_main_t *vam = &vat_main;
14905   int count = ntohl (mp->count);
14906   vl_api_fib_path_t *fp;
14907   int i;
14908
14909   fformat (vam->ofp,
14910            "table-id %d, prefix %U/%d\n",
14911            ntohl (mp->table_id), format_ip4_address, mp->address,
14912            mp->address_length);
14913   fp = mp->path;
14914   for (i = 0; i < count; i++)
14915     {
14916       if (fp->afi == IP46_TYPE_IP6)
14917         fformat (vam->ofp,
14918                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14919                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14920                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14921                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14922                  format_ip6_address, fp->next_hop);
14923       else if (fp->afi == IP46_TYPE_IP4)
14924         fformat (vam->ofp,
14925                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14926                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14927                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14928                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14929                  format_ip4_address, fp->next_hop);
14930       fp++;
14931     }
14932 }
14933
14934 static void vl_api_ip_fib_details_t_handler_json
14935   (vl_api_ip_fib_details_t * mp)
14936 {
14937   vat_main_t *vam = &vat_main;
14938   int count = ntohl (mp->count);
14939   vat_json_node_t *node = NULL;
14940   struct in_addr ip4;
14941   struct in6_addr ip6;
14942   vl_api_fib_path_t *fp;
14943   int i;
14944
14945   if (VAT_JSON_ARRAY != vam->json_tree.type)
14946     {
14947       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14948       vat_json_init_array (&vam->json_tree);
14949     }
14950   node = vat_json_array_add (&vam->json_tree);
14951
14952   vat_json_init_object (node);
14953   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14954   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
14955   vat_json_object_add_ip4 (node, "prefix", ip4);
14956   vat_json_object_add_uint (node, "mask_length", mp->address_length);
14957   vat_json_object_add_uint (node, "path_count", count);
14958   fp = mp->path;
14959   for (i = 0; i < count; i++)
14960     {
14961       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
14962       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
14963       vat_json_object_add_uint (node, "is_local", fp->is_local);
14964       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
14965       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
14966       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
14967       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
14968       if (fp->afi == IP46_TYPE_IP4)
14969         {
14970           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
14971           vat_json_object_add_ip4 (node, "next_hop", ip4);
14972         }
14973       else if (fp->afi == IP46_TYPE_IP6)
14974         {
14975           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
14976           vat_json_object_add_ip6 (node, "next_hop", ip6);
14977         }
14978     }
14979 }
14980
14981 static int
14982 api_ip_fib_dump (vat_main_t * vam)
14983 {
14984   vl_api_ip_fib_dump_t *mp;
14985   f64 timeout;
14986
14987   M (IP_FIB_DUMP, ip_fib_dump);
14988   S;
14989
14990   /* Use a control ping for synchronization */
14991   {
14992     vl_api_control_ping_t *mp;
14993     M (CONTROL_PING, control_ping);
14994     S;
14995   }
14996   W;
14997 }
14998
14999 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15000 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15001
15002 static void
15003 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15004 {
15005   vat_main_t *vam = &vat_main;
15006   int count = ntohl (mp->count);
15007   vl_api_fib_path_t *fp;
15008   int i;
15009
15010   fformat (vam->ofp,
15011            "table-id %d, prefix %U/%d\n",
15012            ntohl (mp->table_id), format_ip6_address, mp->address,
15013            mp->address_length);
15014   fp = mp->path;
15015   for (i = 0; i < count; i++)
15016     {
15017       if (fp->afi == IP46_TYPE_IP6)
15018         fformat (vam->ofp,
15019                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15020                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15021                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15022                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15023                  format_ip6_address, fp->next_hop);
15024       else if (fp->afi == IP46_TYPE_IP4)
15025         fformat (vam->ofp,
15026                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15027                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15028                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15029                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15030                  format_ip4_address, fp->next_hop);
15031       fp++;
15032     }
15033 }
15034
15035 static void vl_api_ip6_fib_details_t_handler_json
15036   (vl_api_ip6_fib_details_t * mp)
15037 {
15038   vat_main_t *vam = &vat_main;
15039   int count = ntohl (mp->count);
15040   vat_json_node_t *node = NULL;
15041   struct in_addr ip4;
15042   struct in6_addr ip6;
15043   vl_api_fib_path_t *fp;
15044   int i;
15045
15046   if (VAT_JSON_ARRAY != vam->json_tree.type)
15047     {
15048       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15049       vat_json_init_array (&vam->json_tree);
15050     }
15051   node = vat_json_array_add (&vam->json_tree);
15052
15053   vat_json_init_object (node);
15054   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15055   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15056   vat_json_object_add_ip6 (node, "prefix", ip6);
15057   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15058   vat_json_object_add_uint (node, "path_count", count);
15059   fp = mp->path;
15060   for (i = 0; i < count; i++)
15061     {
15062       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15063       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15064       vat_json_object_add_uint (node, "is_local", fp->is_local);
15065       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15066       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15067       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15068       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15069       if (fp->afi == IP46_TYPE_IP4)
15070         {
15071           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15072           vat_json_object_add_ip4 (node, "next_hop", ip4);
15073         }
15074       else if (fp->afi == IP46_TYPE_IP6)
15075         {
15076           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15077           vat_json_object_add_ip6 (node, "next_hop", ip6);
15078         }
15079     }
15080 }
15081
15082 static int
15083 api_ip6_fib_dump (vat_main_t * vam)
15084 {
15085   vl_api_ip6_fib_dump_t *mp;
15086   f64 timeout;
15087
15088   M (IP6_FIB_DUMP, ip6_fib_dump);
15089   S;
15090
15091   /* Use a control ping for synchronization */
15092   {
15093     vl_api_control_ping_t *mp;
15094     M (CONTROL_PING, control_ping);
15095     S;
15096   }
15097   W;
15098 }
15099
15100 int
15101 api_classify_table_ids (vat_main_t * vam)
15102 {
15103   vl_api_classify_table_ids_t *mp;
15104   f64 timeout;
15105
15106   /* Construct the API message */
15107   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15108   mp->context = 0;
15109
15110   S;
15111   W;
15112   /* NOTREACHED */
15113   return 0;
15114 }
15115
15116 int
15117 api_classify_table_by_interface (vat_main_t * vam)
15118 {
15119   unformat_input_t *input = vam->input;
15120   vl_api_classify_table_by_interface_t *mp;
15121   f64 timeout;
15122
15123   u32 sw_if_index = ~0;
15124   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15125     {
15126       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15127         ;
15128       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15129         ;
15130       else
15131         break;
15132     }
15133   if (sw_if_index == ~0)
15134     {
15135       errmsg ("missing interface name or sw_if_index\n");
15136       return -99;
15137     }
15138
15139   /* Construct the API message */
15140   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15141   mp->context = 0;
15142   mp->sw_if_index = ntohl (sw_if_index);
15143
15144   S;
15145   W;
15146   /* NOTREACHED */
15147   return 0;
15148 }
15149
15150 int
15151 api_classify_table_info (vat_main_t * vam)
15152 {
15153   unformat_input_t *input = vam->input;
15154   vl_api_classify_table_info_t *mp;
15155   f64 timeout;
15156
15157   u32 table_id = ~0;
15158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15159     {
15160       if (unformat (input, "table_id %d", &table_id))
15161         ;
15162       else
15163         break;
15164     }
15165   if (table_id == ~0)
15166     {
15167       errmsg ("missing table id\n");
15168       return -99;
15169     }
15170
15171   /* Construct the API message */
15172   M (CLASSIFY_TABLE_INFO, classify_table_info);
15173   mp->context = 0;
15174   mp->table_id = ntohl (table_id);
15175
15176   S;
15177   W;
15178   /* NOTREACHED */
15179   return 0;
15180 }
15181
15182 int
15183 api_classify_session_dump (vat_main_t * vam)
15184 {
15185   unformat_input_t *input = vam->input;
15186   vl_api_classify_session_dump_t *mp;
15187   f64 timeout;
15188
15189   u32 table_id = ~0;
15190   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15191     {
15192       if (unformat (input, "table_id %d", &table_id))
15193         ;
15194       else
15195         break;
15196     }
15197   if (table_id == ~0)
15198     {
15199       errmsg ("missing table id\n");
15200       return -99;
15201     }
15202
15203   /* Construct the API message */
15204   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15205   mp->context = 0;
15206   mp->table_id = ntohl (table_id);
15207   S;
15208
15209   /* Use a control ping for synchronization */
15210   {
15211     vl_api_control_ping_t *mp;
15212     M (CONTROL_PING, control_ping);
15213     S;
15214   }
15215   W;
15216   /* NOTREACHED */
15217   return 0;
15218 }
15219
15220 static void
15221 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15222 {
15223   vat_main_t *vam = &vat_main;
15224
15225   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15226            "src_address %U, vrf_id %d, path_mtu %u, "
15227            "template_interval %u, udp_checksum %d\n",
15228            format_ip4_address, mp->collector_address,
15229            ntohs (mp->collector_port),
15230            format_ip4_address, mp->src_address,
15231            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15232            ntohl (mp->template_interval), mp->udp_checksum);
15233
15234   vam->retval = 0;
15235   vam->result_ready = 1;
15236 }
15237
15238 static void
15239   vl_api_ipfix_exporter_details_t_handler_json
15240   (vl_api_ipfix_exporter_details_t * mp)
15241 {
15242   vat_main_t *vam = &vat_main;
15243   vat_json_node_t node;
15244   struct in_addr collector_address;
15245   struct in_addr src_address;
15246
15247   vat_json_init_object (&node);
15248   clib_memcpy (&collector_address, &mp->collector_address,
15249                sizeof (collector_address));
15250   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15251   vat_json_object_add_uint (&node, "collector_port",
15252                             ntohs (mp->collector_port));
15253   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15254   vat_json_object_add_ip4 (&node, "src_address", src_address);
15255   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15256   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15257   vat_json_object_add_uint (&node, "template_interval",
15258                             ntohl (mp->template_interval));
15259   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15260
15261   vat_json_print (vam->ofp, &node);
15262   vat_json_free (&node);
15263   vam->retval = 0;
15264   vam->result_ready = 1;
15265 }
15266
15267 int
15268 api_ipfix_exporter_dump (vat_main_t * vam)
15269 {
15270   vl_api_ipfix_exporter_dump_t *mp;
15271   f64 timeout;
15272
15273   /* Construct the API message */
15274   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15275   mp->context = 0;
15276
15277   S;
15278   W;
15279   /* NOTREACHED */
15280   return 0;
15281 }
15282
15283 static int
15284 api_ipfix_classify_stream_dump (vat_main_t * vam)
15285 {
15286   vl_api_ipfix_classify_stream_dump_t *mp;
15287   f64 timeout;
15288
15289   /* Construct the API message */
15290   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15291   mp->context = 0;
15292
15293   S;
15294   W;
15295   /* NOTREACHED */
15296   return 0;
15297 }
15298
15299 static void
15300   vl_api_ipfix_classify_stream_details_t_handler
15301   (vl_api_ipfix_classify_stream_details_t * mp)
15302 {
15303   vat_main_t *vam = &vat_main;
15304   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15305            ntohl (mp->domain_id), ntohs (mp->src_port));
15306   vam->retval = 0;
15307   vam->result_ready = 1;
15308 }
15309
15310 static void
15311   vl_api_ipfix_classify_stream_details_t_handler_json
15312   (vl_api_ipfix_classify_stream_details_t * mp)
15313 {
15314   vat_main_t *vam = &vat_main;
15315   vat_json_node_t node;
15316
15317   vat_json_init_object (&node);
15318   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15319   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15320
15321   vat_json_print (vam->ofp, &node);
15322   vat_json_free (&node);
15323   vam->retval = 0;
15324   vam->result_ready = 1;
15325 }
15326
15327 static int
15328 api_ipfix_classify_table_dump (vat_main_t * vam)
15329 {
15330   vl_api_ipfix_classify_table_dump_t *mp;
15331   f64 timeout;
15332
15333   if (!vam->json_output)
15334     {
15335       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15336                "transport_protocol");
15337     }
15338
15339   /* Construct the API message */
15340   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15341
15342   /* send it... */
15343   S;
15344
15345   /* Use a control ping for synchronization */
15346   {
15347     vl_api_control_ping_t *mp;
15348     M (CONTROL_PING, control_ping);
15349     S;
15350   }
15351   W;
15352 }
15353
15354 static void
15355   vl_api_ipfix_classify_table_details_t_handler
15356   (vl_api_ipfix_classify_table_details_t * mp)
15357 {
15358   vat_main_t *vam = &vat_main;
15359   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15360            mp->transport_protocol);
15361 }
15362
15363 static void
15364   vl_api_ipfix_classify_table_details_t_handler_json
15365   (vl_api_ipfix_classify_table_details_t * mp)
15366 {
15367   vat_json_node_t *node = NULL;
15368   vat_main_t *vam = &vat_main;
15369
15370   if (VAT_JSON_ARRAY != vam->json_tree.type)
15371     {
15372       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15373       vat_json_init_array (&vam->json_tree);
15374     }
15375
15376   node = vat_json_array_add (&vam->json_tree);
15377   vat_json_init_object (node);
15378
15379   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15380   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15381   vat_json_object_add_uint (node, "transport_protocol",
15382                             mp->transport_protocol);
15383 }
15384
15385 static int
15386 api_sw_interface_span_enable_disable (vat_main_t * vam)
15387 {
15388   unformat_input_t *i = vam->input;
15389   vl_api_sw_interface_span_enable_disable_t *mp;
15390   f64 timeout;
15391   u32 src_sw_if_index = ~0;
15392   u32 dst_sw_if_index = ~0;
15393   u8 enable = 1;
15394
15395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15396     {
15397       if (unformat (i, "src %U", unformat_sw_if_index, vam, &src_sw_if_index))
15398         ;
15399       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15400         ;
15401       else
15402         if (unformat
15403             (i, "dst %U", unformat_sw_if_index, vam, &dst_sw_if_index))
15404         ;
15405       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15406         ;
15407       else if (unformat (i, "disable"))
15408         enable = 0;
15409       else
15410         break;
15411     }
15412
15413   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15414
15415   mp->sw_if_index_from = htonl (src_sw_if_index);
15416   mp->sw_if_index_to = htonl (dst_sw_if_index);
15417   mp->enable = enable;
15418
15419   S;
15420   W;
15421   /* NOTREACHED */
15422   return 0;
15423 }
15424
15425 static void
15426 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
15427                                             * mp)
15428 {
15429   vat_main_t *vam = &vat_main;
15430
15431   fformat (vam->ofp, "%u => %u\n",
15432            ntohl (mp->sw_if_index_from), ntohl (mp->sw_if_index_to));
15433 }
15434
15435 static void
15436   vl_api_sw_interface_span_details_t_handler_json
15437   (vl_api_sw_interface_span_details_t * mp)
15438 {
15439   vat_main_t *vam = &vat_main;
15440   vat_json_node_t *node = NULL;
15441
15442   if (VAT_JSON_ARRAY != vam->json_tree.type)
15443     {
15444       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15445       vat_json_init_array (&vam->json_tree);
15446     }
15447   node = vat_json_array_add (&vam->json_tree);
15448
15449   vat_json_init_object (node);
15450   vat_json_object_add_uint (node, "src-if-index",
15451                             ntohl (mp->sw_if_index_from));
15452   vat_json_object_add_uint (node, "dst-if-index", ntohl (mp->sw_if_index_to));
15453 }
15454
15455 static int
15456 api_sw_interface_span_dump (vat_main_t * vam)
15457 {
15458   vl_api_sw_interface_span_dump_t *mp;
15459   f64 timeout;
15460
15461   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
15462   S;
15463
15464   /* Use a control ping for synchronization */
15465   {
15466     vl_api_control_ping_t *mp;
15467     M (CONTROL_PING, control_ping);
15468     S;
15469   }
15470   W;
15471 }
15472
15473 int
15474 api_pg_create_interface (vat_main_t * vam)
15475 {
15476   unformat_input_t *input = vam->input;
15477   vl_api_pg_create_interface_t *mp;
15478   f64 timeout;
15479
15480   u32 if_id = ~0;
15481   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15482     {
15483       if (unformat (input, "if_id %d", &if_id))
15484         ;
15485       else
15486         break;
15487     }
15488   if (if_id == ~0)
15489     {
15490       errmsg ("missing pg interface index\n");
15491       return -99;
15492     }
15493
15494   /* Construct the API message */
15495   M (PG_CREATE_INTERFACE, pg_create_interface);
15496   mp->context = 0;
15497   mp->interface_id = ntohl (if_id);
15498
15499   S;
15500   W;
15501   /* NOTREACHED */
15502   return 0;
15503 }
15504
15505 int
15506 api_pg_capture (vat_main_t * vam)
15507 {
15508   unformat_input_t *input = vam->input;
15509   vl_api_pg_capture_t *mp;
15510   f64 timeout;
15511
15512   u32 if_id = ~0;
15513   u8 enable = 1;
15514   u32 count = 1;
15515   u8 pcap_file_set = 0;
15516   u8 *pcap_file = 0;
15517   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15518     {
15519       if (unformat (input, "if_id %d", &if_id))
15520         ;
15521       else if (unformat (input, "pcap %s", &pcap_file))
15522         pcap_file_set = 1;
15523       else if (unformat (input, "count %d", &count))
15524         ;
15525       else if (unformat (input, "disable"))
15526         enable = 0;
15527       else
15528         break;
15529     }
15530   if (if_id == ~0)
15531     {
15532       errmsg ("missing pg interface index\n");
15533       return -99;
15534     }
15535   if (pcap_file_set > 0)
15536     {
15537       if (vec_len (pcap_file) > 255)
15538         {
15539           errmsg ("pcap file name is too long\n");
15540           return -99;
15541         }
15542     }
15543
15544   u32 name_len = vec_len (pcap_file);
15545   /* Construct the API message */
15546   M (PG_CAPTURE, pg_capture);
15547   mp->context = 0;
15548   mp->interface_id = ntohl (if_id);
15549   mp->is_enabled = enable;
15550   mp->count = ntohl (count);
15551   mp->pcap_name_length = ntohl (name_len);
15552   if (pcap_file_set != 0)
15553     {
15554       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15555     }
15556   vec_free (pcap_file);
15557
15558   S;
15559   W;
15560   /* NOTREACHED */
15561   return 0;
15562 }
15563
15564 int
15565 api_pg_enable_disable (vat_main_t * vam)
15566 {
15567   unformat_input_t *input = vam->input;
15568   vl_api_pg_enable_disable_t *mp;
15569   f64 timeout;
15570
15571   u8 enable = 1;
15572   u8 stream_name_set = 0;
15573   u8 *stream_name = 0;
15574   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15575     {
15576       if (unformat (input, "stream %s", &stream_name))
15577         stream_name_set = 1;
15578       else if (unformat (input, "disable"))
15579         enable = 0;
15580       else
15581         break;
15582     }
15583
15584   if (stream_name_set > 0)
15585     {
15586       if (vec_len (stream_name) > 255)
15587         {
15588           errmsg ("stream name too long\n");
15589           return -99;
15590         }
15591     }
15592
15593   u32 name_len = vec_len (stream_name);
15594   /* Construct the API message */
15595   M (PG_ENABLE_DISABLE, pg_enable_disable);
15596   mp->context = 0;
15597   mp->is_enabled = enable;
15598   if (stream_name_set != 0)
15599     {
15600       mp->stream_name_length = ntohl (name_len);
15601       clib_memcpy (mp->stream_name, stream_name, name_len);
15602     }
15603   vec_free (stream_name);
15604
15605   S;
15606   W;
15607   /* NOTREACHED */
15608   return 0;
15609 }
15610
15611 int
15612 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15613 {
15614   unformat_input_t *input = vam->input;
15615   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15616   f64 timeout;
15617
15618   u16 *low_ports = 0;
15619   u16 *high_ports = 0;
15620   u16 this_low;
15621   u16 this_hi;
15622   ip4_address_t ip4_addr;
15623   ip6_address_t ip6_addr;
15624   u32 length;
15625   u32 tmp, tmp2;
15626   u8 prefix_set = 0;
15627   u32 vrf_id = ~0;
15628   u8 is_add = 1;
15629   u8 is_ipv6 = 0;
15630
15631   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15632     {
15633       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15634         {
15635           prefix_set = 1;
15636         }
15637       else
15638         if (unformat
15639             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15640         {
15641           prefix_set = 1;
15642           is_ipv6 = 1;
15643         }
15644       else if (unformat (input, "vrf %d", &vrf_id))
15645         ;
15646       else if (unformat (input, "del"))
15647         is_add = 0;
15648       else if (unformat (input, "port %d", &tmp))
15649         {
15650           if (tmp == 0 || tmp > 65535)
15651             {
15652               errmsg ("port %d out of range", tmp);
15653               return -99;
15654             }
15655           this_low = tmp;
15656           this_hi = this_low + 1;
15657           vec_add1 (low_ports, this_low);
15658           vec_add1 (high_ports, this_hi);
15659         }
15660       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15661         {
15662           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15663             {
15664               errmsg ("incorrect range parameters\n");
15665               return -99;
15666             }
15667           this_low = tmp;
15668           /* Note: in debug CLI +1 is added to high before
15669              passing to real fn that does "the work"
15670              (ip_source_and_port_range_check_add_del).
15671              This fn is a wrapper around the binary API fn a
15672              control plane will call, which expects this increment
15673              to have occurred. Hence letting the binary API control
15674              plane fn do the increment for consistency between VAT
15675              and other control planes.
15676            */
15677           this_hi = tmp2;
15678           vec_add1 (low_ports, this_low);
15679           vec_add1 (high_ports, this_hi);
15680         }
15681       else
15682         break;
15683     }
15684
15685   if (prefix_set == 0)
15686     {
15687       errmsg ("<address>/<mask> not specified\n");
15688       return -99;
15689     }
15690
15691   if (vrf_id == ~0)
15692     {
15693       errmsg ("VRF ID required, not specified\n");
15694       return -99;
15695     }
15696
15697   if (vrf_id == 0)
15698     {
15699       errmsg
15700         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15701       return -99;
15702     }
15703
15704   if (vec_len (low_ports) == 0)
15705     {
15706       errmsg ("At least one port or port range required\n");
15707       return -99;
15708     }
15709
15710   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15711      ip_source_and_port_range_check_add_del);
15712
15713   mp->is_add = is_add;
15714
15715   if (is_ipv6)
15716     {
15717       mp->is_ipv6 = 1;
15718       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15719     }
15720   else
15721     {
15722       mp->is_ipv6 = 0;
15723       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15724     }
15725
15726   mp->mask_length = length;
15727   mp->number_of_ranges = vec_len (low_ports);
15728
15729   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15730   vec_free (low_ports);
15731
15732   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15733   vec_free (high_ports);
15734
15735   mp->vrf_id = ntohl (vrf_id);
15736
15737   S;
15738   W;
15739   /* NOTREACHED */
15740   return 0;
15741 }
15742
15743 int
15744 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15745 {
15746   unformat_input_t *input = vam->input;
15747   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15748   f64 timeout;
15749   u32 sw_if_index = ~0;
15750   int vrf_set = 0;
15751   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15752   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15753   u8 is_add = 1;
15754
15755   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15756     {
15757       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15758         ;
15759       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15760         ;
15761       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15762         vrf_set = 1;
15763       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15764         vrf_set = 1;
15765       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15766         vrf_set = 1;
15767       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15768         vrf_set = 1;
15769       else if (unformat (input, "del"))
15770         is_add = 0;
15771       else
15772         break;
15773     }
15774
15775   if (sw_if_index == ~0)
15776     {
15777       errmsg ("Interface required but not specified\n");
15778       return -99;
15779     }
15780
15781   if (vrf_set == 0)
15782     {
15783       errmsg ("VRF ID required but not specified\n");
15784       return -99;
15785     }
15786
15787   if (tcp_out_vrf_id == 0
15788       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15789     {
15790       errmsg
15791         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15792       return -99;
15793     }
15794
15795   /* Construct the API message */
15796   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15797      ip_source_and_port_range_check_interface_add_del);
15798
15799   mp->sw_if_index = ntohl (sw_if_index);
15800   mp->is_add = is_add;
15801   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15802   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15803   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15804   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15805
15806   /* send it... */
15807   S;
15808
15809   /* Wait for a reply... */
15810   W;
15811 }
15812
15813 static int
15814 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15815 {
15816   unformat_input_t *i = vam->input;
15817   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15818   f64 timeout;
15819   u32 local_sa_id = 0;
15820   u32 remote_sa_id = 0;
15821   ip4_address_t src_address;
15822   ip4_address_t dst_address;
15823   u8 is_add = 1;
15824
15825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15826     {
15827       if (unformat (i, "local_sa %d", &local_sa_id))
15828         ;
15829       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15830         ;
15831       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15832         ;
15833       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15834         ;
15835       else if (unformat (i, "del"))
15836         is_add = 0;
15837       else
15838         {
15839           clib_warning ("parse error '%U'", format_unformat_error, i);
15840           return -99;
15841         }
15842     }
15843
15844   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15845
15846   mp->local_sa_id = ntohl (local_sa_id);
15847   mp->remote_sa_id = ntohl (remote_sa_id);
15848   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15849   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15850   mp->is_add = is_add;
15851
15852   S;
15853   W;
15854   /* NOTREACHED */
15855   return 0;
15856 }
15857
15858 static int
15859 api_punt (vat_main_t * vam)
15860 {
15861   unformat_input_t *i = vam->input;
15862   vl_api_punt_t *mp;
15863   f64 timeout;
15864   u32 ipv = ~0;
15865   u32 protocol = ~0;
15866   u32 port = ~0;
15867   int is_add = 1;
15868
15869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15870     {
15871       if (unformat (i, "ip %d", &ipv))
15872         ;
15873       else if (unformat (i, "protocol %d", &protocol))
15874         ;
15875       else if (unformat (i, "port %d", &port))
15876         ;
15877       else if (unformat (i, "del"))
15878         is_add = 0;
15879       else
15880         {
15881           clib_warning ("parse error '%U'", format_unformat_error, i);
15882           return -99;
15883         }
15884     }
15885
15886   M (PUNT, punt);
15887
15888   mp->is_add = (u8) is_add;
15889   mp->ipv = (u8) ipv;
15890   mp->l4_protocol = (u8) protocol;
15891   mp->l4_port = htons ((u16) port);
15892
15893   S;
15894   W;
15895   /* NOTREACHED */
15896   return 0;
15897 }
15898
15899 static void vl_api_ipsec_gre_tunnel_details_t_handler
15900   (vl_api_ipsec_gre_tunnel_details_t * mp)
15901 {
15902   vat_main_t *vam = &vat_main;
15903
15904   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15905            ntohl (mp->sw_if_index),
15906            format_ip4_address, &mp->src_address,
15907            format_ip4_address, &mp->dst_address,
15908            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15909 }
15910
15911 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15912   (vl_api_ipsec_gre_tunnel_details_t * mp)
15913 {
15914   vat_main_t *vam = &vat_main;
15915   vat_json_node_t *node = NULL;
15916   struct in_addr ip4;
15917
15918   if (VAT_JSON_ARRAY != vam->json_tree.type)
15919     {
15920       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15921       vat_json_init_array (&vam->json_tree);
15922     }
15923   node = vat_json_array_add (&vam->json_tree);
15924
15925   vat_json_init_object (node);
15926   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15927   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15928   vat_json_object_add_ip4 (node, "src_address", ip4);
15929   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15930   vat_json_object_add_ip4 (node, "dst_address", ip4);
15931   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15932   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15933 }
15934
15935 static int
15936 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15937 {
15938   unformat_input_t *i = vam->input;
15939   vl_api_ipsec_gre_tunnel_dump_t *mp;
15940   f64 timeout;
15941   u32 sw_if_index;
15942   u8 sw_if_index_set = 0;
15943
15944   /* Parse args required to build the message */
15945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15946     {
15947       if (unformat (i, "sw_if_index %d", &sw_if_index))
15948         sw_if_index_set = 1;
15949       else
15950         break;
15951     }
15952
15953   if (sw_if_index_set == 0)
15954     {
15955       sw_if_index = ~0;
15956     }
15957
15958   if (!vam->json_output)
15959     {
15960       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15961                "sw_if_index", "src_address", "dst_address",
15962                "local_sa_id", "remote_sa_id");
15963     }
15964
15965   /* Get list of gre-tunnel interfaces */
15966   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15967
15968   mp->sw_if_index = htonl (sw_if_index);
15969
15970   S;
15971
15972   /* Use a control ping for synchronization */
15973   {
15974     vl_api_control_ping_t *mp;
15975     M (CONTROL_PING, control_ping);
15976     S;
15977   }
15978   W;
15979 }
15980
15981 static int
15982 api_delete_subif (vat_main_t * vam)
15983 {
15984   unformat_input_t *i = vam->input;
15985   vl_api_delete_subif_t *mp;
15986   f64 timeout;
15987   u32 sw_if_index = ~0;
15988
15989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15990     {
15991       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15992         ;
15993       if (unformat (i, "sw_if_index %d", &sw_if_index))
15994         ;
15995       else
15996         break;
15997     }
15998
15999   if (sw_if_index == ~0)
16000     {
16001       errmsg ("missing sw_if_index\n");
16002       return -99;
16003     }
16004
16005   /* Construct the API message */
16006   M (DELETE_SUBIF, delete_subif);
16007   mp->sw_if_index = ntohl (sw_if_index);
16008
16009   S;
16010   W;
16011 }
16012
16013 #define foreach_pbb_vtr_op      \
16014 _("disable",  L2_VTR_DISABLED)  \
16015 _("pop",  L2_VTR_POP_2)         \
16016 _("push",  L2_VTR_PUSH_2)
16017
16018 static int
16019 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16020 {
16021   unformat_input_t *i = vam->input;
16022   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16023   f64 timeout;
16024   u32 sw_if_index = ~0, vtr_op = ~0;
16025   u16 outer_tag = ~0;
16026   u8 dmac[6], smac[6];
16027   u8 dmac_set = 0, smac_set = 0;
16028   u16 vlanid = 0;
16029   u32 sid = ~0;
16030   u32 tmp;
16031
16032   /* Shut up coverity */
16033   memset (dmac, 0, sizeof (dmac));
16034   memset (smac, 0, sizeof (smac));
16035
16036   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16037     {
16038       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16039         ;
16040       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16041         ;
16042       else if (unformat (i, "vtr_op %d", &vtr_op))
16043         ;
16044 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16045       foreach_pbb_vtr_op
16046 #undef _
16047         else if (unformat (i, "translate_pbb_stag"))
16048         {
16049           if (unformat (i, "%d", &tmp))
16050             {
16051               vtr_op = L2_VTR_TRANSLATE_2_1;
16052               outer_tag = tmp;
16053             }
16054           else
16055             {
16056               errmsg
16057                 ("translate_pbb_stag operation requires outer tag definition\n");
16058               return -99;
16059             }
16060         }
16061       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16062         dmac_set++;
16063       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16064         smac_set++;
16065       else if (unformat (i, "sid %d", &sid))
16066         ;
16067       else if (unformat (i, "vlanid %d", &tmp))
16068         vlanid = tmp;
16069       else
16070         {
16071           clib_warning ("parse error '%U'", format_unformat_error, i);
16072           return -99;
16073         }
16074     }
16075
16076   if ((sw_if_index == ~0) || (vtr_op == ~0))
16077     {
16078       errmsg ("missing sw_if_index or vtr operation\n");
16079       return -99;
16080     }
16081   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16082       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16083     {
16084       errmsg
16085         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
16086       return -99;
16087     }
16088
16089   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16090   mp->sw_if_index = ntohl (sw_if_index);
16091   mp->vtr_op = ntohl (vtr_op);
16092   mp->outer_tag = ntohs (outer_tag);
16093   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16094   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16095   mp->b_vlanid = ntohs (vlanid);
16096   mp->i_sid = ntohl (sid);
16097
16098   S;
16099   W;
16100   /* NOTREACHED */
16101   return 0;
16102 }
16103
16104 static int
16105 api_flow_classify_set_interface (vat_main_t * vam)
16106 {
16107   unformat_input_t *i = vam->input;
16108   vl_api_flow_classify_set_interface_t *mp;
16109   f64 timeout;
16110   u32 sw_if_index;
16111   int sw_if_index_set;
16112   u32 ip4_table_index = ~0;
16113   u32 ip6_table_index = ~0;
16114   u8 is_add = 1;
16115
16116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16117     {
16118       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16119         sw_if_index_set = 1;
16120       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16121         sw_if_index_set = 1;
16122       else if (unformat (i, "del"))
16123         is_add = 0;
16124       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16125         ;
16126       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16127         ;
16128       else
16129         {
16130           clib_warning ("parse error '%U'", format_unformat_error, i);
16131           return -99;
16132         }
16133     }
16134
16135   if (sw_if_index_set == 0)
16136     {
16137       errmsg ("missing interface name or sw_if_index\n");
16138       return -99;
16139     }
16140
16141   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16142
16143   mp->sw_if_index = ntohl (sw_if_index);
16144   mp->ip4_table_index = ntohl (ip4_table_index);
16145   mp->ip6_table_index = ntohl (ip6_table_index);
16146   mp->is_add = is_add;
16147
16148   S;
16149   W;
16150   /* NOTREACHED */
16151   return 0;
16152 }
16153
16154 static int
16155 api_flow_classify_dump (vat_main_t * vam)
16156 {
16157   unformat_input_t *i = vam->input;
16158   vl_api_flow_classify_dump_t *mp;
16159   f64 timeout = ~0;
16160   u8 type = FLOW_CLASSIFY_N_TABLES;
16161
16162   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16163     ;
16164   else
16165     {
16166       errmsg ("classify table type must be specified\n");
16167       return -99;
16168     }
16169
16170   if (!vam->json_output)
16171     {
16172       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
16173     }
16174
16175   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16176   mp->type = type;
16177   /* send it... */
16178   S;
16179
16180   /* Use a control ping for synchronization */
16181   {
16182     vl_api_control_ping_t *mp;
16183     M (CONTROL_PING, control_ping);
16184     S;
16185   }
16186   /* Wait for a reply... */
16187   W;
16188
16189   /* NOTREACHED */
16190   return 0;
16191 }
16192
16193 static int
16194 api_feature_enable_disable (vat_main_t * vam)
16195 {
16196   unformat_input_t *i = vam->input;
16197   vl_api_feature_enable_disable_t *mp;
16198   f64 timeout;
16199   u8 *arc_name = 0;
16200   u8 *feature_name = 0;
16201   u32 sw_if_index = ~0;
16202   u8 enable = 1;
16203
16204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16205     {
16206       if (unformat (i, "arc_name %s", &arc_name))
16207         ;
16208       else if (unformat (i, "feature_name %s", &feature_name))
16209         ;
16210       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16211         ;
16212       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16213         ;
16214       else if (unformat (i, "disable"))
16215         enable = 0;
16216       else
16217         break;
16218     }
16219
16220   if (arc_name == 0)
16221     {
16222       errmsg ("missing arc name\n");
16223       return -99;
16224     }
16225   if (vec_len (arc_name) > 63)
16226     {
16227       errmsg ("arc name too long\n");
16228     }
16229
16230   if (feature_name == 0)
16231     {
16232       errmsg ("missing feature name\n");
16233       return -99;
16234     }
16235   if (vec_len (feature_name) > 63)
16236     {
16237       errmsg ("feature name too long\n");
16238     }
16239
16240   if (sw_if_index == ~0)
16241     {
16242       errmsg ("missing interface name or sw_if_index\n");
16243       return -99;
16244     }
16245
16246   /* Construct the API message */
16247   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16248   mp->sw_if_index = ntohl (sw_if_index);
16249   mp->enable = enable;
16250   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16251   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16252   vec_free (arc_name);
16253   vec_free (feature_name);
16254
16255   S;
16256   W;
16257 }
16258
16259 static int
16260 api_sw_interface_tag_add_del (vat_main_t * vam)
16261 {
16262   unformat_input_t *i = vam->input;
16263   vl_api_sw_interface_tag_add_del_t *mp;
16264   f64 timeout;
16265   u32 sw_if_index = ~0;
16266   u8 *tag = 0;
16267   u8 enable = 1;
16268
16269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16270     {
16271       if (unformat (i, "tag %s", &tag))
16272         ;
16273       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16274         ;
16275       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16276         ;
16277       else if (unformat (i, "del"))
16278         enable = 0;
16279       else
16280         break;
16281     }
16282
16283   if (sw_if_index == ~0)
16284     {
16285       errmsg ("missing interface name or sw_if_index\n");
16286       return -99;
16287     }
16288
16289   if (enable && (tag == 0))
16290     {
16291       errmsg ("no tag specified\n");
16292       return -99;
16293     }
16294
16295   /* Construct the API message */
16296   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
16297   mp->sw_if_index = ntohl (sw_if_index);
16298   mp->is_add = enable;
16299   if (enable)
16300     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
16301   vec_free (tag);
16302
16303   S;
16304   W;
16305 }
16306
16307 static int
16308 q_or_quit (vat_main_t * vam)
16309 {
16310   longjmp (vam->jump_buf, 1);
16311   return 0;                     /* not so much */
16312 }
16313
16314 static int
16315 q (vat_main_t * vam)
16316 {
16317   return q_or_quit (vam);
16318 }
16319
16320 static int
16321 quit (vat_main_t * vam)
16322 {
16323   return q_or_quit (vam);
16324 }
16325
16326 static int
16327 comment (vat_main_t * vam)
16328 {
16329   return 0;
16330 }
16331
16332 static int
16333 cmd_cmp (void *a1, void *a2)
16334 {
16335   u8 **c1 = a1;
16336   u8 **c2 = a2;
16337
16338   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
16339 }
16340
16341 static int
16342 help (vat_main_t * vam)
16343 {
16344   u8 **cmds = 0;
16345   u8 *name = 0;
16346   hash_pair_t *p;
16347   unformat_input_t *i = vam->input;
16348   int j;
16349
16350   if (unformat (i, "%s", &name))
16351     {
16352       uword *hs;
16353
16354       vec_add1 (name, 0);
16355
16356       hs = hash_get_mem (vam->help_by_name, name);
16357       if (hs)
16358         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
16359       else
16360         fformat (vam->ofp, "No such msg / command '%s'\n", name);
16361       vec_free (name);
16362       return 0;
16363     }
16364
16365   fformat (vam->ofp, "Help is available for the following:\n");
16366
16367     /* *INDENT-OFF* */
16368     hash_foreach_pair (p, vam->function_by_name,
16369     ({
16370       vec_add1 (cmds, (u8 *)(p->key));
16371     }));
16372     /* *INDENT-ON* */
16373
16374   vec_sort_with_function (cmds, cmd_cmp);
16375
16376   for (j = 0; j < vec_len (cmds); j++)
16377     fformat (vam->ofp, "%s\n", cmds[j]);
16378
16379   vec_free (cmds);
16380   return 0;
16381 }
16382
16383 static int
16384 set (vat_main_t * vam)
16385 {
16386   u8 *name = 0, *value = 0;
16387   unformat_input_t *i = vam->input;
16388
16389   if (unformat (i, "%s", &name))
16390     {
16391       /* The input buffer is a vector, not a string. */
16392       value = vec_dup (i->buffer);
16393       vec_delete (value, i->index, 0);
16394       /* Almost certainly has a trailing newline */
16395       if (value[vec_len (value) - 1] == '\n')
16396         value[vec_len (value) - 1] = 0;
16397       /* Make sure it's a proper string, one way or the other */
16398       vec_add1 (value, 0);
16399       (void) clib_macro_set_value (&vam->macro_main,
16400                                    (char *) name, (char *) value);
16401     }
16402   else
16403     errmsg ("usage: set <name> <value>\n");
16404
16405   vec_free (name);
16406   vec_free (value);
16407   return 0;
16408 }
16409
16410 static int
16411 unset (vat_main_t * vam)
16412 {
16413   u8 *name = 0;
16414
16415   if (unformat (vam->input, "%s", &name))
16416     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
16417       errmsg ("unset: %s wasn't set\n", name);
16418   vec_free (name);
16419   return 0;
16420 }
16421
16422 typedef struct
16423 {
16424   u8 *name;
16425   u8 *value;
16426 } macro_sort_t;
16427
16428
16429 static int
16430 macro_sort_cmp (void *a1, void *a2)
16431 {
16432   macro_sort_t *s1 = a1;
16433   macro_sort_t *s2 = a2;
16434
16435   return strcmp ((char *) (s1->name), (char *) (s2->name));
16436 }
16437
16438 static int
16439 dump_macro_table (vat_main_t * vam)
16440 {
16441   macro_sort_t *sort_me = 0, *sm;
16442   int i;
16443   hash_pair_t *p;
16444
16445     /* *INDENT-OFF* */
16446     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
16447     ({
16448       vec_add2 (sort_me, sm, 1);
16449       sm->name = (u8 *)(p->key);
16450       sm->value = (u8 *) (p->value[0]);
16451     }));
16452     /* *INDENT-ON* */
16453
16454   vec_sort_with_function (sort_me, macro_sort_cmp);
16455
16456   if (vec_len (sort_me))
16457     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
16458   else
16459     fformat (vam->ofp, "The macro table is empty...\n");
16460
16461   for (i = 0; i < vec_len (sort_me); i++)
16462     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
16463   return 0;
16464 }
16465
16466 static int
16467 dump_node_table (vat_main_t * vam)
16468 {
16469   int i, j;
16470   vlib_node_t *node, *next_node;
16471
16472   if (vec_len (vam->graph_nodes) == 0)
16473     {
16474       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16475       return 0;
16476     }
16477
16478   for (i = 0; i < vec_len (vam->graph_nodes); i++)
16479     {
16480       node = vam->graph_nodes[i];
16481       fformat (vam->ofp, "[%d] %s\n", i, node->name);
16482       for (j = 0; j < vec_len (node->next_nodes); j++)
16483         {
16484           if (node->next_nodes[j] != ~0)
16485             {
16486               next_node = vam->graph_nodes[node->next_nodes[j]];
16487               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16488             }
16489         }
16490     }
16491   return 0;
16492 }
16493
16494 static int
16495 value_sort_cmp (void *a1, void *a2)
16496 {
16497   name_sort_t *n1 = a1;
16498   name_sort_t *n2 = a2;
16499
16500   if (n1->value < n2->value)
16501     return -1;
16502   if (n1->value > n2->value)
16503     return 1;
16504   return 0;
16505 }
16506
16507
16508 static int
16509 dump_msg_api_table (vat_main_t * vam)
16510 {
16511   api_main_t *am = &api_main;
16512   name_sort_t *nses = 0, *ns;
16513   hash_pair_t *hp;
16514   int i;
16515
16516   /* *INDENT-OFF* */
16517   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
16518   ({
16519     vec_add2 (nses, ns, 1);
16520     ns->name = (u8 *)(hp->key);
16521     ns->value = (u32) hp->value[0];
16522   }));
16523   /* *INDENT-ON* */
16524
16525   vec_sort_with_function (nses, value_sort_cmp);
16526
16527   for (i = 0; i < vec_len (nses); i++)
16528     fformat (vam->ofp, " [%d]: %s\n", nses[i].value, nses[i].name);
16529   vec_free (nses);
16530   return 0;
16531 }
16532
16533 static int
16534 get_msg_id (vat_main_t * vam)
16535 {
16536   u8 *name_and_crc;
16537   u32 message_index;
16538
16539   if (unformat (vam->input, "%s", &name_and_crc))
16540     {
16541       message_index = vl_api_get_msg_index (name_and_crc);
16542       if (message_index == ~0)
16543         {
16544           fformat (vam->ofp, " '%s' not found\n", name_and_crc);
16545           return 0;
16546         }
16547       fformat (vam->ofp, " '%s' has message index %d\n",
16548                name_and_crc, message_index);
16549       return 0;
16550     }
16551   errmsg ("name_and_crc required...\n");
16552   return 0;
16553 }
16554
16555 static int
16556 search_node_table (vat_main_t * vam)
16557 {
16558   unformat_input_t *line_input = vam->input;
16559   u8 *node_to_find;
16560   int j;
16561   vlib_node_t *node, *next_node;
16562   uword *p;
16563
16564   if (vam->graph_node_index_by_name == 0)
16565     {
16566       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16567       return 0;
16568     }
16569
16570   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16571     {
16572       if (unformat (line_input, "%s", &node_to_find))
16573         {
16574           vec_add1 (node_to_find, 0);
16575           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
16576           if (p == 0)
16577             {
16578               fformat (vam->ofp, "%s not found...\n", node_to_find);
16579               goto out;
16580             }
16581           node = vam->graph_nodes[p[0]];
16582           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
16583           for (j = 0; j < vec_len (node->next_nodes); j++)
16584             {
16585               if (node->next_nodes[j] != ~0)
16586                 {
16587                   next_node = vam->graph_nodes[node->next_nodes[j]];
16588                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16589                 }
16590             }
16591         }
16592
16593       else
16594         {
16595           clib_warning ("parse error '%U'", format_unformat_error,
16596                         line_input);
16597           return -99;
16598         }
16599
16600     out:
16601       vec_free (node_to_find);
16602
16603     }
16604
16605   return 0;
16606 }
16607
16608
16609 static int
16610 script (vat_main_t * vam)
16611 {
16612   u8 *s = 0;
16613   char *save_current_file;
16614   unformat_input_t save_input;
16615   jmp_buf save_jump_buf;
16616   u32 save_line_number;
16617
16618   FILE *new_fp, *save_ifp;
16619
16620   if (unformat (vam->input, "%s", &s))
16621     {
16622       new_fp = fopen ((char *) s, "r");
16623       if (new_fp == 0)
16624         {
16625           errmsg ("Couldn't open script file %s\n", s);
16626           vec_free (s);
16627           return -99;
16628         }
16629     }
16630   else
16631     {
16632       errmsg ("Missing script name\n");
16633       return -99;
16634     }
16635
16636   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
16637   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
16638   save_ifp = vam->ifp;
16639   save_line_number = vam->input_line_number;
16640   save_current_file = (char *) vam->current_file;
16641
16642   vam->input_line_number = 0;
16643   vam->ifp = new_fp;
16644   vam->current_file = s;
16645   do_one_file (vam);
16646
16647   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
16648   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
16649   vam->ifp = save_ifp;
16650   vam->input_line_number = save_line_number;
16651   vam->current_file = (u8 *) save_current_file;
16652   vec_free (s);
16653
16654   return 0;
16655 }
16656
16657 static int
16658 echo (vat_main_t * vam)
16659 {
16660   fformat (vam->ofp, "%v", vam->input->buffer);
16661   return 0;
16662 }
16663
16664 /* List of API message constructors, CLI names map to api_xxx */
16665 #define foreach_vpe_api_msg                                             \
16666 _(create_loopback,"[mac <mac-addr>]")                                   \
16667 _(sw_interface_dump,"")                                                 \
16668 _(sw_interface_set_flags,                                               \
16669   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
16670 _(sw_interface_add_del_address,                                         \
16671   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
16672 _(sw_interface_set_table,                                               \
16673   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
16674 _(sw_interface_set_mpls_enable,                                                \
16675   "<intfc> | sw_if_index [disable | dis]")                                \
16676 _(sw_interface_set_vpath,                                               \
16677   "<intfc> | sw_if_index <id> enable | disable")                        \
16678 _(sw_interface_set_vxlan_bypass,                                               \
16679   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")                        \
16680 _(sw_interface_set_l2_xconnect,                                         \
16681   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16682   "enable | disable")                                                   \
16683 _(sw_interface_set_l2_bridge,                                           \
16684   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16685   "[shg <split-horizon-group>] [bvi]\n"                                 \
16686   "enable | disable")                                                   \
16687 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16688   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16689   "profile <profile-id>\n")                                             \
16690 _(sw_interface_set_dpdk_hqos_subport,                                   \
16691   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16692   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16693 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16694   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16695 _(bridge_domain_add_del,                                                \
16696   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16697 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16698 _(l2fib_add_del,                                                        \
16699   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16700 _(l2_flags,                                                             \
16701   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16702 _(bridge_flags,                                                         \
16703   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16704 _(tap_connect,                                                          \
16705   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
16706 _(tap_modify,                                                           \
16707   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16708 _(tap_delete,                                                           \
16709   "<vpp-if-name> | sw_if_index <id>")                                   \
16710 _(sw_interface_tap_dump, "")                                            \
16711 _(ip_add_del_route,                                                     \
16712   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
16713   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16714   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16715   "[multipath] [count <n>]")                                            \
16716 _(mpls_route_add_del,                                                   \
16717   "<label> <eos> via <addr> [table-id <n>]\n"                           \
16718   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16719   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16720   "[multipath] [count <n>]")                                            \
16721 _(mpls_ip_bind_unbind,                                                  \
16722   "<label> <addr/len>")                                                 \
16723 _(mpls_tunnel_add_del,                                                  \
16724   " via <addr> [table-id <n>]\n"                                        \
16725   "sw_if_index <id>] [l2]  [del]")                                      \
16726 _(proxy_arp_add_del,                                                    \
16727   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16728 _(proxy_arp_intfc_enable_disable,                                       \
16729   "<intfc> | sw_if_index <id> enable | disable")                        \
16730 _(sw_interface_set_unnumbered,                                          \
16731   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16732 _(ip_neighbor_add_del,                                                  \
16733   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16734   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16735 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16736 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16737 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16738   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16739   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16740   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16741 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16742 _(reset_fib, "vrf <n> [ipv6]")                                          \
16743 _(dhcp_proxy_config,                                                    \
16744   "svr <v46-address> src <v46-address>\n"                               \
16745    "insert-cid <n> [del]")                                              \
16746 _(dhcp_proxy_config_2,                                                  \
16747   "svr <v46-address> src <v46-address>\n"                               \
16748    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16749 _(dhcp_proxy_set_vss,                                                   \
16750   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16751 _(dhcp_client_config,                                                   \
16752   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16753 _(set_ip_flow_hash,                                                     \
16754   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16755 _(sw_interface_ip6_enable_disable,                                      \
16756   "<intfc> | sw_if_index <id> enable | disable")                        \
16757 _(sw_interface_ip6_set_link_local_address,                              \
16758   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16759 _(sw_interface_ip6nd_ra_prefix,                                         \
16760   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16761   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16762   "[nolink] [isno]")                                                    \
16763 _(sw_interface_ip6nd_ra_config,                                         \
16764   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16765   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16766   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16767 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16768 _(l2_patch_add_del,                                                     \
16769   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16770   "enable | disable")                                                   \
16771 _(sr_tunnel_add_del,                                                    \
16772   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16773   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16774   "[policy <policy_name>]")                                             \
16775 _(sr_policy_add_del,                                                    \
16776   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16777 _(sr_multicast_map_add_del,                                             \
16778   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16779 _(classify_add_del_table,                                               \
16780   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16781   " [del] mask <mask-value>\n"                                          \
16782   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
16783   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
16784 _(classify_add_del_session,                                             \
16785   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16786   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16787   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
16788   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
16789 _(classify_set_interface_ip_table,                                      \
16790   "<intfc> | sw_if_index <nn> table <nn>")                              \
16791 _(classify_set_interface_l2_tables,                                     \
16792   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16793   "  [other-table <nn>]")                                               \
16794 _(get_node_index, "node <node-name")                                    \
16795 _(add_node_next, "node <node-name> next <next-node-name>")              \
16796 _(l2tpv3_create_tunnel,                                                 \
16797   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16798   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16799   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16800 _(l2tpv3_set_tunnel_cookies,                                            \
16801   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16802   "[new_remote_cookie <nn>]\n")                                         \
16803 _(l2tpv3_interface_enable_disable,                                      \
16804   "<intfc> | sw_if_index <nn> enable | disable")                        \
16805 _(l2tpv3_set_lookup_key,                                                \
16806   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16807 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16808 _(vxlan_add_del_tunnel,                                                 \
16809   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
16810   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
16811   "vni <vni> [encap-vrf-id <nn>] [decap-next l2|ip4|ip6] [del]")        \
16812 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16813 _(gre_add_del_tunnel,                                                   \
16814   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16815 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16816 _(l2_fib_clear_table, "")                                               \
16817 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16818 _(l2_interface_vlan_tag_rewrite,                                        \
16819   "<intfc> | sw_if_index <nn> \n"                                       \
16820   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
16821   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
16822 _(create_vhost_user_if,                                                 \
16823         "socket <filename> [server] [renumber <dev_instance>] "         \
16824         "[mac <mac_address>]")                                          \
16825 _(modify_vhost_user_if,                                                 \
16826         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
16827         "[server] [renumber <dev_instance>]")                           \
16828 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
16829 _(sw_interface_vhost_user_dump, "")                                     \
16830 _(show_version, "")                                                     \
16831 _(vxlan_gpe_add_del_tunnel,                                             \
16832   "local <addr> remote <addr> vni <nn>\n"                               \
16833     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
16834   "[next-ethernet] [next-nsh]\n")                                       \
16835 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
16836 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
16837 _(interface_name_renumber,                                              \
16838   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
16839 _(input_acl_set_interface,                                              \
16840   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16841   "  [l2-table <nn>] [del]")                                            \
16842 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
16843 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
16844 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
16845 _(ip_dump, "ipv4 | ipv6")                                               \
16846 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
16847 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
16848   "  spid_id <n> ")                                                     \
16849 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
16850   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
16851   "  integ_alg <alg> integ_key <hex>")                                  \
16852 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
16853   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
16854   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
16855   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
16856 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
16857 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
16858 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
16859   "(auth_data 0x<data> | auth_data <data>)")                            \
16860 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
16861   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
16862 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16863   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16864   "(local|remote)")                                                     \
16865 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16866 _(delete_loopback,"sw_if_index <nn>")                                   \
16867 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16868 _(map_add_domain,                                                       \
16869   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16870   "ip6-src <ip6addr> "                                                  \
16871   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16872 _(map_del_domain, "index <n>")                                          \
16873 _(map_add_del_rule,                                                     \
16874   "index <n> psid <n> dst <ip6addr> [del]")                             \
16875 _(map_domain_dump, "")                                                  \
16876 _(map_rule_dump, "index <map-domain>")                                  \
16877 _(want_interface_events,  "enable|disable")                             \
16878 _(want_stats,"enable|disable")                                          \
16879 _(get_first_msg_id, "client <name>")                                    \
16880 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16881 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16882   "fib-id <nn> [ip4][ip6][default]")                                    \
16883 _(get_node_graph, " ")                                                  \
16884 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16885 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16886 _(ioam_disable, "")                                                \
16887 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16888                             " sw_if_index <sw_if_index> p <priority> "  \
16889                             "w <weight>] [del]")                        \
16890 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16891                         "iface <intf> | sw_if_index <sw_if_index> "     \
16892                         "p <priority> w <weight> [del]")                \
16893 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16894                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16895                           "locator-set <locator_name> [del]")           \
16896 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16897   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16898 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16899 _(lisp_gpe_enable_disable, "enable|disable")                            \
16900 _(lisp_enable_disable, "enable|disable")                                \
16901 _(lisp_gpe_add_del_iface, "up|down")                                    \
16902 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
16903                                "[seid <seid>] "                         \
16904                                "rloc <locator> p <prio> "               \
16905                                "w <weight> [rloc <loc> ... ] "          \
16906                                "action <action> [del-all]")             \
16907 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
16908                           "<local-eid>")                                \
16909 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16910 _(lisp_map_request_mode, "src-dst|dst-only")                            \
16911 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16912 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16913 _(lisp_locator_set_dump, "[local | remote]")                            \
16914 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
16915 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16916                        "[local] | [remote]")                            \
16917 _(lisp_eid_table_vni_dump, "")                                          \
16918 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16919 _(lisp_gpe_tunnel_dump, "")                                             \
16920 _(lisp_map_resolver_dump, "")                                           \
16921 _(lisp_adjacencies_get, "vni <vni>")                                    \
16922 _(show_lisp_status, "")                                                 \
16923 _(lisp_get_map_request_itr_rlocs, "")                                   \
16924 _(show_lisp_pitr, "")                                                   \
16925 _(show_lisp_map_request_mode, "")                                       \
16926 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16927 _(af_packet_delete, "name <host interface name>")                       \
16928 _(policer_add_del, "name <policer name> <params> [del]")                \
16929 _(policer_dump, "[name <policer name>]")                                \
16930 _(policer_classify_set_interface,                                       \
16931   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16932   "  [l2-table <nn>] [del]")                                            \
16933 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16934 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16935     "[master|slave]")                                                   \
16936 _(netmap_delete, "name <interface name>")                               \
16937 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
16938 _(mpls_fib_dump, "")                                                    \
16939 _(classify_table_ids, "")                                               \
16940 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16941 _(classify_table_info, "table_id <nn>")                                 \
16942 _(classify_session_dump, "table_id <nn>")                               \
16943 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
16944     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
16945     "[template_interval <nn>] [udp_checksum]")                          \
16946 _(ipfix_exporter_dump, "")                                              \
16947 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
16948 _(ipfix_classify_stream_dump, "")                                       \
16949 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
16950 _(ipfix_classify_table_dump, "")                                        \
16951 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [[dst <intfc> | dst_sw_if_index <id>] | disable]") \
16952 _(sw_interface_span_dump, "")                                           \
16953 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
16954 _(pg_create_interface, "if_id <nn>")                                    \
16955 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
16956 _(pg_enable_disable, "[stream <id>] disable")                           \
16957 _(ip_source_and_port_range_check_add_del,                               \
16958   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
16959 _(ip_source_and_port_range_check_interface_add_del,                     \
16960   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
16961   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
16962 _(ipsec_gre_add_del_tunnel,                                             \
16963   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
16964 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
16965 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
16966 _(l2_interface_pbb_tag_rewrite,                                         \
16967   "<intfc> | sw_if_index <nn> \n"                                       \
16968   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
16969   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
16970 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
16971 _(flow_classify_set_interface,                                          \
16972   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
16973 _(flow_classify_dump, "type [ip4|ip6]")                                 \
16974 _(ip_fib_dump, "")                                                      \
16975 _(ip6_fib_dump, "")                                                     \
16976 _(feature_enable_disable, "arc_name <arc_name> "                        \
16977   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
16978 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
16979 "[disable]")
16980
16981 /* List of command functions, CLI names map directly to functions */
16982 #define foreach_cli_function                                    \
16983 _(comment, "usage: comment <ignore-rest-of-line>")              \
16984 _(dump_interface_table, "usage: dump_interface_table")          \
16985 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
16986 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
16987 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
16988 _(dump_stats_table, "usage: dump_stats_table")                  \
16989 _(dump_macro_table, "usage: dump_macro_table ")                 \
16990 _(dump_node_table, "usage: dump_node_table")                    \
16991 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
16992 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
16993 _(echo, "usage: echo <message>")                                \
16994 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
16995 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
16996 _(help, "usage: help")                                          \
16997 _(q, "usage: quit")                                             \
16998 _(quit, "usage: quit")                                          \
16999 _(search_node_table, "usage: search_node_table <name>...")      \
17000 _(set, "usage: set <variable-name> <value>")                    \
17001 _(script, "usage: script <file-name>")                          \
17002 _(unset, "usage: unset <variable-name>")
17003
17004 #define _(N,n)                                  \
17005     static void vl_api_##n##_t_handler_uni      \
17006     (vl_api_##n##_t * mp)                       \
17007     {                                           \
17008         vat_main_t * vam = &vat_main;           \
17009         if (vam->json_output) {                 \
17010             vl_api_##n##_t_handler_json(mp);    \
17011         } else {                                \
17012             vl_api_##n##_t_handler(mp);         \
17013         }                                       \
17014     }
17015 foreach_vpe_api_reply_msg;
17016 #undef _
17017
17018 void
17019 vat_api_hookup (vat_main_t * vam)
17020 {
17021 #define _(N,n)                                                  \
17022     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17023                            vl_api_##n##_t_handler_uni,          \
17024                            vl_noop_handler,                     \
17025                            vl_api_##n##_t_endian,               \
17026                            vl_api_##n##_t_print,                \
17027                            sizeof(vl_api_##n##_t), 1);
17028   foreach_vpe_api_reply_msg;
17029 #undef _
17030
17031   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17032
17033   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17034
17035   vam->function_by_name = hash_create_string (0, sizeof (uword));
17036
17037   vam->help_by_name = hash_create_string (0, sizeof (uword));
17038
17039   /* API messages we can send */
17040 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17041   foreach_vpe_api_msg;
17042 #undef _
17043
17044   /* Help strings */
17045 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17046   foreach_vpe_api_msg;
17047 #undef _
17048
17049   /* CLI functions */
17050 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17051   foreach_cli_function;
17052 #undef _
17053
17054   /* Help strings */
17055 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17056   foreach_cli_function;
17057 #undef _
17058 }
17059
17060 #undef vl_api_version
17061 #define vl_api_version(n,v) static u32 memory_api_version = v;
17062 #include <vlibmemory/vl_memory_api_h.h>
17063 #undef vl_api_version
17064
17065 #undef vl_api_version
17066 #define vl_api_version(n,v) static u32 vnet_interface_api_version = v;
17067 #include <vnet/interface.api.h>
17068 #undef vl_api_version
17069
17070 #undef vl_api_version
17071 #define vl_api_version(n,v) static u32 vpp_api_version = v;
17072 #include <vpp-api/vpe.api.h>
17073 #undef vl_api_version
17074
17075 static u32 *api_versions[] = {
17076   &memory_api_version,
17077   &vnet_interface_api_version,
17078   &vpp_api_version,
17079 };
17080
17081 void
17082 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
17083 {
17084   int i;
17085
17086   ASSERT (ARRAY_LEN (mp->api_versions) >= ARRAY_LEN (api_versions));
17087
17088   /*
17089    * Send the API signatures. This bit of code must
17090    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
17091    */
17092
17093   for (i = 0; i < ARRAY_LEN (api_versions); i++)
17094     mp->api_versions[i] = clib_host_to_net_u32 (*api_versions[i]);
17095 }
17096
17097 /*
17098  * fd.io coding-style-patch-verification: ON
17099  *
17100  * Local Variables:
17101  * eval: (c-set-style "gnu")
17102  * End:
17103  */