ipsec: remove dependency on DPDK > 0
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248   u32 *r = va_arg (*args, u32 *);
249
250   if (0);
251 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
252   foreach_ipsec_policy_action
253 #undef _
254     else
255     return 0;
256   return 1;
257 }
258
259 uword
260 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
261 {
262   u32 *r = va_arg (*args, u32 *);
263
264   if (0);
265 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
266   foreach_ipsec_crypto_alg
267 #undef _
268     else
269     return 0;
270   return 1;
271 }
272
273 u8 *
274 format_ipsec_crypto_alg (u8 * s, va_list * args)
275 {
276   u32 i = va_arg (*args, u32);
277   u8 *t = 0;
278
279   switch (i)
280     {
281 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
282       foreach_ipsec_crypto_alg
283 #undef _
284     default:
285       return format (s, "unknown");
286     }
287   return format (s, "%s", t);
288 }
289
290 uword
291 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
292 {
293   u32 *r = va_arg (*args, u32 *);
294
295   if (0);
296 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
297   foreach_ipsec_integ_alg
298 #undef _
299     else
300     return 0;
301   return 1;
302 }
303
304 u8 *
305 format_ipsec_integ_alg (u8 * s, va_list * args)
306 {
307   u32 i = va_arg (*args, u32);
308   u8 *t = 0;
309
310   switch (i)
311     {
312 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
313       foreach_ipsec_integ_alg
314 #undef _
315     default:
316       return format (s, "unknown");
317     }
318   return format (s, "%s", t);
319 }
320
321 uword
322 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
323 {
324   u32 *r = va_arg (*args, u32 *);
325
326   if (0);
327 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
328   foreach_ikev2_auth_method
329 #undef _
330     else
331     return 0;
332   return 1;
333 }
334
335 uword
336 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
337 {
338   u32 *r = va_arg (*args, u32 *);
339
340   if (0);
341 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
342   foreach_ikev2_id_type
343 #undef _
344     else
345     return 0;
346   return 1;
347 }
348
349 uword
350 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
351 {
352   u8 *r = va_arg (*args, u8 *);
353
354   if (unformat (input, "kbps"))
355     *r = SSE2_QOS_RATE_KBPS;
356   else if (unformat (input, "pps"))
357     *r = SSE2_QOS_RATE_PPS;
358   else
359     return 0;
360   return 1;
361 }
362
363 uword
364 unformat_policer_round_type (unformat_input_t * input, va_list * args)
365 {
366   u8 *r = va_arg (*args, u8 *);
367
368   if (unformat (input, "closest"))
369     *r = SSE2_QOS_ROUND_TO_CLOSEST;
370   else if (unformat (input, "up"))
371     *r = SSE2_QOS_ROUND_TO_UP;
372   else if (unformat (input, "down"))
373     *r = SSE2_QOS_ROUND_TO_DOWN;
374   else
375     return 0;
376   return 1;
377 }
378
379 uword
380 unformat_policer_type (unformat_input_t * input, va_list * args)
381 {
382   u8 *r = va_arg (*args, u8 *);
383
384   if (unformat (input, "1r2c"))
385     *r = SSE2_QOS_POLICER_TYPE_1R2C;
386   else if (unformat (input, "1r3c"))
387     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
388   else if (unformat (input, "2r3c-2698"))
389     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
390   else if (unformat (input, "2r3c-4115"))
391     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
392   else if (unformat (input, "2r3c-mef5cf1"))
393     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
394   else
395     return 0;
396   return 1;
397 }
398
399 uword
400 unformat_dscp (unformat_input_t * input, va_list * va)
401 {
402   u8 *r = va_arg (*va, u8 *);
403
404   if (0);
405 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
406   foreach_vnet_dscp
407 #undef _
408     else
409     return 0;
410   return 1;
411 }
412
413 uword
414 unformat_policer_action_type (unformat_input_t * input, va_list * va)
415 {
416   sse2_qos_pol_action_params_st *a
417     = va_arg (*va, sse2_qos_pol_action_params_st *);
418
419   if (unformat (input, "drop"))
420     a->action_type = SSE2_QOS_ACTION_DROP;
421   else if (unformat (input, "transmit"))
422     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
423   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
424     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
425   else
426     return 0;
427   return 1;
428 }
429
430 uword
431 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
432 {
433   u32 *r = va_arg (*va, u32 *);
434   u32 tid;
435
436   if (unformat (input, "ip4"))
437     tid = POLICER_CLASSIFY_TABLE_IP4;
438   else if (unformat (input, "ip6"))
439     tid = POLICER_CLASSIFY_TABLE_IP6;
440   else if (unformat (input, "l2"))
441     tid = POLICER_CLASSIFY_TABLE_L2;
442   else
443     return 0;
444
445   *r = tid;
446   return 1;
447 }
448
449 uword
450 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
451 {
452   u32 *r = va_arg (*va, u32 *);
453   u32 tid;
454
455   if (unformat (input, "ip4"))
456     tid = FLOW_CLASSIFY_TABLE_IP4;
457   else if (unformat (input, "ip6"))
458     tid = FLOW_CLASSIFY_TABLE_IP6;
459   else
460     return 0;
461
462   *r = tid;
463   return 1;
464 }
465
466 u8 *
467 format_ip4_address (u8 * s, va_list * args)
468 {
469   u8 *a = va_arg (*args, u8 *);
470   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
471 }
472
473 u8 *
474 format_ip6_address (u8 * s, va_list * args)
475 {
476   ip6_address_t *a = va_arg (*args, ip6_address_t *);
477   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
478
479   i_max_n_zero = ARRAY_LEN (a->as_u16);
480   max_n_zeros = 0;
481   i_first_zero = i_max_n_zero;
482   n_zeros = 0;
483   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
484     {
485       u32 is_zero = a->as_u16[i] == 0;
486       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
487         {
488           i_first_zero = i;
489           n_zeros = 0;
490         }
491       n_zeros += is_zero;
492       if ((!is_zero && n_zeros > max_n_zeros)
493           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
494         {
495           i_max_n_zero = i_first_zero;
496           max_n_zeros = n_zeros;
497           i_first_zero = ARRAY_LEN (a->as_u16);
498           n_zeros = 0;
499         }
500     }
501
502   last_double_colon = 0;
503   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
504     {
505       if (i == i_max_n_zero && max_n_zeros > 1)
506         {
507           s = format (s, "::");
508           i += max_n_zeros - 1;
509           last_double_colon = 1;
510         }
511       else
512         {
513           s = format (s, "%s%x",
514                       (last_double_colon || i == 0) ? "" : ":",
515                       clib_net_to_host_u16 (a->as_u16[i]));
516           last_double_colon = 0;
517         }
518     }
519
520   return s;
521 }
522
523 /* Format an IP46 address. */
524 u8 *
525 format_ip46_address (u8 * s, va_list * args)
526 {
527   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
528   ip46_type_t type = va_arg (*args, ip46_type_t);
529   int is_ip4 = 1;
530
531   switch (type)
532     {
533     case IP46_TYPE_ANY:
534       is_ip4 = ip46_address_is_ip4 (ip46);
535       break;
536     case IP46_TYPE_IP4:
537       is_ip4 = 1;
538       break;
539     case IP46_TYPE_IP6:
540       is_ip4 = 0;
541       break;
542     }
543
544   return is_ip4 ?
545     format (s, "%U", format_ip4_address, &ip46->ip4) :
546     format (s, "%U", format_ip6_address, &ip46->ip6);
547 }
548
549 u8 *
550 format_ethernet_address (u8 * s, va_list * args)
551 {
552   u8 *a = va_arg (*args, u8 *);
553
554   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
555                  a[0], a[1], a[2], a[3], a[4], a[5]);
556 }
557
558 void
559 increment_v4_address (ip4_address_t * a)
560 {
561   u32 v;
562
563   v = ntohl (a->as_u32) + 1;
564   a->as_u32 = ntohl (v);
565 }
566
567 void
568 increment_v6_address (ip6_address_t * a)
569 {
570   u64 v0, v1;
571
572   v0 = clib_net_to_host_u64 (a->as_u64[0]);
573   v1 = clib_net_to_host_u64 (a->as_u64[1]);
574
575   v1 += 1;
576   if (v1 == 0)
577     v0 += 1;
578   a->as_u64[0] = clib_net_to_host_u64 (v0);
579   a->as_u64[1] = clib_net_to_host_u64 (v1);
580 }
581
582 void
583 increment_mac_address (u64 * mac)
584 {
585   u64 tmp = *mac;
586
587   tmp = clib_net_to_host_u64 (tmp);
588   tmp += 1 << 16;               /* skip unused (least significant) octets */
589   tmp = clib_host_to_net_u64 (tmp);
590   *mac = tmp;
591 }
592
593 static void vl_api_create_loopback_reply_t_handler
594   (vl_api_create_loopback_reply_t * mp)
595 {
596   vat_main_t *vam = &vat_main;
597   i32 retval = ntohl (mp->retval);
598
599   vam->retval = retval;
600   vam->regenerate_interface_table = 1;
601   vam->sw_if_index = ntohl (mp->sw_if_index);
602   vam->result_ready = 1;
603 }
604
605 static void vl_api_create_loopback_reply_t_handler_json
606   (vl_api_create_loopback_reply_t * mp)
607 {
608   vat_main_t *vam = &vat_main;
609   vat_json_node_t node;
610
611   vat_json_init_object (&node);
612   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
613   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
614
615   vat_json_print (vam->ofp, &node);
616   vat_json_free (&node);
617   vam->retval = ntohl (mp->retval);
618   vam->result_ready = 1;
619 }
620
621 static void vl_api_af_packet_create_reply_t_handler
622   (vl_api_af_packet_create_reply_t * mp)
623 {
624   vat_main_t *vam = &vat_main;
625   i32 retval = ntohl (mp->retval);
626
627   vam->retval = retval;
628   vam->regenerate_interface_table = 1;
629   vam->sw_if_index = ntohl (mp->sw_if_index);
630   vam->result_ready = 1;
631 }
632
633 static void vl_api_af_packet_create_reply_t_handler_json
634   (vl_api_af_packet_create_reply_t * mp)
635 {
636   vat_main_t *vam = &vat_main;
637   vat_json_node_t node;
638
639   vat_json_init_object (&node);
640   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
641   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
642
643   vat_json_print (vam->ofp, &node);
644   vat_json_free (&node);
645
646   vam->retval = ntohl (mp->retval);
647   vam->result_ready = 1;
648 }
649
650 static void vl_api_create_vlan_subif_reply_t_handler
651   (vl_api_create_vlan_subif_reply_t * mp)
652 {
653   vat_main_t *vam = &vat_main;
654   i32 retval = ntohl (mp->retval);
655
656   vam->retval = retval;
657   vam->regenerate_interface_table = 1;
658   vam->sw_if_index = ntohl (mp->sw_if_index);
659   vam->result_ready = 1;
660 }
661
662 static void vl_api_create_vlan_subif_reply_t_handler_json
663   (vl_api_create_vlan_subif_reply_t * mp)
664 {
665   vat_main_t *vam = &vat_main;
666   vat_json_node_t node;
667
668   vat_json_init_object (&node);
669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
670   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
671
672   vat_json_print (vam->ofp, &node);
673   vat_json_free (&node);
674
675   vam->retval = ntohl (mp->retval);
676   vam->result_ready = 1;
677 }
678
679 static void vl_api_create_subif_reply_t_handler
680   (vl_api_create_subif_reply_t * mp)
681 {
682   vat_main_t *vam = &vat_main;
683   i32 retval = ntohl (mp->retval);
684
685   vam->retval = retval;
686   vam->regenerate_interface_table = 1;
687   vam->sw_if_index = ntohl (mp->sw_if_index);
688   vam->result_ready = 1;
689 }
690
691 static void vl_api_create_subif_reply_t_handler_json
692   (vl_api_create_subif_reply_t * mp)
693 {
694   vat_main_t *vam = &vat_main;
695   vat_json_node_t node;
696
697   vat_json_init_object (&node);
698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
699   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
700
701   vat_json_print (vam->ofp, &node);
702   vat_json_free (&node);
703
704   vam->retval = ntohl (mp->retval);
705   vam->result_ready = 1;
706 }
707
708 static void vl_api_interface_name_renumber_reply_t_handler
709   (vl_api_interface_name_renumber_reply_t * mp)
710 {
711   vat_main_t *vam = &vat_main;
712   i32 retval = ntohl (mp->retval);
713
714   vam->retval = retval;
715   vam->regenerate_interface_table = 1;
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler_json
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   vat_json_node_t node;
724
725   vat_json_init_object (&node);
726   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
727
728   vat_json_print (vam->ofp, &node);
729   vat_json_free (&node);
730
731   vam->retval = ntohl (mp->retval);
732   vam->result_ready = 1;
733 }
734
735 /*
736  * Special-case: build the interface table, maintain
737  * the next loopback sw_if_index vbl.
738  */
739 static void vl_api_sw_interface_details_t_handler
740   (vl_api_sw_interface_details_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   u8 *s = format (0, "%s%c", mp->interface_name, 0);
744
745   hash_set_mem (vam->sw_if_index_by_interface_name, s,
746                 ntohl (mp->sw_if_index));
747
748   /* In sub interface case, fill the sub interface table entry */
749   if (mp->sw_if_index != mp->sup_sw_if_index)
750     {
751       sw_interface_subif_t *sub = NULL;
752
753       vec_add2 (vam->sw_if_subif_table, sub, 1);
754
755       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
756       strncpy ((char *) sub->interface_name, (char *) s,
757                vec_len (sub->interface_name));
758       sub->sw_if_index = ntohl (mp->sw_if_index);
759       sub->sub_id = ntohl (mp->sub_id);
760
761       sub->sub_dot1ad = mp->sub_dot1ad;
762       sub->sub_number_of_tags = mp->sub_number_of_tags;
763       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
764       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
765       sub->sub_exact_match = mp->sub_exact_match;
766       sub->sub_default = mp->sub_default;
767       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
768       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
769
770       /* vlan tag rewrite */
771       sub->vtr_op = ntohl (mp->vtr_op);
772       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
773       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
774       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
775     }
776 }
777
778 static void vl_api_sw_interface_details_t_handler_json
779   (vl_api_sw_interface_details_t * mp)
780 {
781   vat_main_t *vam = &vat_main;
782   vat_json_node_t *node = NULL;
783
784   if (VAT_JSON_ARRAY != vam->json_tree.type)
785     {
786       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
787       vat_json_init_array (&vam->json_tree);
788     }
789   node = vat_json_array_add (&vam->json_tree);
790
791   vat_json_init_object (node);
792   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
793   vat_json_object_add_uint (node, "sup_sw_if_index",
794                             ntohl (mp->sup_sw_if_index));
795   vat_json_object_add_uint (node, "l2_address_length",
796                             ntohl (mp->l2_address_length));
797   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
798                              sizeof (mp->l2_address));
799   vat_json_object_add_string_copy (node, "interface_name",
800                                    mp->interface_name);
801   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
802   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
803   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
804   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
805   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
806   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
807   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
808   vat_json_object_add_uint (node, "sub_number_of_tags",
809                             mp->sub_number_of_tags);
810   vat_json_object_add_uint (node, "sub_outer_vlan_id",
811                             ntohs (mp->sub_outer_vlan_id));
812   vat_json_object_add_uint (node, "sub_inner_vlan_id",
813                             ntohs (mp->sub_inner_vlan_id));
814   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
815   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
816   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
817                             mp->sub_outer_vlan_id_any);
818   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
819                             mp->sub_inner_vlan_id_any);
820   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
821   vat_json_object_add_uint (node, "vtr_push_dot1q",
822                             ntohl (mp->vtr_push_dot1q));
823   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
824   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
825 }
826
827 static void vl_api_sw_interface_set_flags_t_handler
828   (vl_api_sw_interface_set_flags_t * mp)
829 {
830   vat_main_t *vam = &vat_main;
831   if (vam->interface_event_display)
832     errmsg ("interface flags: sw_if_index %d %s %s\n",
833             ntohl (mp->sw_if_index),
834             mp->admin_up_down ? "admin-up" : "admin-down",
835             mp->link_up_down ? "link-up" : "link-down");
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler_json
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   /* JSON output not supported */
842 }
843
844 static void
845 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
846 {
847   vat_main_t *vam = &vat_main;
848   i32 retval = ntohl (mp->retval);
849
850   vam->retval = retval;
851   vam->shmem_result = (u8 *) mp->reply_in_shmem;
852   vam->result_ready = 1;
853 }
854
855 static void
856 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   vat_json_node_t node;
860   api_main_t *am = &api_main;
861   void *oldheap;
862   u8 *reply;
863
864   vat_json_init_object (&node);
865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
866   vat_json_object_add_uint (&node, "reply_in_shmem",
867                             ntohl (mp->reply_in_shmem));
868   /* Toss the shared-memory original... */
869   pthread_mutex_lock (&am->vlib_rp->mutex);
870   oldheap = svm_push_data_heap (am->vlib_rp);
871
872   reply = (u8 *) (mp->reply_in_shmem);
873   vec_free (reply);
874
875   svm_pop_heap (oldheap);
876   pthread_mutex_unlock (&am->vlib_rp->mutex);
877
878   vat_json_print (vam->ofp, &node);
879   vat_json_free (&node);
880
881   vam->retval = ntohl (mp->retval);
882   vam->result_ready = 1;
883 }
884
885 static void
886 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   i32 retval = ntohl (mp->retval);
890
891   vam->retval = retval;
892   vam->cmd_reply = mp->reply;
893   vam->result_ready = 1;
894 }
895
896 static void
897 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   vat_json_node_t node;
901
902   vat_json_init_object (&node);
903   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
904   vat_json_object_add_string_copy (&node, "reply", mp->reply);
905
906   vat_json_print (vam->ofp, &node);
907   vat_json_free (&node);
908
909   vam->retval = ntohl (mp->retval);
910   vam->result_ready = 1;
911 }
912
913 static void vl_api_classify_add_del_table_reply_t_handler
914   (vl_api_classify_add_del_table_reply_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   i32 retval = ntohl (mp->retval);
918   if (vam->async_mode)
919     {
920       vam->async_errors += (retval < 0);
921     }
922   else
923     {
924       vam->retval = retval;
925       if (retval == 0 &&
926           ((mp->new_table_index != 0xFFFFFFFF) ||
927            (mp->skip_n_vectors != 0xFFFFFFFF) ||
928            (mp->match_n_vectors != 0xFFFFFFFF)))
929         /*
930          * Note: this is just barely thread-safe, depends on
931          * the main thread spinning waiting for an answer...
932          */
933         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
934                 ntohl (mp->new_table_index),
935                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
936       vam->result_ready = 1;
937     }
938 }
939
940 static void vl_api_classify_add_del_table_reply_t_handler_json
941   (vl_api_classify_add_del_table_reply_t * mp)
942 {
943   vat_main_t *vam = &vat_main;
944   vat_json_node_t node;
945
946   vat_json_init_object (&node);
947   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
948   vat_json_object_add_uint (&node, "new_table_index",
949                             ntohl (mp->new_table_index));
950   vat_json_object_add_uint (&node, "skip_n_vectors",
951                             ntohl (mp->skip_n_vectors));
952   vat_json_object_add_uint (&node, "match_n_vectors",
953                             ntohl (mp->match_n_vectors));
954
955   vat_json_print (vam->ofp, &node);
956   vat_json_free (&node);
957
958   vam->retval = ntohl (mp->retval);
959   vam->result_ready = 1;
960 }
961
962 static void vl_api_get_node_index_reply_t_handler
963   (vl_api_get_node_index_reply_t * mp)
964 {
965   vat_main_t *vam = &vat_main;
966   i32 retval = ntohl (mp->retval);
967   if (vam->async_mode)
968     {
969       vam->async_errors += (retval < 0);
970     }
971   else
972     {
973       vam->retval = retval;
974       if (retval == 0)
975         errmsg ("node index %d\n", ntohl (mp->node_index));
976       vam->result_ready = 1;
977     }
978 }
979
980 static void vl_api_get_node_index_reply_t_handler_json
981   (vl_api_get_node_index_reply_t * mp)
982 {
983   vat_main_t *vam = &vat_main;
984   vat_json_node_t node;
985
986   vat_json_init_object (&node);
987   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
988   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
989
990   vat_json_print (vam->ofp, &node);
991   vat_json_free (&node);
992
993   vam->retval = ntohl (mp->retval);
994   vam->result_ready = 1;
995 }
996
997 static void vl_api_get_next_index_reply_t_handler
998   (vl_api_get_next_index_reply_t * mp)
999 {
1000   vat_main_t *vam = &vat_main;
1001   i32 retval = ntohl (mp->retval);
1002   if (vam->async_mode)
1003     {
1004       vam->async_errors += (retval < 0);
1005     }
1006   else
1007     {
1008       vam->retval = retval;
1009       if (retval == 0)
1010         errmsg ("next node index %d\n", ntohl (mp->next_index));
1011       vam->result_ready = 1;
1012     }
1013 }
1014
1015 static void vl_api_get_next_index_reply_t_handler_json
1016   (vl_api_get_next_index_reply_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   vat_json_node_t node;
1020
1021   vat_json_init_object (&node);
1022   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1023   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1024
1025   vat_json_print (vam->ofp, &node);
1026   vat_json_free (&node);
1027
1028   vam->retval = ntohl (mp->retval);
1029   vam->result_ready = 1;
1030 }
1031
1032 static void vl_api_add_node_next_reply_t_handler
1033   (vl_api_add_node_next_reply_t * mp)
1034 {
1035   vat_main_t *vam = &vat_main;
1036   i32 retval = ntohl (mp->retval);
1037   if (vam->async_mode)
1038     {
1039       vam->async_errors += (retval < 0);
1040     }
1041   else
1042     {
1043       vam->retval = retval;
1044       if (retval == 0)
1045         errmsg ("next index %d\n", ntohl (mp->next_index));
1046       vam->result_ready = 1;
1047     }
1048 }
1049
1050 static void vl_api_add_node_next_reply_t_handler_json
1051   (vl_api_add_node_next_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   vat_json_node_t node;
1055
1056   vat_json_init_object (&node);
1057   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1058   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1059
1060   vat_json_print (vam->ofp, &node);
1061   vat_json_free (&node);
1062
1063   vam->retval = ntohl (mp->retval);
1064   vam->result_ready = 1;
1065 }
1066
1067 static void vl_api_show_version_reply_t_handler
1068   (vl_api_show_version_reply_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   i32 retval = ntohl (mp->retval);
1072
1073   if (retval >= 0)
1074     {
1075       errmsg ("        program: %s\n", mp->program);
1076       errmsg ("        version: %s\n", mp->version);
1077       errmsg ("     build date: %s\n", mp->build_date);
1078       errmsg ("build directory: %s\n", mp->build_directory);
1079     }
1080   vam->retval = retval;
1081   vam->result_ready = 1;
1082 }
1083
1084 static void vl_api_show_version_reply_t_handler_json
1085   (vl_api_show_version_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   vat_json_node_t node;
1089
1090   vat_json_init_object (&node);
1091   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1092   vat_json_object_add_string_copy (&node, "program", mp->program);
1093   vat_json_object_add_string_copy (&node, "version", mp->version);
1094   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1095   vat_json_object_add_string_copy (&node, "build_directory",
1096                                    mp->build_directory);
1097
1098   vat_json_print (vam->ofp, &node);
1099   vat_json_free (&node);
1100
1101   vam->retval = ntohl (mp->retval);
1102   vam->result_ready = 1;
1103 }
1104
1105 static void
1106 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1107 {
1108   vat_main_t *vam = &vat_main;
1109   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1110           mp->mac_ip ? "mac/ip binding" : "address resolution",
1111           format_ip4_address, &mp->address,
1112           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1113 }
1114
1115 static void
1116 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1117 {
1118   /* JSON output not supported */
1119 }
1120
1121 static void
1122 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1123 {
1124   vat_main_t *vam = &vat_main;
1125   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1126           mp->mac_ip ? "mac/ip binding" : "address resolution",
1127           format_ip6_address, mp->address,
1128           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1129 }
1130
1131 static void
1132 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1133 {
1134   /* JSON output not supported */
1135 }
1136
1137 /*
1138  * Special-case: build the bridge domain table, maintain
1139  * the next bd id vbl.
1140  */
1141 static void vl_api_bridge_domain_details_t_handler
1142   (vl_api_bridge_domain_details_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1146
1147   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1148            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1149
1150   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1151            ntohl (mp->bd_id), mp->learn, mp->forward,
1152            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1153
1154   if (n_sw_ifs)
1155     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1156              "Interface Name");
1157 }
1158
1159 static void vl_api_bridge_domain_details_t_handler_json
1160   (vl_api_bridge_domain_details_t * mp)
1161 {
1162   vat_main_t *vam = &vat_main;
1163   vat_json_node_t *node, *array = NULL;
1164
1165   if (VAT_JSON_ARRAY != vam->json_tree.type)
1166     {
1167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1168       vat_json_init_array (&vam->json_tree);
1169     }
1170   node = vat_json_array_add (&vam->json_tree);
1171
1172   vat_json_init_object (node);
1173   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1174   vat_json_object_add_uint (node, "flood", mp->flood);
1175   vat_json_object_add_uint (node, "forward", mp->forward);
1176   vat_json_object_add_uint (node, "learn", mp->learn);
1177   vat_json_object_add_uint (node, "bvi_sw_if_index",
1178                             ntohl (mp->bvi_sw_if_index));
1179   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1180   array = vat_json_object_add (node, "sw_if");
1181   vat_json_init_array (array);
1182 }
1183
1184 /*
1185  * Special-case: build the bridge domain sw if table.
1186  */
1187 static void vl_api_bridge_domain_sw_if_details_t_handler
1188   (vl_api_bridge_domain_sw_if_details_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   hash_pair_t *p;
1192   u8 *sw_if_name = 0;
1193   u32 sw_if_index;
1194
1195   sw_if_index = ntohl (mp->sw_if_index);
1196   /* *INDENT-OFF* */
1197   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1198   ({
1199     if ((u32) p->value[0] == sw_if_index)
1200       {
1201         sw_if_name = (u8 *)(p->key);
1202         break;
1203       }
1204   }));
1205   /* *INDENT-ON* */
1206
1207   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1208            mp->shg, sw_if_name ? (char *) sw_if_name :
1209            "sw_if_index not found!");
1210 }
1211
1212 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1213   (vl_api_bridge_domain_sw_if_details_t * mp)
1214 {
1215   vat_main_t *vam = &vat_main;
1216   vat_json_node_t *node = NULL;
1217   uword last_index = 0;
1218
1219   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1220   ASSERT (vec_len (vam->json_tree.array) >= 1);
1221   last_index = vec_len (vam->json_tree.array) - 1;
1222   node = &vam->json_tree.array[last_index];
1223   node = vat_json_object_get_element (node, "sw_if");
1224   ASSERT (NULL != node);
1225   node = vat_json_array_add (node);
1226
1227   vat_json_init_object (node);
1228   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1230   vat_json_object_add_uint (node, "shg", mp->shg);
1231 }
1232
1233 static void vl_api_control_ping_reply_t_handler
1234   (vl_api_control_ping_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   i32 retval = ntohl (mp->retval);
1238   if (vam->async_mode)
1239     {
1240       vam->async_errors += (retval < 0);
1241     }
1242   else
1243     {
1244       vam->retval = retval;
1245       vam->result_ready = 1;
1246     }
1247 }
1248
1249 static void vl_api_control_ping_reply_t_handler_json
1250   (vl_api_control_ping_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254
1255   if (VAT_JSON_NONE != vam->json_tree.type)
1256     {
1257       vat_json_print (vam->ofp, &vam->json_tree);
1258       vat_json_free (&vam->json_tree);
1259       vam->json_tree.type = VAT_JSON_NONE;
1260     }
1261   else
1262     {
1263       /* just print [] */
1264       vat_json_init_array (&vam->json_tree);
1265       vat_json_print (vam->ofp, &vam->json_tree);
1266       vam->json_tree.type = VAT_JSON_NONE;
1267     }
1268
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void
1274 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278   if (vam->async_mode)
1279     {
1280       vam->async_errors += (retval < 0);
1281     }
1282   else
1283     {
1284       vam->retval = retval;
1285       vam->result_ready = 1;
1286     }
1287 }
1288
1289 static void vl_api_l2_flags_reply_t_handler_json
1290   (vl_api_l2_flags_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   vat_json_node_t node;
1294
1295   vat_json_init_object (&node);
1296   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1297   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1298                             ntohl (mp->resulting_feature_bitmap));
1299
1300   vat_json_print (vam->ofp, &node);
1301   vat_json_free (&node);
1302
1303   vam->retval = ntohl (mp->retval);
1304   vam->result_ready = 1;
1305 }
1306
1307 static void vl_api_bridge_flags_reply_t_handler
1308   (vl_api_bridge_flags_reply_t * mp)
1309 {
1310   vat_main_t *vam = &vat_main;
1311   i32 retval = ntohl (mp->retval);
1312   if (vam->async_mode)
1313     {
1314       vam->async_errors += (retval < 0);
1315     }
1316   else
1317     {
1318       vam->retval = retval;
1319       vam->result_ready = 1;
1320     }
1321 }
1322
1323 static void vl_api_bridge_flags_reply_t_handler_json
1324   (vl_api_bridge_flags_reply_t * mp)
1325 {
1326   vat_main_t *vam = &vat_main;
1327   vat_json_node_t node;
1328
1329   vat_json_init_object (&node);
1330   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1331   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1332                             ntohl (mp->resulting_feature_bitmap));
1333
1334   vat_json_print (vam->ofp, &node);
1335   vat_json_free (&node);
1336
1337   vam->retval = ntohl (mp->retval);
1338   vam->result_ready = 1;
1339 }
1340
1341 static void vl_api_tap_connect_reply_t_handler
1342   (vl_api_tap_connect_reply_t * mp)
1343 {
1344   vat_main_t *vam = &vat_main;
1345   i32 retval = ntohl (mp->retval);
1346   if (vam->async_mode)
1347     {
1348       vam->async_errors += (retval < 0);
1349     }
1350   else
1351     {
1352       vam->retval = retval;
1353       vam->sw_if_index = ntohl (mp->sw_if_index);
1354       vam->result_ready = 1;
1355     }
1356
1357 }
1358
1359 static void vl_api_tap_connect_reply_t_handler_json
1360   (vl_api_tap_connect_reply_t * mp)
1361 {
1362   vat_main_t *vam = &vat_main;
1363   vat_json_node_t node;
1364
1365   vat_json_init_object (&node);
1366   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1367   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1368
1369   vat_json_print (vam->ofp, &node);
1370   vat_json_free (&node);
1371
1372   vam->retval = ntohl (mp->retval);
1373   vam->result_ready = 1;
1374
1375 }
1376
1377 static void
1378 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1379 {
1380   vat_main_t *vam = &vat_main;
1381   i32 retval = ntohl (mp->retval);
1382   if (vam->async_mode)
1383     {
1384       vam->async_errors += (retval < 0);
1385     }
1386   else
1387     {
1388       vam->retval = retval;
1389       vam->sw_if_index = ntohl (mp->sw_if_index);
1390       vam->result_ready = 1;
1391     }
1392 }
1393
1394 static void vl_api_tap_modify_reply_t_handler_json
1395   (vl_api_tap_modify_reply_t * mp)
1396 {
1397   vat_main_t *vam = &vat_main;
1398   vat_json_node_t node;
1399
1400   vat_json_init_object (&node);
1401   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1402   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1403
1404   vat_json_print (vam->ofp, &node);
1405   vat_json_free (&node);
1406
1407   vam->retval = ntohl (mp->retval);
1408   vam->result_ready = 1;
1409 }
1410
1411 static void
1412 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1413 {
1414   vat_main_t *vam = &vat_main;
1415   i32 retval = ntohl (mp->retval);
1416   if (vam->async_mode)
1417     {
1418       vam->async_errors += (retval < 0);
1419     }
1420   else
1421     {
1422       vam->retval = retval;
1423       vam->result_ready = 1;
1424     }
1425 }
1426
1427 static void vl_api_tap_delete_reply_t_handler_json
1428   (vl_api_tap_delete_reply_t * mp)
1429 {
1430   vat_main_t *vam = &vat_main;
1431   vat_json_node_t node;
1432
1433   vat_json_init_object (&node);
1434   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1435
1436   vat_json_print (vam->ofp, &node);
1437   vat_json_free (&node);
1438
1439   vam->retval = ntohl (mp->retval);
1440   vam->result_ready = 1;
1441 }
1442
1443 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler
1444   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   i32 retval = ntohl (mp->retval);
1448   if (vam->async_mode)
1449     {
1450       vam->async_errors += (retval < 0);
1451     }
1452   else
1453     {
1454       vam->retval = retval;
1455       vam->result_ready = 1;
1456     }
1457 }
1458
1459 static void vl_api_mpls_ethernet_add_del_tunnel_reply_t_handler_json
1460   (vl_api_mpls_ethernet_add_del_tunnel_reply_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   vat_json_node_t node;
1464
1465   vat_json_init_object (&node);
1466   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1467   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1468                             ntohl (mp->tunnel_sw_if_index));
1469
1470   vat_json_print (vam->ofp, &node);
1471   vat_json_free (&node);
1472
1473   vam->retval = ntohl (mp->retval);
1474   vam->result_ready = 1;
1475 }
1476
1477 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1478   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1479 {
1480   vat_main_t *vam = &vat_main;
1481   i32 retval = ntohl (mp->retval);
1482   if (vam->async_mode)
1483     {
1484       vam->async_errors += (retval < 0);
1485     }
1486   else
1487     {
1488       vam->retval = retval;
1489       vam->sw_if_index = ntohl (mp->sw_if_index);
1490       vam->result_ready = 1;
1491     }
1492 }
1493
1494 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1495   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   vat_json_node_t node;
1499
1500   vat_json_init_object (&node);
1501   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1502   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1503
1504   vat_json_print (vam->ofp, &node);
1505   vat_json_free (&node);
1506
1507   vam->retval = ntohl (mp->retval);
1508   vam->result_ready = 1;
1509 }
1510
1511
1512 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1513   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1514 {
1515   vat_main_t *vam = &vat_main;
1516   i32 retval = ntohl (mp->retval);
1517   if (vam->async_mode)
1518     {
1519       vam->async_errors += (retval < 0);
1520     }
1521   else
1522     {
1523       vam->retval = retval;
1524       vam->result_ready = 1;
1525     }
1526 }
1527
1528 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1529   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1530 {
1531   vat_main_t *vam = &vat_main;
1532   vat_json_node_t node;
1533
1534   vat_json_init_object (&node);
1535   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1536   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1537
1538   vat_json_print (vam->ofp, &node);
1539   vat_json_free (&node);
1540
1541   vam->retval = ntohl (mp->retval);
1542   vam->result_ready = 1;
1543 }
1544
1545 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1546   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   i32 retval = ntohl (mp->retval);
1550   if (vam->async_mode)
1551     {
1552       vam->async_errors += (retval < 0);
1553     }
1554   else
1555     {
1556       vam->retval = retval;
1557       vam->sw_if_index = ntohl (mp->sw_if_index);
1558       vam->result_ready = 1;
1559     }
1560 }
1561
1562 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1563   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1564 {
1565   vat_main_t *vam = &vat_main;
1566   vat_json_node_t node;
1567
1568   vat_json_init_object (&node);
1569   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1570   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1571
1572   vat_json_print (vam->ofp, &node);
1573   vat_json_free (&node);
1574
1575   vam->retval = ntohl (mp->retval);
1576   vam->result_ready = 1;
1577 }
1578
1579 static void vl_api_gre_add_del_tunnel_reply_t_handler
1580   (vl_api_gre_add_del_tunnel_reply_t * mp)
1581 {
1582   vat_main_t *vam = &vat_main;
1583   i32 retval = ntohl (mp->retval);
1584   if (vam->async_mode)
1585     {
1586       vam->async_errors += (retval < 0);
1587     }
1588   else
1589     {
1590       vam->retval = retval;
1591       vam->sw_if_index = ntohl (mp->sw_if_index);
1592       vam->result_ready = 1;
1593     }
1594 }
1595
1596 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1597   (vl_api_gre_add_del_tunnel_reply_t * mp)
1598 {
1599   vat_main_t *vam = &vat_main;
1600   vat_json_node_t node;
1601
1602   vat_json_init_object (&node);
1603   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1604   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1605
1606   vat_json_print (vam->ofp, &node);
1607   vat_json_free (&node);
1608
1609   vam->retval = ntohl (mp->retval);
1610   vam->result_ready = 1;
1611 }
1612
1613 static void vl_api_create_vhost_user_if_reply_t_handler
1614   (vl_api_create_vhost_user_if_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   i32 retval = ntohl (mp->retval);
1618   if (vam->async_mode)
1619     {
1620       vam->async_errors += (retval < 0);
1621     }
1622   else
1623     {
1624       vam->retval = retval;
1625       vam->sw_if_index = ntohl (mp->sw_if_index);
1626       vam->result_ready = 1;
1627     }
1628 }
1629
1630 static void vl_api_create_vhost_user_if_reply_t_handler_json
1631   (vl_api_create_vhost_user_if_reply_t * mp)
1632 {
1633   vat_main_t *vam = &vat_main;
1634   vat_json_node_t node;
1635
1636   vat_json_init_object (&node);
1637   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1638   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1639
1640   vat_json_print (vam->ofp, &node);
1641   vat_json_free (&node);
1642
1643   vam->retval = ntohl (mp->retval);
1644   vam->result_ready = 1;
1645 }
1646
1647 static void vl_api_ip_address_details_t_handler
1648   (vl_api_ip_address_details_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   static ip_address_details_t empty_ip_address_details = { {0} };
1652   ip_address_details_t *address = NULL;
1653   ip_details_t *current_ip_details = NULL;
1654   ip_details_t *details = NULL;
1655
1656   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1657
1658   if (!details || vam->current_sw_if_index >= vec_len (details)
1659       || !details[vam->current_sw_if_index].present)
1660     {
1661       errmsg ("ip address details arrived but not stored\n");
1662       errmsg ("ip_dump should be called first\n");
1663       return;
1664     }
1665
1666   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1667
1668 #define addresses (current_ip_details->addr)
1669
1670   vec_validate_init_empty (addresses, vec_len (addresses),
1671                            empty_ip_address_details);
1672
1673   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1674
1675   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1676   address->prefix_length = mp->prefix_length;
1677 #undef addresses
1678 }
1679
1680 static void vl_api_ip_address_details_t_handler_json
1681   (vl_api_ip_address_details_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t *node = NULL;
1685   struct in6_addr ip6;
1686   struct in_addr ip4;
1687
1688   if (VAT_JSON_ARRAY != vam->json_tree.type)
1689     {
1690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1691       vat_json_init_array (&vam->json_tree);
1692     }
1693   node = vat_json_array_add (&vam->json_tree);
1694
1695   vat_json_init_object (node);
1696   if (vam->is_ipv6)
1697     {
1698       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1699       vat_json_object_add_ip6 (node, "ip", ip6);
1700     }
1701   else
1702     {
1703       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1704       vat_json_object_add_ip4 (node, "ip", ip4);
1705     }
1706   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1707 }
1708
1709 static void
1710 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   static ip_details_t empty_ip_details = { 0 };
1714   ip_details_t *ip = NULL;
1715   u32 sw_if_index = ~0;
1716
1717   sw_if_index = ntohl (mp->sw_if_index);
1718
1719   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1720                            sw_if_index, empty_ip_details);
1721
1722   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1723                          sw_if_index);
1724
1725   ip->present = 1;
1726 }
1727
1728 static void
1729 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732
1733   if (VAT_JSON_ARRAY != vam->json_tree.type)
1734     {
1735       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1736       vat_json_init_array (&vam->json_tree);
1737     }
1738   vat_json_array_add_uint (&vam->json_tree,
1739                            clib_net_to_host_u32 (mp->sw_if_index));
1740 }
1741
1742 static void vl_api_map_domain_details_t_handler_json
1743   (vl_api_map_domain_details_t * mp)
1744 {
1745   vat_json_node_t *node = NULL;
1746   vat_main_t *vam = &vat_main;
1747   struct in6_addr ip6;
1748   struct in_addr ip4;
1749
1750   if (VAT_JSON_ARRAY != vam->json_tree.type)
1751     {
1752       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1753       vat_json_init_array (&vam->json_tree);
1754     }
1755
1756   node = vat_json_array_add (&vam->json_tree);
1757   vat_json_init_object (node);
1758
1759   vat_json_object_add_uint (node, "domain_index",
1760                             clib_net_to_host_u32 (mp->domain_index));
1761   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1762   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1763   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1764   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1765   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1766   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1767   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1768   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1769   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1770   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1771   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1772   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1773   vat_json_object_add_uint (node, "flags", mp->flags);
1774   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1775   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1776 }
1777
1778 static void vl_api_map_domain_details_t_handler
1779   (vl_api_map_domain_details_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782
1783   if (mp->is_translation)
1784     {
1785       fformat (vam->ofp,
1786                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1787                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1788                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1789                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1790                clib_net_to_host_u32 (mp->domain_index));
1791     }
1792   else
1793     {
1794       fformat (vam->ofp,
1795                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1796                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1797                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1798                format_ip6_address, mp->ip6_src,
1799                clib_net_to_host_u32 (mp->domain_index));
1800     }
1801   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1802            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1803            mp->is_translation ? "map-t" : "");
1804 }
1805
1806 static void vl_api_map_rule_details_t_handler_json
1807   (vl_api_map_rule_details_t * mp)
1808 {
1809   struct in6_addr ip6;
1810   vat_json_node_t *node = NULL;
1811   vat_main_t *vam = &vat_main;
1812
1813   if (VAT_JSON_ARRAY != vam->json_tree.type)
1814     {
1815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1816       vat_json_init_array (&vam->json_tree);
1817     }
1818
1819   node = vat_json_array_add (&vam->json_tree);
1820   vat_json_init_object (node);
1821
1822   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1823   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1824   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1825 }
1826
1827 static void
1828 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1829 {
1830   vat_main_t *vam = &vat_main;
1831   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1832            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1833 }
1834
1835 static void
1836 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1837 {
1838   vat_main_t *vam = &vat_main;
1839   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1840           "router_addr %U host_mac %U\n",
1841           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1842           format_ip4_address, &mp->host_address,
1843           format_ip4_address, &mp->router_address,
1844           format_ethernet_address, mp->host_mac);
1845 }
1846
1847 static void vl_api_dhcp_compl_event_t_handler_json
1848   (vl_api_dhcp_compl_event_t * mp)
1849 {
1850   /* JSON output not supported */
1851 }
1852
1853 static void
1854 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1855                               u32 counter)
1856 {
1857   vat_main_t *vam = &vat_main;
1858   static u64 default_counter = 0;
1859
1860   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1861                            NULL);
1862   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1863                            sw_if_index, default_counter);
1864   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1865 }
1866
1867 static void
1868 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1869                                 interface_counter_t counter)
1870 {
1871   vat_main_t *vam = &vat_main;
1872   static interface_counter_t default_counter = { 0, };
1873
1874   vec_validate_init_empty (vam->combined_interface_counters,
1875                            vnet_counter_type, NULL);
1876   vec_validate_init_empty (vam->combined_interface_counters
1877                            [vnet_counter_type], sw_if_index, default_counter);
1878   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1879 }
1880
1881 static void vl_api_vnet_interface_counters_t_handler
1882   (vl_api_vnet_interface_counters_t * mp)
1883 {
1884   /* not supported */
1885 }
1886
1887 static void vl_api_vnet_interface_counters_t_handler_json
1888   (vl_api_vnet_interface_counters_t * mp)
1889 {
1890   interface_counter_t counter;
1891   vlib_counter_t *v;
1892   u64 *v_packets;
1893   u64 packets;
1894   u32 count;
1895   u32 first_sw_if_index;
1896   int i;
1897
1898   count = ntohl (mp->count);
1899   first_sw_if_index = ntohl (mp->first_sw_if_index);
1900
1901   if (!mp->is_combined)
1902     {
1903       v_packets = (u64 *) & mp->data;
1904       for (i = 0; i < count; i++)
1905         {
1906           packets =
1907             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1908           set_simple_interface_counter (mp->vnet_counter_type,
1909                                         first_sw_if_index + i, packets);
1910           v_packets++;
1911         }
1912     }
1913   else
1914     {
1915       v = (vlib_counter_t *) & mp->data;
1916       for (i = 0; i < count; i++)
1917         {
1918           counter.packets =
1919             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1920           counter.bytes =
1921             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1922           set_combined_interface_counter (mp->vnet_counter_type,
1923                                           first_sw_if_index + i, counter);
1924           v++;
1925         }
1926     }
1927 }
1928
1929 static u32
1930 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1931 {
1932   vat_main_t *vam = &vat_main;
1933   u32 i;
1934
1935   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1936     {
1937       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1938         {
1939           return i;
1940         }
1941     }
1942   return ~0;
1943 }
1944
1945 static u32
1946 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1947 {
1948   vat_main_t *vam = &vat_main;
1949   u32 i;
1950
1951   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1952     {
1953       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1954         {
1955           return i;
1956         }
1957     }
1958   return ~0;
1959 }
1960
1961 static void vl_api_vnet_ip4_fib_counters_t_handler
1962   (vl_api_vnet_ip4_fib_counters_t * mp)
1963 {
1964   /* not supported */
1965 }
1966
1967 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1968   (vl_api_vnet_ip4_fib_counters_t * mp)
1969 {
1970   vat_main_t *vam = &vat_main;
1971   vl_api_ip4_fib_counter_t *v;
1972   ip4_fib_counter_t *counter;
1973   struct in_addr ip4;
1974   u32 vrf_id;
1975   u32 vrf_index;
1976   u32 count;
1977   int i;
1978
1979   vrf_id = ntohl (mp->vrf_id);
1980   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
1981   if (~0 == vrf_index)
1982     {
1983       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
1984       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1985       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1986       vec_validate (vam->ip4_fib_counters, vrf_index);
1987       vam->ip4_fib_counters[vrf_index] = NULL;
1988     }
1989
1990   vec_free (vam->ip4_fib_counters[vrf_index]);
1991   v = (vl_api_ip4_fib_counter_t *) & mp->c;
1992   count = ntohl (mp->count);
1993   for (i = 0; i < count; i++)
1994     {
1995       vec_validate (vam->ip4_fib_counters[vrf_index], i);
1996       counter = &vam->ip4_fib_counters[vrf_index][i];
1997       clib_memcpy (&ip4, &v->address, sizeof (ip4));
1998       counter->address = ip4;
1999       counter->address_length = v->address_length;
2000       counter->packets = clib_net_to_host_u64 (v->packets);
2001       counter->bytes = clib_net_to_host_u64 (v->bytes);
2002       v++;
2003     }
2004 }
2005
2006 static void vl_api_vnet_ip6_fib_counters_t_handler
2007   (vl_api_vnet_ip6_fib_counters_t * mp)
2008 {
2009   /* not supported */
2010 }
2011
2012 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2013   (vl_api_vnet_ip6_fib_counters_t * mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016   vl_api_ip6_fib_counter_t *v;
2017   ip6_fib_counter_t *counter;
2018   struct in6_addr ip6;
2019   u32 vrf_id;
2020   u32 vrf_index;
2021   u32 count;
2022   int i;
2023
2024   vrf_id = ntohl (mp->vrf_id);
2025   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2026   if (~0 == vrf_index)
2027     {
2028       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2029       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2030       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2031       vec_validate (vam->ip6_fib_counters, vrf_index);
2032       vam->ip6_fib_counters[vrf_index] = NULL;
2033     }
2034
2035   vec_free (vam->ip6_fib_counters[vrf_index]);
2036   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2037   count = ntohl (mp->count);
2038   for (i = 0; i < count; i++)
2039     {
2040       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2041       counter = &vam->ip6_fib_counters[vrf_index][i];
2042       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2043       counter->address = ip6;
2044       counter->address_length = v->address_length;
2045       counter->packets = clib_net_to_host_u64 (v->packets);
2046       counter->bytes = clib_net_to_host_u64 (v->bytes);
2047       v++;
2048     }
2049 }
2050
2051 static void vl_api_get_first_msg_id_reply_t_handler
2052   (vl_api_get_first_msg_id_reply_t * mp)
2053 {
2054   vat_main_t *vam = &vat_main;
2055   i32 retval = ntohl (mp->retval);
2056
2057   if (vam->async_mode)
2058     {
2059       vam->async_errors += (retval < 0);
2060     }
2061   else
2062     {
2063       vam->retval = retval;
2064       vam->result_ready = 1;
2065     }
2066   if (retval >= 0)
2067     {
2068       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2069     }
2070 }
2071
2072 static void vl_api_get_first_msg_id_reply_t_handler_json
2073   (vl_api_get_first_msg_id_reply_t * mp)
2074 {
2075   vat_main_t *vam = &vat_main;
2076   vat_json_node_t node;
2077
2078   vat_json_init_object (&node);
2079   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2080   vat_json_object_add_uint (&node, "first_msg_id",
2081                             (uint) ntohs (mp->first_msg_id));
2082
2083   vat_json_print (vam->ofp, &node);
2084   vat_json_free (&node);
2085
2086   vam->retval = ntohl (mp->retval);
2087   vam->result_ready = 1;
2088 }
2089
2090 static void vl_api_get_node_graph_reply_t_handler
2091   (vl_api_get_node_graph_reply_t * mp)
2092 {
2093   vat_main_t *vam = &vat_main;
2094   api_main_t *am = &api_main;
2095   i32 retval = ntohl (mp->retval);
2096   u8 *pvt_copy, *reply;
2097   void *oldheap;
2098   vlib_node_t *node;
2099   int i;
2100
2101   if (vam->async_mode)
2102     {
2103       vam->async_errors += (retval < 0);
2104     }
2105   else
2106     {
2107       vam->retval = retval;
2108       vam->result_ready = 1;
2109     }
2110
2111   /* "Should never happen..." */
2112   if (retval != 0)
2113     return;
2114
2115   reply = (u8 *) (mp->reply_in_shmem);
2116   pvt_copy = vec_dup (reply);
2117
2118   /* Toss the shared-memory original... */
2119   pthread_mutex_lock (&am->vlib_rp->mutex);
2120   oldheap = svm_push_data_heap (am->vlib_rp);
2121
2122   vec_free (reply);
2123
2124   svm_pop_heap (oldheap);
2125   pthread_mutex_unlock (&am->vlib_rp->mutex);
2126
2127   if (vam->graph_nodes)
2128     {
2129       hash_free (vam->graph_node_index_by_name);
2130
2131       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2132         {
2133           node = vam->graph_nodes[i];
2134           vec_free (node->name);
2135           vec_free (node->next_nodes);
2136           vec_free (node);
2137         }
2138       vec_free (vam->graph_nodes);
2139     }
2140
2141   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2142   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2143   vec_free (pvt_copy);
2144
2145   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2146     {
2147       node = vam->graph_nodes[i];
2148       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2149     }
2150 }
2151
2152 static void vl_api_get_node_graph_reply_t_handler_json
2153   (vl_api_get_node_graph_reply_t * mp)
2154 {
2155   vat_main_t *vam = &vat_main;
2156   api_main_t *am = &api_main;
2157   void *oldheap;
2158   vat_json_node_t node;
2159   u8 *reply;
2160
2161   /* $$$$ make this real? */
2162   vat_json_init_object (&node);
2163   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2164   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2165
2166   reply = (u8 *) (mp->reply_in_shmem);
2167
2168   /* Toss the shared-memory original... */
2169   pthread_mutex_lock (&am->vlib_rp->mutex);
2170   oldheap = svm_push_data_heap (am->vlib_rp);
2171
2172   vec_free (reply);
2173
2174   svm_pop_heap (oldheap);
2175   pthread_mutex_unlock (&am->vlib_rp->mutex);
2176
2177   vat_json_print (vam->ofp, &node);
2178   vat_json_free (&node);
2179
2180   vam->retval = ntohl (mp->retval);
2181   vam->result_ready = 1;
2182 }
2183
2184 static void
2185 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2186 {
2187   vat_main_t *vam = &vat_main;
2188   u8 *s = 0;
2189
2190   if (mp->local)
2191     {
2192       s = format (s, "%=16d%=16d%=16d\n",
2193                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2194     }
2195   else
2196     {
2197       s = format (s, "%=16U%=16d%=16d\n",
2198                   mp->is_ipv6 ? format_ip6_address :
2199                   format_ip4_address,
2200                   mp->ip_address, mp->priority, mp->weight);
2201     }
2202
2203   fformat (vam->ofp, "%v", s);
2204   vec_free (s);
2205 }
2206
2207 static void
2208 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2209                                             mp)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   vat_json_node_t *node = NULL;
2213   struct in6_addr ip6;
2214   struct in_addr ip4;
2215
2216   if (VAT_JSON_ARRAY != vam->json_tree.type)
2217     {
2218       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2219       vat_json_init_array (&vam->json_tree);
2220     }
2221   node = vat_json_array_add (&vam->json_tree);
2222   vat_json_init_object (node);
2223
2224   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2225   vat_json_object_add_uint (node, "priority", mp->priority);
2226   vat_json_object_add_uint (node, "weight", mp->weight);
2227
2228   if (mp->local)
2229     vat_json_object_add_uint (node, "sw_if_index",
2230                               clib_net_to_host_u32 (mp->sw_if_index));
2231   else
2232     {
2233       if (mp->is_ipv6)
2234         {
2235           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2236           vat_json_object_add_ip6 (node, "address", ip6);
2237         }
2238       else
2239         {
2240           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2241           vat_json_object_add_ip4 (node, "address", ip4);
2242         }
2243     }
2244 }
2245
2246 static void
2247 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2248                                            mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   u8 *ls_name = 0;
2252
2253   ls_name = format (0, "%s", mp->ls_name);
2254
2255   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2256            ls_name);
2257   vec_free (ls_name);
2258 }
2259
2260 static void
2261   vl_api_lisp_locator_set_details_t_handler_json
2262   (vl_api_lisp_locator_set_details_t * mp)
2263 {
2264   vat_main_t *vam = &vat_main;
2265   vat_json_node_t *node = 0;
2266   u8 *ls_name = 0;
2267
2268   ls_name = format (0, "%s", mp->ls_name);
2269   vec_add1 (ls_name, 0);
2270
2271   if (VAT_JSON_ARRAY != vam->json_tree.type)
2272     {
2273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2274       vat_json_init_array (&vam->json_tree);
2275     }
2276   node = vat_json_array_add (&vam->json_tree);
2277
2278   vat_json_init_object (node);
2279   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2280   vat_json_object_add_uint (node, "ls_index",
2281                             clib_net_to_host_u32 (mp->ls_index));
2282   vec_free (ls_name);
2283 }
2284
2285 static u8 *
2286 format_lisp_flat_eid (u8 * s, va_list * args)
2287 {
2288   u32 type = va_arg (*args, u32);
2289   u8 *eid = va_arg (*args, u8 *);
2290   u32 eid_len = va_arg (*args, u32);
2291
2292   switch (type)
2293     {
2294     case 0:
2295       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2296     case 1:
2297       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2298     case 2:
2299       return format (s, "%U", format_ethernet_address, eid);
2300     }
2301   return 0;
2302 }
2303
2304 static u8 *
2305 format_lisp_eid_vat (u8 * s, va_list * args)
2306 {
2307   u32 type = va_arg (*args, u32);
2308   u8 *eid = va_arg (*args, u8 *);
2309   u32 eid_len = va_arg (*args, u32);
2310   u8 *seid = va_arg (*args, u8 *);
2311   u32 seid_len = va_arg (*args, u32);
2312   u32 is_src_dst = va_arg (*args, u32);
2313
2314   if (is_src_dst)
2315     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2316
2317   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2318
2319   return s;
2320 }
2321
2322 static void
2323 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2324 {
2325   vat_main_t *vam = &vat_main;
2326   u8 *s = 0, *eid = 0;
2327
2328   if (~0 == mp->locator_set_index)
2329     s = format (0, "action: %d", mp->action);
2330   else
2331     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2332
2333   eid = format (0, "%U", format_lisp_eid_vat,
2334                 mp->eid_type,
2335                 mp->eid,
2336                 mp->eid_prefix_len,
2337                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2338   vec_add1 (eid, 0);
2339
2340   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-d\n",
2341            clib_net_to_host_u32 (mp->vni),
2342            eid,
2343            mp->is_local ? "local" : "remote",
2344            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative);
2345   vec_free (s);
2346   vec_free (eid);
2347 }
2348
2349 static void
2350 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2351                                               * mp)
2352 {
2353   vat_main_t *vam = &vat_main;
2354   vat_json_node_t *node = 0;
2355   u8 *eid = 0;
2356
2357   if (VAT_JSON_ARRAY != vam->json_tree.type)
2358     {
2359       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2360       vat_json_init_array (&vam->json_tree);
2361     }
2362   node = vat_json_array_add (&vam->json_tree);
2363
2364   vat_json_init_object (node);
2365   if (~0 == mp->locator_set_index)
2366     vat_json_object_add_uint (node, "action", mp->action);
2367   else
2368     vat_json_object_add_uint (node, "locator_set_index",
2369                               clib_net_to_host_u32 (mp->locator_set_index));
2370
2371   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2372   eid = format (0, "%U", format_lisp_eid_vat,
2373                 mp->eid_type,
2374                 mp->eid,
2375                 mp->eid_prefix_len,
2376                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2377   vec_add1 (eid, 0);
2378   vat_json_object_add_string_copy (node, "eid", eid);
2379   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2380   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2381   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2382   vec_free (eid);
2383 }
2384
2385 static void
2386   vl_api_lisp_eid_table_map_details_t_handler
2387   (vl_api_lisp_eid_table_map_details_t * mp)
2388 {
2389   vat_main_t *vam = &vat_main;
2390
2391   u8 *line = format (0, "%=10d%=10d",
2392                      clib_net_to_host_u32 (mp->vni),
2393                      clib_net_to_host_u32 (mp->dp_table));
2394   fformat (vam->ofp, "%v\n", line);
2395   vec_free (line);
2396 }
2397
2398 static void
2399   vl_api_lisp_eid_table_map_details_t_handler_json
2400   (vl_api_lisp_eid_table_map_details_t * mp)
2401 {
2402   vat_main_t *vam = &vat_main;
2403   vat_json_node_t *node = NULL;
2404
2405   if (VAT_JSON_ARRAY != vam->json_tree.type)
2406     {
2407       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2408       vat_json_init_array (&vam->json_tree);
2409     }
2410   node = vat_json_array_add (&vam->json_tree);
2411   vat_json_init_object (node);
2412   vat_json_object_add_uint (node, "dp_table",
2413                             clib_net_to_host_u32 (mp->dp_table));
2414   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2415 }
2416
2417 static void
2418   vl_api_lisp_eid_table_vni_details_t_handler
2419   (vl_api_lisp_eid_table_vni_details_t * mp)
2420 {
2421   vat_main_t *vam = &vat_main;
2422
2423   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2424   fformat (vam->ofp, "%v\n", line);
2425   vec_free (line);
2426 }
2427
2428 static void
2429   vl_api_lisp_eid_table_vni_details_t_handler_json
2430   (vl_api_lisp_eid_table_vni_details_t * mp)
2431 {
2432   vat_main_t *vam = &vat_main;
2433   vat_json_node_t *node = NULL;
2434
2435   if (VAT_JSON_ARRAY != vam->json_tree.type)
2436     {
2437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2438       vat_json_init_array (&vam->json_tree);
2439     }
2440   node = vat_json_array_add (&vam->json_tree);
2441   vat_json_init_object (node);
2442   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2443 }
2444
2445 static u8 *
2446 format_decap_next (u8 * s, va_list * args)
2447 {
2448   u32 next_index = va_arg (*args, u32);
2449
2450   switch (next_index)
2451     {
2452     case LISP_GPE_INPUT_NEXT_DROP:
2453       return format (s, "drop");
2454     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2455       return format (s, "ip4");
2456     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2457       return format (s, "ip6");
2458     default:
2459       return format (s, "unknown %d", next_index);
2460     }
2461   return s;
2462 }
2463
2464 static void
2465 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2466                                           mp)
2467 {
2468   vat_main_t *vam = &vat_main;
2469   u8 *iid_str;
2470   u8 *flag_str = NULL;
2471
2472   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2473
2474 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2475   foreach_lisp_gpe_flag_bit;
2476 #undef _
2477
2478   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2479            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2480            mp->tunnels,
2481            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2482            mp->source_ip,
2483            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2484            mp->destination_ip,
2485            ntohl (mp->encap_fib_id),
2486            ntohl (mp->decap_fib_id),
2487            format_decap_next, ntohl (mp->dcap_next),
2488            mp->ver_res >> 6,
2489            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2490
2491   vec_free (iid_str);
2492 }
2493
2494 static void
2495   vl_api_lisp_gpe_tunnel_details_t_handler_json
2496   (vl_api_lisp_gpe_tunnel_details_t * mp)
2497 {
2498   vat_main_t *vam = &vat_main;
2499   vat_json_node_t *node = NULL;
2500   struct in6_addr ip6;
2501   struct in_addr ip4;
2502   u8 *next_decap_str;
2503
2504   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2505
2506   if (VAT_JSON_ARRAY != vam->json_tree.type)
2507     {
2508       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2509       vat_json_init_array (&vam->json_tree);
2510     }
2511   node = vat_json_array_add (&vam->json_tree);
2512
2513   vat_json_init_object (node);
2514   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2515   if (mp->is_ipv6)
2516     {
2517       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2518       vat_json_object_add_ip6 (node, "source address", ip6);
2519       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2520       vat_json_object_add_ip6 (node, "destination address", ip6);
2521     }
2522   else
2523     {
2524       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2525       vat_json_object_add_ip4 (node, "source address", ip4);
2526       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2527       vat_json_object_add_ip4 (node, "destination address", ip4);
2528     }
2529   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2530   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2531   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2532   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2533   vat_json_object_add_uint (node, "flags", mp->flags);
2534   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2535   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2536   vat_json_object_add_uint (node, "res", mp->res);
2537   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2538
2539   vec_free (next_decap_str);
2540 }
2541
2542 static void
2543   vl_api_lisp_adjacencies_get_reply_t_handler
2544   (vl_api_lisp_adjacencies_get_reply_t * mp)
2545 {
2546   vat_main_t *vam = &vat_main;
2547   u32 i, n;
2548   int retval = clib_net_to_host_u32 (mp->retval);
2549   vl_api_lisp_adjacency_t *a;
2550
2551   if (retval)
2552     goto end;
2553
2554   n = clib_net_to_host_u32 (mp->count);
2555
2556   for (i = 0; i < n; i++)
2557     {
2558       a = &mp->adjacencies[i];
2559       fformat (vam->ofp, "%U %40U\n",
2560                format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2561                format_lisp_flat_eid, a->eid_type, a->reid,
2562                a->reid_prefix_len);
2563     }
2564
2565 end:
2566   vam->retval = retval;
2567   vam->result_ready = 1;
2568 }
2569
2570 static void
2571   vl_api_lisp_adjacencies_get_reply_t_handler_json
2572   (vl_api_lisp_adjacencies_get_reply_t * mp)
2573 {
2574   u8 *s = 0;
2575   vat_main_t *vam = &vat_main;
2576   vat_json_node_t *e = 0, root;
2577   u32 i, n;
2578   int retval = clib_net_to_host_u32 (mp->retval);
2579   vl_api_lisp_adjacency_t *a;
2580
2581   if (retval)
2582     goto end;
2583
2584   n = clib_net_to_host_u32 (mp->count);
2585   vat_json_init_array (&root);
2586
2587   for (i = 0; i < n; i++)
2588     {
2589       e = vat_json_array_add (&root);
2590       a = &mp->adjacencies[i];
2591
2592       vat_json_init_object (e);
2593       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2594                   a->leid_prefix_len);
2595       vec_add1 (s, 0);
2596       vat_json_object_add_string_copy (e, "leid", s);
2597       vec_free (s);
2598
2599       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2600                   a->reid_prefix_len);
2601       vec_add1 (s, 0);
2602       vat_json_object_add_string_copy (e, "reid", s);
2603       vec_free (s);
2604     }
2605
2606   vat_json_print (vam->ofp, &root);
2607   vat_json_free (&root);
2608
2609 end:
2610   vam->retval = retval;
2611   vam->result_ready = 1;
2612 }
2613
2614 static void
2615 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2616                                             * mp)
2617 {
2618   vat_main_t *vam = &vat_main;
2619
2620   fformat (vam->ofp, "%=20U\n",
2621            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2622            mp->ip_address);
2623 }
2624
2625 static void
2626   vl_api_lisp_map_resolver_details_t_handler_json
2627   (vl_api_lisp_map_resolver_details_t * mp)
2628 {
2629   vat_main_t *vam = &vat_main;
2630   vat_json_node_t *node = NULL;
2631   struct in6_addr ip6;
2632   struct in_addr ip4;
2633
2634   if (VAT_JSON_ARRAY != vam->json_tree.type)
2635     {
2636       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2637       vat_json_init_array (&vam->json_tree);
2638     }
2639   node = vat_json_array_add (&vam->json_tree);
2640
2641   vat_json_init_object (node);
2642   if (mp->is_ipv6)
2643     {
2644       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2645       vat_json_object_add_ip6 (node, "map resolver", ip6);
2646     }
2647   else
2648     {
2649       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2650       vat_json_object_add_ip4 (node, "map resolver", ip4);
2651     }
2652 }
2653
2654 static void
2655   vl_api_show_lisp_status_reply_t_handler
2656   (vl_api_show_lisp_status_reply_t * mp)
2657 {
2658   vat_main_t *vam = &vat_main;
2659   i32 retval = ntohl (mp->retval);
2660
2661   if (0 <= retval)
2662     {
2663       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2664                mp->feature_status ? "enabled" : "disabled",
2665                mp->gpe_status ? "enabled" : "disabled");
2666     }
2667
2668   vam->retval = retval;
2669   vam->result_ready = 1;
2670 }
2671
2672 static void
2673   vl_api_show_lisp_status_reply_t_handler_json
2674   (vl_api_show_lisp_status_reply_t * mp)
2675 {
2676   vat_main_t *vam = &vat_main;
2677   vat_json_node_t node;
2678   u8 *gpe_status = NULL;
2679   u8 *feature_status = NULL;
2680
2681   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2682   feature_status = format (0, "%s",
2683                            mp->feature_status ? "enabled" : "disabled");
2684   vec_add1 (gpe_status, 0);
2685   vec_add1 (feature_status, 0);
2686
2687   vat_json_init_object (&node);
2688   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2689   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2690
2691   vec_free (gpe_status);
2692   vec_free (feature_status);
2693
2694   vat_json_print (vam->ofp, &node);
2695   vat_json_free (&node);
2696
2697   vam->retval = ntohl (mp->retval);
2698   vam->result_ready = 1;
2699 }
2700
2701 static void
2702   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2703   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2704 {
2705   vat_main_t *vam = &vat_main;
2706   i32 retval = ntohl (mp->retval);
2707
2708   if (retval >= 0)
2709     {
2710       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2711     }
2712
2713   vam->retval = retval;
2714   vam->result_ready = 1;
2715 }
2716
2717 static void
2718   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2719   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2720 {
2721   vat_main_t *vam = &vat_main;
2722   vat_json_node_t *node = NULL;
2723
2724   if (VAT_JSON_ARRAY != vam->json_tree.type)
2725     {
2726       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2727       vat_json_init_array (&vam->json_tree);
2728     }
2729   node = vat_json_array_add (&vam->json_tree);
2730
2731   vat_json_init_object (node);
2732   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2733
2734   vat_json_print (vam->ofp, node);
2735   vat_json_free (node);
2736
2737   vam->retval = ntohl (mp->retval);
2738   vam->result_ready = 1;
2739 }
2740
2741 static u8 *
2742 format_lisp_map_request_mode (u8 * s, va_list * args)
2743 {
2744   u32 mode = va_arg (*args, u32);
2745
2746   switch (mode)
2747     {
2748     case 0:
2749       return format (0, "dst-only");
2750     case 1:
2751       return format (0, "src-dst");
2752     }
2753   return 0;
2754 }
2755
2756 static void
2757   vl_api_show_lisp_map_request_mode_reply_t_handler
2758   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2759 {
2760   vat_main_t *vam = &vat_main;
2761   i32 retval = ntohl (mp->retval);
2762
2763   if (0 <= retval)
2764     {
2765       u32 mode = mp->mode;
2766       fformat (vam->ofp, "map_request_mode: %U\n",
2767                format_lisp_map_request_mode, mode);
2768     }
2769
2770   vam->retval = retval;
2771   vam->result_ready = 1;
2772 }
2773
2774 static void
2775   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2776   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2777 {
2778   vat_main_t *vam = &vat_main;
2779   vat_json_node_t node;
2780   u8 *s = 0;
2781   u32 mode;
2782
2783   mode = mp->mode;
2784   s = format (0, "%U", format_lisp_map_request_mode, mode);
2785   vec_add1 (s, 0);
2786
2787   vat_json_init_object (&node);
2788   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2789   vat_json_print (vam->ofp, &node);
2790   vat_json_free (&node);
2791
2792   vec_free (s);
2793   vam->retval = ntohl (mp->retval);
2794   vam->result_ready = 1;
2795 }
2796
2797 static void
2798 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2799 {
2800   vat_main_t *vam = &vat_main;
2801   i32 retval = ntohl (mp->retval);
2802
2803   if (0 <= retval)
2804     {
2805       fformat (vam->ofp, "%-20s%-16s\n",
2806                mp->status ? "enabled" : "disabled",
2807                mp->status ? (char *) mp->locator_set_name : "");
2808     }
2809
2810   vam->retval = retval;
2811   vam->result_ready = 1;
2812 }
2813
2814 static void
2815 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2816                                             mp)
2817 {
2818   vat_main_t *vam = &vat_main;
2819   vat_json_node_t node;
2820   u8 *status = 0;
2821
2822   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2823   vec_add1 (status, 0);
2824
2825   vat_json_init_object (&node);
2826   vat_json_object_add_string_copy (&node, "status", status);
2827   if (mp->status)
2828     {
2829       vat_json_object_add_string_copy (&node, "locator_set",
2830                                        mp->locator_set_name);
2831     }
2832
2833   vec_free (status);
2834
2835   vat_json_print (vam->ofp, &node);
2836   vat_json_free (&node);
2837
2838   vam->retval = ntohl (mp->retval);
2839   vam->result_ready = 1;
2840 }
2841
2842 static u8 *
2843 format_policer_type (u8 * s, va_list * va)
2844 {
2845   u32 i = va_arg (*va, u32);
2846
2847   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2848     s = format (s, "1r2c");
2849   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2850     s = format (s, "1r3c");
2851   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2852     s = format (s, "2r3c-2698");
2853   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2854     s = format (s, "2r3c-4115");
2855   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2856     s = format (s, "2r3c-mef5cf1");
2857   else
2858     s = format (s, "ILLEGAL");
2859   return s;
2860 }
2861
2862 static u8 *
2863 format_policer_rate_type (u8 * s, va_list * va)
2864 {
2865   u32 i = va_arg (*va, u32);
2866
2867   if (i == SSE2_QOS_RATE_KBPS)
2868     s = format (s, "kbps");
2869   else if (i == SSE2_QOS_RATE_PPS)
2870     s = format (s, "pps");
2871   else
2872     s = format (s, "ILLEGAL");
2873   return s;
2874 }
2875
2876 static u8 *
2877 format_policer_round_type (u8 * s, va_list * va)
2878 {
2879   u32 i = va_arg (*va, u32);
2880
2881   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2882     s = format (s, "closest");
2883   else if (i == SSE2_QOS_ROUND_TO_UP)
2884     s = format (s, "up");
2885   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2886     s = format (s, "down");
2887   else
2888     s = format (s, "ILLEGAL");
2889   return s;
2890 }
2891
2892 static u8 *
2893 format_policer_action_type (u8 * s, va_list * va)
2894 {
2895   u32 i = va_arg (*va, u32);
2896
2897   if (i == SSE2_QOS_ACTION_DROP)
2898     s = format (s, "drop");
2899   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2900     s = format (s, "transmit");
2901   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2902     s = format (s, "mark-and-transmit");
2903   else
2904     s = format (s, "ILLEGAL");
2905   return s;
2906 }
2907
2908 static u8 *
2909 format_dscp (u8 * s, va_list * va)
2910 {
2911   u32 i = va_arg (*va, u32);
2912   char *t = 0;
2913
2914   switch (i)
2915     {
2916 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2917       foreach_vnet_dscp
2918 #undef _
2919     default:
2920       return format (s, "ILLEGAL");
2921     }
2922   s = format (s, "%s", t);
2923   return s;
2924 }
2925
2926 static void
2927 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2928 {
2929   vat_main_t *vam = &vat_main;
2930   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2931
2932   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2933     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
2934   else
2935     conform_dscp_str = format (0, "");
2936
2937   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2938     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
2939   else
2940     exceed_dscp_str = format (0, "");
2941
2942   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2943     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
2944   else
2945     violate_dscp_str = format (0, "");
2946
2947   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2948            "rate type %U, round type %U, %s rate, %s color-aware, "
2949            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2950            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2951            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
2952            mp->name,
2953            format_policer_type, mp->type,
2954            ntohl (mp->cir),
2955            ntohl (mp->eir),
2956            clib_net_to_host_u64 (mp->cb),
2957            clib_net_to_host_u64 (mp->eb),
2958            format_policer_rate_type, mp->rate_type,
2959            format_policer_round_type, mp->round_type,
2960            mp->single_rate ? "single" : "dual",
2961            mp->color_aware ? "is" : "not",
2962            ntohl (mp->cir_tokens_per_period),
2963            ntohl (mp->pir_tokens_per_period),
2964            ntohl (mp->scale),
2965            ntohl (mp->current_limit),
2966            ntohl (mp->current_bucket),
2967            ntohl (mp->extended_limit),
2968            ntohl (mp->extended_bucket),
2969            clib_net_to_host_u64 (mp->last_update_time),
2970            format_policer_action_type, mp->conform_action_type,
2971            conform_dscp_str,
2972            format_policer_action_type, mp->exceed_action_type,
2973            exceed_dscp_str,
2974            format_policer_action_type, mp->violate_action_type,
2975            violate_dscp_str);
2976
2977   vec_free (conform_dscp_str);
2978   vec_free (exceed_dscp_str);
2979   vec_free (violate_dscp_str);
2980 }
2981
2982 static void vl_api_policer_details_t_handler_json
2983   (vl_api_policer_details_t * mp)
2984 {
2985   vat_main_t *vam = &vat_main;
2986   vat_json_node_t *node;
2987   u8 *rate_type_str, *round_type_str, *type_str;
2988   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2989
2990   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2991   round_type_str =
2992     format (0, "%U", format_policer_round_type, mp->round_type);
2993   type_str = format (0, "%U", format_policer_type, mp->type);
2994   conform_action_str = format (0, "%U", format_policer_action_type,
2995                                mp->conform_action_type);
2996   exceed_action_str = format (0, "%U", format_policer_action_type,
2997                               mp->exceed_action_type);
2998   violate_action_str = format (0, "%U", format_policer_action_type,
2999                                mp->violate_action_type);
3000
3001   if (VAT_JSON_ARRAY != vam->json_tree.type)
3002     {
3003       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3004       vat_json_init_array (&vam->json_tree);
3005     }
3006   node = vat_json_array_add (&vam->json_tree);
3007
3008   vat_json_init_object (node);
3009   vat_json_object_add_string_copy (node, "name", mp->name);
3010   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3011   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3012   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3013   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3014   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3015   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3016   vat_json_object_add_string_copy (node, "type", type_str);
3017   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3018   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3019   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3020   vat_json_object_add_uint (node, "cir_tokens_per_period",
3021                             ntohl (mp->cir_tokens_per_period));
3022   vat_json_object_add_uint (node, "eir_tokens_per_period",
3023                             ntohl (mp->pir_tokens_per_period));
3024   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3025   vat_json_object_add_uint (node, "current_bucket",
3026                             ntohl (mp->current_bucket));
3027   vat_json_object_add_uint (node, "extended_limit",
3028                             ntohl (mp->extended_limit));
3029   vat_json_object_add_uint (node, "extended_bucket",
3030                             ntohl (mp->extended_bucket));
3031   vat_json_object_add_uint (node, "last_update_time",
3032                             ntohl (mp->last_update_time));
3033   vat_json_object_add_string_copy (node, "conform_action",
3034                                    conform_action_str);
3035   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3036     {
3037       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3038       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3039       vec_free (dscp_str);
3040     }
3041   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3042   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3043     {
3044       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3045       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3046       vec_free (dscp_str);
3047     }
3048   vat_json_object_add_string_copy (node, "violate_action",
3049                                    violate_action_str);
3050   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3051     {
3052       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3053       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3054       vec_free (dscp_str);
3055     }
3056
3057   vec_free (rate_type_str);
3058   vec_free (round_type_str);
3059   vec_free (type_str);
3060   vec_free (conform_action_str);
3061   vec_free (exceed_action_str);
3062   vec_free (violate_action_str);
3063 }
3064
3065 static void
3066 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3067                                            mp)
3068 {
3069   vat_main_t *vam = &vat_main;
3070   int i, count = ntohl (mp->count);
3071
3072   if (count > 0)
3073     fformat (vam->ofp, "classify table ids (%d) : ", count);
3074   for (i = 0; i < count; i++)
3075     {
3076       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3077       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3078     }
3079   vam->retval = ntohl (mp->retval);
3080   vam->result_ready = 1;
3081 }
3082
3083 static void
3084   vl_api_classify_table_ids_reply_t_handler_json
3085   (vl_api_classify_table_ids_reply_t * mp)
3086 {
3087   vat_main_t *vam = &vat_main;
3088   int i, count = ntohl (mp->count);
3089
3090   if (count > 0)
3091     {
3092       vat_json_node_t node;
3093
3094       vat_json_init_object (&node);
3095       for (i = 0; i < count; i++)
3096         {
3097           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3098         }
3099       vat_json_print (vam->ofp, &node);
3100       vat_json_free (&node);
3101     }
3102   vam->retval = ntohl (mp->retval);
3103   vam->result_ready = 1;
3104 }
3105
3106 static void
3107   vl_api_classify_table_by_interface_reply_t_handler
3108   (vl_api_classify_table_by_interface_reply_t * mp)
3109 {
3110   vat_main_t *vam = &vat_main;
3111   u32 table_id;
3112
3113   table_id = ntohl (mp->l2_table_id);
3114   if (table_id != ~0)
3115     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3116   else
3117     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3118   table_id = ntohl (mp->ip4_table_id);
3119   if (table_id != ~0)
3120     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3121   else
3122     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3123   table_id = ntohl (mp->ip6_table_id);
3124   if (table_id != ~0)
3125     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3126   else
3127     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3128   vam->retval = ntohl (mp->retval);
3129   vam->result_ready = 1;
3130 }
3131
3132 static void
3133   vl_api_classify_table_by_interface_reply_t_handler_json
3134   (vl_api_classify_table_by_interface_reply_t * mp)
3135 {
3136   vat_main_t *vam = &vat_main;
3137   vat_json_node_t node;
3138
3139   vat_json_init_object (&node);
3140
3141   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3142   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3143   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3144
3145   vat_json_print (vam->ofp, &node);
3146   vat_json_free (&node);
3147
3148   vam->retval = ntohl (mp->retval);
3149   vam->result_ready = 1;
3150 }
3151
3152 static void vl_api_policer_add_del_reply_t_handler
3153   (vl_api_policer_add_del_reply_t * mp)
3154 {
3155   vat_main_t *vam = &vat_main;
3156   i32 retval = ntohl (mp->retval);
3157   if (vam->async_mode)
3158     {
3159       vam->async_errors += (retval < 0);
3160     }
3161   else
3162     {
3163       vam->retval = retval;
3164       vam->result_ready = 1;
3165       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3166         /*
3167          * Note: this is just barely thread-safe, depends on
3168          * the main thread spinning waiting for an answer...
3169          */
3170         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3171     }
3172 }
3173
3174 static void vl_api_policer_add_del_reply_t_handler_json
3175   (vl_api_policer_add_del_reply_t * mp)
3176 {
3177   vat_main_t *vam = &vat_main;
3178   vat_json_node_t node;
3179
3180   vat_json_init_object (&node);
3181   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3182   vat_json_object_add_uint (&node, "policer_index",
3183                             ntohl (mp->policer_index));
3184
3185   vat_json_print (vam->ofp, &node);
3186   vat_json_free (&node);
3187
3188   vam->retval = ntohl (mp->retval);
3189   vam->result_ready = 1;
3190 }
3191
3192 /* Format hex dump. */
3193 u8 *
3194 format_hex_bytes (u8 * s, va_list * va)
3195 {
3196   u8 *bytes = va_arg (*va, u8 *);
3197   int n_bytes = va_arg (*va, int);
3198   uword i;
3199
3200   /* Print short or long form depending on byte count. */
3201   uword short_form = n_bytes <= 32;
3202   uword indent = format_get_indent (s);
3203
3204   if (n_bytes == 0)
3205     return s;
3206
3207   for (i = 0; i < n_bytes; i++)
3208     {
3209       if (!short_form && (i % 32) == 0)
3210         s = format (s, "%08x: ", i);
3211       s = format (s, "%02x", bytes[i]);
3212       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3213         s = format (s, "\n%U", format_white_space, indent);
3214     }
3215
3216   return s;
3217 }
3218
3219 static void
3220 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3221                                             * mp)
3222 {
3223   vat_main_t *vam = &vat_main;
3224   i32 retval = ntohl (mp->retval);
3225   if (retval == 0)
3226     {
3227       fformat (vam->ofp, "classify table info :\n");
3228       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3229                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3230                ntohl (mp->miss_next_index));
3231       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3232                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3233                ntohl (mp->match_n_vectors));
3234       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3235                ntohl (mp->mask_length));
3236     }
3237   vam->retval = retval;
3238   vam->result_ready = 1;
3239 }
3240
3241 static void
3242   vl_api_classify_table_info_reply_t_handler_json
3243   (vl_api_classify_table_info_reply_t * mp)
3244 {
3245   vat_main_t *vam = &vat_main;
3246   vat_json_node_t node;
3247
3248   i32 retval = ntohl (mp->retval);
3249   if (retval == 0)
3250     {
3251       vat_json_init_object (&node);
3252
3253       vat_json_object_add_int (&node, "sessions",
3254                                ntohl (mp->active_sessions));
3255       vat_json_object_add_int (&node, "nexttbl",
3256                                ntohl (mp->next_table_index));
3257       vat_json_object_add_int (&node, "nextnode",
3258                                ntohl (mp->miss_next_index));
3259       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3260       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3261       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3262       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3263                       ntohl (mp->mask_length), 0);
3264       vat_json_object_add_string_copy (&node, "mask", s);
3265
3266       vat_json_print (vam->ofp, &node);
3267       vat_json_free (&node);
3268     }
3269   vam->retval = ntohl (mp->retval);
3270   vam->result_ready = 1;
3271 }
3272
3273 static void
3274 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3275                                            mp)
3276 {
3277   vat_main_t *vam = &vat_main;
3278
3279   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3280            ntohl (mp->hit_next_index), ntohl (mp->advance),
3281            ntohl (mp->opaque_index));
3282   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3283            ntohl (mp->match_length));
3284 }
3285
3286 static void
3287   vl_api_classify_session_details_t_handler_json
3288   (vl_api_classify_session_details_t * mp)
3289 {
3290   vat_main_t *vam = &vat_main;
3291   vat_json_node_t *node = NULL;
3292
3293   if (VAT_JSON_ARRAY != vam->json_tree.type)
3294     {
3295       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3296       vat_json_init_array (&vam->json_tree);
3297     }
3298   node = vat_json_array_add (&vam->json_tree);
3299
3300   vat_json_init_object (node);
3301   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3302   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3303   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3304   u8 *s =
3305     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3306             0);
3307   vat_json_object_add_string_copy (node, "match", s);
3308 }
3309
3310 static void vl_api_pg_create_interface_reply_t_handler
3311   (vl_api_pg_create_interface_reply_t * mp)
3312 {
3313   vat_main_t *vam = &vat_main;
3314
3315   vam->retval = ntohl (mp->retval);
3316   vam->result_ready = 1;
3317 }
3318
3319 static void vl_api_pg_create_interface_reply_t_handler_json
3320   (vl_api_pg_create_interface_reply_t * mp)
3321 {
3322   vat_main_t *vam = &vat_main;
3323   vat_json_node_t node;
3324
3325   i32 retval = ntohl (mp->retval);
3326   if (retval == 0)
3327     {
3328       vat_json_init_object (&node);
3329
3330       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3331
3332       vat_json_print (vam->ofp, &node);
3333       vat_json_free (&node);
3334     }
3335   vam->retval = ntohl (mp->retval);
3336   vam->result_ready = 1;
3337 }
3338
3339 static void vl_api_policer_classify_details_t_handler
3340   (vl_api_policer_classify_details_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343
3344   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3345            ntohl (mp->table_index));
3346 }
3347
3348 static void vl_api_policer_classify_details_t_handler_json
3349   (vl_api_policer_classify_details_t * mp)
3350 {
3351   vat_main_t *vam = &vat_main;
3352   vat_json_node_t *node;
3353
3354   if (VAT_JSON_ARRAY != vam->json_tree.type)
3355     {
3356       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3357       vat_json_init_array (&vam->json_tree);
3358     }
3359   node = vat_json_array_add (&vam->json_tree);
3360
3361   vat_json_init_object (node);
3362   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3363   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3364 }
3365
3366 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3367   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3368 {
3369   vat_main_t *vam = &vat_main;
3370   i32 retval = ntohl (mp->retval);
3371   if (vam->async_mode)
3372     {
3373       vam->async_errors += (retval < 0);
3374     }
3375   else
3376     {
3377       vam->retval = retval;
3378       vam->sw_if_index = ntohl (mp->sw_if_index);
3379       vam->result_ready = 1;
3380     }
3381 }
3382
3383 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3384   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3385 {
3386   vat_main_t *vam = &vat_main;
3387   vat_json_node_t node;
3388
3389   vat_json_init_object (&node);
3390   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3391   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3392
3393   vat_json_print (vam->ofp, &node);
3394   vat_json_free (&node);
3395
3396   vam->retval = ntohl (mp->retval);
3397   vam->result_ready = 1;
3398 }
3399
3400 static void vl_api_flow_classify_details_t_handler
3401   (vl_api_flow_classify_details_t * mp)
3402 {
3403   vat_main_t *vam = &vat_main;
3404
3405   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3406            ntohl (mp->table_index));
3407 }
3408
3409 static void vl_api_flow_classify_details_t_handler_json
3410   (vl_api_flow_classify_details_t * mp)
3411 {
3412   vat_main_t *vam = &vat_main;
3413   vat_json_node_t *node;
3414
3415   if (VAT_JSON_ARRAY != vam->json_tree.type)
3416     {
3417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3418       vat_json_init_array (&vam->json_tree);
3419     }
3420   node = vat_json_array_add (&vam->json_tree);
3421
3422   vat_json_init_object (node);
3423   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3424   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3425 }
3426
3427
3428
3429 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3430 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3431 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3432 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3433 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3434 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3435
3436 /*
3437  * Generate boilerplate reply handlers, which
3438  * dig the return value out of the xxx_reply_t API message,
3439  * stick it into vam->retval, and set vam->result_ready
3440  *
3441  * Could also do this by pointing N message decode slots at
3442  * a single function, but that could break in subtle ways.
3443  */
3444
3445 #define foreach_standard_reply_retval_handler           \
3446 _(sw_interface_set_flags_reply)                         \
3447 _(sw_interface_add_del_address_reply)                   \
3448 _(sw_interface_set_table_reply)                         \
3449 _(sw_interface_set_mpls_enable_reply)                   \
3450 _(sw_interface_set_vpath_reply)                         \
3451 _(sw_interface_set_l2_bridge_reply)                     \
3452 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3453 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3454 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3455 _(bridge_domain_add_del_reply)                          \
3456 _(sw_interface_set_l2_xconnect_reply)                   \
3457 _(l2fib_add_del_reply)                                  \
3458 _(ip_add_del_route_reply)                               \
3459 _(mpls_route_add_del_reply)                             \
3460 _(mpls_ip_bind_unbind_reply)                            \
3461 _(proxy_arp_add_del_reply)                              \
3462 _(proxy_arp_intfc_enable_disable_reply)                 \
3463 _(mpls_add_del_encap_reply)                             \
3464 _(mpls_ethernet_add_del_tunnel_2_reply)                 \
3465 _(sw_interface_set_unnumbered_reply)                    \
3466 _(ip_neighbor_add_del_reply)                            \
3467 _(reset_vrf_reply)                                      \
3468 _(oam_add_del_reply)                                    \
3469 _(reset_fib_reply)                                      \
3470 _(dhcp_proxy_config_reply)                              \
3471 _(dhcp_proxy_config_2_reply)                            \
3472 _(dhcp_proxy_set_vss_reply)                             \
3473 _(dhcp_client_config_reply)                             \
3474 _(set_ip_flow_hash_reply)                               \
3475 _(sw_interface_ip6_enable_disable_reply)                \
3476 _(sw_interface_ip6_set_link_local_address_reply)        \
3477 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3478 _(sw_interface_ip6nd_ra_config_reply)                   \
3479 _(set_arp_neighbor_limit_reply)                         \
3480 _(l2_patch_add_del_reply)                               \
3481 _(sr_tunnel_add_del_reply)                              \
3482 _(sr_policy_add_del_reply)                              \
3483 _(sr_multicast_map_add_del_reply)                       \
3484 _(classify_add_del_session_reply)                       \
3485 _(classify_set_interface_ip_table_reply)                \
3486 _(classify_set_interface_l2_tables_reply)               \
3487 _(l2tpv3_set_tunnel_cookies_reply)                      \
3488 _(l2tpv3_interface_enable_disable_reply)                \
3489 _(l2tpv3_set_lookup_key_reply)                          \
3490 _(l2_fib_clear_table_reply)                             \
3491 _(l2_interface_efp_filter_reply)                        \
3492 _(l2_interface_vlan_tag_rewrite_reply)                  \
3493 _(modify_vhost_user_if_reply)                           \
3494 _(delete_vhost_user_if_reply)                           \
3495 _(want_ip4_arp_events_reply)                            \
3496 _(want_ip6_nd_events_reply)                             \
3497 _(input_acl_set_interface_reply)                        \
3498 _(ipsec_spd_add_del_reply)                              \
3499 _(ipsec_interface_add_del_spd_reply)                    \
3500 _(ipsec_spd_add_del_entry_reply)                        \
3501 _(ipsec_sad_add_del_entry_reply)                        \
3502 _(ipsec_sa_set_key_reply)                               \
3503 _(ikev2_profile_add_del_reply)                          \
3504 _(ikev2_profile_set_auth_reply)                         \
3505 _(ikev2_profile_set_id_reply)                           \
3506 _(ikev2_profile_set_ts_reply)                           \
3507 _(ikev2_set_local_key_reply)                            \
3508 _(delete_loopback_reply)                                \
3509 _(bd_ip_mac_add_del_reply)                              \
3510 _(map_del_domain_reply)                                 \
3511 _(map_add_del_rule_reply)                               \
3512 _(want_interface_events_reply)                          \
3513 _(want_stats_reply)                                     \
3514 _(cop_interface_enable_disable_reply)                   \
3515 _(cop_whitelist_enable_disable_reply)                   \
3516 _(sw_interface_clear_stats_reply)                       \
3517 _(ioam_enable_reply)                              \
3518 _(ioam_disable_reply)                              \
3519 _(lisp_add_del_locator_reply)                           \
3520 _(lisp_add_del_local_eid_reply)                         \
3521 _(lisp_add_del_remote_mapping_reply)                    \
3522 _(lisp_add_del_adjacency_reply)                         \
3523 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3524 _(lisp_add_del_map_resolver_reply)                      \
3525 _(lisp_gpe_enable_disable_reply)                        \
3526 _(lisp_gpe_add_del_iface_reply)                         \
3527 _(lisp_enable_disable_reply)                            \
3528 _(lisp_pitr_set_locator_set_reply)                      \
3529 _(lisp_map_request_mode_reply)                          \
3530 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3531 _(lisp_eid_table_add_del_map_reply)                     \
3532 _(vxlan_gpe_add_del_tunnel_reply)                       \
3533 _(af_packet_delete_reply)                               \
3534 _(policer_classify_set_interface_reply)                 \
3535 _(netmap_create_reply)                                  \
3536 _(netmap_delete_reply)                                  \
3537 _(set_ipfix_exporter_reply)                             \
3538 _(set_ipfix_classify_stream_reply)                      \
3539 _(ipfix_classify_table_add_del_reply)                   \
3540 _(flow_classify_set_interface_reply)                    \
3541 _(sw_interface_span_enable_disable_reply)               \
3542 _(pg_capture_reply)                                     \
3543 _(pg_enable_disable_reply)                              \
3544 _(ip_source_and_port_range_check_add_del_reply)         \
3545 _(ip_source_and_port_range_check_interface_add_del_reply)\
3546 _(delete_subif_reply)                                   \
3547 _(l2_interface_pbb_tag_rewrite_reply)                   \
3548 _(punt_reply)                                           \
3549 _(feature_enable_disable_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_L2_XCONNECT_REPLY,                                   \
3601   sw_interface_set_l2_xconnect_reply)                                   \
3602 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3603   sw_interface_set_l2_bridge_reply)                                     \
3604 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3605   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3606 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3607   sw_interface_set_dpdk_hqos_subport_reply)                             \
3608 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3609   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3610 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3611 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3612 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3613 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3614 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3615 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3616 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3617 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3618 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3619 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3620 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3621 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3622 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3623 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3624 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3625   proxy_arp_intfc_enable_disable_reply)                                 \
3626 _(MPLS_ADD_DEL_ENCAP_REPLY, mpls_add_del_encap_reply)                   \
3627 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_REPLY,                                   \
3628   mpls_ethernet_add_del_tunnel_reply)                                   \
3629 _(MPLS_ETHERNET_ADD_DEL_TUNNEL_2_REPLY,                                 \
3630   mpls_ethernet_add_del_tunnel_2_reply)                                 \
3631 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3632   sw_interface_set_unnumbered_reply)                                    \
3633 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3634 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3635 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3636 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3637 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3638 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3639 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3640 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3641 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3642 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3643 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3644 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3645   sw_interface_ip6_enable_disable_reply)                                \
3646 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3647   sw_interface_ip6_set_link_local_address_reply)                        \
3648 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3649   sw_interface_ip6nd_ra_prefix_reply)                                   \
3650 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3651   sw_interface_ip6nd_ra_config_reply)                                   \
3652 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3653 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3654 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3655 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3656 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3657 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3658 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3659 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3660 classify_set_interface_ip_table_reply)                                  \
3661 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3662   classify_set_interface_l2_tables_reply)                               \
3663 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3664 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3665 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3666 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3667 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3668   l2tpv3_interface_enable_disable_reply)                                \
3669 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3670 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3671 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3672 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3673 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3674 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3675 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3676 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3677 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3678 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3679 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3680 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3681 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3682 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3683 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3684 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3685 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3686 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3687 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3688 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3689 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3690 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3691 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3692 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3693 _(IP_DETAILS, ip_details)                                               \
3694 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3695 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3696 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3697 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3698 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3699 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3700 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3701 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3702 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3703 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3704 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3705 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3706 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3707 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3708 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3709 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3710 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3711 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3712 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3713 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3714 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3715 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3716 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3717 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3718 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3719 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3720 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3721 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3722 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3723 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3724 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3725 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3726 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3727 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3728 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3729 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3730 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3731 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3732 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3733 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3734 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3735 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3736 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3737 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3738 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3739 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3740 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3741 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3742 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3743 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3744 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3745 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3746 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3747   lisp_add_del_map_request_itr_rlocs_reply)                             \
3748 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3749   lisp_get_map_request_itr_rlocs_reply)                                 \
3750 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3751 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3752 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3753 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3754 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3755 _(POLICER_DETAILS, policer_details)                                     \
3756 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3757 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3758 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3759 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3760 _(MPLS_ETH_TUNNEL_DETAILS, mpls_eth_tunnel_details)                     \
3761 _(MPLS_FIB_ENCAP_DETAILS, mpls_fib_encap_details)                       \
3762 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3763 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3764 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3765 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3766 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3767 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3768 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3769 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3770 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3771 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3772 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3773 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3774 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3775 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3776 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3777 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3778 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3779 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3780 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3781 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3782  ip_source_and_port_range_check_add_del_reply)                          \
3783 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3784  ip_source_and_port_range_check_interface_add_del_reply)                \
3785 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3786 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3787 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3788 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3789 _(PUNT_REPLY, punt_reply)                                               \
3790 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3791 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3792 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)
3793
3794 /* M: construct, but don't yet send a message */
3795
3796 #define M(T,t)                                  \
3797 do {                                            \
3798     vam->result_ready = 0;                      \
3799     mp = vl_msg_api_alloc(sizeof(*mp));         \
3800     memset (mp, 0, sizeof (*mp));               \
3801     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3802     mp->client_index = vam->my_client_index;    \
3803 } while(0);
3804
3805 #define M2(T,t,n)                               \
3806 do {                                            \
3807     vam->result_ready = 0;                      \
3808     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3809     memset (mp, 0, sizeof (*mp));               \
3810     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3811     mp->client_index = vam->my_client_index;    \
3812 } while(0);
3813
3814
3815 /* S: send a message */
3816 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3817
3818 /* W: wait for results, with timeout */
3819 #define W                                       \
3820 do {                                            \
3821     timeout = vat_time_now (vam) + 1.0;         \
3822                                                 \
3823     while (vat_time_now (vam) < timeout) {      \
3824         if (vam->result_ready == 1) {           \
3825             return (vam->retval);               \
3826         }                                       \
3827     }                                           \
3828     return -99;                                 \
3829 } while(0);
3830
3831 /* W2: wait for results, with timeout */
3832 #define W2(body)                                \
3833 do {                                            \
3834     timeout = vat_time_now (vam) + 1.0;         \
3835                                                 \
3836     while (vat_time_now (vam) < timeout) {      \
3837         if (vam->result_ready == 1) {           \
3838           (body);                               \
3839           return (vam->retval);                 \
3840         }                                       \
3841     }                                           \
3842     return -99;                                 \
3843 } while(0);
3844
3845 typedef struct
3846 {
3847   u8 *name;
3848   u32 value;
3849 } name_sort_t;
3850
3851
3852 #define STR_VTR_OP_CASE(op)     \
3853     case L2_VTR_ ## op:         \
3854         return "" # op;
3855
3856 static const char *
3857 str_vtr_op (u32 vtr_op)
3858 {
3859   switch (vtr_op)
3860     {
3861       STR_VTR_OP_CASE (DISABLED);
3862       STR_VTR_OP_CASE (PUSH_1);
3863       STR_VTR_OP_CASE (PUSH_2);
3864       STR_VTR_OP_CASE (POP_1);
3865       STR_VTR_OP_CASE (POP_2);
3866       STR_VTR_OP_CASE (TRANSLATE_1_1);
3867       STR_VTR_OP_CASE (TRANSLATE_1_2);
3868       STR_VTR_OP_CASE (TRANSLATE_2_1);
3869       STR_VTR_OP_CASE (TRANSLATE_2_2);
3870     }
3871
3872   return "UNKNOWN";
3873 }
3874
3875 static int
3876 dump_sub_interface_table (vat_main_t * vam)
3877 {
3878   const sw_interface_subif_t *sub = NULL;
3879
3880   if (vam->json_output)
3881     {
3882       clib_warning
3883         ("JSON output supported only for VPE API calls and dump_stats_table");
3884       return -99;
3885     }
3886
3887   fformat (vam->ofp,
3888            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
3889            "Interface", "sw_if_index",
3890            "sub id", "dot1ad", "tags", "outer id",
3891            "inner id", "exact", "default", "outer any", "inner any");
3892
3893   vec_foreach (sub, vam->sw_if_subif_table)
3894   {
3895     fformat (vam->ofp,
3896              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
3897              sub->interface_name,
3898              sub->sw_if_index,
3899              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3900              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3901              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3902              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3903     if (sub->vtr_op != L2_VTR_DISABLED)
3904       {
3905         fformat (vam->ofp,
3906                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3907                  "tag1: %d tag2: %d ]\n",
3908                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3909                  sub->vtr_tag1, sub->vtr_tag2);
3910       }
3911   }
3912
3913   return 0;
3914 }
3915
3916 static int
3917 name_sort_cmp (void *a1, void *a2)
3918 {
3919   name_sort_t *n1 = a1;
3920   name_sort_t *n2 = a2;
3921
3922   return strcmp ((char *) n1->name, (char *) n2->name);
3923 }
3924
3925 static int
3926 dump_interface_table (vat_main_t * vam)
3927 {
3928   hash_pair_t *p;
3929   name_sort_t *nses = 0, *ns;
3930
3931   if (vam->json_output)
3932     {
3933       clib_warning
3934         ("JSON output supported only for VPE API calls and dump_stats_table");
3935       return -99;
3936     }
3937
3938   /* *INDENT-OFF* */
3939   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3940   ({
3941     vec_add2 (nses, ns, 1);
3942     ns->name = (u8 *)(p->key);
3943     ns->value = (u32) p->value[0];
3944   }));
3945   /* *INDENT-ON* */
3946
3947   vec_sort_with_function (nses, name_sort_cmp);
3948
3949   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
3950   vec_foreach (ns, nses)
3951   {
3952     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
3953   }
3954   vec_free (nses);
3955   return 0;
3956 }
3957
3958 static int
3959 dump_ip_table (vat_main_t * vam, int is_ipv6)
3960 {
3961   const ip_details_t *det = NULL;
3962   const ip_address_details_t *address = NULL;
3963   u32 i = ~0;
3964
3965   fformat (vam->ofp, "%-12s\n", "sw_if_index");
3966
3967   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3968   {
3969     i++;
3970     if (!det->present)
3971       {
3972         continue;
3973       }
3974     fformat (vam->ofp, "%-12d\n", i);
3975     fformat (vam->ofp,
3976              "            %-30s%-13s\n", "Address", "Prefix length");
3977     if (!det->addr)
3978       {
3979         continue;
3980       }
3981     vec_foreach (address, det->addr)
3982     {
3983       fformat (vam->ofp,
3984                "            %-30U%-13d\n",
3985                is_ipv6 ? format_ip6_address : format_ip4_address,
3986                address->ip, address->prefix_length);
3987     }
3988   }
3989
3990   return 0;
3991 }
3992
3993 static int
3994 dump_ipv4_table (vat_main_t * vam)
3995 {
3996   if (vam->json_output)
3997     {
3998       clib_warning
3999         ("JSON output supported only for VPE API calls and dump_stats_table");
4000       return -99;
4001     }
4002
4003   return dump_ip_table (vam, 0);
4004 }
4005
4006 static int
4007 dump_ipv6_table (vat_main_t * vam)
4008 {
4009   if (vam->json_output)
4010     {
4011       clib_warning
4012         ("JSON output supported only for VPE API calls and dump_stats_table");
4013       return -99;
4014     }
4015
4016   return dump_ip_table (vam, 1);
4017 }
4018
4019 static char *
4020 counter_type_to_str (u8 counter_type, u8 is_combined)
4021 {
4022   if (!is_combined)
4023     {
4024       switch (counter_type)
4025         {
4026         case VNET_INTERFACE_COUNTER_DROP:
4027           return "drop";
4028         case VNET_INTERFACE_COUNTER_PUNT:
4029           return "punt";
4030         case VNET_INTERFACE_COUNTER_IP4:
4031           return "ip4";
4032         case VNET_INTERFACE_COUNTER_IP6:
4033           return "ip6";
4034         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4035           return "rx-no-buf";
4036         case VNET_INTERFACE_COUNTER_RX_MISS:
4037           return "rx-miss";
4038         case VNET_INTERFACE_COUNTER_RX_ERROR:
4039           return "rx-error";
4040         case VNET_INTERFACE_COUNTER_TX_ERROR:
4041           return "tx-error";
4042         default:
4043           return "INVALID-COUNTER-TYPE";
4044         }
4045     }
4046   else
4047     {
4048       switch (counter_type)
4049         {
4050         case VNET_INTERFACE_COUNTER_RX:
4051           return "rx";
4052         case VNET_INTERFACE_COUNTER_TX:
4053           return "tx";
4054         default:
4055           return "INVALID-COUNTER-TYPE";
4056         }
4057     }
4058 }
4059
4060 static int
4061 dump_stats_table (vat_main_t * vam)
4062 {
4063   vat_json_node_t node;
4064   vat_json_node_t *msg_array;
4065   vat_json_node_t *msg;
4066   vat_json_node_t *counter_array;
4067   vat_json_node_t *counter;
4068   interface_counter_t c;
4069   u64 packets;
4070   ip4_fib_counter_t *c4;
4071   ip6_fib_counter_t *c6;
4072   int i, j;
4073
4074   if (!vam->json_output)
4075     {
4076       clib_warning ("dump_stats_table supported only in JSON format");
4077       return -99;
4078     }
4079
4080   vat_json_init_object (&node);
4081
4082   /* interface counters */
4083   msg_array = vat_json_object_add (&node, "interface_counters");
4084   vat_json_init_array (msg_array);
4085   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4086     {
4087       msg = vat_json_array_add (msg_array);
4088       vat_json_init_object (msg);
4089       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4090                                        (u8 *) counter_type_to_str (i, 0));
4091       vat_json_object_add_int (msg, "is_combined", 0);
4092       counter_array = vat_json_object_add (msg, "data");
4093       vat_json_init_array (counter_array);
4094       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4095         {
4096           packets = vam->simple_interface_counters[i][j];
4097           vat_json_array_add_uint (counter_array, packets);
4098         }
4099     }
4100   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4101     {
4102       msg = vat_json_array_add (msg_array);
4103       vat_json_init_object (msg);
4104       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4105                                        (u8 *) counter_type_to_str (i, 1));
4106       vat_json_object_add_int (msg, "is_combined", 1);
4107       counter_array = vat_json_object_add (msg, "data");
4108       vat_json_init_array (counter_array);
4109       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4110         {
4111           c = vam->combined_interface_counters[i][j];
4112           counter = vat_json_array_add (counter_array);
4113           vat_json_init_object (counter);
4114           vat_json_object_add_uint (counter, "packets", c.packets);
4115           vat_json_object_add_uint (counter, "bytes", c.bytes);
4116         }
4117     }
4118
4119   /* ip4 fib counters */
4120   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4121   vat_json_init_array (msg_array);
4122   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4123     {
4124       msg = vat_json_array_add (msg_array);
4125       vat_json_init_object (msg);
4126       vat_json_object_add_uint (msg, "vrf_id",
4127                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4128       counter_array = vat_json_object_add (msg, "c");
4129       vat_json_init_array (counter_array);
4130       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4131         {
4132           counter = vat_json_array_add (counter_array);
4133           vat_json_init_object (counter);
4134           c4 = &vam->ip4_fib_counters[i][j];
4135           vat_json_object_add_ip4 (counter, "address", c4->address);
4136           vat_json_object_add_uint (counter, "address_length",
4137                                     c4->address_length);
4138           vat_json_object_add_uint (counter, "packets", c4->packets);
4139           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4140         }
4141     }
4142
4143   /* ip6 fib counters */
4144   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4145   vat_json_init_array (msg_array);
4146   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4147     {
4148       msg = vat_json_array_add (msg_array);
4149       vat_json_init_object (msg);
4150       vat_json_object_add_uint (msg, "vrf_id",
4151                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4152       counter_array = vat_json_object_add (msg, "c");
4153       vat_json_init_array (counter_array);
4154       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4155         {
4156           counter = vat_json_array_add (counter_array);
4157           vat_json_init_object (counter);
4158           c6 = &vam->ip6_fib_counters[i][j];
4159           vat_json_object_add_ip6 (counter, "address", c6->address);
4160           vat_json_object_add_uint (counter, "address_length",
4161                                     c6->address_length);
4162           vat_json_object_add_uint (counter, "packets", c6->packets);
4163           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4164         }
4165     }
4166
4167   vat_json_print (vam->ofp, &node);
4168   vat_json_free (&node);
4169
4170   return 0;
4171 }
4172
4173 int
4174 exec (vat_main_t * vam)
4175 {
4176   api_main_t *am = &api_main;
4177   vl_api_cli_request_t *mp;
4178   f64 timeout;
4179   void *oldheap;
4180   u8 *cmd = 0;
4181   unformat_input_t *i = vam->input;
4182
4183   if (vec_len (i->buffer) == 0)
4184     return -1;
4185
4186   if (vam->exec_mode == 0 && unformat (i, "mode"))
4187     {
4188       vam->exec_mode = 1;
4189       return 0;
4190     }
4191   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4192     {
4193       vam->exec_mode = 0;
4194       return 0;
4195     }
4196
4197
4198   M (CLI_REQUEST, cli_request);
4199
4200   /*
4201    * Copy cmd into shared memory.
4202    * In order for the CLI command to work, it
4203    * must be a vector ending in \n, not a C-string ending
4204    * in \n\0.
4205    */
4206   pthread_mutex_lock (&am->vlib_rp->mutex);
4207   oldheap = svm_push_data_heap (am->vlib_rp);
4208
4209   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4210   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4211
4212   svm_pop_heap (oldheap);
4213   pthread_mutex_unlock (&am->vlib_rp->mutex);
4214
4215   mp->cmd_in_shmem = (u64) cmd;
4216   S;
4217   timeout = vat_time_now (vam) + 10.0;
4218
4219   while (vat_time_now (vam) < timeout)
4220     {
4221       if (vam->result_ready == 1)
4222         {
4223           u8 *free_me;
4224           if (vam->shmem_result != NULL)
4225             fformat (vam->ofp, "%s", vam->shmem_result);
4226           pthread_mutex_lock (&am->vlib_rp->mutex);
4227           oldheap = svm_push_data_heap (am->vlib_rp);
4228
4229           free_me = (u8 *) vam->shmem_result;
4230           vec_free (free_me);
4231
4232           svm_pop_heap (oldheap);
4233           pthread_mutex_unlock (&am->vlib_rp->mutex);
4234           return 0;
4235         }
4236     }
4237   return -99;
4238 }
4239
4240 /*
4241  * Future replacement of exec() that passes CLI buffers directly in
4242  * the API messages instead of an additional shared memory area.
4243  */
4244 static int
4245 exec_inband (vat_main_t * vam)
4246 {
4247   vl_api_cli_inband_t *mp;
4248   f64 timeout;
4249   unformat_input_t *i = vam->input;
4250
4251   if (vec_len (i->buffer) == 0)
4252     return -1;
4253
4254   if (vam->exec_mode == 0 && unformat (i, "mode"))
4255     {
4256       vam->exec_mode = 1;
4257       return 0;
4258     }
4259   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4260     {
4261       vam->exec_mode = 0;
4262       return 0;
4263     }
4264
4265   /*
4266    * In order for the CLI command to work, it
4267    * must be a vector ending in \n, not a C-string ending
4268    * in \n\0.
4269    */
4270   u32 len = vec_len (vam->input->buffer);
4271   M2 (CLI_INBAND, cli_inband, len);
4272   clib_memcpy (mp->cmd, vam->input->buffer, len);
4273   mp->length = htonl (len);
4274
4275   S;
4276   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4277 }
4278
4279 static int
4280 api_create_loopback (vat_main_t * vam)
4281 {
4282   unformat_input_t *i = vam->input;
4283   vl_api_create_loopback_t *mp;
4284   f64 timeout;
4285   u8 mac_address[6];
4286   u8 mac_set = 0;
4287
4288   memset (mac_address, 0, sizeof (mac_address));
4289
4290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4291     {
4292       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4293         mac_set = 1;
4294       else
4295         break;
4296     }
4297
4298   /* Construct the API message */
4299   M (CREATE_LOOPBACK, create_loopback);
4300   if (mac_set)
4301     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4302
4303   S;
4304   W;
4305 }
4306
4307 static int
4308 api_delete_loopback (vat_main_t * vam)
4309 {
4310   unformat_input_t *i = vam->input;
4311   vl_api_delete_loopback_t *mp;
4312   f64 timeout;
4313   u32 sw_if_index = ~0;
4314
4315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4316     {
4317       if (unformat (i, "sw_if_index %d", &sw_if_index))
4318         ;
4319       else
4320         break;
4321     }
4322
4323   if (sw_if_index == ~0)
4324     {
4325       errmsg ("missing sw_if_index\n");
4326       return -99;
4327     }
4328
4329   /* Construct the API message */
4330   M (DELETE_LOOPBACK, delete_loopback);
4331   mp->sw_if_index = ntohl (sw_if_index);
4332
4333   S;
4334   W;
4335 }
4336
4337 static int
4338 api_want_stats (vat_main_t * vam)
4339 {
4340   unformat_input_t *i = vam->input;
4341   vl_api_want_stats_t *mp;
4342   f64 timeout;
4343   int enable = -1;
4344
4345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4346     {
4347       if (unformat (i, "enable"))
4348         enable = 1;
4349       else if (unformat (i, "disable"))
4350         enable = 0;
4351       else
4352         break;
4353     }
4354
4355   if (enable == -1)
4356     {
4357       errmsg ("missing enable|disable\n");
4358       return -99;
4359     }
4360
4361   M (WANT_STATS, want_stats);
4362   mp->enable_disable = enable;
4363
4364   S;
4365   W;
4366 }
4367
4368 static int
4369 api_want_interface_events (vat_main_t * vam)
4370 {
4371   unformat_input_t *i = vam->input;
4372   vl_api_want_interface_events_t *mp;
4373   f64 timeout;
4374   int enable = -1;
4375
4376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4377     {
4378       if (unformat (i, "enable"))
4379         enable = 1;
4380       else if (unformat (i, "disable"))
4381         enable = 0;
4382       else
4383         break;
4384     }
4385
4386   if (enable == -1)
4387     {
4388       errmsg ("missing enable|disable\n");
4389       return -99;
4390     }
4391
4392   M (WANT_INTERFACE_EVENTS, want_interface_events);
4393   mp->enable_disable = enable;
4394
4395   vam->interface_event_display = enable;
4396
4397   S;
4398   W;
4399 }
4400
4401
4402 /* Note: non-static, called once to set up the initial intfc table */
4403 int
4404 api_sw_interface_dump (vat_main_t * vam)
4405 {
4406   vl_api_sw_interface_dump_t *mp;
4407   f64 timeout;
4408   hash_pair_t *p;
4409   name_sort_t *nses = 0, *ns;
4410   sw_interface_subif_t *sub = NULL;
4411
4412   /* Toss the old name table */
4413   /* *INDENT-OFF* */
4414   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4415   ({
4416     vec_add2 (nses, ns, 1);
4417     ns->name = (u8 *)(p->key);
4418     ns->value = (u32) p->value[0];
4419   }));
4420   /* *INDENT-ON* */
4421
4422   hash_free (vam->sw_if_index_by_interface_name);
4423
4424   vec_foreach (ns, nses) vec_free (ns->name);
4425
4426   vec_free (nses);
4427
4428   vec_foreach (sub, vam->sw_if_subif_table)
4429   {
4430     vec_free (sub->interface_name);
4431   }
4432   vec_free (vam->sw_if_subif_table);
4433
4434   /* recreate the interface name hash table */
4435   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4436
4437   /* Get list of ethernets */
4438   M (SW_INTERFACE_DUMP, sw_interface_dump);
4439   mp->name_filter_valid = 1;
4440   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4441   S;
4442
4443   /* and local / loopback interfaces */
4444   M (SW_INTERFACE_DUMP, sw_interface_dump);
4445   mp->name_filter_valid = 1;
4446   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4447   S;
4448
4449   /* and packet-generator interfaces */
4450   M (SW_INTERFACE_DUMP, sw_interface_dump);
4451   mp->name_filter_valid = 1;
4452   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4453   S;
4454
4455   /* and vxlan-gpe tunnel interfaces */
4456   M (SW_INTERFACE_DUMP, sw_interface_dump);
4457   mp->name_filter_valid = 1;
4458   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4459            sizeof (mp->name_filter) - 1);
4460   S;
4461
4462   /* and vxlan tunnel interfaces */
4463   M (SW_INTERFACE_DUMP, sw_interface_dump);
4464   mp->name_filter_valid = 1;
4465   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4466   S;
4467
4468   /* and host (af_packet) interfaces */
4469   M (SW_INTERFACE_DUMP, sw_interface_dump);
4470   mp->name_filter_valid = 1;
4471   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4472   S;
4473
4474   /* and l2tpv3 tunnel interfaces */
4475   M (SW_INTERFACE_DUMP, sw_interface_dump);
4476   mp->name_filter_valid = 1;
4477   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4478            sizeof (mp->name_filter) - 1);
4479   S;
4480
4481   /* and GRE tunnel interfaces */
4482   M (SW_INTERFACE_DUMP, sw_interface_dump);
4483   mp->name_filter_valid = 1;
4484   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4485   S;
4486
4487   /* and LISP-GPE interfaces */
4488   M (SW_INTERFACE_DUMP, sw_interface_dump);
4489   mp->name_filter_valid = 1;
4490   strncpy ((char *) mp->name_filter, "lisp_gpe",
4491            sizeof (mp->name_filter) - 1);
4492   S;
4493
4494   /* and IPSEC tunnel interfaces */
4495   M (SW_INTERFACE_DUMP, sw_interface_dump);
4496   mp->name_filter_valid = 1;
4497   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4498   S;
4499
4500   /* Use a control ping for synchronization */
4501   {
4502     vl_api_control_ping_t *mp;
4503     M (CONTROL_PING, control_ping);
4504     S;
4505   }
4506   W;
4507 }
4508
4509 static int
4510 api_sw_interface_set_flags (vat_main_t * vam)
4511 {
4512   unformat_input_t *i = vam->input;
4513   vl_api_sw_interface_set_flags_t *mp;
4514   f64 timeout;
4515   u32 sw_if_index;
4516   u8 sw_if_index_set = 0;
4517   u8 admin_up = 0, link_up = 0;
4518
4519   /* Parse args required to build the message */
4520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4521     {
4522       if (unformat (i, "admin-up"))
4523         admin_up = 1;
4524       else if (unformat (i, "admin-down"))
4525         admin_up = 0;
4526       else if (unformat (i, "link-up"))
4527         link_up = 1;
4528       else if (unformat (i, "link-down"))
4529         link_up = 0;
4530       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4531         sw_if_index_set = 1;
4532       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4533         sw_if_index_set = 1;
4534       else
4535         break;
4536     }
4537
4538   if (sw_if_index_set == 0)
4539     {
4540       errmsg ("missing interface name or sw_if_index\n");
4541       return -99;
4542     }
4543
4544   /* Construct the API message */
4545   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4546   mp->sw_if_index = ntohl (sw_if_index);
4547   mp->admin_up_down = admin_up;
4548   mp->link_up_down = link_up;
4549
4550   /* send it... */
4551   S;
4552
4553   /* Wait for a reply, return the good/bad news... */
4554   W;
4555 }
4556
4557 static int
4558 api_sw_interface_clear_stats (vat_main_t * vam)
4559 {
4560   unformat_input_t *i = vam->input;
4561   vl_api_sw_interface_clear_stats_t *mp;
4562   f64 timeout;
4563   u32 sw_if_index;
4564   u8 sw_if_index_set = 0;
4565
4566   /* Parse args required to build the message */
4567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4568     {
4569       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4570         sw_if_index_set = 1;
4571       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4572         sw_if_index_set = 1;
4573       else
4574         break;
4575     }
4576
4577   /* Construct the API message */
4578   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4579
4580   if (sw_if_index_set == 1)
4581     mp->sw_if_index = ntohl (sw_if_index);
4582   else
4583     mp->sw_if_index = ~0;
4584
4585   /* send it... */
4586   S;
4587
4588   /* Wait for a reply, return the good/bad news... */
4589   W;
4590 }
4591
4592 static int
4593 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4594 {
4595   unformat_input_t *i = vam->input;
4596   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4597   f64 timeout;
4598   u32 sw_if_index;
4599   u8 sw_if_index_set = 0;
4600   u32 subport;
4601   u8 subport_set = 0;
4602   u32 pipe;
4603   u8 pipe_set = 0;
4604   u32 profile;
4605   u8 profile_set = 0;
4606
4607   /* Parse args required to build the message */
4608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4609     {
4610       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4611         sw_if_index_set = 1;
4612       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4613         sw_if_index_set = 1;
4614       else if (unformat (i, "subport %u", &subport))
4615         subport_set = 1;
4616       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4617         sw_if_index_set = 1;
4618       else if (unformat (i, "pipe %u", &pipe))
4619         pipe_set = 1;
4620       else if (unformat (i, "profile %u", &profile))
4621         profile_set = 1;
4622       else
4623         break;
4624     }
4625
4626   if (sw_if_index_set == 0)
4627     {
4628       errmsg ("missing interface name or sw_if_index\n");
4629       return -99;
4630     }
4631
4632   if (subport_set == 0)
4633     {
4634       errmsg ("missing subport \n");
4635       return -99;
4636     }
4637
4638   if (pipe_set == 0)
4639     {
4640       errmsg ("missing pipe\n");
4641       return -99;
4642     }
4643
4644   if (profile_set == 0)
4645     {
4646       errmsg ("missing profile\n");
4647       return -99;
4648     }
4649
4650   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4651
4652   mp->sw_if_index = ntohl (sw_if_index);
4653   mp->subport = ntohl (subport);
4654   mp->pipe = ntohl (pipe);
4655   mp->profile = ntohl (profile);
4656
4657
4658   S;
4659   W;
4660   /* NOTREACHED */
4661   return 0;
4662 }
4663
4664 static int
4665 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4666 {
4667   unformat_input_t *i = vam->input;
4668   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4669   f64 timeout;
4670   u32 sw_if_index;
4671   u8 sw_if_index_set = 0;
4672   u32 subport;
4673   u8 subport_set = 0;
4674   u32 tb_rate = 1250000000;     /* 10GbE */
4675   u32 tb_size = 1000000;
4676   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4677   u32 tc_period = 10;
4678
4679   /* Parse args required to build the message */
4680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4681     {
4682       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4683         sw_if_index_set = 1;
4684       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4685         sw_if_index_set = 1;
4686       else if (unformat (i, "subport %u", &subport))
4687         subport_set = 1;
4688       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4689         sw_if_index_set = 1;
4690       else if (unformat (i, "rate %u", &tb_rate))
4691         {
4692           u32 tc_id;
4693
4694           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4695                tc_id++)
4696             tc_rate[tc_id] = tb_rate;
4697         }
4698       else if (unformat (i, "bktsize %u", &tb_size))
4699         ;
4700       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4701         ;
4702       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4703         ;
4704       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4705         ;
4706       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4707         ;
4708       else if (unformat (i, "period %u", &tc_period))
4709         ;
4710       else
4711         break;
4712     }
4713
4714   if (sw_if_index_set == 0)
4715     {
4716       errmsg ("missing interface name or sw_if_index\n");
4717       return -99;
4718     }
4719
4720   if (subport_set == 0)
4721     {
4722       errmsg ("missing subport \n");
4723       return -99;
4724     }
4725
4726   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4727
4728   mp->sw_if_index = ntohl (sw_if_index);
4729   mp->subport = ntohl (subport);
4730   mp->tb_rate = ntohl (tb_rate);
4731   mp->tb_size = ntohl (tb_size);
4732   mp->tc_rate[0] = ntohl (tc_rate[0]);
4733   mp->tc_rate[1] = ntohl (tc_rate[1]);
4734   mp->tc_rate[2] = ntohl (tc_rate[2]);
4735   mp->tc_rate[3] = ntohl (tc_rate[3]);
4736   mp->tc_period = ntohl (tc_period);
4737
4738   S;
4739   W;
4740   /* NOTREACHED */
4741   return 0;
4742 }
4743
4744 static int
4745 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4746 {
4747   unformat_input_t *i = vam->input;
4748   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4749   f64 timeout;
4750   u32 sw_if_index;
4751   u8 sw_if_index_set = 0;
4752   u8 entry_set = 0;
4753   u8 tc_set = 0;
4754   u8 queue_set = 0;
4755   u32 entry, tc, queue;
4756
4757   /* Parse args required to build the message */
4758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4759     {
4760       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4761         sw_if_index_set = 1;
4762       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4763         sw_if_index_set = 1;
4764       else if (unformat (i, "entry %d", &entry))
4765         entry_set = 1;
4766       else if (unformat (i, "tc %d", &tc))
4767         tc_set = 1;
4768       else if (unformat (i, "queue %d", &queue))
4769         queue_set = 1;
4770       else
4771         break;
4772     }
4773
4774   if (sw_if_index_set == 0)
4775     {
4776       errmsg ("missing interface name or sw_if_index\n");
4777       return -99;
4778     }
4779
4780   if (entry_set == 0)
4781     {
4782       errmsg ("missing entry \n");
4783       return -99;
4784     }
4785
4786   if (tc_set == 0)
4787     {
4788       errmsg ("missing traffic class \n");
4789       return -99;
4790     }
4791
4792   if (queue_set == 0)
4793     {
4794       errmsg ("missing queue \n");
4795       return -99;
4796     }
4797
4798   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4799
4800   mp->sw_if_index = ntohl (sw_if_index);
4801   mp->entry = ntohl (entry);
4802   mp->tc = ntohl (tc);
4803   mp->queue = ntohl (queue);
4804
4805   S;
4806   W;
4807   /* NOTREACHED */
4808   return 0;
4809 }
4810
4811 static int
4812 api_sw_interface_add_del_address (vat_main_t * vam)
4813 {
4814   unformat_input_t *i = vam->input;
4815   vl_api_sw_interface_add_del_address_t *mp;
4816   f64 timeout;
4817   u32 sw_if_index;
4818   u8 sw_if_index_set = 0;
4819   u8 is_add = 1, del_all = 0;
4820   u32 address_length = 0;
4821   u8 v4_address_set = 0;
4822   u8 v6_address_set = 0;
4823   ip4_address_t v4address;
4824   ip6_address_t v6address;
4825
4826   /* Parse args required to build the message */
4827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4828     {
4829       if (unformat (i, "del-all"))
4830         del_all = 1;
4831       else if (unformat (i, "del"))
4832         is_add = 0;
4833       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4834         sw_if_index_set = 1;
4835       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4836         sw_if_index_set = 1;
4837       else if (unformat (i, "%U/%d",
4838                          unformat_ip4_address, &v4address, &address_length))
4839         v4_address_set = 1;
4840       else if (unformat (i, "%U/%d",
4841                          unformat_ip6_address, &v6address, &address_length))
4842         v6_address_set = 1;
4843       else
4844         break;
4845     }
4846
4847   if (sw_if_index_set == 0)
4848     {
4849       errmsg ("missing interface name or sw_if_index\n");
4850       return -99;
4851     }
4852   if (v4_address_set && v6_address_set)
4853     {
4854       errmsg ("both v4 and v6 addresses set\n");
4855       return -99;
4856     }
4857   if (!v4_address_set && !v6_address_set && !del_all)
4858     {
4859       errmsg ("no addresses set\n");
4860       return -99;
4861     }
4862
4863   /* Construct the API message */
4864   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4865
4866   mp->sw_if_index = ntohl (sw_if_index);
4867   mp->is_add = is_add;
4868   mp->del_all = del_all;
4869   if (v6_address_set)
4870     {
4871       mp->is_ipv6 = 1;
4872       clib_memcpy (mp->address, &v6address, sizeof (v6address));
4873     }
4874   else
4875     {
4876       clib_memcpy (mp->address, &v4address, sizeof (v4address));
4877     }
4878   mp->address_length = address_length;
4879
4880   /* send it... */
4881   S;
4882
4883   /* Wait for a reply, return good/bad news  */
4884   W;
4885 }
4886
4887 static int
4888 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4889 {
4890   unformat_input_t *i = vam->input;
4891   vl_api_sw_interface_set_mpls_enable_t *mp;
4892   f64 timeout;
4893   u32 sw_if_index;
4894   u8 sw_if_index_set = 0;
4895   u8 enable = 1;
4896
4897   /* Parse args required to build the message */
4898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4899     {
4900       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4901         sw_if_index_set = 1;
4902       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4903         sw_if_index_set = 1;
4904       else if (unformat (i, "disable"))
4905         enable = 0;
4906       else if (unformat (i, "dis"))
4907         enable = 0;
4908       else
4909         break;
4910     }
4911
4912   if (sw_if_index_set == 0)
4913     {
4914       errmsg ("missing interface name or sw_if_index\n");
4915       return -99;
4916     }
4917
4918   /* Construct the API message */
4919   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
4920
4921   mp->sw_if_index = ntohl (sw_if_index);
4922   mp->enable = enable;
4923
4924   /* send it... */
4925   S;
4926
4927   /* Wait for a reply... */
4928   W;
4929 }
4930
4931 static int
4932 api_sw_interface_set_table (vat_main_t * vam)
4933 {
4934   unformat_input_t *i = vam->input;
4935   vl_api_sw_interface_set_table_t *mp;
4936   f64 timeout;
4937   u32 sw_if_index, vrf_id = 0;
4938   u8 sw_if_index_set = 0;
4939   u8 is_ipv6 = 0;
4940
4941   /* Parse args required to build the message */
4942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4943     {
4944       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4945         sw_if_index_set = 1;
4946       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4947         sw_if_index_set = 1;
4948       else if (unformat (i, "vrf %d", &vrf_id))
4949         ;
4950       else if (unformat (i, "ipv6"))
4951         is_ipv6 = 1;
4952       else
4953         break;
4954     }
4955
4956   if (sw_if_index_set == 0)
4957     {
4958       errmsg ("missing interface name or sw_if_index\n");
4959       return -99;
4960     }
4961
4962   /* Construct the API message */
4963   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
4964
4965   mp->sw_if_index = ntohl (sw_if_index);
4966   mp->is_ipv6 = is_ipv6;
4967   mp->vrf_id = ntohl (vrf_id);
4968
4969   /* send it... */
4970   S;
4971
4972   /* Wait for a reply... */
4973   W;
4974 }
4975
4976 static int
4977 api_sw_interface_set_vpath (vat_main_t * vam)
4978 {
4979   unformat_input_t *i = vam->input;
4980   vl_api_sw_interface_set_vpath_t *mp;
4981   f64 timeout;
4982   u32 sw_if_index = 0;
4983   u8 sw_if_index_set = 0;
4984   u8 is_enable = 0;
4985
4986   /* Parse args required to build the message */
4987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4988     {
4989       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4990         sw_if_index_set = 1;
4991       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4992         sw_if_index_set = 1;
4993       else if (unformat (i, "enable"))
4994         is_enable = 1;
4995       else if (unformat (i, "disable"))
4996         is_enable = 0;
4997       else
4998         break;
4999     }
5000
5001   if (sw_if_index_set == 0)
5002     {
5003       errmsg ("missing interface name or sw_if_index\n");
5004       return -99;
5005     }
5006
5007   /* Construct the API message */
5008   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5009
5010   mp->sw_if_index = ntohl (sw_if_index);
5011   mp->enable = is_enable;
5012
5013   /* send it... */
5014   S;
5015
5016   /* Wait for a reply... */
5017   W;
5018 }
5019
5020 static int
5021 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5022 {
5023   unformat_input_t *i = vam->input;
5024   vl_api_sw_interface_set_l2_xconnect_t *mp;
5025   f64 timeout;
5026   u32 rx_sw_if_index;
5027   u8 rx_sw_if_index_set = 0;
5028   u32 tx_sw_if_index;
5029   u8 tx_sw_if_index_set = 0;
5030   u8 enable = 1;
5031
5032   /* Parse args required to build the message */
5033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5034     {
5035       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5036         rx_sw_if_index_set = 1;
5037       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5038         tx_sw_if_index_set = 1;
5039       else if (unformat (i, "rx"))
5040         {
5041           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5042             {
5043               if (unformat (i, "%U", unformat_sw_if_index, vam,
5044                             &rx_sw_if_index))
5045                 rx_sw_if_index_set = 1;
5046             }
5047           else
5048             break;
5049         }
5050       else if (unformat (i, "tx"))
5051         {
5052           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5053             {
5054               if (unformat (i, "%U", unformat_sw_if_index, vam,
5055                             &tx_sw_if_index))
5056                 tx_sw_if_index_set = 1;
5057             }
5058           else
5059             break;
5060         }
5061       else if (unformat (i, "enable"))
5062         enable = 1;
5063       else if (unformat (i, "disable"))
5064         enable = 0;
5065       else
5066         break;
5067     }
5068
5069   if (rx_sw_if_index_set == 0)
5070     {
5071       errmsg ("missing rx interface name or rx_sw_if_index\n");
5072       return -99;
5073     }
5074
5075   if (enable && (tx_sw_if_index_set == 0))
5076     {
5077       errmsg ("missing tx interface name or tx_sw_if_index\n");
5078       return -99;
5079     }
5080
5081   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5082
5083   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5084   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5085   mp->enable = enable;
5086
5087   S;
5088   W;
5089   /* NOTREACHED */
5090   return 0;
5091 }
5092
5093 static int
5094 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5095 {
5096   unformat_input_t *i = vam->input;
5097   vl_api_sw_interface_set_l2_bridge_t *mp;
5098   f64 timeout;
5099   u32 rx_sw_if_index;
5100   u8 rx_sw_if_index_set = 0;
5101   u32 bd_id;
5102   u8 bd_id_set = 0;
5103   u8 bvi = 0;
5104   u32 shg = 0;
5105   u8 enable = 1;
5106
5107   /* Parse args required to build the message */
5108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5109     {
5110       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5111         rx_sw_if_index_set = 1;
5112       else if (unformat (i, "bd_id %d", &bd_id))
5113         bd_id_set = 1;
5114       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5115         rx_sw_if_index_set = 1;
5116       else if (unformat (i, "shg %d", &shg))
5117         ;
5118       else if (unformat (i, "bvi"))
5119         bvi = 1;
5120       else if (unformat (i, "enable"))
5121         enable = 1;
5122       else if (unformat (i, "disable"))
5123         enable = 0;
5124       else
5125         break;
5126     }
5127
5128   if (rx_sw_if_index_set == 0)
5129     {
5130       errmsg ("missing rx interface name or sw_if_index\n");
5131       return -99;
5132     }
5133
5134   if (enable && (bd_id_set == 0))
5135     {
5136       errmsg ("missing bridge domain\n");
5137       return -99;
5138     }
5139
5140   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5141
5142   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5143   mp->bd_id = ntohl (bd_id);
5144   mp->shg = (u8) shg;
5145   mp->bvi = bvi;
5146   mp->enable = enable;
5147
5148   S;
5149   W;
5150   /* NOTREACHED */
5151   return 0;
5152 }
5153
5154 static int
5155 api_bridge_domain_dump (vat_main_t * vam)
5156 {
5157   unformat_input_t *i = vam->input;
5158   vl_api_bridge_domain_dump_t *mp;
5159   f64 timeout;
5160   u32 bd_id = ~0;
5161
5162   /* Parse args required to build the message */
5163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5164     {
5165       if (unformat (i, "bd_id %d", &bd_id))
5166         ;
5167       else
5168         break;
5169     }
5170
5171   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5172   mp->bd_id = ntohl (bd_id);
5173   S;
5174
5175   /* Use a control ping for synchronization */
5176   {
5177     vl_api_control_ping_t *mp;
5178     M (CONTROL_PING, control_ping);
5179     S;
5180   }
5181
5182   W;
5183   /* NOTREACHED */
5184   return 0;
5185 }
5186
5187 static int
5188 api_bridge_domain_add_del (vat_main_t * vam)
5189 {
5190   unformat_input_t *i = vam->input;
5191   vl_api_bridge_domain_add_del_t *mp;
5192   f64 timeout;
5193   u32 bd_id = ~0;
5194   u8 is_add = 1;
5195   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5196
5197   /* Parse args required to build the message */
5198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5199     {
5200       if (unformat (i, "bd_id %d", &bd_id))
5201         ;
5202       else if (unformat (i, "flood %d", &flood))
5203         ;
5204       else if (unformat (i, "uu-flood %d", &uu_flood))
5205         ;
5206       else if (unformat (i, "forward %d", &forward))
5207         ;
5208       else if (unformat (i, "learn %d", &learn))
5209         ;
5210       else if (unformat (i, "arp-term %d", &arp_term))
5211         ;
5212       else if (unformat (i, "del"))
5213         {
5214           is_add = 0;
5215           flood = uu_flood = forward = learn = 0;
5216         }
5217       else
5218         break;
5219     }
5220
5221   if (bd_id == ~0)
5222     {
5223       errmsg ("missing bridge domain\n");
5224       return -99;
5225     }
5226
5227   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5228
5229   mp->bd_id = ntohl (bd_id);
5230   mp->flood = flood;
5231   mp->uu_flood = uu_flood;
5232   mp->forward = forward;
5233   mp->learn = learn;
5234   mp->arp_term = arp_term;
5235   mp->is_add = is_add;
5236
5237   S;
5238   W;
5239   /* NOTREACHED */
5240   return 0;
5241 }
5242
5243 static int
5244 api_l2fib_add_del (vat_main_t * vam)
5245 {
5246   unformat_input_t *i = vam->input;
5247   vl_api_l2fib_add_del_t *mp;
5248   f64 timeout;
5249   u64 mac = 0;
5250   u8 mac_set = 0;
5251   u32 bd_id;
5252   u8 bd_id_set = 0;
5253   u32 sw_if_index;
5254   u8 sw_if_index_set = 0;
5255   u8 is_add = 1;
5256   u8 static_mac = 0;
5257   u8 filter_mac = 0;
5258   u8 bvi_mac = 0;
5259   int count = 1;
5260   f64 before = 0;
5261   int j;
5262
5263   /* Parse args required to build the message */
5264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5265     {
5266       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5267         mac_set = 1;
5268       else if (unformat (i, "bd_id %d", &bd_id))
5269         bd_id_set = 1;
5270       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5271         sw_if_index_set = 1;
5272       else if (unformat (i, "sw_if"))
5273         {
5274           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5275             {
5276               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5277                 sw_if_index_set = 1;
5278             }
5279           else
5280             break;
5281         }
5282       else if (unformat (i, "static"))
5283         static_mac = 1;
5284       else if (unformat (i, "filter"))
5285         {
5286           filter_mac = 1;
5287           static_mac = 1;
5288         }
5289       else if (unformat (i, "bvi"))
5290         {
5291           bvi_mac = 1;
5292           static_mac = 1;
5293         }
5294       else if (unformat (i, "del"))
5295         is_add = 0;
5296       else if (unformat (i, "count %d", &count))
5297         ;
5298       else
5299         break;
5300     }
5301
5302   if (mac_set == 0)
5303     {
5304       errmsg ("missing mac address\n");
5305       return -99;
5306     }
5307
5308   if (bd_id_set == 0)
5309     {
5310       errmsg ("missing bridge domain\n");
5311       return -99;
5312     }
5313
5314   if (is_add && (sw_if_index_set == 0))
5315     {
5316       errmsg ("missing interface name or sw_if_index\n");
5317       return -99;
5318     }
5319
5320   if (count > 1)
5321     {
5322       /* Turn on async mode */
5323       vam->async_mode = 1;
5324       vam->async_errors = 0;
5325       before = vat_time_now (vam);
5326     }
5327
5328   for (j = 0; j < count; j++)
5329     {
5330       M (L2FIB_ADD_DEL, l2fib_add_del);
5331
5332       mp->mac = mac;
5333       mp->bd_id = ntohl (bd_id);
5334       mp->is_add = is_add;
5335
5336       if (is_add)
5337         {
5338           mp->sw_if_index = ntohl (sw_if_index);
5339           mp->static_mac = static_mac;
5340           mp->filter_mac = filter_mac;
5341           mp->bvi_mac = bvi_mac;
5342         }
5343       increment_mac_address (&mac);
5344       /* send it... */
5345       S;
5346     }
5347
5348   if (count > 1)
5349     {
5350       vl_api_control_ping_t *mp;
5351       f64 after;
5352
5353       /* Shut off async mode */
5354       vam->async_mode = 0;
5355
5356       M (CONTROL_PING, control_ping);
5357       S;
5358
5359       timeout = vat_time_now (vam) + 1.0;
5360       while (vat_time_now (vam) < timeout)
5361         if (vam->result_ready == 1)
5362           goto out;
5363       vam->retval = -99;
5364
5365     out:
5366       if (vam->retval == -99)
5367         errmsg ("timeout\n");
5368
5369       if (vam->async_errors > 0)
5370         {
5371           errmsg ("%d asynchronous errors\n", vam->async_errors);
5372           vam->retval = -98;
5373         }
5374       vam->async_errors = 0;
5375       after = vat_time_now (vam);
5376
5377       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5378                count, after - before, count / (after - before));
5379     }
5380   else
5381     {
5382       /* Wait for a reply... */
5383       W;
5384     }
5385   /* Return the good/bad news */
5386   return (vam->retval);
5387 }
5388
5389 static int
5390 api_l2_flags (vat_main_t * vam)
5391 {
5392   unformat_input_t *i = vam->input;
5393   vl_api_l2_flags_t *mp;
5394   f64 timeout;
5395   u32 sw_if_index;
5396   u32 feature_bitmap = 0;
5397   u8 sw_if_index_set = 0;
5398
5399   /* Parse args required to build the message */
5400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5401     {
5402       if (unformat (i, "sw_if_index %d", &sw_if_index))
5403         sw_if_index_set = 1;
5404       else if (unformat (i, "sw_if"))
5405         {
5406           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5407             {
5408               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5409                 sw_if_index_set = 1;
5410             }
5411           else
5412             break;
5413         }
5414       else if (unformat (i, "learn"))
5415         feature_bitmap |= L2INPUT_FEAT_LEARN;
5416       else if (unformat (i, "forward"))
5417         feature_bitmap |= L2INPUT_FEAT_FWD;
5418       else if (unformat (i, "flood"))
5419         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5420       else if (unformat (i, "uu-flood"))
5421         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5422       else
5423         break;
5424     }
5425
5426   if (sw_if_index_set == 0)
5427     {
5428       errmsg ("missing interface name or sw_if_index\n");
5429       return -99;
5430     }
5431
5432   M (L2_FLAGS, l2_flags);
5433
5434   mp->sw_if_index = ntohl (sw_if_index);
5435   mp->feature_bitmap = ntohl (feature_bitmap);
5436
5437   S;
5438   W;
5439   /* NOTREACHED */
5440   return 0;
5441 }
5442
5443 static int
5444 api_bridge_flags (vat_main_t * vam)
5445 {
5446   unformat_input_t *i = vam->input;
5447   vl_api_bridge_flags_t *mp;
5448   f64 timeout;
5449   u32 bd_id;
5450   u8 bd_id_set = 0;
5451   u8 is_set = 1;
5452   u32 flags = 0;
5453
5454   /* Parse args required to build the message */
5455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5456     {
5457       if (unformat (i, "bd_id %d", &bd_id))
5458         bd_id_set = 1;
5459       else if (unformat (i, "learn"))
5460         flags |= L2_LEARN;
5461       else if (unformat (i, "forward"))
5462         flags |= L2_FWD;
5463       else if (unformat (i, "flood"))
5464         flags |= L2_FLOOD;
5465       else if (unformat (i, "uu-flood"))
5466         flags |= L2_UU_FLOOD;
5467       else if (unformat (i, "arp-term"))
5468         flags |= L2_ARP_TERM;
5469       else if (unformat (i, "off"))
5470         is_set = 0;
5471       else if (unformat (i, "disable"))
5472         is_set = 0;
5473       else
5474         break;
5475     }
5476
5477   if (bd_id_set == 0)
5478     {
5479       errmsg ("missing bridge domain\n");
5480       return -99;
5481     }
5482
5483   M (BRIDGE_FLAGS, bridge_flags);
5484
5485   mp->bd_id = ntohl (bd_id);
5486   mp->feature_bitmap = ntohl (flags);
5487   mp->is_set = is_set;
5488
5489   S;
5490   W;
5491   /* NOTREACHED */
5492   return 0;
5493 }
5494
5495 static int
5496 api_bd_ip_mac_add_del (vat_main_t * vam)
5497 {
5498   unformat_input_t *i = vam->input;
5499   vl_api_bd_ip_mac_add_del_t *mp;
5500   f64 timeout;
5501   u32 bd_id;
5502   u8 is_ipv6 = 0;
5503   u8 is_add = 1;
5504   u8 bd_id_set = 0;
5505   u8 ip_set = 0;
5506   u8 mac_set = 0;
5507   ip4_address_t v4addr;
5508   ip6_address_t v6addr;
5509   u8 macaddr[6];
5510
5511
5512   /* Parse args required to build the message */
5513   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5514     {
5515       if (unformat (i, "bd_id %d", &bd_id))
5516         {
5517           bd_id_set++;
5518         }
5519       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5520         {
5521           ip_set++;
5522         }
5523       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5524         {
5525           ip_set++;
5526           is_ipv6++;
5527         }
5528       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5529         {
5530           mac_set++;
5531         }
5532       else if (unformat (i, "del"))
5533         is_add = 0;
5534       else
5535         break;
5536     }
5537
5538   if (bd_id_set == 0)
5539     {
5540       errmsg ("missing bridge domain\n");
5541       return -99;
5542     }
5543   else if (ip_set == 0)
5544     {
5545       errmsg ("missing IP address\n");
5546       return -99;
5547     }
5548   else if (mac_set == 0)
5549     {
5550       errmsg ("missing MAC address\n");
5551       return -99;
5552     }
5553
5554   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5555
5556   mp->bd_id = ntohl (bd_id);
5557   mp->is_ipv6 = is_ipv6;
5558   mp->is_add = is_add;
5559   if (is_ipv6)
5560     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5561   else
5562     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5563   clib_memcpy (mp->mac_address, macaddr, 6);
5564   S;
5565   W;
5566   /* NOTREACHED */
5567   return 0;
5568 }
5569
5570 static int
5571 api_tap_connect (vat_main_t * vam)
5572 {
5573   unformat_input_t *i = vam->input;
5574   vl_api_tap_connect_t *mp;
5575   f64 timeout;
5576   u8 mac_address[6];
5577   u8 random_mac = 1;
5578   u8 name_set = 0;
5579   u8 *tap_name;
5580
5581   memset (mac_address, 0, sizeof (mac_address));
5582
5583   /* Parse args required to build the message */
5584   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5585     {
5586       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5587         {
5588           random_mac = 0;
5589         }
5590       else if (unformat (i, "random-mac"))
5591         random_mac = 1;
5592       else if (unformat (i, "tapname %s", &tap_name))
5593         name_set = 1;
5594       else
5595         break;
5596     }
5597
5598   if (name_set == 0)
5599     {
5600       errmsg ("missing tap name\n");
5601       return -99;
5602     }
5603   if (vec_len (tap_name) > 63)
5604     {
5605       errmsg ("tap name too long\n");
5606     }
5607   vec_add1 (tap_name, 0);
5608
5609   /* Construct the API message */
5610   M (TAP_CONNECT, tap_connect);
5611
5612   mp->use_random_mac = random_mac;
5613   clib_memcpy (mp->mac_address, mac_address, 6);
5614   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5615   vec_free (tap_name);
5616
5617   /* send it... */
5618   S;
5619
5620   /* Wait for a reply... */
5621   W;
5622 }
5623
5624 static int
5625 api_tap_modify (vat_main_t * vam)
5626 {
5627   unformat_input_t *i = vam->input;
5628   vl_api_tap_modify_t *mp;
5629   f64 timeout;
5630   u8 mac_address[6];
5631   u8 random_mac = 1;
5632   u8 name_set = 0;
5633   u8 *tap_name;
5634   u32 sw_if_index = ~0;
5635   u8 sw_if_index_set = 0;
5636
5637   memset (mac_address, 0, sizeof (mac_address));
5638
5639   /* Parse args required to build the message */
5640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5641     {
5642       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5643         sw_if_index_set = 1;
5644       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5645         sw_if_index_set = 1;
5646       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5647         {
5648           random_mac = 0;
5649         }
5650       else if (unformat (i, "random-mac"))
5651         random_mac = 1;
5652       else if (unformat (i, "tapname %s", &tap_name))
5653         name_set = 1;
5654       else
5655         break;
5656     }
5657
5658   if (sw_if_index_set == 0)
5659     {
5660       errmsg ("missing vpp interface name");
5661       return -99;
5662     }
5663   if (name_set == 0)
5664     {
5665       errmsg ("missing tap name\n");
5666       return -99;
5667     }
5668   if (vec_len (tap_name) > 63)
5669     {
5670       errmsg ("tap name too long\n");
5671     }
5672   vec_add1 (tap_name, 0);
5673
5674   /* Construct the API message */
5675   M (TAP_MODIFY, tap_modify);
5676
5677   mp->use_random_mac = random_mac;
5678   mp->sw_if_index = ntohl (sw_if_index);
5679   clib_memcpy (mp->mac_address, mac_address, 6);
5680   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5681   vec_free (tap_name);
5682
5683   /* send it... */
5684   S;
5685
5686   /* Wait for a reply... */
5687   W;
5688 }
5689
5690 static int
5691 api_tap_delete (vat_main_t * vam)
5692 {
5693   unformat_input_t *i = vam->input;
5694   vl_api_tap_delete_t *mp;
5695   f64 timeout;
5696   u32 sw_if_index = ~0;
5697   u8 sw_if_index_set = 0;
5698
5699   /* Parse args required to build the message */
5700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5701     {
5702       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5703         sw_if_index_set = 1;
5704       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5705         sw_if_index_set = 1;
5706       else
5707         break;
5708     }
5709
5710   if (sw_if_index_set == 0)
5711     {
5712       errmsg ("missing vpp interface name");
5713       return -99;
5714     }
5715
5716   /* Construct the API message */
5717   M (TAP_DELETE, tap_delete);
5718
5719   mp->sw_if_index = ntohl (sw_if_index);
5720
5721   /* send it... */
5722   S;
5723
5724   /* Wait for a reply... */
5725   W;
5726 }
5727
5728 static int
5729 api_ip_add_del_route (vat_main_t * vam)
5730 {
5731   unformat_input_t *i = vam->input;
5732   vl_api_ip_add_del_route_t *mp;
5733   f64 timeout;
5734   u32 sw_if_index = ~0, vrf_id = 0;
5735   u8 sw_if_index_set = 0;
5736   u8 is_ipv6 = 0;
5737   u8 is_local = 0, is_drop = 0;
5738   u8 is_unreach = 0, is_prohibit = 0;
5739   u8 create_vrf_if_needed = 0;
5740   u8 is_add = 1;
5741   u32 next_hop_weight = 1;
5742   u8 not_last = 0;
5743   u8 is_multipath = 0;
5744   u8 address_set = 0;
5745   u8 address_length_set = 0;
5746   u32 next_hop_table_id = 0;
5747   u32 resolve_attempts = 0;
5748   u32 dst_address_length = 0;
5749   u8 next_hop_set = 0;
5750   ip4_address_t v4_dst_address, v4_next_hop_address;
5751   ip6_address_t v6_dst_address, v6_next_hop_address;
5752   int count = 1;
5753   int j;
5754   f64 before = 0;
5755   u32 random_add_del = 0;
5756   u32 *random_vector = 0;
5757   uword *random_hash;
5758   u32 random_seed = 0xdeaddabe;
5759   u32 classify_table_index = ~0;
5760   u8 is_classify = 0;
5761   u8 resolve_host = 0, resolve_attached = 0;
5762   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
5763
5764   /* Parse args required to build the message */
5765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5766     {
5767       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5768         sw_if_index_set = 1;
5769       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5770         sw_if_index_set = 1;
5771       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
5772         {
5773           address_set = 1;
5774           is_ipv6 = 0;
5775         }
5776       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
5777         {
5778           address_set = 1;
5779           is_ipv6 = 1;
5780         }
5781       else if (unformat (i, "/%d", &dst_address_length))
5782         {
5783           address_length_set = 1;
5784         }
5785
5786       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
5787                                          &v4_next_hop_address))
5788         {
5789           next_hop_set = 1;
5790         }
5791       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
5792                                          &v6_next_hop_address))
5793         {
5794           next_hop_set = 1;
5795         }
5796       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
5797         ;
5798       else if (unformat (i, "weight %d", &next_hop_weight))
5799         ;
5800       else if (unformat (i, "drop"))
5801         {
5802           is_drop = 1;
5803         }
5804       else if (unformat (i, "null-send-unreach"))
5805         {
5806           is_unreach = 1;
5807         }
5808       else if (unformat (i, "null-send-prohibit"))
5809         {
5810           is_prohibit = 1;
5811         }
5812       else if (unformat (i, "local"))
5813         {
5814           is_local = 1;
5815         }
5816       else if (unformat (i, "classify %d", &classify_table_index))
5817         {
5818           is_classify = 1;
5819         }
5820       else if (unformat (i, "del"))
5821         is_add = 0;
5822       else if (unformat (i, "add"))
5823         is_add = 1;
5824       else if (unformat (i, "not-last"))
5825         not_last = 1;
5826       else if (unformat (i, "resolve-via-host"))
5827         resolve_host = 1;
5828       else if (unformat (i, "resolve-via-attached"))
5829         resolve_attached = 1;
5830       else if (unformat (i, "multipath"))
5831         is_multipath = 1;
5832       else if (unformat (i, "vrf %d", &vrf_id))
5833         ;
5834       else if (unformat (i, "create-vrf"))
5835         create_vrf_if_needed = 1;
5836       else if (unformat (i, "count %d", &count))
5837         ;
5838       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
5839         ;
5840       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
5841         ;
5842       else if (unformat (i, "out-label %d", &next_hop_out_label))
5843         ;
5844       else if (unformat (i, "random"))
5845         random_add_del = 1;
5846       else if (unformat (i, "seed %d", &random_seed))
5847         ;
5848       else
5849         {
5850           clib_warning ("parse error '%U'", format_unformat_error, i);
5851           return -99;
5852         }
5853     }
5854
5855   if (resolve_attempts > 0 && sw_if_index_set == 0)
5856     {
5857       errmsg ("ARP resolution needs explicit interface or sw_if_index\n");
5858       return -99;
5859     }
5860
5861   if (!next_hop_set && !is_drop && !is_local &&
5862       !is_classify && !is_unreach && !is_prohibit)
5863     {
5864       errmsg
5865         ("next hop / local / drop / unreach / prohibit / classify not set\n");
5866       return -99;
5867     }
5868
5869   if (address_set == 0)
5870     {
5871       errmsg ("missing addresses\n");
5872       return -99;
5873     }
5874
5875   if (address_length_set == 0)
5876     {
5877       errmsg ("missing address length\n");
5878       return -99;
5879     }
5880
5881   /* Generate a pile of unique, random routes */
5882   if (random_add_del)
5883     {
5884       u32 this_random_address;
5885       random_hash = hash_create (count, sizeof (uword));
5886
5887       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
5888       for (j = 0; j <= count; j++)
5889         {
5890           do
5891             {
5892               this_random_address = random_u32 (&random_seed);
5893               this_random_address =
5894                 clib_host_to_net_u32 (this_random_address);
5895             }
5896           while (hash_get (random_hash, this_random_address));
5897           vec_add1 (random_vector, this_random_address);
5898           hash_set (random_hash, this_random_address, 1);
5899         }
5900       hash_free (random_hash);
5901       v4_dst_address.as_u32 = random_vector[0];
5902     }
5903
5904   if (count > 1)
5905     {
5906       /* Turn on async mode */
5907       vam->async_mode = 1;
5908       vam->async_errors = 0;
5909       before = vat_time_now (vam);
5910     }
5911
5912   for (j = 0; j < count; j++)
5913     {
5914       /* Construct the API message */
5915       M (IP_ADD_DEL_ROUTE, ip_add_del_route);
5916
5917       mp->next_hop_sw_if_index = ntohl (sw_if_index);
5918       mp->table_id = ntohl (vrf_id);
5919       if (resolve_attempts > 0)
5920         {
5921           mp->resolve_attempts = ntohl (resolve_attempts);
5922           mp->resolve_if_needed = 1;
5923         }
5924       mp->create_vrf_if_needed = create_vrf_if_needed;
5925
5926       mp->is_add = is_add;
5927       mp->is_drop = is_drop;
5928       mp->is_unreach = is_unreach;
5929       mp->is_prohibit = is_prohibit;
5930       mp->is_ipv6 = is_ipv6;
5931       mp->is_local = is_local;
5932       mp->is_classify = is_classify;
5933       mp->is_multipath = is_multipath;
5934       mp->is_resolve_host = resolve_host;
5935       mp->is_resolve_attached = resolve_attached;
5936       mp->not_last = not_last;
5937       mp->next_hop_weight = next_hop_weight;
5938       mp->dst_address_length = dst_address_length;
5939       mp->next_hop_table_id = ntohl (next_hop_table_id);
5940       mp->classify_table_index = ntohl (classify_table_index);
5941       mp->next_hop_out_label = ntohl (next_hop_out_label);
5942
5943       if (is_ipv6)
5944         {
5945           clib_memcpy (mp->dst_address, &v6_dst_address,
5946                        sizeof (v6_dst_address));
5947           if (next_hop_set)
5948             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
5949                          sizeof (v6_next_hop_address));
5950           increment_v6_address (&v6_dst_address);
5951         }
5952       else
5953         {
5954           clib_memcpy (mp->dst_address, &v4_dst_address,
5955                        sizeof (v4_dst_address));
5956           if (next_hop_set)
5957             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
5958                          sizeof (v4_next_hop_address));
5959           if (random_add_del)
5960             v4_dst_address.as_u32 = random_vector[j + 1];
5961           else
5962             increment_v4_address (&v4_dst_address);
5963         }
5964       /* send it... */
5965       S;
5966       /* If we receive SIGTERM, stop now... */
5967       if (vam->do_exit)
5968         break;
5969     }
5970
5971   /* When testing multiple add/del ops, use a control-ping to sync */
5972   if (count > 1)
5973     {
5974       vl_api_control_ping_t *mp;
5975       f64 after;
5976
5977       /* Shut off async mode */
5978       vam->async_mode = 0;
5979
5980       M (CONTROL_PING, control_ping);
5981       S;
5982
5983       timeout = vat_time_now (vam) + 1.0;
5984       while (vat_time_now (vam) < timeout)
5985         if (vam->result_ready == 1)
5986           goto out;
5987       vam->retval = -99;
5988
5989     out:
5990       if (vam->retval == -99)
5991         errmsg ("timeout\n");
5992
5993       if (vam->async_errors > 0)
5994         {
5995           errmsg ("%d asynchronous errors\n", vam->async_errors);
5996           vam->retval = -98;
5997         }
5998       vam->async_errors = 0;
5999       after = vat_time_now (vam);
6000
6001       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6002       if (j > 0)
6003         count = j;
6004
6005       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6006                count, after - before, count / (after - before));
6007     }
6008   else
6009     {
6010       /* Wait for a reply... */
6011       W;
6012     }
6013
6014   /* Return the good/bad news */
6015   return (vam->retval);
6016 }
6017
6018 static int
6019 api_mpls_route_add_del (vat_main_t * vam)
6020 {
6021   unformat_input_t *i = vam->input;
6022   vl_api_mpls_route_add_del_t *mp;
6023   f64 timeout;
6024   u32 sw_if_index = ~0, table_id = 0;
6025   u8 create_table_if_needed = 0;
6026   u8 is_add = 1;
6027   u32 next_hop_weight = 1;
6028   u8 is_multipath = 0;
6029   u32 next_hop_table_id = 0;
6030   u8 next_hop_set = 0;
6031   ip4_address_t v4_next_hop_address = {
6032     .as_u32 = 0,
6033   };
6034   ip6_address_t v6_next_hop_address = { {0} };
6035   int count = 1;
6036   int j;
6037   f64 before = 0;
6038   u32 classify_table_index = ~0;
6039   u8 is_classify = 0;
6040   u8 resolve_host = 0, resolve_attached = 0;
6041   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6042   mpls_label_t local_label = MPLS_LABEL_INVALID;
6043   u8 is_eos = 1;
6044   u8 next_hop_proto_is_ip4 = 1;
6045
6046   /* Parse args required to build the message */
6047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6048     {
6049       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6050         ;
6051       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6052         ;
6053       else if (unformat (i, "%d", &local_label))
6054         ;
6055       else if (unformat (i, "eos"))
6056         is_eos = 1;
6057       else if (unformat (i, "non-eos"))
6058         is_eos = 0;
6059       else if (unformat (i, "via %U", unformat_ip4_address,
6060                          &v4_next_hop_address))
6061         {
6062           next_hop_set = 1;
6063           next_hop_proto_is_ip4 = 1;
6064         }
6065       else if (unformat (i, "via %U", unformat_ip6_address,
6066                          &v6_next_hop_address))
6067         {
6068           next_hop_set = 1;
6069           next_hop_proto_is_ip4 = 0;
6070         }
6071       else if (unformat (i, "weight %d", &next_hop_weight))
6072         ;
6073       else if (unformat (i, "create-table"))
6074         create_table_if_needed = 1;
6075       else if (unformat (i, "classify %d", &classify_table_index))
6076         {
6077           is_classify = 1;
6078         }
6079       else if (unformat (i, "del"))
6080         is_add = 0;
6081       else if (unformat (i, "add"))
6082         is_add = 1;
6083       else if (unformat (i, "resolve-via-host"))
6084         resolve_host = 1;
6085       else if (unformat (i, "resolve-via-attached"))
6086         resolve_attached = 1;
6087       else if (unformat (i, "multipath"))
6088         is_multipath = 1;
6089       else if (unformat (i, "count %d", &count))
6090         ;
6091       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6092         {
6093           next_hop_set = 1;
6094           next_hop_proto_is_ip4 = 1;
6095         }
6096       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6097         {
6098           next_hop_set = 1;
6099           next_hop_proto_is_ip4 = 0;
6100         }
6101       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6102         ;
6103       else if (unformat (i, "out-label %d", &next_hop_out_label))
6104         ;
6105       else
6106         {
6107           clib_warning ("parse error '%U'", format_unformat_error, i);
6108           return -99;
6109         }
6110     }
6111
6112   if (!next_hop_set && !is_classify)
6113     {
6114       errmsg ("next hop / classify not set\n");
6115       return -99;
6116     }
6117
6118   if (MPLS_LABEL_INVALID == local_label)
6119     {
6120       errmsg ("missing label\n");
6121       return -99;
6122     }
6123
6124   if (count > 1)
6125     {
6126       /* Turn on async mode */
6127       vam->async_mode = 1;
6128       vam->async_errors = 0;
6129       before = vat_time_now (vam);
6130     }
6131
6132   for (j = 0; j < count; j++)
6133     {
6134       /* Construct the API message */
6135       M (MPLS_ROUTE_ADD_DEL, mpls_route_add_del);
6136
6137       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6138       mp->mr_table_id = ntohl (table_id);
6139       mp->mr_create_table_if_needed = create_table_if_needed;
6140
6141       mp->mr_is_add = is_add;
6142       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6143       mp->mr_is_classify = is_classify;
6144       mp->mr_is_multipath = is_multipath;
6145       mp->mr_is_resolve_host = resolve_host;
6146       mp->mr_is_resolve_attached = resolve_attached;
6147       mp->mr_next_hop_weight = next_hop_weight;
6148       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6149       mp->mr_classify_table_index = ntohl (classify_table_index);
6150       mp->mr_next_hop_out_label = ntohl (next_hop_out_label);
6151       mp->mr_label = ntohl (local_label);
6152       mp->mr_eos = is_eos;
6153
6154       if (next_hop_set)
6155         {
6156           if (next_hop_proto_is_ip4)
6157             {
6158               clib_memcpy (mp->mr_next_hop,
6159                            &v4_next_hop_address,
6160                            sizeof (v4_next_hop_address));
6161             }
6162           else
6163             {
6164               clib_memcpy (mp->mr_next_hop,
6165                            &v6_next_hop_address,
6166                            sizeof (v6_next_hop_address));
6167             }
6168         }
6169       local_label++;
6170
6171       /* send it... */
6172       S;
6173       /* If we receive SIGTERM, stop now... */
6174       if (vam->do_exit)
6175         break;
6176     }
6177
6178   /* When testing multiple add/del ops, use a control-ping to sync */
6179   if (count > 1)
6180     {
6181       vl_api_control_ping_t *mp;
6182       f64 after;
6183
6184       /* Shut off async mode */
6185       vam->async_mode = 0;
6186
6187       M (CONTROL_PING, control_ping);
6188       S;
6189
6190       timeout = vat_time_now (vam) + 1.0;
6191       while (vat_time_now (vam) < timeout)
6192         if (vam->result_ready == 1)
6193           goto out;
6194       vam->retval = -99;
6195
6196     out:
6197       if (vam->retval == -99)
6198         errmsg ("timeout\n");
6199
6200       if (vam->async_errors > 0)
6201         {
6202           errmsg ("%d asynchronous errors\n", vam->async_errors);
6203           vam->retval = -98;
6204         }
6205       vam->async_errors = 0;
6206       after = vat_time_now (vam);
6207
6208       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6209       if (j > 0)
6210         count = j;
6211
6212       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6213                count, after - before, count / (after - before));
6214     }
6215   else
6216     {
6217       /* Wait for a reply... */
6218       W;
6219     }
6220
6221   /* Return the good/bad news */
6222   return (vam->retval);
6223 }
6224
6225 static int
6226 api_mpls_ip_bind_unbind (vat_main_t * vam)
6227 {
6228   unformat_input_t *i = vam->input;
6229   vl_api_mpls_ip_bind_unbind_t *mp;
6230   f64 timeout;
6231   u32 ip_table_id = 0;
6232   u8 create_table_if_needed = 0;
6233   u8 is_bind = 1;
6234   u8 is_ip4 = 1;
6235   ip4_address_t v4_address;
6236   ip6_address_t v6_address;
6237   u32 address_length;
6238   u8 address_set = 0;
6239   mpls_label_t local_label = MPLS_LABEL_INVALID;
6240
6241   /* Parse args required to build the message */
6242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6243     {
6244       if (unformat (i, "%U/%d", unformat_ip4_address,
6245                     &v4_address, &address_length))
6246         {
6247           is_ip4 = 1;
6248           address_set = 1;
6249         }
6250       else if (unformat (i, "%U/%d", unformat_ip6_address,
6251                          &v6_address, &address_length))
6252         {
6253           is_ip4 = 0;
6254           address_set = 1;
6255         }
6256       else if (unformat (i, "%d", &local_label))
6257         ;
6258       else if (unformat (i, "create-table"))
6259         create_table_if_needed = 1;
6260       else if (unformat (i, "table-id %d", &ip_table_id))
6261         ;
6262       else if (unformat (i, "unbind"))
6263         is_bind = 0;
6264       else if (unformat (i, "bind"))
6265         is_bind = 1;
6266       else
6267         {
6268           clib_warning ("parse error '%U'", format_unformat_error, i);
6269           return -99;
6270         }
6271     }
6272
6273   if (!address_set)
6274     {
6275       errmsg ("IP addres not set\n");
6276       return -99;
6277     }
6278
6279   if (MPLS_LABEL_INVALID == local_label)
6280     {
6281       errmsg ("missing label\n");
6282       return -99;
6283     }
6284
6285   /* Construct the API message */
6286   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6287
6288   mp->mb_create_table_if_needed = create_table_if_needed;
6289   mp->mb_is_bind = is_bind;
6290   mp->mb_is_ip4 = is_ip4;
6291   mp->mb_ip_table_id = ntohl (ip_table_id);
6292   mp->mb_mpls_table_id = 0;
6293   mp->mb_label = ntohl (local_label);
6294   mp->mb_address_length = address_length;
6295
6296   if (is_ip4)
6297     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6298   else
6299     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6300
6301   /* send it... */
6302   S;
6303
6304   /* Wait for a reply... */
6305   W;
6306 }
6307
6308 static int
6309 api_proxy_arp_add_del (vat_main_t * vam)
6310 {
6311   unformat_input_t *i = vam->input;
6312   vl_api_proxy_arp_add_del_t *mp;
6313   f64 timeout;
6314   u32 vrf_id = 0;
6315   u8 is_add = 1;
6316   ip4_address_t lo, hi;
6317   u8 range_set = 0;
6318
6319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6320     {
6321       if (unformat (i, "vrf %d", &vrf_id))
6322         ;
6323       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6324                          unformat_ip4_address, &hi))
6325         range_set = 1;
6326       else if (unformat (i, "del"))
6327         is_add = 0;
6328       else
6329         {
6330           clib_warning ("parse error '%U'", format_unformat_error, i);
6331           return -99;
6332         }
6333     }
6334
6335   if (range_set == 0)
6336     {
6337       errmsg ("address range not set\n");
6338       return -99;
6339     }
6340
6341   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6342
6343   mp->vrf_id = ntohl (vrf_id);
6344   mp->is_add = is_add;
6345   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6346   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6347
6348   S;
6349   W;
6350   /* NOTREACHED */
6351   return 0;
6352 }
6353
6354 static int
6355 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6356 {
6357   unformat_input_t *i = vam->input;
6358   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6359   f64 timeout;
6360   u32 sw_if_index;
6361   u8 enable = 1;
6362   u8 sw_if_index_set = 0;
6363
6364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6365     {
6366       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6367         sw_if_index_set = 1;
6368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6369         sw_if_index_set = 1;
6370       else if (unformat (i, "enable"))
6371         enable = 1;
6372       else if (unformat (i, "disable"))
6373         enable = 0;
6374       else
6375         {
6376           clib_warning ("parse error '%U'", format_unformat_error, i);
6377           return -99;
6378         }
6379     }
6380
6381   if (sw_if_index_set == 0)
6382     {
6383       errmsg ("missing interface name or sw_if_index\n");
6384       return -99;
6385     }
6386
6387   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6388
6389   mp->sw_if_index = ntohl (sw_if_index);
6390   mp->enable_disable = enable;
6391
6392   S;
6393   W;
6394   /* NOTREACHED */
6395   return 0;
6396 }
6397
6398 static int
6399 api_mpls_add_del_encap (vat_main_t * vam)
6400 {
6401   unformat_input_t *i = vam->input;
6402   vl_api_mpls_add_del_encap_t *mp;
6403   f64 timeout;
6404   u32 vrf_id = 0;
6405   u32 *labels = 0;
6406   u32 label;
6407   ip4_address_t dst_address;
6408   u8 is_add = 1;
6409
6410   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6411     {
6412       if (unformat (i, "vrf %d", &vrf_id))
6413         ;
6414       else if (unformat (i, "label %d", &label))
6415         vec_add1 (labels, ntohl (label));
6416       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
6417         ;
6418       else if (unformat (i, "del"))
6419         is_add = 0;
6420       else
6421         {
6422           clib_warning ("parse error '%U'", format_unformat_error, i);
6423           return -99;
6424         }
6425     }
6426
6427   if (vec_len (labels) == 0)
6428     {
6429       errmsg ("missing encap label stack\n");
6430       return -99;
6431     }
6432
6433   M2 (MPLS_ADD_DEL_ENCAP, mpls_add_del_encap,
6434       sizeof (u32) * vec_len (labels));
6435
6436   mp->vrf_id = ntohl (vrf_id);
6437   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
6438   mp->is_add = is_add;
6439   mp->nlabels = vec_len (labels);
6440   clib_memcpy (mp->labels, labels, sizeof (u32) * mp->nlabels);
6441
6442   vec_free (labels);
6443
6444   S;
6445   W;
6446   /* NOTREACHED */
6447   return 0;
6448 }
6449
6450 static int
6451 api_mpls_ethernet_add_del_tunnel (vat_main_t * vam)
6452 {
6453   unformat_input_t *i = vam->input;
6454   vl_api_mpls_ethernet_add_del_tunnel_t *mp;
6455   f64 timeout;
6456   u32 inner_vrf_id = 0;
6457   ip4_address_t intfc_address;
6458   u8 dst_mac_address[6];
6459   int dst_set = 1;
6460   u32 tmp;
6461   u8 intfc_address_length = 0;
6462   u8 is_add = 1;
6463   u8 l2_only = 0;
6464   u32 tx_sw_if_index;
6465   int tx_sw_if_index_set = 0;
6466
6467   /* Shut up coverity */
6468   memset (dst_mac_address, 0, sizeof (dst_mac_address));
6469
6470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6471     {
6472       if (unformat (i, "vrf %d", &inner_vrf_id))
6473         ;
6474       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6475                          &intfc_address, &tmp))
6476         intfc_address_length = tmp;
6477       else if (unformat (i, "%U", unformat_sw_if_index, vam, &tx_sw_if_index))
6478         tx_sw_if_index_set = 1;
6479       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6480         tx_sw_if_index_set = 1;
6481       else if (unformat (i, "dst %U", unformat_ethernet_address,
6482                          dst_mac_address))
6483         dst_set = 1;
6484       else if (unformat (i, "l2-only"))
6485         l2_only = 1;
6486       else if (unformat (i, "del"))
6487         is_add = 0;
6488       else
6489         {
6490           clib_warning ("parse error '%U'", format_unformat_error, i);
6491           return -99;
6492         }
6493     }
6494
6495   if (!dst_set)
6496     {
6497       errmsg ("dst (mac address) not set\n");
6498       return -99;
6499     }
6500   if (!tx_sw_if_index_set)
6501     {
6502       errmsg ("tx-intfc not set\n");
6503       return -99;
6504     }
6505
6506   M (MPLS_ETHERNET_ADD_DEL_TUNNEL, mpls_ethernet_add_del_tunnel);
6507
6508   mp->vrf_id = ntohl (inner_vrf_id);
6509   clib_memcpy (mp->adj_address, &intfc_address, sizeof (intfc_address));
6510   mp->adj_address_length = intfc_address_length;
6511   clib_memcpy (mp->dst_mac_address, dst_mac_address,
6512                sizeof (dst_mac_address));
6513   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6514   mp->l2_only = l2_only;
6515   mp->is_add = is_add;
6516
6517   S;
6518   W;
6519   /* NOTREACHED */
6520   return 0;
6521 }
6522
6523 static int
6524 api_mpls_ethernet_add_del_tunnel_2 (vat_main_t * vam)
6525 {
6526   unformat_input_t *i = vam->input;
6527   vl_api_mpls_ethernet_add_del_tunnel_2_t *mp;
6528   f64 timeout;
6529   u32 inner_vrf_id = 0;
6530   u32 outer_vrf_id = 0;
6531   ip4_address_t adj_address;
6532   int adj_address_set = 0;
6533   ip4_address_t next_hop_address;
6534   int next_hop_address_set = 0;
6535   u32 tmp;
6536   u8 adj_address_length = 0;
6537   u8 l2_only = 0;
6538   u8 is_add = 1;
6539   u32 resolve_attempts = 5;
6540   u8 resolve_if_needed = 1;
6541
6542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6543     {
6544       if (unformat (i, "inner_vrf_id %d", &inner_vrf_id))
6545         ;
6546       else if (unformat (i, "outer_vrf_id %d", &outer_vrf_id))
6547         ;
6548       else if (unformat (i, "adj %U/%d", unformat_ip4_address,
6549                          &adj_address, &tmp))
6550         {
6551           adj_address_length = tmp;
6552           adj_address_set = 1;
6553         }
6554       else if (unformat (i, "next-hop %U", unformat_ip4_address,
6555                          &next_hop_address))
6556         next_hop_address_set = 1;
6557       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6558         ;
6559       else if (unformat (i, "resolve-if-needed %d", &tmp))
6560         resolve_if_needed = tmp;
6561       else if (unformat (i, "l2-only"))
6562         l2_only = 1;
6563       else if (unformat (i, "del"))
6564         is_add = 0;
6565       else
6566         {
6567           clib_warning ("parse error '%U'", format_unformat_error, i);
6568           return -99;
6569         }
6570     }
6571
6572   if (!adj_address_set)
6573     {
6574       errmsg ("adjacency address/mask not set\n");
6575       return -99;
6576     }
6577   if (!next_hop_address_set)
6578     {
6579       errmsg ("ip4 next hop address (in outer fib) not set\n");
6580       return -99;
6581     }
6582
6583   M (MPLS_ETHERNET_ADD_DEL_TUNNEL_2, mpls_ethernet_add_del_tunnel_2);
6584
6585   mp->inner_vrf_id = ntohl (inner_vrf_id);
6586   mp->outer_vrf_id = ntohl (outer_vrf_id);
6587   mp->resolve_attempts = ntohl (resolve_attempts);
6588   mp->resolve_if_needed = resolve_if_needed;
6589   mp->is_add = is_add;
6590   mp->l2_only = l2_only;
6591   clib_memcpy (mp->adj_address, &adj_address, sizeof (adj_address));
6592   mp->adj_address_length = adj_address_length;
6593   clib_memcpy (mp->next_hop_ip4_address_in_outer_vrf, &next_hop_address,
6594                sizeof (next_hop_address));
6595
6596   S;
6597   W;
6598   /* NOTREACHED */
6599   return 0;
6600 }
6601
6602 static int
6603 api_sw_interface_set_unnumbered (vat_main_t * vam)
6604 {
6605   unformat_input_t *i = vam->input;
6606   vl_api_sw_interface_set_unnumbered_t *mp;
6607   f64 timeout;
6608   u32 sw_if_index;
6609   u32 unnum_sw_index = ~0;
6610   u8 is_add = 1;
6611   u8 sw_if_index_set = 0;
6612
6613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6614     {
6615       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6616         sw_if_index_set = 1;
6617       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6618         sw_if_index_set = 1;
6619       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6620         ;
6621       else if (unformat (i, "del"))
6622         is_add = 0;
6623       else
6624         {
6625           clib_warning ("parse error '%U'", format_unformat_error, i);
6626           return -99;
6627         }
6628     }
6629
6630   if (sw_if_index_set == 0)
6631     {
6632       errmsg ("missing interface name or sw_if_index\n");
6633       return -99;
6634     }
6635
6636   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6637
6638   mp->sw_if_index = ntohl (sw_if_index);
6639   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6640   mp->is_add = is_add;
6641
6642   S;
6643   W;
6644   /* NOTREACHED */
6645   return 0;
6646 }
6647
6648 static int
6649 api_ip_neighbor_add_del (vat_main_t * vam)
6650 {
6651   unformat_input_t *i = vam->input;
6652   vl_api_ip_neighbor_add_del_t *mp;
6653   f64 timeout;
6654   u32 sw_if_index;
6655   u8 sw_if_index_set = 0;
6656   u32 vrf_id = 0;
6657   u8 is_add = 1;
6658   u8 is_static = 0;
6659   u8 mac_address[6];
6660   u8 mac_set = 0;
6661   u8 v4_address_set = 0;
6662   u8 v6_address_set = 0;
6663   ip4_address_t v4address;
6664   ip6_address_t v6address;
6665
6666   memset (mac_address, 0, sizeof (mac_address));
6667
6668   /* Parse args required to build the message */
6669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6670     {
6671       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6672         {
6673           mac_set = 1;
6674         }
6675       else if (unformat (i, "del"))
6676         is_add = 0;
6677       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6678         sw_if_index_set = 1;
6679       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6680         sw_if_index_set = 1;
6681       else if (unformat (i, "is_static"))
6682         is_static = 1;
6683       else if (unformat (i, "vrf %d", &vrf_id))
6684         ;
6685       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6686         v4_address_set = 1;
6687       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6688         v6_address_set = 1;
6689       else
6690         {
6691           clib_warning ("parse error '%U'", format_unformat_error, i);
6692           return -99;
6693         }
6694     }
6695
6696   if (sw_if_index_set == 0)
6697     {
6698       errmsg ("missing interface name or sw_if_index\n");
6699       return -99;
6700     }
6701   if (v4_address_set && v6_address_set)
6702     {
6703       errmsg ("both v4 and v6 addresses set\n");
6704       return -99;
6705     }
6706   if (!v4_address_set && !v6_address_set)
6707     {
6708       errmsg ("no address set\n");
6709       return -99;
6710     }
6711
6712   /* Construct the API message */
6713   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6714
6715   mp->sw_if_index = ntohl (sw_if_index);
6716   mp->is_add = is_add;
6717   mp->vrf_id = ntohl (vrf_id);
6718   mp->is_static = is_static;
6719   if (mac_set)
6720     clib_memcpy (mp->mac_address, mac_address, 6);
6721   if (v6_address_set)
6722     {
6723       mp->is_ipv6 = 1;
6724       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6725     }
6726   else
6727     {
6728       /* mp->is_ipv6 = 0; via memset in M macro above */
6729       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6730     }
6731
6732   /* send it... */
6733   S;
6734
6735   /* Wait for a reply, return good/bad news  */
6736   W;
6737
6738   /* NOTREACHED */
6739   return 0;
6740 }
6741
6742 static int
6743 api_reset_vrf (vat_main_t * vam)
6744 {
6745   unformat_input_t *i = vam->input;
6746   vl_api_reset_vrf_t *mp;
6747   f64 timeout;
6748   u32 vrf_id = 0;
6749   u8 is_ipv6 = 0;
6750   u8 vrf_id_set = 0;
6751
6752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6753     {
6754       if (unformat (i, "vrf %d", &vrf_id))
6755         vrf_id_set = 1;
6756       else if (unformat (i, "ipv6"))
6757         is_ipv6 = 1;
6758       else
6759         {
6760           clib_warning ("parse error '%U'", format_unformat_error, i);
6761           return -99;
6762         }
6763     }
6764
6765   if (vrf_id_set == 0)
6766     {
6767       errmsg ("missing vrf id\n");
6768       return -99;
6769     }
6770
6771   M (RESET_VRF, reset_vrf);
6772
6773   mp->vrf_id = ntohl (vrf_id);
6774   mp->is_ipv6 = is_ipv6;
6775
6776   S;
6777   W;
6778   /* NOTREACHED */
6779   return 0;
6780 }
6781
6782 static int
6783 api_create_vlan_subif (vat_main_t * vam)
6784 {
6785   unformat_input_t *i = vam->input;
6786   vl_api_create_vlan_subif_t *mp;
6787   f64 timeout;
6788   u32 sw_if_index;
6789   u8 sw_if_index_set = 0;
6790   u32 vlan_id;
6791   u8 vlan_id_set = 0;
6792
6793   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6794     {
6795       if (unformat (i, "sw_if_index %d", &sw_if_index))
6796         sw_if_index_set = 1;
6797       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6798         sw_if_index_set = 1;
6799       else if (unformat (i, "vlan %d", &vlan_id))
6800         vlan_id_set = 1;
6801       else
6802         {
6803           clib_warning ("parse error '%U'", format_unformat_error, i);
6804           return -99;
6805         }
6806     }
6807
6808   if (sw_if_index_set == 0)
6809     {
6810       errmsg ("missing interface name or sw_if_index\n");
6811       return -99;
6812     }
6813
6814   if (vlan_id_set == 0)
6815     {
6816       errmsg ("missing vlan_id\n");
6817       return -99;
6818     }
6819   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6820
6821   mp->sw_if_index = ntohl (sw_if_index);
6822   mp->vlan_id = ntohl (vlan_id);
6823
6824   S;
6825   W;
6826   /* NOTREACHED */
6827   return 0;
6828 }
6829
6830 #define foreach_create_subif_bit                \
6831 _(no_tags)                                      \
6832 _(one_tag)                                      \
6833 _(two_tags)                                     \
6834 _(dot1ad)                                       \
6835 _(exact_match)                                  \
6836 _(default_sub)                                  \
6837 _(outer_vlan_id_any)                            \
6838 _(inner_vlan_id_any)
6839
6840 static int
6841 api_create_subif (vat_main_t * vam)
6842 {
6843   unformat_input_t *i = vam->input;
6844   vl_api_create_subif_t *mp;
6845   f64 timeout;
6846   u32 sw_if_index;
6847   u8 sw_if_index_set = 0;
6848   u32 sub_id;
6849   u8 sub_id_set = 0;
6850   u32 no_tags = 0;
6851   u32 one_tag = 0;
6852   u32 two_tags = 0;
6853   u32 dot1ad = 0;
6854   u32 exact_match = 0;
6855   u32 default_sub = 0;
6856   u32 outer_vlan_id_any = 0;
6857   u32 inner_vlan_id_any = 0;
6858   u32 tmp;
6859   u16 outer_vlan_id = 0;
6860   u16 inner_vlan_id = 0;
6861
6862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6863     {
6864       if (unformat (i, "sw_if_index %d", &sw_if_index))
6865         sw_if_index_set = 1;
6866       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6867         sw_if_index_set = 1;
6868       else if (unformat (i, "sub_id %d", &sub_id))
6869         sub_id_set = 1;
6870       else if (unformat (i, "outer_vlan_id %d", &tmp))
6871         outer_vlan_id = tmp;
6872       else if (unformat (i, "inner_vlan_id %d", &tmp))
6873         inner_vlan_id = tmp;
6874
6875 #define _(a) else if (unformat (i, #a)) a = 1 ;
6876       foreach_create_subif_bit
6877 #undef _
6878         else
6879         {
6880           clib_warning ("parse error '%U'", format_unformat_error, i);
6881           return -99;
6882         }
6883     }
6884
6885   if (sw_if_index_set == 0)
6886     {
6887       errmsg ("missing interface name or sw_if_index\n");
6888       return -99;
6889     }
6890
6891   if (sub_id_set == 0)
6892     {
6893       errmsg ("missing sub_id\n");
6894       return -99;
6895     }
6896   M (CREATE_SUBIF, create_subif);
6897
6898   mp->sw_if_index = ntohl (sw_if_index);
6899   mp->sub_id = ntohl (sub_id);
6900
6901 #define _(a) mp->a = a;
6902   foreach_create_subif_bit;
6903 #undef _
6904
6905   mp->outer_vlan_id = ntohs (outer_vlan_id);
6906   mp->inner_vlan_id = ntohs (inner_vlan_id);
6907
6908   S;
6909   W;
6910   /* NOTREACHED */
6911   return 0;
6912 }
6913
6914 static int
6915 api_oam_add_del (vat_main_t * vam)
6916 {
6917   unformat_input_t *i = vam->input;
6918   vl_api_oam_add_del_t *mp;
6919   f64 timeout;
6920   u32 vrf_id = 0;
6921   u8 is_add = 1;
6922   ip4_address_t src, dst;
6923   u8 src_set = 0;
6924   u8 dst_set = 0;
6925
6926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6927     {
6928       if (unformat (i, "vrf %d", &vrf_id))
6929         ;
6930       else if (unformat (i, "src %U", unformat_ip4_address, &src))
6931         src_set = 1;
6932       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
6933         dst_set = 1;
6934       else if (unformat (i, "del"))
6935         is_add = 0;
6936       else
6937         {
6938           clib_warning ("parse error '%U'", format_unformat_error, i);
6939           return -99;
6940         }
6941     }
6942
6943   if (src_set == 0)
6944     {
6945       errmsg ("missing src addr\n");
6946       return -99;
6947     }
6948
6949   if (dst_set == 0)
6950     {
6951       errmsg ("missing dst addr\n");
6952       return -99;
6953     }
6954
6955   M (OAM_ADD_DEL, oam_add_del);
6956
6957   mp->vrf_id = ntohl (vrf_id);
6958   mp->is_add = is_add;
6959   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
6960   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
6961
6962   S;
6963   W;
6964   /* NOTREACHED */
6965   return 0;
6966 }
6967
6968 static int
6969 api_reset_fib (vat_main_t * vam)
6970 {
6971   unformat_input_t *i = vam->input;
6972   vl_api_reset_fib_t *mp;
6973   f64 timeout;
6974   u32 vrf_id = 0;
6975   u8 is_ipv6 = 0;
6976   u8 vrf_id_set = 0;
6977
6978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6979     {
6980       if (unformat (i, "vrf %d", &vrf_id))
6981         vrf_id_set = 1;
6982       else if (unformat (i, "ipv6"))
6983         is_ipv6 = 1;
6984       else
6985         {
6986           clib_warning ("parse error '%U'", format_unformat_error, i);
6987           return -99;
6988         }
6989     }
6990
6991   if (vrf_id_set == 0)
6992     {
6993       errmsg ("missing vrf id\n");
6994       return -99;
6995     }
6996
6997   M (RESET_FIB, reset_fib);
6998
6999   mp->vrf_id = ntohl (vrf_id);
7000   mp->is_ipv6 = is_ipv6;
7001
7002   S;
7003   W;
7004   /* NOTREACHED */
7005   return 0;
7006 }
7007
7008 static int
7009 api_dhcp_proxy_config (vat_main_t * vam)
7010 {
7011   unformat_input_t *i = vam->input;
7012   vl_api_dhcp_proxy_config_t *mp;
7013   f64 timeout;
7014   u32 vrf_id = 0;
7015   u8 is_add = 1;
7016   u8 insert_cid = 1;
7017   u8 v4_address_set = 0;
7018   u8 v6_address_set = 0;
7019   ip4_address_t v4address;
7020   ip6_address_t v6address;
7021   u8 v4_src_address_set = 0;
7022   u8 v6_src_address_set = 0;
7023   ip4_address_t v4srcaddress;
7024   ip6_address_t v6srcaddress;
7025
7026   /* Parse args required to build the message */
7027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7028     {
7029       if (unformat (i, "del"))
7030         is_add = 0;
7031       else if (unformat (i, "vrf %d", &vrf_id))
7032         ;
7033       else if (unformat (i, "insert-cid %d", &insert_cid))
7034         ;
7035       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7036         v4_address_set = 1;
7037       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7038         v6_address_set = 1;
7039       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7040         v4_src_address_set = 1;
7041       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7042         v6_src_address_set = 1;
7043       else
7044         break;
7045     }
7046
7047   if (v4_address_set && v6_address_set)
7048     {
7049       errmsg ("both v4 and v6 server addresses set\n");
7050       return -99;
7051     }
7052   if (!v4_address_set && !v6_address_set)
7053     {
7054       errmsg ("no server addresses set\n");
7055       return -99;
7056     }
7057
7058   if (v4_src_address_set && v6_src_address_set)
7059     {
7060       errmsg ("both v4 and v6  src addresses set\n");
7061       return -99;
7062     }
7063   if (!v4_src_address_set && !v6_src_address_set)
7064     {
7065       errmsg ("no src addresses set\n");
7066       return -99;
7067     }
7068
7069   if (!(v4_src_address_set && v4_address_set) &&
7070       !(v6_src_address_set && v6_address_set))
7071     {
7072       errmsg ("no matching server and src addresses set\n");
7073       return -99;
7074     }
7075
7076   /* Construct the API message */
7077   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7078
7079   mp->insert_circuit_id = insert_cid;
7080   mp->is_add = is_add;
7081   mp->vrf_id = ntohl (vrf_id);
7082   if (v6_address_set)
7083     {
7084       mp->is_ipv6 = 1;
7085       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7086       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7087     }
7088   else
7089     {
7090       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7091       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7092     }
7093
7094   /* send it... */
7095   S;
7096
7097   /* Wait for a reply, return good/bad news  */
7098   W;
7099   /* NOTREACHED */
7100   return 0;
7101 }
7102
7103 static int
7104 api_dhcp_proxy_config_2 (vat_main_t * vam)
7105 {
7106   unformat_input_t *i = vam->input;
7107   vl_api_dhcp_proxy_config_2_t *mp;
7108   f64 timeout;
7109   u32 rx_vrf_id = 0;
7110   u32 server_vrf_id = 0;
7111   u8 is_add = 1;
7112   u8 insert_cid = 1;
7113   u8 v4_address_set = 0;
7114   u8 v6_address_set = 0;
7115   ip4_address_t v4address;
7116   ip6_address_t v6address;
7117   u8 v4_src_address_set = 0;
7118   u8 v6_src_address_set = 0;
7119   ip4_address_t v4srcaddress;
7120   ip6_address_t v6srcaddress;
7121
7122   /* Parse args required to build the message */
7123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7124     {
7125       if (unformat (i, "del"))
7126         is_add = 0;
7127       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7128         ;
7129       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7130         ;
7131       else if (unformat (i, "insert-cid %d", &insert_cid))
7132         ;
7133       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7134         v4_address_set = 1;
7135       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7136         v6_address_set = 1;
7137       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7138         v4_src_address_set = 1;
7139       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7140         v6_src_address_set = 1;
7141       else
7142         break;
7143     }
7144
7145   if (v4_address_set && v6_address_set)
7146     {
7147       errmsg ("both v4 and v6 server addresses set\n");
7148       return -99;
7149     }
7150   if (!v4_address_set && !v6_address_set)
7151     {
7152       errmsg ("no server addresses set\n");
7153       return -99;
7154     }
7155
7156   if (v4_src_address_set && v6_src_address_set)
7157     {
7158       errmsg ("both v4 and v6  src addresses set\n");
7159       return -99;
7160     }
7161   if (!v4_src_address_set && !v6_src_address_set)
7162     {
7163       errmsg ("no src addresses set\n");
7164       return -99;
7165     }
7166
7167   if (!(v4_src_address_set && v4_address_set) &&
7168       !(v6_src_address_set && v6_address_set))
7169     {
7170       errmsg ("no matching server and src addresses set\n");
7171       return -99;
7172     }
7173
7174   /* Construct the API message */
7175   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7176
7177   mp->insert_circuit_id = insert_cid;
7178   mp->is_add = is_add;
7179   mp->rx_vrf_id = ntohl (rx_vrf_id);
7180   mp->server_vrf_id = ntohl (server_vrf_id);
7181   if (v6_address_set)
7182     {
7183       mp->is_ipv6 = 1;
7184       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7185       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7186     }
7187   else
7188     {
7189       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7190       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7191     }
7192
7193   /* send it... */
7194   S;
7195
7196   /* Wait for a reply, return good/bad news  */
7197   W;
7198   /* NOTREACHED */
7199   return 0;
7200 }
7201
7202 static int
7203 api_dhcp_proxy_set_vss (vat_main_t * vam)
7204 {
7205   unformat_input_t *i = vam->input;
7206   vl_api_dhcp_proxy_set_vss_t *mp;
7207   f64 timeout;
7208   u8 is_ipv6 = 0;
7209   u8 is_add = 1;
7210   u32 tbl_id;
7211   u8 tbl_id_set = 0;
7212   u32 oui;
7213   u8 oui_set = 0;
7214   u32 fib_id;
7215   u8 fib_id_set = 0;
7216
7217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7218     {
7219       if (unformat (i, "tbl_id %d", &tbl_id))
7220         tbl_id_set = 1;
7221       if (unformat (i, "fib_id %d", &fib_id))
7222         fib_id_set = 1;
7223       if (unformat (i, "oui %d", &oui))
7224         oui_set = 1;
7225       else if (unformat (i, "ipv6"))
7226         is_ipv6 = 1;
7227       else if (unformat (i, "del"))
7228         is_add = 0;
7229       else
7230         {
7231           clib_warning ("parse error '%U'", format_unformat_error, i);
7232           return -99;
7233         }
7234     }
7235
7236   if (tbl_id_set == 0)
7237     {
7238       errmsg ("missing tbl id\n");
7239       return -99;
7240     }
7241
7242   if (fib_id_set == 0)
7243     {
7244       errmsg ("missing fib id\n");
7245       return -99;
7246     }
7247   if (oui_set == 0)
7248     {
7249       errmsg ("missing oui\n");
7250       return -99;
7251     }
7252
7253   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7254   mp->tbl_id = ntohl (tbl_id);
7255   mp->fib_id = ntohl (fib_id);
7256   mp->oui = ntohl (oui);
7257   mp->is_ipv6 = is_ipv6;
7258   mp->is_add = is_add;
7259
7260   S;
7261   W;
7262   /* NOTREACHED */
7263   return 0;
7264 }
7265
7266 static int
7267 api_dhcp_client_config (vat_main_t * vam)
7268 {
7269   unformat_input_t *i = vam->input;
7270   vl_api_dhcp_client_config_t *mp;
7271   f64 timeout;
7272   u32 sw_if_index;
7273   u8 sw_if_index_set = 0;
7274   u8 is_add = 1;
7275   u8 *hostname = 0;
7276   u8 disable_event = 0;
7277
7278   /* Parse args required to build the message */
7279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7280     {
7281       if (unformat (i, "del"))
7282         is_add = 0;
7283       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7284         sw_if_index_set = 1;
7285       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7286         sw_if_index_set = 1;
7287       else if (unformat (i, "hostname %s", &hostname))
7288         ;
7289       else if (unformat (i, "disable_event"))
7290         disable_event = 1;
7291       else
7292         break;
7293     }
7294
7295   if (sw_if_index_set == 0)
7296     {
7297       errmsg ("missing interface name or sw_if_index\n");
7298       return -99;
7299     }
7300
7301   if (vec_len (hostname) > 63)
7302     {
7303       errmsg ("hostname too long\n");
7304     }
7305   vec_add1 (hostname, 0);
7306
7307   /* Construct the API message */
7308   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7309
7310   mp->sw_if_index = ntohl (sw_if_index);
7311   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7312   vec_free (hostname);
7313   mp->is_add = is_add;
7314   mp->want_dhcp_event = disable_event ? 0 : 1;
7315   mp->pid = getpid ();
7316
7317   /* send it... */
7318   S;
7319
7320   /* Wait for a reply, return good/bad news  */
7321   W;
7322   /* NOTREACHED */
7323   return 0;
7324 }
7325
7326 static int
7327 api_set_ip_flow_hash (vat_main_t * vam)
7328 {
7329   unformat_input_t *i = vam->input;
7330   vl_api_set_ip_flow_hash_t *mp;
7331   f64 timeout;
7332   u32 vrf_id = 0;
7333   u8 is_ipv6 = 0;
7334   u8 vrf_id_set = 0;
7335   u8 src = 0;
7336   u8 dst = 0;
7337   u8 sport = 0;
7338   u8 dport = 0;
7339   u8 proto = 0;
7340   u8 reverse = 0;
7341
7342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7343     {
7344       if (unformat (i, "vrf %d", &vrf_id))
7345         vrf_id_set = 1;
7346       else if (unformat (i, "ipv6"))
7347         is_ipv6 = 1;
7348       else if (unformat (i, "src"))
7349         src = 1;
7350       else if (unformat (i, "dst"))
7351         dst = 1;
7352       else if (unformat (i, "sport"))
7353         sport = 1;
7354       else if (unformat (i, "dport"))
7355         dport = 1;
7356       else if (unformat (i, "proto"))
7357         proto = 1;
7358       else if (unformat (i, "reverse"))
7359         reverse = 1;
7360
7361       else
7362         {
7363           clib_warning ("parse error '%U'", format_unformat_error, i);
7364           return -99;
7365         }
7366     }
7367
7368   if (vrf_id_set == 0)
7369     {
7370       errmsg ("missing vrf id\n");
7371       return -99;
7372     }
7373
7374   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7375   mp->src = src;
7376   mp->dst = dst;
7377   mp->sport = sport;
7378   mp->dport = dport;
7379   mp->proto = proto;
7380   mp->reverse = reverse;
7381   mp->vrf_id = ntohl (vrf_id);
7382   mp->is_ipv6 = is_ipv6;
7383
7384   S;
7385   W;
7386   /* NOTREACHED */
7387   return 0;
7388 }
7389
7390 static int
7391 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7392 {
7393   unformat_input_t *i = vam->input;
7394   vl_api_sw_interface_ip6_enable_disable_t *mp;
7395   f64 timeout;
7396   u32 sw_if_index;
7397   u8 sw_if_index_set = 0;
7398   u8 enable = 0;
7399
7400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7401     {
7402       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7403         sw_if_index_set = 1;
7404       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7405         sw_if_index_set = 1;
7406       else if (unformat (i, "enable"))
7407         enable = 1;
7408       else if (unformat (i, "disable"))
7409         enable = 0;
7410       else
7411         {
7412           clib_warning ("parse error '%U'", format_unformat_error, i);
7413           return -99;
7414         }
7415     }
7416
7417   if (sw_if_index_set == 0)
7418     {
7419       errmsg ("missing interface name or sw_if_index\n");
7420       return -99;
7421     }
7422
7423   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7424
7425   mp->sw_if_index = ntohl (sw_if_index);
7426   mp->enable = enable;
7427
7428   S;
7429   W;
7430   /* NOTREACHED */
7431   return 0;
7432 }
7433
7434 static int
7435 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7436 {
7437   unformat_input_t *i = vam->input;
7438   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7439   f64 timeout;
7440   u32 sw_if_index;
7441   u8 sw_if_index_set = 0;
7442   u32 address_length = 0;
7443   u8 v6_address_set = 0;
7444   ip6_address_t v6address;
7445
7446   /* Parse args required to build the message */
7447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7448     {
7449       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7450         sw_if_index_set = 1;
7451       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7452         sw_if_index_set = 1;
7453       else if (unformat (i, "%U/%d",
7454                          unformat_ip6_address, &v6address, &address_length))
7455         v6_address_set = 1;
7456       else
7457         break;
7458     }
7459
7460   if (sw_if_index_set == 0)
7461     {
7462       errmsg ("missing interface name or sw_if_index\n");
7463       return -99;
7464     }
7465   if (!v6_address_set)
7466     {
7467       errmsg ("no address set\n");
7468       return -99;
7469     }
7470
7471   /* Construct the API message */
7472   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7473      sw_interface_ip6_set_link_local_address);
7474
7475   mp->sw_if_index = ntohl (sw_if_index);
7476   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7477   mp->address_length = address_length;
7478
7479   /* send it... */
7480   S;
7481
7482   /* Wait for a reply, return good/bad news  */
7483   W;
7484
7485   /* NOTREACHED */
7486   return 0;
7487 }
7488
7489
7490 static int
7491 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7492 {
7493   unformat_input_t *i = vam->input;
7494   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7495   f64 timeout;
7496   u32 sw_if_index;
7497   u8 sw_if_index_set = 0;
7498   u32 address_length = 0;
7499   u8 v6_address_set = 0;
7500   ip6_address_t v6address;
7501   u8 use_default = 0;
7502   u8 no_advertise = 0;
7503   u8 off_link = 0;
7504   u8 no_autoconfig = 0;
7505   u8 no_onlink = 0;
7506   u8 is_no = 0;
7507   u32 val_lifetime = 0;
7508   u32 pref_lifetime = 0;
7509
7510   /* Parse args required to build the message */
7511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7512     {
7513       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7514         sw_if_index_set = 1;
7515       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7516         sw_if_index_set = 1;
7517       else if (unformat (i, "%U/%d",
7518                          unformat_ip6_address, &v6address, &address_length))
7519         v6_address_set = 1;
7520       else if (unformat (i, "val_life %d", &val_lifetime))
7521         ;
7522       else if (unformat (i, "pref_life %d", &pref_lifetime))
7523         ;
7524       else if (unformat (i, "def"))
7525         use_default = 1;
7526       else if (unformat (i, "noadv"))
7527         no_advertise = 1;
7528       else if (unformat (i, "offl"))
7529         off_link = 1;
7530       else if (unformat (i, "noauto"))
7531         no_autoconfig = 1;
7532       else if (unformat (i, "nolink"))
7533         no_onlink = 1;
7534       else if (unformat (i, "isno"))
7535         is_no = 1;
7536       else
7537         {
7538           clib_warning ("parse error '%U'", format_unformat_error, i);
7539           return -99;
7540         }
7541     }
7542
7543   if (sw_if_index_set == 0)
7544     {
7545       errmsg ("missing interface name or sw_if_index\n");
7546       return -99;
7547     }
7548   if (!v6_address_set)
7549     {
7550       errmsg ("no address set\n");
7551       return -99;
7552     }
7553
7554   /* Construct the API message */
7555   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7556
7557   mp->sw_if_index = ntohl (sw_if_index);
7558   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7559   mp->address_length = address_length;
7560   mp->use_default = use_default;
7561   mp->no_advertise = no_advertise;
7562   mp->off_link = off_link;
7563   mp->no_autoconfig = no_autoconfig;
7564   mp->no_onlink = no_onlink;
7565   mp->is_no = is_no;
7566   mp->val_lifetime = ntohl (val_lifetime);
7567   mp->pref_lifetime = ntohl (pref_lifetime);
7568
7569   /* send it... */
7570   S;
7571
7572   /* Wait for a reply, return good/bad news  */
7573   W;
7574
7575   /* NOTREACHED */
7576   return 0;
7577 }
7578
7579 static int
7580 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7581 {
7582   unformat_input_t *i = vam->input;
7583   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7584   f64 timeout;
7585   u32 sw_if_index;
7586   u8 sw_if_index_set = 0;
7587   u8 suppress = 0;
7588   u8 managed = 0;
7589   u8 other = 0;
7590   u8 ll_option = 0;
7591   u8 send_unicast = 0;
7592   u8 cease = 0;
7593   u8 is_no = 0;
7594   u8 default_router = 0;
7595   u32 max_interval = 0;
7596   u32 min_interval = 0;
7597   u32 lifetime = 0;
7598   u32 initial_count = 0;
7599   u32 initial_interval = 0;
7600
7601
7602   /* Parse args required to build the message */
7603   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7604     {
7605       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7606         sw_if_index_set = 1;
7607       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7608         sw_if_index_set = 1;
7609       else if (unformat (i, "maxint %d", &max_interval))
7610         ;
7611       else if (unformat (i, "minint %d", &min_interval))
7612         ;
7613       else if (unformat (i, "life %d", &lifetime))
7614         ;
7615       else if (unformat (i, "count %d", &initial_count))
7616         ;
7617       else if (unformat (i, "interval %d", &initial_interval))
7618         ;
7619       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7620         suppress = 1;
7621       else if (unformat (i, "managed"))
7622         managed = 1;
7623       else if (unformat (i, "other"))
7624         other = 1;
7625       else if (unformat (i, "ll"))
7626         ll_option = 1;
7627       else if (unformat (i, "send"))
7628         send_unicast = 1;
7629       else if (unformat (i, "cease"))
7630         cease = 1;
7631       else if (unformat (i, "isno"))
7632         is_no = 1;
7633       else if (unformat (i, "def"))
7634         default_router = 1;
7635       else
7636         {
7637           clib_warning ("parse error '%U'", format_unformat_error, i);
7638           return -99;
7639         }
7640     }
7641
7642   if (sw_if_index_set == 0)
7643     {
7644       errmsg ("missing interface name or sw_if_index\n");
7645       return -99;
7646     }
7647
7648   /* Construct the API message */
7649   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7650
7651   mp->sw_if_index = ntohl (sw_if_index);
7652   mp->max_interval = ntohl (max_interval);
7653   mp->min_interval = ntohl (min_interval);
7654   mp->lifetime = ntohl (lifetime);
7655   mp->initial_count = ntohl (initial_count);
7656   mp->initial_interval = ntohl (initial_interval);
7657   mp->suppress = suppress;
7658   mp->managed = managed;
7659   mp->other = other;
7660   mp->ll_option = ll_option;
7661   mp->send_unicast = send_unicast;
7662   mp->cease = cease;
7663   mp->is_no = is_no;
7664   mp->default_router = default_router;
7665
7666   /* send it... */
7667   S;
7668
7669   /* Wait for a reply, return good/bad news  */
7670   W;
7671
7672   /* NOTREACHED */
7673   return 0;
7674 }
7675
7676 static int
7677 api_set_arp_neighbor_limit (vat_main_t * vam)
7678 {
7679   unformat_input_t *i = vam->input;
7680   vl_api_set_arp_neighbor_limit_t *mp;
7681   f64 timeout;
7682   u32 arp_nbr_limit;
7683   u8 limit_set = 0;
7684   u8 is_ipv6 = 0;
7685
7686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7687     {
7688       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7689         limit_set = 1;
7690       else if (unformat (i, "ipv6"))
7691         is_ipv6 = 1;
7692       else
7693         {
7694           clib_warning ("parse error '%U'", format_unformat_error, i);
7695           return -99;
7696         }
7697     }
7698
7699   if (limit_set == 0)
7700     {
7701       errmsg ("missing limit value\n");
7702       return -99;
7703     }
7704
7705   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7706
7707   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7708   mp->is_ipv6 = is_ipv6;
7709
7710   S;
7711   W;
7712   /* NOTREACHED */
7713   return 0;
7714 }
7715
7716 static int
7717 api_l2_patch_add_del (vat_main_t * vam)
7718 {
7719   unformat_input_t *i = vam->input;
7720   vl_api_l2_patch_add_del_t *mp;
7721   f64 timeout;
7722   u32 rx_sw_if_index;
7723   u8 rx_sw_if_index_set = 0;
7724   u32 tx_sw_if_index;
7725   u8 tx_sw_if_index_set = 0;
7726   u8 is_add = 1;
7727
7728   /* Parse args required to build the message */
7729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7730     {
7731       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7732         rx_sw_if_index_set = 1;
7733       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7734         tx_sw_if_index_set = 1;
7735       else if (unformat (i, "rx"))
7736         {
7737           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7738             {
7739               if (unformat (i, "%U", unformat_sw_if_index, vam,
7740                             &rx_sw_if_index))
7741                 rx_sw_if_index_set = 1;
7742             }
7743           else
7744             break;
7745         }
7746       else if (unformat (i, "tx"))
7747         {
7748           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7749             {
7750               if (unformat (i, "%U", unformat_sw_if_index, vam,
7751                             &tx_sw_if_index))
7752                 tx_sw_if_index_set = 1;
7753             }
7754           else
7755             break;
7756         }
7757       else if (unformat (i, "del"))
7758         is_add = 0;
7759       else
7760         break;
7761     }
7762
7763   if (rx_sw_if_index_set == 0)
7764     {
7765       errmsg ("missing rx interface name or rx_sw_if_index\n");
7766       return -99;
7767     }
7768
7769   if (tx_sw_if_index_set == 0)
7770     {
7771       errmsg ("missing tx interface name or tx_sw_if_index\n");
7772       return -99;
7773     }
7774
7775   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7776
7777   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7778   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7779   mp->is_add = is_add;
7780
7781   S;
7782   W;
7783   /* NOTREACHED */
7784   return 0;
7785 }
7786
7787 static int
7788 api_ioam_enable (vat_main_t * vam)
7789 {
7790   unformat_input_t *input = vam->input;
7791   vl_api_ioam_enable_t *mp;
7792   f64 timeout;
7793   u32 id = 0;
7794   int has_trace_option = 0;
7795   int has_pot_option = 0;
7796   int has_seqno_option = 0;
7797   int has_analyse_option = 0;
7798
7799   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7800     {
7801       if (unformat (input, "trace"))
7802         has_trace_option = 1;
7803       else if (unformat (input, "pot"))
7804         has_pot_option = 1;
7805       else if (unformat (input, "seqno"))
7806         has_seqno_option = 1;
7807       else if (unformat (input, "analyse"))
7808         has_analyse_option = 1;
7809       else
7810         break;
7811     }
7812   M (IOAM_ENABLE, ioam_enable);
7813   mp->id = htons (id);
7814   mp->seqno = has_seqno_option;
7815   mp->analyse = has_analyse_option;
7816   mp->pot_enable = has_pot_option;
7817   mp->trace_enable = has_trace_option;
7818
7819   S;
7820   W;
7821
7822   return (0);
7823
7824 }
7825
7826
7827 static int
7828 api_ioam_disable (vat_main_t * vam)
7829 {
7830   vl_api_ioam_disable_t *mp;
7831   f64 timeout;
7832
7833   M (IOAM_DISABLE, ioam_disable);
7834   S;
7835   W;
7836   return 0;
7837 }
7838
7839 static int
7840 api_sr_tunnel_add_del (vat_main_t * vam)
7841 {
7842   unformat_input_t *i = vam->input;
7843   vl_api_sr_tunnel_add_del_t *mp;
7844   f64 timeout;
7845   int is_del = 0;
7846   int pl_index;
7847   ip6_address_t src_address;
7848   int src_address_set = 0;
7849   ip6_address_t dst_address;
7850   u32 dst_mask_width;
7851   int dst_address_set = 0;
7852   u16 flags = 0;
7853   u32 rx_table_id = 0;
7854   u32 tx_table_id = 0;
7855   ip6_address_t *segments = 0;
7856   ip6_address_t *this_seg;
7857   ip6_address_t *tags = 0;
7858   ip6_address_t *this_tag;
7859   ip6_address_t next_address, tag;
7860   u8 *name = 0;
7861   u8 *policy_name = 0;
7862
7863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7864     {
7865       if (unformat (i, "del"))
7866         is_del = 1;
7867       else if (unformat (i, "name %s", &name))
7868         ;
7869       else if (unformat (i, "policy %s", &policy_name))
7870         ;
7871       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
7872         ;
7873       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
7874         ;
7875       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
7876         src_address_set = 1;
7877       else if (unformat (i, "dst %U/%d",
7878                          unformat_ip6_address, &dst_address, &dst_mask_width))
7879         dst_address_set = 1;
7880       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
7881         {
7882           vec_add2 (segments, this_seg, 1);
7883           clib_memcpy (this_seg->as_u8, next_address.as_u8,
7884                        sizeof (*this_seg));
7885         }
7886       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
7887         {
7888           vec_add2 (tags, this_tag, 1);
7889           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
7890         }
7891       else if (unformat (i, "clean"))
7892         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
7893       else if (unformat (i, "protected"))
7894         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
7895       else if (unformat (i, "InPE %d", &pl_index))
7896         {
7897           if (pl_index <= 0 || pl_index > 4)
7898             {
7899             pl_index_range_error:
7900               errmsg ("pl index %d out of range\n", pl_index);
7901               return -99;
7902             }
7903           flags |=
7904             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
7905         }
7906       else if (unformat (i, "EgPE %d", &pl_index))
7907         {
7908           if (pl_index <= 0 || pl_index > 4)
7909             goto pl_index_range_error;
7910           flags |=
7911             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
7912         }
7913       else if (unformat (i, "OrgSrc %d", &pl_index))
7914         {
7915           if (pl_index <= 0 || pl_index > 4)
7916             goto pl_index_range_error;
7917           flags |=
7918             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
7919         }
7920       else
7921         break;
7922     }
7923
7924   if (!src_address_set)
7925     {
7926       errmsg ("src address required\n");
7927       return -99;
7928     }
7929
7930   if (!dst_address_set)
7931     {
7932       errmsg ("dst address required\n");
7933       return -99;
7934     }
7935
7936   if (!segments)
7937     {
7938       errmsg ("at least one sr segment required\n");
7939       return -99;
7940     }
7941
7942   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
7943       vec_len (segments) * sizeof (ip6_address_t)
7944       + vec_len (tags) * sizeof (ip6_address_t));
7945
7946   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
7947   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
7948   mp->dst_mask_width = dst_mask_width;
7949   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
7950   mp->n_segments = vec_len (segments);
7951   mp->n_tags = vec_len (tags);
7952   mp->is_add = is_del == 0;
7953   clib_memcpy (mp->segs_and_tags, segments,
7954                vec_len (segments) * sizeof (ip6_address_t));
7955   clib_memcpy (mp->segs_and_tags +
7956                vec_len (segments) * sizeof (ip6_address_t), tags,
7957                vec_len (tags) * sizeof (ip6_address_t));
7958
7959   mp->outer_vrf_id = ntohl (rx_table_id);
7960   mp->inner_vrf_id = ntohl (tx_table_id);
7961   memcpy (mp->name, name, vec_len (name));
7962   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
7963
7964   vec_free (segments);
7965   vec_free (tags);
7966
7967   S;
7968   W;
7969   /* NOTREACHED */
7970 }
7971
7972 static int
7973 api_sr_policy_add_del (vat_main_t * vam)
7974 {
7975   unformat_input_t *input = vam->input;
7976   vl_api_sr_policy_add_del_t *mp;
7977   f64 timeout;
7978   int is_del = 0;
7979   u8 *name = 0;
7980   u8 *tunnel_name = 0;
7981   u8 **tunnel_names = 0;
7982
7983   int name_set = 0;
7984   int tunnel_set = 0;
7985   int j = 0;
7986   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
7987   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
7988
7989   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7990     {
7991       if (unformat (input, "del"))
7992         is_del = 1;
7993       else if (unformat (input, "name %s", &name))
7994         name_set = 1;
7995       else if (unformat (input, "tunnel %s", &tunnel_name))
7996         {
7997           if (tunnel_name)
7998             {
7999               vec_add1 (tunnel_names, tunnel_name);
8000               /* For serializer:
8001                  - length = #bytes to store in serial vector
8002                  - +1 = byte to store that length
8003                */
8004               tunnel_names_length += (vec_len (tunnel_name) + 1);
8005               tunnel_set = 1;
8006               tunnel_name = 0;
8007             }
8008         }
8009       else
8010         break;
8011     }
8012
8013   if (!name_set)
8014     {
8015       errmsg ("policy name required\n");
8016       return -99;
8017     }
8018
8019   if ((!tunnel_set) && (!is_del))
8020     {
8021       errmsg ("tunnel name required\n");
8022       return -99;
8023     }
8024
8025   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8026
8027
8028
8029   mp->is_add = !is_del;
8030
8031   memcpy (mp->name, name, vec_len (name));
8032   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8033   u8 *serial_orig = 0;
8034   vec_validate (serial_orig, tunnel_names_length);
8035   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8036   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8037
8038   for (j = 0; j < vec_len (tunnel_names); j++)
8039     {
8040       tun_name_len = vec_len (tunnel_names[j]);
8041       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8042       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8043       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8044       serial_orig += tun_name_len;      // Advance past the copy
8045     }
8046   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8047
8048   vec_free (tunnel_names);
8049   vec_free (tunnel_name);
8050
8051   S;
8052   W;
8053   /* NOTREACHED */
8054 }
8055
8056 static int
8057 api_sr_multicast_map_add_del (vat_main_t * vam)
8058 {
8059   unformat_input_t *input = vam->input;
8060   vl_api_sr_multicast_map_add_del_t *mp;
8061   f64 timeout;
8062   int is_del = 0;
8063   ip6_address_t multicast_address;
8064   u8 *policy_name = 0;
8065   int multicast_address_set = 0;
8066
8067   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8068     {
8069       if (unformat (input, "del"))
8070         is_del = 1;
8071       else
8072         if (unformat
8073             (input, "address %U", unformat_ip6_address, &multicast_address))
8074         multicast_address_set = 1;
8075       else if (unformat (input, "sr-policy %s", &policy_name))
8076         ;
8077       else
8078         break;
8079     }
8080
8081   if (!is_del && !policy_name)
8082     {
8083       errmsg ("sr-policy name required\n");
8084       return -99;
8085     }
8086
8087
8088   if (!multicast_address_set)
8089     {
8090       errmsg ("address required\n");
8091       return -99;
8092     }
8093
8094   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8095
8096   mp->is_add = !is_del;
8097   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8098   clib_memcpy (mp->multicast_address, &multicast_address,
8099                sizeof (mp->multicast_address));
8100
8101
8102   vec_free (policy_name);
8103
8104   S;
8105   W;
8106   /* NOTREACHED */
8107 }
8108
8109
8110 #define foreach_tcp_proto_field                 \
8111 _(src_port)                                     \
8112 _(dst_port)
8113
8114 #define foreach_udp_proto_field                 \
8115 _(src_port)                                     \
8116 _(dst_port)
8117
8118 #define foreach_ip4_proto_field                 \
8119 _(src_address)                                  \
8120 _(dst_address)                                  \
8121 _(tos)                                          \
8122 _(length)                                       \
8123 _(fragment_id)                                  \
8124 _(ttl)                                          \
8125 _(protocol)                                     \
8126 _(checksum)
8127
8128 uword
8129 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8130 {
8131   u8 **maskp = va_arg (*args, u8 **);
8132   u8 *mask = 0;
8133   u8 found_something = 0;
8134   tcp_header_t *tcp;
8135
8136 #define _(a) u8 a=0;
8137   foreach_tcp_proto_field;
8138 #undef _
8139
8140   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8141     {
8142       if (0);
8143 #define _(a) else if (unformat (input, #a)) a=1;
8144       foreach_tcp_proto_field
8145 #undef _
8146         else
8147         break;
8148     }
8149
8150 #define _(a) found_something += a;
8151   foreach_tcp_proto_field;
8152 #undef _
8153
8154   if (found_something == 0)
8155     return 0;
8156
8157   vec_validate (mask, sizeof (*tcp) - 1);
8158
8159   tcp = (tcp_header_t *) mask;
8160
8161 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8162   foreach_tcp_proto_field;
8163 #undef _
8164
8165   *maskp = mask;
8166   return 1;
8167 }
8168
8169 uword
8170 unformat_udp_mask (unformat_input_t * input, va_list * args)
8171 {
8172   u8 **maskp = va_arg (*args, u8 **);
8173   u8 *mask = 0;
8174   u8 found_something = 0;
8175   udp_header_t *udp;
8176
8177 #define _(a) u8 a=0;
8178   foreach_udp_proto_field;
8179 #undef _
8180
8181   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8182     {
8183       if (0);
8184 #define _(a) else if (unformat (input, #a)) a=1;
8185       foreach_udp_proto_field
8186 #undef _
8187         else
8188         break;
8189     }
8190
8191 #define _(a) found_something += a;
8192   foreach_udp_proto_field;
8193 #undef _
8194
8195   if (found_something == 0)
8196     return 0;
8197
8198   vec_validate (mask, sizeof (*udp) - 1);
8199
8200   udp = (udp_header_t *) mask;
8201
8202 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8203   foreach_udp_proto_field;
8204 #undef _
8205
8206   *maskp = mask;
8207   return 1;
8208 }
8209
8210 typedef struct
8211 {
8212   u16 src_port, dst_port;
8213 } tcpudp_header_t;
8214
8215 uword
8216 unformat_l4_mask (unformat_input_t * input, va_list * args)
8217 {
8218   u8 **maskp = va_arg (*args, u8 **);
8219   u16 src_port = 0, dst_port = 0;
8220   tcpudp_header_t *tcpudp;
8221
8222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8223     {
8224       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8225         return 1;
8226       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8227         return 1;
8228       else if (unformat (input, "src_port"))
8229         src_port = 0xFFFF;
8230       else if (unformat (input, "dst_port"))
8231         dst_port = 0xFFFF;
8232       else
8233         return 0;
8234     }
8235
8236   if (!src_port && !dst_port)
8237     return 0;
8238
8239   u8 *mask = 0;
8240   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8241
8242   tcpudp = (tcpudp_header_t *) mask;
8243   tcpudp->src_port = src_port;
8244   tcpudp->dst_port = dst_port;
8245
8246   *maskp = mask;
8247
8248   return 1;
8249 }
8250
8251 uword
8252 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8253 {
8254   u8 **maskp = va_arg (*args, u8 **);
8255   u8 *mask = 0;
8256   u8 found_something = 0;
8257   ip4_header_t *ip;
8258
8259 #define _(a) u8 a=0;
8260   foreach_ip4_proto_field;
8261 #undef _
8262   u8 version = 0;
8263   u8 hdr_length = 0;
8264
8265
8266   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8267     {
8268       if (unformat (input, "version"))
8269         version = 1;
8270       else if (unformat (input, "hdr_length"))
8271         hdr_length = 1;
8272       else if (unformat (input, "src"))
8273         src_address = 1;
8274       else if (unformat (input, "dst"))
8275         dst_address = 1;
8276       else if (unformat (input, "proto"))
8277         protocol = 1;
8278
8279 #define _(a) else if (unformat (input, #a)) a=1;
8280       foreach_ip4_proto_field
8281 #undef _
8282         else
8283         break;
8284     }
8285
8286 #define _(a) found_something += a;
8287   foreach_ip4_proto_field;
8288 #undef _
8289
8290   if (found_something == 0)
8291     return 0;
8292
8293   vec_validate (mask, sizeof (*ip) - 1);
8294
8295   ip = (ip4_header_t *) mask;
8296
8297 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8298   foreach_ip4_proto_field;
8299 #undef _
8300
8301   ip->ip_version_and_header_length = 0;
8302
8303   if (version)
8304     ip->ip_version_and_header_length |= 0xF0;
8305
8306   if (hdr_length)
8307     ip->ip_version_and_header_length |= 0x0F;
8308
8309   *maskp = mask;
8310   return 1;
8311 }
8312
8313 #define foreach_ip6_proto_field                 \
8314 _(src_address)                                  \
8315 _(dst_address)                                  \
8316 _(payload_length)                               \
8317 _(hop_limit)                                    \
8318 _(protocol)
8319
8320 uword
8321 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8322 {
8323   u8 **maskp = va_arg (*args, u8 **);
8324   u8 *mask = 0;
8325   u8 found_something = 0;
8326   ip6_header_t *ip;
8327   u32 ip_version_traffic_class_and_flow_label;
8328
8329 #define _(a) u8 a=0;
8330   foreach_ip6_proto_field;
8331 #undef _
8332   u8 version = 0;
8333   u8 traffic_class = 0;
8334   u8 flow_label = 0;
8335
8336   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8337     {
8338       if (unformat (input, "version"))
8339         version = 1;
8340       else if (unformat (input, "traffic-class"))
8341         traffic_class = 1;
8342       else if (unformat (input, "flow-label"))
8343         flow_label = 1;
8344       else if (unformat (input, "src"))
8345         src_address = 1;
8346       else if (unformat (input, "dst"))
8347         dst_address = 1;
8348       else if (unformat (input, "proto"))
8349         protocol = 1;
8350
8351 #define _(a) else if (unformat (input, #a)) a=1;
8352       foreach_ip6_proto_field
8353 #undef _
8354         else
8355         break;
8356     }
8357
8358 #define _(a) found_something += a;
8359   foreach_ip6_proto_field;
8360 #undef _
8361
8362   if (found_something == 0)
8363     return 0;
8364
8365   vec_validate (mask, sizeof (*ip) - 1);
8366
8367   ip = (ip6_header_t *) mask;
8368
8369 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8370   foreach_ip6_proto_field;
8371 #undef _
8372
8373   ip_version_traffic_class_and_flow_label = 0;
8374
8375   if (version)
8376     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8377
8378   if (traffic_class)
8379     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8380
8381   if (flow_label)
8382     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8383
8384   ip->ip_version_traffic_class_and_flow_label =
8385     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8386
8387   *maskp = mask;
8388   return 1;
8389 }
8390
8391 uword
8392 unformat_l3_mask (unformat_input_t * input, va_list * args)
8393 {
8394   u8 **maskp = va_arg (*args, u8 **);
8395
8396   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8397     {
8398       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8399         return 1;
8400       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8401         return 1;
8402       else
8403         break;
8404     }
8405   return 0;
8406 }
8407
8408 uword
8409 unformat_l2_mask (unformat_input_t * input, va_list * args)
8410 {
8411   u8 **maskp = va_arg (*args, u8 **);
8412   u8 *mask = 0;
8413   u8 src = 0;
8414   u8 dst = 0;
8415   u8 proto = 0;
8416   u8 tag1 = 0;
8417   u8 tag2 = 0;
8418   u8 ignore_tag1 = 0;
8419   u8 ignore_tag2 = 0;
8420   u8 cos1 = 0;
8421   u8 cos2 = 0;
8422   u8 dot1q = 0;
8423   u8 dot1ad = 0;
8424   int len = 14;
8425
8426   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8427     {
8428       if (unformat (input, "src"))
8429         src = 1;
8430       else if (unformat (input, "dst"))
8431         dst = 1;
8432       else if (unformat (input, "proto"))
8433         proto = 1;
8434       else if (unformat (input, "tag1"))
8435         tag1 = 1;
8436       else if (unformat (input, "tag2"))
8437         tag2 = 1;
8438       else if (unformat (input, "ignore-tag1"))
8439         ignore_tag1 = 1;
8440       else if (unformat (input, "ignore-tag2"))
8441         ignore_tag2 = 1;
8442       else if (unformat (input, "cos1"))
8443         cos1 = 1;
8444       else if (unformat (input, "cos2"))
8445         cos2 = 1;
8446       else if (unformat (input, "dot1q"))
8447         dot1q = 1;
8448       else if (unformat (input, "dot1ad"))
8449         dot1ad = 1;
8450       else
8451         break;
8452     }
8453   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8454        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8455     return 0;
8456
8457   if (tag1 || ignore_tag1 || cos1 || dot1q)
8458     len = 18;
8459   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8460     len = 22;
8461
8462   vec_validate (mask, len - 1);
8463
8464   if (dst)
8465     memset (mask, 0xff, 6);
8466
8467   if (src)
8468     memset (mask + 6, 0xff, 6);
8469
8470   if (tag2 || dot1ad)
8471     {
8472       /* inner vlan tag */
8473       if (tag2)
8474         {
8475           mask[19] = 0xff;
8476           mask[18] = 0x0f;
8477         }
8478       if (cos2)
8479         mask[18] |= 0xe0;
8480       if (proto)
8481         mask[21] = mask[20] = 0xff;
8482       if (tag1)
8483         {
8484           mask[15] = 0xff;
8485           mask[14] = 0x0f;
8486         }
8487       if (cos1)
8488         mask[14] |= 0xe0;
8489       *maskp = mask;
8490       return 1;
8491     }
8492   if (tag1 | dot1q)
8493     {
8494       if (tag1)
8495         {
8496           mask[15] = 0xff;
8497           mask[14] = 0x0f;
8498         }
8499       if (cos1)
8500         mask[14] |= 0xe0;
8501       if (proto)
8502         mask[16] = mask[17] = 0xff;
8503
8504       *maskp = mask;
8505       return 1;
8506     }
8507   if (cos2)
8508     mask[18] |= 0xe0;
8509   if (cos1)
8510     mask[14] |= 0xe0;
8511   if (proto)
8512     mask[12] = mask[13] = 0xff;
8513
8514   *maskp = mask;
8515   return 1;
8516 }
8517
8518 uword
8519 unformat_classify_mask (unformat_input_t * input, va_list * args)
8520 {
8521   u8 **maskp = va_arg (*args, u8 **);
8522   u32 *skipp = va_arg (*args, u32 *);
8523   u32 *matchp = va_arg (*args, u32 *);
8524   u32 match;
8525   u8 *mask = 0;
8526   u8 *l2 = 0;
8527   u8 *l3 = 0;
8528   u8 *l4 = 0;
8529   int i;
8530
8531   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8532     {
8533       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8534         ;
8535       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8536         ;
8537       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8538         ;
8539       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8540         ;
8541       else
8542         break;
8543     }
8544
8545   if (l4 && !l3)
8546     {
8547       vec_free (mask);
8548       vec_free (l2);
8549       vec_free (l4);
8550       return 0;
8551     }
8552
8553   if (mask || l2 || l3 || l4)
8554     {
8555       if (l2 || l3 || l4)
8556         {
8557           /* "With a free Ethernet header in every package" */
8558           if (l2 == 0)
8559             vec_validate (l2, 13);
8560           mask = l2;
8561           if (vec_len (l3))
8562             {
8563               vec_append (mask, l3);
8564               vec_free (l3);
8565             }
8566           if (vec_len (l4))
8567             {
8568               vec_append (mask, l4);
8569               vec_free (l4);
8570             }
8571         }
8572
8573       /* Scan forward looking for the first significant mask octet */
8574       for (i = 0; i < vec_len (mask); i++)
8575         if (mask[i])
8576           break;
8577
8578       /* compute (skip, match) params */
8579       *skipp = i / sizeof (u32x4);
8580       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8581
8582       /* Pad mask to an even multiple of the vector size */
8583       while (vec_len (mask) % sizeof (u32x4))
8584         vec_add1 (mask, 0);
8585
8586       match = vec_len (mask) / sizeof (u32x4);
8587
8588       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8589         {
8590           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8591           if (*tmp || *(tmp + 1))
8592             break;
8593           match--;
8594         }
8595       if (match == 0)
8596         clib_warning ("BUG: match 0");
8597
8598       _vec_len (mask) = match * sizeof (u32x4);
8599
8600       *matchp = match;
8601       *maskp = mask;
8602
8603       return 1;
8604     }
8605
8606   return 0;
8607 }
8608
8609 #define foreach_l2_next                         \
8610 _(drop, DROP)                                   \
8611 _(ethernet, ETHERNET_INPUT)                     \
8612 _(ip4, IP4_INPUT)                               \
8613 _(ip6, IP6_INPUT)
8614
8615 uword
8616 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8617 {
8618   u32 *miss_next_indexp = va_arg (*args, u32 *);
8619   u32 next_index = 0;
8620   u32 tmp;
8621
8622 #define _(n,N) \
8623   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8624   foreach_l2_next;
8625 #undef _
8626
8627   if (unformat (input, "%d", &tmp))
8628     {
8629       next_index = tmp;
8630       goto out;
8631     }
8632
8633   return 0;
8634
8635 out:
8636   *miss_next_indexp = next_index;
8637   return 1;
8638 }
8639
8640 #define foreach_ip_next                         \
8641 _(drop, DROP)                                   \
8642 _(local, LOCAL)                                 \
8643 _(rewrite, REWRITE)
8644
8645 uword
8646 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8647 {
8648   u32 *miss_next_indexp = va_arg (*args, u32 *);
8649   u32 next_index = 0;
8650   u32 tmp;
8651
8652 #define _(n,N) \
8653   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8654   foreach_ip_next;
8655 #undef _
8656
8657   if (unformat (input, "%d", &tmp))
8658     {
8659       next_index = tmp;
8660       goto out;
8661     }
8662
8663   return 0;
8664
8665 out:
8666   *miss_next_indexp = next_index;
8667   return 1;
8668 }
8669
8670 #define foreach_acl_next                        \
8671 _(deny, DENY)
8672
8673 uword
8674 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8675 {
8676   u32 *miss_next_indexp = va_arg (*args, u32 *);
8677   u32 next_index = 0;
8678   u32 tmp;
8679
8680 #define _(n,N) \
8681   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8682   foreach_acl_next;
8683 #undef _
8684
8685   if (unformat (input, "permit"))
8686     {
8687       next_index = ~0;
8688       goto out;
8689     }
8690   else if (unformat (input, "%d", &tmp))
8691     {
8692       next_index = tmp;
8693       goto out;
8694     }
8695
8696   return 0;
8697
8698 out:
8699   *miss_next_indexp = next_index;
8700   return 1;
8701 }
8702
8703 uword
8704 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8705 {
8706   u32 *r = va_arg (*args, u32 *);
8707
8708   if (unformat (input, "conform-color"))
8709     *r = POLICE_CONFORM;
8710   else if (unformat (input, "exceed-color"))
8711     *r = POLICE_EXCEED;
8712   else
8713     return 0;
8714
8715   return 1;
8716 }
8717
8718 static int
8719 api_classify_add_del_table (vat_main_t * vam)
8720 {
8721   unformat_input_t *i = vam->input;
8722   vl_api_classify_add_del_table_t *mp;
8723
8724   u32 nbuckets = 2;
8725   u32 skip = ~0;
8726   u32 match = ~0;
8727   int is_add = 1;
8728   u32 table_index = ~0;
8729   u32 next_table_index = ~0;
8730   u32 miss_next_index = ~0;
8731   u32 memory_size = 32 << 20;
8732   u8 *mask = 0;
8733   f64 timeout;
8734   u32 current_data_flag = 0;
8735   int current_data_offset = 0;
8736
8737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8738     {
8739       if (unformat (i, "del"))
8740         is_add = 0;
8741       else if (unformat (i, "buckets %d", &nbuckets))
8742         ;
8743       else if (unformat (i, "memory_size %d", &memory_size))
8744         ;
8745       else if (unformat (i, "skip %d", &skip))
8746         ;
8747       else if (unformat (i, "match %d", &match))
8748         ;
8749       else if (unformat (i, "table %d", &table_index))
8750         ;
8751       else if (unformat (i, "mask %U", unformat_classify_mask,
8752                          &mask, &skip, &match))
8753         ;
8754       else if (unformat (i, "next-table %d", &next_table_index))
8755         ;
8756       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8757                          &miss_next_index))
8758         ;
8759       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8760                          &miss_next_index))
8761         ;
8762       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8763                          &miss_next_index))
8764         ;
8765       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8766         ;
8767       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8768         ;
8769       else
8770         break;
8771     }
8772
8773   if (is_add && mask == 0)
8774     {
8775       errmsg ("Mask required\n");
8776       return -99;
8777     }
8778
8779   if (is_add && skip == ~0)
8780     {
8781       errmsg ("skip count required\n");
8782       return -99;
8783     }
8784
8785   if (is_add && match == ~0)
8786     {
8787       errmsg ("match count required\n");
8788       return -99;
8789     }
8790
8791   if (!is_add && table_index == ~0)
8792     {
8793       errmsg ("table index required for delete\n");
8794       return -99;
8795     }
8796
8797   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8798
8799   mp->is_add = is_add;
8800   mp->table_index = ntohl (table_index);
8801   mp->nbuckets = ntohl (nbuckets);
8802   mp->memory_size = ntohl (memory_size);
8803   mp->skip_n_vectors = ntohl (skip);
8804   mp->match_n_vectors = ntohl (match);
8805   mp->next_table_index = ntohl (next_table_index);
8806   mp->miss_next_index = ntohl (miss_next_index);
8807   mp->current_data_flag = ntohl (current_data_flag);
8808   mp->current_data_offset = ntohl (current_data_offset);
8809   clib_memcpy (mp->mask, mask, vec_len (mask));
8810
8811   vec_free (mask);
8812
8813   S;
8814   W;
8815   /* NOTREACHED */
8816 }
8817
8818 uword
8819 unformat_l4_match (unformat_input_t * input, va_list * args)
8820 {
8821   u8 **matchp = va_arg (*args, u8 **);
8822
8823   u8 *proto_header = 0;
8824   int src_port = 0;
8825   int dst_port = 0;
8826
8827   tcpudp_header_t h;
8828
8829   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8830     {
8831       if (unformat (input, "src_port %d", &src_port))
8832         ;
8833       else if (unformat (input, "dst_port %d", &dst_port))
8834         ;
8835       else
8836         return 0;
8837     }
8838
8839   h.src_port = clib_host_to_net_u16 (src_port);
8840   h.dst_port = clib_host_to_net_u16 (dst_port);
8841   vec_validate (proto_header, sizeof (h) - 1);
8842   memcpy (proto_header, &h, sizeof (h));
8843
8844   *matchp = proto_header;
8845
8846   return 1;
8847 }
8848
8849 uword
8850 unformat_ip4_match (unformat_input_t * input, va_list * args)
8851 {
8852   u8 **matchp = va_arg (*args, u8 **);
8853   u8 *match = 0;
8854   ip4_header_t *ip;
8855   int version = 0;
8856   u32 version_val;
8857   int hdr_length = 0;
8858   u32 hdr_length_val;
8859   int src = 0, dst = 0;
8860   ip4_address_t src_val, dst_val;
8861   int proto = 0;
8862   u32 proto_val;
8863   int tos = 0;
8864   u32 tos_val;
8865   int length = 0;
8866   u32 length_val;
8867   int fragment_id = 0;
8868   u32 fragment_id_val;
8869   int ttl = 0;
8870   int ttl_val;
8871   int checksum = 0;
8872   u32 checksum_val;
8873
8874   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8875     {
8876       if (unformat (input, "version %d", &version_val))
8877         version = 1;
8878       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8879         hdr_length = 1;
8880       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8881         src = 1;
8882       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8883         dst = 1;
8884       else if (unformat (input, "proto %d", &proto_val))
8885         proto = 1;
8886       else if (unformat (input, "tos %d", &tos_val))
8887         tos = 1;
8888       else if (unformat (input, "length %d", &length_val))
8889         length = 1;
8890       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8891         fragment_id = 1;
8892       else if (unformat (input, "ttl %d", &ttl_val))
8893         ttl = 1;
8894       else if (unformat (input, "checksum %d", &checksum_val))
8895         checksum = 1;
8896       else
8897         break;
8898     }
8899
8900   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8901       + ttl + checksum == 0)
8902     return 0;
8903
8904   /*
8905    * Aligned because we use the real comparison functions
8906    */
8907   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8908
8909   ip = (ip4_header_t *) match;
8910
8911   /* These are realistically matched in practice */
8912   if (src)
8913     ip->src_address.as_u32 = src_val.as_u32;
8914
8915   if (dst)
8916     ip->dst_address.as_u32 = dst_val.as_u32;
8917
8918   if (proto)
8919     ip->protocol = proto_val;
8920
8921
8922   /* These are not, but they're included for completeness */
8923   if (version)
8924     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8925
8926   if (hdr_length)
8927     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8928
8929   if (tos)
8930     ip->tos = tos_val;
8931
8932   if (length)
8933     ip->length = clib_host_to_net_u16 (length_val);
8934
8935   if (ttl)
8936     ip->ttl = ttl_val;
8937
8938   if (checksum)
8939     ip->checksum = clib_host_to_net_u16 (checksum_val);
8940
8941   *matchp = match;
8942   return 1;
8943 }
8944
8945 uword
8946 unformat_ip6_match (unformat_input_t * input, va_list * args)
8947 {
8948   u8 **matchp = va_arg (*args, u8 **);
8949   u8 *match = 0;
8950   ip6_header_t *ip;
8951   int version = 0;
8952   u32 version_val;
8953   u8 traffic_class = 0;
8954   u32 traffic_class_val = 0;
8955   u8 flow_label = 0;
8956   u8 flow_label_val;
8957   int src = 0, dst = 0;
8958   ip6_address_t src_val, dst_val;
8959   int proto = 0;
8960   u32 proto_val;
8961   int payload_length = 0;
8962   u32 payload_length_val;
8963   int hop_limit = 0;
8964   int hop_limit_val;
8965   u32 ip_version_traffic_class_and_flow_label;
8966
8967   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8968     {
8969       if (unformat (input, "version %d", &version_val))
8970         version = 1;
8971       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8972         traffic_class = 1;
8973       else if (unformat (input, "flow_label %d", &flow_label_val))
8974         flow_label = 1;
8975       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8976         src = 1;
8977       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8978         dst = 1;
8979       else if (unformat (input, "proto %d", &proto_val))
8980         proto = 1;
8981       else if (unformat (input, "payload_length %d", &payload_length_val))
8982         payload_length = 1;
8983       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8984         hop_limit = 1;
8985       else
8986         break;
8987     }
8988
8989   if (version + traffic_class + flow_label + src + dst + proto +
8990       payload_length + hop_limit == 0)
8991     return 0;
8992
8993   /*
8994    * Aligned because we use the real comparison functions
8995    */
8996   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8997
8998   ip = (ip6_header_t *) match;
8999
9000   if (src)
9001     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9002
9003   if (dst)
9004     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9005
9006   if (proto)
9007     ip->protocol = proto_val;
9008
9009   ip_version_traffic_class_and_flow_label = 0;
9010
9011   if (version)
9012     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9013
9014   if (traffic_class)
9015     ip_version_traffic_class_and_flow_label |=
9016       (traffic_class_val & 0xFF) << 20;
9017
9018   if (flow_label)
9019     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9020
9021   ip->ip_version_traffic_class_and_flow_label =
9022     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9023
9024   if (payload_length)
9025     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9026
9027   if (hop_limit)
9028     ip->hop_limit = hop_limit_val;
9029
9030   *matchp = match;
9031   return 1;
9032 }
9033
9034 uword
9035 unformat_l3_match (unformat_input_t * input, va_list * args)
9036 {
9037   u8 **matchp = va_arg (*args, u8 **);
9038
9039   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9040     {
9041       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9042         return 1;
9043       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9044         return 1;
9045       else
9046         break;
9047     }
9048   return 0;
9049 }
9050
9051 uword
9052 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9053 {
9054   u8 *tagp = va_arg (*args, u8 *);
9055   u32 tag;
9056
9057   if (unformat (input, "%d", &tag))
9058     {
9059       tagp[0] = (tag >> 8) & 0x0F;
9060       tagp[1] = tag & 0xFF;
9061       return 1;
9062     }
9063
9064   return 0;
9065 }
9066
9067 uword
9068 unformat_l2_match (unformat_input_t * input, va_list * args)
9069 {
9070   u8 **matchp = va_arg (*args, u8 **);
9071   u8 *match = 0;
9072   u8 src = 0;
9073   u8 src_val[6];
9074   u8 dst = 0;
9075   u8 dst_val[6];
9076   u8 proto = 0;
9077   u16 proto_val;
9078   u8 tag1 = 0;
9079   u8 tag1_val[2];
9080   u8 tag2 = 0;
9081   u8 tag2_val[2];
9082   int len = 14;
9083   u8 ignore_tag1 = 0;
9084   u8 ignore_tag2 = 0;
9085   u8 cos1 = 0;
9086   u8 cos2 = 0;
9087   u32 cos1_val = 0;
9088   u32 cos2_val = 0;
9089
9090   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9091     {
9092       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9093         src = 1;
9094       else
9095         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9096         dst = 1;
9097       else if (unformat (input, "proto %U",
9098                          unformat_ethernet_type_host_byte_order, &proto_val))
9099         proto = 1;
9100       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9101         tag1 = 1;
9102       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9103         tag2 = 1;
9104       else if (unformat (input, "ignore-tag1"))
9105         ignore_tag1 = 1;
9106       else if (unformat (input, "ignore-tag2"))
9107         ignore_tag2 = 1;
9108       else if (unformat (input, "cos1 %d", &cos1_val))
9109         cos1 = 1;
9110       else if (unformat (input, "cos2 %d", &cos2_val))
9111         cos2 = 1;
9112       else
9113         break;
9114     }
9115   if ((src + dst + proto + tag1 + tag2 +
9116        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9117     return 0;
9118
9119   if (tag1 || ignore_tag1 || cos1)
9120     len = 18;
9121   if (tag2 || ignore_tag2 || cos2)
9122     len = 22;
9123
9124   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9125
9126   if (dst)
9127     clib_memcpy (match, dst_val, 6);
9128
9129   if (src)
9130     clib_memcpy (match + 6, src_val, 6);
9131
9132   if (tag2)
9133     {
9134       /* inner vlan tag */
9135       match[19] = tag2_val[1];
9136       match[18] = tag2_val[0];
9137       if (cos2)
9138         match[18] |= (cos2_val & 0x7) << 5;
9139       if (proto)
9140         {
9141           match[21] = proto_val & 0xff;
9142           match[20] = proto_val >> 8;
9143         }
9144       if (tag1)
9145         {
9146           match[15] = tag1_val[1];
9147           match[14] = tag1_val[0];
9148         }
9149       if (cos1)
9150         match[14] |= (cos1_val & 0x7) << 5;
9151       *matchp = match;
9152       return 1;
9153     }
9154   if (tag1)
9155     {
9156       match[15] = tag1_val[1];
9157       match[14] = tag1_val[0];
9158       if (proto)
9159         {
9160           match[17] = proto_val & 0xff;
9161           match[16] = proto_val >> 8;
9162         }
9163       if (cos1)
9164         match[14] |= (cos1_val & 0x7) << 5;
9165
9166       *matchp = match;
9167       return 1;
9168     }
9169   if (cos2)
9170     match[18] |= (cos2_val & 0x7) << 5;
9171   if (cos1)
9172     match[14] |= (cos1_val & 0x7) << 5;
9173   if (proto)
9174     {
9175       match[13] = proto_val & 0xff;
9176       match[12] = proto_val >> 8;
9177     }
9178
9179   *matchp = match;
9180   return 1;
9181 }
9182
9183
9184 uword
9185 unformat_classify_match (unformat_input_t * input, va_list * args)
9186 {
9187   u8 **matchp = va_arg (*args, u8 **);
9188   u32 skip_n_vectors = va_arg (*args, u32);
9189   u32 match_n_vectors = va_arg (*args, u32);
9190
9191   u8 *match = 0;
9192   u8 *l2 = 0;
9193   u8 *l3 = 0;
9194   u8 *l4 = 0;
9195
9196   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9197     {
9198       if (unformat (input, "hex %U", unformat_hex_string, &match))
9199         ;
9200       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9201         ;
9202       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9203         ;
9204       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9205         ;
9206       else
9207         break;
9208     }
9209
9210   if (l4 && !l3)
9211     {
9212       vec_free (match);
9213       vec_free (l2);
9214       vec_free (l4);
9215       return 0;
9216     }
9217
9218   if (match || l2 || l3 || l4)
9219     {
9220       if (l2 || l3 || l4)
9221         {
9222           /* "Win a free Ethernet header in every packet" */
9223           if (l2 == 0)
9224             vec_validate_aligned (l2, 13, sizeof (u32x4));
9225           match = l2;
9226           if (vec_len (l3))
9227             {
9228               vec_append_aligned (match, l3, sizeof (u32x4));
9229               vec_free (l3);
9230             }
9231           if (vec_len (l4))
9232             {
9233               vec_append_aligned (match, l4, sizeof (u32x4));
9234               vec_free (l4);
9235             }
9236         }
9237
9238       /* Make sure the vector is big enough even if key is all 0's */
9239       vec_validate_aligned
9240         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9241          sizeof (u32x4));
9242
9243       /* Set size, include skipped vectors */
9244       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9245
9246       *matchp = match;
9247
9248       return 1;
9249     }
9250
9251   return 0;
9252 }
9253
9254 static int
9255 api_classify_add_del_session (vat_main_t * vam)
9256 {
9257   unformat_input_t *i = vam->input;
9258   vl_api_classify_add_del_session_t *mp;
9259   int is_add = 1;
9260   u32 table_index = ~0;
9261   u32 hit_next_index = ~0;
9262   u32 opaque_index = ~0;
9263   u8 *match = 0;
9264   i32 advance = 0;
9265   f64 timeout;
9266   u32 skip_n_vectors = 0;
9267   u32 match_n_vectors = 0;
9268   u32 action = 0;
9269   u32 metadata = 0;
9270
9271   /*
9272    * Warning: you have to supply skip_n and match_n
9273    * because the API client cant simply look at the classify
9274    * table object.
9275    */
9276
9277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9278     {
9279       if (unformat (i, "del"))
9280         is_add = 0;
9281       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9282                          &hit_next_index))
9283         ;
9284       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9285                          &hit_next_index))
9286         ;
9287       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9288                          &hit_next_index))
9289         ;
9290       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9291         ;
9292       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9293         ;
9294       else if (unformat (i, "opaque-index %d", &opaque_index))
9295         ;
9296       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9297         ;
9298       else if (unformat (i, "match_n %d", &match_n_vectors))
9299         ;
9300       else if (unformat (i, "match %U", unformat_classify_match,
9301                          &match, skip_n_vectors, match_n_vectors))
9302         ;
9303       else if (unformat (i, "advance %d", &advance))
9304         ;
9305       else if (unformat (i, "table-index %d", &table_index))
9306         ;
9307       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9308         action = 1;
9309       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9310         action = 2;
9311       else if (unformat (i, "action %d", &action))
9312         ;
9313       else if (unformat (i, "metadata %d", &metadata))
9314         ;
9315       else
9316         break;
9317     }
9318
9319   if (table_index == ~0)
9320     {
9321       errmsg ("Table index required\n");
9322       return -99;
9323     }
9324
9325   if (is_add && match == 0)
9326     {
9327       errmsg ("Match value required\n");
9328       return -99;
9329     }
9330
9331   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9332
9333   mp->is_add = is_add;
9334   mp->table_index = ntohl (table_index);
9335   mp->hit_next_index = ntohl (hit_next_index);
9336   mp->opaque_index = ntohl (opaque_index);
9337   mp->advance = ntohl (advance);
9338   mp->action = action;
9339   mp->metadata = ntohl (metadata);
9340   clib_memcpy (mp->match, match, vec_len (match));
9341   vec_free (match);
9342
9343   S;
9344   W;
9345   /* NOTREACHED */
9346 }
9347
9348 static int
9349 api_classify_set_interface_ip_table (vat_main_t * vam)
9350 {
9351   unformat_input_t *i = vam->input;
9352   vl_api_classify_set_interface_ip_table_t *mp;
9353   f64 timeout;
9354   u32 sw_if_index;
9355   int sw_if_index_set;
9356   u32 table_index = ~0;
9357   u8 is_ipv6 = 0;
9358
9359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9360     {
9361       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9362         sw_if_index_set = 1;
9363       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9364         sw_if_index_set = 1;
9365       else if (unformat (i, "table %d", &table_index))
9366         ;
9367       else
9368         {
9369           clib_warning ("parse error '%U'", format_unformat_error, i);
9370           return -99;
9371         }
9372     }
9373
9374   if (sw_if_index_set == 0)
9375     {
9376       errmsg ("missing interface name or sw_if_index\n");
9377       return -99;
9378     }
9379
9380
9381   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9382
9383   mp->sw_if_index = ntohl (sw_if_index);
9384   mp->table_index = ntohl (table_index);
9385   mp->is_ipv6 = is_ipv6;
9386
9387   S;
9388   W;
9389   /* NOTREACHED */
9390   return 0;
9391 }
9392
9393 static int
9394 api_classify_set_interface_l2_tables (vat_main_t * vam)
9395 {
9396   unformat_input_t *i = vam->input;
9397   vl_api_classify_set_interface_l2_tables_t *mp;
9398   f64 timeout;
9399   u32 sw_if_index;
9400   int sw_if_index_set;
9401   u32 ip4_table_index = ~0;
9402   u32 ip6_table_index = ~0;
9403   u32 other_table_index = ~0;
9404   u32 is_input = 1;
9405
9406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9407     {
9408       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9409         sw_if_index_set = 1;
9410       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9411         sw_if_index_set = 1;
9412       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9413         ;
9414       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9415         ;
9416       else if (unformat (i, "other-table %d", &other_table_index))
9417         ;
9418       else if (unformat (i, "is-input %d", &is_input))
9419         ;
9420       else
9421         {
9422           clib_warning ("parse error '%U'", format_unformat_error, i);
9423           return -99;
9424         }
9425     }
9426
9427   if (sw_if_index_set == 0)
9428     {
9429       errmsg ("missing interface name or sw_if_index\n");
9430       return -99;
9431     }
9432
9433
9434   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9435
9436   mp->sw_if_index = ntohl (sw_if_index);
9437   mp->ip4_table_index = ntohl (ip4_table_index);
9438   mp->ip6_table_index = ntohl (ip6_table_index);
9439   mp->other_table_index = ntohl (other_table_index);
9440   mp->is_input = (u8) is_input;
9441
9442   S;
9443   W;
9444   /* NOTREACHED */
9445   return 0;
9446 }
9447
9448 static int
9449 api_set_ipfix_exporter (vat_main_t * vam)
9450 {
9451   unformat_input_t *i = vam->input;
9452   vl_api_set_ipfix_exporter_t *mp;
9453   ip4_address_t collector_address;
9454   u8 collector_address_set = 0;
9455   u32 collector_port = ~0;
9456   ip4_address_t src_address;
9457   u8 src_address_set = 0;
9458   u32 vrf_id = ~0;
9459   u32 path_mtu = ~0;
9460   u32 template_interval = ~0;
9461   u8 udp_checksum = 0;
9462   f64 timeout;
9463
9464   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9465     {
9466       if (unformat (i, "collector_address %U", unformat_ip4_address,
9467                     &collector_address))
9468         collector_address_set = 1;
9469       else if (unformat (i, "collector_port %d", &collector_port))
9470         ;
9471       else if (unformat (i, "src_address %U", unformat_ip4_address,
9472                          &src_address))
9473         src_address_set = 1;
9474       else if (unformat (i, "vrf_id %d", &vrf_id))
9475         ;
9476       else if (unformat (i, "path_mtu %d", &path_mtu))
9477         ;
9478       else if (unformat (i, "template_interval %d", &template_interval))
9479         ;
9480       else if (unformat (i, "udp_checksum"))
9481         udp_checksum = 1;
9482       else
9483         break;
9484     }
9485
9486   if (collector_address_set == 0)
9487     {
9488       errmsg ("collector_address required\n");
9489       return -99;
9490     }
9491
9492   if (src_address_set == 0)
9493     {
9494       errmsg ("src_address required\n");
9495       return -99;
9496     }
9497
9498   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9499
9500   memcpy (mp->collector_address, collector_address.data,
9501           sizeof (collector_address.data));
9502   mp->collector_port = htons ((u16) collector_port);
9503   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9504   mp->vrf_id = htonl (vrf_id);
9505   mp->path_mtu = htonl (path_mtu);
9506   mp->template_interval = htonl (template_interval);
9507   mp->udp_checksum = udp_checksum;
9508
9509   S;
9510   W;
9511   /* NOTREACHED */
9512 }
9513
9514 static int
9515 api_set_ipfix_classify_stream (vat_main_t * vam)
9516 {
9517   unformat_input_t *i = vam->input;
9518   vl_api_set_ipfix_classify_stream_t *mp;
9519   u32 domain_id = 0;
9520   u32 src_port = UDP_DST_PORT_ipfix;
9521   f64 timeout;
9522
9523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9524     {
9525       if (unformat (i, "domain %d", &domain_id))
9526         ;
9527       else if (unformat (i, "src_port %d", &src_port))
9528         ;
9529       else
9530         {
9531           errmsg ("unknown input `%U'", format_unformat_error, i);
9532           return -99;
9533         }
9534     }
9535
9536   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9537
9538   mp->domain_id = htonl (domain_id);
9539   mp->src_port = htons ((u16) src_port);
9540
9541   S;
9542   W;
9543   /* NOTREACHED */
9544 }
9545
9546 static int
9547 api_ipfix_classify_table_add_del (vat_main_t * vam)
9548 {
9549   unformat_input_t *i = vam->input;
9550   vl_api_ipfix_classify_table_add_del_t *mp;
9551   int is_add = -1;
9552   u32 classify_table_index = ~0;
9553   u8 ip_version = 0;
9554   u8 transport_protocol = 255;
9555   f64 timeout;
9556
9557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9558     {
9559       if (unformat (i, "add"))
9560         is_add = 1;
9561       else if (unformat (i, "del"))
9562         is_add = 0;
9563       else if (unformat (i, "table %d", &classify_table_index))
9564         ;
9565       else if (unformat (i, "ip4"))
9566         ip_version = 4;
9567       else if (unformat (i, "ip6"))
9568         ip_version = 6;
9569       else if (unformat (i, "tcp"))
9570         transport_protocol = 6;
9571       else if (unformat (i, "udp"))
9572         transport_protocol = 17;
9573       else
9574         {
9575           errmsg ("unknown input `%U'", format_unformat_error, i);
9576           return -99;
9577         }
9578     }
9579
9580   if (is_add == -1)
9581     {
9582       errmsg ("expecting: add|del");
9583       return -99;
9584     }
9585   if (classify_table_index == ~0)
9586     {
9587       errmsg ("classifier table not specified");
9588       return -99;
9589     }
9590   if (ip_version == 0)
9591     {
9592       errmsg ("IP version not specified");
9593       return -99;
9594     }
9595
9596   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9597
9598   mp->is_add = is_add;
9599   mp->table_id = htonl (classify_table_index);
9600   mp->ip_version = ip_version;
9601   mp->transport_protocol = transport_protocol;
9602
9603   S;
9604   W;
9605   /* NOTREACHED */
9606 }
9607
9608 static int
9609 api_get_node_index (vat_main_t * vam)
9610 {
9611   unformat_input_t *i = vam->input;
9612   vl_api_get_node_index_t *mp;
9613   f64 timeout;
9614   u8 *name = 0;
9615
9616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9617     {
9618       if (unformat (i, "node %s", &name))
9619         ;
9620       else
9621         break;
9622     }
9623   if (name == 0)
9624     {
9625       errmsg ("node name required\n");
9626       return -99;
9627     }
9628   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9629     {
9630       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9631       return -99;
9632     }
9633
9634   M (GET_NODE_INDEX, get_node_index);
9635   clib_memcpy (mp->node_name, name, vec_len (name));
9636   vec_free (name);
9637
9638   S;
9639   W;
9640   /* NOTREACHED */
9641   return 0;
9642 }
9643
9644 static int
9645 api_get_next_index (vat_main_t * vam)
9646 {
9647   unformat_input_t *i = vam->input;
9648   vl_api_get_next_index_t *mp;
9649   f64 timeout;
9650   u8 *node_name = 0, *next_node_name = 0;
9651
9652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9653     {
9654       if (unformat (i, "node-name %s", &node_name))
9655         ;
9656       else if (unformat (i, "next-node-name %s", &next_node_name))
9657         break;
9658     }
9659
9660   if (node_name == 0)
9661     {
9662       errmsg ("node name required\n");
9663       return -99;
9664     }
9665   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9666     {
9667       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9668       return -99;
9669     }
9670
9671   if (next_node_name == 0)
9672     {
9673       errmsg ("next node name required\n");
9674       return -99;
9675     }
9676   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9677     {
9678       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9679       return -99;
9680     }
9681
9682   M (GET_NEXT_INDEX, get_next_index);
9683   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9684   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9685   vec_free (node_name);
9686   vec_free (next_node_name);
9687
9688   S;
9689   W;
9690   /* NOTREACHED */
9691   return 0;
9692 }
9693
9694 static int
9695 api_add_node_next (vat_main_t * vam)
9696 {
9697   unformat_input_t *i = vam->input;
9698   vl_api_add_node_next_t *mp;
9699   f64 timeout;
9700   u8 *name = 0;
9701   u8 *next = 0;
9702
9703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9704     {
9705       if (unformat (i, "node %s", &name))
9706         ;
9707       else if (unformat (i, "next %s", &next))
9708         ;
9709       else
9710         break;
9711     }
9712   if (name == 0)
9713     {
9714       errmsg ("node name required\n");
9715       return -99;
9716     }
9717   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9718     {
9719       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9720       return -99;
9721     }
9722   if (next == 0)
9723     {
9724       errmsg ("next node required\n");
9725       return -99;
9726     }
9727   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9728     {
9729       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9730       return -99;
9731     }
9732
9733   M (ADD_NODE_NEXT, add_node_next);
9734   clib_memcpy (mp->node_name, name, vec_len (name));
9735   clib_memcpy (mp->next_name, next, vec_len (next));
9736   vec_free (name);
9737   vec_free (next);
9738
9739   S;
9740   W;
9741   /* NOTREACHED */
9742   return 0;
9743 }
9744
9745 static int
9746 api_l2tpv3_create_tunnel (vat_main_t * vam)
9747 {
9748   unformat_input_t *i = vam->input;
9749   ip6_address_t client_address, our_address;
9750   int client_address_set = 0;
9751   int our_address_set = 0;
9752   u32 local_session_id = 0;
9753   u32 remote_session_id = 0;
9754   u64 local_cookie = 0;
9755   u64 remote_cookie = 0;
9756   u8 l2_sublayer_present = 0;
9757   vl_api_l2tpv3_create_tunnel_t *mp;
9758   f64 timeout;
9759
9760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9761     {
9762       if (unformat (i, "client_address %U", unformat_ip6_address,
9763                     &client_address))
9764         client_address_set = 1;
9765       else if (unformat (i, "our_address %U", unformat_ip6_address,
9766                          &our_address))
9767         our_address_set = 1;
9768       else if (unformat (i, "local_session_id %d", &local_session_id))
9769         ;
9770       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9771         ;
9772       else if (unformat (i, "local_cookie %lld", &local_cookie))
9773         ;
9774       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9775         ;
9776       else if (unformat (i, "l2-sublayer-present"))
9777         l2_sublayer_present = 1;
9778       else
9779         break;
9780     }
9781
9782   if (client_address_set == 0)
9783     {
9784       errmsg ("client_address required\n");
9785       return -99;
9786     }
9787
9788   if (our_address_set == 0)
9789     {
9790       errmsg ("our_address required\n");
9791       return -99;
9792     }
9793
9794   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9795
9796   clib_memcpy (mp->client_address, client_address.as_u8,
9797                sizeof (mp->client_address));
9798
9799   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9800
9801   mp->local_session_id = ntohl (local_session_id);
9802   mp->remote_session_id = ntohl (remote_session_id);
9803   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9804   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9805   mp->l2_sublayer_present = l2_sublayer_present;
9806   mp->is_ipv6 = 1;
9807
9808   S;
9809   W;
9810   /* NOTREACHED */
9811   return 0;
9812 }
9813
9814 static int
9815 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9816 {
9817   unformat_input_t *i = vam->input;
9818   u32 sw_if_index;
9819   u8 sw_if_index_set = 0;
9820   u64 new_local_cookie = 0;
9821   u64 new_remote_cookie = 0;
9822   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9823   f64 timeout;
9824
9825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9826     {
9827       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9828         sw_if_index_set = 1;
9829       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9830         sw_if_index_set = 1;
9831       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9832         ;
9833       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
9834         ;
9835       else
9836         break;
9837     }
9838
9839   if (sw_if_index_set == 0)
9840     {
9841       errmsg ("missing interface name or sw_if_index\n");
9842       return -99;
9843     }
9844
9845   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
9846
9847   mp->sw_if_index = ntohl (sw_if_index);
9848   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
9849   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
9850
9851   S;
9852   W;
9853   /* NOTREACHED */
9854   return 0;
9855 }
9856
9857 static int
9858 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
9859 {
9860   unformat_input_t *i = vam->input;
9861   vl_api_l2tpv3_interface_enable_disable_t *mp;
9862   f64 timeout;
9863   u32 sw_if_index;
9864   u8 sw_if_index_set = 0;
9865   u8 enable_disable = 1;
9866
9867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9868     {
9869       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9870         sw_if_index_set = 1;
9871       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9872         sw_if_index_set = 1;
9873       else if (unformat (i, "enable"))
9874         enable_disable = 1;
9875       else if (unformat (i, "disable"))
9876         enable_disable = 0;
9877       else
9878         break;
9879     }
9880
9881   if (sw_if_index_set == 0)
9882     {
9883       errmsg ("missing interface name or sw_if_index\n");
9884       return -99;
9885     }
9886
9887   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
9888
9889   mp->sw_if_index = ntohl (sw_if_index);
9890   mp->enable_disable = enable_disable;
9891
9892   S;
9893   W;
9894   /* NOTREACHED */
9895   return 0;
9896 }
9897
9898 static int
9899 api_l2tpv3_set_lookup_key (vat_main_t * vam)
9900 {
9901   unformat_input_t *i = vam->input;
9902   vl_api_l2tpv3_set_lookup_key_t *mp;
9903   f64 timeout;
9904   u8 key = ~0;
9905
9906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9907     {
9908       if (unformat (i, "lookup_v6_src"))
9909         key = L2T_LOOKUP_SRC_ADDRESS;
9910       else if (unformat (i, "lookup_v6_dst"))
9911         key = L2T_LOOKUP_DST_ADDRESS;
9912       else if (unformat (i, "lookup_session_id"))
9913         key = L2T_LOOKUP_SESSION_ID;
9914       else
9915         break;
9916     }
9917
9918   if (key == (u8) ~ 0)
9919     {
9920       errmsg ("l2tp session lookup key unset\n");
9921       return -99;
9922     }
9923
9924   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
9925
9926   mp->key = key;
9927
9928   S;
9929   W;
9930   /* NOTREACHED */
9931   return 0;
9932 }
9933
9934 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
9935   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9936 {
9937   vat_main_t *vam = &vat_main;
9938
9939   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
9940            format_ip6_address, mp->our_address,
9941            format_ip6_address, mp->client_address,
9942            clib_net_to_host_u32 (mp->sw_if_index));
9943
9944   fformat (vam->ofp,
9945            "   local cookies %016llx %016llx remote cookie %016llx\n",
9946            clib_net_to_host_u64 (mp->local_cookie[0]),
9947            clib_net_to_host_u64 (mp->local_cookie[1]),
9948            clib_net_to_host_u64 (mp->remote_cookie));
9949
9950   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
9951            clib_net_to_host_u32 (mp->local_session_id),
9952            clib_net_to_host_u32 (mp->remote_session_id));
9953
9954   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
9955            mp->l2_sublayer_present ? "preset" : "absent");
9956
9957 }
9958
9959 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
9960   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
9961 {
9962   vat_main_t *vam = &vat_main;
9963   vat_json_node_t *node = NULL;
9964   struct in6_addr addr;
9965
9966   if (VAT_JSON_ARRAY != vam->json_tree.type)
9967     {
9968       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9969       vat_json_init_array (&vam->json_tree);
9970     }
9971   node = vat_json_array_add (&vam->json_tree);
9972
9973   vat_json_init_object (node);
9974
9975   clib_memcpy (&addr, mp->our_address, sizeof (addr));
9976   vat_json_object_add_ip6 (node, "our_address", addr);
9977   clib_memcpy (&addr, mp->client_address, sizeof (addr));
9978   vat_json_object_add_ip6 (node, "client_address", addr);
9979
9980   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
9981   vat_json_init_array (lc);
9982   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
9983   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
9984   vat_json_object_add_uint (node, "remote_cookie",
9985                             clib_net_to_host_u64 (mp->remote_cookie));
9986
9987   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
9988   vat_json_object_add_uint (node, "local_session_id",
9989                             clib_net_to_host_u32 (mp->local_session_id));
9990   vat_json_object_add_uint (node, "remote_session_id",
9991                             clib_net_to_host_u32 (mp->remote_session_id));
9992   vat_json_object_add_string_copy (node, "l2_sublayer",
9993                                    mp->l2_sublayer_present ? (u8 *) "present"
9994                                    : (u8 *) "absent");
9995 }
9996
9997 static int
9998 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
9999 {
10000   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10001   f64 timeout;
10002
10003   /* Get list of l2tpv3-tunnel interfaces */
10004   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10005   S;
10006
10007   /* Use a control ping for synchronization */
10008   {
10009     vl_api_control_ping_t *mp;
10010     M (CONTROL_PING, control_ping);
10011     S;
10012   }
10013   W;
10014 }
10015
10016
10017 static void vl_api_sw_interface_tap_details_t_handler
10018   (vl_api_sw_interface_tap_details_t * mp)
10019 {
10020   vat_main_t *vam = &vat_main;
10021
10022   fformat (vam->ofp, "%-16s %d\n",
10023            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10024 }
10025
10026 static void vl_api_sw_interface_tap_details_t_handler_json
10027   (vl_api_sw_interface_tap_details_t * mp)
10028 {
10029   vat_main_t *vam = &vat_main;
10030   vat_json_node_t *node = NULL;
10031
10032   if (VAT_JSON_ARRAY != vam->json_tree.type)
10033     {
10034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10035       vat_json_init_array (&vam->json_tree);
10036     }
10037   node = vat_json_array_add (&vam->json_tree);
10038
10039   vat_json_init_object (node);
10040   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10041   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10042 }
10043
10044 static int
10045 api_sw_interface_tap_dump (vat_main_t * vam)
10046 {
10047   vl_api_sw_interface_tap_dump_t *mp;
10048   f64 timeout;
10049
10050   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10051   /* Get list of tap interfaces */
10052   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10053   S;
10054
10055   /* Use a control ping for synchronization */
10056   {
10057     vl_api_control_ping_t *mp;
10058     M (CONTROL_PING, control_ping);
10059     S;
10060   }
10061   W;
10062 }
10063
10064 static uword unformat_vxlan_decap_next
10065   (unformat_input_t * input, va_list * args)
10066 {
10067   u32 *result = va_arg (*args, u32 *);
10068   u32 tmp;
10069
10070   if (unformat (input, "l2"))
10071     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10072   else if (unformat (input, "%d", &tmp))
10073     *result = tmp;
10074   else
10075     return 0;
10076   return 1;
10077 }
10078
10079 static int
10080 api_vxlan_add_del_tunnel (vat_main_t * vam)
10081 {
10082   unformat_input_t *line_input = vam->input;
10083   vl_api_vxlan_add_del_tunnel_t *mp;
10084   f64 timeout;
10085   ip4_address_t src4, dst4;
10086   ip6_address_t src6, dst6;
10087   u8 is_add = 1;
10088   u8 ipv4_set = 0, ipv6_set = 0;
10089   u8 src_set = 0;
10090   u8 dst_set = 0;
10091   u32 encap_vrf_id = 0;
10092   u32 decap_next_index = ~0;
10093   u32 vni = 0;
10094
10095   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10096     {
10097       if (unformat (line_input, "del"))
10098         is_add = 0;
10099       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10100         {
10101           ipv4_set = 1;
10102           src_set = 1;
10103         }
10104       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10105         {
10106           ipv4_set = 1;
10107           dst_set = 1;
10108         }
10109       else if (unformat (line_input, "src %U", unformat_ip6_address, &src6))
10110         {
10111           ipv6_set = 1;
10112           src_set = 1;
10113         }
10114       else if (unformat (line_input, "dst %U", unformat_ip6_address, &dst6))
10115         {
10116           ipv6_set = 1;
10117           dst_set = 1;
10118         }
10119       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10120         ;
10121       else if (unformat (line_input, "decap-next %U",
10122                          unformat_vxlan_decap_next, &decap_next_index))
10123         ;
10124       else if (unformat (line_input, "vni %d", &vni))
10125         ;
10126       else
10127         {
10128           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10129           return -99;
10130         }
10131     }
10132
10133   if (src_set == 0)
10134     {
10135       errmsg ("tunnel src address not specified\n");
10136       return -99;
10137     }
10138   if (dst_set == 0)
10139     {
10140       errmsg ("tunnel dst address not specified\n");
10141       return -99;
10142     }
10143
10144   if (ipv4_set && ipv6_set)
10145     {
10146       errmsg ("both IPv4 and IPv6 addresses specified");
10147       return -99;
10148     }
10149
10150   if ((vni == 0) || (vni >> 24))
10151     {
10152       errmsg ("vni not specified or out of range\n");
10153       return -99;
10154     }
10155
10156   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10157
10158   if (ipv6_set)
10159     {
10160       clib_memcpy (&mp->src_address, &src6, sizeof (src6));
10161       clib_memcpy (&mp->dst_address, &dst6, sizeof (dst6));
10162     }
10163   else
10164     {
10165       clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10166       clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10167     }
10168   mp->encap_vrf_id = ntohl (encap_vrf_id);
10169   mp->decap_next_index = ntohl (decap_next_index);
10170   mp->vni = ntohl (vni);
10171   mp->is_add = is_add;
10172   mp->is_ipv6 = ipv6_set;
10173
10174   S;
10175   W;
10176   /* NOTREACHED */
10177   return 0;
10178 }
10179
10180 static void vl_api_vxlan_tunnel_details_t_handler
10181   (vl_api_vxlan_tunnel_details_t * mp)
10182 {
10183   vat_main_t *vam = &vat_main;
10184
10185   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d\n",
10186            ntohl (mp->sw_if_index),
10187            format_ip46_address, &(mp->src_address[0]),
10188            IP46_TYPE_ANY,
10189            format_ip46_address, &(mp->dst_address[0]),
10190            IP46_TYPE_ANY,
10191            ntohl (mp->encap_vrf_id),
10192            ntohl (mp->decap_next_index), ntohl (mp->vni));
10193 }
10194
10195 static void vl_api_vxlan_tunnel_details_t_handler_json
10196   (vl_api_vxlan_tunnel_details_t * mp)
10197 {
10198   vat_main_t *vam = &vat_main;
10199   vat_json_node_t *node = NULL;
10200   struct in_addr ip4;
10201   struct in6_addr ip6;
10202
10203   if (VAT_JSON_ARRAY != vam->json_tree.type)
10204     {
10205       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10206       vat_json_init_array (&vam->json_tree);
10207     }
10208   node = vat_json_array_add (&vam->json_tree);
10209
10210   vat_json_init_object (node);
10211   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10212   if (mp->is_ipv6)
10213     {
10214       clib_memcpy (&ip6, &(mp->src_address[0]), sizeof (ip6));
10215       vat_json_object_add_ip6 (node, "src_address", ip6);
10216       clib_memcpy (&ip6, &(mp->dst_address[0]), sizeof (ip6));
10217       vat_json_object_add_ip6 (node, "dst_address", ip6);
10218     }
10219   else
10220     {
10221       clib_memcpy (&ip4, &(mp->src_address[0]), sizeof (ip4));
10222       vat_json_object_add_ip4 (node, "src_address", ip4);
10223       clib_memcpy (&ip4, &(mp->dst_address[0]), sizeof (ip4));
10224       vat_json_object_add_ip4 (node, "dst_address", ip4);
10225     }
10226   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10227   vat_json_object_add_uint (node, "decap_next_index",
10228                             ntohl (mp->decap_next_index));
10229   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10230   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10231 }
10232
10233 static int
10234 api_vxlan_tunnel_dump (vat_main_t * vam)
10235 {
10236   unformat_input_t *i = vam->input;
10237   vl_api_vxlan_tunnel_dump_t *mp;
10238   f64 timeout;
10239   u32 sw_if_index;
10240   u8 sw_if_index_set = 0;
10241
10242   /* Parse args required to build the message */
10243   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10244     {
10245       if (unformat (i, "sw_if_index %d", &sw_if_index))
10246         sw_if_index_set = 1;
10247       else
10248         break;
10249     }
10250
10251   if (sw_if_index_set == 0)
10252     {
10253       sw_if_index = ~0;
10254     }
10255
10256   if (!vam->json_output)
10257     {
10258       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s\n",
10259                "sw_if_index", "src_address", "dst_address",
10260                "encap_vrf_id", "decap_next_index", "vni");
10261     }
10262
10263   /* Get list of vxlan-tunnel interfaces */
10264   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10265
10266   mp->sw_if_index = htonl (sw_if_index);
10267
10268   S;
10269
10270   /* Use a control ping for synchronization */
10271   {
10272     vl_api_control_ping_t *mp;
10273     M (CONTROL_PING, control_ping);
10274     S;
10275   }
10276   W;
10277 }
10278
10279 static int
10280 api_gre_add_del_tunnel (vat_main_t * vam)
10281 {
10282   unformat_input_t *line_input = vam->input;
10283   vl_api_gre_add_del_tunnel_t *mp;
10284   f64 timeout;
10285   ip4_address_t src4, dst4;
10286   u8 is_add = 1;
10287   u8 teb = 0;
10288   u8 src_set = 0;
10289   u8 dst_set = 0;
10290   u32 outer_fib_id = 0;
10291
10292   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10293     {
10294       if (unformat (line_input, "del"))
10295         is_add = 0;
10296       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10297         src_set = 1;
10298       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10299         dst_set = 1;
10300       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10301         ;
10302       else if (unformat (line_input, "teb"))
10303         teb = 1;
10304       else
10305         {
10306           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10307           return -99;
10308         }
10309     }
10310
10311   if (src_set == 0)
10312     {
10313       errmsg ("tunnel src address not specified\n");
10314       return -99;
10315     }
10316   if (dst_set == 0)
10317     {
10318       errmsg ("tunnel dst address not specified\n");
10319       return -99;
10320     }
10321
10322
10323   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10324
10325   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10326   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10327   mp->outer_fib_id = ntohl (outer_fib_id);
10328   mp->is_add = is_add;
10329   mp->teb = teb;
10330
10331   S;
10332   W;
10333   /* NOTREACHED */
10334   return 0;
10335 }
10336
10337 static void vl_api_gre_tunnel_details_t_handler
10338   (vl_api_gre_tunnel_details_t * mp)
10339 {
10340   vat_main_t *vam = &vat_main;
10341
10342   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10343            ntohl (mp->sw_if_index),
10344            format_ip4_address, &mp->src_address,
10345            format_ip4_address, &mp->dst_address,
10346            mp->teb, ntohl (mp->outer_fib_id));
10347 }
10348
10349 static void vl_api_gre_tunnel_details_t_handler_json
10350   (vl_api_gre_tunnel_details_t * mp)
10351 {
10352   vat_main_t *vam = &vat_main;
10353   vat_json_node_t *node = NULL;
10354   struct in_addr ip4;
10355
10356   if (VAT_JSON_ARRAY != vam->json_tree.type)
10357     {
10358       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10359       vat_json_init_array (&vam->json_tree);
10360     }
10361   node = vat_json_array_add (&vam->json_tree);
10362
10363   vat_json_init_object (node);
10364   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10365   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10366   vat_json_object_add_ip4 (node, "src_address", ip4);
10367   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10368   vat_json_object_add_ip4 (node, "dst_address", ip4);
10369   vat_json_object_add_uint (node, "teb", mp->teb);
10370   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10371 }
10372
10373 static int
10374 api_gre_tunnel_dump (vat_main_t * vam)
10375 {
10376   unformat_input_t *i = vam->input;
10377   vl_api_gre_tunnel_dump_t *mp;
10378   f64 timeout;
10379   u32 sw_if_index;
10380   u8 sw_if_index_set = 0;
10381
10382   /* Parse args required to build the message */
10383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10384     {
10385       if (unformat (i, "sw_if_index %d", &sw_if_index))
10386         sw_if_index_set = 1;
10387       else
10388         break;
10389     }
10390
10391   if (sw_if_index_set == 0)
10392     {
10393       sw_if_index = ~0;
10394     }
10395
10396   if (!vam->json_output)
10397     {
10398       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10399                "sw_if_index", "src_address", "dst_address", "teb",
10400                "outer_fib_id");
10401     }
10402
10403   /* Get list of gre-tunnel interfaces */
10404   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10405
10406   mp->sw_if_index = htonl (sw_if_index);
10407
10408   S;
10409
10410   /* Use a control ping for synchronization */
10411   {
10412     vl_api_control_ping_t *mp;
10413     M (CONTROL_PING, control_ping);
10414     S;
10415   }
10416   W;
10417 }
10418
10419 static int
10420 api_l2_fib_clear_table (vat_main_t * vam)
10421 {
10422 //  unformat_input_t * i = vam->input;
10423   vl_api_l2_fib_clear_table_t *mp;
10424   f64 timeout;
10425
10426   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10427
10428   S;
10429   W;
10430   /* NOTREACHED */
10431   return 0;
10432 }
10433
10434 static int
10435 api_l2_interface_efp_filter (vat_main_t * vam)
10436 {
10437   unformat_input_t *i = vam->input;
10438   vl_api_l2_interface_efp_filter_t *mp;
10439   f64 timeout;
10440   u32 sw_if_index;
10441   u8 enable = 1;
10442   u8 sw_if_index_set = 0;
10443
10444   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10445     {
10446       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10447         sw_if_index_set = 1;
10448       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10449         sw_if_index_set = 1;
10450       else if (unformat (i, "enable"))
10451         enable = 1;
10452       else if (unformat (i, "disable"))
10453         enable = 0;
10454       else
10455         {
10456           clib_warning ("parse error '%U'", format_unformat_error, i);
10457           return -99;
10458         }
10459     }
10460
10461   if (sw_if_index_set == 0)
10462     {
10463       errmsg ("missing sw_if_index\n");
10464       return -99;
10465     }
10466
10467   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10468
10469   mp->sw_if_index = ntohl (sw_if_index);
10470   mp->enable_disable = enable;
10471
10472   S;
10473   W;
10474   /* NOTREACHED */
10475   return 0;
10476 }
10477
10478 #define foreach_vtr_op                          \
10479 _("disable",  L2_VTR_DISABLED)                  \
10480 _("push-1",  L2_VTR_PUSH_1)                     \
10481 _("push-2",  L2_VTR_PUSH_2)                     \
10482 _("pop-1",  L2_VTR_POP_1)                       \
10483 _("pop-2",  L2_VTR_POP_2)                       \
10484 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10485 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10486 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10487 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10488
10489 static int
10490 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10491 {
10492   unformat_input_t *i = vam->input;
10493   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10494   f64 timeout;
10495   u32 sw_if_index;
10496   u8 sw_if_index_set = 0;
10497   u8 vtr_op_set = 0;
10498   u32 vtr_op = 0;
10499   u32 push_dot1q = 1;
10500   u32 tag1 = ~0;
10501   u32 tag2 = ~0;
10502
10503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10504     {
10505       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10506         sw_if_index_set = 1;
10507       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10508         sw_if_index_set = 1;
10509       else if (unformat (i, "vtr_op %d", &vtr_op))
10510         vtr_op_set = 1;
10511 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10512       foreach_vtr_op
10513 #undef _
10514         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10515         ;
10516       else if (unformat (i, "tag1 %d", &tag1))
10517         ;
10518       else if (unformat (i, "tag2 %d", &tag2))
10519         ;
10520       else
10521         {
10522           clib_warning ("parse error '%U'", format_unformat_error, i);
10523           return -99;
10524         }
10525     }
10526
10527   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10528     {
10529       errmsg ("missing vtr operation or sw_if_index\n");
10530       return -99;
10531     }
10532
10533   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10534     mp->sw_if_index = ntohl (sw_if_index);
10535   mp->vtr_op = ntohl (vtr_op);
10536   mp->push_dot1q = ntohl (push_dot1q);
10537   mp->tag1 = ntohl (tag1);
10538   mp->tag2 = ntohl (tag2);
10539
10540   S;
10541   W;
10542   /* NOTREACHED */
10543   return 0;
10544 }
10545
10546 static int
10547 api_create_vhost_user_if (vat_main_t * vam)
10548 {
10549   unformat_input_t *i = vam->input;
10550   vl_api_create_vhost_user_if_t *mp;
10551   f64 timeout;
10552   u8 *file_name;
10553   u8 is_server = 0;
10554   u8 file_name_set = 0;
10555   u32 custom_dev_instance = ~0;
10556   u8 hwaddr[6];
10557   u8 use_custom_mac = 0;
10558
10559   /* Shut up coverity */
10560   memset (hwaddr, 0, sizeof (hwaddr));
10561
10562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10563     {
10564       if (unformat (i, "socket %s", &file_name))
10565         {
10566           file_name_set = 1;
10567         }
10568       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10569         ;
10570       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10571         use_custom_mac = 1;
10572       else if (unformat (i, "server"))
10573         is_server = 1;
10574       else
10575         break;
10576     }
10577
10578   if (file_name_set == 0)
10579     {
10580       errmsg ("missing socket file name\n");
10581       return -99;
10582     }
10583
10584   if (vec_len (file_name) > 255)
10585     {
10586       errmsg ("socket file name too long\n");
10587       return -99;
10588     }
10589   vec_add1 (file_name, 0);
10590
10591   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10592
10593   mp->is_server = is_server;
10594   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10595   vec_free (file_name);
10596   if (custom_dev_instance != ~0)
10597     {
10598       mp->renumber = 1;
10599       mp->custom_dev_instance = ntohl (custom_dev_instance);
10600     }
10601   mp->use_custom_mac = use_custom_mac;
10602   clib_memcpy (mp->mac_address, hwaddr, 6);
10603
10604   S;
10605   W;
10606   /* NOTREACHED */
10607   return 0;
10608 }
10609
10610 static int
10611 api_modify_vhost_user_if (vat_main_t * vam)
10612 {
10613   unformat_input_t *i = vam->input;
10614   vl_api_modify_vhost_user_if_t *mp;
10615   f64 timeout;
10616   u8 *file_name;
10617   u8 is_server = 0;
10618   u8 file_name_set = 0;
10619   u32 custom_dev_instance = ~0;
10620   u8 sw_if_index_set = 0;
10621   u32 sw_if_index = (u32) ~ 0;
10622
10623   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10624     {
10625       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10626         sw_if_index_set = 1;
10627       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10628         sw_if_index_set = 1;
10629       else if (unformat (i, "socket %s", &file_name))
10630         {
10631           file_name_set = 1;
10632         }
10633       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10634         ;
10635       else if (unformat (i, "server"))
10636         is_server = 1;
10637       else
10638         break;
10639     }
10640
10641   if (sw_if_index_set == 0)
10642     {
10643       errmsg ("missing sw_if_index or interface name\n");
10644       return -99;
10645     }
10646
10647   if (file_name_set == 0)
10648     {
10649       errmsg ("missing socket file name\n");
10650       return -99;
10651     }
10652
10653   if (vec_len (file_name) > 255)
10654     {
10655       errmsg ("socket file name too long\n");
10656       return -99;
10657     }
10658   vec_add1 (file_name, 0);
10659
10660   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10661
10662   mp->sw_if_index = ntohl (sw_if_index);
10663   mp->is_server = is_server;
10664   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10665   vec_free (file_name);
10666   if (custom_dev_instance != ~0)
10667     {
10668       mp->renumber = 1;
10669       mp->custom_dev_instance = ntohl (custom_dev_instance);
10670     }
10671
10672   S;
10673   W;
10674   /* NOTREACHED */
10675   return 0;
10676 }
10677
10678 static int
10679 api_delete_vhost_user_if (vat_main_t * vam)
10680 {
10681   unformat_input_t *i = vam->input;
10682   vl_api_delete_vhost_user_if_t *mp;
10683   f64 timeout;
10684   u32 sw_if_index = ~0;
10685   u8 sw_if_index_set = 0;
10686
10687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10688     {
10689       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10690         sw_if_index_set = 1;
10691       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10692         sw_if_index_set = 1;
10693       else
10694         break;
10695     }
10696
10697   if (sw_if_index_set == 0)
10698     {
10699       errmsg ("missing sw_if_index or interface name\n");
10700       return -99;
10701     }
10702
10703
10704   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10705
10706   mp->sw_if_index = ntohl (sw_if_index);
10707
10708   S;
10709   W;
10710   /* NOTREACHED */
10711   return 0;
10712 }
10713
10714 static void vl_api_sw_interface_vhost_user_details_t_handler
10715   (vl_api_sw_interface_vhost_user_details_t * mp)
10716 {
10717   vat_main_t *vam = &vat_main;
10718
10719   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10720            (char *) mp->interface_name,
10721            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10722            clib_net_to_host_u64 (mp->features), mp->is_server,
10723            ntohl (mp->num_regions), (char *) mp->sock_filename);
10724   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10725 }
10726
10727 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10728   (vl_api_sw_interface_vhost_user_details_t * mp)
10729 {
10730   vat_main_t *vam = &vat_main;
10731   vat_json_node_t *node = NULL;
10732
10733   if (VAT_JSON_ARRAY != vam->json_tree.type)
10734     {
10735       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10736       vat_json_init_array (&vam->json_tree);
10737     }
10738   node = vat_json_array_add (&vam->json_tree);
10739
10740   vat_json_init_object (node);
10741   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10742   vat_json_object_add_string_copy (node, "interface_name",
10743                                    mp->interface_name);
10744   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10745                             ntohl (mp->virtio_net_hdr_sz));
10746   vat_json_object_add_uint (node, "features",
10747                             clib_net_to_host_u64 (mp->features));
10748   vat_json_object_add_uint (node, "is_server", mp->is_server);
10749   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10750   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10751   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10752 }
10753
10754 static int
10755 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10756 {
10757   vl_api_sw_interface_vhost_user_dump_t *mp;
10758   f64 timeout;
10759   fformat (vam->ofp,
10760            "Interface name           idx hdr_sz features server regions filename\n");
10761
10762   /* Get list of vhost-user interfaces */
10763   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10764   S;
10765
10766   /* Use a control ping for synchronization */
10767   {
10768     vl_api_control_ping_t *mp;
10769     M (CONTROL_PING, control_ping);
10770     S;
10771   }
10772   W;
10773 }
10774
10775 static int
10776 api_show_version (vat_main_t * vam)
10777 {
10778   vl_api_show_version_t *mp;
10779   f64 timeout;
10780
10781   M (SHOW_VERSION, show_version);
10782
10783   S;
10784   W;
10785   /* NOTREACHED */
10786   return 0;
10787 }
10788
10789
10790 static int
10791 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10792 {
10793   unformat_input_t *line_input = vam->input;
10794   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10795   f64 timeout;
10796   ip4_address_t local4, remote4;
10797   ip6_address_t local6, remote6;
10798   u8 is_add = 1;
10799   u8 ipv4_set = 0, ipv6_set = 0;
10800   u8 local_set = 0;
10801   u8 remote_set = 0;
10802   u32 encap_vrf_id = 0;
10803   u32 decap_vrf_id = 0;
10804   u8 protocol = ~0;
10805   u32 vni;
10806   u8 vni_set = 0;
10807
10808   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10809     {
10810       if (unformat (line_input, "del"))
10811         is_add = 0;
10812       else if (unformat (line_input, "local %U",
10813                          unformat_ip4_address, &local4))
10814         {
10815           local_set = 1;
10816           ipv4_set = 1;
10817         }
10818       else if (unformat (line_input, "remote %U",
10819                          unformat_ip4_address, &remote4))
10820         {
10821           remote_set = 1;
10822           ipv4_set = 1;
10823         }
10824       else if (unformat (line_input, "local %U",
10825                          unformat_ip6_address, &local6))
10826         {
10827           local_set = 1;
10828           ipv6_set = 1;
10829         }
10830       else if (unformat (line_input, "remote %U",
10831                          unformat_ip6_address, &remote6))
10832         {
10833           remote_set = 1;
10834           ipv6_set = 1;
10835         }
10836       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10837         ;
10838       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10839         ;
10840       else if (unformat (line_input, "vni %d", &vni))
10841         vni_set = 1;
10842       else if (unformat (line_input, "next-ip4"))
10843         protocol = 1;
10844       else if (unformat (line_input, "next-ip6"))
10845         protocol = 2;
10846       else if (unformat (line_input, "next-ethernet"))
10847         protocol = 3;
10848       else if (unformat (line_input, "next-nsh"))
10849         protocol = 4;
10850       else
10851         {
10852           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10853           return -99;
10854         }
10855     }
10856
10857   if (local_set == 0)
10858     {
10859       errmsg ("tunnel local address not specified\n");
10860       return -99;
10861     }
10862   if (remote_set == 0)
10863     {
10864       errmsg ("tunnel remote address not specified\n");
10865       return -99;
10866     }
10867   if (ipv4_set && ipv6_set)
10868     {
10869       errmsg ("both IPv4 and IPv6 addresses specified");
10870       return -99;
10871     }
10872
10873   if (vni_set == 0)
10874     {
10875       errmsg ("vni not specified\n");
10876       return -99;
10877     }
10878
10879   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
10880
10881
10882   if (ipv6_set)
10883     {
10884       clib_memcpy (&mp->local, &local6, sizeof (local6));
10885       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
10886     }
10887   else
10888     {
10889       clib_memcpy (&mp->local, &local4, sizeof (local4));
10890       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
10891     }
10892
10893   mp->encap_vrf_id = ntohl (encap_vrf_id);
10894   mp->decap_vrf_id = ntohl (decap_vrf_id);
10895   mp->protocol = ntohl (protocol);
10896   mp->vni = ntohl (vni);
10897   mp->is_add = is_add;
10898   mp->is_ipv6 = ipv6_set;
10899
10900   S;
10901   W;
10902   /* NOTREACHED */
10903   return 0;
10904 }
10905
10906 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10907   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10908 {
10909   vat_main_t *vam = &vat_main;
10910
10911   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
10912            ntohl (mp->sw_if_index),
10913            format_ip46_address, &(mp->local[0]),
10914            format_ip46_address, &(mp->remote[0]),
10915            ntohl (mp->vni),
10916            ntohl (mp->protocol),
10917            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10918 }
10919
10920 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10921   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10922 {
10923   vat_main_t *vam = &vat_main;
10924   vat_json_node_t *node = NULL;
10925   struct in_addr ip4;
10926   struct in6_addr ip6;
10927
10928   if (VAT_JSON_ARRAY != vam->json_tree.type)
10929     {
10930       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10931       vat_json_init_array (&vam->json_tree);
10932     }
10933   node = vat_json_array_add (&vam->json_tree);
10934
10935   vat_json_init_object (node);
10936   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10937   if (mp->is_ipv6)
10938     {
10939       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
10940       vat_json_object_add_ip6 (node, "local", ip6);
10941       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
10942       vat_json_object_add_ip6 (node, "remote", ip6);
10943     }
10944   else
10945     {
10946       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
10947       vat_json_object_add_ip4 (node, "local", ip4);
10948       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
10949       vat_json_object_add_ip4 (node, "remote", ip4);
10950     }
10951   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10952   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10953   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10954   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10955   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10956 }
10957
10958 static int
10959 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10960 {
10961   unformat_input_t *i = vam->input;
10962   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10963   f64 timeout;
10964   u32 sw_if_index;
10965   u8 sw_if_index_set = 0;
10966
10967   /* Parse args required to build the message */
10968   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10969     {
10970       if (unformat (i, "sw_if_index %d", &sw_if_index))
10971         sw_if_index_set = 1;
10972       else
10973         break;
10974     }
10975
10976   if (sw_if_index_set == 0)
10977     {
10978       sw_if_index = ~0;
10979     }
10980
10981   if (!vam->json_output)
10982     {
10983       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
10984                "sw_if_index", "local", "remote", "vni",
10985                "protocol", "encap_vrf_id", "decap_vrf_id");
10986     }
10987
10988   /* Get list of vxlan-tunnel interfaces */
10989   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
10990
10991   mp->sw_if_index = htonl (sw_if_index);
10992
10993   S;
10994
10995   /* Use a control ping for synchronization */
10996   {
10997     vl_api_control_ping_t *mp;
10998     M (CONTROL_PING, control_ping);
10999     S;
11000   }
11001   W;
11002 }
11003
11004 u8 *
11005 format_l2_fib_mac_address (u8 * s, va_list * args)
11006 {
11007   u8 *a = va_arg (*args, u8 *);
11008
11009   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11010                  a[2], a[3], a[4], a[5], a[6], a[7]);
11011 }
11012
11013 static void vl_api_l2_fib_table_entry_t_handler
11014   (vl_api_l2_fib_table_entry_t * mp)
11015 {
11016   vat_main_t *vam = &vat_main;
11017
11018   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11019            "       %d       %d     %d\n",
11020            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11021            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11022            mp->bvi_mac);
11023 }
11024
11025 static void vl_api_l2_fib_table_entry_t_handler_json
11026   (vl_api_l2_fib_table_entry_t * mp)
11027 {
11028   vat_main_t *vam = &vat_main;
11029   vat_json_node_t *node = NULL;
11030
11031   if (VAT_JSON_ARRAY != vam->json_tree.type)
11032     {
11033       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11034       vat_json_init_array (&vam->json_tree);
11035     }
11036   node = vat_json_array_add (&vam->json_tree);
11037
11038   vat_json_init_object (node);
11039   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11040   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11041   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11042   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11043   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11044   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11045 }
11046
11047 static int
11048 api_l2_fib_table_dump (vat_main_t * vam)
11049 {
11050   unformat_input_t *i = vam->input;
11051   vl_api_l2_fib_table_dump_t *mp;
11052   f64 timeout;
11053   u32 bd_id;
11054   u8 bd_id_set = 0;
11055
11056   /* Parse args required to build the message */
11057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11058     {
11059       if (unformat (i, "bd_id %d", &bd_id))
11060         bd_id_set = 1;
11061       else
11062         break;
11063     }
11064
11065   if (bd_id_set == 0)
11066     {
11067       errmsg ("missing bridge domain\n");
11068       return -99;
11069     }
11070
11071   fformat (vam->ofp,
11072            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11073
11074   /* Get list of l2 fib entries */
11075   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11076
11077   mp->bd_id = ntohl (bd_id);
11078   S;
11079
11080   /* Use a control ping for synchronization */
11081   {
11082     vl_api_control_ping_t *mp;
11083     M (CONTROL_PING, control_ping);
11084     S;
11085   }
11086   W;
11087 }
11088
11089
11090 static int
11091 api_interface_name_renumber (vat_main_t * vam)
11092 {
11093   unformat_input_t *line_input = vam->input;
11094   vl_api_interface_name_renumber_t *mp;
11095   u32 sw_if_index = ~0;
11096   f64 timeout;
11097   u32 new_show_dev_instance = ~0;
11098
11099   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11100     {
11101       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11102                     &sw_if_index))
11103         ;
11104       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11105         ;
11106       else if (unformat (line_input, "new_show_dev_instance %d",
11107                          &new_show_dev_instance))
11108         ;
11109       else
11110         break;
11111     }
11112
11113   if (sw_if_index == ~0)
11114     {
11115       errmsg ("missing interface name or sw_if_index\n");
11116       return -99;
11117     }
11118
11119   if (new_show_dev_instance == ~0)
11120     {
11121       errmsg ("missing new_show_dev_instance\n");
11122       return -99;
11123     }
11124
11125   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11126
11127   mp->sw_if_index = ntohl (sw_if_index);
11128   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11129
11130   S;
11131   W;
11132 }
11133
11134 static int
11135 api_want_ip4_arp_events (vat_main_t * vam)
11136 {
11137   unformat_input_t *line_input = vam->input;
11138   vl_api_want_ip4_arp_events_t *mp;
11139   f64 timeout;
11140   ip4_address_t address;
11141   int address_set = 0;
11142   u32 enable_disable = 1;
11143
11144   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11145     {
11146       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11147         address_set = 1;
11148       else if (unformat (line_input, "del"))
11149         enable_disable = 0;
11150       else
11151         break;
11152     }
11153
11154   if (address_set == 0)
11155     {
11156       errmsg ("missing addresses\n");
11157       return -99;
11158     }
11159
11160   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11161   mp->enable_disable = enable_disable;
11162   mp->pid = getpid ();
11163   mp->address = address.as_u32;
11164
11165   S;
11166   W;
11167 }
11168
11169 static int
11170 api_want_ip6_nd_events (vat_main_t * vam)
11171 {
11172   unformat_input_t *line_input = vam->input;
11173   vl_api_want_ip6_nd_events_t *mp;
11174   f64 timeout;
11175   ip6_address_t address;
11176   int address_set = 0;
11177   u32 enable_disable = 1;
11178
11179   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11180     {
11181       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11182         address_set = 1;
11183       else if (unformat (line_input, "del"))
11184         enable_disable = 0;
11185       else
11186         break;
11187     }
11188
11189   if (address_set == 0)
11190     {
11191       errmsg ("missing addresses\n");
11192       return -99;
11193     }
11194
11195   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11196   mp->enable_disable = enable_disable;
11197   mp->pid = getpid ();
11198   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11199
11200   S;
11201   W;
11202 }
11203
11204 static int
11205 api_input_acl_set_interface (vat_main_t * vam)
11206 {
11207   unformat_input_t *i = vam->input;
11208   vl_api_input_acl_set_interface_t *mp;
11209   f64 timeout;
11210   u32 sw_if_index;
11211   int sw_if_index_set;
11212   u32 ip4_table_index = ~0;
11213   u32 ip6_table_index = ~0;
11214   u32 l2_table_index = ~0;
11215   u8 is_add = 1;
11216
11217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11218     {
11219       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11220         sw_if_index_set = 1;
11221       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11222         sw_if_index_set = 1;
11223       else if (unformat (i, "del"))
11224         is_add = 0;
11225       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11226         ;
11227       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11228         ;
11229       else if (unformat (i, "l2-table %d", &l2_table_index))
11230         ;
11231       else
11232         {
11233           clib_warning ("parse error '%U'", format_unformat_error, i);
11234           return -99;
11235         }
11236     }
11237
11238   if (sw_if_index_set == 0)
11239     {
11240       errmsg ("missing interface name or sw_if_index\n");
11241       return -99;
11242     }
11243
11244   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11245
11246   mp->sw_if_index = ntohl (sw_if_index);
11247   mp->ip4_table_index = ntohl (ip4_table_index);
11248   mp->ip6_table_index = ntohl (ip6_table_index);
11249   mp->l2_table_index = ntohl (l2_table_index);
11250   mp->is_add = is_add;
11251
11252   S;
11253   W;
11254   /* NOTREACHED */
11255   return 0;
11256 }
11257
11258 static int
11259 api_ip_address_dump (vat_main_t * vam)
11260 {
11261   unformat_input_t *i = vam->input;
11262   vl_api_ip_address_dump_t *mp;
11263   u32 sw_if_index = ~0;
11264   u8 sw_if_index_set = 0;
11265   u8 ipv4_set = 0;
11266   u8 ipv6_set = 0;
11267   f64 timeout;
11268
11269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11270     {
11271       if (unformat (i, "sw_if_index %d", &sw_if_index))
11272         sw_if_index_set = 1;
11273       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11274         sw_if_index_set = 1;
11275       else if (unformat (i, "ipv4"))
11276         ipv4_set = 1;
11277       else if (unformat (i, "ipv6"))
11278         ipv6_set = 1;
11279       else
11280         break;
11281     }
11282
11283   if (ipv4_set && ipv6_set)
11284     {
11285       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11286       return -99;
11287     }
11288
11289   if ((!ipv4_set) && (!ipv6_set))
11290     {
11291       errmsg ("no ipv4 nor ipv6 flag set\n");
11292       return -99;
11293     }
11294
11295   if (sw_if_index_set == 0)
11296     {
11297       errmsg ("missing interface name or sw_if_index\n");
11298       return -99;
11299     }
11300
11301   vam->current_sw_if_index = sw_if_index;
11302   vam->is_ipv6 = ipv6_set;
11303
11304   M (IP_ADDRESS_DUMP, ip_address_dump);
11305   mp->sw_if_index = ntohl (sw_if_index);
11306   mp->is_ipv6 = ipv6_set;
11307   S;
11308
11309   /* Use a control ping for synchronization */
11310   {
11311     vl_api_control_ping_t *mp;
11312     M (CONTROL_PING, control_ping);
11313     S;
11314   }
11315   W;
11316 }
11317
11318 static int
11319 api_ip_dump (vat_main_t * vam)
11320 {
11321   vl_api_ip_dump_t *mp;
11322   unformat_input_t *in = vam->input;
11323   int ipv4_set = 0;
11324   int ipv6_set = 0;
11325   int is_ipv6;
11326   f64 timeout;
11327   int i;
11328
11329   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11330     {
11331       if (unformat (in, "ipv4"))
11332         ipv4_set = 1;
11333       else if (unformat (in, "ipv6"))
11334         ipv6_set = 1;
11335       else
11336         break;
11337     }
11338
11339   if (ipv4_set && ipv6_set)
11340     {
11341       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11342       return -99;
11343     }
11344
11345   if ((!ipv4_set) && (!ipv6_set))
11346     {
11347       errmsg ("no ipv4 nor ipv6 flag set\n");
11348       return -99;
11349     }
11350
11351   is_ipv6 = ipv6_set;
11352   vam->is_ipv6 = is_ipv6;
11353
11354   /* free old data */
11355   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11356     {
11357       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11358     }
11359   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11360
11361   M (IP_DUMP, ip_dump);
11362   mp->is_ipv6 = ipv6_set;
11363   S;
11364
11365   /* Use a control ping for synchronization */
11366   {
11367     vl_api_control_ping_t *mp;
11368     M (CONTROL_PING, control_ping);
11369     S;
11370   }
11371   W;
11372 }
11373
11374 static int
11375 api_ipsec_spd_add_del (vat_main_t * vam)
11376 {
11377   unformat_input_t *i = vam->input;
11378   vl_api_ipsec_spd_add_del_t *mp;
11379   f64 timeout;
11380   u32 spd_id = ~0;
11381   u8 is_add = 1;
11382
11383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11384     {
11385       if (unformat (i, "spd_id %d", &spd_id))
11386         ;
11387       else if (unformat (i, "del"))
11388         is_add = 0;
11389       else
11390         {
11391           clib_warning ("parse error '%U'", format_unformat_error, i);
11392           return -99;
11393         }
11394     }
11395   if (spd_id == ~0)
11396     {
11397       errmsg ("spd_id must be set\n");
11398       return -99;
11399     }
11400
11401   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11402
11403   mp->spd_id = ntohl (spd_id);
11404   mp->is_add = is_add;
11405
11406   S;
11407   W;
11408   /* NOTREACHED */
11409   return 0;
11410 }
11411
11412 static int
11413 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11414 {
11415   unformat_input_t *i = vam->input;
11416   vl_api_ipsec_interface_add_del_spd_t *mp;
11417   f64 timeout;
11418   u32 sw_if_index;
11419   u8 sw_if_index_set = 0;
11420   u32 spd_id = (u32) ~ 0;
11421   u8 is_add = 1;
11422
11423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11424     {
11425       if (unformat (i, "del"))
11426         is_add = 0;
11427       else if (unformat (i, "spd_id %d", &spd_id))
11428         ;
11429       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11430         sw_if_index_set = 1;
11431       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11432         sw_if_index_set = 1;
11433       else
11434         {
11435           clib_warning ("parse error '%U'", format_unformat_error, i);
11436           return -99;
11437         }
11438
11439     }
11440
11441   if (spd_id == (u32) ~ 0)
11442     {
11443       errmsg ("spd_id must be set\n");
11444       return -99;
11445     }
11446
11447   if (sw_if_index_set == 0)
11448     {
11449       errmsg ("missing interface name or sw_if_index\n");
11450       return -99;
11451     }
11452
11453   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11454
11455   mp->spd_id = ntohl (spd_id);
11456   mp->sw_if_index = ntohl (sw_if_index);
11457   mp->is_add = is_add;
11458
11459   S;
11460   W;
11461   /* NOTREACHED */
11462   return 0;
11463 }
11464
11465 static int
11466 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11467 {
11468   unformat_input_t *i = vam->input;
11469   vl_api_ipsec_spd_add_del_entry_t *mp;
11470   f64 timeout;
11471   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11472   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11473   i32 priority = 0;
11474   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11475   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11476   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11477   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11478
11479   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11480   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11481   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11482   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11483   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11484   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11485
11486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11487     {
11488       if (unformat (i, "del"))
11489         is_add = 0;
11490       if (unformat (i, "outbound"))
11491         is_outbound = 1;
11492       if (unformat (i, "inbound"))
11493         is_outbound = 0;
11494       else if (unformat (i, "spd_id %d", &spd_id))
11495         ;
11496       else if (unformat (i, "sa_id %d", &sa_id))
11497         ;
11498       else if (unformat (i, "priority %d", &priority))
11499         ;
11500       else if (unformat (i, "protocol %d", &protocol))
11501         ;
11502       else if (unformat (i, "lport_start %d", &lport_start))
11503         ;
11504       else if (unformat (i, "lport_stop %d", &lport_stop))
11505         ;
11506       else if (unformat (i, "rport_start %d", &rport_start))
11507         ;
11508       else if (unformat (i, "rport_stop %d", &rport_stop))
11509         ;
11510       else
11511         if (unformat
11512             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11513         {
11514           is_ipv6 = 0;
11515           is_ip_any = 0;
11516         }
11517       else
11518         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11519         {
11520           is_ipv6 = 0;
11521           is_ip_any = 0;
11522         }
11523       else
11524         if (unformat
11525             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11526         {
11527           is_ipv6 = 0;
11528           is_ip_any = 0;
11529         }
11530       else
11531         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11532         {
11533           is_ipv6 = 0;
11534           is_ip_any = 0;
11535         }
11536       else
11537         if (unformat
11538             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11539         {
11540           is_ipv6 = 1;
11541           is_ip_any = 0;
11542         }
11543       else
11544         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11545         {
11546           is_ipv6 = 1;
11547           is_ip_any = 0;
11548         }
11549       else
11550         if (unformat
11551             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11552         {
11553           is_ipv6 = 1;
11554           is_ip_any = 0;
11555         }
11556       else
11557         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11558         {
11559           is_ipv6 = 1;
11560           is_ip_any = 0;
11561         }
11562       else
11563         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11564         {
11565           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11566             {
11567               clib_warning ("unsupported action: 'resolve'");
11568               return -99;
11569             }
11570         }
11571       else
11572         {
11573           clib_warning ("parse error '%U'", format_unformat_error, i);
11574           return -99;
11575         }
11576
11577     }
11578
11579   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11580
11581   mp->spd_id = ntohl (spd_id);
11582   mp->priority = ntohl (priority);
11583   mp->is_outbound = is_outbound;
11584
11585   mp->is_ipv6 = is_ipv6;
11586   if (is_ipv6 || is_ip_any)
11587     {
11588       clib_memcpy (mp->remote_address_start, &raddr6_start,
11589                    sizeof (ip6_address_t));
11590       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11591                    sizeof (ip6_address_t));
11592       clib_memcpy (mp->local_address_start, &laddr6_start,
11593                    sizeof (ip6_address_t));
11594       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11595                    sizeof (ip6_address_t));
11596     }
11597   else
11598     {
11599       clib_memcpy (mp->remote_address_start, &raddr4_start,
11600                    sizeof (ip4_address_t));
11601       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11602                    sizeof (ip4_address_t));
11603       clib_memcpy (mp->local_address_start, &laddr4_start,
11604                    sizeof (ip4_address_t));
11605       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11606                    sizeof (ip4_address_t));
11607     }
11608   mp->protocol = (u8) protocol;
11609   mp->local_port_start = ntohs ((u16) lport_start);
11610   mp->local_port_stop = ntohs ((u16) lport_stop);
11611   mp->remote_port_start = ntohs ((u16) rport_start);
11612   mp->remote_port_stop = ntohs ((u16) rport_stop);
11613   mp->policy = (u8) policy;
11614   mp->sa_id = ntohl (sa_id);
11615   mp->is_add = is_add;
11616   mp->is_ip_any = is_ip_any;
11617   S;
11618   W;
11619   /* NOTREACHED */
11620   return 0;
11621 }
11622
11623 static int
11624 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11625 {
11626   unformat_input_t *i = vam->input;
11627   vl_api_ipsec_sad_add_del_entry_t *mp;
11628   f64 timeout;
11629   u32 sad_id = 0, spi = 0;
11630   u8 *ck = 0, *ik = 0;
11631   u8 is_add = 1;
11632
11633   u8 protocol = IPSEC_PROTOCOL_AH;
11634   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11635   u32 crypto_alg = 0, integ_alg = 0;
11636   ip4_address_t tun_src4;
11637   ip4_address_t tun_dst4;
11638   ip6_address_t tun_src6;
11639   ip6_address_t tun_dst6;
11640
11641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11642     {
11643       if (unformat (i, "del"))
11644         is_add = 0;
11645       else if (unformat (i, "sad_id %d", &sad_id))
11646         ;
11647       else if (unformat (i, "spi %d", &spi))
11648         ;
11649       else if (unformat (i, "esp"))
11650         protocol = IPSEC_PROTOCOL_ESP;
11651       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11652         {
11653           is_tunnel = 1;
11654           is_tunnel_ipv6 = 0;
11655         }
11656       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11657         {
11658           is_tunnel = 1;
11659           is_tunnel_ipv6 = 0;
11660         }
11661       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11662         {
11663           is_tunnel = 1;
11664           is_tunnel_ipv6 = 1;
11665         }
11666       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11667         {
11668           is_tunnel = 1;
11669           is_tunnel_ipv6 = 1;
11670         }
11671       else
11672         if (unformat
11673             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11674         {
11675           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11676               crypto_alg > IPSEC_INTEG_ALG_SHA_512_256)
11677             {
11678               clib_warning ("unsupported crypto-alg: '%U'",
11679                             format_ipsec_crypto_alg, crypto_alg);
11680               return -99;
11681             }
11682         }
11683       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11684         ;
11685       else
11686         if (unformat
11687             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11688         {
11689           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11690               integ_alg > IPSEC_INTEG_ALG_SHA_512_256)
11691             {
11692               clib_warning ("unsupported integ-alg: '%U'",
11693                             format_ipsec_integ_alg, integ_alg);
11694               return -99;
11695             }
11696         }
11697       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11698         ;
11699       else
11700         {
11701           clib_warning ("parse error '%U'", format_unformat_error, i);
11702           return -99;
11703         }
11704
11705     }
11706
11707   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11708
11709   mp->sad_id = ntohl (sad_id);
11710   mp->is_add = is_add;
11711   mp->protocol = protocol;
11712   mp->spi = ntohl (spi);
11713   mp->is_tunnel = is_tunnel;
11714   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11715   mp->crypto_algorithm = crypto_alg;
11716   mp->integrity_algorithm = integ_alg;
11717   mp->crypto_key_length = vec_len (ck);
11718   mp->integrity_key_length = vec_len (ik);
11719
11720   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11721     mp->crypto_key_length = sizeof (mp->crypto_key);
11722
11723   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11724     mp->integrity_key_length = sizeof (mp->integrity_key);
11725
11726   if (ck)
11727     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11728   if (ik)
11729     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11730
11731   if (is_tunnel)
11732     {
11733       if (is_tunnel_ipv6)
11734         {
11735           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11736                        sizeof (ip6_address_t));
11737           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
11738                        sizeof (ip6_address_t));
11739         }
11740       else
11741         {
11742           clib_memcpy (mp->tunnel_src_address, &tun_src4,
11743                        sizeof (ip4_address_t));
11744           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
11745                        sizeof (ip4_address_t));
11746         }
11747     }
11748
11749   S;
11750   W;
11751   /* NOTREACHED */
11752   return 0;
11753 }
11754
11755 static int
11756 api_ipsec_sa_set_key (vat_main_t * vam)
11757 {
11758   unformat_input_t *i = vam->input;
11759   vl_api_ipsec_sa_set_key_t *mp;
11760   f64 timeout;
11761   u32 sa_id;
11762   u8 *ck = 0, *ik = 0;
11763
11764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11765     {
11766       if (unformat (i, "sa_id %d", &sa_id))
11767         ;
11768       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11769         ;
11770       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11771         ;
11772       else
11773         {
11774           clib_warning ("parse error '%U'", format_unformat_error, i);
11775           return -99;
11776         }
11777     }
11778
11779   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
11780
11781   mp->sa_id = ntohl (sa_id);
11782   mp->crypto_key_length = vec_len (ck);
11783   mp->integrity_key_length = vec_len (ik);
11784
11785   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11786     mp->crypto_key_length = sizeof (mp->crypto_key);
11787
11788   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11789     mp->integrity_key_length = sizeof (mp->integrity_key);
11790
11791   if (ck)
11792     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11793   if (ik)
11794     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11795
11796   S;
11797   W;
11798   /* NOTREACHED */
11799   return 0;
11800 }
11801
11802 static int
11803 api_ikev2_profile_add_del (vat_main_t * vam)
11804 {
11805   unformat_input_t *i = vam->input;
11806   vl_api_ikev2_profile_add_del_t *mp;
11807   f64 timeout;
11808   u8 is_add = 1;
11809   u8 *name = 0;
11810
11811   const char *valid_chars = "a-zA-Z0-9_";
11812
11813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11814     {
11815       if (unformat (i, "del"))
11816         is_add = 0;
11817       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11818         vec_add1 (name, 0);
11819       else
11820         {
11821           errmsg ("parse error '%U'", format_unformat_error, i);
11822           return -99;
11823         }
11824     }
11825
11826   if (!vec_len (name))
11827     {
11828       errmsg ("profile name must be specified");
11829       return -99;
11830     }
11831
11832   if (vec_len (name) > 64)
11833     {
11834       errmsg ("profile name too long");
11835       return -99;
11836     }
11837
11838   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
11839
11840   clib_memcpy (mp->name, name, vec_len (name));
11841   mp->is_add = is_add;
11842   vec_free (name);
11843
11844   S;
11845   W;
11846   /* NOTREACHED */
11847   return 0;
11848 }
11849
11850 static int
11851 api_ikev2_profile_set_auth (vat_main_t * vam)
11852 {
11853   unformat_input_t *i = vam->input;
11854   vl_api_ikev2_profile_set_auth_t *mp;
11855   f64 timeout;
11856   u8 *name = 0;
11857   u8 *data = 0;
11858   u32 auth_method = 0;
11859   u8 is_hex = 0;
11860
11861   const char *valid_chars = "a-zA-Z0-9_";
11862
11863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11864     {
11865       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11866         vec_add1 (name, 0);
11867       else if (unformat (i, "auth_method %U",
11868                          unformat_ikev2_auth_method, &auth_method))
11869         ;
11870       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
11871         is_hex = 1;
11872       else if (unformat (i, "auth_data %v", &data))
11873         ;
11874       else
11875         {
11876           errmsg ("parse error '%U'", format_unformat_error, i);
11877           return -99;
11878         }
11879     }
11880
11881   if (!vec_len (name))
11882     {
11883       errmsg ("profile name must be specified");
11884       return -99;
11885     }
11886
11887   if (vec_len (name) > 64)
11888     {
11889       errmsg ("profile name too long");
11890       return -99;
11891     }
11892
11893   if (!vec_len (data))
11894     {
11895       errmsg ("auth_data must be specified");
11896       return -99;
11897     }
11898
11899   if (!auth_method)
11900     {
11901       errmsg ("auth_method must be specified");
11902       return -99;
11903     }
11904
11905   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
11906
11907   mp->is_hex = is_hex;
11908   mp->auth_method = (u8) auth_method;
11909   mp->data_len = vec_len (data);
11910   clib_memcpy (mp->name, name, vec_len (name));
11911   clib_memcpy (mp->data, data, vec_len (data));
11912   vec_free (name);
11913   vec_free (data);
11914
11915   S;
11916   W;
11917   /* NOTREACHED */
11918   return 0;
11919 }
11920
11921 static int
11922 api_ikev2_profile_set_id (vat_main_t * vam)
11923 {
11924   unformat_input_t *i = vam->input;
11925   vl_api_ikev2_profile_set_id_t *mp;
11926   f64 timeout;
11927   u8 *name = 0;
11928   u8 *data = 0;
11929   u8 is_local = 0;
11930   u32 id_type = 0;
11931   ip4_address_t ip4;
11932
11933   const char *valid_chars = "a-zA-Z0-9_";
11934
11935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11936     {
11937       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
11938         vec_add1 (name, 0);
11939       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
11940         ;
11941       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
11942         {
11943           data = vec_new (u8, 4);
11944           clib_memcpy (data, ip4.as_u8, 4);
11945         }
11946       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
11947         ;
11948       else if (unformat (i, "id_data %v", &data))
11949         ;
11950       else if (unformat (i, "local"))
11951         is_local = 1;
11952       else if (unformat (i, "remote"))
11953         is_local = 0;
11954       else
11955         {
11956           errmsg ("parse error '%U'", format_unformat_error, i);
11957           return -99;
11958         }
11959     }
11960
11961   if (!vec_len (name))
11962     {
11963       errmsg ("profile name must be specified");
11964       return -99;
11965     }
11966
11967   if (vec_len (name) > 64)
11968     {
11969       errmsg ("profile name too long");
11970       return -99;
11971     }
11972
11973   if (!vec_len (data))
11974     {
11975       errmsg ("id_data must be specified");
11976       return -99;
11977     }
11978
11979   if (!id_type)
11980     {
11981       errmsg ("id_type must be specified");
11982       return -99;
11983     }
11984
11985   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
11986
11987   mp->is_local = is_local;
11988   mp->id_type = (u8) id_type;
11989   mp->data_len = vec_len (data);
11990   clib_memcpy (mp->name, name, vec_len (name));
11991   clib_memcpy (mp->data, data, vec_len (data));
11992   vec_free (name);
11993   vec_free (data);
11994
11995   S;
11996   W;
11997   /* NOTREACHED */
11998   return 0;
11999 }
12000
12001 static int
12002 api_ikev2_profile_set_ts (vat_main_t * vam)
12003 {
12004   unformat_input_t *i = vam->input;
12005   vl_api_ikev2_profile_set_ts_t *mp;
12006   f64 timeout;
12007   u8 *name = 0;
12008   u8 is_local = 0;
12009   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12010   ip4_address_t start_addr, end_addr;
12011
12012   const char *valid_chars = "a-zA-Z0-9_";
12013
12014   start_addr.as_u32 = 0;
12015   end_addr.as_u32 = (u32) ~ 0;
12016
12017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12018     {
12019       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12020         vec_add1 (name, 0);
12021       else if (unformat (i, "protocol %d", &proto))
12022         ;
12023       else if (unformat (i, "start_port %d", &start_port))
12024         ;
12025       else if (unformat (i, "end_port %d", &end_port))
12026         ;
12027       else
12028         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12029         ;
12030       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12031         ;
12032       else if (unformat (i, "local"))
12033         is_local = 1;
12034       else if (unformat (i, "remote"))
12035         is_local = 0;
12036       else
12037         {
12038           errmsg ("parse error '%U'", format_unformat_error, i);
12039           return -99;
12040         }
12041     }
12042
12043   if (!vec_len (name))
12044     {
12045       errmsg ("profile name must be specified");
12046       return -99;
12047     }
12048
12049   if (vec_len (name) > 64)
12050     {
12051       errmsg ("profile name too long");
12052       return -99;
12053     }
12054
12055   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12056
12057   mp->is_local = is_local;
12058   mp->proto = (u8) proto;
12059   mp->start_port = (u16) start_port;
12060   mp->end_port = (u16) end_port;
12061   mp->start_addr = start_addr.as_u32;
12062   mp->end_addr = end_addr.as_u32;
12063   clib_memcpy (mp->name, name, vec_len (name));
12064   vec_free (name);
12065
12066   S;
12067   W;
12068   /* NOTREACHED */
12069   return 0;
12070 }
12071
12072 static int
12073 api_ikev2_set_local_key (vat_main_t * vam)
12074 {
12075   unformat_input_t *i = vam->input;
12076   vl_api_ikev2_set_local_key_t *mp;
12077   f64 timeout;
12078   u8 *file = 0;
12079
12080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12081     {
12082       if (unformat (i, "file %v", &file))
12083         vec_add1 (file, 0);
12084       else
12085         {
12086           errmsg ("parse error '%U'", format_unformat_error, i);
12087           return -99;
12088         }
12089     }
12090
12091   if (!vec_len (file))
12092     {
12093       errmsg ("RSA key file must be specified");
12094       return -99;
12095     }
12096
12097   if (vec_len (file) > 256)
12098     {
12099       errmsg ("file name too long");
12100       return -99;
12101     }
12102
12103   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12104
12105   clib_memcpy (mp->key_file, file, vec_len (file));
12106   vec_free (file);
12107
12108   S;
12109   W;
12110   /* NOTREACHED */
12111   return 0;
12112 }
12113
12114 /*
12115  * MAP
12116  */
12117 static int
12118 api_map_add_domain (vat_main_t * vam)
12119 {
12120   unformat_input_t *i = vam->input;
12121   vl_api_map_add_domain_t *mp;
12122   f64 timeout;
12123
12124   ip4_address_t ip4_prefix;
12125   ip6_address_t ip6_prefix;
12126   ip6_address_t ip6_src;
12127   u32 num_m_args = 0;
12128   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12129     0, psid_length = 0;
12130   u8 is_translation = 0;
12131   u32 mtu = 0;
12132   u32 ip6_src_len = 128;
12133
12134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12135     {
12136       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12137                     &ip4_prefix, &ip4_prefix_len))
12138         num_m_args++;
12139       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12140                          &ip6_prefix, &ip6_prefix_len))
12141         num_m_args++;
12142       else
12143         if (unformat
12144             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12145              &ip6_src_len))
12146         num_m_args++;
12147       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12148         num_m_args++;
12149       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12150         num_m_args++;
12151       else if (unformat (i, "psid-offset %d", &psid_offset))
12152         num_m_args++;
12153       else if (unformat (i, "psid-len %d", &psid_length))
12154         num_m_args++;
12155       else if (unformat (i, "mtu %d", &mtu))
12156         num_m_args++;
12157       else if (unformat (i, "map-t"))
12158         is_translation = 1;
12159       else
12160         {
12161           clib_warning ("parse error '%U'", format_unformat_error, i);
12162           return -99;
12163         }
12164     }
12165
12166   if (num_m_args < 3)
12167     {
12168       errmsg ("mandatory argument(s) missing\n");
12169       return -99;
12170     }
12171
12172   /* Construct the API message */
12173   M (MAP_ADD_DOMAIN, map_add_domain);
12174
12175   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12176   mp->ip4_prefix_len = ip4_prefix_len;
12177
12178   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12179   mp->ip6_prefix_len = ip6_prefix_len;
12180
12181   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12182   mp->ip6_src_prefix_len = ip6_src_len;
12183
12184   mp->ea_bits_len = ea_bits_len;
12185   mp->psid_offset = psid_offset;
12186   mp->psid_length = psid_length;
12187   mp->is_translation = is_translation;
12188   mp->mtu = htons (mtu);
12189
12190   /* send it... */
12191   S;
12192
12193   /* Wait for a reply, return good/bad news  */
12194   W;
12195 }
12196
12197 static int
12198 api_map_del_domain (vat_main_t * vam)
12199 {
12200   unformat_input_t *i = vam->input;
12201   vl_api_map_del_domain_t *mp;
12202   f64 timeout;
12203
12204   u32 num_m_args = 0;
12205   u32 index;
12206
12207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12208     {
12209       if (unformat (i, "index %d", &index))
12210         num_m_args++;
12211       else
12212         {
12213           clib_warning ("parse error '%U'", format_unformat_error, i);
12214           return -99;
12215         }
12216     }
12217
12218   if (num_m_args != 1)
12219     {
12220       errmsg ("mandatory argument(s) missing\n");
12221       return -99;
12222     }
12223
12224   /* Construct the API message */
12225   M (MAP_DEL_DOMAIN, map_del_domain);
12226
12227   mp->index = ntohl (index);
12228
12229   /* send it... */
12230   S;
12231
12232   /* Wait for a reply, return good/bad news  */
12233   W;
12234 }
12235
12236 static int
12237 api_map_add_del_rule (vat_main_t * vam)
12238 {
12239   unformat_input_t *i = vam->input;
12240   vl_api_map_add_del_rule_t *mp;
12241   f64 timeout;
12242   u8 is_add = 1;
12243   ip6_address_t ip6_dst;
12244   u32 num_m_args = 0, index, psid = 0;
12245
12246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12247     {
12248       if (unformat (i, "index %d", &index))
12249         num_m_args++;
12250       else if (unformat (i, "psid %d", &psid))
12251         num_m_args++;
12252       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12253         num_m_args++;
12254       else if (unformat (i, "del"))
12255         {
12256           is_add = 0;
12257         }
12258       else
12259         {
12260           clib_warning ("parse error '%U'", format_unformat_error, i);
12261           return -99;
12262         }
12263     }
12264
12265   /* Construct the API message */
12266   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12267
12268   mp->index = ntohl (index);
12269   mp->is_add = is_add;
12270   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12271   mp->psid = ntohs (psid);
12272
12273   /* send it... */
12274   S;
12275
12276   /* Wait for a reply, return good/bad news  */
12277   W;
12278 }
12279
12280 static int
12281 api_map_domain_dump (vat_main_t * vam)
12282 {
12283   vl_api_map_domain_dump_t *mp;
12284   f64 timeout;
12285
12286   /* Construct the API message */
12287   M (MAP_DOMAIN_DUMP, map_domain_dump);
12288
12289   /* send it... */
12290   S;
12291
12292   /* Use a control ping for synchronization */
12293   {
12294     vl_api_control_ping_t *mp;
12295     M (CONTROL_PING, control_ping);
12296     S;
12297   }
12298   W;
12299 }
12300
12301 static int
12302 api_map_rule_dump (vat_main_t * vam)
12303 {
12304   unformat_input_t *i = vam->input;
12305   vl_api_map_rule_dump_t *mp;
12306   f64 timeout;
12307   u32 domain_index = ~0;
12308
12309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12310     {
12311       if (unformat (i, "index %u", &domain_index))
12312         ;
12313       else
12314         break;
12315     }
12316
12317   if (domain_index == ~0)
12318     {
12319       clib_warning ("parse error: domain index expected");
12320       return -99;
12321     }
12322
12323   /* Construct the API message */
12324   M (MAP_RULE_DUMP, map_rule_dump);
12325
12326   mp->domain_index = htonl (domain_index);
12327
12328   /* send it... */
12329   S;
12330
12331   /* Use a control ping for synchronization */
12332   {
12333     vl_api_control_ping_t *mp;
12334     M (CONTROL_PING, control_ping);
12335     S;
12336   }
12337   W;
12338 }
12339
12340 static void vl_api_map_add_domain_reply_t_handler
12341   (vl_api_map_add_domain_reply_t * mp)
12342 {
12343   vat_main_t *vam = &vat_main;
12344   i32 retval = ntohl (mp->retval);
12345
12346   if (vam->async_mode)
12347     {
12348       vam->async_errors += (retval < 0);
12349     }
12350   else
12351     {
12352       vam->retval = retval;
12353       vam->result_ready = 1;
12354     }
12355 }
12356
12357 static void vl_api_map_add_domain_reply_t_handler_json
12358   (vl_api_map_add_domain_reply_t * mp)
12359 {
12360   vat_main_t *vam = &vat_main;
12361   vat_json_node_t node;
12362
12363   vat_json_init_object (&node);
12364   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12365   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12366
12367   vat_json_print (vam->ofp, &node);
12368   vat_json_free (&node);
12369
12370   vam->retval = ntohl (mp->retval);
12371   vam->result_ready = 1;
12372 }
12373
12374 static int
12375 api_get_first_msg_id (vat_main_t * vam)
12376 {
12377   vl_api_get_first_msg_id_t *mp;
12378   f64 timeout;
12379   unformat_input_t *i = vam->input;
12380   u8 *name;
12381   u8 name_set = 0;
12382
12383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12384     {
12385       if (unformat (i, "client %s", &name))
12386         name_set = 1;
12387       else
12388         break;
12389     }
12390
12391   if (name_set == 0)
12392     {
12393       errmsg ("missing client name\n");
12394       return -99;
12395     }
12396   vec_add1 (name, 0);
12397
12398   if (vec_len (name) > 63)
12399     {
12400       errmsg ("client name too long\n");
12401       return -99;
12402     }
12403
12404   M (GET_FIRST_MSG_ID, get_first_msg_id);
12405   clib_memcpy (mp->name, name, vec_len (name));
12406   S;
12407   W;
12408   /* NOTREACHED */
12409   return 0;
12410 }
12411
12412 static int
12413 api_cop_interface_enable_disable (vat_main_t * vam)
12414 {
12415   unformat_input_t *line_input = vam->input;
12416   vl_api_cop_interface_enable_disable_t *mp;
12417   f64 timeout;
12418   u32 sw_if_index = ~0;
12419   u8 enable_disable = 1;
12420
12421   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12422     {
12423       if (unformat (line_input, "disable"))
12424         enable_disable = 0;
12425       if (unformat (line_input, "enable"))
12426         enable_disable = 1;
12427       else if (unformat (line_input, "%U", unformat_sw_if_index,
12428                          vam, &sw_if_index))
12429         ;
12430       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12431         ;
12432       else
12433         break;
12434     }
12435
12436   if (sw_if_index == ~0)
12437     {
12438       errmsg ("missing interface name or sw_if_index\n");
12439       return -99;
12440     }
12441
12442   /* Construct the API message */
12443   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12444   mp->sw_if_index = ntohl (sw_if_index);
12445   mp->enable_disable = enable_disable;
12446
12447   /* send it... */
12448   S;
12449   /* Wait for the reply */
12450   W;
12451 }
12452
12453 static int
12454 api_cop_whitelist_enable_disable (vat_main_t * vam)
12455 {
12456   unformat_input_t *line_input = vam->input;
12457   vl_api_cop_whitelist_enable_disable_t *mp;
12458   f64 timeout;
12459   u32 sw_if_index = ~0;
12460   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12461   u32 fib_id = 0;
12462
12463   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12464     {
12465       if (unformat (line_input, "ip4"))
12466         ip4 = 1;
12467       else if (unformat (line_input, "ip6"))
12468         ip6 = 1;
12469       else if (unformat (line_input, "default"))
12470         default_cop = 1;
12471       else if (unformat (line_input, "%U", unformat_sw_if_index,
12472                          vam, &sw_if_index))
12473         ;
12474       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12475         ;
12476       else if (unformat (line_input, "fib-id %d", &fib_id))
12477         ;
12478       else
12479         break;
12480     }
12481
12482   if (sw_if_index == ~0)
12483     {
12484       errmsg ("missing interface name or sw_if_index\n");
12485       return -99;
12486     }
12487
12488   /* Construct the API message */
12489   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12490   mp->sw_if_index = ntohl (sw_if_index);
12491   mp->fib_id = ntohl (fib_id);
12492   mp->ip4 = ip4;
12493   mp->ip6 = ip6;
12494   mp->default_cop = default_cop;
12495
12496   /* send it... */
12497   S;
12498   /* Wait for the reply */
12499   W;
12500 }
12501
12502 static int
12503 api_get_node_graph (vat_main_t * vam)
12504 {
12505   vl_api_get_node_graph_t *mp;
12506   f64 timeout;
12507
12508   M (GET_NODE_GRAPH, get_node_graph);
12509
12510   /* send it... */
12511   S;
12512   /* Wait for the reply */
12513   W;
12514 }
12515
12516 /* *INDENT-OFF* */
12517 /** Used for parsing LISP eids */
12518 typedef CLIB_PACKED(struct{
12519   u8 addr[16];   /**< eid address */
12520   u32 len;       /**< prefix length if IP */
12521   u8 type;      /**< type of eid */
12522 }) lisp_eid_vat_t;
12523 /* *INDENT-ON* */
12524
12525 static uword
12526 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12527 {
12528   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12529
12530   memset (a, 0, sizeof (a[0]));
12531
12532   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12533     {
12534       a->type = 0;              /* ipv4 type */
12535     }
12536   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12537     {
12538       a->type = 1;              /* ipv6 type */
12539     }
12540   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12541     {
12542       a->type = 2;              /* mac type */
12543     }
12544   else
12545     {
12546       return 0;
12547     }
12548
12549   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12550     {
12551       return 0;
12552     }
12553
12554   return 1;
12555 }
12556
12557 static int
12558 lisp_eid_size_vat (u8 type)
12559 {
12560   switch (type)
12561     {
12562     case 0:
12563       return 4;
12564     case 1:
12565       return 16;
12566     case 2:
12567       return 6;
12568     }
12569   return 0;
12570 }
12571
12572 static void
12573 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12574 {
12575   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12576 }
12577
12578 /* *INDENT-OFF* */
12579 /** Used for transferring locators via VPP API */
12580 typedef CLIB_PACKED(struct
12581 {
12582   u32 sw_if_index; /**< locator sw_if_index */
12583   u8 priority; /**< locator priority */
12584   u8 weight;   /**< locator weight */
12585 }) ls_locator_t;
12586 /* *INDENT-ON* */
12587
12588 static int
12589 api_lisp_add_del_locator_set (vat_main_t * vam)
12590 {
12591   unformat_input_t *input = vam->input;
12592   vl_api_lisp_add_del_locator_set_t *mp;
12593   f64 timeout = ~0;
12594   u8 is_add = 1;
12595   u8 *locator_set_name = NULL;
12596   u8 locator_set_name_set = 0;
12597   ls_locator_t locator, *locators = 0;
12598   u32 sw_if_index, priority, weight;
12599   u32 data_len = 0;
12600
12601   /* Parse args required to build the message */
12602   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12603     {
12604       if (unformat (input, "del"))
12605         {
12606           is_add = 0;
12607         }
12608       else if (unformat (input, "locator-set %s", &locator_set_name))
12609         {
12610           locator_set_name_set = 1;
12611         }
12612       else if (unformat (input, "sw_if_index %u p %u w %u",
12613                          &sw_if_index, &priority, &weight))
12614         {
12615           locator.sw_if_index = htonl (sw_if_index);
12616           locator.priority = priority;
12617           locator.weight = weight;
12618           vec_add1 (locators, locator);
12619         }
12620       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12621                          vam, &sw_if_index, &priority, &weight))
12622         {
12623           locator.sw_if_index = htonl (sw_if_index);
12624           locator.priority = priority;
12625           locator.weight = weight;
12626           vec_add1 (locators, locator);
12627         }
12628       else
12629         break;
12630     }
12631
12632   if (locator_set_name_set == 0)
12633     {
12634       errmsg ("missing locator-set name");
12635       vec_free (locators);
12636       return -99;
12637     }
12638
12639   if (vec_len (locator_set_name) > 64)
12640     {
12641       errmsg ("locator-set name too long\n");
12642       vec_free (locator_set_name);
12643       vec_free (locators);
12644       return -99;
12645     }
12646   vec_add1 (locator_set_name, 0);
12647
12648   data_len = sizeof (ls_locator_t) * vec_len (locators);
12649
12650   /* Construct the API message */
12651   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12652
12653   mp->is_add = is_add;
12654   clib_memcpy (mp->locator_set_name, locator_set_name,
12655                vec_len (locator_set_name));
12656   vec_free (locator_set_name);
12657
12658   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12659   if (locators)
12660     clib_memcpy (mp->locators, locators, data_len);
12661   vec_free (locators);
12662
12663   /* send it... */
12664   S;
12665
12666   /* Wait for a reply... */
12667   W;
12668
12669   /* NOTREACHED */
12670   return 0;
12671 }
12672
12673 static int
12674 api_lisp_add_del_locator (vat_main_t * vam)
12675 {
12676   unformat_input_t *input = vam->input;
12677   vl_api_lisp_add_del_locator_t *mp;
12678   f64 timeout = ~0;
12679   u32 tmp_if_index = ~0;
12680   u32 sw_if_index = ~0;
12681   u8 sw_if_index_set = 0;
12682   u8 sw_if_index_if_name_set = 0;
12683   u32 priority = ~0;
12684   u8 priority_set = 0;
12685   u32 weight = ~0;
12686   u8 weight_set = 0;
12687   u8 is_add = 1;
12688   u8 *locator_set_name = NULL;
12689   u8 locator_set_name_set = 0;
12690
12691   /* Parse args required to build the message */
12692   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12693     {
12694       if (unformat (input, "del"))
12695         {
12696           is_add = 0;
12697         }
12698       else if (unformat (input, "locator-set %s", &locator_set_name))
12699         {
12700           locator_set_name_set = 1;
12701         }
12702       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12703                          &tmp_if_index))
12704         {
12705           sw_if_index_if_name_set = 1;
12706           sw_if_index = tmp_if_index;
12707         }
12708       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12709         {
12710           sw_if_index_set = 1;
12711           sw_if_index = tmp_if_index;
12712         }
12713       else if (unformat (input, "p %d", &priority))
12714         {
12715           priority_set = 1;
12716         }
12717       else if (unformat (input, "w %d", &weight))
12718         {
12719           weight_set = 1;
12720         }
12721       else
12722         break;
12723     }
12724
12725   if (locator_set_name_set == 0)
12726     {
12727       errmsg ("missing locator-set name");
12728       return -99;
12729     }
12730
12731   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12732     {
12733       errmsg ("missing sw_if_index");
12734       vec_free (locator_set_name);
12735       return -99;
12736     }
12737
12738   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
12739     {
12740       errmsg ("cannot use both params interface name and sw_if_index");
12741       vec_free (locator_set_name);
12742       return -99;
12743     }
12744
12745   if (priority_set == 0)
12746     {
12747       errmsg ("missing locator-set priority\n");
12748       vec_free (locator_set_name);
12749       return -99;
12750     }
12751
12752   if (weight_set == 0)
12753     {
12754       errmsg ("missing locator-set weight\n");
12755       vec_free (locator_set_name);
12756       return -99;
12757     }
12758
12759   if (vec_len (locator_set_name) > 64)
12760     {
12761       errmsg ("locator-set name too long\n");
12762       vec_free (locator_set_name);
12763       return -99;
12764     }
12765   vec_add1 (locator_set_name, 0);
12766
12767   /* Construct the API message */
12768   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
12769
12770   mp->is_add = is_add;
12771   mp->sw_if_index = ntohl (sw_if_index);
12772   mp->priority = priority;
12773   mp->weight = weight;
12774   clib_memcpy (mp->locator_set_name, locator_set_name,
12775                vec_len (locator_set_name));
12776   vec_free (locator_set_name);
12777
12778   /* send it... */
12779   S;
12780
12781   /* Wait for a reply... */
12782   W;
12783
12784   /* NOTREACHED */
12785   return 0;
12786 }
12787
12788 static int
12789 api_lisp_add_del_local_eid (vat_main_t * vam)
12790 {
12791   unformat_input_t *input = vam->input;
12792   vl_api_lisp_add_del_local_eid_t *mp;
12793   f64 timeout = ~0;
12794   u8 is_add = 1;
12795   u8 eid_set = 0;
12796   lisp_eid_vat_t _eid, *eid = &_eid;
12797   u8 *locator_set_name = 0;
12798   u8 locator_set_name_set = 0;
12799   u32 vni = 0;
12800
12801   /* Parse args required to build the message */
12802   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12803     {
12804       if (unformat (input, "del"))
12805         {
12806           is_add = 0;
12807         }
12808       else if (unformat (input, "vni %d", &vni))
12809         {
12810           ;
12811         }
12812       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
12813         {
12814           eid_set = 1;
12815         }
12816       else if (unformat (input, "locator-set %s", &locator_set_name))
12817         {
12818           locator_set_name_set = 1;
12819         }
12820       else
12821         break;
12822     }
12823
12824   if (locator_set_name_set == 0)
12825     {
12826       errmsg ("missing locator-set name\n");
12827       return -99;
12828     }
12829
12830   if (0 == eid_set)
12831     {
12832       errmsg ("EID address not set!");
12833       vec_free (locator_set_name);
12834       return -99;
12835     }
12836
12837   if (vec_len (locator_set_name) > 64)
12838     {
12839       errmsg ("locator-set name too long\n");
12840       vec_free (locator_set_name);
12841       return -99;
12842     }
12843   vec_add1 (locator_set_name, 0);
12844
12845   /* Construct the API message */
12846   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
12847
12848   mp->is_add = is_add;
12849   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
12850   mp->eid_type = eid->type;
12851   mp->prefix_len = eid->len;
12852   mp->vni = clib_host_to_net_u32 (vni);
12853   clib_memcpy (mp->locator_set_name, locator_set_name,
12854                vec_len (locator_set_name));
12855
12856   vec_free (locator_set_name);
12857
12858   /* send it... */
12859   S;
12860
12861   /* Wait for a reply... */
12862   W;
12863
12864   /* NOTREACHED */
12865   return 0;
12866 }
12867
12868 /* *INDENT-OFF* */
12869 /** Used for transferring locators via VPP API */
12870 typedef CLIB_PACKED(struct
12871 {
12872   u8 is_ip4; /**< is locator an IPv4 address? */
12873   u8 priority; /**< locator priority */
12874   u8 weight;   /**< locator weight */
12875   u8 addr[16]; /**< IPv4/IPv6 address */
12876 }) rloc_t;
12877 /* *INDENT-ON* */
12878
12879 static int
12880 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
12881 {
12882   unformat_input_t *input = vam->input;
12883   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
12884   f64 timeout = ~0;
12885   u8 is_add = 1;
12886   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
12887   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
12888   u8 rmt_eid_set = 0, lcl_eid_set = 0;
12889   u32 action = ~0, p, w;
12890   ip4_address_t rmt_rloc4, lcl_rloc4;
12891   ip6_address_t rmt_rloc6, lcl_rloc6;
12892   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
12893
12894   memset (&rloc, 0, sizeof (rloc));
12895
12896   /* Parse args required to build the message */
12897   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12898     {
12899       if (unformat (input, "del"))
12900         {
12901           is_add = 0;
12902         }
12903       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
12904         {
12905           rmt_eid_set = 1;
12906         }
12907       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
12908         {
12909           lcl_eid_set = 1;
12910         }
12911       else if (unformat (input, "p %d w %d", &p, &w))
12912         {
12913           if (!curr_rloc)
12914             {
12915               errmsg ("No RLOC configured for setting priority/weight!");
12916               return -99;
12917             }
12918           curr_rloc->priority = p;
12919           curr_rloc->weight = w;
12920         }
12921       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
12922                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
12923         {
12924           rloc.is_ip4 = 1;
12925
12926           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
12927           rloc.priority = rloc.weight = 0;
12928           vec_add1 (lcl_locs, rloc);
12929
12930           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
12931           vec_add1 (rmt_locs, rloc);
12932           /* priority and weight saved in rmt loc */
12933           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12934         }
12935       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
12936                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
12937         {
12938           rloc.is_ip4 = 0;
12939           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
12940           rloc.priority = rloc.weight = 0;
12941           vec_add1 (lcl_locs, rloc);
12942
12943           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
12944           vec_add1 (rmt_locs, rloc);
12945           /* priority and weight saved in rmt loc */
12946           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
12947         }
12948       else if (unformat (input, "action %d", &action))
12949         {
12950           ;
12951         }
12952       else
12953         {
12954           clib_warning ("parse error '%U'", format_unformat_error, input);
12955           return -99;
12956         }
12957     }
12958
12959   if (!rmt_eid_set)
12960     {
12961       errmsg ("remote eid addresses not set\n");
12962       return -99;
12963     }
12964
12965   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
12966     {
12967       errmsg ("eid types don't match\n");
12968       return -99;
12969     }
12970
12971   if (0 == rmt_locs && (u32) ~ 0 == action)
12972     {
12973       errmsg ("action not set for negative mapping\n");
12974       return -99;
12975     }
12976
12977   /* Construct the API message */
12978   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
12979
12980   mp->is_add = is_add;
12981   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
12982   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
12983   mp->eid_type = rmt_eid->type;
12984   mp->rmt_len = rmt_eid->len;
12985   mp->lcl_len = lcl_eid->len;
12986   mp->action = action;
12987
12988   if (0 != rmt_locs && 0 != lcl_locs)
12989     {
12990       mp->loc_num = vec_len (rmt_locs);
12991       clib_memcpy (mp->lcl_locs, lcl_locs,
12992                    (sizeof (rloc_t) * vec_len (lcl_locs)));
12993       clib_memcpy (mp->rmt_locs, rmt_locs,
12994                    (sizeof (rloc_t) * vec_len (rmt_locs)));
12995     }
12996   vec_free (lcl_locs);
12997   vec_free (rmt_locs);
12998
12999   /* send it... */
13000   S;
13001
13002   /* Wait for a reply... */
13003   W;
13004
13005   /* NOTREACHED */
13006   return 0;
13007 }
13008
13009 static int
13010 api_lisp_add_del_map_resolver (vat_main_t * vam)
13011 {
13012   unformat_input_t *input = vam->input;
13013   vl_api_lisp_add_del_map_resolver_t *mp;
13014   f64 timeout = ~0;
13015   u8 is_add = 1;
13016   u8 ipv4_set = 0;
13017   u8 ipv6_set = 0;
13018   ip4_address_t ipv4;
13019   ip6_address_t ipv6;
13020
13021   /* Parse args required to build the message */
13022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13023     {
13024       if (unformat (input, "del"))
13025         {
13026           is_add = 0;
13027         }
13028       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13029         {
13030           ipv4_set = 1;
13031         }
13032       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13033         {
13034           ipv6_set = 1;
13035         }
13036       else
13037         break;
13038     }
13039
13040   if (ipv4_set && ipv6_set)
13041     {
13042       errmsg ("both eid v4 and v6 addresses set\n");
13043       return -99;
13044     }
13045
13046   if (!ipv4_set && !ipv6_set)
13047     {
13048       errmsg ("eid addresses not set\n");
13049       return -99;
13050     }
13051
13052   /* Construct the API message */
13053   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13054
13055   mp->is_add = is_add;
13056   if (ipv6_set)
13057     {
13058       mp->is_ipv6 = 1;
13059       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13060     }
13061   else
13062     {
13063       mp->is_ipv6 = 0;
13064       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13065     }
13066
13067   /* send it... */
13068   S;
13069
13070   /* Wait for a reply... */
13071   W;
13072
13073   /* NOTREACHED */
13074   return 0;
13075 }
13076
13077 static int
13078 api_lisp_gpe_enable_disable (vat_main_t * vam)
13079 {
13080   unformat_input_t *input = vam->input;
13081   vl_api_lisp_gpe_enable_disable_t *mp;
13082   f64 timeout = ~0;
13083   u8 is_set = 0;
13084   u8 is_en = 1;
13085
13086   /* Parse args required to build the message */
13087   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13088     {
13089       if (unformat (input, "enable"))
13090         {
13091           is_set = 1;
13092           is_en = 1;
13093         }
13094       else if (unformat (input, "disable"))
13095         {
13096           is_set = 1;
13097           is_en = 0;
13098         }
13099       else
13100         break;
13101     }
13102
13103   if (is_set == 0)
13104     {
13105       errmsg ("Value not set\n");
13106       return -99;
13107     }
13108
13109   /* Construct the API message */
13110   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13111
13112   mp->is_en = is_en;
13113
13114   /* send it... */
13115   S;
13116
13117   /* Wait for a reply... */
13118   W;
13119
13120   /* NOTREACHED */
13121   return 0;
13122 }
13123
13124 static int
13125 api_lisp_enable_disable (vat_main_t * vam)
13126 {
13127   unformat_input_t *input = vam->input;
13128   vl_api_lisp_enable_disable_t *mp;
13129   f64 timeout = ~0;
13130   u8 is_set = 0;
13131   u8 is_en = 0;
13132
13133   /* Parse args required to build the message */
13134   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13135     {
13136       if (unformat (input, "enable"))
13137         {
13138           is_set = 1;
13139           is_en = 1;
13140         }
13141       else if (unformat (input, "disable"))
13142         {
13143           is_set = 1;
13144         }
13145       else
13146         break;
13147     }
13148
13149   if (!is_set)
13150     {
13151       errmsg ("Value not set\n");
13152       return -99;
13153     }
13154
13155   /* Construct the API message */
13156   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13157
13158   mp->is_en = is_en;
13159
13160   /* send it... */
13161   S;
13162
13163   /* Wait for a reply... */
13164   W;
13165
13166   /* NOTREACHED */
13167   return 0;
13168 }
13169
13170 static int
13171 api_show_lisp_map_request_mode (vat_main_t * vam)
13172 {
13173   f64 timeout = ~0;
13174   vl_api_show_lisp_map_request_mode_t *mp;
13175
13176   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13177
13178   /* send */
13179   S;
13180
13181   /* wait for reply */
13182   W;
13183
13184   return 0;
13185 }
13186
13187 static int
13188 api_lisp_map_request_mode (vat_main_t * vam)
13189 {
13190   f64 timeout = ~0;
13191   unformat_input_t *input = vam->input;
13192   vl_api_lisp_map_request_mode_t *mp;
13193   u8 mode = 0;
13194
13195   /* Parse args required to build the message */
13196   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13197     {
13198       if (unformat (input, "dst-only"))
13199         mode = 0;
13200       else if (unformat (input, "src-dst"))
13201         mode = 1;
13202       else
13203         {
13204           errmsg ("parse error '%U'", format_unformat_error, input);
13205           return -99;
13206         }
13207     }
13208
13209   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13210
13211   mp->mode = mode;
13212
13213   /* send */
13214   S;
13215
13216   /* wait for reply */
13217   W;
13218
13219   /* notreached */
13220   return 0;
13221 }
13222
13223 /**
13224  * Enable/disable LISP proxy ITR.
13225  *
13226  * @param vam vpp API test context
13227  * @return return code
13228  */
13229 static int
13230 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13231 {
13232   f64 timeout = ~0;
13233   u8 ls_name_set = 0;
13234   unformat_input_t *input = vam->input;
13235   vl_api_lisp_pitr_set_locator_set_t *mp;
13236   u8 is_add = 1;
13237   u8 *ls_name = 0;
13238
13239   /* Parse args required to build the message */
13240   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13241     {
13242       if (unformat (input, "del"))
13243         is_add = 0;
13244       else if (unformat (input, "locator-set %s", &ls_name))
13245         ls_name_set = 1;
13246       else
13247         {
13248           errmsg ("parse error '%U'", format_unformat_error, input);
13249           return -99;
13250         }
13251     }
13252
13253   if (!ls_name_set)
13254     {
13255       errmsg ("locator-set name not set!");
13256       return -99;
13257     }
13258
13259   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13260
13261   mp->is_add = is_add;
13262   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13263   vec_free (ls_name);
13264
13265   /* send */
13266   S;
13267
13268   /* wait for reply */
13269   W;
13270
13271   /* notreached */
13272   return 0;
13273 }
13274
13275 static int
13276 api_show_lisp_pitr (vat_main_t * vam)
13277 {
13278   vl_api_show_lisp_pitr_t *mp;
13279   f64 timeout = ~0;
13280
13281   if (!vam->json_output)
13282     {
13283       fformat (vam->ofp, "%=20s\n", "lisp status:");
13284     }
13285
13286   M (SHOW_LISP_PITR, show_lisp_pitr);
13287   /* send it... */
13288   S;
13289
13290   /* Wait for a reply... */
13291   W;
13292
13293   /* NOTREACHED */
13294   return 0;
13295 }
13296
13297 /**
13298  * Add/delete mapping between vni and vrf
13299  */
13300 static int
13301 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13302 {
13303   f64 timeout = ~0;
13304   unformat_input_t *input = vam->input;
13305   vl_api_lisp_eid_table_add_del_map_t *mp;
13306   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13307   u32 vni, vrf, bd_index;
13308
13309   /* Parse args required to build the message */
13310   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13311     {
13312       if (unformat (input, "del"))
13313         is_add = 0;
13314       else if (unformat (input, "vrf %d", &vrf))
13315         vrf_set = 1;
13316       else if (unformat (input, "bd_index %d", &bd_index))
13317         bd_index_set = 1;
13318       else if (unformat (input, "vni %d", &vni))
13319         vni_set = 1;
13320       else
13321         break;
13322     }
13323
13324   if (!vni_set || (!vrf_set && !bd_index_set))
13325     {
13326       errmsg ("missing arguments!");
13327       return -99;
13328     }
13329
13330   if (vrf_set && bd_index_set)
13331     {
13332       errmsg ("error: both vrf and bd entered!");
13333       return -99;
13334     }
13335
13336   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13337
13338   mp->is_add = is_add;
13339   mp->vni = htonl (vni);
13340   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13341   mp->is_l2 = bd_index_set;
13342
13343   /* send */
13344   S;
13345
13346   /* wait for reply */
13347   W;
13348
13349   /* notreached */
13350   return 0;
13351 }
13352
13353 uword
13354 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13355 {
13356   u32 *action = va_arg (*args, u32 *);
13357   u8 *s = 0;
13358
13359   if (unformat (input, "%s", &s))
13360     {
13361       if (!strcmp ((char *) s, "no-action"))
13362         action[0] = 0;
13363       else if (!strcmp ((char *) s, "natively-forward"))
13364         action[0] = 1;
13365       else if (!strcmp ((char *) s, "send-map-request"))
13366         action[0] = 2;
13367       else if (!strcmp ((char *) s, "drop"))
13368         action[0] = 3;
13369       else
13370         {
13371           clib_warning ("invalid action: '%s'", s);
13372           action[0] = 3;
13373         }
13374     }
13375   else
13376     return 0;
13377
13378   vec_free (s);
13379   return 1;
13380 }
13381
13382 /**
13383  * Add/del remote mapping to/from LISP control plane
13384  *
13385  * @param vam vpp API test context
13386  * @return return code
13387  */
13388 static int
13389 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13390 {
13391   unformat_input_t *input = vam->input;
13392   vl_api_lisp_add_del_remote_mapping_t *mp;
13393   f64 timeout = ~0;
13394   u32 vni = 0;
13395   lisp_eid_vat_t _eid, *eid = &_eid;
13396   lisp_eid_vat_t _seid, *seid = &_seid;
13397   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13398   u32 action = ~0, p, w, data_len;
13399   ip4_address_t rloc4;
13400   ip6_address_t rloc6;
13401   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13402
13403   memset (&rloc, 0, sizeof (rloc));
13404
13405   /* Parse args required to build the message */
13406   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13407     {
13408       if (unformat (input, "del-all"))
13409         {
13410           del_all = 1;
13411         }
13412       else if (unformat (input, "del"))
13413         {
13414           is_add = 0;
13415         }
13416       else if (unformat (input, "add"))
13417         {
13418           is_add = 1;
13419         }
13420       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13421         {
13422           eid_set = 1;
13423         }
13424       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13425         {
13426           seid_set = 1;
13427         }
13428       else if (unformat (input, "vni %d", &vni))
13429         {
13430           ;
13431         }
13432       else if (unformat (input, "p %d w %d", &p, &w))
13433         {
13434           if (!curr_rloc)
13435             {
13436               errmsg ("No RLOC configured for setting priority/weight!");
13437               return -99;
13438             }
13439           curr_rloc->priority = p;
13440           curr_rloc->weight = w;
13441         }
13442       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13443         {
13444           rloc.is_ip4 = 1;
13445           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13446           vec_add1 (rlocs, rloc);
13447           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13448         }
13449       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13450         {
13451           rloc.is_ip4 = 0;
13452           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13453           vec_add1 (rlocs, rloc);
13454           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13455         }
13456       else if (unformat (input, "action %U",
13457                          unformat_negative_mapping_action, &action))
13458         {
13459           ;
13460         }
13461       else
13462         {
13463           clib_warning ("parse error '%U'", format_unformat_error, input);
13464           return -99;
13465         }
13466     }
13467
13468   if (0 == eid_set)
13469     {
13470       errmsg ("missing params!");
13471       return -99;
13472     }
13473
13474   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13475     {
13476       errmsg ("no action set for negative map-reply!");
13477       return -99;
13478     }
13479
13480   data_len = vec_len (rlocs) * sizeof (rloc_t);
13481
13482   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13483   mp->is_add = is_add;
13484   mp->vni = htonl (vni);
13485   mp->action = (u8) action;
13486   mp->is_src_dst = seid_set;
13487   mp->eid_len = eid->len;
13488   mp->seid_len = seid->len;
13489   mp->del_all = del_all;
13490   mp->eid_type = eid->type;
13491   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13492   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13493
13494   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13495   clib_memcpy (mp->rlocs, rlocs, data_len);
13496   vec_free (rlocs);
13497
13498   /* send it... */
13499   S;
13500
13501   /* Wait for a reply... */
13502   W;
13503
13504   /* NOTREACHED */
13505   return 0;
13506 }
13507
13508 /**
13509  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
13510  * forwarding entries in data-plane accordingly.
13511  *
13512  * @param vam vpp API test context
13513  * @return return code
13514  */
13515 static int
13516 api_lisp_add_del_adjacency (vat_main_t * vam)
13517 {
13518   unformat_input_t *input = vam->input;
13519   vl_api_lisp_add_del_adjacency_t *mp;
13520   f64 timeout = ~0;
13521   u32 vni = 0;
13522   ip4_address_t leid4, reid4;
13523   ip6_address_t leid6, reid6;
13524   u8 reid_mac[6] = { 0 };
13525   u8 leid_mac[6] = { 0 };
13526   u8 reid_type, leid_type;
13527   u32 leid_len = 0, reid_len = 0, len;
13528   u8 is_add = 1;
13529
13530   leid_type = reid_type = (u8) ~ 0;
13531
13532   /* Parse args required to build the message */
13533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13534     {
13535       if (unformat (input, "del"))
13536         {
13537           is_add = 0;
13538         }
13539       else if (unformat (input, "add"))
13540         {
13541           is_add = 1;
13542         }
13543       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
13544                          &reid4, &len))
13545         {
13546           reid_type = 0;        /* ipv4 */
13547           reid_len = len;
13548         }
13549       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
13550                          &reid6, &len))
13551         {
13552           reid_type = 1;        /* ipv6 */
13553           reid_len = len;
13554         }
13555       else if (unformat (input, "reid %U", unformat_ethernet_address,
13556                          reid_mac))
13557         {
13558           reid_type = 2;        /* mac */
13559         }
13560       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
13561                          &leid4, &len))
13562         {
13563           leid_type = 0;        /* ipv4 */
13564           leid_len = len;
13565         }
13566       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
13567                          &leid6, &len))
13568         {
13569           leid_type = 1;        /* ipv6 */
13570           leid_len = len;
13571         }
13572       else if (unformat (input, "leid %U", unformat_ethernet_address,
13573                          leid_mac))
13574         {
13575           leid_type = 2;        /* mac */
13576         }
13577       else if (unformat (input, "vni %d", &vni))
13578         {
13579           ;
13580         }
13581       else
13582         {
13583           errmsg ("parse error '%U'", format_unformat_error, input);
13584           return -99;
13585         }
13586     }
13587
13588   if ((u8) ~ 0 == reid_type)
13589     {
13590       errmsg ("missing params!");
13591       return -99;
13592     }
13593
13594   if (leid_type != reid_type)
13595     {
13596       errmsg ("remote and local EIDs are of different types!");
13597       return -99;
13598     }
13599
13600   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
13601   mp->is_add = is_add;
13602   mp->vni = htonl (vni);
13603   mp->leid_len = leid_len;
13604   mp->reid_len = reid_len;
13605   mp->eid_type = reid_type;
13606
13607   switch (mp->eid_type)
13608     {
13609     case 0:
13610       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
13611       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
13612       break;
13613     case 1:
13614       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
13615       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
13616       break;
13617     case 2:
13618       clib_memcpy (mp->leid, leid_mac, 6);
13619       clib_memcpy (mp->reid, reid_mac, 6);
13620       break;
13621     default:
13622       errmsg ("unknown EID type %d!", mp->eid_type);
13623       return 0;
13624     }
13625
13626   /* send it... */
13627   S;
13628
13629   /* Wait for a reply... */
13630   W;
13631
13632   /* NOTREACHED */
13633   return 0;
13634 }
13635
13636 static int
13637 api_lisp_gpe_add_del_iface (vat_main_t * vam)
13638 {
13639   unformat_input_t *input = vam->input;
13640   vl_api_lisp_gpe_add_del_iface_t *mp;
13641   f64 timeout = ~0;
13642   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
13643   u32 dp_table = 0, vni = 0;
13644
13645   /* Parse args required to build the message */
13646   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13647     {
13648       if (unformat (input, "up"))
13649         {
13650           action_set = 1;
13651           is_add = 1;
13652         }
13653       else if (unformat (input, "down"))
13654         {
13655           action_set = 1;
13656           is_add = 0;
13657         }
13658       else if (unformat (input, "table_id %d", &dp_table))
13659         {
13660           dp_table_set = 1;
13661         }
13662       else if (unformat (input, "bd_id %d", &dp_table))
13663         {
13664           dp_table_set = 1;
13665           is_l2 = 1;
13666         }
13667       else if (unformat (input, "vni %d", &vni))
13668         {
13669           vni_set = 1;
13670         }
13671       else
13672         break;
13673     }
13674
13675   if (action_set == 0)
13676     {
13677       errmsg ("Action not set\n");
13678       return -99;
13679     }
13680   if (dp_table_set == 0 || vni_set == 0)
13681     {
13682       errmsg ("vni and dp_table must be set\n");
13683       return -99;
13684     }
13685
13686   /* Construct the API message */
13687   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
13688
13689   mp->is_add = is_add;
13690   mp->dp_table = dp_table;
13691   mp->is_l2 = is_l2;
13692   mp->vni = vni;
13693
13694   /* send it... */
13695   S;
13696
13697   /* Wait for a reply... */
13698   W;
13699
13700   /* NOTREACHED */
13701   return 0;
13702 }
13703
13704 /**
13705  * Add/del map request itr rlocs from LISP control plane and updates
13706  *
13707  * @param vam vpp API test context
13708  * @return return code
13709  */
13710 static int
13711 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
13712 {
13713   unformat_input_t *input = vam->input;
13714   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
13715   f64 timeout = ~0;
13716   u8 *locator_set_name = 0;
13717   u8 locator_set_name_set = 0;
13718   u8 is_add = 1;
13719
13720   /* Parse args required to build the message */
13721   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13722     {
13723       if (unformat (input, "del"))
13724         {
13725           is_add = 0;
13726         }
13727       else if (unformat (input, "%_%v%_", &locator_set_name))
13728         {
13729           locator_set_name_set = 1;
13730         }
13731       else
13732         {
13733           clib_warning ("parse error '%U'", format_unformat_error, input);
13734           return -99;
13735         }
13736     }
13737
13738   if (is_add && !locator_set_name_set)
13739     {
13740       errmsg ("itr-rloc is not set!");
13741       return -99;
13742     }
13743
13744   if (is_add && vec_len (locator_set_name) > 64)
13745     {
13746       errmsg ("itr-rloc locator-set name too long\n");
13747       vec_free (locator_set_name);
13748       return -99;
13749     }
13750
13751   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
13752   mp->is_add = is_add;
13753   if (is_add)
13754     {
13755       clib_memcpy (mp->locator_set_name, locator_set_name,
13756                    vec_len (locator_set_name));
13757     }
13758   else
13759     {
13760       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
13761     }
13762   vec_free (locator_set_name);
13763
13764   /* send it... */
13765   S;
13766
13767   /* Wait for a reply... */
13768   W;
13769
13770   /* NOTREACHED */
13771   return 0;
13772 }
13773
13774 static int
13775 api_lisp_locator_dump (vat_main_t * vam)
13776 {
13777   unformat_input_t *input = vam->input;
13778   vl_api_lisp_locator_dump_t *mp;
13779   f64 timeout = ~0;
13780   u8 is_index_set = 0, is_name_set = 0;
13781   u8 *ls_name = 0;
13782   u32 ls_index = ~0;
13783
13784   /* Parse args required to build the message */
13785   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13786     {
13787       if (unformat (input, "ls_name %_%v%_", &ls_name))
13788         {
13789           is_name_set = 1;
13790         }
13791       else if (unformat (input, "ls_index %d", &ls_index))
13792         {
13793           is_index_set = 1;
13794         }
13795       else
13796         {
13797           errmsg ("parse error '%U'", format_unformat_error, input);
13798           return -99;
13799         }
13800     }
13801
13802   if (!is_index_set && !is_name_set)
13803     {
13804       errmsg ("error: expected one of index or name!\n");
13805       return -99;
13806     }
13807
13808   if (is_index_set && is_name_set)
13809     {
13810       errmsg ("error: only one param expected!\n");
13811       return -99;
13812     }
13813
13814   if (vec_len (ls_name) > 62)
13815     {
13816       errmsg ("error: locator set name too long!");
13817       return -99;
13818     }
13819
13820   if (!vam->json_output)
13821     {
13822       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
13823                "weight");
13824     }
13825
13826   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
13827   mp->is_index_set = is_index_set;
13828
13829   if (is_index_set)
13830     mp->ls_index = clib_host_to_net_u32 (ls_index);
13831   else
13832     {
13833       vec_add1 (ls_name, 0);
13834       strncpy ((char *) mp->ls_name, (char *) ls_name,
13835                sizeof (mp->ls_name) - 1);
13836     }
13837
13838   /* send it... */
13839   S;
13840
13841   /* Use a control ping for synchronization */
13842   {
13843     vl_api_control_ping_t *mp;
13844     M (CONTROL_PING, control_ping);
13845     S;
13846   }
13847   /* Wait for a reply... */
13848   W;
13849
13850   /* NOTREACHED */
13851   return 0;
13852 }
13853
13854 static int
13855 api_lisp_locator_set_dump (vat_main_t * vam)
13856 {
13857   vl_api_lisp_locator_set_dump_t *mp;
13858   unformat_input_t *input = vam->input;
13859   f64 timeout = ~0;
13860   u8 filter = 0;
13861
13862   /* Parse args required to build the message */
13863   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13864     {
13865       if (unformat (input, "local"))
13866         {
13867           filter = 1;
13868         }
13869       else if (unformat (input, "remote"))
13870         {
13871           filter = 2;
13872         }
13873       else
13874         {
13875           errmsg ("parse error '%U'", format_unformat_error, input);
13876           return -99;
13877         }
13878     }
13879
13880   if (!vam->json_output)
13881     {
13882       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
13883     }
13884
13885   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
13886
13887   mp->filter = filter;
13888
13889   /* send it... */
13890   S;
13891
13892   /* Use a control ping for synchronization */
13893   {
13894     vl_api_control_ping_t *mp;
13895     M (CONTROL_PING, control_ping);
13896     S;
13897   }
13898   /* Wait for a reply... */
13899   W;
13900
13901   /* NOTREACHED */
13902   return 0;
13903 }
13904
13905 static int
13906 api_lisp_eid_table_map_dump (vat_main_t * vam)
13907 {
13908   u8 is_l2 = 0;
13909   u8 mode_set = 0;
13910   unformat_input_t *input = vam->input;
13911   vl_api_lisp_eid_table_map_dump_t *mp;
13912   f64 timeout = ~0;
13913
13914   /* Parse args required to build the message */
13915   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13916     {
13917       if (unformat (input, "l2"))
13918         {
13919           is_l2 = 1;
13920           mode_set = 1;
13921         }
13922       else if (unformat (input, "l3"))
13923         {
13924           is_l2 = 0;
13925           mode_set = 1;
13926         }
13927       else
13928         {
13929           errmsg ("parse error '%U'", format_unformat_error, input);
13930           return -99;
13931         }
13932     }
13933
13934   if (!mode_set)
13935     {
13936       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
13937       return -99;
13938     }
13939
13940   if (!vam->json_output)
13941     {
13942       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
13943     }
13944
13945   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
13946   mp->is_l2 = is_l2;
13947
13948   /* send it... */
13949   S;
13950
13951   /* Use a control ping for synchronization */
13952   {
13953     vl_api_control_ping_t *mp;
13954     M (CONTROL_PING, control_ping);
13955     S;
13956   }
13957   /* Wait for a reply... */
13958   W;
13959
13960   /* NOTREACHED */
13961   return 0;
13962 }
13963
13964 static int
13965 api_lisp_eid_table_vni_dump (vat_main_t * vam)
13966 {
13967   vl_api_lisp_eid_table_vni_dump_t *mp;
13968   f64 timeout = ~0;
13969
13970   if (!vam->json_output)
13971     {
13972       fformat (vam->ofp, "VNI\n");
13973     }
13974
13975   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
13976
13977   /* send it... */
13978   S;
13979
13980   /* Use a control ping for synchronization */
13981   {
13982     vl_api_control_ping_t *mp;
13983     M (CONTROL_PING, control_ping);
13984     S;
13985   }
13986   /* Wait for a reply... */
13987   W;
13988
13989   /* NOTREACHED */
13990   return 0;
13991 }
13992
13993 static int
13994 api_lisp_eid_table_dump (vat_main_t * vam)
13995 {
13996   unformat_input_t *i = vam->input;
13997   vl_api_lisp_eid_table_dump_t *mp;
13998   f64 timeout = ~0;
13999   struct in_addr ip4;
14000   struct in6_addr ip6;
14001   u8 mac[6];
14002   u8 eid_type = ~0, eid_set = 0;
14003   u32 prefix_length = ~0, t, vni = 0;
14004   u8 filter = 0;
14005
14006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14007     {
14008       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14009         {
14010           eid_set = 1;
14011           eid_type = 0;
14012           prefix_length = t;
14013         }
14014       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14015         {
14016           eid_set = 1;
14017           eid_type = 1;
14018           prefix_length = t;
14019         }
14020       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14021         {
14022           eid_set = 1;
14023           eid_type = 2;
14024         }
14025       else if (unformat (i, "vni %d", &t))
14026         {
14027           vni = t;
14028         }
14029       else if (unformat (i, "local"))
14030         {
14031           filter = 1;
14032         }
14033       else if (unformat (i, "remote"))
14034         {
14035           filter = 2;
14036         }
14037       else
14038         {
14039           errmsg ("parse error '%U'", format_unformat_error, i);
14040           return -99;
14041         }
14042     }
14043
14044   if (!vam->json_output)
14045     {
14046       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-s\n", "EID", "type",
14047                "ls_index", "ttl", "authoritative");
14048     }
14049
14050   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14051
14052   mp->filter = filter;
14053   if (eid_set)
14054     {
14055       mp->eid_set = 1;
14056       mp->vni = htonl (vni);
14057       mp->eid_type = eid_type;
14058       switch (eid_type)
14059         {
14060         case 0:
14061           mp->prefix_length = prefix_length;
14062           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14063           break;
14064         case 1:
14065           mp->prefix_length = prefix_length;
14066           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14067           break;
14068         case 2:
14069           clib_memcpy (mp->eid, mac, sizeof (mac));
14070           break;
14071         default:
14072           errmsg ("unknown EID type %d!", eid_type);
14073           return -99;
14074         }
14075     }
14076
14077   /* send it... */
14078   S;
14079
14080   /* Use a control ping for synchronization */
14081   {
14082     vl_api_control_ping_t *mp;
14083     M (CONTROL_PING, control_ping);
14084     S;
14085   }
14086
14087   /* Wait for a reply... */
14088   W;
14089
14090   /* NOTREACHED */
14091   return 0;
14092 }
14093
14094 static int
14095 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14096 {
14097   vl_api_lisp_gpe_tunnel_dump_t *mp;
14098   f64 timeout = ~0;
14099
14100   if (!vam->json_output)
14101     {
14102       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14103                "%=16s%=16s%=16s%=16s%=16s\n",
14104                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14105                "Decap next", "Lisp version", "Flags", "Next protocol",
14106                "ver_res", "res", "iid");
14107     }
14108
14109   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14110   /* send it... */
14111   S;
14112
14113   /* Use a control ping for synchronization */
14114   {
14115     vl_api_control_ping_t *mp;
14116     M (CONTROL_PING, control_ping);
14117     S;
14118   }
14119   /* Wait for a reply... */
14120   W;
14121
14122   /* NOTREACHED */
14123   return 0;
14124 }
14125
14126 static int
14127 api_lisp_adjacencies_get (vat_main_t * vam)
14128 {
14129   unformat_input_t *i = vam->input;
14130   vl_api_lisp_adjacencies_get_t *mp;
14131   f64 timeout = ~0;
14132   u8 vni_set = 0;
14133   u32 vni = ~0;
14134
14135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14136     {
14137       if (unformat (i, "vni %d", &vni))
14138         {
14139           vni_set = 1;
14140         }
14141       else
14142         {
14143           errmsg ("parse error '%U'\n", format_unformat_error, i);
14144           return -99;
14145         }
14146     }
14147
14148   if (!vni_set)
14149     {
14150       errmsg ("vni not set!\n");
14151       return -99;
14152     }
14153
14154   if (!vam->json_output)
14155     {
14156       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14157     }
14158
14159   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14160   mp->vni = clib_host_to_net_u32 (vni);
14161
14162   /* send it... */
14163   S;
14164
14165   /* Wait for a reply... */
14166   W;
14167
14168   /* NOTREACHED */
14169   return 0;
14170 }
14171
14172 static int
14173 api_lisp_map_resolver_dump (vat_main_t * vam)
14174 {
14175   vl_api_lisp_map_resolver_dump_t *mp;
14176   f64 timeout = ~0;
14177
14178   if (!vam->json_output)
14179     {
14180       fformat (vam->ofp, "%=20s\n", "Map resolver");
14181     }
14182
14183   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14184   /* send it... */
14185   S;
14186
14187   /* Use a control ping for synchronization */
14188   {
14189     vl_api_control_ping_t *mp;
14190     M (CONTROL_PING, control_ping);
14191     S;
14192   }
14193   /* Wait for a reply... */
14194   W;
14195
14196   /* NOTREACHED */
14197   return 0;
14198 }
14199
14200 static int
14201 api_show_lisp_status (vat_main_t * vam)
14202 {
14203   vl_api_show_lisp_status_t *mp;
14204   f64 timeout = ~0;
14205
14206   if (!vam->json_output)
14207     {
14208       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14209     }
14210
14211   M (SHOW_LISP_STATUS, show_lisp_status);
14212   /* send it... */
14213   S;
14214   /* Wait for a reply... */
14215   W;
14216
14217   /* NOTREACHED */
14218   return 0;
14219 }
14220
14221 static int
14222 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14223 {
14224   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14225   f64 timeout = ~0;
14226
14227   if (!vam->json_output)
14228     {
14229       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14230     }
14231
14232   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14233   /* send it... */
14234   S;
14235   /* Wait for a reply... */
14236   W;
14237
14238   /* NOTREACHED */
14239   return 0;
14240 }
14241
14242 static int
14243 api_af_packet_create (vat_main_t * vam)
14244 {
14245   unformat_input_t *i = vam->input;
14246   vl_api_af_packet_create_t *mp;
14247   f64 timeout;
14248   u8 *host_if_name = 0;
14249   u8 hw_addr[6];
14250   u8 random_hw_addr = 1;
14251
14252   memset (hw_addr, 0, sizeof (hw_addr));
14253
14254   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14255     {
14256       if (unformat (i, "name %s", &host_if_name))
14257         vec_add1 (host_if_name, 0);
14258       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14259         random_hw_addr = 0;
14260       else
14261         break;
14262     }
14263
14264   if (!vec_len (host_if_name))
14265     {
14266       errmsg ("host-interface name must be specified");
14267       return -99;
14268     }
14269
14270   if (vec_len (host_if_name) > 64)
14271     {
14272       errmsg ("host-interface name too long");
14273       return -99;
14274     }
14275
14276   M (AF_PACKET_CREATE, af_packet_create);
14277
14278   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14279   clib_memcpy (mp->hw_addr, hw_addr, 6);
14280   mp->use_random_hw_addr = random_hw_addr;
14281   vec_free (host_if_name);
14282
14283   S;
14284   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14285   /* NOTREACHED */
14286   return 0;
14287 }
14288
14289 static int
14290 api_af_packet_delete (vat_main_t * vam)
14291 {
14292   unformat_input_t *i = vam->input;
14293   vl_api_af_packet_delete_t *mp;
14294   f64 timeout;
14295   u8 *host_if_name = 0;
14296
14297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14298     {
14299       if (unformat (i, "name %s", &host_if_name))
14300         vec_add1 (host_if_name, 0);
14301       else
14302         break;
14303     }
14304
14305   if (!vec_len (host_if_name))
14306     {
14307       errmsg ("host-interface name must be specified");
14308       return -99;
14309     }
14310
14311   if (vec_len (host_if_name) > 64)
14312     {
14313       errmsg ("host-interface name too long");
14314       return -99;
14315     }
14316
14317   M (AF_PACKET_DELETE, af_packet_delete);
14318
14319   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14320   vec_free (host_if_name);
14321
14322   S;
14323   W;
14324   /* NOTREACHED */
14325   return 0;
14326 }
14327
14328 static int
14329 api_policer_add_del (vat_main_t * vam)
14330 {
14331   unformat_input_t *i = vam->input;
14332   vl_api_policer_add_del_t *mp;
14333   f64 timeout;
14334   u8 is_add = 1;
14335   u8 *name = 0;
14336   u32 cir = 0;
14337   u32 eir = 0;
14338   u64 cb = 0;
14339   u64 eb = 0;
14340   u8 rate_type = 0;
14341   u8 round_type = 0;
14342   u8 type = 0;
14343   u8 color_aware = 0;
14344   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14345
14346   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14347   conform_action.dscp = 0;
14348   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14349   exceed_action.dscp = 0;
14350   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14351   violate_action.dscp = 0;
14352
14353   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14354     {
14355       if (unformat (i, "del"))
14356         is_add = 0;
14357       else if (unformat (i, "name %s", &name))
14358         vec_add1 (name, 0);
14359       else if (unformat (i, "cir %u", &cir))
14360         ;
14361       else if (unformat (i, "eir %u", &eir))
14362         ;
14363       else if (unformat (i, "cb %u", &cb))
14364         ;
14365       else if (unformat (i, "eb %u", &eb))
14366         ;
14367       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14368                          &rate_type))
14369         ;
14370       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14371                          &round_type))
14372         ;
14373       else if (unformat (i, "type %U", unformat_policer_type, &type))
14374         ;
14375       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14376                          &conform_action))
14377         ;
14378       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14379                          &exceed_action))
14380         ;
14381       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14382                          &violate_action))
14383         ;
14384       else if (unformat (i, "color-aware"))
14385         color_aware = 1;
14386       else
14387         break;
14388     }
14389
14390   if (!vec_len (name))
14391     {
14392       errmsg ("policer name must be specified");
14393       return -99;
14394     }
14395
14396   if (vec_len (name) > 64)
14397     {
14398       errmsg ("policer name too long");
14399       return -99;
14400     }
14401
14402   M (POLICER_ADD_DEL, policer_add_del);
14403
14404   clib_memcpy (mp->name, name, vec_len (name));
14405   vec_free (name);
14406   mp->is_add = is_add;
14407   mp->cir = cir;
14408   mp->eir = eir;
14409   mp->cb = cb;
14410   mp->eb = eb;
14411   mp->rate_type = rate_type;
14412   mp->round_type = round_type;
14413   mp->type = type;
14414   mp->conform_action_type = conform_action.action_type;
14415   mp->conform_dscp = conform_action.dscp;
14416   mp->exceed_action_type = exceed_action.action_type;
14417   mp->exceed_dscp = exceed_action.dscp;
14418   mp->violate_action_type = violate_action.action_type;
14419   mp->violate_dscp = violate_action.dscp;
14420   mp->color_aware = color_aware;
14421
14422   S;
14423   W;
14424   /* NOTREACHED */
14425   return 0;
14426 }
14427
14428 static int
14429 api_policer_dump (vat_main_t * vam)
14430 {
14431   unformat_input_t *i = vam->input;
14432   vl_api_policer_dump_t *mp;
14433   f64 timeout = ~0;
14434   u8 *match_name = 0;
14435   u8 match_name_valid = 0;
14436
14437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14438     {
14439       if (unformat (i, "name %s", &match_name))
14440         {
14441           vec_add1 (match_name, 0);
14442           match_name_valid = 1;
14443         }
14444       else
14445         break;
14446     }
14447
14448   M (POLICER_DUMP, policer_dump);
14449   mp->match_name_valid = match_name_valid;
14450   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14451   vec_free (match_name);
14452   /* send it... */
14453   S;
14454
14455   /* Use a control ping for synchronization */
14456   {
14457     vl_api_control_ping_t *mp;
14458     M (CONTROL_PING, control_ping);
14459     S;
14460   }
14461   /* Wait for a reply... */
14462   W;
14463
14464   /* NOTREACHED */
14465   return 0;
14466 }
14467
14468 static int
14469 api_policer_classify_set_interface (vat_main_t * vam)
14470 {
14471   unformat_input_t *i = vam->input;
14472   vl_api_policer_classify_set_interface_t *mp;
14473   f64 timeout;
14474   u32 sw_if_index;
14475   int sw_if_index_set;
14476   u32 ip4_table_index = ~0;
14477   u32 ip6_table_index = ~0;
14478   u32 l2_table_index = ~0;
14479   u8 is_add = 1;
14480
14481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14482     {
14483       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
14484         sw_if_index_set = 1;
14485       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14486         sw_if_index_set = 1;
14487       else if (unformat (i, "del"))
14488         is_add = 0;
14489       else if (unformat (i, "ip4-table %d", &ip4_table_index))
14490         ;
14491       else if (unformat (i, "ip6-table %d", &ip6_table_index))
14492         ;
14493       else if (unformat (i, "l2-table %d", &l2_table_index))
14494         ;
14495       else
14496         {
14497           clib_warning ("parse error '%U'", format_unformat_error, i);
14498           return -99;
14499         }
14500     }
14501
14502   if (sw_if_index_set == 0)
14503     {
14504       errmsg ("missing interface name or sw_if_index\n");
14505       return -99;
14506     }
14507
14508   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
14509
14510   mp->sw_if_index = ntohl (sw_if_index);
14511   mp->ip4_table_index = ntohl (ip4_table_index);
14512   mp->ip6_table_index = ntohl (ip6_table_index);
14513   mp->l2_table_index = ntohl (l2_table_index);
14514   mp->is_add = is_add;
14515
14516   S;
14517   W;
14518   /* NOTREACHED */
14519   return 0;
14520 }
14521
14522 static int
14523 api_policer_classify_dump (vat_main_t * vam)
14524 {
14525   unformat_input_t *i = vam->input;
14526   vl_api_policer_classify_dump_t *mp;
14527   f64 timeout = ~0;
14528   u8 type = POLICER_CLASSIFY_N_TABLES;
14529
14530   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
14531     ;
14532   else
14533     {
14534       errmsg ("classify table type must be specified\n");
14535       return -99;
14536     }
14537
14538   if (!vam->json_output)
14539     {
14540       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
14541     }
14542
14543   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
14544   mp->type = type;
14545   /* send it... */
14546   S;
14547
14548   /* Use a control ping for synchronization */
14549   {
14550     vl_api_control_ping_t *mp;
14551     M (CONTROL_PING, control_ping);
14552     S;
14553   }
14554   /* Wait for a reply... */
14555   W;
14556
14557   /* NOTREACHED */
14558   return 0;
14559 }
14560
14561 static int
14562 api_netmap_create (vat_main_t * vam)
14563 {
14564   unformat_input_t *i = vam->input;
14565   vl_api_netmap_create_t *mp;
14566   f64 timeout;
14567   u8 *if_name = 0;
14568   u8 hw_addr[6];
14569   u8 random_hw_addr = 1;
14570   u8 is_pipe = 0;
14571   u8 is_master = 0;
14572
14573   memset (hw_addr, 0, sizeof (hw_addr));
14574
14575   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14576     {
14577       if (unformat (i, "name %s", &if_name))
14578         vec_add1 (if_name, 0);
14579       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14580         random_hw_addr = 0;
14581       else if (unformat (i, "pipe"))
14582         is_pipe = 1;
14583       else if (unformat (i, "master"))
14584         is_master = 1;
14585       else if (unformat (i, "slave"))
14586         is_master = 0;
14587       else
14588         break;
14589     }
14590
14591   if (!vec_len (if_name))
14592     {
14593       errmsg ("interface name must be specified");
14594       return -99;
14595     }
14596
14597   if (vec_len (if_name) > 64)
14598     {
14599       errmsg ("interface name too long");
14600       return -99;
14601     }
14602
14603   M (NETMAP_CREATE, netmap_create);
14604
14605   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14606   clib_memcpy (mp->hw_addr, hw_addr, 6);
14607   mp->use_random_hw_addr = random_hw_addr;
14608   mp->is_pipe = is_pipe;
14609   mp->is_master = is_master;
14610   vec_free (if_name);
14611
14612   S;
14613   W;
14614   /* NOTREACHED */
14615   return 0;
14616 }
14617
14618 static int
14619 api_netmap_delete (vat_main_t * vam)
14620 {
14621   unformat_input_t *i = vam->input;
14622   vl_api_netmap_delete_t *mp;
14623   f64 timeout;
14624   u8 *if_name = 0;
14625
14626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14627     {
14628       if (unformat (i, "name %s", &if_name))
14629         vec_add1 (if_name, 0);
14630       else
14631         break;
14632     }
14633
14634   if (!vec_len (if_name))
14635     {
14636       errmsg ("interface name must be specified");
14637       return -99;
14638     }
14639
14640   if (vec_len (if_name) > 64)
14641     {
14642       errmsg ("interface name too long");
14643       return -99;
14644     }
14645
14646   M (NETMAP_DELETE, netmap_delete);
14647
14648   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
14649   vec_free (if_name);
14650
14651   S;
14652   W;
14653   /* NOTREACHED */
14654   return 0;
14655 }
14656
14657 static void vl_api_mpls_eth_tunnel_details_t_handler
14658   (vl_api_mpls_eth_tunnel_details_t * mp)
14659 {
14660   vat_main_t *vam = &vat_main;
14661   i32 i;
14662   i32 len = ntohl (mp->nlabels);
14663
14664   fformat (vam->ofp, "[%d]: dst %U, adj %U/%d, labels ",
14665            ntohl (mp->tunnel_index),
14666            format_ethernet_address, &mp->tunnel_dst_mac,
14667            format_ip4_address, &mp->intfc_address, ntohl (mp->mask_width));
14668   for (i = 0; i < len; i++)
14669     {
14670       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14671     }
14672   fformat (vam->ofp, "\n");
14673   fformat (vam->ofp, "      tx on %d, rx fib index %d\n",
14674            ntohl (mp->tx_sw_if_index), ntohl (mp->inner_fib_index));
14675 }
14676
14677 static void vl_api_mpls_eth_tunnel_details_t_handler_json
14678   (vl_api_mpls_eth_tunnel_details_t * mp)
14679 {
14680   vat_main_t *vam = &vat_main;
14681   vat_json_node_t *node = NULL;
14682   struct in_addr ip4;
14683   i32 i;
14684   i32 len = ntohl (mp->nlabels);
14685
14686   if (VAT_JSON_ARRAY != vam->json_tree.type)
14687     {
14688       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14689       vat_json_init_array (&vam->json_tree);
14690     }
14691   node = vat_json_array_add (&vam->json_tree);
14692
14693   vat_json_init_object (node);
14694   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
14695   clib_memcpy (&ip4, &(mp->intfc_address), sizeof (ip4));
14696   vat_json_object_add_ip4 (node, "intfc_address", ip4);
14697   vat_json_object_add_uint (node, "inner_fib_index",
14698                             ntohl (mp->inner_fib_index));
14699   vat_json_object_add_uint (node, "mask_width", ntohl (mp->mask_width));
14700   vat_json_object_add_uint (node, "encap_index", ntohl (mp->encap_index));
14701   vat_json_object_add_uint (node, "hw_if_index", ntohl (mp->hw_if_index));
14702   vat_json_object_add_uint (node, "l2_only", ntohl (mp->l2_only));
14703   vat_json_object_add_string_copy (node, "tunnel_dst_mac",
14704                                    format (0, "%U", format_ethernet_address,
14705                                            &mp->tunnel_dst_mac));
14706   vat_json_object_add_uint (node, "tx_sw_if_index",
14707                             ntohl (mp->tx_sw_if_index));
14708   vat_json_object_add_uint (node, "label_count", len);
14709   for (i = 0; i < len; i++)
14710     {
14711       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14712     }
14713 }
14714
14715 static int
14716 api_mpls_eth_tunnel_dump (vat_main_t * vam)
14717 {
14718   vl_api_mpls_eth_tunnel_dump_t *mp;
14719   f64 timeout;
14720   i32 index = -1;
14721
14722   /* Parse args required to build the message */
14723   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
14724     {
14725       if (!unformat (vam->input, "tunnel_index %d", &index))
14726         {
14727           index = -1;
14728           break;
14729         }
14730     }
14731
14732   fformat (vam->ofp, "  tunnel_index %d\n", index);
14733
14734   M (MPLS_ETH_TUNNEL_DUMP, mpls_eth_tunnel_dump);
14735   mp->tunnel_index = htonl (index);
14736   S;
14737
14738   /* Use a control ping for synchronization */
14739   {
14740     vl_api_control_ping_t *mp;
14741     M (CONTROL_PING, control_ping);
14742     S;
14743   }
14744   W;
14745 }
14746
14747 static void vl_api_mpls_fib_encap_details_t_handler
14748   (vl_api_mpls_fib_encap_details_t * mp)
14749 {
14750   vat_main_t *vam = &vat_main;
14751   i32 i;
14752   i32 len = ntohl (mp->nlabels);
14753
14754   fformat (vam->ofp, "table %d, dest %U, label ",
14755            ntohl (mp->fib_index), format_ip4_address, &mp->dest, len);
14756   for (i = 0; i < len; i++)
14757     {
14758       fformat (vam->ofp, "%u ", ntohl (mp->labels[i]));
14759     }
14760   fformat (vam->ofp, "\n");
14761 }
14762
14763 static void vl_api_mpls_fib_encap_details_t_handler_json
14764   (vl_api_mpls_fib_encap_details_t * mp)
14765 {
14766   vat_main_t *vam = &vat_main;
14767   vat_json_node_t *node = NULL;
14768   i32 i;
14769   i32 len = ntohl (mp->nlabels);
14770   struct in_addr ip4;
14771
14772   if (VAT_JSON_ARRAY != vam->json_tree.type)
14773     {
14774       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14775       vat_json_init_array (&vam->json_tree);
14776     }
14777   node = vat_json_array_add (&vam->json_tree);
14778
14779   vat_json_init_object (node);
14780   vat_json_object_add_uint (node, "table", ntohl (mp->fib_index));
14781   vat_json_object_add_uint (node, "entry_index", ntohl (mp->entry_index));
14782   clib_memcpy (&ip4, &(mp->dest), sizeof (ip4));
14783   vat_json_object_add_ip4 (node, "dest", ip4);
14784   vat_json_object_add_uint (node, "s_bit", ntohl (mp->s_bit));
14785   vat_json_object_add_uint (node, "label_count", len);
14786   for (i = 0; i < len; i++)
14787     {
14788       vat_json_object_add_uint (node, "label", ntohl (mp->labels[i]));
14789     }
14790 }
14791
14792 static int
14793 api_mpls_fib_encap_dump (vat_main_t * vam)
14794 {
14795   vl_api_mpls_fib_encap_dump_t *mp;
14796   f64 timeout;
14797
14798   M (MPLS_FIB_ENCAP_DUMP, mpls_fib_encap_dump);
14799   S;
14800
14801   /* Use a control ping for synchronization */
14802   {
14803     vl_api_control_ping_t *mp;
14804     M (CONTROL_PING, control_ping);
14805     S;
14806   }
14807   W;
14808 }
14809
14810 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
14811 #define vl_api_mpls_fib_details_t_print vl_noop_handler
14812
14813 static void
14814 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
14815 {
14816   vat_main_t *vam = &vat_main;
14817   int count = ntohl (mp->count);
14818   vl_api_fib_path_t *fp;
14819   int i;
14820
14821   fformat (vam->ofp,
14822            "table-id %d, label %u, ess_bit %u\n",
14823            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
14824   fp = mp->path;
14825   for (i = 0; i < count; i++)
14826     {
14827       if (fp->afi == IP46_TYPE_IP6)
14828         fformat (vam->ofp,
14829                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14830                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14831                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14832                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14833                  format_ip6_address, fp->next_hop);
14834       else if (fp->afi == IP46_TYPE_IP4)
14835         fformat (vam->ofp,
14836                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14837                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14838                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14839                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14840                  format_ip4_address, fp->next_hop);
14841       fp++;
14842     }
14843 }
14844
14845 static void vl_api_mpls_fib_details_t_handler_json
14846   (vl_api_mpls_fib_details_t * mp)
14847 {
14848   vat_main_t *vam = &vat_main;
14849   int count = ntohl (mp->count);
14850   vat_json_node_t *node = NULL;
14851   struct in_addr ip4;
14852   struct in6_addr ip6;
14853   vl_api_fib_path_t *fp;
14854   int i;
14855
14856   if (VAT_JSON_ARRAY != vam->json_tree.type)
14857     {
14858       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14859       vat_json_init_array (&vam->json_tree);
14860     }
14861   node = vat_json_array_add (&vam->json_tree);
14862
14863   vat_json_init_object (node);
14864   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14865   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
14866   vat_json_object_add_uint (node, "label", ntohl (mp->label));
14867   vat_json_object_add_uint (node, "path_count", count);
14868   fp = mp->path;
14869   for (i = 0; i < count; i++)
14870     {
14871       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
14872       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
14873       vat_json_object_add_uint (node, "is_local", fp->is_local);
14874       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
14875       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
14876       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
14877       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
14878       if (fp->afi == IP46_TYPE_IP4)
14879         {
14880           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
14881           vat_json_object_add_ip4 (node, "next_hop", ip4);
14882         }
14883       else if (fp->afi == IP46_TYPE_IP6)
14884         {
14885           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
14886           vat_json_object_add_ip6 (node, "next_hop", ip6);
14887         }
14888     }
14889 }
14890
14891 static int
14892 api_mpls_fib_dump (vat_main_t * vam)
14893 {
14894   vl_api_mpls_fib_dump_t *mp;
14895   f64 timeout;
14896
14897   M (MPLS_FIB_DUMP, mpls_fib_dump);
14898   S;
14899
14900   /* Use a control ping for synchronization */
14901   {
14902     vl_api_control_ping_t *mp;
14903     M (CONTROL_PING, control_ping);
14904     S;
14905   }
14906   W;
14907 }
14908
14909 #define vl_api_ip_fib_details_t_endian vl_noop_handler
14910 #define vl_api_ip_fib_details_t_print vl_noop_handler
14911
14912 static void
14913 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
14914 {
14915   vat_main_t *vam = &vat_main;
14916   int count = ntohl (mp->count);
14917   vl_api_fib_path_t *fp;
14918   int i;
14919
14920   fformat (vam->ofp,
14921            "table-id %d, prefix %U/%d\n",
14922            ntohl (mp->table_id), format_ip4_address, mp->address,
14923            mp->address_length);
14924   fp = mp->path;
14925   for (i = 0; i < count; i++)
14926     {
14927       if (fp->afi == IP46_TYPE_IP6)
14928         fformat (vam->ofp,
14929                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14930                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14931                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14932                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14933                  format_ip6_address, fp->next_hop);
14934       else if (fp->afi == IP46_TYPE_IP4)
14935         fformat (vam->ofp,
14936                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
14937                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
14938                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
14939                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
14940                  format_ip4_address, fp->next_hop);
14941       fp++;
14942     }
14943 }
14944
14945 static void vl_api_ip_fib_details_t_handler_json
14946   (vl_api_ip_fib_details_t * mp)
14947 {
14948   vat_main_t *vam = &vat_main;
14949   int count = ntohl (mp->count);
14950   vat_json_node_t *node = NULL;
14951   struct in_addr ip4;
14952   struct in6_addr ip6;
14953   vl_api_fib_path_t *fp;
14954   int i;
14955
14956   if (VAT_JSON_ARRAY != vam->json_tree.type)
14957     {
14958       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14959       vat_json_init_array (&vam->json_tree);
14960     }
14961   node = vat_json_array_add (&vam->json_tree);
14962
14963   vat_json_init_object (node);
14964   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
14965   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
14966   vat_json_object_add_ip4 (node, "prefix", ip4);
14967   vat_json_object_add_uint (node, "mask_length", mp->address_length);
14968   vat_json_object_add_uint (node, "path_count", count);
14969   fp = mp->path;
14970   for (i = 0; i < count; i++)
14971     {
14972       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
14973       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
14974       vat_json_object_add_uint (node, "is_local", fp->is_local);
14975       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
14976       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
14977       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
14978       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
14979       if (fp->afi == IP46_TYPE_IP4)
14980         {
14981           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
14982           vat_json_object_add_ip4 (node, "next_hop", ip4);
14983         }
14984       else if (fp->afi == IP46_TYPE_IP6)
14985         {
14986           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
14987           vat_json_object_add_ip6 (node, "next_hop", ip6);
14988         }
14989     }
14990 }
14991
14992 static int
14993 api_ip_fib_dump (vat_main_t * vam)
14994 {
14995   vl_api_ip_fib_dump_t *mp;
14996   f64 timeout;
14997
14998   M (IP_FIB_DUMP, ip_fib_dump);
14999   S;
15000
15001   /* Use a control ping for synchronization */
15002   {
15003     vl_api_control_ping_t *mp;
15004     M (CONTROL_PING, control_ping);
15005     S;
15006   }
15007   W;
15008 }
15009
15010 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15011 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15012
15013 static void
15014 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15015 {
15016   vat_main_t *vam = &vat_main;
15017   int count = ntohl (mp->count);
15018   vl_api_fib_path_t *fp;
15019   int i;
15020
15021   fformat (vam->ofp,
15022            "table-id %d, prefix %U/%d\n",
15023            ntohl (mp->table_id), format_ip6_address, mp->address,
15024            mp->address_length);
15025   fp = mp->path;
15026   for (i = 0; i < count; i++)
15027     {
15028       if (fp->afi == IP46_TYPE_IP6)
15029         fformat (vam->ofp,
15030                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15031                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15032                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15033                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15034                  format_ip6_address, fp->next_hop);
15035       else if (fp->afi == IP46_TYPE_IP4)
15036         fformat (vam->ofp,
15037                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15038                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15039                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15040                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15041                  format_ip4_address, fp->next_hop);
15042       fp++;
15043     }
15044 }
15045
15046 static void vl_api_ip6_fib_details_t_handler_json
15047   (vl_api_ip6_fib_details_t * mp)
15048 {
15049   vat_main_t *vam = &vat_main;
15050   int count = ntohl (mp->count);
15051   vat_json_node_t *node = NULL;
15052   struct in_addr ip4;
15053   struct in6_addr ip6;
15054   vl_api_fib_path_t *fp;
15055   int i;
15056
15057   if (VAT_JSON_ARRAY != vam->json_tree.type)
15058     {
15059       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15060       vat_json_init_array (&vam->json_tree);
15061     }
15062   node = vat_json_array_add (&vam->json_tree);
15063
15064   vat_json_init_object (node);
15065   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15066   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15067   vat_json_object_add_ip6 (node, "prefix", ip6);
15068   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15069   vat_json_object_add_uint (node, "path_count", count);
15070   fp = mp->path;
15071   for (i = 0; i < count; i++)
15072     {
15073       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15074       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15075       vat_json_object_add_uint (node, "is_local", fp->is_local);
15076       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15077       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15078       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15079       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15080       if (fp->afi == IP46_TYPE_IP4)
15081         {
15082           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15083           vat_json_object_add_ip4 (node, "next_hop", ip4);
15084         }
15085       else if (fp->afi == IP46_TYPE_IP6)
15086         {
15087           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15088           vat_json_object_add_ip6 (node, "next_hop", ip6);
15089         }
15090     }
15091 }
15092
15093 static int
15094 api_ip6_fib_dump (vat_main_t * vam)
15095 {
15096   vl_api_ip6_fib_dump_t *mp;
15097   f64 timeout;
15098
15099   M (IP6_FIB_DUMP, ip6_fib_dump);
15100   S;
15101
15102   /* Use a control ping for synchronization */
15103   {
15104     vl_api_control_ping_t *mp;
15105     M (CONTROL_PING, control_ping);
15106     S;
15107   }
15108   W;
15109 }
15110
15111 int
15112 api_classify_table_ids (vat_main_t * vam)
15113 {
15114   vl_api_classify_table_ids_t *mp;
15115   f64 timeout;
15116
15117   /* Construct the API message */
15118   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15119   mp->context = 0;
15120
15121   S;
15122   W;
15123   /* NOTREACHED */
15124   return 0;
15125 }
15126
15127 int
15128 api_classify_table_by_interface (vat_main_t * vam)
15129 {
15130   unformat_input_t *input = vam->input;
15131   vl_api_classify_table_by_interface_t *mp;
15132   f64 timeout;
15133
15134   u32 sw_if_index = ~0;
15135   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15136     {
15137       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15138         ;
15139       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15140         ;
15141       else
15142         break;
15143     }
15144   if (sw_if_index == ~0)
15145     {
15146       errmsg ("missing interface name or sw_if_index\n");
15147       return -99;
15148     }
15149
15150   /* Construct the API message */
15151   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15152   mp->context = 0;
15153   mp->sw_if_index = ntohl (sw_if_index);
15154
15155   S;
15156   W;
15157   /* NOTREACHED */
15158   return 0;
15159 }
15160
15161 int
15162 api_classify_table_info (vat_main_t * vam)
15163 {
15164   unformat_input_t *input = vam->input;
15165   vl_api_classify_table_info_t *mp;
15166   f64 timeout;
15167
15168   u32 table_id = ~0;
15169   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15170     {
15171       if (unformat (input, "table_id %d", &table_id))
15172         ;
15173       else
15174         break;
15175     }
15176   if (table_id == ~0)
15177     {
15178       errmsg ("missing table id\n");
15179       return -99;
15180     }
15181
15182   /* Construct the API message */
15183   M (CLASSIFY_TABLE_INFO, classify_table_info);
15184   mp->context = 0;
15185   mp->table_id = ntohl (table_id);
15186
15187   S;
15188   W;
15189   /* NOTREACHED */
15190   return 0;
15191 }
15192
15193 int
15194 api_classify_session_dump (vat_main_t * vam)
15195 {
15196   unformat_input_t *input = vam->input;
15197   vl_api_classify_session_dump_t *mp;
15198   f64 timeout;
15199
15200   u32 table_id = ~0;
15201   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15202     {
15203       if (unformat (input, "table_id %d", &table_id))
15204         ;
15205       else
15206         break;
15207     }
15208   if (table_id == ~0)
15209     {
15210       errmsg ("missing table id\n");
15211       return -99;
15212     }
15213
15214   /* Construct the API message */
15215   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15216   mp->context = 0;
15217   mp->table_id = ntohl (table_id);
15218   S;
15219
15220   /* Use a control ping for synchronization */
15221   {
15222     vl_api_control_ping_t *mp;
15223     M (CONTROL_PING, control_ping);
15224     S;
15225   }
15226   W;
15227   /* NOTREACHED */
15228   return 0;
15229 }
15230
15231 static void
15232 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15233 {
15234   vat_main_t *vam = &vat_main;
15235
15236   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15237            "src_address %U, vrf_id %d, path_mtu %u, "
15238            "template_interval %u, udp_checksum %d\n",
15239            format_ip4_address, mp->collector_address,
15240            ntohs (mp->collector_port),
15241            format_ip4_address, mp->src_address,
15242            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15243            ntohl (mp->template_interval), mp->udp_checksum);
15244
15245   vam->retval = 0;
15246   vam->result_ready = 1;
15247 }
15248
15249 static void
15250   vl_api_ipfix_exporter_details_t_handler_json
15251   (vl_api_ipfix_exporter_details_t * mp)
15252 {
15253   vat_main_t *vam = &vat_main;
15254   vat_json_node_t node;
15255   struct in_addr collector_address;
15256   struct in_addr src_address;
15257
15258   vat_json_init_object (&node);
15259   clib_memcpy (&collector_address, &mp->collector_address,
15260                sizeof (collector_address));
15261   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15262   vat_json_object_add_uint (&node, "collector_port",
15263                             ntohs (mp->collector_port));
15264   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15265   vat_json_object_add_ip4 (&node, "src_address", src_address);
15266   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15267   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15268   vat_json_object_add_uint (&node, "template_interval",
15269                             ntohl (mp->template_interval));
15270   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15271
15272   vat_json_print (vam->ofp, &node);
15273   vat_json_free (&node);
15274   vam->retval = 0;
15275   vam->result_ready = 1;
15276 }
15277
15278 int
15279 api_ipfix_exporter_dump (vat_main_t * vam)
15280 {
15281   vl_api_ipfix_exporter_dump_t *mp;
15282   f64 timeout;
15283
15284   /* Construct the API message */
15285   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15286   mp->context = 0;
15287
15288   S;
15289   W;
15290   /* NOTREACHED */
15291   return 0;
15292 }
15293
15294 static int
15295 api_ipfix_classify_stream_dump (vat_main_t * vam)
15296 {
15297   vl_api_ipfix_classify_stream_dump_t *mp;
15298   f64 timeout;
15299
15300   /* Construct the API message */
15301   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15302   mp->context = 0;
15303
15304   S;
15305   W;
15306   /* NOTREACHED */
15307   return 0;
15308 }
15309
15310 static void
15311   vl_api_ipfix_classify_stream_details_t_handler
15312   (vl_api_ipfix_classify_stream_details_t * mp)
15313 {
15314   vat_main_t *vam = &vat_main;
15315   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15316            ntohl (mp->domain_id), ntohs (mp->src_port));
15317   vam->retval = 0;
15318   vam->result_ready = 1;
15319 }
15320
15321 static void
15322   vl_api_ipfix_classify_stream_details_t_handler_json
15323   (vl_api_ipfix_classify_stream_details_t * mp)
15324 {
15325   vat_main_t *vam = &vat_main;
15326   vat_json_node_t node;
15327
15328   vat_json_init_object (&node);
15329   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15330   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15331
15332   vat_json_print (vam->ofp, &node);
15333   vat_json_free (&node);
15334   vam->retval = 0;
15335   vam->result_ready = 1;
15336 }
15337
15338 static int
15339 api_ipfix_classify_table_dump (vat_main_t * vam)
15340 {
15341   vl_api_ipfix_classify_table_dump_t *mp;
15342   f64 timeout;
15343
15344   if (!vam->json_output)
15345     {
15346       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15347                "transport_protocol");
15348     }
15349
15350   /* Construct the API message */
15351   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15352
15353   /* send it... */
15354   S;
15355
15356   /* Use a control ping for synchronization */
15357   {
15358     vl_api_control_ping_t *mp;
15359     M (CONTROL_PING, control_ping);
15360     S;
15361   }
15362   W;
15363 }
15364
15365 static void
15366   vl_api_ipfix_classify_table_details_t_handler
15367   (vl_api_ipfix_classify_table_details_t * mp)
15368 {
15369   vat_main_t *vam = &vat_main;
15370   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15371            mp->transport_protocol);
15372 }
15373
15374 static void
15375   vl_api_ipfix_classify_table_details_t_handler_json
15376   (vl_api_ipfix_classify_table_details_t * mp)
15377 {
15378   vat_json_node_t *node = NULL;
15379   vat_main_t *vam = &vat_main;
15380
15381   if (VAT_JSON_ARRAY != vam->json_tree.type)
15382     {
15383       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15384       vat_json_init_array (&vam->json_tree);
15385     }
15386
15387   node = vat_json_array_add (&vam->json_tree);
15388   vat_json_init_object (node);
15389
15390   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15391   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15392   vat_json_object_add_uint (node, "transport_protocol",
15393                             mp->transport_protocol);
15394 }
15395
15396 static int
15397 api_sw_interface_span_enable_disable (vat_main_t * vam)
15398 {
15399   unformat_input_t *i = vam->input;
15400   vl_api_sw_interface_span_enable_disable_t *mp;
15401   f64 timeout;
15402   u32 src_sw_if_index = ~0;
15403   u32 dst_sw_if_index = ~0;
15404   u8 enable = 1;
15405
15406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15407     {
15408       if (unformat (i, "src %U", unformat_sw_if_index, vam, &src_sw_if_index))
15409         ;
15410       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15411         ;
15412       else
15413         if (unformat
15414             (i, "dst %U", unformat_sw_if_index, vam, &dst_sw_if_index))
15415         ;
15416       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15417         ;
15418       else if (unformat (i, "disable"))
15419         enable = 0;
15420       else
15421         break;
15422     }
15423
15424   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15425
15426   mp->sw_if_index_from = htonl (src_sw_if_index);
15427   mp->sw_if_index_to = htonl (dst_sw_if_index);
15428   mp->enable = enable;
15429
15430   S;
15431   W;
15432   /* NOTREACHED */
15433   return 0;
15434 }
15435
15436 static void
15437 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
15438                                             * mp)
15439 {
15440   vat_main_t *vam = &vat_main;
15441
15442   fformat (vam->ofp, "%u => %u\n",
15443            ntohl (mp->sw_if_index_from), ntohl (mp->sw_if_index_to));
15444 }
15445
15446 static void
15447   vl_api_sw_interface_span_details_t_handler_json
15448   (vl_api_sw_interface_span_details_t * mp)
15449 {
15450   vat_main_t *vam = &vat_main;
15451   vat_json_node_t *node = NULL;
15452
15453   if (VAT_JSON_ARRAY != vam->json_tree.type)
15454     {
15455       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15456       vat_json_init_array (&vam->json_tree);
15457     }
15458   node = vat_json_array_add (&vam->json_tree);
15459
15460   vat_json_init_object (node);
15461   vat_json_object_add_uint (node, "src-if-index",
15462                             ntohl (mp->sw_if_index_from));
15463   vat_json_object_add_uint (node, "dst-if-index", ntohl (mp->sw_if_index_to));
15464 }
15465
15466 static int
15467 api_sw_interface_span_dump (vat_main_t * vam)
15468 {
15469   vl_api_sw_interface_span_dump_t *mp;
15470   f64 timeout;
15471
15472   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
15473   S;
15474
15475   /* Use a control ping for synchronization */
15476   {
15477     vl_api_control_ping_t *mp;
15478     M (CONTROL_PING, control_ping);
15479     S;
15480   }
15481   W;
15482 }
15483
15484 int
15485 api_pg_create_interface (vat_main_t * vam)
15486 {
15487   unformat_input_t *input = vam->input;
15488   vl_api_pg_create_interface_t *mp;
15489   f64 timeout;
15490
15491   u32 if_id = ~0;
15492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15493     {
15494       if (unformat (input, "if_id %d", &if_id))
15495         ;
15496       else
15497         break;
15498     }
15499   if (if_id == ~0)
15500     {
15501       errmsg ("missing pg interface index\n");
15502       return -99;
15503     }
15504
15505   /* Construct the API message */
15506   M (PG_CREATE_INTERFACE, pg_create_interface);
15507   mp->context = 0;
15508   mp->interface_id = ntohl (if_id);
15509
15510   S;
15511   W;
15512   /* NOTREACHED */
15513   return 0;
15514 }
15515
15516 int
15517 api_pg_capture (vat_main_t * vam)
15518 {
15519   unformat_input_t *input = vam->input;
15520   vl_api_pg_capture_t *mp;
15521   f64 timeout;
15522
15523   u32 if_id = ~0;
15524   u8 enable = 1;
15525   u32 count = 1;
15526   u8 pcap_file_set = 0;
15527   u8 *pcap_file = 0;
15528   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15529     {
15530       if (unformat (input, "if_id %d", &if_id))
15531         ;
15532       else if (unformat (input, "pcap %s", &pcap_file))
15533         pcap_file_set = 1;
15534       else if (unformat (input, "count %d", &count))
15535         ;
15536       else if (unformat (input, "disable"))
15537         enable = 0;
15538       else
15539         break;
15540     }
15541   if (if_id == ~0)
15542     {
15543       errmsg ("missing pg interface index\n");
15544       return -99;
15545     }
15546   if (pcap_file_set > 0)
15547     {
15548       if (vec_len (pcap_file) > 255)
15549         {
15550           errmsg ("pcap file name is too long\n");
15551           return -99;
15552         }
15553     }
15554
15555   u32 name_len = vec_len (pcap_file);
15556   /* Construct the API message */
15557   M (PG_CAPTURE, pg_capture);
15558   mp->context = 0;
15559   mp->interface_id = ntohl (if_id);
15560   mp->is_enabled = enable;
15561   mp->count = ntohl (count);
15562   mp->pcap_name_length = ntohl (name_len);
15563   if (pcap_file_set != 0)
15564     {
15565       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
15566     }
15567   vec_free (pcap_file);
15568
15569   S;
15570   W;
15571   /* NOTREACHED */
15572   return 0;
15573 }
15574
15575 int
15576 api_pg_enable_disable (vat_main_t * vam)
15577 {
15578   unformat_input_t *input = vam->input;
15579   vl_api_pg_enable_disable_t *mp;
15580   f64 timeout;
15581
15582   u8 enable = 1;
15583   u8 stream_name_set = 0;
15584   u8 *stream_name = 0;
15585   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15586     {
15587       if (unformat (input, "stream %s", &stream_name))
15588         stream_name_set = 1;
15589       else if (unformat (input, "disable"))
15590         enable = 0;
15591       else
15592         break;
15593     }
15594
15595   if (stream_name_set > 0)
15596     {
15597       if (vec_len (stream_name) > 255)
15598         {
15599           errmsg ("stream name too long\n");
15600           return -99;
15601         }
15602     }
15603
15604   u32 name_len = vec_len (stream_name);
15605   /* Construct the API message */
15606   M (PG_ENABLE_DISABLE, pg_enable_disable);
15607   mp->context = 0;
15608   mp->is_enabled = enable;
15609   if (stream_name_set != 0)
15610     {
15611       mp->stream_name_length = ntohl (name_len);
15612       clib_memcpy (mp->stream_name, stream_name, name_len);
15613     }
15614   vec_free (stream_name);
15615
15616   S;
15617   W;
15618   /* NOTREACHED */
15619   return 0;
15620 }
15621
15622 int
15623 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
15624 {
15625   unformat_input_t *input = vam->input;
15626   vl_api_ip_source_and_port_range_check_add_del_t *mp;
15627   f64 timeout;
15628
15629   u16 *low_ports = 0;
15630   u16 *high_ports = 0;
15631   u16 this_low;
15632   u16 this_hi;
15633   ip4_address_t ip4_addr;
15634   ip6_address_t ip6_addr;
15635   u32 length;
15636   u32 tmp, tmp2;
15637   u8 prefix_set = 0;
15638   u32 vrf_id = ~0;
15639   u8 is_add = 1;
15640   u8 is_ipv6 = 0;
15641
15642   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15643     {
15644       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
15645         {
15646           prefix_set = 1;
15647         }
15648       else
15649         if (unformat
15650             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
15651         {
15652           prefix_set = 1;
15653           is_ipv6 = 1;
15654         }
15655       else if (unformat (input, "vrf %d", &vrf_id))
15656         ;
15657       else if (unformat (input, "del"))
15658         is_add = 0;
15659       else if (unformat (input, "port %d", &tmp))
15660         {
15661           if (tmp == 0 || tmp > 65535)
15662             {
15663               errmsg ("port %d out of range", tmp);
15664               return -99;
15665             }
15666           this_low = tmp;
15667           this_hi = this_low + 1;
15668           vec_add1 (low_ports, this_low);
15669           vec_add1 (high_ports, this_hi);
15670         }
15671       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
15672         {
15673           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
15674             {
15675               errmsg ("incorrect range parameters\n");
15676               return -99;
15677             }
15678           this_low = tmp;
15679           /* Note: in debug CLI +1 is added to high before
15680              passing to real fn that does "the work"
15681              (ip_source_and_port_range_check_add_del).
15682              This fn is a wrapper around the binary API fn a
15683              control plane will call, which expects this increment
15684              to have occurred. Hence letting the binary API control
15685              plane fn do the increment for consistency between VAT
15686              and other control planes.
15687            */
15688           this_hi = tmp2;
15689           vec_add1 (low_ports, this_low);
15690           vec_add1 (high_ports, this_hi);
15691         }
15692       else
15693         break;
15694     }
15695
15696   if (prefix_set == 0)
15697     {
15698       errmsg ("<address>/<mask> not specified\n");
15699       return -99;
15700     }
15701
15702   if (vrf_id == ~0)
15703     {
15704       errmsg ("VRF ID required, not specified\n");
15705       return -99;
15706     }
15707
15708   if (vrf_id == 0)
15709     {
15710       errmsg
15711         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15712       return -99;
15713     }
15714
15715   if (vec_len (low_ports) == 0)
15716     {
15717       errmsg ("At least one port or port range required\n");
15718       return -99;
15719     }
15720
15721   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
15722      ip_source_and_port_range_check_add_del);
15723
15724   mp->is_add = is_add;
15725
15726   if (is_ipv6)
15727     {
15728       mp->is_ipv6 = 1;
15729       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
15730     }
15731   else
15732     {
15733       mp->is_ipv6 = 0;
15734       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
15735     }
15736
15737   mp->mask_length = length;
15738   mp->number_of_ranges = vec_len (low_ports);
15739
15740   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
15741   vec_free (low_ports);
15742
15743   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
15744   vec_free (high_ports);
15745
15746   mp->vrf_id = ntohl (vrf_id);
15747
15748   S;
15749   W;
15750   /* NOTREACHED */
15751   return 0;
15752 }
15753
15754 int
15755 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
15756 {
15757   unformat_input_t *input = vam->input;
15758   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
15759   f64 timeout;
15760   u32 sw_if_index = ~0;
15761   int vrf_set = 0;
15762   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
15763   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
15764   u8 is_add = 1;
15765
15766   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15767     {
15768       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15769         ;
15770       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15771         ;
15772       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
15773         vrf_set = 1;
15774       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
15775         vrf_set = 1;
15776       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
15777         vrf_set = 1;
15778       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
15779         vrf_set = 1;
15780       else if (unformat (input, "del"))
15781         is_add = 0;
15782       else
15783         break;
15784     }
15785
15786   if (sw_if_index == ~0)
15787     {
15788       errmsg ("Interface required but not specified\n");
15789       return -99;
15790     }
15791
15792   if (vrf_set == 0)
15793     {
15794       errmsg ("VRF ID required but not specified\n");
15795       return -99;
15796     }
15797
15798   if (tcp_out_vrf_id == 0
15799       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
15800     {
15801       errmsg
15802         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
15803       return -99;
15804     }
15805
15806   /* Construct the API message */
15807   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
15808      ip_source_and_port_range_check_interface_add_del);
15809
15810   mp->sw_if_index = ntohl (sw_if_index);
15811   mp->is_add = is_add;
15812   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
15813   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
15814   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
15815   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
15816
15817   /* send it... */
15818   S;
15819
15820   /* Wait for a reply... */
15821   W;
15822 }
15823
15824 static int
15825 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
15826 {
15827   unformat_input_t *i = vam->input;
15828   vl_api_ipsec_gre_add_del_tunnel_t *mp;
15829   f64 timeout;
15830   u32 local_sa_id = 0;
15831   u32 remote_sa_id = 0;
15832   ip4_address_t src_address;
15833   ip4_address_t dst_address;
15834   u8 is_add = 1;
15835
15836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15837     {
15838       if (unformat (i, "local_sa %d", &local_sa_id))
15839         ;
15840       else if (unformat (i, "remote_sa %d", &remote_sa_id))
15841         ;
15842       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
15843         ;
15844       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
15845         ;
15846       else if (unformat (i, "del"))
15847         is_add = 0;
15848       else
15849         {
15850           clib_warning ("parse error '%U'", format_unformat_error, i);
15851           return -99;
15852         }
15853     }
15854
15855   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
15856
15857   mp->local_sa_id = ntohl (local_sa_id);
15858   mp->remote_sa_id = ntohl (remote_sa_id);
15859   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
15860   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
15861   mp->is_add = is_add;
15862
15863   S;
15864   W;
15865   /* NOTREACHED */
15866   return 0;
15867 }
15868
15869 static int
15870 api_punt (vat_main_t * vam)
15871 {
15872   unformat_input_t *i = vam->input;
15873   vl_api_punt_t *mp;
15874   f64 timeout;
15875   u32 ipv = ~0;
15876   u32 protocol = ~0;
15877   u32 port = ~0;
15878   int is_add = 1;
15879
15880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15881     {
15882       if (unformat (i, "ip %d", &ipv))
15883         ;
15884       else if (unformat (i, "protocol %d", &protocol))
15885         ;
15886       else if (unformat (i, "port %d", &port))
15887         ;
15888       else if (unformat (i, "del"))
15889         is_add = 0;
15890       else
15891         {
15892           clib_warning ("parse error '%U'", format_unformat_error, i);
15893           return -99;
15894         }
15895     }
15896
15897   M (PUNT, punt);
15898
15899   mp->is_add = (u8) is_add;
15900   mp->ipv = (u8) ipv;
15901   mp->l4_protocol = (u8) protocol;
15902   mp->l4_port = htons ((u16) port);
15903
15904   S;
15905   W;
15906   /* NOTREACHED */
15907   return 0;
15908 }
15909
15910 static void vl_api_ipsec_gre_tunnel_details_t_handler
15911   (vl_api_ipsec_gre_tunnel_details_t * mp)
15912 {
15913   vat_main_t *vam = &vat_main;
15914
15915   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
15916            ntohl (mp->sw_if_index),
15917            format_ip4_address, &mp->src_address,
15918            format_ip4_address, &mp->dst_address,
15919            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
15920 }
15921
15922 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
15923   (vl_api_ipsec_gre_tunnel_details_t * mp)
15924 {
15925   vat_main_t *vam = &vat_main;
15926   vat_json_node_t *node = NULL;
15927   struct in_addr ip4;
15928
15929   if (VAT_JSON_ARRAY != vam->json_tree.type)
15930     {
15931       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15932       vat_json_init_array (&vam->json_tree);
15933     }
15934   node = vat_json_array_add (&vam->json_tree);
15935
15936   vat_json_init_object (node);
15937   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
15938   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
15939   vat_json_object_add_ip4 (node, "src_address", ip4);
15940   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
15941   vat_json_object_add_ip4 (node, "dst_address", ip4);
15942   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
15943   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
15944 }
15945
15946 static int
15947 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
15948 {
15949   unformat_input_t *i = vam->input;
15950   vl_api_ipsec_gre_tunnel_dump_t *mp;
15951   f64 timeout;
15952   u32 sw_if_index;
15953   u8 sw_if_index_set = 0;
15954
15955   /* Parse args required to build the message */
15956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15957     {
15958       if (unformat (i, "sw_if_index %d", &sw_if_index))
15959         sw_if_index_set = 1;
15960       else
15961         break;
15962     }
15963
15964   if (sw_if_index_set == 0)
15965     {
15966       sw_if_index = ~0;
15967     }
15968
15969   if (!vam->json_output)
15970     {
15971       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
15972                "sw_if_index", "src_address", "dst_address",
15973                "local_sa_id", "remote_sa_id");
15974     }
15975
15976   /* Get list of gre-tunnel interfaces */
15977   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
15978
15979   mp->sw_if_index = htonl (sw_if_index);
15980
15981   S;
15982
15983   /* Use a control ping for synchronization */
15984   {
15985     vl_api_control_ping_t *mp;
15986     M (CONTROL_PING, control_ping);
15987     S;
15988   }
15989   W;
15990 }
15991
15992 static int
15993 api_delete_subif (vat_main_t * vam)
15994 {
15995   unformat_input_t *i = vam->input;
15996   vl_api_delete_subif_t *mp;
15997   f64 timeout;
15998   u32 sw_if_index = ~0;
15999
16000   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16001     {
16002       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16003         ;
16004       if (unformat (i, "sw_if_index %d", &sw_if_index))
16005         ;
16006       else
16007         break;
16008     }
16009
16010   if (sw_if_index == ~0)
16011     {
16012       errmsg ("missing sw_if_index\n");
16013       return -99;
16014     }
16015
16016   /* Construct the API message */
16017   M (DELETE_SUBIF, delete_subif);
16018   mp->sw_if_index = ntohl (sw_if_index);
16019
16020   S;
16021   W;
16022 }
16023
16024 #define foreach_pbb_vtr_op      \
16025 _("disable",  L2_VTR_DISABLED)  \
16026 _("pop",  L2_VTR_POP_2)         \
16027 _("push",  L2_VTR_PUSH_2)
16028
16029 static int
16030 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16031 {
16032   unformat_input_t *i = vam->input;
16033   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16034   f64 timeout;
16035   u32 sw_if_index = ~0, vtr_op = ~0;
16036   u16 outer_tag = ~0;
16037   u8 dmac[6], smac[6];
16038   u8 dmac_set = 0, smac_set = 0;
16039   u16 vlanid = 0;
16040   u32 sid = ~0;
16041   u32 tmp;
16042
16043   /* Shut up coverity */
16044   memset (dmac, 0, sizeof (dmac));
16045   memset (smac, 0, sizeof (smac));
16046
16047   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16048     {
16049       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16050         ;
16051       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16052         ;
16053       else if (unformat (i, "vtr_op %d", &vtr_op))
16054         ;
16055 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16056       foreach_pbb_vtr_op
16057 #undef _
16058         else if (unformat (i, "translate_pbb_stag"))
16059         {
16060           if (unformat (i, "%d", &tmp))
16061             {
16062               vtr_op = L2_VTR_TRANSLATE_2_1;
16063               outer_tag = tmp;
16064             }
16065           else
16066             {
16067               errmsg
16068                 ("translate_pbb_stag operation requires outer tag definition\n");
16069               return -99;
16070             }
16071         }
16072       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16073         dmac_set++;
16074       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16075         smac_set++;
16076       else if (unformat (i, "sid %d", &sid))
16077         ;
16078       else if (unformat (i, "vlanid %d", &tmp))
16079         vlanid = tmp;
16080       else
16081         {
16082           clib_warning ("parse error '%U'", format_unformat_error, i);
16083           return -99;
16084         }
16085     }
16086
16087   if ((sw_if_index == ~0) || (vtr_op == ~0))
16088     {
16089       errmsg ("missing sw_if_index or vtr operation\n");
16090       return -99;
16091     }
16092   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16093       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16094     {
16095       errmsg
16096         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
16097       return -99;
16098     }
16099
16100   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16101   mp->sw_if_index = ntohl (sw_if_index);
16102   mp->vtr_op = ntohl (vtr_op);
16103   mp->outer_tag = ntohs (outer_tag);
16104   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16105   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16106   mp->b_vlanid = ntohs (vlanid);
16107   mp->i_sid = ntohl (sid);
16108
16109   S;
16110   W;
16111   /* NOTREACHED */
16112   return 0;
16113 }
16114
16115 static int
16116 api_flow_classify_set_interface (vat_main_t * vam)
16117 {
16118   unformat_input_t *i = vam->input;
16119   vl_api_flow_classify_set_interface_t *mp;
16120   f64 timeout;
16121   u32 sw_if_index;
16122   int sw_if_index_set;
16123   u32 ip4_table_index = ~0;
16124   u32 ip6_table_index = ~0;
16125   u8 is_add = 1;
16126
16127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16128     {
16129       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16130         sw_if_index_set = 1;
16131       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16132         sw_if_index_set = 1;
16133       else if (unformat (i, "del"))
16134         is_add = 0;
16135       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16136         ;
16137       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16138         ;
16139       else
16140         {
16141           clib_warning ("parse error '%U'", format_unformat_error, i);
16142           return -99;
16143         }
16144     }
16145
16146   if (sw_if_index_set == 0)
16147     {
16148       errmsg ("missing interface name or sw_if_index\n");
16149       return -99;
16150     }
16151
16152   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16153
16154   mp->sw_if_index = ntohl (sw_if_index);
16155   mp->ip4_table_index = ntohl (ip4_table_index);
16156   mp->ip6_table_index = ntohl (ip6_table_index);
16157   mp->is_add = is_add;
16158
16159   S;
16160   W;
16161   /* NOTREACHED */
16162   return 0;
16163 }
16164
16165 static int
16166 api_flow_classify_dump (vat_main_t * vam)
16167 {
16168   unformat_input_t *i = vam->input;
16169   vl_api_flow_classify_dump_t *mp;
16170   f64 timeout = ~0;
16171   u8 type = FLOW_CLASSIFY_N_TABLES;
16172
16173   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16174     ;
16175   else
16176     {
16177       errmsg ("classify table type must be specified\n");
16178       return -99;
16179     }
16180
16181   if (!vam->json_output)
16182     {
16183       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
16184     }
16185
16186   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16187   mp->type = type;
16188   /* send it... */
16189   S;
16190
16191   /* Use a control ping for synchronization */
16192   {
16193     vl_api_control_ping_t *mp;
16194     M (CONTROL_PING, control_ping);
16195     S;
16196   }
16197   /* Wait for a reply... */
16198   W;
16199
16200   /* NOTREACHED */
16201   return 0;
16202 }
16203
16204 static int
16205 api_feature_enable_disable (vat_main_t * vam)
16206 {
16207   unformat_input_t *i = vam->input;
16208   vl_api_feature_enable_disable_t *mp;
16209   f64 timeout;
16210   u8 *arc_name = 0;
16211   u8 *feature_name = 0;
16212   u32 sw_if_index = ~0;
16213   u8 enable = 1;
16214
16215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16216     {
16217       if (unformat (i, "arc_name %s", &arc_name))
16218         ;
16219       else if (unformat (i, "feature_name %s", &feature_name))
16220         ;
16221       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16222         ;
16223       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16224         ;
16225       else if (unformat (i, "disable"))
16226         enable = 0;
16227       else
16228         break;
16229     }
16230
16231   if (arc_name == 0)
16232     {
16233       errmsg ("missing arc name\n");
16234       return -99;
16235     }
16236   if (vec_len (arc_name) > 63)
16237     {
16238       errmsg ("arc name too long\n");
16239     }
16240
16241   if (feature_name == 0)
16242     {
16243       errmsg ("missing feature name\n");
16244       return -99;
16245     }
16246   if (vec_len (feature_name) > 63)
16247     {
16248       errmsg ("feature name too long\n");
16249     }
16250
16251   if (sw_if_index == ~0)
16252     {
16253       errmsg ("missing interface name or sw_if_index\n");
16254       return -99;
16255     }
16256
16257   /* Construct the API message */
16258   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16259   mp->sw_if_index = ntohl (sw_if_index);
16260   mp->enable = enable;
16261   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16262   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16263   vec_free (arc_name);
16264   vec_free (feature_name);
16265
16266   S;
16267   W;
16268 }
16269
16270 static int
16271 q_or_quit (vat_main_t * vam)
16272 {
16273   longjmp (vam->jump_buf, 1);
16274   return 0;                     /* not so much */
16275 }
16276
16277 static int
16278 q (vat_main_t * vam)
16279 {
16280   return q_or_quit (vam);
16281 }
16282
16283 static int
16284 quit (vat_main_t * vam)
16285 {
16286   return q_or_quit (vam);
16287 }
16288
16289 static int
16290 comment (vat_main_t * vam)
16291 {
16292   return 0;
16293 }
16294
16295 static int
16296 cmd_cmp (void *a1, void *a2)
16297 {
16298   u8 **c1 = a1;
16299   u8 **c2 = a2;
16300
16301   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
16302 }
16303
16304 static int
16305 help (vat_main_t * vam)
16306 {
16307   u8 **cmds = 0;
16308   u8 *name = 0;
16309   hash_pair_t *p;
16310   unformat_input_t *i = vam->input;
16311   int j;
16312
16313   if (unformat (i, "%s", &name))
16314     {
16315       uword *hs;
16316
16317       vec_add1 (name, 0);
16318
16319       hs = hash_get_mem (vam->help_by_name, name);
16320       if (hs)
16321         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
16322       else
16323         fformat (vam->ofp, "No such msg / command '%s'\n", name);
16324       vec_free (name);
16325       return 0;
16326     }
16327
16328   fformat (vam->ofp, "Help is available for the following:\n");
16329
16330     /* *INDENT-OFF* */
16331     hash_foreach_pair (p, vam->function_by_name,
16332     ({
16333       vec_add1 (cmds, (u8 *)(p->key));
16334     }));
16335     /* *INDENT-ON* */
16336
16337   vec_sort_with_function (cmds, cmd_cmp);
16338
16339   for (j = 0; j < vec_len (cmds); j++)
16340     fformat (vam->ofp, "%s\n", cmds[j]);
16341
16342   vec_free (cmds);
16343   return 0;
16344 }
16345
16346 static int
16347 set (vat_main_t * vam)
16348 {
16349   u8 *name = 0, *value = 0;
16350   unformat_input_t *i = vam->input;
16351
16352   if (unformat (i, "%s", &name))
16353     {
16354       /* The input buffer is a vector, not a string. */
16355       value = vec_dup (i->buffer);
16356       vec_delete (value, i->index, 0);
16357       /* Almost certainly has a trailing newline */
16358       if (value[vec_len (value) - 1] == '\n')
16359         value[vec_len (value) - 1] = 0;
16360       /* Make sure it's a proper string, one way or the other */
16361       vec_add1 (value, 0);
16362       (void) clib_macro_set_value (&vam->macro_main,
16363                                    (char *) name, (char *) value);
16364     }
16365   else
16366     errmsg ("usage: set <name> <value>\n");
16367
16368   vec_free (name);
16369   vec_free (value);
16370   return 0;
16371 }
16372
16373 static int
16374 unset (vat_main_t * vam)
16375 {
16376   u8 *name = 0;
16377
16378   if (unformat (vam->input, "%s", &name))
16379     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
16380       errmsg ("unset: %s wasn't set\n", name);
16381   vec_free (name);
16382   return 0;
16383 }
16384
16385 typedef struct
16386 {
16387   u8 *name;
16388   u8 *value;
16389 } macro_sort_t;
16390
16391
16392 static int
16393 macro_sort_cmp (void *a1, void *a2)
16394 {
16395   macro_sort_t *s1 = a1;
16396   macro_sort_t *s2 = a2;
16397
16398   return strcmp ((char *) (s1->name), (char *) (s2->name));
16399 }
16400
16401 static int
16402 dump_macro_table (vat_main_t * vam)
16403 {
16404   macro_sort_t *sort_me = 0, *sm;
16405   int i;
16406   hash_pair_t *p;
16407
16408     /* *INDENT-OFF* */
16409     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
16410     ({
16411       vec_add2 (sort_me, sm, 1);
16412       sm->name = (u8 *)(p->key);
16413       sm->value = (u8 *) (p->value[0]);
16414     }));
16415     /* *INDENT-ON* */
16416
16417   vec_sort_with_function (sort_me, macro_sort_cmp);
16418
16419   if (vec_len (sort_me))
16420     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
16421   else
16422     fformat (vam->ofp, "The macro table is empty...\n");
16423
16424   for (i = 0; i < vec_len (sort_me); i++)
16425     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
16426   return 0;
16427 }
16428
16429 static int
16430 dump_node_table (vat_main_t * vam)
16431 {
16432   int i, j;
16433   vlib_node_t *node, *next_node;
16434
16435   if (vec_len (vam->graph_nodes) == 0)
16436     {
16437       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16438       return 0;
16439     }
16440
16441   for (i = 0; i < vec_len (vam->graph_nodes); i++)
16442     {
16443       node = vam->graph_nodes[i];
16444       fformat (vam->ofp, "[%d] %s\n", i, node->name);
16445       for (j = 0; j < vec_len (node->next_nodes); j++)
16446         {
16447           if (node->next_nodes[j] != ~0)
16448             {
16449               next_node = vam->graph_nodes[node->next_nodes[j]];
16450               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16451             }
16452         }
16453     }
16454   return 0;
16455 }
16456
16457 static int
16458 value_sort_cmp (void *a1, void *a2)
16459 {
16460   name_sort_t *n1 = a1;
16461   name_sort_t *n2 = a2;
16462
16463   if (n1->value < n2->value)
16464     return -1;
16465   if (n1->value > n2->value)
16466     return 1;
16467   return 0;
16468 }
16469
16470
16471 static int
16472 dump_msg_api_table (vat_main_t * vam)
16473 {
16474   api_main_t *am = &api_main;
16475   name_sort_t *nses = 0, *ns;
16476   hash_pair_t *hp;
16477   int i;
16478
16479   /* *INDENT-OFF* */
16480   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
16481   ({
16482     vec_add2 (nses, ns, 1);
16483     ns->name = (u8 *)(hp->key);
16484     ns->value = (u32) hp->value[0];
16485   }));
16486   /* *INDENT-ON* */
16487
16488   vec_sort_with_function (nses, value_sort_cmp);
16489
16490   for (i = 0; i < vec_len (nses); i++)
16491     fformat (vam->ofp, " [%d]: %s\n", nses[i].value, nses[i].name);
16492   vec_free (nses);
16493   return 0;
16494 }
16495
16496 static int
16497 get_msg_id (vat_main_t * vam)
16498 {
16499   u8 *name_and_crc;
16500   u32 message_index;
16501
16502   if (unformat (vam->input, "%s", &name_and_crc))
16503     {
16504       message_index = vl_api_get_msg_index (name_and_crc);
16505       if (message_index == ~0)
16506         {
16507           fformat (vam->ofp, " '%s' not found\n", name_and_crc);
16508           return 0;
16509         }
16510       fformat (vam->ofp, " '%s' has message index %d\n",
16511                name_and_crc, message_index);
16512       return 0;
16513     }
16514   errmsg ("name_and_crc required...\n");
16515   return 0;
16516 }
16517
16518 static int
16519 search_node_table (vat_main_t * vam)
16520 {
16521   unformat_input_t *line_input = vam->input;
16522   u8 *node_to_find;
16523   int j;
16524   vlib_node_t *node, *next_node;
16525   uword *p;
16526
16527   if (vam->graph_node_index_by_name == 0)
16528     {
16529       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
16530       return 0;
16531     }
16532
16533   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
16534     {
16535       if (unformat (line_input, "%s", &node_to_find))
16536         {
16537           vec_add1 (node_to_find, 0);
16538           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
16539           if (p == 0)
16540             {
16541               fformat (vam->ofp, "%s not found...\n", node_to_find);
16542               goto out;
16543             }
16544           node = vam->graph_nodes[p[0]];
16545           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
16546           for (j = 0; j < vec_len (node->next_nodes); j++)
16547             {
16548               if (node->next_nodes[j] != ~0)
16549                 {
16550                   next_node = vam->graph_nodes[node->next_nodes[j]];
16551                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
16552                 }
16553             }
16554         }
16555
16556       else
16557         {
16558           clib_warning ("parse error '%U'", format_unformat_error,
16559                         line_input);
16560           return -99;
16561         }
16562
16563     out:
16564       vec_free (node_to_find);
16565
16566     }
16567
16568   return 0;
16569 }
16570
16571
16572 static int
16573 script (vat_main_t * vam)
16574 {
16575   u8 *s = 0;
16576   char *save_current_file;
16577   unformat_input_t save_input;
16578   jmp_buf save_jump_buf;
16579   u32 save_line_number;
16580
16581   FILE *new_fp, *save_ifp;
16582
16583   if (unformat (vam->input, "%s", &s))
16584     {
16585       new_fp = fopen ((char *) s, "r");
16586       if (new_fp == 0)
16587         {
16588           errmsg ("Couldn't open script file %s\n", s);
16589           vec_free (s);
16590           return -99;
16591         }
16592     }
16593   else
16594     {
16595       errmsg ("Missing script name\n");
16596       return -99;
16597     }
16598
16599   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
16600   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
16601   save_ifp = vam->ifp;
16602   save_line_number = vam->input_line_number;
16603   save_current_file = (char *) vam->current_file;
16604
16605   vam->input_line_number = 0;
16606   vam->ifp = new_fp;
16607   vam->current_file = s;
16608   do_one_file (vam);
16609
16610   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
16611   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
16612   vam->ifp = save_ifp;
16613   vam->input_line_number = save_line_number;
16614   vam->current_file = (u8 *) save_current_file;
16615   vec_free (s);
16616
16617   return 0;
16618 }
16619
16620 static int
16621 echo (vat_main_t * vam)
16622 {
16623   fformat (vam->ofp, "%v", vam->input->buffer);
16624   return 0;
16625 }
16626
16627 /* List of API message constructors, CLI names map to api_xxx */
16628 #define foreach_vpe_api_msg                                             \
16629 _(create_loopback,"[mac <mac-addr>]")                                   \
16630 _(sw_interface_dump,"")                                                 \
16631 _(sw_interface_set_flags,                                               \
16632   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
16633 _(sw_interface_add_del_address,                                         \
16634   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
16635 _(sw_interface_set_table,                                               \
16636   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
16637 _(sw_interface_set_mpls_enable,                                                \
16638   "<intfc> | sw_if_index [disable | dis]")                                \
16639 _(sw_interface_set_vpath,                                               \
16640   "<intfc> | sw_if_index <id> enable | disable")                        \
16641 _(sw_interface_set_l2_xconnect,                                         \
16642   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16643   "enable | disable")                                                   \
16644 _(sw_interface_set_l2_bridge,                                           \
16645   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
16646   "[shg <split-horizon-group>] [bvi]\n"                                 \
16647   "enable | disable")                                                   \
16648 _(sw_interface_set_dpdk_hqos_pipe,                                      \
16649   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
16650   "profile <profile-id>\n")                                             \
16651 _(sw_interface_set_dpdk_hqos_subport,                                   \
16652   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
16653   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
16654 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
16655   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
16656 _(bridge_domain_add_del,                                                \
16657   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
16658 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
16659 _(l2fib_add_del,                                                        \
16660   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
16661 _(l2_flags,                                                             \
16662   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
16663 _(bridge_flags,                                                         \
16664   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
16665 _(tap_connect,                                                          \
16666   "tapname <name> mac <mac-addr> | random-mac")                         \
16667 _(tap_modify,                                                           \
16668   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
16669 _(tap_delete,                                                           \
16670   "<vpp-if-name> | sw_if_index <id>")                                   \
16671 _(sw_interface_tap_dump, "")                                            \
16672 _(ip_add_del_route,                                                     \
16673   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
16674   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16675   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16676   "[multipath] [count <n>]")                                            \
16677 _(mpls_route_add_del,                                                   \
16678   "<label> <eos> via <addr> [table-id <n>]\n"                           \
16679   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
16680   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
16681   "[multipath] [count <n>]")                                            \
16682 _(mpls_ip_bind_unbind,                                                  \
16683   "<label> <addr/len>")                                                 \
16684 _(proxy_arp_add_del,                                                    \
16685   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
16686 _(proxy_arp_intfc_enable_disable,                                       \
16687   "<intfc> | sw_if_index <id> enable | disable")                        \
16688 _(mpls_add_del_encap,                                                   \
16689   "label <n> dst <ip4-addr> [vrf <n>] [del]")                           \
16690 _(sw_interface_set_unnumbered,                                          \
16691   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
16692 _(ip_neighbor_add_del,                                                  \
16693   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
16694   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
16695 _(reset_vrf, "vrf <id> [ipv6]")                                         \
16696 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
16697 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
16698   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
16699   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
16700   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
16701 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
16702 _(reset_fib, "vrf <n> [ipv6]")                                          \
16703 _(dhcp_proxy_config,                                                    \
16704   "svr <v46-address> src <v46-address>\n"                               \
16705    "insert-cid <n> [del]")                                              \
16706 _(dhcp_proxy_config_2,                                                  \
16707   "svr <v46-address> src <v46-address>\n"                               \
16708    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
16709 _(dhcp_proxy_set_vss,                                                   \
16710   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
16711 _(dhcp_client_config,                                                   \
16712   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
16713 _(set_ip_flow_hash,                                                     \
16714   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
16715 _(sw_interface_ip6_enable_disable,                                      \
16716   "<intfc> | sw_if_index <id> enable | disable")                        \
16717 _(sw_interface_ip6_set_link_local_address,                              \
16718   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
16719 _(sw_interface_ip6nd_ra_prefix,                                         \
16720   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
16721   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
16722   "[nolink] [isno]")                                                    \
16723 _(sw_interface_ip6nd_ra_config,                                         \
16724   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
16725   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
16726   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
16727 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
16728 _(l2_patch_add_del,                                                     \
16729   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
16730   "enable | disable")                                                   \
16731 _(mpls_ethernet_add_del_tunnel,                                         \
16732   "tx <intfc> | tx_sw_if_index <n> dst <mac-addr>\n"                    \
16733   "adj <ip4-addr>/<mw> dst <mac-addr> [del]")                           \
16734 _(mpls_ethernet_add_del_tunnel_2,                                       \
16735   "inner_vrf_id <n> outer_vrf_id <n> next-hop <ip4-addr>\n"             \
16736   "resolve-attempts <n> resolve-if-needed 0 | 1 [del]")                 \
16737 _(sr_tunnel_add_del,                                                    \
16738   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
16739   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
16740   "[policy <policy_name>]")                                             \
16741 _(sr_policy_add_del,                                                    \
16742   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
16743 _(sr_multicast_map_add_del,                                             \
16744   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
16745 _(classify_add_del_table,                                               \
16746   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
16747   " [del] mask <mask-value>\n"                                          \
16748   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
16749   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
16750 _(classify_add_del_session,                                             \
16751   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
16752   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
16753   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
16754   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
16755 _(classify_set_interface_ip_table,                                      \
16756   "<intfc> | sw_if_index <nn> table <nn>")                              \
16757 _(classify_set_interface_l2_tables,                                     \
16758   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16759   "  [other-table <nn>]")                                               \
16760 _(get_node_index, "node <node-name")                                    \
16761 _(add_node_next, "node <node-name> next <next-node-name>")              \
16762 _(l2tpv3_create_tunnel,                                                 \
16763   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
16764   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
16765   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
16766 _(l2tpv3_set_tunnel_cookies,                                            \
16767   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
16768   "[new_remote_cookie <nn>]\n")                                         \
16769 _(l2tpv3_interface_enable_disable,                                      \
16770   "<intfc> | sw_if_index <nn> enable | disable")                        \
16771 _(l2tpv3_set_lookup_key,                                                \
16772   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
16773 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
16774 _(vxlan_add_del_tunnel,                                                 \
16775   "src <ip-addr> dst <ip-addr> vni <vni> [encap-vrf-id <nn>]\n"         \
16776   " [decap-next l2|ip4|ip6] [del]")                                     \
16777 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
16778 _(gre_add_del_tunnel,                                                   \
16779   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
16780 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
16781 _(l2_fib_clear_table, "")                                               \
16782 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
16783 _(l2_interface_vlan_tag_rewrite,                                        \
16784   "<intfc> | sw_if_index <nn> \n"                                       \
16785   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
16786   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
16787 _(create_vhost_user_if,                                                 \
16788         "socket <filename> [server] [renumber <dev_instance>] "         \
16789         "[mac <mac_address>]")                                          \
16790 _(modify_vhost_user_if,                                                 \
16791         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
16792         "[server] [renumber <dev_instance>]")                           \
16793 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
16794 _(sw_interface_vhost_user_dump, "")                                     \
16795 _(show_version, "")                                                     \
16796 _(vxlan_gpe_add_del_tunnel,                                             \
16797   "local <addr> remote <addr> vni <nn>\n"                               \
16798     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
16799   "[next-ethernet] [next-nsh]\n")                                       \
16800 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
16801 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
16802 _(interface_name_renumber,                                              \
16803   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
16804 _(input_acl_set_interface,                                              \
16805   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16806   "  [l2-table <nn>] [del]")                                            \
16807 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
16808 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
16809 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
16810 _(ip_dump, "ipv4 | ipv6")                                               \
16811 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
16812 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
16813   "  spid_id <n> ")                                                     \
16814 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
16815   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
16816   "  integ_alg <alg> integ_key <hex>")                                  \
16817 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
16818   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
16819   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
16820   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
16821 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
16822 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
16823 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
16824   "(auth_data 0x<data> | auth_data <data>)")                            \
16825 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
16826   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
16827 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
16828   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
16829   "(local|remote)")                                                     \
16830 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
16831 _(delete_loopback,"sw_if_index <nn>")                                   \
16832 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
16833 _(map_add_domain,                                                       \
16834   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
16835   "ip6-src <ip6addr> "                                                  \
16836   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
16837 _(map_del_domain, "index <n>")                                          \
16838 _(map_add_del_rule,                                                     \
16839   "index <n> psid <n> dst <ip6addr> [del]")                             \
16840 _(map_domain_dump, "")                                                  \
16841 _(map_rule_dump, "index <map-domain>")                                  \
16842 _(want_interface_events,  "enable|disable")                             \
16843 _(want_stats,"enable|disable")                                          \
16844 _(get_first_msg_id, "client <name>")                                    \
16845 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
16846 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
16847   "fib-id <nn> [ip4][ip6][default]")                                    \
16848 _(get_node_graph, " ")                                                  \
16849 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
16850 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
16851 _(ioam_disable, "")                                                \
16852 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
16853                             " sw_if_index <sw_if_index> p <priority> "  \
16854                             "w <weight>] [del]")                        \
16855 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
16856                         "iface <intf> | sw_if_index <sw_if_index> "     \
16857                         "p <priority> w <weight> [del]")                \
16858 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
16859                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
16860                           "locator-set <locator_name> [del]")           \
16861 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
16862   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
16863 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
16864 _(lisp_gpe_enable_disable, "enable|disable")                            \
16865 _(lisp_enable_disable, "enable|disable")                                \
16866 _(lisp_gpe_add_del_iface, "up|down")                                    \
16867 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
16868                                "[seid <seid>] "                         \
16869                                "rloc <locator> p <prio> "               \
16870                                "w <weight> [rloc <loc> ... ] "          \
16871                                "action <action> [del-all]")             \
16872 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
16873                           "<local-eid>")                                \
16874 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
16875 _(lisp_map_request_mode, "src-dst|dst-only")                            \
16876 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
16877 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
16878 _(lisp_locator_set_dump, "[local | remote]")                            \
16879 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
16880 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
16881                        "[local] | [remote]")                            \
16882 _(lisp_eid_table_vni_dump, "")                                          \
16883 _(lisp_eid_table_map_dump, "l2|l3")                                     \
16884 _(lisp_gpe_tunnel_dump, "")                                             \
16885 _(lisp_map_resolver_dump, "")                                           \
16886 _(lisp_adjacencies_get, "vni <vni>")                                    \
16887 _(show_lisp_status, "")                                                 \
16888 _(lisp_get_map_request_itr_rlocs, "")                                   \
16889 _(show_lisp_pitr, "")                                                   \
16890 _(show_lisp_map_request_mode, "")                                       \
16891 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
16892 _(af_packet_delete, "name <host interface name>")                       \
16893 _(policer_add_del, "name <policer name> <params> [del]")                \
16894 _(policer_dump, "[name <policer name>]")                                \
16895 _(policer_classify_set_interface,                                       \
16896   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
16897   "  [l2-table <nn>] [del]")                                            \
16898 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
16899 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
16900     "[master|slave]")                                                   \
16901 _(netmap_delete, "name <interface name>")                               \
16902 _(mpls_eth_tunnel_dump, "tunnel_index <tunnel-id>")                     \
16903 _(mpls_fib_encap_dump, "")                                              \
16904 _(mpls_fib_dump, "")                                                    \
16905 _(classify_table_ids, "")                                               \
16906 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
16907 _(classify_table_info, "table_id <nn>")                                 \
16908 _(classify_session_dump, "table_id <nn>")                               \
16909 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
16910     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
16911     "[template_interval <nn>] [udp_checksum]")                          \
16912 _(ipfix_exporter_dump, "")                                              \
16913 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
16914 _(ipfix_classify_stream_dump, "")                                       \
16915 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
16916 _(ipfix_classify_table_dump, "")                                        \
16917 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [[dst <intfc> | dst_sw_if_index <id>] | disable]") \
16918 _(sw_interface_span_dump, "")                                           \
16919 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
16920 _(pg_create_interface, "if_id <nn>")                                    \
16921 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
16922 _(pg_enable_disable, "[stream <id>] disable")                           \
16923 _(ip_source_and_port_range_check_add_del,                               \
16924   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
16925 _(ip_source_and_port_range_check_interface_add_del,                     \
16926   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
16927   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
16928 _(ipsec_gre_add_del_tunnel,                                             \
16929   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
16930 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
16931 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
16932 _(l2_interface_pbb_tag_rewrite,                                         \
16933   "<intfc> | sw_if_index <nn> \n"                                       \
16934   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
16935   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
16936 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
16937 _(flow_classify_set_interface,                                          \
16938   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
16939 _(flow_classify_dump, "type [ip4|ip6]")                                 \
16940 _(ip_fib_dump, "")                                                      \
16941 _(ip6_fib_dump, "")                                                     \
16942 _(feature_enable_disable, "arc_name <arc_name> "                        \
16943   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")
16944
16945 /* List of command functions, CLI names map directly to functions */
16946 #define foreach_cli_function                                    \
16947 _(comment, "usage: comment <ignore-rest-of-line>")              \
16948 _(dump_interface_table, "usage: dump_interface_table")          \
16949 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
16950 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
16951 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
16952 _(dump_stats_table, "usage: dump_stats_table")                  \
16953 _(dump_macro_table, "usage: dump_macro_table ")                 \
16954 _(dump_node_table, "usage: dump_node_table")                    \
16955 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
16956 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
16957 _(echo, "usage: echo <message>")                                \
16958 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
16959 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
16960 _(help, "usage: help")                                          \
16961 _(q, "usage: quit")                                             \
16962 _(quit, "usage: quit")                                          \
16963 _(search_node_table, "usage: search_node_table <name>...")      \
16964 _(set, "usage: set <variable-name> <value>")                    \
16965 _(script, "usage: script <file-name>")                          \
16966 _(unset, "usage: unset <variable-name>")
16967
16968 #define _(N,n)                                  \
16969     static void vl_api_##n##_t_handler_uni      \
16970     (vl_api_##n##_t * mp)                       \
16971     {                                           \
16972         vat_main_t * vam = &vat_main;           \
16973         if (vam->json_output) {                 \
16974             vl_api_##n##_t_handler_json(mp);    \
16975         } else {                                \
16976             vl_api_##n##_t_handler(mp);         \
16977         }                                       \
16978     }
16979 foreach_vpe_api_reply_msg;
16980 #undef _
16981
16982 void
16983 vat_api_hookup (vat_main_t * vam)
16984 {
16985 #define _(N,n)                                                  \
16986     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
16987                            vl_api_##n##_t_handler_uni,          \
16988                            vl_noop_handler,                     \
16989                            vl_api_##n##_t_endian,               \
16990                            vl_api_##n##_t_print,                \
16991                            sizeof(vl_api_##n##_t), 1);
16992   foreach_vpe_api_reply_msg;
16993 #undef _
16994
16995   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
16996
16997   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
16998
16999   vam->function_by_name = hash_create_string (0, sizeof (uword));
17000
17001   vam->help_by_name = hash_create_string (0, sizeof (uword));
17002
17003   /* API messages we can send */
17004 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17005   foreach_vpe_api_msg;
17006 #undef _
17007
17008   /* Help strings */
17009 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17010   foreach_vpe_api_msg;
17011 #undef _
17012
17013   /* CLI functions */
17014 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17015   foreach_cli_function;
17016 #undef _
17017
17018   /* Help strings */
17019 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17020   foreach_cli_function;
17021 #undef _
17022 }
17023
17024 #undef vl_api_version
17025 #define vl_api_version(n,v) static u32 vpe_api_version = v;
17026 #include <vpp-api/vpe.api.h>
17027 #undef vl_api_version
17028
17029 void
17030 vl_client_add_api_signatures (vl_api_memclnt_create_t * mp)
17031 {
17032   /*
17033    * Send the main API signature in slot 0. This bit of code must
17034    * match the checks in ../vpe/api/api.c: vl_msg_api_version_check().
17035    */
17036   mp->api_versions[0] = clib_host_to_net_u32 (vpe_api_version);
17037 }
17038
17039 /*
17040  * fd.io coding-style-patch-verification: ON
17041  *
17042  * Local Variables:
17043  * eval: (c-set-style "gnu")
17044  * End:
17045  */