344259b88cdfad9b2581788aec9736fa1a339a7b
[vpp.git] / vpp-api-test / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vlibsocket/api.h>
24 #include <vnet/ip/ip.h>
25 #include <vnet/sr/sr_packet.h>
26 #include <vnet/l2/l2_input.h>
27 #include <vnet/l2tp/l2tp.h>
28 #include <vnet/vxlan/vxlan.h>
29 #include <vnet/gre/gre.h>
30 #include <vnet/vxlan-gpe/vxlan_gpe.h>
31 #include <vnet/lisp-gpe/lisp_gpe.h>
32
33 #include <vpp-api/vpe_msg_enum.h>
34 #include <vnet/l2/l2_classify.h>
35 #include <vnet/l2/l2_vtr.h>
36 #include <vnet/classify/input_acl.h>
37 #include <vnet/classify/policer_classify.h>
38 #include <vnet/classify/flow_classify.h>
39 #include <vnet/mpls/mpls.h>
40 #include <vnet/ipsec/ipsec.h>
41 #include <vnet/ipsec/ikev2.h>
42 #include <inttypes.h>
43 #include <vnet/map/map.h>
44 #include <vnet/cop/cop.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
46 #include <vnet/ip/ip_source_and_port_range_check.h>
47 #include <vnet/policer/xlate.h>
48 #include <vnet/span/span.h>
49 #include <vnet/policer/policer.h>
50 #include <vnet/policer/police.h>
51
52 #include "vat/json_format.h"
53
54 #include <inttypes.h>
55 #include <sys/stat.h>
56
57 #define vl_typedefs             /* define message structures */
58 #include <vpp-api/vpe_all_api_h.h>
59 #undef vl_typedefs
60
61 /* declare message handlers for each api */
62
63 #define vl_endianfun            /* define message structures */
64 #include <vpp-api/vpe_all_api_h.h>
65 #undef vl_endianfun
66
67 /* instantiate all the print functions we know about */
68 #define vl_print(handle, ...)
69 #define vl_printfun
70 #include <vpp-api/vpe_all_api_h.h>
71 #undef vl_printfun
72
73 uword
74 unformat_sw_if_index (unformat_input_t * input, va_list * args)
75 {
76   vat_main_t *vam = va_arg (*args, vat_main_t *);
77   u32 *result = va_arg (*args, u32 *);
78   u8 *if_name;
79   uword *p;
80
81   if (!unformat (input, "%s", &if_name))
82     return 0;
83
84   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
85   if (p == 0)
86     return 0;
87   *result = p[0];
88   return 1;
89 }
90
91 /* Parse an IP4 address %d.%d.%d.%d. */
92 uword
93 unformat_ip4_address (unformat_input_t * input, va_list * args)
94 {
95   u8 *result = va_arg (*args, u8 *);
96   unsigned a[4];
97
98   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
99     return 0;
100
101   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
102     return 0;
103
104   result[0] = a[0];
105   result[1] = a[1];
106   result[2] = a[2];
107   result[3] = a[3];
108
109   return 1;
110 }
111
112
113 uword
114 unformat_ethernet_address (unformat_input_t * input, va_list * args)
115 {
116   u8 *result = va_arg (*args, u8 *);
117   u32 i, a[6];
118
119   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
120                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
121     return 0;
122
123   /* Check range. */
124   for (i = 0; i < 6; i++)
125     if (a[i] >= (1 << 8))
126       return 0;
127
128   for (i = 0; i < 6; i++)
129     result[i] = a[i];
130
131   return 1;
132 }
133
134 /* Returns ethernet type as an int in host byte order. */
135 uword
136 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
137                                         va_list * args)
138 {
139   u16 *result = va_arg (*args, u16 *);
140   int type;
141
142   /* Numeric type. */
143   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
144     {
145       if (type >= (1 << 16))
146         return 0;
147       *result = type;
148       return 1;
149     }
150   return 0;
151 }
152
153 /* Parse an IP6 address. */
154 uword
155 unformat_ip6_address (unformat_input_t * input, va_list * args)
156 {
157   ip6_address_t *result = va_arg (*args, ip6_address_t *);
158   u16 hex_quads[8];
159   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
160   uword c, n_colon, double_colon_index;
161
162   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
163   double_colon_index = ARRAY_LEN (hex_quads);
164   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
165     {
166       hex_digit = 16;
167       if (c >= '0' && c <= '9')
168         hex_digit = c - '0';
169       else if (c >= 'a' && c <= 'f')
170         hex_digit = c + 10 - 'a';
171       else if (c >= 'A' && c <= 'F')
172         hex_digit = c + 10 - 'A';
173       else if (c == ':' && n_colon < 2)
174         n_colon++;
175       else
176         {
177           unformat_put_input (input);
178           break;
179         }
180
181       /* Too many hex quads. */
182       if (n_hex_quads >= ARRAY_LEN (hex_quads))
183         return 0;
184
185       if (hex_digit < 16)
186         {
187           hex_quad = (hex_quad << 4) | hex_digit;
188
189           /* Hex quad must fit in 16 bits. */
190           if (n_hex_digits >= 4)
191             return 0;
192
193           n_colon = 0;
194           n_hex_digits++;
195         }
196
197       /* Save position of :: */
198       if (n_colon == 2)
199         {
200           /* More than one :: ? */
201           if (double_colon_index < ARRAY_LEN (hex_quads))
202             return 0;
203           double_colon_index = n_hex_quads;
204         }
205
206       if (n_colon > 0 && n_hex_digits > 0)
207         {
208           hex_quads[n_hex_quads++] = hex_quad;
209           hex_quad = 0;
210           n_hex_digits = 0;
211         }
212     }
213
214   if (n_hex_digits > 0)
215     hex_quads[n_hex_quads++] = hex_quad;
216
217   {
218     word i;
219
220     /* Expand :: to appropriate number of zero hex quads. */
221     if (double_colon_index < ARRAY_LEN (hex_quads))
222       {
223         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
224
225         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
226           hex_quads[n_zero + i] = hex_quads[i];
227
228         for (i = 0; i < n_zero; i++)
229           hex_quads[double_colon_index + i] = 0;
230
231         n_hex_quads = ARRAY_LEN (hex_quads);
232       }
233
234     /* Too few hex quads given. */
235     if (n_hex_quads < ARRAY_LEN (hex_quads))
236       return 0;
237
238     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
239       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
240
241     return 1;
242   }
243 }
244
245 uword
246 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
247 {
248   u32 *r = va_arg (*args, u32 *);
249
250   if (0);
251 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
252   foreach_ipsec_policy_action
253 #undef _
254     else
255     return 0;
256   return 1;
257 }
258
259 uword
260 unformat_ipsec_crypto_alg (unformat_input_t * input, va_list * args)
261 {
262   u32 *r = va_arg (*args, u32 *);
263
264   if (0);
265 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_CRYPTO_ALG_##f;
266   foreach_ipsec_crypto_alg
267 #undef _
268     else
269     return 0;
270   return 1;
271 }
272
273 u8 *
274 format_ipsec_crypto_alg (u8 * s, va_list * args)
275 {
276   u32 i = va_arg (*args, u32);
277   u8 *t = 0;
278
279   switch (i)
280     {
281 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
282       foreach_ipsec_crypto_alg
283 #undef _
284     default:
285       return format (s, "unknown");
286     }
287   return format (s, "%s", t);
288 }
289
290 uword
291 unformat_ipsec_integ_alg (unformat_input_t * input, va_list * args)
292 {
293   u32 *r = va_arg (*args, u32 *);
294
295   if (0);
296 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_INTEG_ALG_##f;
297   foreach_ipsec_integ_alg
298 #undef _
299     else
300     return 0;
301   return 1;
302 }
303
304 u8 *
305 format_ipsec_integ_alg (u8 * s, va_list * args)
306 {
307   u32 i = va_arg (*args, u32);
308   u8 *t = 0;
309
310   switch (i)
311     {
312 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
313       foreach_ipsec_integ_alg
314 #undef _
315     default:
316       return format (s, "unknown");
317     }
318   return format (s, "%s", t);
319 }
320
321 uword
322 unformat_ikev2_auth_method (unformat_input_t * input, va_list * args)
323 {
324   u32 *r = va_arg (*args, u32 *);
325
326   if (0);
327 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_AUTH_METHOD_##f;
328   foreach_ikev2_auth_method
329 #undef _
330     else
331     return 0;
332   return 1;
333 }
334
335 uword
336 unformat_ikev2_id_type (unformat_input_t * input, va_list * args)
337 {
338   u32 *r = va_arg (*args, u32 *);
339
340   if (0);
341 #define _(v,f,s) else if (unformat (input, s)) *r = IKEV2_ID_TYPE_##f;
342   foreach_ikev2_id_type
343 #undef _
344     else
345     return 0;
346   return 1;
347 }
348
349 uword
350 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
351 {
352   u8 *r = va_arg (*args, u8 *);
353
354   if (unformat (input, "kbps"))
355     *r = SSE2_QOS_RATE_KBPS;
356   else if (unformat (input, "pps"))
357     *r = SSE2_QOS_RATE_PPS;
358   else
359     return 0;
360   return 1;
361 }
362
363 uword
364 unformat_policer_round_type (unformat_input_t * input, va_list * args)
365 {
366   u8 *r = va_arg (*args, u8 *);
367
368   if (unformat (input, "closest"))
369     *r = SSE2_QOS_ROUND_TO_CLOSEST;
370   else if (unformat (input, "up"))
371     *r = SSE2_QOS_ROUND_TO_UP;
372   else if (unformat (input, "down"))
373     *r = SSE2_QOS_ROUND_TO_DOWN;
374   else
375     return 0;
376   return 1;
377 }
378
379 uword
380 unformat_policer_type (unformat_input_t * input, va_list * args)
381 {
382   u8 *r = va_arg (*args, u8 *);
383
384   if (unformat (input, "1r2c"))
385     *r = SSE2_QOS_POLICER_TYPE_1R2C;
386   else if (unformat (input, "1r3c"))
387     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
388   else if (unformat (input, "2r3c-2698"))
389     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
390   else if (unformat (input, "2r3c-4115"))
391     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
392   else if (unformat (input, "2r3c-mef5cf1"))
393     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
394   else
395     return 0;
396   return 1;
397 }
398
399 uword
400 unformat_dscp (unformat_input_t * input, va_list * va)
401 {
402   u8 *r = va_arg (*va, u8 *);
403
404   if (0);
405 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
406   foreach_vnet_dscp
407 #undef _
408     else
409     return 0;
410   return 1;
411 }
412
413 uword
414 unformat_policer_action_type (unformat_input_t * input, va_list * va)
415 {
416   sse2_qos_pol_action_params_st *a
417     = va_arg (*va, sse2_qos_pol_action_params_st *);
418
419   if (unformat (input, "drop"))
420     a->action_type = SSE2_QOS_ACTION_DROP;
421   else if (unformat (input, "transmit"))
422     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
423   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
424     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
425   else
426     return 0;
427   return 1;
428 }
429
430 uword
431 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
432 {
433   u32 *r = va_arg (*va, u32 *);
434   u32 tid;
435
436   if (unformat (input, "ip4"))
437     tid = POLICER_CLASSIFY_TABLE_IP4;
438   else if (unformat (input, "ip6"))
439     tid = POLICER_CLASSIFY_TABLE_IP6;
440   else if (unformat (input, "l2"))
441     tid = POLICER_CLASSIFY_TABLE_L2;
442   else
443     return 0;
444
445   *r = tid;
446   return 1;
447 }
448
449 uword
450 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
451 {
452   u32 *r = va_arg (*va, u32 *);
453   u32 tid;
454
455   if (unformat (input, "ip4"))
456     tid = FLOW_CLASSIFY_TABLE_IP4;
457   else if (unformat (input, "ip6"))
458     tid = FLOW_CLASSIFY_TABLE_IP6;
459   else
460     return 0;
461
462   *r = tid;
463   return 1;
464 }
465
466 u8 *
467 format_ip4_address (u8 * s, va_list * args)
468 {
469   u8 *a = va_arg (*args, u8 *);
470   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
471 }
472
473 u8 *
474 format_ip6_address (u8 * s, va_list * args)
475 {
476   ip6_address_t *a = va_arg (*args, ip6_address_t *);
477   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
478
479   i_max_n_zero = ARRAY_LEN (a->as_u16);
480   max_n_zeros = 0;
481   i_first_zero = i_max_n_zero;
482   n_zeros = 0;
483   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
484     {
485       u32 is_zero = a->as_u16[i] == 0;
486       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
487         {
488           i_first_zero = i;
489           n_zeros = 0;
490         }
491       n_zeros += is_zero;
492       if ((!is_zero && n_zeros > max_n_zeros)
493           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
494         {
495           i_max_n_zero = i_first_zero;
496           max_n_zeros = n_zeros;
497           i_first_zero = ARRAY_LEN (a->as_u16);
498           n_zeros = 0;
499         }
500     }
501
502   last_double_colon = 0;
503   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
504     {
505       if (i == i_max_n_zero && max_n_zeros > 1)
506         {
507           s = format (s, "::");
508           i += max_n_zeros - 1;
509           last_double_colon = 1;
510         }
511       else
512         {
513           s = format (s, "%s%x",
514                       (last_double_colon || i == 0) ? "" : ":",
515                       clib_net_to_host_u16 (a->as_u16[i]));
516           last_double_colon = 0;
517         }
518     }
519
520   return s;
521 }
522
523 /* Format an IP46 address. */
524 u8 *
525 format_ip46_address (u8 * s, va_list * args)
526 {
527   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
528   ip46_type_t type = va_arg (*args, ip46_type_t);
529   int is_ip4 = 1;
530
531   switch (type)
532     {
533     case IP46_TYPE_ANY:
534       is_ip4 = ip46_address_is_ip4 (ip46);
535       break;
536     case IP46_TYPE_IP4:
537       is_ip4 = 1;
538       break;
539     case IP46_TYPE_IP6:
540       is_ip4 = 0;
541       break;
542     }
543
544   return is_ip4 ?
545     format (s, "%U", format_ip4_address, &ip46->ip4) :
546     format (s, "%U", format_ip6_address, &ip46->ip6);
547 }
548
549 u8 *
550 format_ethernet_address (u8 * s, va_list * args)
551 {
552   u8 *a = va_arg (*args, u8 *);
553
554   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
555                  a[0], a[1], a[2], a[3], a[4], a[5]);
556 }
557
558 void
559 increment_v4_address (ip4_address_t * a)
560 {
561   u32 v;
562
563   v = ntohl (a->as_u32) + 1;
564   a->as_u32 = ntohl (v);
565 }
566
567 void
568 increment_v6_address (ip6_address_t * a)
569 {
570   u64 v0, v1;
571
572   v0 = clib_net_to_host_u64 (a->as_u64[0]);
573   v1 = clib_net_to_host_u64 (a->as_u64[1]);
574
575   v1 += 1;
576   if (v1 == 0)
577     v0 += 1;
578   a->as_u64[0] = clib_net_to_host_u64 (v0);
579   a->as_u64[1] = clib_net_to_host_u64 (v1);
580 }
581
582 void
583 increment_mac_address (u64 * mac)
584 {
585   u64 tmp = *mac;
586
587   tmp = clib_net_to_host_u64 (tmp);
588   tmp += 1 << 16;               /* skip unused (least significant) octets */
589   tmp = clib_host_to_net_u64 (tmp);
590   *mac = tmp;
591 }
592
593 static void vl_api_create_loopback_reply_t_handler
594   (vl_api_create_loopback_reply_t * mp)
595 {
596   vat_main_t *vam = &vat_main;
597   i32 retval = ntohl (mp->retval);
598
599   vam->retval = retval;
600   vam->regenerate_interface_table = 1;
601   vam->sw_if_index = ntohl (mp->sw_if_index);
602   vam->result_ready = 1;
603 }
604
605 static void vl_api_create_loopback_reply_t_handler_json
606   (vl_api_create_loopback_reply_t * mp)
607 {
608   vat_main_t *vam = &vat_main;
609   vat_json_node_t node;
610
611   vat_json_init_object (&node);
612   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
613   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
614
615   vat_json_print (vam->ofp, &node);
616   vat_json_free (&node);
617   vam->retval = ntohl (mp->retval);
618   vam->result_ready = 1;
619 }
620
621 static void vl_api_af_packet_create_reply_t_handler
622   (vl_api_af_packet_create_reply_t * mp)
623 {
624   vat_main_t *vam = &vat_main;
625   i32 retval = ntohl (mp->retval);
626
627   vam->retval = retval;
628   vam->regenerate_interface_table = 1;
629   vam->sw_if_index = ntohl (mp->sw_if_index);
630   vam->result_ready = 1;
631 }
632
633 static void vl_api_af_packet_create_reply_t_handler_json
634   (vl_api_af_packet_create_reply_t * mp)
635 {
636   vat_main_t *vam = &vat_main;
637   vat_json_node_t node;
638
639   vat_json_init_object (&node);
640   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
641   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
642
643   vat_json_print (vam->ofp, &node);
644   vat_json_free (&node);
645
646   vam->retval = ntohl (mp->retval);
647   vam->result_ready = 1;
648 }
649
650 static void vl_api_create_vlan_subif_reply_t_handler
651   (vl_api_create_vlan_subif_reply_t * mp)
652 {
653   vat_main_t *vam = &vat_main;
654   i32 retval = ntohl (mp->retval);
655
656   vam->retval = retval;
657   vam->regenerate_interface_table = 1;
658   vam->sw_if_index = ntohl (mp->sw_if_index);
659   vam->result_ready = 1;
660 }
661
662 static void vl_api_create_vlan_subif_reply_t_handler_json
663   (vl_api_create_vlan_subif_reply_t * mp)
664 {
665   vat_main_t *vam = &vat_main;
666   vat_json_node_t node;
667
668   vat_json_init_object (&node);
669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
670   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
671
672   vat_json_print (vam->ofp, &node);
673   vat_json_free (&node);
674
675   vam->retval = ntohl (mp->retval);
676   vam->result_ready = 1;
677 }
678
679 static void vl_api_create_subif_reply_t_handler
680   (vl_api_create_subif_reply_t * mp)
681 {
682   vat_main_t *vam = &vat_main;
683   i32 retval = ntohl (mp->retval);
684
685   vam->retval = retval;
686   vam->regenerate_interface_table = 1;
687   vam->sw_if_index = ntohl (mp->sw_if_index);
688   vam->result_ready = 1;
689 }
690
691 static void vl_api_create_subif_reply_t_handler_json
692   (vl_api_create_subif_reply_t * mp)
693 {
694   vat_main_t *vam = &vat_main;
695   vat_json_node_t node;
696
697   vat_json_init_object (&node);
698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
699   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
700
701   vat_json_print (vam->ofp, &node);
702   vat_json_free (&node);
703
704   vam->retval = ntohl (mp->retval);
705   vam->result_ready = 1;
706 }
707
708 static void vl_api_interface_name_renumber_reply_t_handler
709   (vl_api_interface_name_renumber_reply_t * mp)
710 {
711   vat_main_t *vam = &vat_main;
712   i32 retval = ntohl (mp->retval);
713
714   vam->retval = retval;
715   vam->regenerate_interface_table = 1;
716   vam->result_ready = 1;
717 }
718
719 static void vl_api_interface_name_renumber_reply_t_handler_json
720   (vl_api_interface_name_renumber_reply_t * mp)
721 {
722   vat_main_t *vam = &vat_main;
723   vat_json_node_t node;
724
725   vat_json_init_object (&node);
726   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
727
728   vat_json_print (vam->ofp, &node);
729   vat_json_free (&node);
730
731   vam->retval = ntohl (mp->retval);
732   vam->result_ready = 1;
733 }
734
735 /*
736  * Special-case: build the interface table, maintain
737  * the next loopback sw_if_index vbl.
738  */
739 static void vl_api_sw_interface_details_t_handler
740   (vl_api_sw_interface_details_t * mp)
741 {
742   vat_main_t *vam = &vat_main;
743   u8 *s = format (0, "%s%c", mp->interface_name, 0);
744
745   hash_set_mem (vam->sw_if_index_by_interface_name, s,
746                 ntohl (mp->sw_if_index));
747
748   /* In sub interface case, fill the sub interface table entry */
749   if (mp->sw_if_index != mp->sup_sw_if_index)
750     {
751       sw_interface_subif_t *sub = NULL;
752
753       vec_add2 (vam->sw_if_subif_table, sub, 1);
754
755       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
756       strncpy ((char *) sub->interface_name, (char *) s,
757                vec_len (sub->interface_name));
758       sub->sw_if_index = ntohl (mp->sw_if_index);
759       sub->sub_id = ntohl (mp->sub_id);
760
761       sub->sub_dot1ad = mp->sub_dot1ad;
762       sub->sub_number_of_tags = mp->sub_number_of_tags;
763       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
764       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
765       sub->sub_exact_match = mp->sub_exact_match;
766       sub->sub_default = mp->sub_default;
767       sub->sub_outer_vlan_id_any = mp->sub_outer_vlan_id_any;
768       sub->sub_inner_vlan_id_any = mp->sub_inner_vlan_id_any;
769
770       /* vlan tag rewrite */
771       sub->vtr_op = ntohl (mp->vtr_op);
772       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
773       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
774       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
775     }
776 }
777
778 static void vl_api_sw_interface_details_t_handler_json
779   (vl_api_sw_interface_details_t * mp)
780 {
781   vat_main_t *vam = &vat_main;
782   vat_json_node_t *node = NULL;
783
784   if (VAT_JSON_ARRAY != vam->json_tree.type)
785     {
786       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
787       vat_json_init_array (&vam->json_tree);
788     }
789   node = vat_json_array_add (&vam->json_tree);
790
791   vat_json_init_object (node);
792   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
793   vat_json_object_add_uint (node, "sup_sw_if_index",
794                             ntohl (mp->sup_sw_if_index));
795   vat_json_object_add_uint (node, "l2_address_length",
796                             ntohl (mp->l2_address_length));
797   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
798                              sizeof (mp->l2_address));
799   vat_json_object_add_string_copy (node, "interface_name",
800                                    mp->interface_name);
801   vat_json_object_add_uint (node, "admin_up_down", mp->admin_up_down);
802   vat_json_object_add_uint (node, "link_up_down", mp->link_up_down);
803   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
804   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
805   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
806   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
807   vat_json_object_add_uint (node, "sub_dot1ad", mp->sub_dot1ad);
808   vat_json_object_add_uint (node, "sub_number_of_tags",
809                             mp->sub_number_of_tags);
810   vat_json_object_add_uint (node, "sub_outer_vlan_id",
811                             ntohs (mp->sub_outer_vlan_id));
812   vat_json_object_add_uint (node, "sub_inner_vlan_id",
813                             ntohs (mp->sub_inner_vlan_id));
814   vat_json_object_add_uint (node, "sub_exact_match", mp->sub_exact_match);
815   vat_json_object_add_uint (node, "sub_default", mp->sub_default);
816   vat_json_object_add_uint (node, "sub_outer_vlan_id_any",
817                             mp->sub_outer_vlan_id_any);
818   vat_json_object_add_uint (node, "sub_inner_vlan_id_any",
819                             mp->sub_inner_vlan_id_any);
820   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
821   vat_json_object_add_uint (node, "vtr_push_dot1q",
822                             ntohl (mp->vtr_push_dot1q));
823   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
824   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
825 }
826
827 static void vl_api_sw_interface_set_flags_t_handler
828   (vl_api_sw_interface_set_flags_t * mp)
829 {
830   vat_main_t *vam = &vat_main;
831   if (vam->interface_event_display)
832     errmsg ("interface flags: sw_if_index %d %s %s\n",
833             ntohl (mp->sw_if_index),
834             mp->admin_up_down ? "admin-up" : "admin-down",
835             mp->link_up_down ? "link-up" : "link-down");
836 }
837
838 static void vl_api_sw_interface_set_flags_t_handler_json
839   (vl_api_sw_interface_set_flags_t * mp)
840 {
841   /* JSON output not supported */
842 }
843
844 static void
845 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
846 {
847   vat_main_t *vam = &vat_main;
848   i32 retval = ntohl (mp->retval);
849
850   vam->retval = retval;
851   vam->shmem_result = (u8 *) mp->reply_in_shmem;
852   vam->result_ready = 1;
853 }
854
855 static void
856 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
857 {
858   vat_main_t *vam = &vat_main;
859   vat_json_node_t node;
860   api_main_t *am = &api_main;
861   void *oldheap;
862   u8 *reply;
863
864   vat_json_init_object (&node);
865   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
866   vat_json_object_add_uint (&node, "reply_in_shmem",
867                             ntohl (mp->reply_in_shmem));
868   /* Toss the shared-memory original... */
869   pthread_mutex_lock (&am->vlib_rp->mutex);
870   oldheap = svm_push_data_heap (am->vlib_rp);
871
872   reply = (u8 *) (mp->reply_in_shmem);
873   vec_free (reply);
874
875   svm_pop_heap (oldheap);
876   pthread_mutex_unlock (&am->vlib_rp->mutex);
877
878   vat_json_print (vam->ofp, &node);
879   vat_json_free (&node);
880
881   vam->retval = ntohl (mp->retval);
882   vam->result_ready = 1;
883 }
884
885 static void
886 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
887 {
888   vat_main_t *vam = &vat_main;
889   i32 retval = ntohl (mp->retval);
890
891   vam->retval = retval;
892   vam->cmd_reply = mp->reply;
893   vam->result_ready = 1;
894 }
895
896 static void
897 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   vat_json_node_t node;
901
902   vat_json_init_object (&node);
903   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
904   vat_json_object_add_string_copy (&node, "reply", mp->reply);
905
906   vat_json_print (vam->ofp, &node);
907   vat_json_free (&node);
908
909   vam->retval = ntohl (mp->retval);
910   vam->result_ready = 1;
911 }
912
913 static void vl_api_classify_add_del_table_reply_t_handler
914   (vl_api_classify_add_del_table_reply_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   i32 retval = ntohl (mp->retval);
918   if (vam->async_mode)
919     {
920       vam->async_errors += (retval < 0);
921     }
922   else
923     {
924       vam->retval = retval;
925       if (retval == 0 &&
926           ((mp->new_table_index != 0xFFFFFFFF) ||
927            (mp->skip_n_vectors != 0xFFFFFFFF) ||
928            (mp->match_n_vectors != 0xFFFFFFFF)))
929         /*
930          * Note: this is just barely thread-safe, depends on
931          * the main thread spinning waiting for an answer...
932          */
933         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d\n",
934                 ntohl (mp->new_table_index),
935                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
936       vam->result_ready = 1;
937     }
938 }
939
940 static void vl_api_classify_add_del_table_reply_t_handler_json
941   (vl_api_classify_add_del_table_reply_t * mp)
942 {
943   vat_main_t *vam = &vat_main;
944   vat_json_node_t node;
945
946   vat_json_init_object (&node);
947   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
948   vat_json_object_add_uint (&node, "new_table_index",
949                             ntohl (mp->new_table_index));
950   vat_json_object_add_uint (&node, "skip_n_vectors",
951                             ntohl (mp->skip_n_vectors));
952   vat_json_object_add_uint (&node, "match_n_vectors",
953                             ntohl (mp->match_n_vectors));
954
955   vat_json_print (vam->ofp, &node);
956   vat_json_free (&node);
957
958   vam->retval = ntohl (mp->retval);
959   vam->result_ready = 1;
960 }
961
962 static void vl_api_get_node_index_reply_t_handler
963   (vl_api_get_node_index_reply_t * mp)
964 {
965   vat_main_t *vam = &vat_main;
966   i32 retval = ntohl (mp->retval);
967   if (vam->async_mode)
968     {
969       vam->async_errors += (retval < 0);
970     }
971   else
972     {
973       vam->retval = retval;
974       if (retval == 0)
975         errmsg ("node index %d\n", ntohl (mp->node_index));
976       vam->result_ready = 1;
977     }
978 }
979
980 static void vl_api_get_node_index_reply_t_handler_json
981   (vl_api_get_node_index_reply_t * mp)
982 {
983   vat_main_t *vam = &vat_main;
984   vat_json_node_t node;
985
986   vat_json_init_object (&node);
987   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
988   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
989
990   vat_json_print (vam->ofp, &node);
991   vat_json_free (&node);
992
993   vam->retval = ntohl (mp->retval);
994   vam->result_ready = 1;
995 }
996
997 static void vl_api_get_next_index_reply_t_handler
998   (vl_api_get_next_index_reply_t * mp)
999 {
1000   vat_main_t *vam = &vat_main;
1001   i32 retval = ntohl (mp->retval);
1002   if (vam->async_mode)
1003     {
1004       vam->async_errors += (retval < 0);
1005     }
1006   else
1007     {
1008       vam->retval = retval;
1009       if (retval == 0)
1010         errmsg ("next node index %d\n", ntohl (mp->next_index));
1011       vam->result_ready = 1;
1012     }
1013 }
1014
1015 static void vl_api_get_next_index_reply_t_handler_json
1016   (vl_api_get_next_index_reply_t * mp)
1017 {
1018   vat_main_t *vam = &vat_main;
1019   vat_json_node_t node;
1020
1021   vat_json_init_object (&node);
1022   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1023   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1024
1025   vat_json_print (vam->ofp, &node);
1026   vat_json_free (&node);
1027
1028   vam->retval = ntohl (mp->retval);
1029   vam->result_ready = 1;
1030 }
1031
1032 static void vl_api_add_node_next_reply_t_handler
1033   (vl_api_add_node_next_reply_t * mp)
1034 {
1035   vat_main_t *vam = &vat_main;
1036   i32 retval = ntohl (mp->retval);
1037   if (vam->async_mode)
1038     {
1039       vam->async_errors += (retval < 0);
1040     }
1041   else
1042     {
1043       vam->retval = retval;
1044       if (retval == 0)
1045         errmsg ("next index %d\n", ntohl (mp->next_index));
1046       vam->result_ready = 1;
1047     }
1048 }
1049
1050 static void vl_api_add_node_next_reply_t_handler_json
1051   (vl_api_add_node_next_reply_t * mp)
1052 {
1053   vat_main_t *vam = &vat_main;
1054   vat_json_node_t node;
1055
1056   vat_json_init_object (&node);
1057   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1058   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1059
1060   vat_json_print (vam->ofp, &node);
1061   vat_json_free (&node);
1062
1063   vam->retval = ntohl (mp->retval);
1064   vam->result_ready = 1;
1065 }
1066
1067 static void vl_api_show_version_reply_t_handler
1068   (vl_api_show_version_reply_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   i32 retval = ntohl (mp->retval);
1072
1073   if (retval >= 0)
1074     {
1075       errmsg ("        program: %s\n", mp->program);
1076       errmsg ("        version: %s\n", mp->version);
1077       errmsg ("     build date: %s\n", mp->build_date);
1078       errmsg ("build directory: %s\n", mp->build_directory);
1079     }
1080   vam->retval = retval;
1081   vam->result_ready = 1;
1082 }
1083
1084 static void vl_api_show_version_reply_t_handler_json
1085   (vl_api_show_version_reply_t * mp)
1086 {
1087   vat_main_t *vam = &vat_main;
1088   vat_json_node_t node;
1089
1090   vat_json_init_object (&node);
1091   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1092   vat_json_object_add_string_copy (&node, "program", mp->program);
1093   vat_json_object_add_string_copy (&node, "version", mp->version);
1094   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1095   vat_json_object_add_string_copy (&node, "build_directory",
1096                                    mp->build_directory);
1097
1098   vat_json_print (vam->ofp, &node);
1099   vat_json_free (&node);
1100
1101   vam->retval = ntohl (mp->retval);
1102   vam->result_ready = 1;
1103 }
1104
1105 static void
1106 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1107 {
1108   vat_main_t *vam = &vat_main;
1109   errmsg ("arp %s event: address %U new mac %U sw_if_index %d\n",
1110           mp->mac_ip ? "mac/ip binding" : "address resolution",
1111           format_ip4_address, &mp->address,
1112           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1113 }
1114
1115 static void
1116 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1117 {
1118   /* JSON output not supported */
1119 }
1120
1121 static void
1122 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1123 {
1124   vat_main_t *vam = &vat_main;
1125   errmsg ("ip6 nd %s event: address %U new mac %U sw_if_index %d\n",
1126           mp->mac_ip ? "mac/ip binding" : "address resolution",
1127           format_ip6_address, mp->address,
1128           format_ethernet_address, mp->new_mac, mp->sw_if_index);
1129 }
1130
1131 static void
1132 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1133 {
1134   /* JSON output not supported */
1135 }
1136
1137 /*
1138  * Special-case: build the bridge domain table, maintain
1139  * the next bd id vbl.
1140  */
1141 static void vl_api_bridge_domain_details_t_handler
1142   (vl_api_bridge_domain_details_t * mp)
1143 {
1144   vat_main_t *vam = &vat_main;
1145   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1146
1147   fformat (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-3s\n",
1148            " ID", "LRN", "FWD", "FLD", "BVI", "#IF");
1149
1150   fformat (vam->ofp, "%3d %3d %3d %3d %3d %3d\n",
1151            ntohl (mp->bd_id), mp->learn, mp->forward,
1152            mp->flood, ntohl (mp->bvi_sw_if_index), n_sw_ifs);
1153
1154   if (n_sw_ifs)
1155     fformat (vam->ofp, "\n\n%s %s  %s\n", "sw_if_index", "SHG",
1156              "Interface Name");
1157 }
1158
1159 static void vl_api_bridge_domain_details_t_handler_json
1160   (vl_api_bridge_domain_details_t * mp)
1161 {
1162   vat_main_t *vam = &vat_main;
1163   vat_json_node_t *node, *array = NULL;
1164
1165   if (VAT_JSON_ARRAY != vam->json_tree.type)
1166     {
1167       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1168       vat_json_init_array (&vam->json_tree);
1169     }
1170   node = vat_json_array_add (&vam->json_tree);
1171
1172   vat_json_init_object (node);
1173   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1174   vat_json_object_add_uint (node, "flood", mp->flood);
1175   vat_json_object_add_uint (node, "forward", mp->forward);
1176   vat_json_object_add_uint (node, "learn", mp->learn);
1177   vat_json_object_add_uint (node, "bvi_sw_if_index",
1178                             ntohl (mp->bvi_sw_if_index));
1179   vat_json_object_add_uint (node, "n_sw_ifs", ntohl (mp->n_sw_ifs));
1180   array = vat_json_object_add (node, "sw_if");
1181   vat_json_init_array (array);
1182 }
1183
1184 /*
1185  * Special-case: build the bridge domain sw if table.
1186  */
1187 static void vl_api_bridge_domain_sw_if_details_t_handler
1188   (vl_api_bridge_domain_sw_if_details_t * mp)
1189 {
1190   vat_main_t *vam = &vat_main;
1191   hash_pair_t *p;
1192   u8 *sw_if_name = 0;
1193   u32 sw_if_index;
1194
1195   sw_if_index = ntohl (mp->sw_if_index);
1196   /* *INDENT-OFF* */
1197   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1198   ({
1199     if ((u32) p->value[0] == sw_if_index)
1200       {
1201         sw_if_name = (u8 *)(p->key);
1202         break;
1203       }
1204   }));
1205   /* *INDENT-ON* */
1206
1207   fformat (vam->ofp, "%7d     %3d  %s", sw_if_index,
1208            mp->shg, sw_if_name ? (char *) sw_if_name :
1209            "sw_if_index not found!");
1210 }
1211
1212 static void vl_api_bridge_domain_sw_if_details_t_handler_json
1213   (vl_api_bridge_domain_sw_if_details_t * mp)
1214 {
1215   vat_main_t *vam = &vat_main;
1216   vat_json_node_t *node = NULL;
1217   uword last_index = 0;
1218
1219   ASSERT (VAT_JSON_ARRAY == vam->json_tree.type);
1220   ASSERT (vec_len (vam->json_tree.array) >= 1);
1221   last_index = vec_len (vam->json_tree.array) - 1;
1222   node = &vam->json_tree.array[last_index];
1223   node = vat_json_object_get_element (node, "sw_if");
1224   ASSERT (NULL != node);
1225   node = vat_json_array_add (node);
1226
1227   vat_json_init_object (node);
1228   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1229   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1230   vat_json_object_add_uint (node, "shg", mp->shg);
1231 }
1232
1233 static void vl_api_control_ping_reply_t_handler
1234   (vl_api_control_ping_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   i32 retval = ntohl (mp->retval);
1238   if (vam->async_mode)
1239     {
1240       vam->async_errors += (retval < 0);
1241     }
1242   else
1243     {
1244       vam->retval = retval;
1245       vam->result_ready = 1;
1246     }
1247 }
1248
1249 static void vl_api_control_ping_reply_t_handler_json
1250   (vl_api_control_ping_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254
1255   if (VAT_JSON_NONE != vam->json_tree.type)
1256     {
1257       vat_json_print (vam->ofp, &vam->json_tree);
1258       vat_json_free (&vam->json_tree);
1259       vam->json_tree.type = VAT_JSON_NONE;
1260     }
1261   else
1262     {
1263       /* just print [] */
1264       vat_json_init_array (&vam->json_tree);
1265       vat_json_print (vam->ofp, &vam->json_tree);
1266       vam->json_tree.type = VAT_JSON_NONE;
1267     }
1268
1269   vam->retval = retval;
1270   vam->result_ready = 1;
1271 }
1272
1273 static void
1274 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1275 {
1276   vat_main_t *vam = &vat_main;
1277   i32 retval = ntohl (mp->retval);
1278   if (vam->async_mode)
1279     {
1280       vam->async_errors += (retval < 0);
1281     }
1282   else
1283     {
1284       vam->retval = retval;
1285       vam->result_ready = 1;
1286     }
1287 }
1288
1289 static void vl_api_l2_flags_reply_t_handler_json
1290   (vl_api_l2_flags_reply_t * mp)
1291 {
1292   vat_main_t *vam = &vat_main;
1293   vat_json_node_t node;
1294
1295   vat_json_init_object (&node);
1296   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1297   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1298                             ntohl (mp->resulting_feature_bitmap));
1299
1300   vat_json_print (vam->ofp, &node);
1301   vat_json_free (&node);
1302
1303   vam->retval = ntohl (mp->retval);
1304   vam->result_ready = 1;
1305 }
1306
1307 static void vl_api_bridge_flags_reply_t_handler
1308   (vl_api_bridge_flags_reply_t * mp)
1309 {
1310   vat_main_t *vam = &vat_main;
1311   i32 retval = ntohl (mp->retval);
1312   if (vam->async_mode)
1313     {
1314       vam->async_errors += (retval < 0);
1315     }
1316   else
1317     {
1318       vam->retval = retval;
1319       vam->result_ready = 1;
1320     }
1321 }
1322
1323 static void vl_api_bridge_flags_reply_t_handler_json
1324   (vl_api_bridge_flags_reply_t * mp)
1325 {
1326   vat_main_t *vam = &vat_main;
1327   vat_json_node_t node;
1328
1329   vat_json_init_object (&node);
1330   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1331   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1332                             ntohl (mp->resulting_feature_bitmap));
1333
1334   vat_json_print (vam->ofp, &node);
1335   vat_json_free (&node);
1336
1337   vam->retval = ntohl (mp->retval);
1338   vam->result_ready = 1;
1339 }
1340
1341 static void vl_api_tap_connect_reply_t_handler
1342   (vl_api_tap_connect_reply_t * mp)
1343 {
1344   vat_main_t *vam = &vat_main;
1345   i32 retval = ntohl (mp->retval);
1346   if (vam->async_mode)
1347     {
1348       vam->async_errors += (retval < 0);
1349     }
1350   else
1351     {
1352       vam->retval = retval;
1353       vam->sw_if_index = ntohl (mp->sw_if_index);
1354       vam->result_ready = 1;
1355     }
1356
1357 }
1358
1359 static void vl_api_tap_connect_reply_t_handler_json
1360   (vl_api_tap_connect_reply_t * mp)
1361 {
1362   vat_main_t *vam = &vat_main;
1363   vat_json_node_t node;
1364
1365   vat_json_init_object (&node);
1366   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1367   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1368
1369   vat_json_print (vam->ofp, &node);
1370   vat_json_free (&node);
1371
1372   vam->retval = ntohl (mp->retval);
1373   vam->result_ready = 1;
1374
1375 }
1376
1377 static void
1378 vl_api_tap_modify_reply_t_handler (vl_api_tap_modify_reply_t * mp)
1379 {
1380   vat_main_t *vam = &vat_main;
1381   i32 retval = ntohl (mp->retval);
1382   if (vam->async_mode)
1383     {
1384       vam->async_errors += (retval < 0);
1385     }
1386   else
1387     {
1388       vam->retval = retval;
1389       vam->sw_if_index = ntohl (mp->sw_if_index);
1390       vam->result_ready = 1;
1391     }
1392 }
1393
1394 static void vl_api_tap_modify_reply_t_handler_json
1395   (vl_api_tap_modify_reply_t * mp)
1396 {
1397   vat_main_t *vam = &vat_main;
1398   vat_json_node_t node;
1399
1400   vat_json_init_object (&node);
1401   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1402   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1403
1404   vat_json_print (vam->ofp, &node);
1405   vat_json_free (&node);
1406
1407   vam->retval = ntohl (mp->retval);
1408   vam->result_ready = 1;
1409 }
1410
1411 static void
1412 vl_api_tap_delete_reply_t_handler (vl_api_tap_delete_reply_t * mp)
1413 {
1414   vat_main_t *vam = &vat_main;
1415   i32 retval = ntohl (mp->retval);
1416   if (vam->async_mode)
1417     {
1418       vam->async_errors += (retval < 0);
1419     }
1420   else
1421     {
1422       vam->retval = retval;
1423       vam->result_ready = 1;
1424     }
1425 }
1426
1427 static void vl_api_tap_delete_reply_t_handler_json
1428   (vl_api_tap_delete_reply_t * mp)
1429 {
1430   vat_main_t *vam = &vat_main;
1431   vat_json_node_t node;
1432
1433   vat_json_init_object (&node);
1434   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1435
1436   vat_json_print (vam->ofp, &node);
1437   vat_json_free (&node);
1438
1439   vam->retval = ntohl (mp->retval);
1440   vam->result_ready = 1;
1441 }
1442
1443 static void vl_api_mpls_tunnel_add_del_reply_t_handler
1444   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1445 {
1446   vat_main_t *vam = &vat_main;
1447   i32 retval = ntohl (mp->retval);
1448   if (vam->async_mode)
1449     {
1450       vam->async_errors += (retval < 0);
1451     }
1452   else
1453     {
1454       vam->retval = retval;
1455       vam->result_ready = 1;
1456     }
1457 }
1458
1459 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
1460   (vl_api_mpls_tunnel_add_del_reply_t * mp)
1461 {
1462   vat_main_t *vam = &vat_main;
1463   vat_json_node_t node;
1464
1465   vat_json_init_object (&node);
1466   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1467   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
1468                             ntohl (mp->sw_if_index));
1469
1470   vat_json_print (vam->ofp, &node);
1471   vat_json_free (&node);
1472
1473   vam->retval = ntohl (mp->retval);
1474   vam->result_ready = 1;
1475 }
1476
1477 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
1478   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1479 {
1480   vat_main_t *vam = &vat_main;
1481   i32 retval = ntohl (mp->retval);
1482   if (vam->async_mode)
1483     {
1484       vam->async_errors += (retval < 0);
1485     }
1486   else
1487     {
1488       vam->retval = retval;
1489       vam->sw_if_index = ntohl (mp->sw_if_index);
1490       vam->result_ready = 1;
1491     }
1492 }
1493
1494 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
1495   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   vat_json_node_t node;
1499
1500   vat_json_init_object (&node);
1501   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1502   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1503
1504   vat_json_print (vam->ofp, &node);
1505   vat_json_free (&node);
1506
1507   vam->retval = ntohl (mp->retval);
1508   vam->result_ready = 1;
1509 }
1510
1511
1512 static void vl_api_lisp_add_del_locator_set_reply_t_handler
1513   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1514 {
1515   vat_main_t *vam = &vat_main;
1516   i32 retval = ntohl (mp->retval);
1517   if (vam->async_mode)
1518     {
1519       vam->async_errors += (retval < 0);
1520     }
1521   else
1522     {
1523       vam->retval = retval;
1524       vam->result_ready = 1;
1525     }
1526 }
1527
1528 static void vl_api_lisp_add_del_locator_set_reply_t_handler_json
1529   (vl_api_lisp_add_del_locator_set_reply_t * mp)
1530 {
1531   vat_main_t *vam = &vat_main;
1532   vat_json_node_t node;
1533
1534   vat_json_init_object (&node);
1535   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1536   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
1537
1538   vat_json_print (vam->ofp, &node);
1539   vat_json_free (&node);
1540
1541   vam->retval = ntohl (mp->retval);
1542   vam->result_ready = 1;
1543 }
1544
1545 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
1546   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1547 {
1548   vat_main_t *vam = &vat_main;
1549   i32 retval = ntohl (mp->retval);
1550   if (vam->async_mode)
1551     {
1552       vam->async_errors += (retval < 0);
1553     }
1554   else
1555     {
1556       vam->retval = retval;
1557       vam->sw_if_index = ntohl (mp->sw_if_index);
1558       vam->result_ready = 1;
1559     }
1560 }
1561
1562 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
1563   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
1564 {
1565   vat_main_t *vam = &vat_main;
1566   vat_json_node_t node;
1567
1568   vat_json_init_object (&node);
1569   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1570   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1571
1572   vat_json_print (vam->ofp, &node);
1573   vat_json_free (&node);
1574
1575   vam->retval = ntohl (mp->retval);
1576   vam->result_ready = 1;
1577 }
1578
1579 static void vl_api_gre_add_del_tunnel_reply_t_handler
1580   (vl_api_gre_add_del_tunnel_reply_t * mp)
1581 {
1582   vat_main_t *vam = &vat_main;
1583   i32 retval = ntohl (mp->retval);
1584   if (vam->async_mode)
1585     {
1586       vam->async_errors += (retval < 0);
1587     }
1588   else
1589     {
1590       vam->retval = retval;
1591       vam->sw_if_index = ntohl (mp->sw_if_index);
1592       vam->result_ready = 1;
1593     }
1594 }
1595
1596 static void vl_api_gre_add_del_tunnel_reply_t_handler_json
1597   (vl_api_gre_add_del_tunnel_reply_t * mp)
1598 {
1599   vat_main_t *vam = &vat_main;
1600   vat_json_node_t node;
1601
1602   vat_json_init_object (&node);
1603   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1604   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1605
1606   vat_json_print (vam->ofp, &node);
1607   vat_json_free (&node);
1608
1609   vam->retval = ntohl (mp->retval);
1610   vam->result_ready = 1;
1611 }
1612
1613 static void vl_api_create_vhost_user_if_reply_t_handler
1614   (vl_api_create_vhost_user_if_reply_t * mp)
1615 {
1616   vat_main_t *vam = &vat_main;
1617   i32 retval = ntohl (mp->retval);
1618   if (vam->async_mode)
1619     {
1620       vam->async_errors += (retval < 0);
1621     }
1622   else
1623     {
1624       vam->retval = retval;
1625       vam->sw_if_index = ntohl (mp->sw_if_index);
1626       vam->result_ready = 1;
1627     }
1628 }
1629
1630 static void vl_api_create_vhost_user_if_reply_t_handler_json
1631   (vl_api_create_vhost_user_if_reply_t * mp)
1632 {
1633   vat_main_t *vam = &vat_main;
1634   vat_json_node_t node;
1635
1636   vat_json_init_object (&node);
1637   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1638   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1639
1640   vat_json_print (vam->ofp, &node);
1641   vat_json_free (&node);
1642
1643   vam->retval = ntohl (mp->retval);
1644   vam->result_ready = 1;
1645 }
1646
1647 static void vl_api_ip_address_details_t_handler
1648   (vl_api_ip_address_details_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   static ip_address_details_t empty_ip_address_details = { {0} };
1652   ip_address_details_t *address = NULL;
1653   ip_details_t *current_ip_details = NULL;
1654   ip_details_t *details = NULL;
1655
1656   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
1657
1658   if (!details || vam->current_sw_if_index >= vec_len (details)
1659       || !details[vam->current_sw_if_index].present)
1660     {
1661       errmsg ("ip address details arrived but not stored\n");
1662       errmsg ("ip_dump should be called first\n");
1663       return;
1664     }
1665
1666   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
1667
1668 #define addresses (current_ip_details->addr)
1669
1670   vec_validate_init_empty (addresses, vec_len (addresses),
1671                            empty_ip_address_details);
1672
1673   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
1674
1675   clib_memcpy (&address->ip, &mp->ip, sizeof (address->ip));
1676   address->prefix_length = mp->prefix_length;
1677 #undef addresses
1678 }
1679
1680 static void vl_api_ip_address_details_t_handler_json
1681   (vl_api_ip_address_details_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t *node = NULL;
1685   struct in6_addr ip6;
1686   struct in_addr ip4;
1687
1688   if (VAT_JSON_ARRAY != vam->json_tree.type)
1689     {
1690       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1691       vat_json_init_array (&vam->json_tree);
1692     }
1693   node = vat_json_array_add (&vam->json_tree);
1694
1695   vat_json_init_object (node);
1696   if (vam->is_ipv6)
1697     {
1698       clib_memcpy (&ip6, mp->ip, sizeof (ip6));
1699       vat_json_object_add_ip6 (node, "ip", ip6);
1700     }
1701   else
1702     {
1703       clib_memcpy (&ip4, mp->ip, sizeof (ip4));
1704       vat_json_object_add_ip4 (node, "ip", ip4);
1705     }
1706   vat_json_object_add_uint (node, "prefix_length", mp->prefix_length);
1707 }
1708
1709 static void
1710 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
1711 {
1712   vat_main_t *vam = &vat_main;
1713   static ip_details_t empty_ip_details = { 0 };
1714   ip_details_t *ip = NULL;
1715   u32 sw_if_index = ~0;
1716
1717   sw_if_index = ntohl (mp->sw_if_index);
1718
1719   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1720                            sw_if_index, empty_ip_details);
1721
1722   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
1723                          sw_if_index);
1724
1725   ip->present = 1;
1726 }
1727
1728 static void
1729 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
1730 {
1731   vat_main_t *vam = &vat_main;
1732
1733   if (VAT_JSON_ARRAY != vam->json_tree.type)
1734     {
1735       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1736       vat_json_init_array (&vam->json_tree);
1737     }
1738   vat_json_array_add_uint (&vam->json_tree,
1739                            clib_net_to_host_u32 (mp->sw_if_index));
1740 }
1741
1742 static void vl_api_map_domain_details_t_handler_json
1743   (vl_api_map_domain_details_t * mp)
1744 {
1745   vat_json_node_t *node = NULL;
1746   vat_main_t *vam = &vat_main;
1747   struct in6_addr ip6;
1748   struct in_addr ip4;
1749
1750   if (VAT_JSON_ARRAY != vam->json_tree.type)
1751     {
1752       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1753       vat_json_init_array (&vam->json_tree);
1754     }
1755
1756   node = vat_json_array_add (&vam->json_tree);
1757   vat_json_init_object (node);
1758
1759   vat_json_object_add_uint (node, "domain_index",
1760                             clib_net_to_host_u32 (mp->domain_index));
1761   clib_memcpy (&ip6, mp->ip6_prefix, sizeof (ip6));
1762   vat_json_object_add_ip6 (node, "ip6_prefix", ip6);
1763   clib_memcpy (&ip4, mp->ip4_prefix, sizeof (ip4));
1764   vat_json_object_add_ip4 (node, "ip4_prefix", ip4);
1765   clib_memcpy (&ip6, mp->ip6_src, sizeof (ip6));
1766   vat_json_object_add_ip6 (node, "ip6_src", ip6);
1767   vat_json_object_add_int (node, "ip6_prefix_len", mp->ip6_prefix_len);
1768   vat_json_object_add_int (node, "ip4_prefix_len", mp->ip4_prefix_len);
1769   vat_json_object_add_int (node, "ip6_src_len", mp->ip6_src_len);
1770   vat_json_object_add_int (node, "ea_bits_len", mp->ea_bits_len);
1771   vat_json_object_add_int (node, "psid_offset", mp->psid_offset);
1772   vat_json_object_add_int (node, "psid_length", mp->psid_length);
1773   vat_json_object_add_uint (node, "flags", mp->flags);
1774   vat_json_object_add_uint (node, "mtu", clib_net_to_host_u16 (mp->mtu));
1775   vat_json_object_add_int (node, "is_translation", mp->is_translation);
1776 }
1777
1778 static void vl_api_map_domain_details_t_handler
1779   (vl_api_map_domain_details_t * mp)
1780 {
1781   vat_main_t *vam = &vat_main;
1782
1783   if (mp->is_translation)
1784     {
1785       fformat (vam->ofp,
1786                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U/%d (ip6-src) index: %u\n",
1787                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1788                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1789                format_ip6_address, mp->ip6_src, mp->ip6_src_len,
1790                clib_net_to_host_u32 (mp->domain_index));
1791     }
1792   else
1793     {
1794       fformat (vam->ofp,
1795                "* %U/%d (ipv4-prefix) %U/%d (ipv6-prefix) %U (ip6-src) index: %u\n",
1796                format_ip4_address, mp->ip4_prefix, mp->ip4_prefix_len,
1797                format_ip6_address, mp->ip6_prefix, mp->ip6_prefix_len,
1798                format_ip6_address, mp->ip6_src,
1799                clib_net_to_host_u32 (mp->domain_index));
1800     }
1801   fformat (vam->ofp, "  ea-len %d psid-offset %d psid-len %d mtu %d %s\n",
1802            mp->ea_bits_len, mp->psid_offset, mp->psid_length, mp->mtu,
1803            mp->is_translation ? "map-t" : "");
1804 }
1805
1806 static void vl_api_map_rule_details_t_handler_json
1807   (vl_api_map_rule_details_t * mp)
1808 {
1809   struct in6_addr ip6;
1810   vat_json_node_t *node = NULL;
1811   vat_main_t *vam = &vat_main;
1812
1813   if (VAT_JSON_ARRAY != vam->json_tree.type)
1814     {
1815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1816       vat_json_init_array (&vam->json_tree);
1817     }
1818
1819   node = vat_json_array_add (&vam->json_tree);
1820   vat_json_init_object (node);
1821
1822   vat_json_object_add_uint (node, "psid", clib_net_to_host_u16 (mp->psid));
1823   clib_memcpy (&ip6, mp->ip6_dst, sizeof (ip6));
1824   vat_json_object_add_ip6 (node, "ip6_dst", ip6);
1825 }
1826
1827 static void
1828 vl_api_map_rule_details_t_handler (vl_api_map_rule_details_t * mp)
1829 {
1830   vat_main_t *vam = &vat_main;
1831   fformat (vam->ofp, " %d (psid) %U (ip6-dst)\n",
1832            clib_net_to_host_u16 (mp->psid), format_ip6_address, mp->ip6_dst);
1833 }
1834
1835 static void
1836 vl_api_dhcp_compl_event_t_handler (vl_api_dhcp_compl_event_t * mp)
1837 {
1838   vat_main_t *vam = &vat_main;
1839   errmsg ("DHCP compl event: pid %d %s hostname %s host_addr %U "
1840           "router_addr %U host_mac %U\n",
1841           mp->pid, mp->is_ipv6 ? "ipv6" : "ipv4", mp->hostname,
1842           format_ip4_address, &mp->host_address,
1843           format_ip4_address, &mp->router_address,
1844           format_ethernet_address, mp->host_mac);
1845 }
1846
1847 static void vl_api_dhcp_compl_event_t_handler_json
1848   (vl_api_dhcp_compl_event_t * mp)
1849 {
1850   /* JSON output not supported */
1851 }
1852
1853 static void
1854 set_simple_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1855                               u32 counter)
1856 {
1857   vat_main_t *vam = &vat_main;
1858   static u64 default_counter = 0;
1859
1860   vec_validate_init_empty (vam->simple_interface_counters, vnet_counter_type,
1861                            NULL);
1862   vec_validate_init_empty (vam->simple_interface_counters[vnet_counter_type],
1863                            sw_if_index, default_counter);
1864   vam->simple_interface_counters[vnet_counter_type][sw_if_index] = counter;
1865 }
1866
1867 static void
1868 set_combined_interface_counter (u8 vnet_counter_type, u32 sw_if_index,
1869                                 interface_counter_t counter)
1870 {
1871   vat_main_t *vam = &vat_main;
1872   static interface_counter_t default_counter = { 0, };
1873
1874   vec_validate_init_empty (vam->combined_interface_counters,
1875                            vnet_counter_type, NULL);
1876   vec_validate_init_empty (vam->combined_interface_counters
1877                            [vnet_counter_type], sw_if_index, default_counter);
1878   vam->combined_interface_counters[vnet_counter_type][sw_if_index] = counter;
1879 }
1880
1881 static void vl_api_vnet_interface_counters_t_handler
1882   (vl_api_vnet_interface_counters_t * mp)
1883 {
1884   /* not supported */
1885 }
1886
1887 static void vl_api_vnet_interface_counters_t_handler_json
1888   (vl_api_vnet_interface_counters_t * mp)
1889 {
1890   interface_counter_t counter;
1891   vlib_counter_t *v;
1892   u64 *v_packets;
1893   u64 packets;
1894   u32 count;
1895   u32 first_sw_if_index;
1896   int i;
1897
1898   count = ntohl (mp->count);
1899   first_sw_if_index = ntohl (mp->first_sw_if_index);
1900
1901   if (!mp->is_combined)
1902     {
1903       v_packets = (u64 *) & mp->data;
1904       for (i = 0; i < count; i++)
1905         {
1906           packets =
1907             clib_net_to_host_u64 (clib_mem_unaligned (v_packets, u64));
1908           set_simple_interface_counter (mp->vnet_counter_type,
1909                                         first_sw_if_index + i, packets);
1910           v_packets++;
1911         }
1912     }
1913   else
1914     {
1915       v = (vlib_counter_t *) & mp->data;
1916       for (i = 0; i < count; i++)
1917         {
1918           counter.packets =
1919             clib_net_to_host_u64 (clib_mem_unaligned (&v->packets, u64));
1920           counter.bytes =
1921             clib_net_to_host_u64 (clib_mem_unaligned (&v->bytes, u64));
1922           set_combined_interface_counter (mp->vnet_counter_type,
1923                                           first_sw_if_index + i, counter);
1924           v++;
1925         }
1926     }
1927 }
1928
1929 static u32
1930 ip4_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1931 {
1932   vat_main_t *vam = &vat_main;
1933   u32 i;
1934
1935   for (i = 0; i < vec_len (vam->ip4_fib_counters_vrf_id_by_index); i++)
1936     {
1937       if (vam->ip4_fib_counters_vrf_id_by_index[i] == vrf_id)
1938         {
1939           return i;
1940         }
1941     }
1942   return ~0;
1943 }
1944
1945 static u32
1946 ip6_fib_counters_get_vrf_index_by_vrf_id (u32 vrf_id)
1947 {
1948   vat_main_t *vam = &vat_main;
1949   u32 i;
1950
1951   for (i = 0; i < vec_len (vam->ip6_fib_counters_vrf_id_by_index); i++)
1952     {
1953       if (vam->ip6_fib_counters_vrf_id_by_index[i] == vrf_id)
1954         {
1955           return i;
1956         }
1957     }
1958   return ~0;
1959 }
1960
1961 static void vl_api_vnet_ip4_fib_counters_t_handler
1962   (vl_api_vnet_ip4_fib_counters_t * mp)
1963 {
1964   /* not supported */
1965 }
1966
1967 static void vl_api_vnet_ip4_fib_counters_t_handler_json
1968   (vl_api_vnet_ip4_fib_counters_t * mp)
1969 {
1970   vat_main_t *vam = &vat_main;
1971   vl_api_ip4_fib_counter_t *v;
1972   ip4_fib_counter_t *counter;
1973   struct in_addr ip4;
1974   u32 vrf_id;
1975   u32 vrf_index;
1976   u32 count;
1977   int i;
1978
1979   vrf_id = ntohl (mp->vrf_id);
1980   vrf_index = ip4_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
1981   if (~0 == vrf_index)
1982     {
1983       vrf_index = vec_len (vam->ip4_fib_counters_vrf_id_by_index);
1984       vec_validate (vam->ip4_fib_counters_vrf_id_by_index, vrf_index);
1985       vam->ip4_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
1986       vec_validate (vam->ip4_fib_counters, vrf_index);
1987       vam->ip4_fib_counters[vrf_index] = NULL;
1988     }
1989
1990   vec_free (vam->ip4_fib_counters[vrf_index]);
1991   v = (vl_api_ip4_fib_counter_t *) & mp->c;
1992   count = ntohl (mp->count);
1993   for (i = 0; i < count; i++)
1994     {
1995       vec_validate (vam->ip4_fib_counters[vrf_index], i);
1996       counter = &vam->ip4_fib_counters[vrf_index][i];
1997       clib_memcpy (&ip4, &v->address, sizeof (ip4));
1998       counter->address = ip4;
1999       counter->address_length = v->address_length;
2000       counter->packets = clib_net_to_host_u64 (v->packets);
2001       counter->bytes = clib_net_to_host_u64 (v->bytes);
2002       v++;
2003     }
2004 }
2005
2006 static void vl_api_vnet_ip6_fib_counters_t_handler
2007   (vl_api_vnet_ip6_fib_counters_t * mp)
2008 {
2009   /* not supported */
2010 }
2011
2012 static void vl_api_vnet_ip6_fib_counters_t_handler_json
2013   (vl_api_vnet_ip6_fib_counters_t * mp)
2014 {
2015   vat_main_t *vam = &vat_main;
2016   vl_api_ip6_fib_counter_t *v;
2017   ip6_fib_counter_t *counter;
2018   struct in6_addr ip6;
2019   u32 vrf_id;
2020   u32 vrf_index;
2021   u32 count;
2022   int i;
2023
2024   vrf_id = ntohl (mp->vrf_id);
2025   vrf_index = ip6_fib_counters_get_vrf_index_by_vrf_id (vrf_id);
2026   if (~0 == vrf_index)
2027     {
2028       vrf_index = vec_len (vam->ip6_fib_counters_vrf_id_by_index);
2029       vec_validate (vam->ip6_fib_counters_vrf_id_by_index, vrf_index);
2030       vam->ip6_fib_counters_vrf_id_by_index[vrf_index] = vrf_id;
2031       vec_validate (vam->ip6_fib_counters, vrf_index);
2032       vam->ip6_fib_counters[vrf_index] = NULL;
2033     }
2034
2035   vec_free (vam->ip6_fib_counters[vrf_index]);
2036   v = (vl_api_ip6_fib_counter_t *) & mp->c;
2037   count = ntohl (mp->count);
2038   for (i = 0; i < count; i++)
2039     {
2040       vec_validate (vam->ip6_fib_counters[vrf_index], i);
2041       counter = &vam->ip6_fib_counters[vrf_index][i];
2042       clib_memcpy (&ip6, &v->address, sizeof (ip6));
2043       counter->address = ip6;
2044       counter->address_length = v->address_length;
2045       counter->packets = clib_net_to_host_u64 (v->packets);
2046       counter->bytes = clib_net_to_host_u64 (v->bytes);
2047       v++;
2048     }
2049 }
2050
2051 static void vl_api_get_first_msg_id_reply_t_handler
2052   (vl_api_get_first_msg_id_reply_t * mp)
2053 {
2054   vat_main_t *vam = &vat_main;
2055   i32 retval = ntohl (mp->retval);
2056
2057   if (vam->async_mode)
2058     {
2059       vam->async_errors += (retval < 0);
2060     }
2061   else
2062     {
2063       vam->retval = retval;
2064       vam->result_ready = 1;
2065     }
2066   if (retval >= 0)
2067     {
2068       errmsg ("first message id %d\n", ntohs (mp->first_msg_id));
2069     }
2070 }
2071
2072 static void vl_api_get_first_msg_id_reply_t_handler_json
2073   (vl_api_get_first_msg_id_reply_t * mp)
2074 {
2075   vat_main_t *vam = &vat_main;
2076   vat_json_node_t node;
2077
2078   vat_json_init_object (&node);
2079   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2080   vat_json_object_add_uint (&node, "first_msg_id",
2081                             (uint) ntohs (mp->first_msg_id));
2082
2083   vat_json_print (vam->ofp, &node);
2084   vat_json_free (&node);
2085
2086   vam->retval = ntohl (mp->retval);
2087   vam->result_ready = 1;
2088 }
2089
2090 static void vl_api_get_node_graph_reply_t_handler
2091   (vl_api_get_node_graph_reply_t * mp)
2092 {
2093   vat_main_t *vam = &vat_main;
2094   api_main_t *am = &api_main;
2095   i32 retval = ntohl (mp->retval);
2096   u8 *pvt_copy, *reply;
2097   void *oldheap;
2098   vlib_node_t *node;
2099   int i;
2100
2101   if (vam->async_mode)
2102     {
2103       vam->async_errors += (retval < 0);
2104     }
2105   else
2106     {
2107       vam->retval = retval;
2108       vam->result_ready = 1;
2109     }
2110
2111   /* "Should never happen..." */
2112   if (retval != 0)
2113     return;
2114
2115   reply = (u8 *) (mp->reply_in_shmem);
2116   pvt_copy = vec_dup (reply);
2117
2118   /* Toss the shared-memory original... */
2119   pthread_mutex_lock (&am->vlib_rp->mutex);
2120   oldheap = svm_push_data_heap (am->vlib_rp);
2121
2122   vec_free (reply);
2123
2124   svm_pop_heap (oldheap);
2125   pthread_mutex_unlock (&am->vlib_rp->mutex);
2126
2127   if (vam->graph_nodes)
2128     {
2129       hash_free (vam->graph_node_index_by_name);
2130
2131       for (i = 0; i < vec_len (vam->graph_nodes); i++)
2132         {
2133           node = vam->graph_nodes[i];
2134           vec_free (node->name);
2135           vec_free (node->next_nodes);
2136           vec_free (node);
2137         }
2138       vec_free (vam->graph_nodes);
2139     }
2140
2141   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2142   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2143   vec_free (pvt_copy);
2144
2145   for (i = 0; i < vec_len (vam->graph_nodes); i++)
2146     {
2147       node = vam->graph_nodes[i];
2148       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2149     }
2150 }
2151
2152 static void vl_api_get_node_graph_reply_t_handler_json
2153   (vl_api_get_node_graph_reply_t * mp)
2154 {
2155   vat_main_t *vam = &vat_main;
2156   api_main_t *am = &api_main;
2157   void *oldheap;
2158   vat_json_node_t node;
2159   u8 *reply;
2160
2161   /* $$$$ make this real? */
2162   vat_json_init_object (&node);
2163   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2164   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2165
2166   reply = (u8 *) (mp->reply_in_shmem);
2167
2168   /* Toss the shared-memory original... */
2169   pthread_mutex_lock (&am->vlib_rp->mutex);
2170   oldheap = svm_push_data_heap (am->vlib_rp);
2171
2172   vec_free (reply);
2173
2174   svm_pop_heap (oldheap);
2175   pthread_mutex_unlock (&am->vlib_rp->mutex);
2176
2177   vat_json_print (vam->ofp, &node);
2178   vat_json_free (&node);
2179
2180   vam->retval = ntohl (mp->retval);
2181   vam->result_ready = 1;
2182 }
2183
2184 static void
2185 vl_api_lisp_locator_details_t_handler (vl_api_lisp_locator_details_t * mp)
2186 {
2187   vat_main_t *vam = &vat_main;
2188   u8 *s = 0;
2189
2190   if (mp->local)
2191     {
2192       s = format (s, "%=16d%=16d%=16d\n",
2193                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2194     }
2195   else
2196     {
2197       s = format (s, "%=16U%=16d%=16d\n",
2198                   mp->is_ipv6 ? format_ip6_address :
2199                   format_ip4_address,
2200                   mp->ip_address, mp->priority, mp->weight);
2201     }
2202
2203   fformat (vam->ofp, "%v", s);
2204   vec_free (s);
2205 }
2206
2207 static void
2208 vl_api_lisp_locator_details_t_handler_json (vl_api_lisp_locator_details_t *
2209                                             mp)
2210 {
2211   vat_main_t *vam = &vat_main;
2212   vat_json_node_t *node = NULL;
2213   struct in6_addr ip6;
2214   struct in_addr ip4;
2215
2216   if (VAT_JSON_ARRAY != vam->json_tree.type)
2217     {
2218       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2219       vat_json_init_array (&vam->json_tree);
2220     }
2221   node = vat_json_array_add (&vam->json_tree);
2222   vat_json_init_object (node);
2223
2224   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2225   vat_json_object_add_uint (node, "priority", mp->priority);
2226   vat_json_object_add_uint (node, "weight", mp->weight);
2227
2228   if (mp->local)
2229     vat_json_object_add_uint (node, "sw_if_index",
2230                               clib_net_to_host_u32 (mp->sw_if_index));
2231   else
2232     {
2233       if (mp->is_ipv6)
2234         {
2235           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2236           vat_json_object_add_ip6 (node, "address", ip6);
2237         }
2238       else
2239         {
2240           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2241           vat_json_object_add_ip4 (node, "address", ip4);
2242         }
2243     }
2244 }
2245
2246 static void
2247 vl_api_lisp_locator_set_details_t_handler (vl_api_lisp_locator_set_details_t *
2248                                            mp)
2249 {
2250   vat_main_t *vam = &vat_main;
2251   u8 *ls_name = 0;
2252
2253   ls_name = format (0, "%s", mp->ls_name);
2254
2255   fformat (vam->ofp, "%=10d%=15v\n", clib_net_to_host_u32 (mp->ls_index),
2256            ls_name);
2257   vec_free (ls_name);
2258 }
2259
2260 static void
2261   vl_api_lisp_locator_set_details_t_handler_json
2262   (vl_api_lisp_locator_set_details_t * mp)
2263 {
2264   vat_main_t *vam = &vat_main;
2265   vat_json_node_t *node = 0;
2266   u8 *ls_name = 0;
2267
2268   ls_name = format (0, "%s", mp->ls_name);
2269   vec_add1 (ls_name, 0);
2270
2271   if (VAT_JSON_ARRAY != vam->json_tree.type)
2272     {
2273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2274       vat_json_init_array (&vam->json_tree);
2275     }
2276   node = vat_json_array_add (&vam->json_tree);
2277
2278   vat_json_init_object (node);
2279   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2280   vat_json_object_add_uint (node, "ls_index",
2281                             clib_net_to_host_u32 (mp->ls_index));
2282   vec_free (ls_name);
2283 }
2284
2285 static u8 *
2286 format_lisp_flat_eid (u8 * s, va_list * args)
2287 {
2288   u32 type = va_arg (*args, u32);
2289   u8 *eid = va_arg (*args, u8 *);
2290   u32 eid_len = va_arg (*args, u32);
2291
2292   switch (type)
2293     {
2294     case 0:
2295       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2296     case 1:
2297       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2298     case 2:
2299       return format (s, "%U", format_ethernet_address, eid);
2300     }
2301   return 0;
2302 }
2303
2304 static u8 *
2305 format_lisp_eid_vat (u8 * s, va_list * args)
2306 {
2307   u32 type = va_arg (*args, u32);
2308   u8 *eid = va_arg (*args, u8 *);
2309   u32 eid_len = va_arg (*args, u32);
2310   u8 *seid = va_arg (*args, u8 *);
2311   u32 seid_len = va_arg (*args, u32);
2312   u32 is_src_dst = va_arg (*args, u32);
2313
2314   if (is_src_dst)
2315     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2316
2317   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2318
2319   return s;
2320 }
2321
2322 static void
2323 vl_api_lisp_eid_table_details_t_handler (vl_api_lisp_eid_table_details_t * mp)
2324 {
2325   vat_main_t *vam = &vat_main;
2326   u8 *s = 0, *eid = 0;
2327
2328   if (~0 == mp->locator_set_index)
2329     s = format (0, "action: %d", mp->action);
2330   else
2331     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2332
2333   eid = format (0, "%U", format_lisp_eid_vat,
2334                 mp->eid_type,
2335                 mp->eid,
2336                 mp->eid_prefix_len,
2337                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2338   vec_add1 (eid, 0);
2339
2340   fformat (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s\n",
2341            clib_net_to_host_u32 (mp->vni),
2342            eid,
2343            mp->is_local ? "local" : "remote",
2344            s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2345            clib_net_to_host_u16 (mp->key_id), mp->key);
2346
2347   vec_free (s);
2348   vec_free (eid);
2349 }
2350
2351 static void
2352 vl_api_lisp_eid_table_details_t_handler_json (vl_api_lisp_eid_table_details_t
2353                                               * mp)
2354 {
2355   vat_main_t *vam = &vat_main;
2356   vat_json_node_t *node = 0;
2357   u8 *eid = 0;
2358
2359   if (VAT_JSON_ARRAY != vam->json_tree.type)
2360     {
2361       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2362       vat_json_init_array (&vam->json_tree);
2363     }
2364   node = vat_json_array_add (&vam->json_tree);
2365
2366   vat_json_init_object (node);
2367   if (~0 == mp->locator_set_index)
2368     vat_json_object_add_uint (node, "action", mp->action);
2369   else
2370     vat_json_object_add_uint (node, "locator_set_index",
2371                               clib_net_to_host_u32 (mp->locator_set_index));
2372
2373   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2374   eid = format (0, "%U", format_lisp_eid_vat,
2375                 mp->eid_type,
2376                 mp->eid,
2377                 mp->eid_prefix_len,
2378                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2379   vec_add1 (eid, 0);
2380   vat_json_object_add_string_copy (node, "eid", eid);
2381   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2382   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2383   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2384
2385   if (mp->key_id)
2386     {
2387       vat_json_object_add_uint (node, "key_id",
2388                                 clib_net_to_host_u16 (mp->key_id));
2389       vat_json_object_add_string_copy (node, "key", mp->key);
2390     }
2391   vec_free (eid);
2392 }
2393
2394 static void
2395   vl_api_lisp_eid_table_map_details_t_handler
2396   (vl_api_lisp_eid_table_map_details_t * mp)
2397 {
2398   vat_main_t *vam = &vat_main;
2399
2400   u8 *line = format (0, "%=10d%=10d",
2401                      clib_net_to_host_u32 (mp->vni),
2402                      clib_net_to_host_u32 (mp->dp_table));
2403   fformat (vam->ofp, "%v\n", line);
2404   vec_free (line);
2405 }
2406
2407 static void
2408   vl_api_lisp_eid_table_map_details_t_handler_json
2409   (vl_api_lisp_eid_table_map_details_t * mp)
2410 {
2411   vat_main_t *vam = &vat_main;
2412   vat_json_node_t *node = NULL;
2413
2414   if (VAT_JSON_ARRAY != vam->json_tree.type)
2415     {
2416       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2417       vat_json_init_array (&vam->json_tree);
2418     }
2419   node = vat_json_array_add (&vam->json_tree);
2420   vat_json_init_object (node);
2421   vat_json_object_add_uint (node, "dp_table",
2422                             clib_net_to_host_u32 (mp->dp_table));
2423   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2424 }
2425
2426 static void
2427   vl_api_lisp_eid_table_vni_details_t_handler
2428   (vl_api_lisp_eid_table_vni_details_t * mp)
2429 {
2430   vat_main_t *vam = &vat_main;
2431
2432   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
2433   fformat (vam->ofp, "%v\n", line);
2434   vec_free (line);
2435 }
2436
2437 static void
2438   vl_api_lisp_eid_table_vni_details_t_handler_json
2439   (vl_api_lisp_eid_table_vni_details_t * mp)
2440 {
2441   vat_main_t *vam = &vat_main;
2442   vat_json_node_t *node = NULL;
2443
2444   if (VAT_JSON_ARRAY != vam->json_tree.type)
2445     {
2446       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2447       vat_json_init_array (&vam->json_tree);
2448     }
2449   node = vat_json_array_add (&vam->json_tree);
2450   vat_json_init_object (node);
2451   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2452 }
2453
2454 static u8 *
2455 format_decap_next (u8 * s, va_list * args)
2456 {
2457   u32 next_index = va_arg (*args, u32);
2458
2459   switch (next_index)
2460     {
2461     case LISP_GPE_INPUT_NEXT_DROP:
2462       return format (s, "drop");
2463     case LISP_GPE_INPUT_NEXT_IP4_INPUT:
2464       return format (s, "ip4");
2465     case LISP_GPE_INPUT_NEXT_IP6_INPUT:
2466       return format (s, "ip6");
2467     default:
2468       return format (s, "unknown %d", next_index);
2469     }
2470   return s;
2471 }
2472
2473 static void
2474 vl_api_lisp_gpe_tunnel_details_t_handler (vl_api_lisp_gpe_tunnel_details_t *
2475                                           mp)
2476 {
2477   vat_main_t *vam = &vat_main;
2478   u8 *iid_str;
2479   u8 *flag_str = NULL;
2480
2481   iid_str = format (0, "%d (0x%x)", ntohl (mp->iid), ntohl (mp->iid));
2482
2483 #define _(n,v) if (mp->flags & v) flag_str = format (flag_str, "%s-bit ", #n);
2484   foreach_lisp_gpe_flag_bit;
2485 #undef _
2486
2487   fformat (vam->ofp, "%=20d%=30U%=16U%=16d%=16d%=16U"
2488            "%=16d%=16d%=16sd=16d%=16s%=16s\n",
2489            mp->tunnels,
2490            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2491            mp->source_ip,
2492            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2493            mp->destination_ip,
2494            ntohl (mp->encap_fib_id),
2495            ntohl (mp->decap_fib_id),
2496            format_decap_next, ntohl (mp->dcap_next),
2497            mp->ver_res >> 6,
2498            flag_str, mp->next_protocol, mp->ver_res, mp->res, iid_str);
2499
2500   vec_free (iid_str);
2501 }
2502
2503 static void
2504   vl_api_lisp_gpe_tunnel_details_t_handler_json
2505   (vl_api_lisp_gpe_tunnel_details_t * mp)
2506 {
2507   vat_main_t *vam = &vat_main;
2508   vat_json_node_t *node = NULL;
2509   struct in6_addr ip6;
2510   struct in_addr ip4;
2511   u8 *next_decap_str;
2512
2513   next_decap_str = format (0, "%U", format_decap_next, htonl (mp->dcap_next));
2514
2515   if (VAT_JSON_ARRAY != vam->json_tree.type)
2516     {
2517       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2518       vat_json_init_array (&vam->json_tree);
2519     }
2520   node = vat_json_array_add (&vam->json_tree);
2521
2522   vat_json_init_object (node);
2523   vat_json_object_add_uint (node, "tunel", mp->tunnels);
2524   if (mp->is_ipv6)
2525     {
2526       clib_memcpy (&ip6, mp->source_ip, sizeof (ip6));
2527       vat_json_object_add_ip6 (node, "source address", ip6);
2528       clib_memcpy (&ip6, mp->destination_ip, sizeof (ip6));
2529       vat_json_object_add_ip6 (node, "destination address", ip6);
2530     }
2531   else
2532     {
2533       clib_memcpy (&ip4, mp->source_ip, sizeof (ip4));
2534       vat_json_object_add_ip4 (node, "source address", ip4);
2535       clib_memcpy (&ip4, mp->destination_ip, sizeof (ip4));
2536       vat_json_object_add_ip4 (node, "destination address", ip4);
2537     }
2538   vat_json_object_add_uint (node, "fib encap", ntohl (mp->encap_fib_id));
2539   vat_json_object_add_uint (node, "fib decap", ntohl (mp->decap_fib_id));
2540   vat_json_object_add_string_copy (node, "decap next", next_decap_str);
2541   vat_json_object_add_uint (node, "lisp version", mp->ver_res >> 6);
2542   vat_json_object_add_uint (node, "flags", mp->flags);
2543   vat_json_object_add_uint (node, "next protocol", mp->next_protocol);
2544   vat_json_object_add_uint (node, "ver_res", mp->ver_res);
2545   vat_json_object_add_uint (node, "res", mp->res);
2546   vat_json_object_add_uint (node, "iid", ntohl (mp->iid));
2547
2548   vec_free (next_decap_str);
2549 }
2550
2551 static void
2552   vl_api_show_lisp_map_register_state_reply_t_handler
2553   (vl_api_show_lisp_map_register_state_reply_t * mp)
2554 {
2555   vat_main_t *vam = &vat_main;
2556   int retval = clib_net_to_host_u32 (mp->retval);
2557
2558   fformat (vam->ofp, "%s\n", mp->is_enabled ? "enabled" : "disabled");
2559
2560   vam->retval = retval;
2561   vam->result_ready = 1;
2562 }
2563
2564 static void
2565   vl_api_show_lisp_map_register_state_reply_t_handler_json
2566   (vl_api_show_lisp_map_register_state_reply_t * mp)
2567 {
2568   vat_main_t *vam = &vat_main;
2569   vat_json_node_t _node, *node = &_node;
2570   int retval = clib_net_to_host_u32 (mp->retval);
2571
2572   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2573
2574   vat_json_init_object (node);
2575   vat_json_object_add_string_copy (node, "state", s);
2576
2577   vat_json_print (vam->ofp, node);
2578   vat_json_free (node);
2579
2580   vam->retval = retval;
2581   vam->result_ready = 1;
2582   vec_free (s);
2583 }
2584
2585 static void
2586   vl_api_show_lisp_rloc_probe_state_reply_t_handler
2587   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2588 {
2589   vat_main_t *vam = &vat_main;
2590   int retval = clib_net_to_host_u32 (mp->retval);
2591
2592   if (retval)
2593     goto end;
2594
2595   fformat (vam->ofp, "%s\n", mp->is_enabled ? "enabled" : "disabled");
2596 end:
2597   vam->retval = retval;
2598   vam->result_ready = 1;
2599 }
2600
2601 static void
2602   vl_api_show_lisp_rloc_probe_state_reply_t_handler_json
2603   (vl_api_show_lisp_rloc_probe_state_reply_t * mp)
2604 {
2605   vat_main_t *vam = &vat_main;
2606   vat_json_node_t _node, *node = &_node;
2607   int retval = clib_net_to_host_u32 (mp->retval);
2608
2609   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
2610   vat_json_init_object (node);
2611   vat_json_object_add_string_copy (node, "state", s);
2612
2613   vat_json_print (vam->ofp, node);
2614   vat_json_free (node);
2615
2616   vam->retval = retval;
2617   vam->result_ready = 1;
2618   vec_free (s);
2619 }
2620
2621 static void
2622   vl_api_lisp_adjacencies_get_reply_t_handler
2623   (vl_api_lisp_adjacencies_get_reply_t * mp)
2624 {
2625   vat_main_t *vam = &vat_main;
2626   u32 i, n;
2627   int retval = clib_net_to_host_u32 (mp->retval);
2628   vl_api_lisp_adjacency_t *a;
2629
2630   if (retval)
2631     goto end;
2632
2633   n = clib_net_to_host_u32 (mp->count);
2634
2635   for (i = 0; i < n; i++)
2636     {
2637       a = &mp->adjacencies[i];
2638       fformat (vam->ofp, "%U %40U\n",
2639                format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
2640                format_lisp_flat_eid, a->eid_type, a->reid,
2641                a->reid_prefix_len);
2642     }
2643
2644 end:
2645   vam->retval = retval;
2646   vam->result_ready = 1;
2647 }
2648
2649 static void
2650   vl_api_lisp_adjacencies_get_reply_t_handler_json
2651   (vl_api_lisp_adjacencies_get_reply_t * mp)
2652 {
2653   u8 *s = 0;
2654   vat_main_t *vam = &vat_main;
2655   vat_json_node_t *e = 0, root;
2656   u32 i, n;
2657   int retval = clib_net_to_host_u32 (mp->retval);
2658   vl_api_lisp_adjacency_t *a;
2659
2660   if (retval)
2661     goto end;
2662
2663   n = clib_net_to_host_u32 (mp->count);
2664   vat_json_init_array (&root);
2665
2666   for (i = 0; i < n; i++)
2667     {
2668       e = vat_json_array_add (&root);
2669       a = &mp->adjacencies[i];
2670
2671       vat_json_init_object (e);
2672       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
2673                   a->leid_prefix_len);
2674       vec_add1 (s, 0);
2675       vat_json_object_add_string_copy (e, "leid", s);
2676       vec_free (s);
2677
2678       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
2679                   a->reid_prefix_len);
2680       vec_add1 (s, 0);
2681       vat_json_object_add_string_copy (e, "reid", s);
2682       vec_free (s);
2683     }
2684
2685   vat_json_print (vam->ofp, &root);
2686   vat_json_free (&root);
2687
2688 end:
2689   vam->retval = retval;
2690   vam->result_ready = 1;
2691 }
2692
2693 static void
2694 vl_api_lisp_map_server_details_t_handler (vl_api_lisp_map_server_details_t
2695                                           * mp)
2696 {
2697   vat_main_t *vam = &vat_main;
2698
2699   fformat (vam->ofp, "%=20U\n",
2700            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2701            mp->ip_address);
2702 }
2703
2704 static void
2705   vl_api_lisp_map_server_details_t_handler_json
2706   (vl_api_lisp_map_server_details_t * mp)
2707 {
2708   vat_main_t *vam = &vat_main;
2709   vat_json_node_t *node = NULL;
2710   struct in6_addr ip6;
2711   struct in_addr ip4;
2712
2713   if (VAT_JSON_ARRAY != vam->json_tree.type)
2714     {
2715       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2716       vat_json_init_array (&vam->json_tree);
2717     }
2718   node = vat_json_array_add (&vam->json_tree);
2719
2720   vat_json_init_object (node);
2721   if (mp->is_ipv6)
2722     {
2723       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2724       vat_json_object_add_ip6 (node, "map-server", ip6);
2725     }
2726   else
2727     {
2728       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2729       vat_json_object_add_ip4 (node, "map-server", ip4);
2730     }
2731 }
2732
2733 static void
2734 vl_api_lisp_map_resolver_details_t_handler (vl_api_lisp_map_resolver_details_t
2735                                             * mp)
2736 {
2737   vat_main_t *vam = &vat_main;
2738
2739   fformat (vam->ofp, "%=20U\n",
2740            mp->is_ipv6 ? format_ip6_address : format_ip4_address,
2741            mp->ip_address);
2742 }
2743
2744 static void
2745   vl_api_lisp_map_resolver_details_t_handler_json
2746   (vl_api_lisp_map_resolver_details_t * mp)
2747 {
2748   vat_main_t *vam = &vat_main;
2749   vat_json_node_t *node = NULL;
2750   struct in6_addr ip6;
2751   struct in_addr ip4;
2752
2753   if (VAT_JSON_ARRAY != vam->json_tree.type)
2754     {
2755       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2756       vat_json_init_array (&vam->json_tree);
2757     }
2758   node = vat_json_array_add (&vam->json_tree);
2759
2760   vat_json_init_object (node);
2761   if (mp->is_ipv6)
2762     {
2763       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2764       vat_json_object_add_ip6 (node, "map resolver", ip6);
2765     }
2766   else
2767     {
2768       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2769       vat_json_object_add_ip4 (node, "map resolver", ip4);
2770     }
2771 }
2772
2773 static void
2774   vl_api_show_lisp_status_reply_t_handler
2775   (vl_api_show_lisp_status_reply_t * mp)
2776 {
2777   vat_main_t *vam = &vat_main;
2778   i32 retval = ntohl (mp->retval);
2779
2780   if (0 <= retval)
2781     {
2782       fformat (vam->ofp, "feature: %s\ngpe: %s\n",
2783                mp->feature_status ? "enabled" : "disabled",
2784                mp->gpe_status ? "enabled" : "disabled");
2785     }
2786
2787   vam->retval = retval;
2788   vam->result_ready = 1;
2789 }
2790
2791 static void
2792   vl_api_show_lisp_status_reply_t_handler_json
2793   (vl_api_show_lisp_status_reply_t * mp)
2794 {
2795   vat_main_t *vam = &vat_main;
2796   vat_json_node_t node;
2797   u8 *gpe_status = NULL;
2798   u8 *feature_status = NULL;
2799
2800   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
2801   feature_status = format (0, "%s",
2802                            mp->feature_status ? "enabled" : "disabled");
2803   vec_add1 (gpe_status, 0);
2804   vec_add1 (feature_status, 0);
2805
2806   vat_json_init_object (&node);
2807   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
2808   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
2809
2810   vec_free (gpe_status);
2811   vec_free (feature_status);
2812
2813   vat_json_print (vam->ofp, &node);
2814   vat_json_free (&node);
2815
2816   vam->retval = ntohl (mp->retval);
2817   vam->result_ready = 1;
2818 }
2819
2820 static void
2821   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler
2822   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2823 {
2824   vat_main_t *vam = &vat_main;
2825   i32 retval = ntohl (mp->retval);
2826
2827   if (retval >= 0)
2828     {
2829       fformat (vam->ofp, "%=20s\n", mp->locator_set_name);
2830     }
2831
2832   vam->retval = retval;
2833   vam->result_ready = 1;
2834 }
2835
2836 static void
2837   vl_api_lisp_get_map_request_itr_rlocs_reply_t_handler_json
2838   (vl_api_lisp_get_map_request_itr_rlocs_reply_t * mp)
2839 {
2840   vat_main_t *vam = &vat_main;
2841   vat_json_node_t *node = NULL;
2842
2843   if (VAT_JSON_ARRAY != vam->json_tree.type)
2844     {
2845       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2846       vat_json_init_array (&vam->json_tree);
2847     }
2848   node = vat_json_array_add (&vam->json_tree);
2849
2850   vat_json_init_object (node);
2851   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
2852
2853   vat_json_print (vam->ofp, node);
2854   vat_json_free (node);
2855
2856   vam->retval = ntohl (mp->retval);
2857   vam->result_ready = 1;
2858 }
2859
2860 static u8 *
2861 format_lisp_map_request_mode (u8 * s, va_list * args)
2862 {
2863   u32 mode = va_arg (*args, u32);
2864
2865   switch (mode)
2866     {
2867     case 0:
2868       return format (0, "dst-only");
2869     case 1:
2870       return format (0, "src-dst");
2871     }
2872   return 0;
2873 }
2874
2875 static void
2876   vl_api_show_lisp_map_request_mode_reply_t_handler
2877   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2878 {
2879   vat_main_t *vam = &vat_main;
2880   i32 retval = ntohl (mp->retval);
2881
2882   if (0 <= retval)
2883     {
2884       u32 mode = mp->mode;
2885       fformat (vam->ofp, "map_request_mode: %U\n",
2886                format_lisp_map_request_mode, mode);
2887     }
2888
2889   vam->retval = retval;
2890   vam->result_ready = 1;
2891 }
2892
2893 static void
2894   vl_api_show_lisp_map_request_mode_reply_t_handler_json
2895   (vl_api_show_lisp_map_request_mode_reply_t * mp)
2896 {
2897   vat_main_t *vam = &vat_main;
2898   vat_json_node_t node;
2899   u8 *s = 0;
2900   u32 mode;
2901
2902   mode = mp->mode;
2903   s = format (0, "%U", format_lisp_map_request_mode, mode);
2904   vec_add1 (s, 0);
2905
2906   vat_json_init_object (&node);
2907   vat_json_object_add_string_copy (&node, "map_request_mode", s);
2908   vat_json_print (vam->ofp, &node);
2909   vat_json_free (&node);
2910
2911   vec_free (s);
2912   vam->retval = ntohl (mp->retval);
2913   vam->result_ready = 1;
2914 }
2915
2916 static void
2917 vl_api_show_lisp_pitr_reply_t_handler (vl_api_show_lisp_pitr_reply_t * mp)
2918 {
2919   vat_main_t *vam = &vat_main;
2920   i32 retval = ntohl (mp->retval);
2921
2922   if (0 <= retval)
2923     {
2924       fformat (vam->ofp, "%-20s%-16s\n",
2925                mp->status ? "enabled" : "disabled",
2926                mp->status ? (char *) mp->locator_set_name : "");
2927     }
2928
2929   vam->retval = retval;
2930   vam->result_ready = 1;
2931 }
2932
2933 static void
2934 vl_api_show_lisp_pitr_reply_t_handler_json (vl_api_show_lisp_pitr_reply_t *
2935                                             mp)
2936 {
2937   vat_main_t *vam = &vat_main;
2938   vat_json_node_t node;
2939   u8 *status = 0;
2940
2941   status = format (0, "%s", mp->status ? "enabled" : "disabled");
2942   vec_add1 (status, 0);
2943
2944   vat_json_init_object (&node);
2945   vat_json_object_add_string_copy (&node, "status", status);
2946   if (mp->status)
2947     {
2948       vat_json_object_add_string_copy (&node, "locator_set",
2949                                        mp->locator_set_name);
2950     }
2951
2952   vec_free (status);
2953
2954   vat_json_print (vam->ofp, &node);
2955   vat_json_free (&node);
2956
2957   vam->retval = ntohl (mp->retval);
2958   vam->result_ready = 1;
2959 }
2960
2961 static u8 *
2962 format_policer_type (u8 * s, va_list * va)
2963 {
2964   u32 i = va_arg (*va, u32);
2965
2966   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2967     s = format (s, "1r2c");
2968   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2969     s = format (s, "1r3c");
2970   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2971     s = format (s, "2r3c-2698");
2972   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2973     s = format (s, "2r3c-4115");
2974   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2975     s = format (s, "2r3c-mef5cf1");
2976   else
2977     s = format (s, "ILLEGAL");
2978   return s;
2979 }
2980
2981 static u8 *
2982 format_policer_rate_type (u8 * s, va_list * va)
2983 {
2984   u32 i = va_arg (*va, u32);
2985
2986   if (i == SSE2_QOS_RATE_KBPS)
2987     s = format (s, "kbps");
2988   else if (i == SSE2_QOS_RATE_PPS)
2989     s = format (s, "pps");
2990   else
2991     s = format (s, "ILLEGAL");
2992   return s;
2993 }
2994
2995 static u8 *
2996 format_policer_round_type (u8 * s, va_list * va)
2997 {
2998   u32 i = va_arg (*va, u32);
2999
3000   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
3001     s = format (s, "closest");
3002   else if (i == SSE2_QOS_ROUND_TO_UP)
3003     s = format (s, "up");
3004   else if (i == SSE2_QOS_ROUND_TO_DOWN)
3005     s = format (s, "down");
3006   else
3007     s = format (s, "ILLEGAL");
3008   return s;
3009 }
3010
3011 static u8 *
3012 format_policer_action_type (u8 * s, va_list * va)
3013 {
3014   u32 i = va_arg (*va, u32);
3015
3016   if (i == SSE2_QOS_ACTION_DROP)
3017     s = format (s, "drop");
3018   else if (i == SSE2_QOS_ACTION_TRANSMIT)
3019     s = format (s, "transmit");
3020   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3021     s = format (s, "mark-and-transmit");
3022   else
3023     s = format (s, "ILLEGAL");
3024   return s;
3025 }
3026
3027 static u8 *
3028 format_dscp (u8 * s, va_list * va)
3029 {
3030   u32 i = va_arg (*va, u32);
3031   char *t = 0;
3032
3033   switch (i)
3034     {
3035 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
3036       foreach_vnet_dscp
3037 #undef _
3038     default:
3039       return format (s, "ILLEGAL");
3040     }
3041   s = format (s, "%s", t);
3042   return s;
3043 }
3044
3045 static void
3046 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
3047 {
3048   vat_main_t *vam = &vat_main;
3049   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
3050
3051   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3052     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3053   else
3054     conform_dscp_str = format (0, "");
3055
3056   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3057     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3058   else
3059     exceed_dscp_str = format (0, "");
3060
3061   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3062     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3063   else
3064     violate_dscp_str = format (0, "");
3065
3066   fformat (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
3067            "rate type %U, round type %U, %s rate, %s color-aware, "
3068            "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
3069            "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
3070            "conform action %U%s, exceed action %U%s, violate action %U%s\n",
3071            mp->name,
3072            format_policer_type, mp->type,
3073            ntohl (mp->cir),
3074            ntohl (mp->eir),
3075            clib_net_to_host_u64 (mp->cb),
3076            clib_net_to_host_u64 (mp->eb),
3077            format_policer_rate_type, mp->rate_type,
3078            format_policer_round_type, mp->round_type,
3079            mp->single_rate ? "single" : "dual",
3080            mp->color_aware ? "is" : "not",
3081            ntohl (mp->cir_tokens_per_period),
3082            ntohl (mp->pir_tokens_per_period),
3083            ntohl (mp->scale),
3084            ntohl (mp->current_limit),
3085            ntohl (mp->current_bucket),
3086            ntohl (mp->extended_limit),
3087            ntohl (mp->extended_bucket),
3088            clib_net_to_host_u64 (mp->last_update_time),
3089            format_policer_action_type, mp->conform_action_type,
3090            conform_dscp_str,
3091            format_policer_action_type, mp->exceed_action_type,
3092            exceed_dscp_str,
3093            format_policer_action_type, mp->violate_action_type,
3094            violate_dscp_str);
3095
3096   vec_free (conform_dscp_str);
3097   vec_free (exceed_dscp_str);
3098   vec_free (violate_dscp_str);
3099 }
3100
3101 static void vl_api_policer_details_t_handler_json
3102   (vl_api_policer_details_t * mp)
3103 {
3104   vat_main_t *vam = &vat_main;
3105   vat_json_node_t *node;
3106   u8 *rate_type_str, *round_type_str, *type_str;
3107   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
3108
3109   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
3110   round_type_str =
3111     format (0, "%U", format_policer_round_type, mp->round_type);
3112   type_str = format (0, "%U", format_policer_type, mp->type);
3113   conform_action_str = format (0, "%U", format_policer_action_type,
3114                                mp->conform_action_type);
3115   exceed_action_str = format (0, "%U", format_policer_action_type,
3116                               mp->exceed_action_type);
3117   violate_action_str = format (0, "%U", format_policer_action_type,
3118                                mp->violate_action_type);
3119
3120   if (VAT_JSON_ARRAY != vam->json_tree.type)
3121     {
3122       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3123       vat_json_init_array (&vam->json_tree);
3124     }
3125   node = vat_json_array_add (&vam->json_tree);
3126
3127   vat_json_init_object (node);
3128   vat_json_object_add_string_copy (node, "name", mp->name);
3129   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
3130   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
3131   vat_json_object_add_uint (node, "cb", ntohl (mp->cb));
3132   vat_json_object_add_uint (node, "eb", ntohl (mp->eb));
3133   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
3134   vat_json_object_add_string_copy (node, "round_type", round_type_str);
3135   vat_json_object_add_string_copy (node, "type", type_str);
3136   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
3137   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
3138   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
3139   vat_json_object_add_uint (node, "cir_tokens_per_period",
3140                             ntohl (mp->cir_tokens_per_period));
3141   vat_json_object_add_uint (node, "eir_tokens_per_period",
3142                             ntohl (mp->pir_tokens_per_period));
3143   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
3144   vat_json_object_add_uint (node, "current_bucket",
3145                             ntohl (mp->current_bucket));
3146   vat_json_object_add_uint (node, "extended_limit",
3147                             ntohl (mp->extended_limit));
3148   vat_json_object_add_uint (node, "extended_bucket",
3149                             ntohl (mp->extended_bucket));
3150   vat_json_object_add_uint (node, "last_update_time",
3151                             ntohl (mp->last_update_time));
3152   vat_json_object_add_string_copy (node, "conform_action",
3153                                    conform_action_str);
3154   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3155     {
3156       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
3157       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
3158       vec_free (dscp_str);
3159     }
3160   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
3161   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3162     {
3163       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
3164       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
3165       vec_free (dscp_str);
3166     }
3167   vat_json_object_add_string_copy (node, "violate_action",
3168                                    violate_action_str);
3169   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
3170     {
3171       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
3172       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
3173       vec_free (dscp_str);
3174     }
3175
3176   vec_free (rate_type_str);
3177   vec_free (round_type_str);
3178   vec_free (type_str);
3179   vec_free (conform_action_str);
3180   vec_free (exceed_action_str);
3181   vec_free (violate_action_str);
3182 }
3183
3184 static void
3185 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
3186                                            mp)
3187 {
3188   vat_main_t *vam = &vat_main;
3189   int i, count = ntohl (mp->count);
3190
3191   if (count > 0)
3192     fformat (vam->ofp, "classify table ids (%d) : ", count);
3193   for (i = 0; i < count; i++)
3194     {
3195       fformat (vam->ofp, "%d", ntohl (mp->ids[i]));
3196       fformat (vam->ofp, (i < count - 1) ? "," : "\n");
3197     }
3198   vam->retval = ntohl (mp->retval);
3199   vam->result_ready = 1;
3200 }
3201
3202 static void
3203   vl_api_classify_table_ids_reply_t_handler_json
3204   (vl_api_classify_table_ids_reply_t * mp)
3205 {
3206   vat_main_t *vam = &vat_main;
3207   int i, count = ntohl (mp->count);
3208
3209   if (count > 0)
3210     {
3211       vat_json_node_t node;
3212
3213       vat_json_init_object (&node);
3214       for (i = 0; i < count; i++)
3215         {
3216           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
3217         }
3218       vat_json_print (vam->ofp, &node);
3219       vat_json_free (&node);
3220     }
3221   vam->retval = ntohl (mp->retval);
3222   vam->result_ready = 1;
3223 }
3224
3225 static void
3226   vl_api_classify_table_by_interface_reply_t_handler
3227   (vl_api_classify_table_by_interface_reply_t * mp)
3228 {
3229   vat_main_t *vam = &vat_main;
3230   u32 table_id;
3231
3232   table_id = ntohl (mp->l2_table_id);
3233   if (table_id != ~0)
3234     fformat (vam->ofp, "l2 table id : %d\n", table_id);
3235   else
3236     fformat (vam->ofp, "l2 table id : No input ACL tables configured\n");
3237   table_id = ntohl (mp->ip4_table_id);
3238   if (table_id != ~0)
3239     fformat (vam->ofp, "ip4 table id : %d\n", table_id);
3240   else
3241     fformat (vam->ofp, "ip4 table id : No input ACL tables configured\n");
3242   table_id = ntohl (mp->ip6_table_id);
3243   if (table_id != ~0)
3244     fformat (vam->ofp, "ip6 table id : %d\n", table_id);
3245   else
3246     fformat (vam->ofp, "ip6 table id : No input ACL tables configured\n");
3247   vam->retval = ntohl (mp->retval);
3248   vam->result_ready = 1;
3249 }
3250
3251 static void
3252   vl_api_classify_table_by_interface_reply_t_handler_json
3253   (vl_api_classify_table_by_interface_reply_t * mp)
3254 {
3255   vat_main_t *vam = &vat_main;
3256   vat_json_node_t node;
3257
3258   vat_json_init_object (&node);
3259
3260   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
3261   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
3262   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
3263
3264   vat_json_print (vam->ofp, &node);
3265   vat_json_free (&node);
3266
3267   vam->retval = ntohl (mp->retval);
3268   vam->result_ready = 1;
3269 }
3270
3271 static void vl_api_policer_add_del_reply_t_handler
3272   (vl_api_policer_add_del_reply_t * mp)
3273 {
3274   vat_main_t *vam = &vat_main;
3275   i32 retval = ntohl (mp->retval);
3276   if (vam->async_mode)
3277     {
3278       vam->async_errors += (retval < 0);
3279     }
3280   else
3281     {
3282       vam->retval = retval;
3283       vam->result_ready = 1;
3284       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3285         /*
3286          * Note: this is just barely thread-safe, depends on
3287          * the main thread spinning waiting for an answer...
3288          */
3289         errmsg ("policer index %d\n", ntohl (mp->policer_index));
3290     }
3291 }
3292
3293 static void vl_api_policer_add_del_reply_t_handler_json
3294   (vl_api_policer_add_del_reply_t * mp)
3295 {
3296   vat_main_t *vam = &vat_main;
3297   vat_json_node_t node;
3298
3299   vat_json_init_object (&node);
3300   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3301   vat_json_object_add_uint (&node, "policer_index",
3302                             ntohl (mp->policer_index));
3303
3304   vat_json_print (vam->ofp, &node);
3305   vat_json_free (&node);
3306
3307   vam->retval = ntohl (mp->retval);
3308   vam->result_ready = 1;
3309 }
3310
3311 /* Format hex dump. */
3312 u8 *
3313 format_hex_bytes (u8 * s, va_list * va)
3314 {
3315   u8 *bytes = va_arg (*va, u8 *);
3316   int n_bytes = va_arg (*va, int);
3317   uword i;
3318
3319   /* Print short or long form depending on byte count. */
3320   uword short_form = n_bytes <= 32;
3321   uword indent = format_get_indent (s);
3322
3323   if (n_bytes == 0)
3324     return s;
3325
3326   for (i = 0; i < n_bytes; i++)
3327     {
3328       if (!short_form && (i % 32) == 0)
3329         s = format (s, "%08x: ", i);
3330       s = format (s, "%02x", bytes[i]);
3331       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3332         s = format (s, "\n%U", format_white_space, indent);
3333     }
3334
3335   return s;
3336 }
3337
3338 static void
3339 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3340                                             * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   i32 retval = ntohl (mp->retval);
3344   if (retval == 0)
3345     {
3346       fformat (vam->ofp, "classify table info :\n");
3347       fformat (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d\n",
3348                ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3349                ntohl (mp->miss_next_index));
3350       fformat (vam->ofp, "nbuckets: %d skip: %d match: %d\n",
3351                ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3352                ntohl (mp->match_n_vectors));
3353       fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->mask,
3354                ntohl (mp->mask_length));
3355     }
3356   vam->retval = retval;
3357   vam->result_ready = 1;
3358 }
3359
3360 static void
3361   vl_api_classify_table_info_reply_t_handler_json
3362   (vl_api_classify_table_info_reply_t * mp)
3363 {
3364   vat_main_t *vam = &vat_main;
3365   vat_json_node_t node;
3366
3367   i32 retval = ntohl (mp->retval);
3368   if (retval == 0)
3369     {
3370       vat_json_init_object (&node);
3371
3372       vat_json_object_add_int (&node, "sessions",
3373                                ntohl (mp->active_sessions));
3374       vat_json_object_add_int (&node, "nexttbl",
3375                                ntohl (mp->next_table_index));
3376       vat_json_object_add_int (&node, "nextnode",
3377                                ntohl (mp->miss_next_index));
3378       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3379       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3380       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3381       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3382                       ntohl (mp->mask_length), 0);
3383       vat_json_object_add_string_copy (&node, "mask", s);
3384
3385       vat_json_print (vam->ofp, &node);
3386       vat_json_free (&node);
3387     }
3388   vam->retval = ntohl (mp->retval);
3389   vam->result_ready = 1;
3390 }
3391
3392 static void
3393 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3394                                            mp)
3395 {
3396   vat_main_t *vam = &vat_main;
3397
3398   fformat (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3399            ntohl (mp->hit_next_index), ntohl (mp->advance),
3400            ntohl (mp->opaque_index));
3401   fformat (vam->ofp, "mask: %U\n", format_hex_bytes, mp->match,
3402            ntohl (mp->match_length));
3403 }
3404
3405 static void
3406   vl_api_classify_session_details_t_handler_json
3407   (vl_api_classify_session_details_t * mp)
3408 {
3409   vat_main_t *vam = &vat_main;
3410   vat_json_node_t *node = NULL;
3411
3412   if (VAT_JSON_ARRAY != vam->json_tree.type)
3413     {
3414       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3415       vat_json_init_array (&vam->json_tree);
3416     }
3417   node = vat_json_array_add (&vam->json_tree);
3418
3419   vat_json_init_object (node);
3420   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3421   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3422   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3423   u8 *s =
3424     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3425             0);
3426   vat_json_object_add_string_copy (node, "match", s);
3427 }
3428
3429 static void vl_api_pg_create_interface_reply_t_handler
3430   (vl_api_pg_create_interface_reply_t * mp)
3431 {
3432   vat_main_t *vam = &vat_main;
3433
3434   vam->retval = ntohl (mp->retval);
3435   vam->result_ready = 1;
3436 }
3437
3438 static void vl_api_pg_create_interface_reply_t_handler_json
3439   (vl_api_pg_create_interface_reply_t * mp)
3440 {
3441   vat_main_t *vam = &vat_main;
3442   vat_json_node_t node;
3443
3444   i32 retval = ntohl (mp->retval);
3445   if (retval == 0)
3446     {
3447       vat_json_init_object (&node);
3448
3449       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3450
3451       vat_json_print (vam->ofp, &node);
3452       vat_json_free (&node);
3453     }
3454   vam->retval = ntohl (mp->retval);
3455   vam->result_ready = 1;
3456 }
3457
3458 static void vl_api_policer_classify_details_t_handler
3459   (vl_api_policer_classify_details_t * mp)
3460 {
3461   vat_main_t *vam = &vat_main;
3462
3463   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3464            ntohl (mp->table_index));
3465 }
3466
3467 static void vl_api_policer_classify_details_t_handler_json
3468   (vl_api_policer_classify_details_t * mp)
3469 {
3470   vat_main_t *vam = &vat_main;
3471   vat_json_node_t *node;
3472
3473   if (VAT_JSON_ARRAY != vam->json_tree.type)
3474     {
3475       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3476       vat_json_init_array (&vam->json_tree);
3477     }
3478   node = vat_json_array_add (&vam->json_tree);
3479
3480   vat_json_init_object (node);
3481   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3482   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3483 }
3484
3485 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler
3486   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3487 {
3488   vat_main_t *vam = &vat_main;
3489   i32 retval = ntohl (mp->retval);
3490   if (vam->async_mode)
3491     {
3492       vam->async_errors += (retval < 0);
3493     }
3494   else
3495     {
3496       vam->retval = retval;
3497       vam->sw_if_index = ntohl (mp->sw_if_index);
3498       vam->result_ready = 1;
3499     }
3500 }
3501
3502 static void vl_api_ipsec_gre_add_del_tunnel_reply_t_handler_json
3503   (vl_api_ipsec_gre_add_del_tunnel_reply_t * mp)
3504 {
3505   vat_main_t *vam = &vat_main;
3506   vat_json_node_t node;
3507
3508   vat_json_init_object (&node);
3509   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3510   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
3511
3512   vat_json_print (vam->ofp, &node);
3513   vat_json_free (&node);
3514
3515   vam->retval = ntohl (mp->retval);
3516   vam->result_ready = 1;
3517 }
3518
3519 static void vl_api_flow_classify_details_t_handler
3520   (vl_api_flow_classify_details_t * mp)
3521 {
3522   vat_main_t *vam = &vat_main;
3523
3524   fformat (vam->ofp, "%10d%20d\n", ntohl (mp->sw_if_index),
3525            ntohl (mp->table_index));
3526 }
3527
3528 static void vl_api_flow_classify_details_t_handler_json
3529   (vl_api_flow_classify_details_t * mp)
3530 {
3531   vat_main_t *vam = &vat_main;
3532   vat_json_node_t *node;
3533
3534   if (VAT_JSON_ARRAY != vam->json_tree.type)
3535     {
3536       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3537       vat_json_init_array (&vam->json_tree);
3538     }
3539   node = vat_json_array_add (&vam->json_tree);
3540
3541   vat_json_init_object (node);
3542   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3543   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3544 }
3545
3546
3547
3548 #define vl_api_vnet_ip4_fib_counters_t_endian vl_noop_handler
3549 #define vl_api_vnet_ip4_fib_counters_t_print vl_noop_handler
3550 #define vl_api_vnet_ip6_fib_counters_t_endian vl_noop_handler
3551 #define vl_api_vnet_ip6_fib_counters_t_print vl_noop_handler
3552 #define vl_api_lisp_adjacencies_get_reply_t_endian vl_noop_handler
3553 #define vl_api_lisp_adjacencies_get_reply_t_print vl_noop_handler
3554
3555 /*
3556  * Generate boilerplate reply handlers, which
3557  * dig the return value out of the xxx_reply_t API message,
3558  * stick it into vam->retval, and set vam->result_ready
3559  *
3560  * Could also do this by pointing N message decode slots at
3561  * a single function, but that could break in subtle ways.
3562  */
3563
3564 #define foreach_standard_reply_retval_handler           \
3565 _(sw_interface_set_flags_reply)                         \
3566 _(sw_interface_add_del_address_reply)                   \
3567 _(sw_interface_set_table_reply)                         \
3568 _(sw_interface_set_mpls_enable_reply)                   \
3569 _(sw_interface_set_vpath_reply)                         \
3570 _(sw_interface_set_vxlan_bypass_reply)                  \
3571 _(sw_interface_set_l2_bridge_reply)                     \
3572 _(sw_interface_set_dpdk_hqos_pipe_reply)                \
3573 _(sw_interface_set_dpdk_hqos_subport_reply)             \
3574 _(sw_interface_set_dpdk_hqos_tctbl_reply)               \
3575 _(bridge_domain_add_del_reply)                          \
3576 _(sw_interface_set_l2_xconnect_reply)                   \
3577 _(l2fib_add_del_reply)                                  \
3578 _(ip_add_del_route_reply)                               \
3579 _(mpls_route_add_del_reply)                             \
3580 _(mpls_ip_bind_unbind_reply)                            \
3581 _(proxy_arp_add_del_reply)                              \
3582 _(proxy_arp_intfc_enable_disable_reply)                 \
3583 _(sw_interface_set_unnumbered_reply)                    \
3584 _(ip_neighbor_add_del_reply)                            \
3585 _(reset_vrf_reply)                                      \
3586 _(oam_add_del_reply)                                    \
3587 _(reset_fib_reply)                                      \
3588 _(dhcp_proxy_config_reply)                              \
3589 _(dhcp_proxy_config_2_reply)                            \
3590 _(dhcp_proxy_set_vss_reply)                             \
3591 _(dhcp_client_config_reply)                             \
3592 _(set_ip_flow_hash_reply)                               \
3593 _(sw_interface_ip6_enable_disable_reply)                \
3594 _(sw_interface_ip6_set_link_local_address_reply)        \
3595 _(sw_interface_ip6nd_ra_prefix_reply)                   \
3596 _(sw_interface_ip6nd_ra_config_reply)                   \
3597 _(set_arp_neighbor_limit_reply)                         \
3598 _(l2_patch_add_del_reply)                               \
3599 _(sr_tunnel_add_del_reply)                              \
3600 _(sr_policy_add_del_reply)                              \
3601 _(sr_multicast_map_add_del_reply)                       \
3602 _(classify_add_del_session_reply)                       \
3603 _(classify_set_interface_ip_table_reply)                \
3604 _(classify_set_interface_l2_tables_reply)               \
3605 _(l2tpv3_set_tunnel_cookies_reply)                      \
3606 _(l2tpv3_interface_enable_disable_reply)                \
3607 _(l2tpv3_set_lookup_key_reply)                          \
3608 _(l2_fib_clear_table_reply)                             \
3609 _(l2_interface_efp_filter_reply)                        \
3610 _(l2_interface_vlan_tag_rewrite_reply)                  \
3611 _(modify_vhost_user_if_reply)                           \
3612 _(delete_vhost_user_if_reply)                           \
3613 _(want_ip4_arp_events_reply)                            \
3614 _(want_ip6_nd_events_reply)                             \
3615 _(input_acl_set_interface_reply)                        \
3616 _(ipsec_spd_add_del_reply)                              \
3617 _(ipsec_interface_add_del_spd_reply)                    \
3618 _(ipsec_spd_add_del_entry_reply)                        \
3619 _(ipsec_sad_add_del_entry_reply)                        \
3620 _(ipsec_sa_set_key_reply)                               \
3621 _(ikev2_profile_add_del_reply)                          \
3622 _(ikev2_profile_set_auth_reply)                         \
3623 _(ikev2_profile_set_id_reply)                           \
3624 _(ikev2_profile_set_ts_reply)                           \
3625 _(ikev2_set_local_key_reply)                            \
3626 _(delete_loopback_reply)                                \
3627 _(bd_ip_mac_add_del_reply)                              \
3628 _(map_del_domain_reply)                                 \
3629 _(map_add_del_rule_reply)                               \
3630 _(want_interface_events_reply)                          \
3631 _(want_stats_reply)                                     \
3632 _(cop_interface_enable_disable_reply)                   \
3633 _(cop_whitelist_enable_disable_reply)                   \
3634 _(sw_interface_clear_stats_reply)                       \
3635 _(ioam_enable_reply)                              \
3636 _(ioam_disable_reply)                              \
3637 _(lisp_add_del_locator_reply)                           \
3638 _(lisp_add_del_local_eid_reply)                         \
3639 _(lisp_add_del_remote_mapping_reply)                    \
3640 _(lisp_add_del_adjacency_reply)                         \
3641 _(lisp_gpe_add_del_fwd_entry_reply)                     \
3642 _(lisp_add_del_map_resolver_reply)                      \
3643 _(lisp_add_del_map_server_reply)                        \
3644 _(lisp_gpe_enable_disable_reply)                        \
3645 _(lisp_gpe_add_del_iface_reply)                         \
3646 _(lisp_enable_disable_reply)                            \
3647 _(lisp_rloc_probe_enable_disable_reply)                 \
3648 _(lisp_map_register_enable_disable_reply)               \
3649 _(lisp_pitr_set_locator_set_reply)                      \
3650 _(lisp_map_request_mode_reply)                          \
3651 _(lisp_add_del_map_request_itr_rlocs_reply)             \
3652 _(lisp_eid_table_add_del_map_reply)                     \
3653 _(vxlan_gpe_add_del_tunnel_reply)                       \
3654 _(af_packet_delete_reply)                               \
3655 _(policer_classify_set_interface_reply)                 \
3656 _(netmap_create_reply)                                  \
3657 _(netmap_delete_reply)                                  \
3658 _(set_ipfix_exporter_reply)                             \
3659 _(set_ipfix_classify_stream_reply)                      \
3660 _(ipfix_classify_table_add_del_reply)                   \
3661 _(flow_classify_set_interface_reply)                    \
3662 _(sw_interface_span_enable_disable_reply)               \
3663 _(pg_capture_reply)                                     \
3664 _(pg_enable_disable_reply)                              \
3665 _(ip_source_and_port_range_check_add_del_reply)         \
3666 _(ip_source_and_port_range_check_interface_add_del_reply)\
3667 _(delete_subif_reply)                                   \
3668 _(l2_interface_pbb_tag_rewrite_reply)                   \
3669 _(punt_reply)                                           \
3670 _(feature_enable_disable_reply)                         \
3671 _(sw_interface_tag_add_del_reply)                       \
3672 _(sw_interface_set_mtu_reply)
3673
3674 #define _(n)                                    \
3675     static void vl_api_##n##_t_handler          \
3676     (vl_api_##n##_t * mp)                       \
3677     {                                           \
3678         vat_main_t * vam = &vat_main;           \
3679         i32 retval = ntohl(mp->retval);         \
3680         if (vam->async_mode) {                  \
3681             vam->async_errors += (retval < 0);  \
3682         } else {                                \
3683             vam->retval = retval;               \
3684             vam->result_ready = 1;              \
3685         }                                       \
3686     }
3687 foreach_standard_reply_retval_handler;
3688 #undef _
3689
3690 #define _(n)                                    \
3691     static void vl_api_##n##_t_handler_json     \
3692     (vl_api_##n##_t * mp)                       \
3693     {                                           \
3694         vat_main_t * vam = &vat_main;           \
3695         vat_json_node_t node;                   \
3696         vat_json_init_object(&node);            \
3697         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3698         vat_json_print(vam->ofp, &node);        \
3699         vam->retval = ntohl(mp->retval);        \
3700         vam->result_ready = 1;                  \
3701     }
3702 foreach_standard_reply_retval_handler;
3703 #undef _
3704
3705 /*
3706  * Table of message reply handlers, must include boilerplate handlers
3707  * we just generated
3708  */
3709
3710 #define foreach_vpe_api_reply_msg                                       \
3711 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3712 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3713 _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags)                       \
3714 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3715 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3716 _(CLI_REPLY, cli_reply)                                                 \
3717 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3718 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3719   sw_interface_add_del_address_reply)                                   \
3720 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3721 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3722 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3723 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3724 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3725   sw_interface_set_l2_xconnect_reply)                                   \
3726 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3727   sw_interface_set_l2_bridge_reply)                                     \
3728 _(SW_INTERFACE_SET_DPDK_HQOS_PIPE_REPLY,                                \
3729   sw_interface_set_dpdk_hqos_pipe_reply)                                \
3730 _(SW_INTERFACE_SET_DPDK_HQOS_SUBPORT_REPLY,                             \
3731   sw_interface_set_dpdk_hqos_subport_reply)                             \
3732 _(SW_INTERFACE_SET_DPDK_HQOS_TCTBL_REPLY,                               \
3733   sw_interface_set_dpdk_hqos_tctbl_reply)                               \
3734 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3735 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3736 _(BRIDGE_DOMAIN_SW_IF_DETAILS, bridge_domain_sw_if_details)             \
3737 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3738 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3739 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3740 _(TAP_CONNECT_REPLY, tap_connect_reply)                                 \
3741 _(TAP_MODIFY_REPLY, tap_modify_reply)                                   \
3742 _(TAP_DELETE_REPLY, tap_delete_reply)                                   \
3743 _(SW_INTERFACE_TAP_DETAILS, sw_interface_tap_details)                   \
3744 _(IP_ADD_DEL_ROUTE_REPLY, ip_add_del_route_reply)                       \
3745 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3746 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3747 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
3748 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
3749   proxy_arp_intfc_enable_disable_reply)                                 \
3750 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
3751 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3752   sw_interface_set_unnumbered_reply)                                    \
3753 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
3754 _(RESET_VRF_REPLY, reset_vrf_reply)                                     \
3755 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3756 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3757 _(OAM_ADD_DEL_REPLY, oam_add_del_reply)                                 \
3758 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
3759 _(DHCP_PROXY_CONFIG_REPLY, dhcp_proxy_config_reply)                     \
3760 _(DHCP_PROXY_CONFIG_2_REPLY, dhcp_proxy_config_2_reply)                 \
3761 _(DHCP_PROXY_SET_VSS_REPLY, dhcp_proxy_set_vss_reply)                   \
3762 _(DHCP_CLIENT_CONFIG_REPLY, dhcp_client_config_reply)                   \
3763 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3764 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3765   sw_interface_ip6_enable_disable_reply)                                \
3766 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY,                        \
3767   sw_interface_ip6_set_link_local_address_reply)                        \
3768 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
3769   sw_interface_ip6nd_ra_prefix_reply)                                   \
3770 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
3771   sw_interface_ip6nd_ra_config_reply)                                   \
3772 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
3773 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3774 _(SR_TUNNEL_ADD_DEL_REPLY, sr_tunnel_add_del_reply)                     \
3775 _(SR_POLICY_ADD_DEL_REPLY, sr_policy_add_del_reply)                     \
3776 _(SR_MULTICAST_MAP_ADD_DEL_REPLY, sr_multicast_map_add_del_reply)                     \
3777 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3778 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3779 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3780 classify_set_interface_ip_table_reply)                                  \
3781 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3782   classify_set_interface_l2_tables_reply)                               \
3783 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3784 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3785 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
3786 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
3787 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
3788   l2tpv3_interface_enable_disable_reply)                                \
3789 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
3790 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
3791 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3792 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3793 _(GRE_ADD_DEL_TUNNEL_REPLY, gre_add_del_tunnel_reply)                   \
3794 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
3795 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3796 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3797 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3798 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3799 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3800 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3801 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3802 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3803 _(L2_FIB_TABLE_ENTRY, l2_fib_table_entry)                               \
3804 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)           \
3805 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3806 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3807 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
3808 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
3809 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
3810 _(IP6_ND_EVENT, ip6_nd_event)                                           \
3811 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3812 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3813 _(IP_DETAILS, ip_details)                                               \
3814 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3815 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3816 _(IPSEC_SPD_ADD_DEL_ENTRY_REPLY, ipsec_spd_add_del_entry_reply)         \
3817 _(IPSEC_SAD_ADD_DEL_ENTRY_REPLY, ipsec_sad_add_del_entry_reply)         \
3818 _(IPSEC_SA_SET_KEY_REPLY, ipsec_sa_set_key_reply)                       \
3819 _(IKEV2_PROFILE_ADD_DEL_REPLY, ikev2_profile_add_del_reply)             \
3820 _(IKEV2_PROFILE_SET_AUTH_REPLY, ikev2_profile_set_auth_reply)           \
3821 _(IKEV2_PROFILE_SET_ID_REPLY, ikev2_profile_set_id_reply)               \
3822 _(IKEV2_PROFILE_SET_TS_REPLY, ikev2_profile_set_ts_reply)               \
3823 _(IKEV2_SET_LOCAL_KEY_REPLY, ikev2_set_local_key_reply)                 \
3824 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3825 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3826 _(DHCP_COMPL_EVENT, dhcp_compl_event)                                   \
3827 _(VNET_INTERFACE_COUNTERS, vnet_interface_counters)                     \
3828 _(VNET_IP4_FIB_COUNTERS, vnet_ip4_fib_counters)                         \
3829 _(VNET_IP6_FIB_COUNTERS, vnet_ip6_fib_counters)                         \
3830 _(MAP_ADD_DOMAIN_REPLY, map_add_domain_reply)                           \
3831 _(MAP_DEL_DOMAIN_REPLY, map_del_domain_reply)                           \
3832 _(MAP_ADD_DEL_RULE_REPLY, map_add_del_rule_reply)                       \
3833 _(MAP_DOMAIN_DETAILS, map_domain_details)                               \
3834 _(MAP_RULE_DETAILS, map_rule_details)                                   \
3835 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3836 _(WANT_STATS_REPLY, want_stats_reply)                                   \
3837 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3838 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3839 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3840 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3841 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3842 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3843 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3844 _(LISP_ADD_DEL_LOCATOR_SET_REPLY, lisp_add_del_locator_set_reply)       \
3845 _(LISP_ADD_DEL_LOCATOR_REPLY, lisp_add_del_locator_reply)               \
3846 _(LISP_ADD_DEL_LOCAL_EID_REPLY, lisp_add_del_local_eid_reply)           \
3847 _(LISP_ADD_DEL_REMOTE_MAPPING_REPLY, lisp_add_del_remote_mapping_reply) \
3848 _(LISP_ADD_DEL_ADJACENCY_REPLY, lisp_add_del_adjacency_reply)           \
3849 _(LISP_GPE_ADD_DEL_FWD_ENTRY_REPLY, lisp_gpe_add_del_fwd_entry_reply)   \
3850 _(LISP_ADD_DEL_MAP_RESOLVER_REPLY, lisp_add_del_map_resolver_reply)     \
3851 _(LISP_ADD_DEL_MAP_SERVER_REPLY, lisp_add_del_map_server_reply)         \
3852 _(LISP_GPE_ENABLE_DISABLE_REPLY, lisp_gpe_enable_disable_reply)         \
3853 _(LISP_ENABLE_DISABLE_REPLY, lisp_enable_disable_reply)                 \
3854 _(LISP_MAP_REGISTER_ENABLE_DISABLE_REPLY,                               \
3855   lisp_map_register_enable_disable_reply)                               \
3856 _(LISP_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                 \
3857   lisp_rloc_probe_enable_disable_reply)                                 \
3858 _(LISP_PITR_SET_LOCATOR_SET_REPLY, lisp_pitr_set_locator_set_reply)     \
3859 _(LISP_MAP_REQUEST_MODE_REPLY, lisp_map_request_mode_reply)             \
3860 _(LISP_EID_TABLE_ADD_DEL_MAP_REPLY, lisp_eid_table_add_del_map_reply)   \
3861 _(LISP_GPE_ADD_DEL_IFACE_REPLY, lisp_gpe_add_del_iface_reply)           \
3862 _(LISP_LOCATOR_SET_DETAILS, lisp_locator_set_details)                   \
3863 _(LISP_LOCATOR_DETAILS, lisp_locator_details)                           \
3864 _(LISP_EID_TABLE_DETAILS, lisp_eid_table_details)                       \
3865 _(LISP_EID_TABLE_MAP_DETAILS, lisp_eid_table_map_details)               \
3866 _(LISP_EID_TABLE_VNI_DETAILS, lisp_eid_table_vni_details)               \
3867 _(LISP_GPE_TUNNEL_DETAILS, lisp_gpe_tunnel_details)                     \
3868 _(LISP_MAP_RESOLVER_DETAILS, lisp_map_resolver_details)                 \
3869 _(LISP_MAP_SERVER_DETAILS, lisp_map_server_details)                     \
3870 _(LISP_ADJACENCIES_GET_REPLY, lisp_adjacencies_get_reply)               \
3871 _(SHOW_LISP_STATUS_REPLY, show_lisp_status_reply)                       \
3872 _(LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                             \
3873   lisp_add_del_map_request_itr_rlocs_reply)                             \
3874 _(LISP_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                 \
3875   lisp_get_map_request_itr_rlocs_reply)                                 \
3876 _(SHOW_LISP_PITR_REPLY, show_lisp_pitr_reply)                           \
3877 _(SHOW_LISP_MAP_REQUEST_MODE_REPLY, show_lisp_map_request_mode_reply)   \
3878 _(SHOW_LISP_RLOC_PROBE_STATE_REPLY, show_lisp_rloc_probe_state_reply)   \
3879 _(SHOW_LISP_MAP_REGISTER_STATE_REPLY,                                   \
3880   show_lisp_map_register_state_reply)                                   \
3881 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3882 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3883 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3884 _(POLICER_DETAILS, policer_details)                                     \
3885 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3886 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3887 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
3888 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
3889 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
3890 _(MPLS_FIB_DETAILS, mpls_fib_details)                                   \
3891 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3892 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3893 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3894 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3895 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3896 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3897 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3898 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3899 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3900 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3901 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3902 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3903 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3904 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3905 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3906 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3907 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3908 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3909 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3910  ip_source_and_port_range_check_add_del_reply)                          \
3911 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3912  ip_source_and_port_range_check_interface_add_del_reply)                \
3913 _(IPSEC_GRE_ADD_DEL_TUNNEL_REPLY, ipsec_gre_add_del_tunnel_reply)       \
3914 _(IPSEC_GRE_TUNNEL_DETAILS, ipsec_gre_tunnel_details)                   \
3915 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3916 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3917 _(PUNT_REPLY, punt_reply)                                               \
3918 _(IP_FIB_DETAILS, ip_fib_details)                                       \
3919 _(IP6_FIB_DETAILS, ip6_fib_details)                                     \
3920 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
3921 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
3922 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
3923 _(SW_INTERFACE_SET_MTU_REPLY, sw_interface_set_mtu_reply)               \
3924 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
3925 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)
3926
3927 /* M: construct, but don't yet send a message */
3928
3929 #define M(T,t)                                  \
3930 do {                                            \
3931     vam->result_ready = 0;                      \
3932     mp = vl_msg_api_alloc(sizeof(*mp));         \
3933     memset (mp, 0, sizeof (*mp));               \
3934     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3935     mp->client_index = vam->my_client_index;    \
3936 } while(0);
3937
3938 #define M2(T,t,n)                               \
3939 do {                                            \
3940     vam->result_ready = 0;                      \
3941     mp = vl_msg_api_alloc(sizeof(*mp)+(n));     \
3942     memset (mp, 0, sizeof (*mp));               \
3943     mp->_vl_msg_id = ntohs (VL_API_##T);        \
3944     mp->client_index = vam->my_client_index;    \
3945 } while(0);
3946
3947
3948 /* S: send a message */
3949 #define S (vl_msg_api_send_shmem (vam->vl_input_queue, (u8 *)&mp))
3950
3951 /* W: wait for results, with timeout */
3952 #define W                                       \
3953 do {                                            \
3954     timeout = vat_time_now (vam) + 1.0;         \
3955                                                 \
3956     while (vat_time_now (vam) < timeout) {      \
3957         if (vam->result_ready == 1) {           \
3958             return (vam->retval);               \
3959         }                                       \
3960     }                                           \
3961     return -99;                                 \
3962 } while(0);
3963
3964 /* W2: wait for results, with timeout */
3965 #define W2(body)                                \
3966 do {                                            \
3967     timeout = vat_time_now (vam) + 1.0;         \
3968                                                 \
3969     while (vat_time_now (vam) < timeout) {      \
3970         if (vam->result_ready == 1) {           \
3971           (body);                               \
3972           return (vam->retval);                 \
3973         }                                       \
3974     }                                           \
3975     return -99;                                 \
3976 } while(0);
3977
3978 typedef struct
3979 {
3980   u8 *name;
3981   u32 value;
3982 } name_sort_t;
3983
3984
3985 #define STR_VTR_OP_CASE(op)     \
3986     case L2_VTR_ ## op:         \
3987         return "" # op;
3988
3989 static const char *
3990 str_vtr_op (u32 vtr_op)
3991 {
3992   switch (vtr_op)
3993     {
3994       STR_VTR_OP_CASE (DISABLED);
3995       STR_VTR_OP_CASE (PUSH_1);
3996       STR_VTR_OP_CASE (PUSH_2);
3997       STR_VTR_OP_CASE (POP_1);
3998       STR_VTR_OP_CASE (POP_2);
3999       STR_VTR_OP_CASE (TRANSLATE_1_1);
4000       STR_VTR_OP_CASE (TRANSLATE_1_2);
4001       STR_VTR_OP_CASE (TRANSLATE_2_1);
4002       STR_VTR_OP_CASE (TRANSLATE_2_2);
4003     }
4004
4005   return "UNKNOWN";
4006 }
4007
4008 static int
4009 dump_sub_interface_table (vat_main_t * vam)
4010 {
4011   const sw_interface_subif_t *sub = NULL;
4012
4013   if (vam->json_output)
4014     {
4015       clib_warning
4016         ("JSON output supported only for VPE API calls and dump_stats_table");
4017       return -99;
4018     }
4019
4020   fformat (vam->ofp,
4021            "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s\n",
4022            "Interface", "sw_if_index",
4023            "sub id", "dot1ad", "tags", "outer id",
4024            "inner id", "exact", "default", "outer any", "inner any");
4025
4026   vec_foreach (sub, vam->sw_if_subif_table)
4027   {
4028     fformat (vam->ofp,
4029              "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d\n",
4030              sub->interface_name,
4031              sub->sw_if_index,
4032              sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
4033              sub->sub_number_of_tags, sub->sub_outer_vlan_id,
4034              sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
4035              sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
4036     if (sub->vtr_op != L2_VTR_DISABLED)
4037       {
4038         fformat (vam->ofp,
4039                  "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
4040                  "tag1: %d tag2: %d ]\n",
4041                  str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
4042                  sub->vtr_tag1, sub->vtr_tag2);
4043       }
4044   }
4045
4046   return 0;
4047 }
4048
4049 static int
4050 name_sort_cmp (void *a1, void *a2)
4051 {
4052   name_sort_t *n1 = a1;
4053   name_sort_t *n2 = a2;
4054
4055   return strcmp ((char *) n1->name, (char *) n2->name);
4056 }
4057
4058 static int
4059 dump_interface_table (vat_main_t * vam)
4060 {
4061   hash_pair_t *p;
4062   name_sort_t *nses = 0, *ns;
4063
4064   if (vam->json_output)
4065     {
4066       clib_warning
4067         ("JSON output supported only for VPE API calls and dump_stats_table");
4068       return -99;
4069     }
4070
4071   /* *INDENT-OFF* */
4072   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4073   ({
4074     vec_add2 (nses, ns, 1);
4075     ns->name = (u8 *)(p->key);
4076     ns->value = (u32) p->value[0];
4077   }));
4078   /* *INDENT-ON* */
4079
4080   vec_sort_with_function (nses, name_sort_cmp);
4081
4082   fformat (vam->ofp, "%-25s%-15s\n", "Interface", "sw_if_index");
4083   vec_foreach (ns, nses)
4084   {
4085     fformat (vam->ofp, "%-25s%-15d\n", ns->name, ns->value);
4086   }
4087   vec_free (nses);
4088   return 0;
4089 }
4090
4091 static int
4092 dump_ip_table (vat_main_t * vam, int is_ipv6)
4093 {
4094   const ip_details_t *det = NULL;
4095   const ip_address_details_t *address = NULL;
4096   u32 i = ~0;
4097
4098   fformat (vam->ofp, "%-12s\n", "sw_if_index");
4099
4100   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
4101   {
4102     i++;
4103     if (!det->present)
4104       {
4105         continue;
4106       }
4107     fformat (vam->ofp, "%-12d\n", i);
4108     fformat (vam->ofp,
4109              "            %-30s%-13s\n", "Address", "Prefix length");
4110     if (!det->addr)
4111       {
4112         continue;
4113       }
4114     vec_foreach (address, det->addr)
4115     {
4116       fformat (vam->ofp,
4117                "            %-30U%-13d\n",
4118                is_ipv6 ? format_ip6_address : format_ip4_address,
4119                address->ip, address->prefix_length);
4120     }
4121   }
4122
4123   return 0;
4124 }
4125
4126 static int
4127 dump_ipv4_table (vat_main_t * vam)
4128 {
4129   if (vam->json_output)
4130     {
4131       clib_warning
4132         ("JSON output supported only for VPE API calls and dump_stats_table");
4133       return -99;
4134     }
4135
4136   return dump_ip_table (vam, 0);
4137 }
4138
4139 static int
4140 dump_ipv6_table (vat_main_t * vam)
4141 {
4142   if (vam->json_output)
4143     {
4144       clib_warning
4145         ("JSON output supported only for VPE API calls and dump_stats_table");
4146       return -99;
4147     }
4148
4149   return dump_ip_table (vam, 1);
4150 }
4151
4152 static char *
4153 counter_type_to_str (u8 counter_type, u8 is_combined)
4154 {
4155   if (!is_combined)
4156     {
4157       switch (counter_type)
4158         {
4159         case VNET_INTERFACE_COUNTER_DROP:
4160           return "drop";
4161         case VNET_INTERFACE_COUNTER_PUNT:
4162           return "punt";
4163         case VNET_INTERFACE_COUNTER_IP4:
4164           return "ip4";
4165         case VNET_INTERFACE_COUNTER_IP6:
4166           return "ip6";
4167         case VNET_INTERFACE_COUNTER_RX_NO_BUF:
4168           return "rx-no-buf";
4169         case VNET_INTERFACE_COUNTER_RX_MISS:
4170           return "rx-miss";
4171         case VNET_INTERFACE_COUNTER_RX_ERROR:
4172           return "rx-error";
4173         case VNET_INTERFACE_COUNTER_TX_ERROR:
4174           return "tx-error";
4175         default:
4176           return "INVALID-COUNTER-TYPE";
4177         }
4178     }
4179   else
4180     {
4181       switch (counter_type)
4182         {
4183         case VNET_INTERFACE_COUNTER_RX:
4184           return "rx";
4185         case VNET_INTERFACE_COUNTER_TX:
4186           return "tx";
4187         default:
4188           return "INVALID-COUNTER-TYPE";
4189         }
4190     }
4191 }
4192
4193 static int
4194 dump_stats_table (vat_main_t * vam)
4195 {
4196   vat_json_node_t node;
4197   vat_json_node_t *msg_array;
4198   vat_json_node_t *msg;
4199   vat_json_node_t *counter_array;
4200   vat_json_node_t *counter;
4201   interface_counter_t c;
4202   u64 packets;
4203   ip4_fib_counter_t *c4;
4204   ip6_fib_counter_t *c6;
4205   int i, j;
4206
4207   if (!vam->json_output)
4208     {
4209       clib_warning ("dump_stats_table supported only in JSON format");
4210       return -99;
4211     }
4212
4213   vat_json_init_object (&node);
4214
4215   /* interface counters */
4216   msg_array = vat_json_object_add (&node, "interface_counters");
4217   vat_json_init_array (msg_array);
4218   for (i = 0; i < vec_len (vam->simple_interface_counters); i++)
4219     {
4220       msg = vat_json_array_add (msg_array);
4221       vat_json_init_object (msg);
4222       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4223                                        (u8 *) counter_type_to_str (i, 0));
4224       vat_json_object_add_int (msg, "is_combined", 0);
4225       counter_array = vat_json_object_add (msg, "data");
4226       vat_json_init_array (counter_array);
4227       for (j = 0; j < vec_len (vam->simple_interface_counters[i]); j++)
4228         {
4229           packets = vam->simple_interface_counters[i][j];
4230           vat_json_array_add_uint (counter_array, packets);
4231         }
4232     }
4233   for (i = 0; i < vec_len (vam->combined_interface_counters); i++)
4234     {
4235       msg = vat_json_array_add (msg_array);
4236       vat_json_init_object (msg);
4237       vat_json_object_add_string_copy (msg, "vnet_counter_type",
4238                                        (u8 *) counter_type_to_str (i, 1));
4239       vat_json_object_add_int (msg, "is_combined", 1);
4240       counter_array = vat_json_object_add (msg, "data");
4241       vat_json_init_array (counter_array);
4242       for (j = 0; j < vec_len (vam->combined_interface_counters[i]); j++)
4243         {
4244           c = vam->combined_interface_counters[i][j];
4245           counter = vat_json_array_add (counter_array);
4246           vat_json_init_object (counter);
4247           vat_json_object_add_uint (counter, "packets", c.packets);
4248           vat_json_object_add_uint (counter, "bytes", c.bytes);
4249         }
4250     }
4251
4252   /* ip4 fib counters */
4253   msg_array = vat_json_object_add (&node, "ip4_fib_counters");
4254   vat_json_init_array (msg_array);
4255   for (i = 0; i < vec_len (vam->ip4_fib_counters); i++)
4256     {
4257       msg = vat_json_array_add (msg_array);
4258       vat_json_init_object (msg);
4259       vat_json_object_add_uint (msg, "vrf_id",
4260                                 vam->ip4_fib_counters_vrf_id_by_index[i]);
4261       counter_array = vat_json_object_add (msg, "c");
4262       vat_json_init_array (counter_array);
4263       for (j = 0; j < vec_len (vam->ip4_fib_counters[i]); j++)
4264         {
4265           counter = vat_json_array_add (counter_array);
4266           vat_json_init_object (counter);
4267           c4 = &vam->ip4_fib_counters[i][j];
4268           vat_json_object_add_ip4 (counter, "address", c4->address);
4269           vat_json_object_add_uint (counter, "address_length",
4270                                     c4->address_length);
4271           vat_json_object_add_uint (counter, "packets", c4->packets);
4272           vat_json_object_add_uint (counter, "bytes", c4->bytes);
4273         }
4274     }
4275
4276   /* ip6 fib counters */
4277   msg_array = vat_json_object_add (&node, "ip6_fib_counters");
4278   vat_json_init_array (msg_array);
4279   for (i = 0; i < vec_len (vam->ip6_fib_counters); i++)
4280     {
4281       msg = vat_json_array_add (msg_array);
4282       vat_json_init_object (msg);
4283       vat_json_object_add_uint (msg, "vrf_id",
4284                                 vam->ip6_fib_counters_vrf_id_by_index[i]);
4285       counter_array = vat_json_object_add (msg, "c");
4286       vat_json_init_array (counter_array);
4287       for (j = 0; j < vec_len (vam->ip6_fib_counters[i]); j++)
4288         {
4289           counter = vat_json_array_add (counter_array);
4290           vat_json_init_object (counter);
4291           c6 = &vam->ip6_fib_counters[i][j];
4292           vat_json_object_add_ip6 (counter, "address", c6->address);
4293           vat_json_object_add_uint (counter, "address_length",
4294                                     c6->address_length);
4295           vat_json_object_add_uint (counter, "packets", c6->packets);
4296           vat_json_object_add_uint (counter, "bytes", c6->bytes);
4297         }
4298     }
4299
4300   vat_json_print (vam->ofp, &node);
4301   vat_json_free (&node);
4302
4303   return 0;
4304 }
4305
4306 int
4307 exec (vat_main_t * vam)
4308 {
4309   api_main_t *am = &api_main;
4310   vl_api_cli_request_t *mp;
4311   f64 timeout;
4312   void *oldheap;
4313   u8 *cmd = 0;
4314   unformat_input_t *i = vam->input;
4315
4316   if (vec_len (i->buffer) == 0)
4317     return -1;
4318
4319   if (vam->exec_mode == 0 && unformat (i, "mode"))
4320     {
4321       vam->exec_mode = 1;
4322       return 0;
4323     }
4324   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4325     {
4326       vam->exec_mode = 0;
4327       return 0;
4328     }
4329
4330
4331   M (CLI_REQUEST, cli_request);
4332
4333   /*
4334    * Copy cmd into shared memory.
4335    * In order for the CLI command to work, it
4336    * must be a vector ending in \n, not a C-string ending
4337    * in \n\0.
4338    */
4339   pthread_mutex_lock (&am->vlib_rp->mutex);
4340   oldheap = svm_push_data_heap (am->vlib_rp);
4341
4342   vec_validate (cmd, vec_len (vam->input->buffer) - 1);
4343   clib_memcpy (cmd, vam->input->buffer, vec_len (vam->input->buffer));
4344
4345   svm_pop_heap (oldheap);
4346   pthread_mutex_unlock (&am->vlib_rp->mutex);
4347
4348   mp->cmd_in_shmem = (u64) cmd;
4349   S;
4350   timeout = vat_time_now (vam) + 10.0;
4351
4352   while (vat_time_now (vam) < timeout)
4353     {
4354       if (vam->result_ready == 1)
4355         {
4356           u8 *free_me;
4357           if (vam->shmem_result != NULL)
4358             fformat (vam->ofp, "%s", vam->shmem_result);
4359           pthread_mutex_lock (&am->vlib_rp->mutex);
4360           oldheap = svm_push_data_heap (am->vlib_rp);
4361
4362           free_me = (u8 *) vam->shmem_result;
4363           vec_free (free_me);
4364
4365           svm_pop_heap (oldheap);
4366           pthread_mutex_unlock (&am->vlib_rp->mutex);
4367           return 0;
4368         }
4369     }
4370   return -99;
4371 }
4372
4373 /*
4374  * Future replacement of exec() that passes CLI buffers directly in
4375  * the API messages instead of an additional shared memory area.
4376  */
4377 static int
4378 exec_inband (vat_main_t * vam)
4379 {
4380   vl_api_cli_inband_t *mp;
4381   f64 timeout;
4382   unformat_input_t *i = vam->input;
4383
4384   if (vec_len (i->buffer) == 0)
4385     return -1;
4386
4387   if (vam->exec_mode == 0 && unformat (i, "mode"))
4388     {
4389       vam->exec_mode = 1;
4390       return 0;
4391     }
4392   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
4393     {
4394       vam->exec_mode = 0;
4395       return 0;
4396     }
4397
4398   /*
4399    * In order for the CLI command to work, it
4400    * must be a vector ending in \n, not a C-string ending
4401    * in \n\0.
4402    */
4403   u32 len = vec_len (vam->input->buffer);
4404   M2 (CLI_INBAND, cli_inband, len);
4405   clib_memcpy (mp->cmd, vam->input->buffer, len);
4406   mp->length = htonl (len);
4407
4408   S;
4409   W2 (fformat (vam->ofp, "%s", vam->cmd_reply));
4410 }
4411
4412 static int
4413 api_create_loopback (vat_main_t * vam)
4414 {
4415   unformat_input_t *i = vam->input;
4416   vl_api_create_loopback_t *mp;
4417   f64 timeout;
4418   u8 mac_address[6];
4419   u8 mac_set = 0;
4420
4421   memset (mac_address, 0, sizeof (mac_address));
4422
4423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4424     {
4425       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
4426         mac_set = 1;
4427       else
4428         break;
4429     }
4430
4431   /* Construct the API message */
4432   M (CREATE_LOOPBACK, create_loopback);
4433   if (mac_set)
4434     clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
4435
4436   S;
4437   W;
4438 }
4439
4440 static int
4441 api_delete_loopback (vat_main_t * vam)
4442 {
4443   unformat_input_t *i = vam->input;
4444   vl_api_delete_loopback_t *mp;
4445   f64 timeout;
4446   u32 sw_if_index = ~0;
4447
4448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4449     {
4450       if (unformat (i, "sw_if_index %d", &sw_if_index))
4451         ;
4452       else
4453         break;
4454     }
4455
4456   if (sw_if_index == ~0)
4457     {
4458       errmsg ("missing sw_if_index\n");
4459       return -99;
4460     }
4461
4462   /* Construct the API message */
4463   M (DELETE_LOOPBACK, delete_loopback);
4464   mp->sw_if_index = ntohl (sw_if_index);
4465
4466   S;
4467   W;
4468 }
4469
4470 static int
4471 api_want_stats (vat_main_t * vam)
4472 {
4473   unformat_input_t *i = vam->input;
4474   vl_api_want_stats_t *mp;
4475   f64 timeout;
4476   int enable = -1;
4477
4478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4479     {
4480       if (unformat (i, "enable"))
4481         enable = 1;
4482       else if (unformat (i, "disable"))
4483         enable = 0;
4484       else
4485         break;
4486     }
4487
4488   if (enable == -1)
4489     {
4490       errmsg ("missing enable|disable\n");
4491       return -99;
4492     }
4493
4494   M (WANT_STATS, want_stats);
4495   mp->enable_disable = enable;
4496
4497   S;
4498   W;
4499 }
4500
4501 static int
4502 api_want_interface_events (vat_main_t * vam)
4503 {
4504   unformat_input_t *i = vam->input;
4505   vl_api_want_interface_events_t *mp;
4506   f64 timeout;
4507   int enable = -1;
4508
4509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4510     {
4511       if (unformat (i, "enable"))
4512         enable = 1;
4513       else if (unformat (i, "disable"))
4514         enable = 0;
4515       else
4516         break;
4517     }
4518
4519   if (enable == -1)
4520     {
4521       errmsg ("missing enable|disable\n");
4522       return -99;
4523     }
4524
4525   M (WANT_INTERFACE_EVENTS, want_interface_events);
4526   mp->enable_disable = enable;
4527
4528   vam->interface_event_display = enable;
4529
4530   S;
4531   W;
4532 }
4533
4534
4535 /* Note: non-static, called once to set up the initial intfc table */
4536 int
4537 api_sw_interface_dump (vat_main_t * vam)
4538 {
4539   vl_api_sw_interface_dump_t *mp;
4540   f64 timeout;
4541   hash_pair_t *p;
4542   name_sort_t *nses = 0, *ns;
4543   sw_interface_subif_t *sub = NULL;
4544
4545   /* Toss the old name table */
4546   /* *INDENT-OFF* */
4547   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
4548   ({
4549     vec_add2 (nses, ns, 1);
4550     ns->name = (u8 *)(p->key);
4551     ns->value = (u32) p->value[0];
4552   }));
4553   /* *INDENT-ON* */
4554
4555   hash_free (vam->sw_if_index_by_interface_name);
4556
4557   vec_foreach (ns, nses) vec_free (ns->name);
4558
4559   vec_free (nses);
4560
4561   vec_foreach (sub, vam->sw_if_subif_table)
4562   {
4563     vec_free (sub->interface_name);
4564   }
4565   vec_free (vam->sw_if_subif_table);
4566
4567   /* recreate the interface name hash table */
4568   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
4569
4570   /* Get list of ethernets */
4571   M (SW_INTERFACE_DUMP, sw_interface_dump);
4572   mp->name_filter_valid = 1;
4573   strncpy ((char *) mp->name_filter, "Ether", sizeof (mp->name_filter) - 1);
4574   S;
4575
4576   /* and local / loopback interfaces */
4577   M (SW_INTERFACE_DUMP, sw_interface_dump);
4578   mp->name_filter_valid = 1;
4579   strncpy ((char *) mp->name_filter, "lo", sizeof (mp->name_filter) - 1);
4580   S;
4581
4582   /* and packet-generator interfaces */
4583   M (SW_INTERFACE_DUMP, sw_interface_dump);
4584   mp->name_filter_valid = 1;
4585   strncpy ((char *) mp->name_filter, "pg", sizeof (mp->name_filter) - 1);
4586   S;
4587
4588   /* and vxlan-gpe tunnel interfaces */
4589   M (SW_INTERFACE_DUMP, sw_interface_dump);
4590   mp->name_filter_valid = 1;
4591   strncpy ((char *) mp->name_filter, "vxlan_gpe",
4592            sizeof (mp->name_filter) - 1);
4593   S;
4594
4595   /* and vxlan tunnel interfaces */
4596   M (SW_INTERFACE_DUMP, sw_interface_dump);
4597   mp->name_filter_valid = 1;
4598   strncpy ((char *) mp->name_filter, "vxlan", sizeof (mp->name_filter) - 1);
4599   S;
4600
4601   /* and host (af_packet) interfaces */
4602   M (SW_INTERFACE_DUMP, sw_interface_dump);
4603   mp->name_filter_valid = 1;
4604   strncpy ((char *) mp->name_filter, "host", sizeof (mp->name_filter) - 1);
4605   S;
4606
4607   /* and l2tpv3 tunnel interfaces */
4608   M (SW_INTERFACE_DUMP, sw_interface_dump);
4609   mp->name_filter_valid = 1;
4610   strncpy ((char *) mp->name_filter, "l2tpv3_tunnel",
4611            sizeof (mp->name_filter) - 1);
4612   S;
4613
4614   /* and GRE tunnel interfaces */
4615   M (SW_INTERFACE_DUMP, sw_interface_dump);
4616   mp->name_filter_valid = 1;
4617   strncpy ((char *) mp->name_filter, "gre", sizeof (mp->name_filter) - 1);
4618   S;
4619
4620   /* and LISP-GPE interfaces */
4621   M (SW_INTERFACE_DUMP, sw_interface_dump);
4622   mp->name_filter_valid = 1;
4623   strncpy ((char *) mp->name_filter, "lisp_gpe",
4624            sizeof (mp->name_filter) - 1);
4625   S;
4626
4627   /* and IPSEC tunnel interfaces */
4628   M (SW_INTERFACE_DUMP, sw_interface_dump);
4629   mp->name_filter_valid = 1;
4630   strncpy ((char *) mp->name_filter, "ipsec", sizeof (mp->name_filter) - 1);
4631   S;
4632
4633   /* Use a control ping for synchronization */
4634   {
4635     vl_api_control_ping_t *mp;
4636     M (CONTROL_PING, control_ping);
4637     S;
4638   }
4639   W;
4640 }
4641
4642 static int
4643 api_sw_interface_set_flags (vat_main_t * vam)
4644 {
4645   unformat_input_t *i = vam->input;
4646   vl_api_sw_interface_set_flags_t *mp;
4647   f64 timeout;
4648   u32 sw_if_index;
4649   u8 sw_if_index_set = 0;
4650   u8 admin_up = 0, link_up = 0;
4651
4652   /* Parse args required to build the message */
4653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4654     {
4655       if (unformat (i, "admin-up"))
4656         admin_up = 1;
4657       else if (unformat (i, "admin-down"))
4658         admin_up = 0;
4659       else if (unformat (i, "link-up"))
4660         link_up = 1;
4661       else if (unformat (i, "link-down"))
4662         link_up = 0;
4663       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4664         sw_if_index_set = 1;
4665       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4666         sw_if_index_set = 1;
4667       else
4668         break;
4669     }
4670
4671   if (sw_if_index_set == 0)
4672     {
4673       errmsg ("missing interface name or sw_if_index\n");
4674       return -99;
4675     }
4676
4677   /* Construct the API message */
4678   M (SW_INTERFACE_SET_FLAGS, sw_interface_set_flags);
4679   mp->sw_if_index = ntohl (sw_if_index);
4680   mp->admin_up_down = admin_up;
4681   mp->link_up_down = link_up;
4682
4683   /* send it... */
4684   S;
4685
4686   /* Wait for a reply, return the good/bad news... */
4687   W;
4688 }
4689
4690 static int
4691 api_sw_interface_clear_stats (vat_main_t * vam)
4692 {
4693   unformat_input_t *i = vam->input;
4694   vl_api_sw_interface_clear_stats_t *mp;
4695   f64 timeout;
4696   u32 sw_if_index;
4697   u8 sw_if_index_set = 0;
4698
4699   /* Parse args required to build the message */
4700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4701     {
4702       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4703         sw_if_index_set = 1;
4704       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4705         sw_if_index_set = 1;
4706       else
4707         break;
4708     }
4709
4710   /* Construct the API message */
4711   M (SW_INTERFACE_CLEAR_STATS, sw_interface_clear_stats);
4712
4713   if (sw_if_index_set == 1)
4714     mp->sw_if_index = ntohl (sw_if_index);
4715   else
4716     mp->sw_if_index = ~0;
4717
4718   /* send it... */
4719   S;
4720
4721   /* Wait for a reply, return the good/bad news... */
4722   W;
4723 }
4724
4725 static int
4726 api_sw_interface_set_dpdk_hqos_pipe (vat_main_t * vam)
4727 {
4728   unformat_input_t *i = vam->input;
4729   vl_api_sw_interface_set_dpdk_hqos_pipe_t *mp;
4730   f64 timeout;
4731   u32 sw_if_index;
4732   u8 sw_if_index_set = 0;
4733   u32 subport;
4734   u8 subport_set = 0;
4735   u32 pipe;
4736   u8 pipe_set = 0;
4737   u32 profile;
4738   u8 profile_set = 0;
4739
4740   /* Parse args required to build the message */
4741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4742     {
4743       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4744         sw_if_index_set = 1;
4745       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4746         sw_if_index_set = 1;
4747       else if (unformat (i, "subport %u", &subport))
4748         subport_set = 1;
4749       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4750         sw_if_index_set = 1;
4751       else if (unformat (i, "pipe %u", &pipe))
4752         pipe_set = 1;
4753       else if (unformat (i, "profile %u", &profile))
4754         profile_set = 1;
4755       else
4756         break;
4757     }
4758
4759   if (sw_if_index_set == 0)
4760     {
4761       errmsg ("missing interface name or sw_if_index\n");
4762       return -99;
4763     }
4764
4765   if (subport_set == 0)
4766     {
4767       errmsg ("missing subport \n");
4768       return -99;
4769     }
4770
4771   if (pipe_set == 0)
4772     {
4773       errmsg ("missing pipe\n");
4774       return -99;
4775     }
4776
4777   if (profile_set == 0)
4778     {
4779       errmsg ("missing profile\n");
4780       return -99;
4781     }
4782
4783   M (SW_INTERFACE_SET_DPDK_HQOS_PIPE, sw_interface_set_dpdk_hqos_pipe);
4784
4785   mp->sw_if_index = ntohl (sw_if_index);
4786   mp->subport = ntohl (subport);
4787   mp->pipe = ntohl (pipe);
4788   mp->profile = ntohl (profile);
4789
4790
4791   S;
4792   W;
4793   /* NOTREACHED */
4794   return 0;
4795 }
4796
4797 static int
4798 api_sw_interface_set_dpdk_hqos_subport (vat_main_t * vam)
4799 {
4800   unformat_input_t *i = vam->input;
4801   vl_api_sw_interface_set_dpdk_hqos_subport_t *mp;
4802   f64 timeout;
4803   u32 sw_if_index;
4804   u8 sw_if_index_set = 0;
4805   u32 subport;
4806   u8 subport_set = 0;
4807   u32 tb_rate = 1250000000;     /* 10GbE */
4808   u32 tb_size = 1000000;
4809   u32 tc_rate[] = { 1250000000, 1250000000, 1250000000, 1250000000 };
4810   u32 tc_period = 10;
4811
4812   /* Parse args required to build the message */
4813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4814     {
4815       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4816         sw_if_index_set = 1;
4817       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4818         sw_if_index_set = 1;
4819       else if (unformat (i, "subport %u", &subport))
4820         subport_set = 1;
4821       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4822         sw_if_index_set = 1;
4823       else if (unformat (i, "rate %u", &tb_rate))
4824         {
4825           u32 tc_id;
4826
4827           for (tc_id = 0; tc_id < (sizeof (tc_rate) / sizeof (tc_rate[0]));
4828                tc_id++)
4829             tc_rate[tc_id] = tb_rate;
4830         }
4831       else if (unformat (i, "bktsize %u", &tb_size))
4832         ;
4833       else if (unformat (i, "tc0 %u", &tc_rate[0]))
4834         ;
4835       else if (unformat (i, "tc1 %u", &tc_rate[1]))
4836         ;
4837       else if (unformat (i, "tc2 %u", &tc_rate[2]))
4838         ;
4839       else if (unformat (i, "tc3 %u", &tc_rate[3]))
4840         ;
4841       else if (unformat (i, "period %u", &tc_period))
4842         ;
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
4853   if (subport_set == 0)
4854     {
4855       errmsg ("missing subport \n");
4856       return -99;
4857     }
4858
4859   M (SW_INTERFACE_SET_DPDK_HQOS_SUBPORT, sw_interface_set_dpdk_hqos_subport);
4860
4861   mp->sw_if_index = ntohl (sw_if_index);
4862   mp->subport = ntohl (subport);
4863   mp->tb_rate = ntohl (tb_rate);
4864   mp->tb_size = ntohl (tb_size);
4865   mp->tc_rate[0] = ntohl (tc_rate[0]);
4866   mp->tc_rate[1] = ntohl (tc_rate[1]);
4867   mp->tc_rate[2] = ntohl (tc_rate[2]);
4868   mp->tc_rate[3] = ntohl (tc_rate[3]);
4869   mp->tc_period = ntohl (tc_period);
4870
4871   S;
4872   W;
4873   /* NOTREACHED */
4874   return 0;
4875 }
4876
4877 static int
4878 api_sw_interface_set_dpdk_hqos_tctbl (vat_main_t * vam)
4879 {
4880   unformat_input_t *i = vam->input;
4881   vl_api_sw_interface_set_dpdk_hqos_tctbl_t *mp;
4882   f64 timeout;
4883   u32 sw_if_index;
4884   u8 sw_if_index_set = 0;
4885   u8 entry_set = 0;
4886   u8 tc_set = 0;
4887   u8 queue_set = 0;
4888   u32 entry, tc, queue;
4889
4890   /* Parse args required to build the message */
4891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4892     {
4893       if (unformat (i, "rx %U", unformat_sw_if_index, vam, &sw_if_index))
4894         sw_if_index_set = 1;
4895       else if (unformat (i, "sw_if_index %u", &sw_if_index))
4896         sw_if_index_set = 1;
4897       else if (unformat (i, "entry %d", &entry))
4898         entry_set = 1;
4899       else if (unformat (i, "tc %d", &tc))
4900         tc_set = 1;
4901       else if (unformat (i, "queue %d", &queue))
4902         queue_set = 1;
4903       else
4904         break;
4905     }
4906
4907   if (sw_if_index_set == 0)
4908     {
4909       errmsg ("missing interface name or sw_if_index\n");
4910       return -99;
4911     }
4912
4913   if (entry_set == 0)
4914     {
4915       errmsg ("missing entry \n");
4916       return -99;
4917     }
4918
4919   if (tc_set == 0)
4920     {
4921       errmsg ("missing traffic class \n");
4922       return -99;
4923     }
4924
4925   if (queue_set == 0)
4926     {
4927       errmsg ("missing queue \n");
4928       return -99;
4929     }
4930
4931   M (SW_INTERFACE_SET_DPDK_HQOS_TCTBL, sw_interface_set_dpdk_hqos_tctbl);
4932
4933   mp->sw_if_index = ntohl (sw_if_index);
4934   mp->entry = ntohl (entry);
4935   mp->tc = ntohl (tc);
4936   mp->queue = ntohl (queue);
4937
4938   S;
4939   W;
4940   /* NOTREACHED */
4941   return 0;
4942 }
4943
4944 static int
4945 api_sw_interface_add_del_address (vat_main_t * vam)
4946 {
4947   unformat_input_t *i = vam->input;
4948   vl_api_sw_interface_add_del_address_t *mp;
4949   f64 timeout;
4950   u32 sw_if_index;
4951   u8 sw_if_index_set = 0;
4952   u8 is_add = 1, del_all = 0;
4953   u32 address_length = 0;
4954   u8 v4_address_set = 0;
4955   u8 v6_address_set = 0;
4956   ip4_address_t v4address;
4957   ip6_address_t v6address;
4958
4959   /* Parse args required to build the message */
4960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4961     {
4962       if (unformat (i, "del-all"))
4963         del_all = 1;
4964       else if (unformat (i, "del"))
4965         is_add = 0;
4966       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
4967         sw_if_index_set = 1;
4968       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4969         sw_if_index_set = 1;
4970       else if (unformat (i, "%U/%d",
4971                          unformat_ip4_address, &v4address, &address_length))
4972         v4_address_set = 1;
4973       else if (unformat (i, "%U/%d",
4974                          unformat_ip6_address, &v6address, &address_length))
4975         v6_address_set = 1;
4976       else
4977         break;
4978     }
4979
4980   if (sw_if_index_set == 0)
4981     {
4982       errmsg ("missing interface name or sw_if_index\n");
4983       return -99;
4984     }
4985   if (v4_address_set && v6_address_set)
4986     {
4987       errmsg ("both v4 and v6 addresses set\n");
4988       return -99;
4989     }
4990   if (!v4_address_set && !v6_address_set && !del_all)
4991     {
4992       errmsg ("no addresses set\n");
4993       return -99;
4994     }
4995
4996   /* Construct the API message */
4997   M (SW_INTERFACE_ADD_DEL_ADDRESS, sw_interface_add_del_address);
4998
4999   mp->sw_if_index = ntohl (sw_if_index);
5000   mp->is_add = is_add;
5001   mp->del_all = del_all;
5002   if (v6_address_set)
5003     {
5004       mp->is_ipv6 = 1;
5005       clib_memcpy (mp->address, &v6address, sizeof (v6address));
5006     }
5007   else
5008     {
5009       clib_memcpy (mp->address, &v4address, sizeof (v4address));
5010     }
5011   mp->address_length = address_length;
5012
5013   /* send it... */
5014   S;
5015
5016   /* Wait for a reply, return good/bad news  */
5017   W;
5018 }
5019
5020 static int
5021 api_sw_interface_set_mpls_enable (vat_main_t * vam)
5022 {
5023   unformat_input_t *i = vam->input;
5024   vl_api_sw_interface_set_mpls_enable_t *mp;
5025   f64 timeout;
5026   u32 sw_if_index;
5027   u8 sw_if_index_set = 0;
5028   u8 enable = 1;
5029
5030   /* Parse args required to build the message */
5031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5032     {
5033       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5034         sw_if_index_set = 1;
5035       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5036         sw_if_index_set = 1;
5037       else if (unformat (i, "disable"))
5038         enable = 0;
5039       else if (unformat (i, "dis"))
5040         enable = 0;
5041       else
5042         break;
5043     }
5044
5045   if (sw_if_index_set == 0)
5046     {
5047       errmsg ("missing interface name or sw_if_index\n");
5048       return -99;
5049     }
5050
5051   /* Construct the API message */
5052   M (SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable);
5053
5054   mp->sw_if_index = ntohl (sw_if_index);
5055   mp->enable = enable;
5056
5057   /* send it... */
5058   S;
5059
5060   /* Wait for a reply... */
5061   W;
5062 }
5063
5064 static int
5065 api_sw_interface_set_table (vat_main_t * vam)
5066 {
5067   unformat_input_t *i = vam->input;
5068   vl_api_sw_interface_set_table_t *mp;
5069   f64 timeout;
5070   u32 sw_if_index, vrf_id = 0;
5071   u8 sw_if_index_set = 0;
5072   u8 is_ipv6 = 0;
5073
5074   /* Parse args required to build the message */
5075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5076     {
5077       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5078         sw_if_index_set = 1;
5079       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5080         sw_if_index_set = 1;
5081       else if (unformat (i, "vrf %d", &vrf_id))
5082         ;
5083       else if (unformat (i, "ipv6"))
5084         is_ipv6 = 1;
5085       else
5086         break;
5087     }
5088
5089   if (sw_if_index_set == 0)
5090     {
5091       errmsg ("missing interface name or sw_if_index\n");
5092       return -99;
5093     }
5094
5095   /* Construct the API message */
5096   M (SW_INTERFACE_SET_TABLE, sw_interface_set_table);
5097
5098   mp->sw_if_index = ntohl (sw_if_index);
5099   mp->is_ipv6 = is_ipv6;
5100   mp->vrf_id = ntohl (vrf_id);
5101
5102   /* send it... */
5103   S;
5104
5105   /* Wait for a reply... */
5106   W;
5107 }
5108
5109 static void vl_api_sw_interface_get_table_reply_t_handler
5110   (vl_api_sw_interface_get_table_reply_t * mp)
5111 {
5112   vat_main_t *vam = &vat_main;
5113
5114   fformat (vam->ofp, "%d\n", ntohl (mp->vrf_id));
5115
5116   vam->retval = ntohl (mp->retval);
5117   vam->result_ready = 1;
5118
5119 }
5120
5121 static void vl_api_sw_interface_get_table_reply_t_handler_json
5122   (vl_api_sw_interface_get_table_reply_t * mp)
5123 {
5124   vat_main_t *vam = &vat_main;
5125   vat_json_node_t node;
5126
5127   vat_json_init_object (&node);
5128   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
5129   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
5130
5131   vat_json_print (vam->ofp, &node);
5132   vat_json_free (&node);
5133
5134   vam->retval = ntohl (mp->retval);
5135   vam->result_ready = 1;
5136 }
5137
5138 static int
5139 api_sw_interface_get_table (vat_main_t * vam)
5140 {
5141   unformat_input_t *i = vam->input;
5142   vl_api_sw_interface_get_table_t *mp;
5143   u32 sw_if_index;
5144   u8 sw_if_index_set = 0;
5145   u8 is_ipv6 = 0;
5146   f64 timeout;
5147
5148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5149     {
5150       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5151         sw_if_index_set = 1;
5152       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5153         sw_if_index_set = 1;
5154       else if (unformat (i, "ipv6"))
5155         is_ipv6 = 1;
5156       else
5157         break;
5158     }
5159
5160   if (sw_if_index_set == 0)
5161     {
5162       errmsg ("missing interface name or sw_if_index\n");
5163       return -99;
5164     }
5165
5166   M (SW_INTERFACE_GET_TABLE, sw_interface_get_table);
5167   mp->sw_if_index = htonl (sw_if_index);
5168   mp->is_ipv6 = is_ipv6;
5169
5170   S;
5171   W;
5172 }
5173
5174 static int
5175 api_sw_interface_set_vpath (vat_main_t * vam)
5176 {
5177   unformat_input_t *i = vam->input;
5178   vl_api_sw_interface_set_vpath_t *mp;
5179   f64 timeout;
5180   u32 sw_if_index = 0;
5181   u8 sw_if_index_set = 0;
5182   u8 is_enable = 0;
5183
5184   /* Parse args required to build the message */
5185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5186     {
5187       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5188         sw_if_index_set = 1;
5189       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5190         sw_if_index_set = 1;
5191       else if (unformat (i, "enable"))
5192         is_enable = 1;
5193       else if (unformat (i, "disable"))
5194         is_enable = 0;
5195       else
5196         break;
5197     }
5198
5199   if (sw_if_index_set == 0)
5200     {
5201       errmsg ("missing interface name or sw_if_index\n");
5202       return -99;
5203     }
5204
5205   /* Construct the API message */
5206   M (SW_INTERFACE_SET_VPATH, sw_interface_set_vpath);
5207
5208   mp->sw_if_index = ntohl (sw_if_index);
5209   mp->enable = is_enable;
5210
5211   /* send it... */
5212   S;
5213
5214   /* Wait for a reply... */
5215   W;
5216 }
5217
5218 static int
5219 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
5220 {
5221   unformat_input_t *i = vam->input;
5222   vl_api_sw_interface_set_vxlan_bypass_t *mp;
5223   f64 timeout;
5224   u32 sw_if_index = 0;
5225   u8 sw_if_index_set = 0;
5226   u8 is_enable = 0;
5227   u8 is_ipv6 = 0;
5228
5229   /* Parse args required to build the message */
5230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5231     {
5232       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5233         sw_if_index_set = 1;
5234       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5235         sw_if_index_set = 1;
5236       else if (unformat (i, "enable"))
5237         is_enable = 1;
5238       else if (unformat (i, "disable"))
5239         is_enable = 0;
5240       else if (unformat (i, "ip4"))
5241         is_ipv6 = 0;
5242       else if (unformat (i, "ip6"))
5243         is_ipv6 = 1;
5244       else
5245         break;
5246     }
5247
5248   if (sw_if_index_set == 0)
5249     {
5250       errmsg ("missing interface name or sw_if_index\n");
5251       return -99;
5252     }
5253
5254   /* Construct the API message */
5255   M (SW_INTERFACE_SET_VXLAN_BYPASS, sw_interface_set_vxlan_bypass);
5256
5257   mp->sw_if_index = ntohl (sw_if_index);
5258   mp->enable = is_enable;
5259   mp->is_ipv6 = is_ipv6;
5260
5261   /* send it... */
5262   S;
5263
5264   /* Wait for a reply... */
5265   W;
5266 }
5267
5268 static int
5269 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
5270 {
5271   unformat_input_t *i = vam->input;
5272   vl_api_sw_interface_set_l2_xconnect_t *mp;
5273   f64 timeout;
5274   u32 rx_sw_if_index;
5275   u8 rx_sw_if_index_set = 0;
5276   u32 tx_sw_if_index;
5277   u8 tx_sw_if_index_set = 0;
5278   u8 enable = 1;
5279
5280   /* Parse args required to build the message */
5281   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5282     {
5283       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
5284         rx_sw_if_index_set = 1;
5285       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
5286         tx_sw_if_index_set = 1;
5287       else if (unformat (i, "rx"))
5288         {
5289           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5290             {
5291               if (unformat (i, "%U", unformat_sw_if_index, vam,
5292                             &rx_sw_if_index))
5293                 rx_sw_if_index_set = 1;
5294             }
5295           else
5296             break;
5297         }
5298       else if (unformat (i, "tx"))
5299         {
5300           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5301             {
5302               if (unformat (i, "%U", unformat_sw_if_index, vam,
5303                             &tx_sw_if_index))
5304                 tx_sw_if_index_set = 1;
5305             }
5306           else
5307             break;
5308         }
5309       else if (unformat (i, "enable"))
5310         enable = 1;
5311       else if (unformat (i, "disable"))
5312         enable = 0;
5313       else
5314         break;
5315     }
5316
5317   if (rx_sw_if_index_set == 0)
5318     {
5319       errmsg ("missing rx interface name or rx_sw_if_index\n");
5320       return -99;
5321     }
5322
5323   if (enable && (tx_sw_if_index_set == 0))
5324     {
5325       errmsg ("missing tx interface name or tx_sw_if_index\n");
5326       return -99;
5327     }
5328
5329   M (SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect);
5330
5331   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5332   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
5333   mp->enable = enable;
5334
5335   S;
5336   W;
5337   /* NOTREACHED */
5338   return 0;
5339 }
5340
5341 static int
5342 api_sw_interface_set_l2_bridge (vat_main_t * vam)
5343 {
5344   unformat_input_t *i = vam->input;
5345   vl_api_sw_interface_set_l2_bridge_t *mp;
5346   f64 timeout;
5347   u32 rx_sw_if_index;
5348   u8 rx_sw_if_index_set = 0;
5349   u32 bd_id;
5350   u8 bd_id_set = 0;
5351   u8 bvi = 0;
5352   u32 shg = 0;
5353   u8 enable = 1;
5354
5355   /* Parse args required to build the message */
5356   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5357     {
5358       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
5359         rx_sw_if_index_set = 1;
5360       else if (unformat (i, "bd_id %d", &bd_id))
5361         bd_id_set = 1;
5362       else if (unformat (i, "%U", unformat_sw_if_index, vam, &rx_sw_if_index))
5363         rx_sw_if_index_set = 1;
5364       else if (unformat (i, "shg %d", &shg))
5365         ;
5366       else if (unformat (i, "bvi"))
5367         bvi = 1;
5368       else if (unformat (i, "enable"))
5369         enable = 1;
5370       else if (unformat (i, "disable"))
5371         enable = 0;
5372       else
5373         break;
5374     }
5375
5376   if (rx_sw_if_index_set == 0)
5377     {
5378       errmsg ("missing rx interface name or sw_if_index\n");
5379       return -99;
5380     }
5381
5382   if (enable && (bd_id_set == 0))
5383     {
5384       errmsg ("missing bridge domain\n");
5385       return -99;
5386     }
5387
5388   M (SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge);
5389
5390   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
5391   mp->bd_id = ntohl (bd_id);
5392   mp->shg = (u8) shg;
5393   mp->bvi = bvi;
5394   mp->enable = enable;
5395
5396   S;
5397   W;
5398   /* NOTREACHED */
5399   return 0;
5400 }
5401
5402 static int
5403 api_bridge_domain_dump (vat_main_t * vam)
5404 {
5405   unformat_input_t *i = vam->input;
5406   vl_api_bridge_domain_dump_t *mp;
5407   f64 timeout;
5408   u32 bd_id = ~0;
5409
5410   /* Parse args required to build the message */
5411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5412     {
5413       if (unformat (i, "bd_id %d", &bd_id))
5414         ;
5415       else
5416         break;
5417     }
5418
5419   M (BRIDGE_DOMAIN_DUMP, bridge_domain_dump);
5420   mp->bd_id = ntohl (bd_id);
5421   S;
5422
5423   /* Use a control ping for synchronization */
5424   {
5425     vl_api_control_ping_t *mp;
5426     M (CONTROL_PING, control_ping);
5427     S;
5428   }
5429
5430   W;
5431   /* NOTREACHED */
5432   return 0;
5433 }
5434
5435 static int
5436 api_bridge_domain_add_del (vat_main_t * vam)
5437 {
5438   unformat_input_t *i = vam->input;
5439   vl_api_bridge_domain_add_del_t *mp;
5440   f64 timeout;
5441   u32 bd_id = ~0;
5442   u8 is_add = 1;
5443   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
5444
5445   /* Parse args required to build the message */
5446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5447     {
5448       if (unformat (i, "bd_id %d", &bd_id))
5449         ;
5450       else if (unformat (i, "flood %d", &flood))
5451         ;
5452       else if (unformat (i, "uu-flood %d", &uu_flood))
5453         ;
5454       else if (unformat (i, "forward %d", &forward))
5455         ;
5456       else if (unformat (i, "learn %d", &learn))
5457         ;
5458       else if (unformat (i, "arp-term %d", &arp_term))
5459         ;
5460       else if (unformat (i, "del"))
5461         {
5462           is_add = 0;
5463           flood = uu_flood = forward = learn = 0;
5464         }
5465       else
5466         break;
5467     }
5468
5469   if (bd_id == ~0)
5470     {
5471       errmsg ("missing bridge domain\n");
5472       return -99;
5473     }
5474
5475   M (BRIDGE_DOMAIN_ADD_DEL, bridge_domain_add_del);
5476
5477   mp->bd_id = ntohl (bd_id);
5478   mp->flood = flood;
5479   mp->uu_flood = uu_flood;
5480   mp->forward = forward;
5481   mp->learn = learn;
5482   mp->arp_term = arp_term;
5483   mp->is_add = is_add;
5484
5485   S;
5486   W;
5487   /* NOTREACHED */
5488   return 0;
5489 }
5490
5491 static int
5492 api_l2fib_add_del (vat_main_t * vam)
5493 {
5494   unformat_input_t *i = vam->input;
5495   vl_api_l2fib_add_del_t *mp;
5496   f64 timeout;
5497   u64 mac = 0;
5498   u8 mac_set = 0;
5499   u32 bd_id;
5500   u8 bd_id_set = 0;
5501   u32 sw_if_index = ~0;
5502   u8 sw_if_index_set = 0;
5503   u8 is_add = 1;
5504   u8 static_mac = 0;
5505   u8 filter_mac = 0;
5506   u8 bvi_mac = 0;
5507   int count = 1;
5508   f64 before = 0;
5509   int j;
5510
5511   /* Parse args required to build the message */
5512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5513     {
5514       if (unformat (i, "mac %U", unformat_ethernet_address, &mac))
5515         mac_set = 1;
5516       else if (unformat (i, "bd_id %d", &bd_id))
5517         bd_id_set = 1;
5518       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5519         sw_if_index_set = 1;
5520       else if (unformat (i, "sw_if"))
5521         {
5522           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5523             {
5524               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5525                 sw_if_index_set = 1;
5526             }
5527           else
5528             break;
5529         }
5530       else if (unformat (i, "static"))
5531         static_mac = 1;
5532       else if (unformat (i, "filter"))
5533         {
5534           filter_mac = 1;
5535           static_mac = 1;
5536         }
5537       else if (unformat (i, "bvi"))
5538         {
5539           bvi_mac = 1;
5540           static_mac = 1;
5541         }
5542       else if (unformat (i, "del"))
5543         is_add = 0;
5544       else if (unformat (i, "count %d", &count))
5545         ;
5546       else
5547         break;
5548     }
5549
5550   if (mac_set == 0)
5551     {
5552       errmsg ("missing mac address\n");
5553       return -99;
5554     }
5555
5556   if (bd_id_set == 0)
5557     {
5558       errmsg ("missing bridge domain\n");
5559       return -99;
5560     }
5561
5562   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
5563     {
5564       errmsg ("missing interface name or sw_if_index\n");
5565       return -99;
5566     }
5567
5568   if (count > 1)
5569     {
5570       /* Turn on async mode */
5571       vam->async_mode = 1;
5572       vam->async_errors = 0;
5573       before = vat_time_now (vam);
5574     }
5575
5576   for (j = 0; j < count; j++)
5577     {
5578       M (L2FIB_ADD_DEL, l2fib_add_del);
5579
5580       mp->mac = mac;
5581       mp->bd_id = ntohl (bd_id);
5582       mp->is_add = is_add;
5583
5584       if (is_add)
5585         {
5586           mp->sw_if_index = ntohl (sw_if_index);
5587           mp->static_mac = static_mac;
5588           mp->filter_mac = filter_mac;
5589           mp->bvi_mac = bvi_mac;
5590         }
5591       increment_mac_address (&mac);
5592       /* send it... */
5593       S;
5594     }
5595
5596   if (count > 1)
5597     {
5598       vl_api_control_ping_t *mp;
5599       f64 after;
5600
5601       /* Shut off async mode */
5602       vam->async_mode = 0;
5603
5604       M (CONTROL_PING, control_ping);
5605       S;
5606
5607       timeout = vat_time_now (vam) + 1.0;
5608       while (vat_time_now (vam) < timeout)
5609         if (vam->result_ready == 1)
5610           goto out;
5611       vam->retval = -99;
5612
5613     out:
5614       if (vam->retval == -99)
5615         errmsg ("timeout\n");
5616
5617       if (vam->async_errors > 0)
5618         {
5619           errmsg ("%d asynchronous errors\n", vam->async_errors);
5620           vam->retval = -98;
5621         }
5622       vam->async_errors = 0;
5623       after = vat_time_now (vam);
5624
5625       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
5626                count, after - before, count / (after - before));
5627     }
5628   else
5629     {
5630       /* Wait for a reply... */
5631       W;
5632     }
5633   /* Return the good/bad news */
5634   return (vam->retval);
5635 }
5636
5637 static int
5638 api_l2_flags (vat_main_t * vam)
5639 {
5640   unformat_input_t *i = vam->input;
5641   vl_api_l2_flags_t *mp;
5642   f64 timeout;
5643   u32 sw_if_index;
5644   u32 feature_bitmap = 0;
5645   u8 sw_if_index_set = 0;
5646
5647   /* Parse args required to build the message */
5648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5649     {
5650       if (unformat (i, "sw_if_index %d", &sw_if_index))
5651         sw_if_index_set = 1;
5652       else if (unformat (i, "sw_if"))
5653         {
5654           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5655             {
5656               if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5657                 sw_if_index_set = 1;
5658             }
5659           else
5660             break;
5661         }
5662       else if (unformat (i, "learn"))
5663         feature_bitmap |= L2INPUT_FEAT_LEARN;
5664       else if (unformat (i, "forward"))
5665         feature_bitmap |= L2INPUT_FEAT_FWD;
5666       else if (unformat (i, "flood"))
5667         feature_bitmap |= L2INPUT_FEAT_FLOOD;
5668       else if (unformat (i, "uu-flood"))
5669         feature_bitmap |= L2INPUT_FEAT_UU_FLOOD;
5670       else
5671         break;
5672     }
5673
5674   if (sw_if_index_set == 0)
5675     {
5676       errmsg ("missing interface name or sw_if_index\n");
5677       return -99;
5678     }
5679
5680   M (L2_FLAGS, l2_flags);
5681
5682   mp->sw_if_index = ntohl (sw_if_index);
5683   mp->feature_bitmap = ntohl (feature_bitmap);
5684
5685   S;
5686   W;
5687   /* NOTREACHED */
5688   return 0;
5689 }
5690
5691 static int
5692 api_bridge_flags (vat_main_t * vam)
5693 {
5694   unformat_input_t *i = vam->input;
5695   vl_api_bridge_flags_t *mp;
5696   f64 timeout;
5697   u32 bd_id;
5698   u8 bd_id_set = 0;
5699   u8 is_set = 1;
5700   u32 flags = 0;
5701
5702   /* Parse args required to build the message */
5703   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5704     {
5705       if (unformat (i, "bd_id %d", &bd_id))
5706         bd_id_set = 1;
5707       else if (unformat (i, "learn"))
5708         flags |= L2_LEARN;
5709       else if (unformat (i, "forward"))
5710         flags |= L2_FWD;
5711       else if (unformat (i, "flood"))
5712         flags |= L2_FLOOD;
5713       else if (unformat (i, "uu-flood"))
5714         flags |= L2_UU_FLOOD;
5715       else if (unformat (i, "arp-term"))
5716         flags |= L2_ARP_TERM;
5717       else if (unformat (i, "off"))
5718         is_set = 0;
5719       else if (unformat (i, "disable"))
5720         is_set = 0;
5721       else
5722         break;
5723     }
5724
5725   if (bd_id_set == 0)
5726     {
5727       errmsg ("missing bridge domain\n");
5728       return -99;
5729     }
5730
5731   M (BRIDGE_FLAGS, bridge_flags);
5732
5733   mp->bd_id = ntohl (bd_id);
5734   mp->feature_bitmap = ntohl (flags);
5735   mp->is_set = is_set;
5736
5737   S;
5738   W;
5739   /* NOTREACHED */
5740   return 0;
5741 }
5742
5743 static int
5744 api_bd_ip_mac_add_del (vat_main_t * vam)
5745 {
5746   unformat_input_t *i = vam->input;
5747   vl_api_bd_ip_mac_add_del_t *mp;
5748   f64 timeout;
5749   u32 bd_id;
5750   u8 is_ipv6 = 0;
5751   u8 is_add = 1;
5752   u8 bd_id_set = 0;
5753   u8 ip_set = 0;
5754   u8 mac_set = 0;
5755   ip4_address_t v4addr;
5756   ip6_address_t v6addr;
5757   u8 macaddr[6];
5758
5759
5760   /* Parse args required to build the message */
5761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5762     {
5763       if (unformat (i, "bd_id %d", &bd_id))
5764         {
5765           bd_id_set++;
5766         }
5767       else if (unformat (i, "%U", unformat_ip4_address, &v4addr))
5768         {
5769           ip_set++;
5770         }
5771       else if (unformat (i, "%U", unformat_ip6_address, &v6addr))
5772         {
5773           ip_set++;
5774           is_ipv6++;
5775         }
5776       else if (unformat (i, "%U", unformat_ethernet_address, macaddr))
5777         {
5778           mac_set++;
5779         }
5780       else if (unformat (i, "del"))
5781         is_add = 0;
5782       else
5783         break;
5784     }
5785
5786   if (bd_id_set == 0)
5787     {
5788       errmsg ("missing bridge domain\n");
5789       return -99;
5790     }
5791   else if (ip_set == 0)
5792     {
5793       errmsg ("missing IP address\n");
5794       return -99;
5795     }
5796   else if (mac_set == 0)
5797     {
5798       errmsg ("missing MAC address\n");
5799       return -99;
5800     }
5801
5802   M (BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del);
5803
5804   mp->bd_id = ntohl (bd_id);
5805   mp->is_ipv6 = is_ipv6;
5806   mp->is_add = is_add;
5807   if (is_ipv6)
5808     clib_memcpy (mp->ip_address, &v6addr, sizeof (v6addr));
5809   else
5810     clib_memcpy (mp->ip_address, &v4addr, sizeof (v4addr));
5811   clib_memcpy (mp->mac_address, macaddr, 6);
5812   S;
5813   W;
5814   /* NOTREACHED */
5815   return 0;
5816 }
5817
5818 static int
5819 api_tap_connect (vat_main_t * vam)
5820 {
5821   unformat_input_t *i = vam->input;
5822   vl_api_tap_connect_t *mp;
5823   f64 timeout;
5824   u8 mac_address[6];
5825   u8 random_mac = 1;
5826   u8 name_set = 0;
5827   u8 *tap_name;
5828   u8 *tag = 0;
5829
5830   memset (mac_address, 0, sizeof (mac_address));
5831
5832   /* Parse args required to build the message */
5833   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5834     {
5835       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5836         {
5837           random_mac = 0;
5838         }
5839       else if (unformat (i, "random-mac"))
5840         random_mac = 1;
5841       else if (unformat (i, "tapname %s", &tap_name))
5842         name_set = 1;
5843       else if (unformat (i, "tag %s", &tag))
5844         ;
5845       else
5846         break;
5847     }
5848
5849   if (name_set == 0)
5850     {
5851       errmsg ("missing tap name\n");
5852       return -99;
5853     }
5854   if (vec_len (tap_name) > 63)
5855     {
5856       errmsg ("tap name too long\n");
5857       return -99;
5858     }
5859   vec_add1 (tap_name, 0);
5860
5861   if (vec_len (tag) > 63)
5862     {
5863       errmsg ("tag too long\n");
5864       return -99;
5865     }
5866
5867   /* Construct the API message */
5868   M (TAP_CONNECT, tap_connect);
5869
5870   mp->use_random_mac = random_mac;
5871   clib_memcpy (mp->mac_address, mac_address, 6);
5872   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5873   if (tag)
5874     clib_memcpy (mp->tag, tag, vec_len (tag));
5875
5876   vec_free (tap_name);
5877   vec_free (tag);
5878
5879   /* send it... */
5880   S;
5881
5882   /* Wait for a reply... */
5883   W;
5884 }
5885
5886 static int
5887 api_tap_modify (vat_main_t * vam)
5888 {
5889   unformat_input_t *i = vam->input;
5890   vl_api_tap_modify_t *mp;
5891   f64 timeout;
5892   u8 mac_address[6];
5893   u8 random_mac = 1;
5894   u8 name_set = 0;
5895   u8 *tap_name;
5896   u32 sw_if_index = ~0;
5897   u8 sw_if_index_set = 0;
5898
5899   memset (mac_address, 0, sizeof (mac_address));
5900
5901   /* Parse args required to build the message */
5902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5903     {
5904       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5905         sw_if_index_set = 1;
5906       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5907         sw_if_index_set = 1;
5908       else if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5909         {
5910           random_mac = 0;
5911         }
5912       else if (unformat (i, "random-mac"))
5913         random_mac = 1;
5914       else if (unformat (i, "tapname %s", &tap_name))
5915         name_set = 1;
5916       else
5917         break;
5918     }
5919
5920   if (sw_if_index_set == 0)
5921     {
5922       errmsg ("missing vpp interface name");
5923       return -99;
5924     }
5925   if (name_set == 0)
5926     {
5927       errmsg ("missing tap name\n");
5928       return -99;
5929     }
5930   if (vec_len (tap_name) > 63)
5931     {
5932       errmsg ("tap name too long\n");
5933     }
5934   vec_add1 (tap_name, 0);
5935
5936   /* Construct the API message */
5937   M (TAP_MODIFY, tap_modify);
5938
5939   mp->use_random_mac = random_mac;
5940   mp->sw_if_index = ntohl (sw_if_index);
5941   clib_memcpy (mp->mac_address, mac_address, 6);
5942   clib_memcpy (mp->tap_name, tap_name, vec_len (tap_name));
5943   vec_free (tap_name);
5944
5945   /* send it... */
5946   S;
5947
5948   /* Wait for a reply... */
5949   W;
5950 }
5951
5952 static int
5953 api_tap_delete (vat_main_t * vam)
5954 {
5955   unformat_input_t *i = vam->input;
5956   vl_api_tap_delete_t *mp;
5957   f64 timeout;
5958   u32 sw_if_index = ~0;
5959   u8 sw_if_index_set = 0;
5960
5961   /* Parse args required to build the message */
5962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5963     {
5964       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
5965         sw_if_index_set = 1;
5966       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5967         sw_if_index_set = 1;
5968       else
5969         break;
5970     }
5971
5972   if (sw_if_index_set == 0)
5973     {
5974       errmsg ("missing vpp interface name");
5975       return -99;
5976     }
5977
5978   /* Construct the API message */
5979   M (TAP_DELETE, tap_delete);
5980
5981   mp->sw_if_index = ntohl (sw_if_index);
5982
5983   /* send it... */
5984   S;
5985
5986   /* Wait for a reply... */
5987   W;
5988 }
5989
5990 static int
5991 api_ip_add_del_route (vat_main_t * vam)
5992 {
5993   unformat_input_t *i = vam->input;
5994   vl_api_ip_add_del_route_t *mp;
5995   f64 timeout;
5996   u32 sw_if_index = ~0, vrf_id = 0;
5997   u8 is_ipv6 = 0;
5998   u8 is_local = 0, is_drop = 0;
5999   u8 is_unreach = 0, is_prohibit = 0;
6000   u8 create_vrf_if_needed = 0;
6001   u8 is_add = 1;
6002   u32 next_hop_weight = 1;
6003   u8 not_last = 0;
6004   u8 is_multipath = 0;
6005   u8 address_set = 0;
6006   u8 address_length_set = 0;
6007   u32 next_hop_table_id = 0;
6008   u32 resolve_attempts = 0;
6009   u32 dst_address_length = 0;
6010   u8 next_hop_set = 0;
6011   ip4_address_t v4_dst_address, v4_next_hop_address;
6012   ip6_address_t v6_dst_address, v6_next_hop_address;
6013   int count = 1;
6014   int j;
6015   f64 before = 0;
6016   u32 random_add_del = 0;
6017   u32 *random_vector = 0;
6018   uword *random_hash;
6019   u32 random_seed = 0xdeaddabe;
6020   u32 classify_table_index = ~0;
6021   u8 is_classify = 0;
6022   u8 resolve_host = 0, resolve_attached = 0;
6023   mpls_label_t *next_hop_out_label_stack = NULL;
6024   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6025   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6026
6027   /* Parse args required to build the message */
6028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6029     {
6030       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6031         ;
6032       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6033         ;
6034       else if (unformat (i, "%U", unformat_ip4_address, &v4_dst_address))
6035         {
6036           address_set = 1;
6037           is_ipv6 = 0;
6038         }
6039       else if (unformat (i, "%U", unformat_ip6_address, &v6_dst_address))
6040         {
6041           address_set = 1;
6042           is_ipv6 = 1;
6043         }
6044       else if (unformat (i, "/%d", &dst_address_length))
6045         {
6046           address_length_set = 1;
6047         }
6048
6049       else if (is_ipv6 == 0 && unformat (i, "via %U", unformat_ip4_address,
6050                                          &v4_next_hop_address))
6051         {
6052           next_hop_set = 1;
6053         }
6054       else if (is_ipv6 == 1 && unformat (i, "via %U", unformat_ip6_address,
6055                                          &v6_next_hop_address))
6056         {
6057           next_hop_set = 1;
6058         }
6059       else if (unformat (i, "resolve-attempts %d", &resolve_attempts))
6060         ;
6061       else if (unformat (i, "weight %d", &next_hop_weight))
6062         ;
6063       else if (unformat (i, "drop"))
6064         {
6065           is_drop = 1;
6066         }
6067       else if (unformat (i, "null-send-unreach"))
6068         {
6069           is_unreach = 1;
6070         }
6071       else if (unformat (i, "null-send-prohibit"))
6072         {
6073           is_prohibit = 1;
6074         }
6075       else if (unformat (i, "local"))
6076         {
6077           is_local = 1;
6078         }
6079       else if (unformat (i, "classify %d", &classify_table_index))
6080         {
6081           is_classify = 1;
6082         }
6083       else if (unformat (i, "del"))
6084         is_add = 0;
6085       else if (unformat (i, "add"))
6086         is_add = 1;
6087       else if (unformat (i, "not-last"))
6088         not_last = 1;
6089       else if (unformat (i, "resolve-via-host"))
6090         resolve_host = 1;
6091       else if (unformat (i, "resolve-via-attached"))
6092         resolve_attached = 1;
6093       else if (unformat (i, "multipath"))
6094         is_multipath = 1;
6095       else if (unformat (i, "vrf %d", &vrf_id))
6096         ;
6097       else if (unformat (i, "create-vrf"))
6098         create_vrf_if_needed = 1;
6099       else if (unformat (i, "count %d", &count))
6100         ;
6101       else if (unformat (i, "lookup-in-vrf %d", &next_hop_table_id))
6102         ;
6103       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6104         ;
6105       else if (unformat (i, "out-label %d", &next_hop_out_label))
6106         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6107       else if (unformat (i, "via-label %d", &next_hop_via_label))
6108         ;
6109       else if (unformat (i, "random"))
6110         random_add_del = 1;
6111       else if (unformat (i, "seed %d", &random_seed))
6112         ;
6113       else
6114         {
6115           clib_warning ("parse error '%U'", format_unformat_error, i);
6116           return -99;
6117         }
6118     }
6119
6120   if (!next_hop_set && !is_drop && !is_local &&
6121       !is_classify && !is_unreach && !is_prohibit &&
6122       MPLS_LABEL_INVALID == next_hop_via_label)
6123     {
6124       errmsg
6125         ("next hop / local / drop / unreach / prohibit / classify not set\n");
6126       return -99;
6127     }
6128
6129   if (next_hop_set && MPLS_LABEL_INVALID != next_hop_via_label)
6130     {
6131       errmsg ("next hop and next-hop via label set\n");
6132       return -99;
6133     }
6134   if (address_set == 0)
6135     {
6136       errmsg ("missing addresses\n");
6137       return -99;
6138     }
6139
6140   if (address_length_set == 0)
6141     {
6142       errmsg ("missing address length\n");
6143       return -99;
6144     }
6145
6146   /* Generate a pile of unique, random routes */
6147   if (random_add_del)
6148     {
6149       u32 this_random_address;
6150       random_hash = hash_create (count, sizeof (uword));
6151
6152       hash_set (random_hash, v4_next_hop_address.as_u32, 1);
6153       for (j = 0; j <= count; j++)
6154         {
6155           do
6156             {
6157               this_random_address = random_u32 (&random_seed);
6158               this_random_address =
6159                 clib_host_to_net_u32 (this_random_address);
6160             }
6161           while (hash_get (random_hash, this_random_address));
6162           vec_add1 (random_vector, this_random_address);
6163           hash_set (random_hash, this_random_address, 1);
6164         }
6165       hash_free (random_hash);
6166       v4_dst_address.as_u32 = random_vector[0];
6167     }
6168
6169   if (count > 1)
6170     {
6171       /* Turn on async mode */
6172       vam->async_mode = 1;
6173       vam->async_errors = 0;
6174       before = vat_time_now (vam);
6175     }
6176
6177   for (j = 0; j < count; j++)
6178     {
6179       /* Construct the API message */
6180       M2 (IP_ADD_DEL_ROUTE, ip_add_del_route,
6181           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6182
6183       mp->next_hop_sw_if_index = ntohl (sw_if_index);
6184       mp->table_id = ntohl (vrf_id);
6185       mp->create_vrf_if_needed = create_vrf_if_needed;
6186
6187       mp->is_add = is_add;
6188       mp->is_drop = is_drop;
6189       mp->is_unreach = is_unreach;
6190       mp->is_prohibit = is_prohibit;
6191       mp->is_ipv6 = is_ipv6;
6192       mp->is_local = is_local;
6193       mp->is_classify = is_classify;
6194       mp->is_multipath = is_multipath;
6195       mp->is_resolve_host = resolve_host;
6196       mp->is_resolve_attached = resolve_attached;
6197       mp->not_last = not_last;
6198       mp->next_hop_weight = next_hop_weight;
6199       mp->dst_address_length = dst_address_length;
6200       mp->next_hop_table_id = ntohl (next_hop_table_id);
6201       mp->classify_table_index = ntohl (classify_table_index);
6202       mp->next_hop_via_label = ntohl (next_hop_via_label);
6203       mp->next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6204       if (0 != mp->next_hop_n_out_labels)
6205         {
6206           memcpy (mp->next_hop_out_label_stack,
6207                   next_hop_out_label_stack,
6208                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6209           vec_free (next_hop_out_label_stack);
6210         }
6211
6212       if (is_ipv6)
6213         {
6214           clib_memcpy (mp->dst_address, &v6_dst_address,
6215                        sizeof (v6_dst_address));
6216           if (next_hop_set)
6217             clib_memcpy (mp->next_hop_address, &v6_next_hop_address,
6218                          sizeof (v6_next_hop_address));
6219           increment_v6_address (&v6_dst_address);
6220         }
6221       else
6222         {
6223           clib_memcpy (mp->dst_address, &v4_dst_address,
6224                        sizeof (v4_dst_address));
6225           if (next_hop_set)
6226             clib_memcpy (mp->next_hop_address, &v4_next_hop_address,
6227                          sizeof (v4_next_hop_address));
6228           if (random_add_del)
6229             v4_dst_address.as_u32 = random_vector[j + 1];
6230           else
6231             increment_v4_address (&v4_dst_address);
6232         }
6233       /* send it... */
6234       S;
6235       /* If we receive SIGTERM, stop now... */
6236       if (vam->do_exit)
6237         break;
6238     }
6239
6240   /* When testing multiple add/del ops, use a control-ping to sync */
6241   if (count > 1)
6242     {
6243       vl_api_control_ping_t *mp;
6244       f64 after;
6245
6246       /* Shut off async mode */
6247       vam->async_mode = 0;
6248
6249       M (CONTROL_PING, control_ping);
6250       S;
6251
6252       timeout = vat_time_now (vam) + 1.0;
6253       while (vat_time_now (vam) < timeout)
6254         if (vam->result_ready == 1)
6255           goto out;
6256       vam->retval = -99;
6257
6258     out:
6259       if (vam->retval == -99)
6260         errmsg ("timeout\n");
6261
6262       if (vam->async_errors > 0)
6263         {
6264           errmsg ("%d asynchronous errors\n", vam->async_errors);
6265           vam->retval = -98;
6266         }
6267       vam->async_errors = 0;
6268       after = vat_time_now (vam);
6269
6270       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6271       if (j > 0)
6272         count = j;
6273
6274       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6275                count, after - before, count / (after - before));
6276     }
6277   else
6278     {
6279       /* Wait for a reply... */
6280       W;
6281     }
6282
6283   /* Return the good/bad news */
6284   return (vam->retval);
6285 }
6286
6287 static int
6288 api_mpls_route_add_del (vat_main_t * vam)
6289 {
6290   unformat_input_t *i = vam->input;
6291   vl_api_mpls_route_add_del_t *mp;
6292   f64 timeout;
6293   u32 sw_if_index = ~0, table_id = 0;
6294   u8 create_table_if_needed = 0;
6295   u8 is_add = 1;
6296   u32 next_hop_weight = 1;
6297   u8 is_multipath = 0;
6298   u32 next_hop_table_id = 0;
6299   u8 next_hop_set = 0;
6300   ip4_address_t v4_next_hop_address = {
6301     .as_u32 = 0,
6302   };
6303   ip6_address_t v6_next_hop_address = { {0} };
6304   int count = 1;
6305   int j;
6306   f64 before = 0;
6307   u32 classify_table_index = ~0;
6308   u8 is_classify = 0;
6309   u8 resolve_host = 0, resolve_attached = 0;
6310   mpls_label_t next_hop_via_label = MPLS_LABEL_INVALID;
6311   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6312   mpls_label_t *next_hop_out_label_stack = NULL;
6313   mpls_label_t local_label = MPLS_LABEL_INVALID;
6314   u8 is_eos = 0;
6315   u8 next_hop_proto_is_ip4 = 1;
6316
6317   /* Parse args required to build the message */
6318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6319     {
6320       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6321         ;
6322       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6323         ;
6324       else if (unformat (i, "%d", &local_label))
6325         ;
6326       else if (unformat (i, "eos"))
6327         is_eos = 1;
6328       else if (unformat (i, "non-eos"))
6329         is_eos = 0;
6330       else if (unformat (i, "via %U", unformat_ip4_address,
6331                          &v4_next_hop_address))
6332         {
6333           next_hop_set = 1;
6334           next_hop_proto_is_ip4 = 1;
6335         }
6336       else if (unformat (i, "via %U", unformat_ip6_address,
6337                          &v6_next_hop_address))
6338         {
6339           next_hop_set = 1;
6340           next_hop_proto_is_ip4 = 0;
6341         }
6342       else if (unformat (i, "weight %d", &next_hop_weight))
6343         ;
6344       else if (unformat (i, "create-table"))
6345         create_table_if_needed = 1;
6346       else if (unformat (i, "classify %d", &classify_table_index))
6347         {
6348           is_classify = 1;
6349         }
6350       else if (unformat (i, "del"))
6351         is_add = 0;
6352       else if (unformat (i, "add"))
6353         is_add = 1;
6354       else if (unformat (i, "resolve-via-host"))
6355         resolve_host = 1;
6356       else if (unformat (i, "resolve-via-attached"))
6357         resolve_attached = 1;
6358       else if (unformat (i, "multipath"))
6359         is_multipath = 1;
6360       else if (unformat (i, "count %d", &count))
6361         ;
6362       else if (unformat (i, "lookup-in-ip4-table %d", &next_hop_table_id))
6363         {
6364           next_hop_set = 1;
6365           next_hop_proto_is_ip4 = 1;
6366         }
6367       else if (unformat (i, "lookup-in-ip6-table %d", &next_hop_table_id))
6368         {
6369           next_hop_set = 1;
6370           next_hop_proto_is_ip4 = 0;
6371         }
6372       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6373         ;
6374       else if (unformat (i, "via-label %d", &next_hop_via_label))
6375         ;
6376       else if (unformat (i, "out-label %d", &next_hop_out_label))
6377         vec_add1 (next_hop_out_label_stack, ntohl (next_hop_out_label));
6378       else
6379         {
6380           clib_warning ("parse error '%U'", format_unformat_error, i);
6381           return -99;
6382         }
6383     }
6384
6385   if (!next_hop_set && !is_classify)
6386     {
6387       errmsg ("next hop / classify not set\n");
6388       return -99;
6389     }
6390
6391   if (MPLS_LABEL_INVALID == local_label)
6392     {
6393       errmsg ("missing label\n");
6394       return -99;
6395     }
6396
6397   if (count > 1)
6398     {
6399       /* Turn on async mode */
6400       vam->async_mode = 1;
6401       vam->async_errors = 0;
6402       before = vat_time_now (vam);
6403     }
6404
6405   for (j = 0; j < count; j++)
6406     {
6407       /* Construct the API message */
6408       M2 (MPLS_ROUTE_ADD_DEL, mpls_route_add_del,
6409           sizeof (mpls_label_t) * vec_len (next_hop_out_label_stack));
6410
6411       mp->mr_next_hop_sw_if_index = ntohl (sw_if_index);
6412       mp->mr_table_id = ntohl (table_id);
6413       mp->mr_create_table_if_needed = create_table_if_needed;
6414
6415       mp->mr_is_add = is_add;
6416       mp->mr_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6417       mp->mr_is_classify = is_classify;
6418       mp->mr_is_multipath = is_multipath;
6419       mp->mr_is_resolve_host = resolve_host;
6420       mp->mr_is_resolve_attached = resolve_attached;
6421       mp->mr_next_hop_weight = next_hop_weight;
6422       mp->mr_next_hop_table_id = ntohl (next_hop_table_id);
6423       mp->mr_classify_table_index = ntohl (classify_table_index);
6424       mp->mr_next_hop_via_label = ntohl (next_hop_via_label);
6425       mp->mr_label = ntohl (local_label);
6426       mp->mr_eos = is_eos;
6427
6428       mp->mr_next_hop_n_out_labels = vec_len (next_hop_out_label_stack);
6429       if (0 != mp->mr_next_hop_n_out_labels)
6430         {
6431           memcpy (mp->mr_next_hop_out_label_stack,
6432                   next_hop_out_label_stack,
6433                   vec_len (next_hop_out_label_stack) * sizeof (mpls_label_t));
6434           vec_free (next_hop_out_label_stack);
6435         }
6436
6437       if (next_hop_set)
6438         {
6439           if (next_hop_proto_is_ip4)
6440             {
6441               clib_memcpy (mp->mr_next_hop,
6442                            &v4_next_hop_address,
6443                            sizeof (v4_next_hop_address));
6444             }
6445           else
6446             {
6447               clib_memcpy (mp->mr_next_hop,
6448                            &v6_next_hop_address,
6449                            sizeof (v6_next_hop_address));
6450             }
6451         }
6452       local_label++;
6453
6454       /* send it... */
6455       S;
6456       /* If we receive SIGTERM, stop now... */
6457       if (vam->do_exit)
6458         break;
6459     }
6460
6461   /* When testing multiple add/del ops, use a control-ping to sync */
6462   if (count > 1)
6463     {
6464       vl_api_control_ping_t *mp;
6465       f64 after;
6466
6467       /* Shut off async mode */
6468       vam->async_mode = 0;
6469
6470       M (CONTROL_PING, control_ping);
6471       S;
6472
6473       timeout = vat_time_now (vam) + 1.0;
6474       while (vat_time_now (vam) < timeout)
6475         if (vam->result_ready == 1)
6476           goto out;
6477       vam->retval = -99;
6478
6479     out:
6480       if (vam->retval == -99)
6481         errmsg ("timeout\n");
6482
6483       if (vam->async_errors > 0)
6484         {
6485           errmsg ("%d asynchronous errors\n", vam->async_errors);
6486           vam->retval = -98;
6487         }
6488       vam->async_errors = 0;
6489       after = vat_time_now (vam);
6490
6491       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6492       if (j > 0)
6493         count = j;
6494
6495       fformat (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec\n",
6496                count, after - before, count / (after - before));
6497     }
6498   else
6499     {
6500       /* Wait for a reply... */
6501       W;
6502     }
6503
6504   /* Return the good/bad news */
6505   return (vam->retval);
6506 }
6507
6508 static int
6509 api_mpls_ip_bind_unbind (vat_main_t * vam)
6510 {
6511   unformat_input_t *i = vam->input;
6512   vl_api_mpls_ip_bind_unbind_t *mp;
6513   f64 timeout;
6514   u32 ip_table_id = 0;
6515   u8 create_table_if_needed = 0;
6516   u8 is_bind = 1;
6517   u8 is_ip4 = 1;
6518   ip4_address_t v4_address;
6519   ip6_address_t v6_address;
6520   u32 address_length;
6521   u8 address_set = 0;
6522   mpls_label_t local_label = MPLS_LABEL_INVALID;
6523
6524   /* Parse args required to build the message */
6525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6526     {
6527       if (unformat (i, "%U/%d", unformat_ip4_address,
6528                     &v4_address, &address_length))
6529         {
6530           is_ip4 = 1;
6531           address_set = 1;
6532         }
6533       else if (unformat (i, "%U/%d", unformat_ip6_address,
6534                          &v6_address, &address_length))
6535         {
6536           is_ip4 = 0;
6537           address_set = 1;
6538         }
6539       else if (unformat (i, "%d", &local_label))
6540         ;
6541       else if (unformat (i, "create-table"))
6542         create_table_if_needed = 1;
6543       else if (unformat (i, "table-id %d", &ip_table_id))
6544         ;
6545       else if (unformat (i, "unbind"))
6546         is_bind = 0;
6547       else if (unformat (i, "bind"))
6548         is_bind = 1;
6549       else
6550         {
6551           clib_warning ("parse error '%U'", format_unformat_error, i);
6552           return -99;
6553         }
6554     }
6555
6556   if (!address_set)
6557     {
6558       errmsg ("IP addres not set\n");
6559       return -99;
6560     }
6561
6562   if (MPLS_LABEL_INVALID == local_label)
6563     {
6564       errmsg ("missing label\n");
6565       return -99;
6566     }
6567
6568   /* Construct the API message */
6569   M (MPLS_IP_BIND_UNBIND, mpls_ip_bind_unbind);
6570
6571   mp->mb_create_table_if_needed = create_table_if_needed;
6572   mp->mb_is_bind = is_bind;
6573   mp->mb_is_ip4 = is_ip4;
6574   mp->mb_ip_table_id = ntohl (ip_table_id);
6575   mp->mb_mpls_table_id = 0;
6576   mp->mb_label = ntohl (local_label);
6577   mp->mb_address_length = address_length;
6578
6579   if (is_ip4)
6580     clib_memcpy (mp->mb_address, &v4_address, sizeof (v4_address));
6581   else
6582     clib_memcpy (mp->mb_address, &v6_address, sizeof (v6_address));
6583
6584   /* send it... */
6585   S;
6586
6587   /* Wait for a reply... */
6588   W;
6589 }
6590
6591 static int
6592 api_proxy_arp_add_del (vat_main_t * vam)
6593 {
6594   unformat_input_t *i = vam->input;
6595   vl_api_proxy_arp_add_del_t *mp;
6596   f64 timeout;
6597   u32 vrf_id = 0;
6598   u8 is_add = 1;
6599   ip4_address_t lo, hi;
6600   u8 range_set = 0;
6601
6602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6603     {
6604       if (unformat (i, "vrf %d", &vrf_id))
6605         ;
6606       else if (unformat (i, "%U - %U", unformat_ip4_address, &lo,
6607                          unformat_ip4_address, &hi))
6608         range_set = 1;
6609       else if (unformat (i, "del"))
6610         is_add = 0;
6611       else
6612         {
6613           clib_warning ("parse error '%U'", format_unformat_error, i);
6614           return -99;
6615         }
6616     }
6617
6618   if (range_set == 0)
6619     {
6620       errmsg ("address range not set\n");
6621       return -99;
6622     }
6623
6624   M (PROXY_ARP_ADD_DEL, proxy_arp_add_del);
6625
6626   mp->vrf_id = ntohl (vrf_id);
6627   mp->is_add = is_add;
6628   clib_memcpy (mp->low_address, &lo, sizeof (mp->low_address));
6629   clib_memcpy (mp->hi_address, &hi, sizeof (mp->hi_address));
6630
6631   S;
6632   W;
6633   /* NOTREACHED */
6634   return 0;
6635 }
6636
6637 static int
6638 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
6639 {
6640   unformat_input_t *i = vam->input;
6641   vl_api_proxy_arp_intfc_enable_disable_t *mp;
6642   f64 timeout;
6643   u32 sw_if_index;
6644   u8 enable = 1;
6645   u8 sw_if_index_set = 0;
6646
6647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6648     {
6649       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6650         sw_if_index_set = 1;
6651       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6652         sw_if_index_set = 1;
6653       else if (unformat (i, "enable"))
6654         enable = 1;
6655       else if (unformat (i, "disable"))
6656         enable = 0;
6657       else
6658         {
6659           clib_warning ("parse error '%U'", format_unformat_error, i);
6660           return -99;
6661         }
6662     }
6663
6664   if (sw_if_index_set == 0)
6665     {
6666       errmsg ("missing interface name or sw_if_index\n");
6667       return -99;
6668     }
6669
6670   M (PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable);
6671
6672   mp->sw_if_index = ntohl (sw_if_index);
6673   mp->enable_disable = enable;
6674
6675   S;
6676   W;
6677   /* NOTREACHED */
6678   return 0;
6679 }
6680
6681 static int
6682 api_mpls_tunnel_add_del (vat_main_t * vam)
6683 {
6684   unformat_input_t *i = vam->input;
6685   vl_api_mpls_tunnel_add_del_t *mp;
6686   f64 timeout;
6687
6688   u8 is_add = 1;
6689   u8 l2_only = 0;
6690   u32 sw_if_index = ~0;
6691   u32 next_hop_sw_if_index = ~0;
6692   u32 next_hop_proto_is_ip4 = 1;
6693
6694   u32 next_hop_table_id = 0;
6695   ip4_address_t v4_next_hop_address = {
6696     .as_u32 = 0,
6697   };
6698   ip6_address_t v6_next_hop_address = { {0} };
6699   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID, *labels = NULL;
6700
6701   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6702     {
6703       if (unformat (i, "add"))
6704         is_add = 1;
6705       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6706         is_add = 0;
6707       else if (unformat (i, "sw_if_index %d", &next_hop_sw_if_index))
6708         ;
6709       else if (unformat (i, "via %U",
6710                          unformat_ip4_address, &v4_next_hop_address))
6711         {
6712           next_hop_proto_is_ip4 = 1;
6713         }
6714       else if (unformat (i, "via %U",
6715                          unformat_ip6_address, &v6_next_hop_address))
6716         {
6717           next_hop_proto_is_ip4 = 0;
6718         }
6719       else if (unformat (i, "l2-only"))
6720         l2_only = 1;
6721       else if (unformat (i, "next-hop-table %d", &next_hop_table_id))
6722         ;
6723       else if (unformat (i, "out-label %d", &next_hop_out_label))
6724         vec_add1 (labels, ntohl (next_hop_out_label));
6725       else
6726         {
6727           clib_warning ("parse error '%U'", format_unformat_error, i);
6728           return -99;
6729         }
6730     }
6731
6732   M2 (MPLS_TUNNEL_ADD_DEL, mpls_tunnel_add_del,
6733       sizeof (mpls_label_t) * vec_len (labels));
6734
6735   mp->mt_next_hop_sw_if_index = ntohl (next_hop_sw_if_index);
6736   mp->mt_sw_if_index = ntohl (sw_if_index);
6737   mp->mt_is_add = is_add;
6738   mp->mt_l2_only = l2_only;
6739   mp->mt_next_hop_table_id = ntohl (next_hop_table_id);
6740   mp->mt_next_hop_proto_is_ip4 = next_hop_proto_is_ip4;
6741
6742   mp->mt_next_hop_n_out_labels = vec_len (labels);
6743
6744   if (0 != mp->mt_next_hop_n_out_labels)
6745     {
6746       clib_memcpy (mp->mt_next_hop_out_label_stack, labels,
6747                    sizeof (mpls_label_t) * mp->mt_next_hop_n_out_labels);
6748       vec_free (labels);
6749     }
6750
6751   if (next_hop_proto_is_ip4)
6752     {
6753       clib_memcpy (mp->mt_next_hop,
6754                    &v4_next_hop_address, sizeof (v4_next_hop_address));
6755     }
6756   else
6757     {
6758       clib_memcpy (mp->mt_next_hop,
6759                    &v6_next_hop_address, sizeof (v6_next_hop_address));
6760     }
6761
6762   S;
6763   W;
6764   /* NOTREACHED */
6765   return 0;
6766 }
6767
6768 static int
6769 api_sw_interface_set_unnumbered (vat_main_t * vam)
6770 {
6771   unformat_input_t *i = vam->input;
6772   vl_api_sw_interface_set_unnumbered_t *mp;
6773   f64 timeout;
6774   u32 sw_if_index;
6775   u32 unnum_sw_index = ~0;
6776   u8 is_add = 1;
6777   u8 sw_if_index_set = 0;
6778
6779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6780     {
6781       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6782         sw_if_index_set = 1;
6783       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6784         sw_if_index_set = 1;
6785       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6786         ;
6787       else if (unformat (i, "del"))
6788         is_add = 0;
6789       else
6790         {
6791           clib_warning ("parse error '%U'", format_unformat_error, i);
6792           return -99;
6793         }
6794     }
6795
6796   if (sw_if_index_set == 0)
6797     {
6798       errmsg ("missing interface name or sw_if_index\n");
6799       return -99;
6800     }
6801
6802   M (SW_INTERFACE_SET_UNNUMBERED, sw_interface_set_unnumbered);
6803
6804   mp->sw_if_index = ntohl (sw_if_index);
6805   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6806   mp->is_add = is_add;
6807
6808   S;
6809   W;
6810   /* NOTREACHED */
6811   return 0;
6812 }
6813
6814 static int
6815 api_ip_neighbor_add_del (vat_main_t * vam)
6816 {
6817   unformat_input_t *i = vam->input;
6818   vl_api_ip_neighbor_add_del_t *mp;
6819   f64 timeout;
6820   u32 sw_if_index;
6821   u8 sw_if_index_set = 0;
6822   u32 vrf_id = 0;
6823   u8 is_add = 1;
6824   u8 is_static = 0;
6825   u8 mac_address[6];
6826   u8 mac_set = 0;
6827   u8 v4_address_set = 0;
6828   u8 v6_address_set = 0;
6829   ip4_address_t v4address;
6830   ip6_address_t v6address;
6831
6832   memset (mac_address, 0, sizeof (mac_address));
6833
6834   /* Parse args required to build the message */
6835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6836     {
6837       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
6838         {
6839           mac_set = 1;
6840         }
6841       else if (unformat (i, "del"))
6842         is_add = 0;
6843       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6844         sw_if_index_set = 1;
6845       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6846         sw_if_index_set = 1;
6847       else if (unformat (i, "is_static"))
6848         is_static = 1;
6849       else if (unformat (i, "vrf %d", &vrf_id))
6850         ;
6851       else if (unformat (i, "dst %U", unformat_ip4_address, &v4address))
6852         v4_address_set = 1;
6853       else if (unformat (i, "dst %U", unformat_ip6_address, &v6address))
6854         v6_address_set = 1;
6855       else
6856         {
6857           clib_warning ("parse error '%U'", format_unformat_error, i);
6858           return -99;
6859         }
6860     }
6861
6862   if (sw_if_index_set == 0)
6863     {
6864       errmsg ("missing interface name or sw_if_index\n");
6865       return -99;
6866     }
6867   if (v4_address_set && v6_address_set)
6868     {
6869       errmsg ("both v4 and v6 addresses set\n");
6870       return -99;
6871     }
6872   if (!v4_address_set && !v6_address_set)
6873     {
6874       errmsg ("no address set\n");
6875       return -99;
6876     }
6877
6878   /* Construct the API message */
6879   M (IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del);
6880
6881   mp->sw_if_index = ntohl (sw_if_index);
6882   mp->is_add = is_add;
6883   mp->vrf_id = ntohl (vrf_id);
6884   mp->is_static = is_static;
6885   if (mac_set)
6886     clib_memcpy (mp->mac_address, mac_address, 6);
6887   if (v6_address_set)
6888     {
6889       mp->is_ipv6 = 1;
6890       clib_memcpy (mp->dst_address, &v6address, sizeof (v6address));
6891     }
6892   else
6893     {
6894       /* mp->is_ipv6 = 0; via memset in M macro above */
6895       clib_memcpy (mp->dst_address, &v4address, sizeof (v4address));
6896     }
6897
6898   /* send it... */
6899   S;
6900
6901   /* Wait for a reply, return good/bad news  */
6902   W;
6903
6904   /* NOTREACHED */
6905   return 0;
6906 }
6907
6908 static int
6909 api_reset_vrf (vat_main_t * vam)
6910 {
6911   unformat_input_t *i = vam->input;
6912   vl_api_reset_vrf_t *mp;
6913   f64 timeout;
6914   u32 vrf_id = 0;
6915   u8 is_ipv6 = 0;
6916   u8 vrf_id_set = 0;
6917
6918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6919     {
6920       if (unformat (i, "vrf %d", &vrf_id))
6921         vrf_id_set = 1;
6922       else if (unformat (i, "ipv6"))
6923         is_ipv6 = 1;
6924       else
6925         {
6926           clib_warning ("parse error '%U'", format_unformat_error, i);
6927           return -99;
6928         }
6929     }
6930
6931   if (vrf_id_set == 0)
6932     {
6933       errmsg ("missing vrf id\n");
6934       return -99;
6935     }
6936
6937   M (RESET_VRF, reset_vrf);
6938
6939   mp->vrf_id = ntohl (vrf_id);
6940   mp->is_ipv6 = is_ipv6;
6941
6942   S;
6943   W;
6944   /* NOTREACHED */
6945   return 0;
6946 }
6947
6948 static int
6949 api_create_vlan_subif (vat_main_t * vam)
6950 {
6951   unformat_input_t *i = vam->input;
6952   vl_api_create_vlan_subif_t *mp;
6953   f64 timeout;
6954   u32 sw_if_index;
6955   u8 sw_if_index_set = 0;
6956   u32 vlan_id;
6957   u8 vlan_id_set = 0;
6958
6959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6960     {
6961       if (unformat (i, "sw_if_index %d", &sw_if_index))
6962         sw_if_index_set = 1;
6963       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
6964         sw_if_index_set = 1;
6965       else if (unformat (i, "vlan %d", &vlan_id))
6966         vlan_id_set = 1;
6967       else
6968         {
6969           clib_warning ("parse error '%U'", format_unformat_error, i);
6970           return -99;
6971         }
6972     }
6973
6974   if (sw_if_index_set == 0)
6975     {
6976       errmsg ("missing interface name or sw_if_index\n");
6977       return -99;
6978     }
6979
6980   if (vlan_id_set == 0)
6981     {
6982       errmsg ("missing vlan_id\n");
6983       return -99;
6984     }
6985   M (CREATE_VLAN_SUBIF, create_vlan_subif);
6986
6987   mp->sw_if_index = ntohl (sw_if_index);
6988   mp->vlan_id = ntohl (vlan_id);
6989
6990   S;
6991   W;
6992   /* NOTREACHED */
6993   return 0;
6994 }
6995
6996 #define foreach_create_subif_bit                \
6997 _(no_tags)                                      \
6998 _(one_tag)                                      \
6999 _(two_tags)                                     \
7000 _(dot1ad)                                       \
7001 _(exact_match)                                  \
7002 _(default_sub)                                  \
7003 _(outer_vlan_id_any)                            \
7004 _(inner_vlan_id_any)
7005
7006 static int
7007 api_create_subif (vat_main_t * vam)
7008 {
7009   unformat_input_t *i = vam->input;
7010   vl_api_create_subif_t *mp;
7011   f64 timeout;
7012   u32 sw_if_index;
7013   u8 sw_if_index_set = 0;
7014   u32 sub_id;
7015   u8 sub_id_set = 0;
7016   u32 no_tags = 0;
7017   u32 one_tag = 0;
7018   u32 two_tags = 0;
7019   u32 dot1ad = 0;
7020   u32 exact_match = 0;
7021   u32 default_sub = 0;
7022   u32 outer_vlan_id_any = 0;
7023   u32 inner_vlan_id_any = 0;
7024   u32 tmp;
7025   u16 outer_vlan_id = 0;
7026   u16 inner_vlan_id = 0;
7027
7028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7029     {
7030       if (unformat (i, "sw_if_index %d", &sw_if_index))
7031         sw_if_index_set = 1;
7032       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7033         sw_if_index_set = 1;
7034       else if (unformat (i, "sub_id %d", &sub_id))
7035         sub_id_set = 1;
7036       else if (unformat (i, "outer_vlan_id %d", &tmp))
7037         outer_vlan_id = tmp;
7038       else if (unformat (i, "inner_vlan_id %d", &tmp))
7039         inner_vlan_id = tmp;
7040
7041 #define _(a) else if (unformat (i, #a)) a = 1 ;
7042       foreach_create_subif_bit
7043 #undef _
7044         else
7045         {
7046           clib_warning ("parse error '%U'", format_unformat_error, i);
7047           return -99;
7048         }
7049     }
7050
7051   if (sw_if_index_set == 0)
7052     {
7053       errmsg ("missing interface name or sw_if_index\n");
7054       return -99;
7055     }
7056
7057   if (sub_id_set == 0)
7058     {
7059       errmsg ("missing sub_id\n");
7060       return -99;
7061     }
7062   M (CREATE_SUBIF, create_subif);
7063
7064   mp->sw_if_index = ntohl (sw_if_index);
7065   mp->sub_id = ntohl (sub_id);
7066
7067 #define _(a) mp->a = a;
7068   foreach_create_subif_bit;
7069 #undef _
7070
7071   mp->outer_vlan_id = ntohs (outer_vlan_id);
7072   mp->inner_vlan_id = ntohs (inner_vlan_id);
7073
7074   S;
7075   W;
7076   /* NOTREACHED */
7077   return 0;
7078 }
7079
7080 static int
7081 api_oam_add_del (vat_main_t * vam)
7082 {
7083   unformat_input_t *i = vam->input;
7084   vl_api_oam_add_del_t *mp;
7085   f64 timeout;
7086   u32 vrf_id = 0;
7087   u8 is_add = 1;
7088   ip4_address_t src, dst;
7089   u8 src_set = 0;
7090   u8 dst_set = 0;
7091
7092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7093     {
7094       if (unformat (i, "vrf %d", &vrf_id))
7095         ;
7096       else if (unformat (i, "src %U", unformat_ip4_address, &src))
7097         src_set = 1;
7098       else if (unformat (i, "dst %U", unformat_ip4_address, &dst))
7099         dst_set = 1;
7100       else if (unformat (i, "del"))
7101         is_add = 0;
7102       else
7103         {
7104           clib_warning ("parse error '%U'", format_unformat_error, i);
7105           return -99;
7106         }
7107     }
7108
7109   if (src_set == 0)
7110     {
7111       errmsg ("missing src addr\n");
7112       return -99;
7113     }
7114
7115   if (dst_set == 0)
7116     {
7117       errmsg ("missing dst addr\n");
7118       return -99;
7119     }
7120
7121   M (OAM_ADD_DEL, oam_add_del);
7122
7123   mp->vrf_id = ntohl (vrf_id);
7124   mp->is_add = is_add;
7125   clib_memcpy (mp->src_address, &src, sizeof (mp->src_address));
7126   clib_memcpy (mp->dst_address, &dst, sizeof (mp->dst_address));
7127
7128   S;
7129   W;
7130   /* NOTREACHED */
7131   return 0;
7132 }
7133
7134 static int
7135 api_reset_fib (vat_main_t * vam)
7136 {
7137   unformat_input_t *i = vam->input;
7138   vl_api_reset_fib_t *mp;
7139   f64 timeout;
7140   u32 vrf_id = 0;
7141   u8 is_ipv6 = 0;
7142   u8 vrf_id_set = 0;
7143
7144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7145     {
7146       if (unformat (i, "vrf %d", &vrf_id))
7147         vrf_id_set = 1;
7148       else if (unformat (i, "ipv6"))
7149         is_ipv6 = 1;
7150       else
7151         {
7152           clib_warning ("parse error '%U'", format_unformat_error, i);
7153           return -99;
7154         }
7155     }
7156
7157   if (vrf_id_set == 0)
7158     {
7159       errmsg ("missing vrf id\n");
7160       return -99;
7161     }
7162
7163   M (RESET_FIB, reset_fib);
7164
7165   mp->vrf_id = ntohl (vrf_id);
7166   mp->is_ipv6 = is_ipv6;
7167
7168   S;
7169   W;
7170   /* NOTREACHED */
7171   return 0;
7172 }
7173
7174 static int
7175 api_dhcp_proxy_config (vat_main_t * vam)
7176 {
7177   unformat_input_t *i = vam->input;
7178   vl_api_dhcp_proxy_config_t *mp;
7179   f64 timeout;
7180   u32 vrf_id = 0;
7181   u8 is_add = 1;
7182   u8 insert_cid = 1;
7183   u8 v4_address_set = 0;
7184   u8 v6_address_set = 0;
7185   ip4_address_t v4address;
7186   ip6_address_t v6address;
7187   u8 v4_src_address_set = 0;
7188   u8 v6_src_address_set = 0;
7189   ip4_address_t v4srcaddress;
7190   ip6_address_t v6srcaddress;
7191
7192   /* Parse args required to build the message */
7193   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7194     {
7195       if (unformat (i, "del"))
7196         is_add = 0;
7197       else if (unformat (i, "vrf %d", &vrf_id))
7198         ;
7199       else if (unformat (i, "insert-cid %d", &insert_cid))
7200         ;
7201       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7202         v4_address_set = 1;
7203       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7204         v6_address_set = 1;
7205       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7206         v4_src_address_set = 1;
7207       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7208         v6_src_address_set = 1;
7209       else
7210         break;
7211     }
7212
7213   if (v4_address_set && v6_address_set)
7214     {
7215       errmsg ("both v4 and v6 server addresses set\n");
7216       return -99;
7217     }
7218   if (!v4_address_set && !v6_address_set)
7219     {
7220       errmsg ("no server addresses set\n");
7221       return -99;
7222     }
7223
7224   if (v4_src_address_set && v6_src_address_set)
7225     {
7226       errmsg ("both v4 and v6  src addresses set\n");
7227       return -99;
7228     }
7229   if (!v4_src_address_set && !v6_src_address_set)
7230     {
7231       errmsg ("no src addresses set\n");
7232       return -99;
7233     }
7234
7235   if (!(v4_src_address_set && v4_address_set) &&
7236       !(v6_src_address_set && v6_address_set))
7237     {
7238       errmsg ("no matching server and src addresses set\n");
7239       return -99;
7240     }
7241
7242   /* Construct the API message */
7243   M (DHCP_PROXY_CONFIG, dhcp_proxy_config);
7244
7245   mp->insert_circuit_id = insert_cid;
7246   mp->is_add = is_add;
7247   mp->vrf_id = ntohl (vrf_id);
7248   if (v6_address_set)
7249     {
7250       mp->is_ipv6 = 1;
7251       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7252       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7253     }
7254   else
7255     {
7256       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7257       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7258     }
7259
7260   /* send it... */
7261   S;
7262
7263   /* Wait for a reply, return good/bad news  */
7264   W;
7265   /* NOTREACHED */
7266   return 0;
7267 }
7268
7269 static int
7270 api_dhcp_proxy_config_2 (vat_main_t * vam)
7271 {
7272   unformat_input_t *i = vam->input;
7273   vl_api_dhcp_proxy_config_2_t *mp;
7274   f64 timeout;
7275   u32 rx_vrf_id = 0;
7276   u32 server_vrf_id = 0;
7277   u8 is_add = 1;
7278   u8 insert_cid = 1;
7279   u8 v4_address_set = 0;
7280   u8 v6_address_set = 0;
7281   ip4_address_t v4address;
7282   ip6_address_t v6address;
7283   u8 v4_src_address_set = 0;
7284   u8 v6_src_address_set = 0;
7285   ip4_address_t v4srcaddress;
7286   ip6_address_t v6srcaddress;
7287
7288   /* Parse args required to build the message */
7289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7290     {
7291       if (unformat (i, "del"))
7292         is_add = 0;
7293       else if (unformat (i, "rx_vrf_id %d", &rx_vrf_id))
7294         ;
7295       else if (unformat (i, "server_vrf_id %d", &server_vrf_id))
7296         ;
7297       else if (unformat (i, "insert-cid %d", &insert_cid))
7298         ;
7299       else if (unformat (i, "svr %U", unformat_ip4_address, &v4address))
7300         v4_address_set = 1;
7301       else if (unformat (i, "svr %U", unformat_ip6_address, &v6address))
7302         v6_address_set = 1;
7303       else if (unformat (i, "src %U", unformat_ip4_address, &v4srcaddress))
7304         v4_src_address_set = 1;
7305       else if (unformat (i, "src %U", unformat_ip6_address, &v6srcaddress))
7306         v6_src_address_set = 1;
7307       else
7308         break;
7309     }
7310
7311   if (v4_address_set && v6_address_set)
7312     {
7313       errmsg ("both v4 and v6 server addresses set\n");
7314       return -99;
7315     }
7316   if (!v4_address_set && !v6_address_set)
7317     {
7318       errmsg ("no server addresses set\n");
7319       return -99;
7320     }
7321
7322   if (v4_src_address_set && v6_src_address_set)
7323     {
7324       errmsg ("both v4 and v6  src addresses set\n");
7325       return -99;
7326     }
7327   if (!v4_src_address_set && !v6_src_address_set)
7328     {
7329       errmsg ("no src addresses set\n");
7330       return -99;
7331     }
7332
7333   if (!(v4_src_address_set && v4_address_set) &&
7334       !(v6_src_address_set && v6_address_set))
7335     {
7336       errmsg ("no matching server and src addresses set\n");
7337       return -99;
7338     }
7339
7340   /* Construct the API message */
7341   M (DHCP_PROXY_CONFIG_2, dhcp_proxy_config_2);
7342
7343   mp->insert_circuit_id = insert_cid;
7344   mp->is_add = is_add;
7345   mp->rx_vrf_id = ntohl (rx_vrf_id);
7346   mp->server_vrf_id = ntohl (server_vrf_id);
7347   if (v6_address_set)
7348     {
7349       mp->is_ipv6 = 1;
7350       clib_memcpy (mp->dhcp_server, &v6address, sizeof (v6address));
7351       clib_memcpy (mp->dhcp_src_address, &v6srcaddress, sizeof (v6address));
7352     }
7353   else
7354     {
7355       clib_memcpy (mp->dhcp_server, &v4address, sizeof (v4address));
7356       clib_memcpy (mp->dhcp_src_address, &v4srcaddress, sizeof (v4address));
7357     }
7358
7359   /* send it... */
7360   S;
7361
7362   /* Wait for a reply, return good/bad news  */
7363   W;
7364   /* NOTREACHED */
7365   return 0;
7366 }
7367
7368 static int
7369 api_dhcp_proxy_set_vss (vat_main_t * vam)
7370 {
7371   unformat_input_t *i = vam->input;
7372   vl_api_dhcp_proxy_set_vss_t *mp;
7373   f64 timeout;
7374   u8 is_ipv6 = 0;
7375   u8 is_add = 1;
7376   u32 tbl_id;
7377   u8 tbl_id_set = 0;
7378   u32 oui;
7379   u8 oui_set = 0;
7380   u32 fib_id;
7381   u8 fib_id_set = 0;
7382
7383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7384     {
7385       if (unformat (i, "tbl_id %d", &tbl_id))
7386         tbl_id_set = 1;
7387       if (unformat (i, "fib_id %d", &fib_id))
7388         fib_id_set = 1;
7389       if (unformat (i, "oui %d", &oui))
7390         oui_set = 1;
7391       else if (unformat (i, "ipv6"))
7392         is_ipv6 = 1;
7393       else if (unformat (i, "del"))
7394         is_add = 0;
7395       else
7396         {
7397           clib_warning ("parse error '%U'", format_unformat_error, i);
7398           return -99;
7399         }
7400     }
7401
7402   if (tbl_id_set == 0)
7403     {
7404       errmsg ("missing tbl id\n");
7405       return -99;
7406     }
7407
7408   if (fib_id_set == 0)
7409     {
7410       errmsg ("missing fib id\n");
7411       return -99;
7412     }
7413   if (oui_set == 0)
7414     {
7415       errmsg ("missing oui\n");
7416       return -99;
7417     }
7418
7419   M (DHCP_PROXY_SET_VSS, dhcp_proxy_set_vss);
7420   mp->tbl_id = ntohl (tbl_id);
7421   mp->fib_id = ntohl (fib_id);
7422   mp->oui = ntohl (oui);
7423   mp->is_ipv6 = is_ipv6;
7424   mp->is_add = is_add;
7425
7426   S;
7427   W;
7428   /* NOTREACHED */
7429   return 0;
7430 }
7431
7432 static int
7433 api_dhcp_client_config (vat_main_t * vam)
7434 {
7435   unformat_input_t *i = vam->input;
7436   vl_api_dhcp_client_config_t *mp;
7437   f64 timeout;
7438   u32 sw_if_index;
7439   u8 sw_if_index_set = 0;
7440   u8 is_add = 1;
7441   u8 *hostname = 0;
7442   u8 disable_event = 0;
7443
7444   /* Parse args required to build the message */
7445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7446     {
7447       if (unformat (i, "del"))
7448         is_add = 0;
7449       else 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, "hostname %s", &hostname))
7454         ;
7455       else if (unformat (i, "disable_event"))
7456         disable_event = 1;
7457       else
7458         break;
7459     }
7460
7461   if (sw_if_index_set == 0)
7462     {
7463       errmsg ("missing interface name or sw_if_index\n");
7464       return -99;
7465     }
7466
7467   if (vec_len (hostname) > 63)
7468     {
7469       errmsg ("hostname too long\n");
7470     }
7471   vec_add1 (hostname, 0);
7472
7473   /* Construct the API message */
7474   M (DHCP_CLIENT_CONFIG, dhcp_client_config);
7475
7476   mp->sw_if_index = ntohl (sw_if_index);
7477   clib_memcpy (mp->hostname, hostname, vec_len (hostname));
7478   vec_free (hostname);
7479   mp->is_add = is_add;
7480   mp->want_dhcp_event = disable_event ? 0 : 1;
7481   mp->pid = getpid ();
7482
7483   /* send it... */
7484   S;
7485
7486   /* Wait for a reply, return good/bad news  */
7487   W;
7488   /* NOTREACHED */
7489   return 0;
7490 }
7491
7492 static int
7493 api_set_ip_flow_hash (vat_main_t * vam)
7494 {
7495   unformat_input_t *i = vam->input;
7496   vl_api_set_ip_flow_hash_t *mp;
7497   f64 timeout;
7498   u32 vrf_id = 0;
7499   u8 is_ipv6 = 0;
7500   u8 vrf_id_set = 0;
7501   u8 src = 0;
7502   u8 dst = 0;
7503   u8 sport = 0;
7504   u8 dport = 0;
7505   u8 proto = 0;
7506   u8 reverse = 0;
7507
7508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7509     {
7510       if (unformat (i, "vrf %d", &vrf_id))
7511         vrf_id_set = 1;
7512       else if (unformat (i, "ipv6"))
7513         is_ipv6 = 1;
7514       else if (unformat (i, "src"))
7515         src = 1;
7516       else if (unformat (i, "dst"))
7517         dst = 1;
7518       else if (unformat (i, "sport"))
7519         sport = 1;
7520       else if (unformat (i, "dport"))
7521         dport = 1;
7522       else if (unformat (i, "proto"))
7523         proto = 1;
7524       else if (unformat (i, "reverse"))
7525         reverse = 1;
7526
7527       else
7528         {
7529           clib_warning ("parse error '%U'", format_unformat_error, i);
7530           return -99;
7531         }
7532     }
7533
7534   if (vrf_id_set == 0)
7535     {
7536       errmsg ("missing vrf id\n");
7537       return -99;
7538     }
7539
7540   M (SET_IP_FLOW_HASH, set_ip_flow_hash);
7541   mp->src = src;
7542   mp->dst = dst;
7543   mp->sport = sport;
7544   mp->dport = dport;
7545   mp->proto = proto;
7546   mp->reverse = reverse;
7547   mp->vrf_id = ntohl (vrf_id);
7548   mp->is_ipv6 = is_ipv6;
7549
7550   S;
7551   W;
7552   /* NOTREACHED */
7553   return 0;
7554 }
7555
7556 static int
7557 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7558 {
7559   unformat_input_t *i = vam->input;
7560   vl_api_sw_interface_ip6_enable_disable_t *mp;
7561   f64 timeout;
7562   u32 sw_if_index;
7563   u8 sw_if_index_set = 0;
7564   u8 enable = 0;
7565
7566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7567     {
7568       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7569         sw_if_index_set = 1;
7570       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7571         sw_if_index_set = 1;
7572       else if (unformat (i, "enable"))
7573         enable = 1;
7574       else if (unformat (i, "disable"))
7575         enable = 0;
7576       else
7577         {
7578           clib_warning ("parse error '%U'", format_unformat_error, i);
7579           return -99;
7580         }
7581     }
7582
7583   if (sw_if_index_set == 0)
7584     {
7585       errmsg ("missing interface name or sw_if_index\n");
7586       return -99;
7587     }
7588
7589   M (SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable);
7590
7591   mp->sw_if_index = ntohl (sw_if_index);
7592   mp->enable = enable;
7593
7594   S;
7595   W;
7596   /* NOTREACHED */
7597   return 0;
7598 }
7599
7600 static int
7601 api_sw_interface_ip6_set_link_local_address (vat_main_t * vam)
7602 {
7603   unformat_input_t *i = vam->input;
7604   vl_api_sw_interface_ip6_set_link_local_address_t *mp;
7605   f64 timeout;
7606   u32 sw_if_index;
7607   u8 sw_if_index_set = 0;
7608   u32 address_length = 0;
7609   u8 v6_address_set = 0;
7610   ip6_address_t v6address;
7611
7612   /* Parse args required to build the message */
7613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7614     {
7615       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7616         sw_if_index_set = 1;
7617       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7618         sw_if_index_set = 1;
7619       else if (unformat (i, "%U/%d",
7620                          unformat_ip6_address, &v6address, &address_length))
7621         v6_address_set = 1;
7622       else
7623         break;
7624     }
7625
7626   if (sw_if_index_set == 0)
7627     {
7628       errmsg ("missing interface name or sw_if_index\n");
7629       return -99;
7630     }
7631   if (!v6_address_set)
7632     {
7633       errmsg ("no address set\n");
7634       return -99;
7635     }
7636
7637   /* Construct the API message */
7638   M (SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS,
7639      sw_interface_ip6_set_link_local_address);
7640
7641   mp->sw_if_index = ntohl (sw_if_index);
7642   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7643   mp->address_length = address_length;
7644
7645   /* send it... */
7646   S;
7647
7648   /* Wait for a reply, return good/bad news  */
7649   W;
7650
7651   /* NOTREACHED */
7652   return 0;
7653 }
7654
7655
7656 static int
7657 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
7658 {
7659   unformat_input_t *i = vam->input;
7660   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
7661   f64 timeout;
7662   u32 sw_if_index;
7663   u8 sw_if_index_set = 0;
7664   u32 address_length = 0;
7665   u8 v6_address_set = 0;
7666   ip6_address_t v6address;
7667   u8 use_default = 0;
7668   u8 no_advertise = 0;
7669   u8 off_link = 0;
7670   u8 no_autoconfig = 0;
7671   u8 no_onlink = 0;
7672   u8 is_no = 0;
7673   u32 val_lifetime = 0;
7674   u32 pref_lifetime = 0;
7675
7676   /* Parse args required to build the message */
7677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7678     {
7679       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7680         sw_if_index_set = 1;
7681       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7682         sw_if_index_set = 1;
7683       else if (unformat (i, "%U/%d",
7684                          unformat_ip6_address, &v6address, &address_length))
7685         v6_address_set = 1;
7686       else if (unformat (i, "val_life %d", &val_lifetime))
7687         ;
7688       else if (unformat (i, "pref_life %d", &pref_lifetime))
7689         ;
7690       else if (unformat (i, "def"))
7691         use_default = 1;
7692       else if (unformat (i, "noadv"))
7693         no_advertise = 1;
7694       else if (unformat (i, "offl"))
7695         off_link = 1;
7696       else if (unformat (i, "noauto"))
7697         no_autoconfig = 1;
7698       else if (unformat (i, "nolink"))
7699         no_onlink = 1;
7700       else if (unformat (i, "isno"))
7701         is_no = 1;
7702       else
7703         {
7704           clib_warning ("parse error '%U'", format_unformat_error, i);
7705           return -99;
7706         }
7707     }
7708
7709   if (sw_if_index_set == 0)
7710     {
7711       errmsg ("missing interface name or sw_if_index\n");
7712       return -99;
7713     }
7714   if (!v6_address_set)
7715     {
7716       errmsg ("no address set\n");
7717       return -99;
7718     }
7719
7720   /* Construct the API message */
7721   M (SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix);
7722
7723   mp->sw_if_index = ntohl (sw_if_index);
7724   clib_memcpy (mp->address, &v6address, sizeof (v6address));
7725   mp->address_length = address_length;
7726   mp->use_default = use_default;
7727   mp->no_advertise = no_advertise;
7728   mp->off_link = off_link;
7729   mp->no_autoconfig = no_autoconfig;
7730   mp->no_onlink = no_onlink;
7731   mp->is_no = is_no;
7732   mp->val_lifetime = ntohl (val_lifetime);
7733   mp->pref_lifetime = ntohl (pref_lifetime);
7734
7735   /* send it... */
7736   S;
7737
7738   /* Wait for a reply, return good/bad news  */
7739   W;
7740
7741   /* NOTREACHED */
7742   return 0;
7743 }
7744
7745 static int
7746 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
7747 {
7748   unformat_input_t *i = vam->input;
7749   vl_api_sw_interface_ip6nd_ra_config_t *mp;
7750   f64 timeout;
7751   u32 sw_if_index;
7752   u8 sw_if_index_set = 0;
7753   u8 suppress = 0;
7754   u8 managed = 0;
7755   u8 other = 0;
7756   u8 ll_option = 0;
7757   u8 send_unicast = 0;
7758   u8 cease = 0;
7759   u8 is_no = 0;
7760   u8 default_router = 0;
7761   u32 max_interval = 0;
7762   u32 min_interval = 0;
7763   u32 lifetime = 0;
7764   u32 initial_count = 0;
7765   u32 initial_interval = 0;
7766
7767
7768   /* Parse args required to build the message */
7769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7770     {
7771       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
7772         sw_if_index_set = 1;
7773       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7774         sw_if_index_set = 1;
7775       else if (unformat (i, "maxint %d", &max_interval))
7776         ;
7777       else if (unformat (i, "minint %d", &min_interval))
7778         ;
7779       else if (unformat (i, "life %d", &lifetime))
7780         ;
7781       else if (unformat (i, "count %d", &initial_count))
7782         ;
7783       else if (unformat (i, "interval %d", &initial_interval))
7784         ;
7785       else if (unformat (i, "suppress") || unformat (i, "surpress"))
7786         suppress = 1;
7787       else if (unformat (i, "managed"))
7788         managed = 1;
7789       else if (unformat (i, "other"))
7790         other = 1;
7791       else if (unformat (i, "ll"))
7792         ll_option = 1;
7793       else if (unformat (i, "send"))
7794         send_unicast = 1;
7795       else if (unformat (i, "cease"))
7796         cease = 1;
7797       else if (unformat (i, "isno"))
7798         is_no = 1;
7799       else if (unformat (i, "def"))
7800         default_router = 1;
7801       else
7802         {
7803           clib_warning ("parse error '%U'", format_unformat_error, i);
7804           return -99;
7805         }
7806     }
7807
7808   if (sw_if_index_set == 0)
7809     {
7810       errmsg ("missing interface name or sw_if_index\n");
7811       return -99;
7812     }
7813
7814   /* Construct the API message */
7815   M (SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config);
7816
7817   mp->sw_if_index = ntohl (sw_if_index);
7818   mp->max_interval = ntohl (max_interval);
7819   mp->min_interval = ntohl (min_interval);
7820   mp->lifetime = ntohl (lifetime);
7821   mp->initial_count = ntohl (initial_count);
7822   mp->initial_interval = ntohl (initial_interval);
7823   mp->suppress = suppress;
7824   mp->managed = managed;
7825   mp->other = other;
7826   mp->ll_option = ll_option;
7827   mp->send_unicast = send_unicast;
7828   mp->cease = cease;
7829   mp->is_no = is_no;
7830   mp->default_router = default_router;
7831
7832   /* send it... */
7833   S;
7834
7835   /* Wait for a reply, return good/bad news  */
7836   W;
7837
7838   /* NOTREACHED */
7839   return 0;
7840 }
7841
7842 static int
7843 api_set_arp_neighbor_limit (vat_main_t * vam)
7844 {
7845   unformat_input_t *i = vam->input;
7846   vl_api_set_arp_neighbor_limit_t *mp;
7847   f64 timeout;
7848   u32 arp_nbr_limit;
7849   u8 limit_set = 0;
7850   u8 is_ipv6 = 0;
7851
7852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7853     {
7854       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
7855         limit_set = 1;
7856       else if (unformat (i, "ipv6"))
7857         is_ipv6 = 1;
7858       else
7859         {
7860           clib_warning ("parse error '%U'", format_unformat_error, i);
7861           return -99;
7862         }
7863     }
7864
7865   if (limit_set == 0)
7866     {
7867       errmsg ("missing limit value\n");
7868       return -99;
7869     }
7870
7871   M (SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit);
7872
7873   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
7874   mp->is_ipv6 = is_ipv6;
7875
7876   S;
7877   W;
7878   /* NOTREACHED */
7879   return 0;
7880 }
7881
7882 static int
7883 api_l2_patch_add_del (vat_main_t * vam)
7884 {
7885   unformat_input_t *i = vam->input;
7886   vl_api_l2_patch_add_del_t *mp;
7887   f64 timeout;
7888   u32 rx_sw_if_index;
7889   u8 rx_sw_if_index_set = 0;
7890   u32 tx_sw_if_index;
7891   u8 tx_sw_if_index_set = 0;
7892   u8 is_add = 1;
7893
7894   /* Parse args required to build the message */
7895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7896     {
7897       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7898         rx_sw_if_index_set = 1;
7899       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7900         tx_sw_if_index_set = 1;
7901       else if (unformat (i, "rx"))
7902         {
7903           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7904             {
7905               if (unformat (i, "%U", unformat_sw_if_index, vam,
7906                             &rx_sw_if_index))
7907                 rx_sw_if_index_set = 1;
7908             }
7909           else
7910             break;
7911         }
7912       else if (unformat (i, "tx"))
7913         {
7914           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7915             {
7916               if (unformat (i, "%U", unformat_sw_if_index, vam,
7917                             &tx_sw_if_index))
7918                 tx_sw_if_index_set = 1;
7919             }
7920           else
7921             break;
7922         }
7923       else if (unformat (i, "del"))
7924         is_add = 0;
7925       else
7926         break;
7927     }
7928
7929   if (rx_sw_if_index_set == 0)
7930     {
7931       errmsg ("missing rx interface name or rx_sw_if_index\n");
7932       return -99;
7933     }
7934
7935   if (tx_sw_if_index_set == 0)
7936     {
7937       errmsg ("missing tx interface name or tx_sw_if_index\n");
7938       return -99;
7939     }
7940
7941   M (L2_PATCH_ADD_DEL, l2_patch_add_del);
7942
7943   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7944   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7945   mp->is_add = is_add;
7946
7947   S;
7948   W;
7949   /* NOTREACHED */
7950   return 0;
7951 }
7952
7953 static int
7954 api_ioam_enable (vat_main_t * vam)
7955 {
7956   unformat_input_t *input = vam->input;
7957   vl_api_ioam_enable_t *mp;
7958   f64 timeout;
7959   u32 id = 0;
7960   int has_trace_option = 0;
7961   int has_pot_option = 0;
7962   int has_seqno_option = 0;
7963   int has_analyse_option = 0;
7964
7965   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7966     {
7967       if (unformat (input, "trace"))
7968         has_trace_option = 1;
7969       else if (unformat (input, "pot"))
7970         has_pot_option = 1;
7971       else if (unformat (input, "seqno"))
7972         has_seqno_option = 1;
7973       else if (unformat (input, "analyse"))
7974         has_analyse_option = 1;
7975       else
7976         break;
7977     }
7978   M (IOAM_ENABLE, ioam_enable);
7979   mp->id = htons (id);
7980   mp->seqno = has_seqno_option;
7981   mp->analyse = has_analyse_option;
7982   mp->pot_enable = has_pot_option;
7983   mp->trace_enable = has_trace_option;
7984
7985   S;
7986   W;
7987
7988   return (0);
7989
7990 }
7991
7992
7993 static int
7994 api_ioam_disable (vat_main_t * vam)
7995 {
7996   vl_api_ioam_disable_t *mp;
7997   f64 timeout;
7998
7999   M (IOAM_DISABLE, ioam_disable);
8000   S;
8001   W;
8002   return 0;
8003 }
8004
8005 static int
8006 api_sr_tunnel_add_del (vat_main_t * vam)
8007 {
8008   unformat_input_t *i = vam->input;
8009   vl_api_sr_tunnel_add_del_t *mp;
8010   f64 timeout;
8011   int is_del = 0;
8012   int pl_index;
8013   ip6_address_t src_address;
8014   int src_address_set = 0;
8015   ip6_address_t dst_address;
8016   u32 dst_mask_width;
8017   int dst_address_set = 0;
8018   u16 flags = 0;
8019   u32 rx_table_id = 0;
8020   u32 tx_table_id = 0;
8021   ip6_address_t *segments = 0;
8022   ip6_address_t *this_seg;
8023   ip6_address_t *tags = 0;
8024   ip6_address_t *this_tag;
8025   ip6_address_t next_address, tag;
8026   u8 *name = 0;
8027   u8 *policy_name = 0;
8028
8029   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8030     {
8031       if (unformat (i, "del"))
8032         is_del = 1;
8033       else if (unformat (i, "name %s", &name))
8034         ;
8035       else if (unformat (i, "policy %s", &policy_name))
8036         ;
8037       else if (unformat (i, "rx_fib_id %d", &rx_table_id))
8038         ;
8039       else if (unformat (i, "tx_fib_id %d", &tx_table_id))
8040         ;
8041       else if (unformat (i, "src %U", unformat_ip6_address, &src_address))
8042         src_address_set = 1;
8043       else if (unformat (i, "dst %U/%d",
8044                          unformat_ip6_address, &dst_address, &dst_mask_width))
8045         dst_address_set = 1;
8046       else if (unformat (i, "next %U", unformat_ip6_address, &next_address))
8047         {
8048           vec_add2 (segments, this_seg, 1);
8049           clib_memcpy (this_seg->as_u8, next_address.as_u8,
8050                        sizeof (*this_seg));
8051         }
8052       else if (unformat (i, "tag %U", unformat_ip6_address, &tag))
8053         {
8054           vec_add2 (tags, this_tag, 1);
8055           clib_memcpy (this_tag->as_u8, tag.as_u8, sizeof (*this_tag));
8056         }
8057       else if (unformat (i, "clean"))
8058         flags |= IP6_SR_HEADER_FLAG_CLEANUP;
8059       else if (unformat (i, "protected"))
8060         flags |= IP6_SR_HEADER_FLAG_PROTECTED;
8061       else if (unformat (i, "InPE %d", &pl_index))
8062         {
8063           if (pl_index <= 0 || pl_index > 4)
8064             {
8065             pl_index_range_error:
8066               errmsg ("pl index %d out of range\n", pl_index);
8067               return -99;
8068             }
8069           flags |=
8070             IP6_SR_HEADER_FLAG_PL_ELT_INGRESS_PE << (3 * (pl_index - 1));
8071         }
8072       else if (unformat (i, "EgPE %d", &pl_index))
8073         {
8074           if (pl_index <= 0 || pl_index > 4)
8075             goto pl_index_range_error;
8076           flags |=
8077             IP6_SR_HEADER_FLAG_PL_ELT_EGRESS_PE << (3 * (pl_index - 1));
8078         }
8079       else if (unformat (i, "OrgSrc %d", &pl_index))
8080         {
8081           if (pl_index <= 0 || pl_index > 4)
8082             goto pl_index_range_error;
8083           flags |=
8084             IP6_SR_HEADER_FLAG_PL_ELT_ORIG_SRC_ADDR << (3 * (pl_index - 1));
8085         }
8086       else
8087         break;
8088     }
8089
8090   if (!src_address_set)
8091     {
8092       errmsg ("src address required\n");
8093       return -99;
8094     }
8095
8096   if (!dst_address_set)
8097     {
8098       errmsg ("dst address required\n");
8099       return -99;
8100     }
8101
8102   if (!segments)
8103     {
8104       errmsg ("at least one sr segment required\n");
8105       return -99;
8106     }
8107
8108   M2 (SR_TUNNEL_ADD_DEL, sr_tunnel_add_del,
8109       vec_len (segments) * sizeof (ip6_address_t)
8110       + vec_len (tags) * sizeof (ip6_address_t));
8111
8112   clib_memcpy (mp->src_address, &src_address, sizeof (mp->src_address));
8113   clib_memcpy (mp->dst_address, &dst_address, sizeof (mp->dst_address));
8114   mp->dst_mask_width = dst_mask_width;
8115   mp->flags_net_byte_order = clib_host_to_net_u16 (flags);
8116   mp->n_segments = vec_len (segments);
8117   mp->n_tags = vec_len (tags);
8118   mp->is_add = is_del == 0;
8119   clib_memcpy (mp->segs_and_tags, segments,
8120                vec_len (segments) * sizeof (ip6_address_t));
8121   clib_memcpy (mp->segs_and_tags +
8122                vec_len (segments) * sizeof (ip6_address_t), tags,
8123                vec_len (tags) * sizeof (ip6_address_t));
8124
8125   mp->outer_vrf_id = ntohl (rx_table_id);
8126   mp->inner_vrf_id = ntohl (tx_table_id);
8127   memcpy (mp->name, name, vec_len (name));
8128   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8129
8130   vec_free (segments);
8131   vec_free (tags);
8132
8133   S;
8134   W;
8135   /* NOTREACHED */
8136 }
8137
8138 static int
8139 api_sr_policy_add_del (vat_main_t * vam)
8140 {
8141   unformat_input_t *input = vam->input;
8142   vl_api_sr_policy_add_del_t *mp;
8143   f64 timeout;
8144   int is_del = 0;
8145   u8 *name = 0;
8146   u8 *tunnel_name = 0;
8147   u8 **tunnel_names = 0;
8148
8149   int name_set = 0;
8150   int tunnel_set = 0;
8151   int j = 0;
8152   int tunnel_names_length = 1;  // Init to 1 to offset the #tunnel_names counter byte
8153   int tun_name_len = 0;         // Different naming convention used as confusing these would be "bad" (TM)
8154
8155   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8156     {
8157       if (unformat (input, "del"))
8158         is_del = 1;
8159       else if (unformat (input, "name %s", &name))
8160         name_set = 1;
8161       else if (unformat (input, "tunnel %s", &tunnel_name))
8162         {
8163           if (tunnel_name)
8164             {
8165               vec_add1 (tunnel_names, tunnel_name);
8166               /* For serializer:
8167                  - length = #bytes to store in serial vector
8168                  - +1 = byte to store that length
8169                */
8170               tunnel_names_length += (vec_len (tunnel_name) + 1);
8171               tunnel_set = 1;
8172               tunnel_name = 0;
8173             }
8174         }
8175       else
8176         break;
8177     }
8178
8179   if (!name_set)
8180     {
8181       errmsg ("policy name required\n");
8182       return -99;
8183     }
8184
8185   if ((!tunnel_set) && (!is_del))
8186     {
8187       errmsg ("tunnel name required\n");
8188       return -99;
8189     }
8190
8191   M2 (SR_POLICY_ADD_DEL, sr_policy_add_del, tunnel_names_length);
8192
8193
8194
8195   mp->is_add = !is_del;
8196
8197   memcpy (mp->name, name, vec_len (name));
8198   // Since mp->tunnel_names is of type u8[0] and not a u8 *, u8 ** needs to be serialized
8199   u8 *serial_orig = 0;
8200   vec_validate (serial_orig, tunnel_names_length);
8201   *serial_orig = vec_len (tunnel_names);        // Store the number of tunnels as length in first byte of serialized vector
8202   serial_orig += 1;             // Move along one byte to store the length of first tunnel_name
8203
8204   for (j = 0; j < vec_len (tunnel_names); j++)
8205     {
8206       tun_name_len = vec_len (tunnel_names[j]);
8207       *serial_orig = tun_name_len;      // Store length of tunnel name in first byte of Length/Value pair
8208       serial_orig += 1;         // Move along one byte to store the actual tunnel name
8209       memcpy (serial_orig, tunnel_names[j], tun_name_len);
8210       serial_orig += tun_name_len;      // Advance past the copy
8211     }
8212   memcpy (mp->tunnel_names, serial_orig - tunnel_names_length, tunnel_names_length);    // Regress serial_orig to head then copy fwd
8213
8214   vec_free (tunnel_names);
8215   vec_free (tunnel_name);
8216
8217   S;
8218   W;
8219   /* NOTREACHED */
8220 }
8221
8222 static int
8223 api_sr_multicast_map_add_del (vat_main_t * vam)
8224 {
8225   unformat_input_t *input = vam->input;
8226   vl_api_sr_multicast_map_add_del_t *mp;
8227   f64 timeout;
8228   int is_del = 0;
8229   ip6_address_t multicast_address;
8230   u8 *policy_name = 0;
8231   int multicast_address_set = 0;
8232
8233   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8234     {
8235       if (unformat (input, "del"))
8236         is_del = 1;
8237       else
8238         if (unformat
8239             (input, "address %U", unformat_ip6_address, &multicast_address))
8240         multicast_address_set = 1;
8241       else if (unformat (input, "sr-policy %s", &policy_name))
8242         ;
8243       else
8244         break;
8245     }
8246
8247   if (!is_del && !policy_name)
8248     {
8249       errmsg ("sr-policy name required\n");
8250       return -99;
8251     }
8252
8253
8254   if (!multicast_address_set)
8255     {
8256       errmsg ("address required\n");
8257       return -99;
8258     }
8259
8260   M (SR_MULTICAST_MAP_ADD_DEL, sr_multicast_map_add_del);
8261
8262   mp->is_add = !is_del;
8263   memcpy (mp->policy_name, policy_name, vec_len (policy_name));
8264   clib_memcpy (mp->multicast_address, &multicast_address,
8265                sizeof (mp->multicast_address));
8266
8267
8268   vec_free (policy_name);
8269
8270   S;
8271   W;
8272   /* NOTREACHED */
8273 }
8274
8275
8276 #define foreach_tcp_proto_field                 \
8277 _(src_port)                                     \
8278 _(dst_port)
8279
8280 #define foreach_udp_proto_field                 \
8281 _(src_port)                                     \
8282 _(dst_port)
8283
8284 #define foreach_ip4_proto_field                 \
8285 _(src_address)                                  \
8286 _(dst_address)                                  \
8287 _(tos)                                          \
8288 _(length)                                       \
8289 _(fragment_id)                                  \
8290 _(ttl)                                          \
8291 _(protocol)                                     \
8292 _(checksum)
8293
8294 uword
8295 unformat_tcp_mask (unformat_input_t * input, va_list * args)
8296 {
8297   u8 **maskp = va_arg (*args, u8 **);
8298   u8 *mask = 0;
8299   u8 found_something = 0;
8300   tcp_header_t *tcp;
8301
8302 #define _(a) u8 a=0;
8303   foreach_tcp_proto_field;
8304 #undef _
8305
8306   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8307     {
8308       if (0);
8309 #define _(a) else if (unformat (input, #a)) a=1;
8310       foreach_tcp_proto_field
8311 #undef _
8312         else
8313         break;
8314     }
8315
8316 #define _(a) found_something += a;
8317   foreach_tcp_proto_field;
8318 #undef _
8319
8320   if (found_something == 0)
8321     return 0;
8322
8323   vec_validate (mask, sizeof (*tcp) - 1);
8324
8325   tcp = (tcp_header_t *) mask;
8326
8327 #define _(a) if (a) memset (&tcp->a, 0xff, sizeof (tcp->a));
8328   foreach_tcp_proto_field;
8329 #undef _
8330
8331   *maskp = mask;
8332   return 1;
8333 }
8334
8335 uword
8336 unformat_udp_mask (unformat_input_t * input, va_list * args)
8337 {
8338   u8 **maskp = va_arg (*args, u8 **);
8339   u8 *mask = 0;
8340   u8 found_something = 0;
8341   udp_header_t *udp;
8342
8343 #define _(a) u8 a=0;
8344   foreach_udp_proto_field;
8345 #undef _
8346
8347   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8348     {
8349       if (0);
8350 #define _(a) else if (unformat (input, #a)) a=1;
8351       foreach_udp_proto_field
8352 #undef _
8353         else
8354         break;
8355     }
8356
8357 #define _(a) found_something += a;
8358   foreach_udp_proto_field;
8359 #undef _
8360
8361   if (found_something == 0)
8362     return 0;
8363
8364   vec_validate (mask, sizeof (*udp) - 1);
8365
8366   udp = (udp_header_t *) mask;
8367
8368 #define _(a) if (a) memset (&udp->a, 0xff, sizeof (udp->a));
8369   foreach_udp_proto_field;
8370 #undef _
8371
8372   *maskp = mask;
8373   return 1;
8374 }
8375
8376 typedef struct
8377 {
8378   u16 src_port, dst_port;
8379 } tcpudp_header_t;
8380
8381 uword
8382 unformat_l4_mask (unformat_input_t * input, va_list * args)
8383 {
8384   u8 **maskp = va_arg (*args, u8 **);
8385   u16 src_port = 0, dst_port = 0;
8386   tcpudp_header_t *tcpudp;
8387
8388   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8389     {
8390       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
8391         return 1;
8392       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
8393         return 1;
8394       else if (unformat (input, "src_port"))
8395         src_port = 0xFFFF;
8396       else if (unformat (input, "dst_port"))
8397         dst_port = 0xFFFF;
8398       else
8399         return 0;
8400     }
8401
8402   if (!src_port && !dst_port)
8403     return 0;
8404
8405   u8 *mask = 0;
8406   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
8407
8408   tcpudp = (tcpudp_header_t *) mask;
8409   tcpudp->src_port = src_port;
8410   tcpudp->dst_port = dst_port;
8411
8412   *maskp = mask;
8413
8414   return 1;
8415 }
8416
8417 uword
8418 unformat_ip4_mask (unformat_input_t * input, va_list * args)
8419 {
8420   u8 **maskp = va_arg (*args, u8 **);
8421   u8 *mask = 0;
8422   u8 found_something = 0;
8423   ip4_header_t *ip;
8424
8425 #define _(a) u8 a=0;
8426   foreach_ip4_proto_field;
8427 #undef _
8428   u8 version = 0;
8429   u8 hdr_length = 0;
8430
8431
8432   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8433     {
8434       if (unformat (input, "version"))
8435         version = 1;
8436       else if (unformat (input, "hdr_length"))
8437         hdr_length = 1;
8438       else if (unformat (input, "src"))
8439         src_address = 1;
8440       else if (unformat (input, "dst"))
8441         dst_address = 1;
8442       else if (unformat (input, "proto"))
8443         protocol = 1;
8444
8445 #define _(a) else if (unformat (input, #a)) a=1;
8446       foreach_ip4_proto_field
8447 #undef _
8448         else
8449         break;
8450     }
8451
8452 #define _(a) found_something += a;
8453   foreach_ip4_proto_field;
8454 #undef _
8455
8456   if (found_something == 0)
8457     return 0;
8458
8459   vec_validate (mask, sizeof (*ip) - 1);
8460
8461   ip = (ip4_header_t *) mask;
8462
8463 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8464   foreach_ip4_proto_field;
8465 #undef _
8466
8467   ip->ip_version_and_header_length = 0;
8468
8469   if (version)
8470     ip->ip_version_and_header_length |= 0xF0;
8471
8472   if (hdr_length)
8473     ip->ip_version_and_header_length |= 0x0F;
8474
8475   *maskp = mask;
8476   return 1;
8477 }
8478
8479 #define foreach_ip6_proto_field                 \
8480 _(src_address)                                  \
8481 _(dst_address)                                  \
8482 _(payload_length)                               \
8483 _(hop_limit)                                    \
8484 _(protocol)
8485
8486 uword
8487 unformat_ip6_mask (unformat_input_t * input, va_list * args)
8488 {
8489   u8 **maskp = va_arg (*args, u8 **);
8490   u8 *mask = 0;
8491   u8 found_something = 0;
8492   ip6_header_t *ip;
8493   u32 ip_version_traffic_class_and_flow_label;
8494
8495 #define _(a) u8 a=0;
8496   foreach_ip6_proto_field;
8497 #undef _
8498   u8 version = 0;
8499   u8 traffic_class = 0;
8500   u8 flow_label = 0;
8501
8502   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8503     {
8504       if (unformat (input, "version"))
8505         version = 1;
8506       else if (unformat (input, "traffic-class"))
8507         traffic_class = 1;
8508       else if (unformat (input, "flow-label"))
8509         flow_label = 1;
8510       else if (unformat (input, "src"))
8511         src_address = 1;
8512       else if (unformat (input, "dst"))
8513         dst_address = 1;
8514       else if (unformat (input, "proto"))
8515         protocol = 1;
8516
8517 #define _(a) else if (unformat (input, #a)) a=1;
8518       foreach_ip6_proto_field
8519 #undef _
8520         else
8521         break;
8522     }
8523
8524 #define _(a) found_something += a;
8525   foreach_ip6_proto_field;
8526 #undef _
8527
8528   if (found_something == 0)
8529     return 0;
8530
8531   vec_validate (mask, sizeof (*ip) - 1);
8532
8533   ip = (ip6_header_t *) mask;
8534
8535 #define _(a) if (a) memset (&ip->a, 0xff, sizeof (ip->a));
8536   foreach_ip6_proto_field;
8537 #undef _
8538
8539   ip_version_traffic_class_and_flow_label = 0;
8540
8541   if (version)
8542     ip_version_traffic_class_and_flow_label |= 0xF0000000;
8543
8544   if (traffic_class)
8545     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
8546
8547   if (flow_label)
8548     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
8549
8550   ip->ip_version_traffic_class_and_flow_label =
8551     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8552
8553   *maskp = mask;
8554   return 1;
8555 }
8556
8557 uword
8558 unformat_l3_mask (unformat_input_t * input, va_list * args)
8559 {
8560   u8 **maskp = va_arg (*args, u8 **);
8561
8562   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8563     {
8564       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
8565         return 1;
8566       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
8567         return 1;
8568       else
8569         break;
8570     }
8571   return 0;
8572 }
8573
8574 uword
8575 unformat_l2_mask (unformat_input_t * input, va_list * args)
8576 {
8577   u8 **maskp = va_arg (*args, u8 **);
8578   u8 *mask = 0;
8579   u8 src = 0;
8580   u8 dst = 0;
8581   u8 proto = 0;
8582   u8 tag1 = 0;
8583   u8 tag2 = 0;
8584   u8 ignore_tag1 = 0;
8585   u8 ignore_tag2 = 0;
8586   u8 cos1 = 0;
8587   u8 cos2 = 0;
8588   u8 dot1q = 0;
8589   u8 dot1ad = 0;
8590   int len = 14;
8591
8592   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8593     {
8594       if (unformat (input, "src"))
8595         src = 1;
8596       else if (unformat (input, "dst"))
8597         dst = 1;
8598       else if (unformat (input, "proto"))
8599         proto = 1;
8600       else if (unformat (input, "tag1"))
8601         tag1 = 1;
8602       else if (unformat (input, "tag2"))
8603         tag2 = 1;
8604       else if (unformat (input, "ignore-tag1"))
8605         ignore_tag1 = 1;
8606       else if (unformat (input, "ignore-tag2"))
8607         ignore_tag2 = 1;
8608       else if (unformat (input, "cos1"))
8609         cos1 = 1;
8610       else if (unformat (input, "cos2"))
8611         cos2 = 1;
8612       else if (unformat (input, "dot1q"))
8613         dot1q = 1;
8614       else if (unformat (input, "dot1ad"))
8615         dot1ad = 1;
8616       else
8617         break;
8618     }
8619   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
8620        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8621     return 0;
8622
8623   if (tag1 || ignore_tag1 || cos1 || dot1q)
8624     len = 18;
8625   if (tag2 || ignore_tag2 || cos2 || dot1ad)
8626     len = 22;
8627
8628   vec_validate (mask, len - 1);
8629
8630   if (dst)
8631     memset (mask, 0xff, 6);
8632
8633   if (src)
8634     memset (mask + 6, 0xff, 6);
8635
8636   if (tag2 || dot1ad)
8637     {
8638       /* inner vlan tag */
8639       if (tag2)
8640         {
8641           mask[19] = 0xff;
8642           mask[18] = 0x0f;
8643         }
8644       if (cos2)
8645         mask[18] |= 0xe0;
8646       if (proto)
8647         mask[21] = mask[20] = 0xff;
8648       if (tag1)
8649         {
8650           mask[15] = 0xff;
8651           mask[14] = 0x0f;
8652         }
8653       if (cos1)
8654         mask[14] |= 0xe0;
8655       *maskp = mask;
8656       return 1;
8657     }
8658   if (tag1 | dot1q)
8659     {
8660       if (tag1)
8661         {
8662           mask[15] = 0xff;
8663           mask[14] = 0x0f;
8664         }
8665       if (cos1)
8666         mask[14] |= 0xe0;
8667       if (proto)
8668         mask[16] = mask[17] = 0xff;
8669
8670       *maskp = mask;
8671       return 1;
8672     }
8673   if (cos2)
8674     mask[18] |= 0xe0;
8675   if (cos1)
8676     mask[14] |= 0xe0;
8677   if (proto)
8678     mask[12] = mask[13] = 0xff;
8679
8680   *maskp = mask;
8681   return 1;
8682 }
8683
8684 uword
8685 unformat_classify_mask (unformat_input_t * input, va_list * args)
8686 {
8687   u8 **maskp = va_arg (*args, u8 **);
8688   u32 *skipp = va_arg (*args, u32 *);
8689   u32 *matchp = va_arg (*args, u32 *);
8690   u32 match;
8691   u8 *mask = 0;
8692   u8 *l2 = 0;
8693   u8 *l3 = 0;
8694   u8 *l4 = 0;
8695   int i;
8696
8697   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8698     {
8699       if (unformat (input, "hex %U", unformat_hex_string, &mask))
8700         ;
8701       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
8702         ;
8703       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
8704         ;
8705       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
8706         ;
8707       else
8708         break;
8709     }
8710
8711   if (l4 && !l3)
8712     {
8713       vec_free (mask);
8714       vec_free (l2);
8715       vec_free (l4);
8716       return 0;
8717     }
8718
8719   if (mask || l2 || l3 || l4)
8720     {
8721       if (l2 || l3 || l4)
8722         {
8723           /* "With a free Ethernet header in every package" */
8724           if (l2 == 0)
8725             vec_validate (l2, 13);
8726           mask = l2;
8727           if (vec_len (l3))
8728             {
8729               vec_append (mask, l3);
8730               vec_free (l3);
8731             }
8732           if (vec_len (l4))
8733             {
8734               vec_append (mask, l4);
8735               vec_free (l4);
8736             }
8737         }
8738
8739       /* Scan forward looking for the first significant mask octet */
8740       for (i = 0; i < vec_len (mask); i++)
8741         if (mask[i])
8742           break;
8743
8744       /* compute (skip, match) params */
8745       *skipp = i / sizeof (u32x4);
8746       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8747
8748       /* Pad mask to an even multiple of the vector size */
8749       while (vec_len (mask) % sizeof (u32x4))
8750         vec_add1 (mask, 0);
8751
8752       match = vec_len (mask) / sizeof (u32x4);
8753
8754       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8755         {
8756           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8757           if (*tmp || *(tmp + 1))
8758             break;
8759           match--;
8760         }
8761       if (match == 0)
8762         clib_warning ("BUG: match 0");
8763
8764       _vec_len (mask) = match * sizeof (u32x4);
8765
8766       *matchp = match;
8767       *maskp = mask;
8768
8769       return 1;
8770     }
8771
8772   return 0;
8773 }
8774
8775 #define foreach_l2_next                         \
8776 _(drop, DROP)                                   \
8777 _(ethernet, ETHERNET_INPUT)                     \
8778 _(ip4, IP4_INPUT)                               \
8779 _(ip6, IP6_INPUT)
8780
8781 uword
8782 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8783 {
8784   u32 *miss_next_indexp = va_arg (*args, u32 *);
8785   u32 next_index = 0;
8786   u32 tmp;
8787
8788 #define _(n,N) \
8789   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8790   foreach_l2_next;
8791 #undef _
8792
8793   if (unformat (input, "%d", &tmp))
8794     {
8795       next_index = tmp;
8796       goto out;
8797     }
8798
8799   return 0;
8800
8801 out:
8802   *miss_next_indexp = next_index;
8803   return 1;
8804 }
8805
8806 #define foreach_ip_next                         \
8807 _(drop, DROP)                                   \
8808 _(local, LOCAL)                                 \
8809 _(rewrite, REWRITE)
8810
8811 uword
8812 unformat_ip_next_index (unformat_input_t * input, va_list * args)
8813 {
8814   u32 *miss_next_indexp = va_arg (*args, u32 *);
8815   u32 next_index = 0;
8816   u32 tmp;
8817
8818 #define _(n,N) \
8819   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8820   foreach_ip_next;
8821 #undef _
8822
8823   if (unformat (input, "%d", &tmp))
8824     {
8825       next_index = tmp;
8826       goto out;
8827     }
8828
8829   return 0;
8830
8831 out:
8832   *miss_next_indexp = next_index;
8833   return 1;
8834 }
8835
8836 #define foreach_acl_next                        \
8837 _(deny, DENY)
8838
8839 uword
8840 unformat_acl_next_index (unformat_input_t * input, va_list * args)
8841 {
8842   u32 *miss_next_indexp = va_arg (*args, u32 *);
8843   u32 next_index = 0;
8844   u32 tmp;
8845
8846 #define _(n,N) \
8847   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8848   foreach_acl_next;
8849 #undef _
8850
8851   if (unformat (input, "permit"))
8852     {
8853       next_index = ~0;
8854       goto out;
8855     }
8856   else if (unformat (input, "%d", &tmp))
8857     {
8858       next_index = tmp;
8859       goto out;
8860     }
8861
8862   return 0;
8863
8864 out:
8865   *miss_next_indexp = next_index;
8866   return 1;
8867 }
8868
8869 uword
8870 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8871 {
8872   u32 *r = va_arg (*args, u32 *);
8873
8874   if (unformat (input, "conform-color"))
8875     *r = POLICE_CONFORM;
8876   else if (unformat (input, "exceed-color"))
8877     *r = POLICE_EXCEED;
8878   else
8879     return 0;
8880
8881   return 1;
8882 }
8883
8884 static int
8885 api_classify_add_del_table (vat_main_t * vam)
8886 {
8887   unformat_input_t *i = vam->input;
8888   vl_api_classify_add_del_table_t *mp;
8889
8890   u32 nbuckets = 2;
8891   u32 skip = ~0;
8892   u32 match = ~0;
8893   int is_add = 1;
8894   u32 table_index = ~0;
8895   u32 next_table_index = ~0;
8896   u32 miss_next_index = ~0;
8897   u32 memory_size = 32 << 20;
8898   u8 *mask = 0;
8899   f64 timeout;
8900   u32 current_data_flag = 0;
8901   int current_data_offset = 0;
8902
8903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8904     {
8905       if (unformat (i, "del"))
8906         is_add = 0;
8907       else if (unformat (i, "buckets %d", &nbuckets))
8908         ;
8909       else if (unformat (i, "memory_size %d", &memory_size))
8910         ;
8911       else if (unformat (i, "skip %d", &skip))
8912         ;
8913       else if (unformat (i, "match %d", &match))
8914         ;
8915       else if (unformat (i, "table %d", &table_index))
8916         ;
8917       else if (unformat (i, "mask %U", unformat_classify_mask,
8918                          &mask, &skip, &match))
8919         ;
8920       else if (unformat (i, "next-table %d", &next_table_index))
8921         ;
8922       else if (unformat (i, "miss-next %U", unformat_ip_next_index,
8923                          &miss_next_index))
8924         ;
8925       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8926                          &miss_next_index))
8927         ;
8928       else if (unformat (i, "acl-miss-next %U", unformat_acl_next_index,
8929                          &miss_next_index))
8930         ;
8931       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8932         ;
8933       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8934         ;
8935       else
8936         break;
8937     }
8938
8939   if (is_add && mask == 0)
8940     {
8941       errmsg ("Mask required\n");
8942       return -99;
8943     }
8944
8945   if (is_add && skip == ~0)
8946     {
8947       errmsg ("skip count required\n");
8948       return -99;
8949     }
8950
8951   if (is_add && match == ~0)
8952     {
8953       errmsg ("match count required\n");
8954       return -99;
8955     }
8956
8957   if (!is_add && table_index == ~0)
8958     {
8959       errmsg ("table index required for delete\n");
8960       return -99;
8961     }
8962
8963   M2 (CLASSIFY_ADD_DEL_TABLE, classify_add_del_table, vec_len (mask));
8964
8965   mp->is_add = is_add;
8966   mp->table_index = ntohl (table_index);
8967   mp->nbuckets = ntohl (nbuckets);
8968   mp->memory_size = ntohl (memory_size);
8969   mp->skip_n_vectors = ntohl (skip);
8970   mp->match_n_vectors = ntohl (match);
8971   mp->next_table_index = ntohl (next_table_index);
8972   mp->miss_next_index = ntohl (miss_next_index);
8973   mp->current_data_flag = ntohl (current_data_flag);
8974   mp->current_data_offset = ntohl (current_data_offset);
8975   clib_memcpy (mp->mask, mask, vec_len (mask));
8976
8977   vec_free (mask);
8978
8979   S;
8980   W;
8981   /* NOTREACHED */
8982 }
8983
8984 uword
8985 unformat_l4_match (unformat_input_t * input, va_list * args)
8986 {
8987   u8 **matchp = va_arg (*args, u8 **);
8988
8989   u8 *proto_header = 0;
8990   int src_port = 0;
8991   int dst_port = 0;
8992
8993   tcpudp_header_t h;
8994
8995   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8996     {
8997       if (unformat (input, "src_port %d", &src_port))
8998         ;
8999       else if (unformat (input, "dst_port %d", &dst_port))
9000         ;
9001       else
9002         return 0;
9003     }
9004
9005   h.src_port = clib_host_to_net_u16 (src_port);
9006   h.dst_port = clib_host_to_net_u16 (dst_port);
9007   vec_validate (proto_header, sizeof (h) - 1);
9008   memcpy (proto_header, &h, sizeof (h));
9009
9010   *matchp = proto_header;
9011
9012   return 1;
9013 }
9014
9015 uword
9016 unformat_ip4_match (unformat_input_t * input, va_list * args)
9017 {
9018   u8 **matchp = va_arg (*args, u8 **);
9019   u8 *match = 0;
9020   ip4_header_t *ip;
9021   int version = 0;
9022   u32 version_val;
9023   int hdr_length = 0;
9024   u32 hdr_length_val;
9025   int src = 0, dst = 0;
9026   ip4_address_t src_val, dst_val;
9027   int proto = 0;
9028   u32 proto_val;
9029   int tos = 0;
9030   u32 tos_val;
9031   int length = 0;
9032   u32 length_val;
9033   int fragment_id = 0;
9034   u32 fragment_id_val;
9035   int ttl = 0;
9036   int ttl_val;
9037   int checksum = 0;
9038   u32 checksum_val;
9039
9040   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9041     {
9042       if (unformat (input, "version %d", &version_val))
9043         version = 1;
9044       else if (unformat (input, "hdr_length %d", &hdr_length_val))
9045         hdr_length = 1;
9046       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
9047         src = 1;
9048       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
9049         dst = 1;
9050       else if (unformat (input, "proto %d", &proto_val))
9051         proto = 1;
9052       else if (unformat (input, "tos %d", &tos_val))
9053         tos = 1;
9054       else if (unformat (input, "length %d", &length_val))
9055         length = 1;
9056       else if (unformat (input, "fragment_id %d", &fragment_id_val))
9057         fragment_id = 1;
9058       else if (unformat (input, "ttl %d", &ttl_val))
9059         ttl = 1;
9060       else if (unformat (input, "checksum %d", &checksum_val))
9061         checksum = 1;
9062       else
9063         break;
9064     }
9065
9066   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
9067       + ttl + checksum == 0)
9068     return 0;
9069
9070   /*
9071    * Aligned because we use the real comparison functions
9072    */
9073   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9074
9075   ip = (ip4_header_t *) match;
9076
9077   /* These are realistically matched in practice */
9078   if (src)
9079     ip->src_address.as_u32 = src_val.as_u32;
9080
9081   if (dst)
9082     ip->dst_address.as_u32 = dst_val.as_u32;
9083
9084   if (proto)
9085     ip->protocol = proto_val;
9086
9087
9088   /* These are not, but they're included for completeness */
9089   if (version)
9090     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
9091
9092   if (hdr_length)
9093     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
9094
9095   if (tos)
9096     ip->tos = tos_val;
9097
9098   if (length)
9099     ip->length = clib_host_to_net_u16 (length_val);
9100
9101   if (ttl)
9102     ip->ttl = ttl_val;
9103
9104   if (checksum)
9105     ip->checksum = clib_host_to_net_u16 (checksum_val);
9106
9107   *matchp = match;
9108   return 1;
9109 }
9110
9111 uword
9112 unformat_ip6_match (unformat_input_t * input, va_list * args)
9113 {
9114   u8 **matchp = va_arg (*args, u8 **);
9115   u8 *match = 0;
9116   ip6_header_t *ip;
9117   int version = 0;
9118   u32 version_val;
9119   u8 traffic_class = 0;
9120   u32 traffic_class_val = 0;
9121   u8 flow_label = 0;
9122   u8 flow_label_val;
9123   int src = 0, dst = 0;
9124   ip6_address_t src_val, dst_val;
9125   int proto = 0;
9126   u32 proto_val;
9127   int payload_length = 0;
9128   u32 payload_length_val;
9129   int hop_limit = 0;
9130   int hop_limit_val;
9131   u32 ip_version_traffic_class_and_flow_label;
9132
9133   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9134     {
9135       if (unformat (input, "version %d", &version_val))
9136         version = 1;
9137       else if (unformat (input, "traffic_class %d", &traffic_class_val))
9138         traffic_class = 1;
9139       else if (unformat (input, "flow_label %d", &flow_label_val))
9140         flow_label = 1;
9141       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
9142         src = 1;
9143       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
9144         dst = 1;
9145       else if (unformat (input, "proto %d", &proto_val))
9146         proto = 1;
9147       else if (unformat (input, "payload_length %d", &payload_length_val))
9148         payload_length = 1;
9149       else if (unformat (input, "hop_limit %d", &hop_limit_val))
9150         hop_limit = 1;
9151       else
9152         break;
9153     }
9154
9155   if (version + traffic_class + flow_label + src + dst + proto +
9156       payload_length + hop_limit == 0)
9157     return 0;
9158
9159   /*
9160    * Aligned because we use the real comparison functions
9161    */
9162   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
9163
9164   ip = (ip6_header_t *) match;
9165
9166   if (src)
9167     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
9168
9169   if (dst)
9170     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
9171
9172   if (proto)
9173     ip->protocol = proto_val;
9174
9175   ip_version_traffic_class_and_flow_label = 0;
9176
9177   if (version)
9178     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
9179
9180   if (traffic_class)
9181     ip_version_traffic_class_and_flow_label |=
9182       (traffic_class_val & 0xFF) << 20;
9183
9184   if (flow_label)
9185     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
9186
9187   ip->ip_version_traffic_class_and_flow_label =
9188     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9189
9190   if (payload_length)
9191     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
9192
9193   if (hop_limit)
9194     ip->hop_limit = hop_limit_val;
9195
9196   *matchp = match;
9197   return 1;
9198 }
9199
9200 uword
9201 unformat_l3_match (unformat_input_t * input, va_list * args)
9202 {
9203   u8 **matchp = va_arg (*args, u8 **);
9204
9205   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9206     {
9207       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
9208         return 1;
9209       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
9210         return 1;
9211       else
9212         break;
9213     }
9214   return 0;
9215 }
9216
9217 uword
9218 unformat_vlan_tag (unformat_input_t * input, va_list * args)
9219 {
9220   u8 *tagp = va_arg (*args, u8 *);
9221   u32 tag;
9222
9223   if (unformat (input, "%d", &tag))
9224     {
9225       tagp[0] = (tag >> 8) & 0x0F;
9226       tagp[1] = tag & 0xFF;
9227       return 1;
9228     }
9229
9230   return 0;
9231 }
9232
9233 uword
9234 unformat_l2_match (unformat_input_t * input, va_list * args)
9235 {
9236   u8 **matchp = va_arg (*args, u8 **);
9237   u8 *match = 0;
9238   u8 src = 0;
9239   u8 src_val[6];
9240   u8 dst = 0;
9241   u8 dst_val[6];
9242   u8 proto = 0;
9243   u16 proto_val;
9244   u8 tag1 = 0;
9245   u8 tag1_val[2];
9246   u8 tag2 = 0;
9247   u8 tag2_val[2];
9248   int len = 14;
9249   u8 ignore_tag1 = 0;
9250   u8 ignore_tag2 = 0;
9251   u8 cos1 = 0;
9252   u8 cos2 = 0;
9253   u32 cos1_val = 0;
9254   u32 cos2_val = 0;
9255
9256   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9257     {
9258       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
9259         src = 1;
9260       else
9261         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
9262         dst = 1;
9263       else if (unformat (input, "proto %U",
9264                          unformat_ethernet_type_host_byte_order, &proto_val))
9265         proto = 1;
9266       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
9267         tag1 = 1;
9268       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
9269         tag2 = 1;
9270       else if (unformat (input, "ignore-tag1"))
9271         ignore_tag1 = 1;
9272       else if (unformat (input, "ignore-tag2"))
9273         ignore_tag2 = 1;
9274       else if (unformat (input, "cos1 %d", &cos1_val))
9275         cos1 = 1;
9276       else if (unformat (input, "cos2 %d", &cos2_val))
9277         cos2 = 1;
9278       else
9279         break;
9280     }
9281   if ((src + dst + proto + tag1 + tag2 +
9282        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9283     return 0;
9284
9285   if (tag1 || ignore_tag1 || cos1)
9286     len = 18;
9287   if (tag2 || ignore_tag2 || cos2)
9288     len = 22;
9289
9290   vec_validate_aligned (match, len - 1, sizeof (u32x4));
9291
9292   if (dst)
9293     clib_memcpy (match, dst_val, 6);
9294
9295   if (src)
9296     clib_memcpy (match + 6, src_val, 6);
9297
9298   if (tag2)
9299     {
9300       /* inner vlan tag */
9301       match[19] = tag2_val[1];
9302       match[18] = tag2_val[0];
9303       if (cos2)
9304         match[18] |= (cos2_val & 0x7) << 5;
9305       if (proto)
9306         {
9307           match[21] = proto_val & 0xff;
9308           match[20] = proto_val >> 8;
9309         }
9310       if (tag1)
9311         {
9312           match[15] = tag1_val[1];
9313           match[14] = tag1_val[0];
9314         }
9315       if (cos1)
9316         match[14] |= (cos1_val & 0x7) << 5;
9317       *matchp = match;
9318       return 1;
9319     }
9320   if (tag1)
9321     {
9322       match[15] = tag1_val[1];
9323       match[14] = tag1_val[0];
9324       if (proto)
9325         {
9326           match[17] = proto_val & 0xff;
9327           match[16] = proto_val >> 8;
9328         }
9329       if (cos1)
9330         match[14] |= (cos1_val & 0x7) << 5;
9331
9332       *matchp = match;
9333       return 1;
9334     }
9335   if (cos2)
9336     match[18] |= (cos2_val & 0x7) << 5;
9337   if (cos1)
9338     match[14] |= (cos1_val & 0x7) << 5;
9339   if (proto)
9340     {
9341       match[13] = proto_val & 0xff;
9342       match[12] = proto_val >> 8;
9343     }
9344
9345   *matchp = match;
9346   return 1;
9347 }
9348
9349
9350 uword
9351 unformat_classify_match (unformat_input_t * input, va_list * args)
9352 {
9353   u8 **matchp = va_arg (*args, u8 **);
9354   u32 skip_n_vectors = va_arg (*args, u32);
9355   u32 match_n_vectors = va_arg (*args, u32);
9356
9357   u8 *match = 0;
9358   u8 *l2 = 0;
9359   u8 *l3 = 0;
9360   u8 *l4 = 0;
9361
9362   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9363     {
9364       if (unformat (input, "hex %U", unformat_hex_string, &match))
9365         ;
9366       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
9367         ;
9368       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
9369         ;
9370       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
9371         ;
9372       else
9373         break;
9374     }
9375
9376   if (l4 && !l3)
9377     {
9378       vec_free (match);
9379       vec_free (l2);
9380       vec_free (l4);
9381       return 0;
9382     }
9383
9384   if (match || l2 || l3 || l4)
9385     {
9386       if (l2 || l3 || l4)
9387         {
9388           /* "Win a free Ethernet header in every packet" */
9389           if (l2 == 0)
9390             vec_validate_aligned (l2, 13, sizeof (u32x4));
9391           match = l2;
9392           if (vec_len (l3))
9393             {
9394               vec_append_aligned (match, l3, sizeof (u32x4));
9395               vec_free (l3);
9396             }
9397           if (vec_len (l4))
9398             {
9399               vec_append_aligned (match, l4, sizeof (u32x4));
9400               vec_free (l4);
9401             }
9402         }
9403
9404       /* Make sure the vector is big enough even if key is all 0's */
9405       vec_validate_aligned
9406         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
9407          sizeof (u32x4));
9408
9409       /* Set size, include skipped vectors */
9410       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
9411
9412       *matchp = match;
9413
9414       return 1;
9415     }
9416
9417   return 0;
9418 }
9419
9420 static int
9421 api_classify_add_del_session (vat_main_t * vam)
9422 {
9423   unformat_input_t *i = vam->input;
9424   vl_api_classify_add_del_session_t *mp;
9425   int is_add = 1;
9426   u32 table_index = ~0;
9427   u32 hit_next_index = ~0;
9428   u32 opaque_index = ~0;
9429   u8 *match = 0;
9430   i32 advance = 0;
9431   f64 timeout;
9432   u32 skip_n_vectors = 0;
9433   u32 match_n_vectors = 0;
9434   u32 action = 0;
9435   u32 metadata = 0;
9436
9437   /*
9438    * Warning: you have to supply skip_n and match_n
9439    * because the API client cant simply look at the classify
9440    * table object.
9441    */
9442
9443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9444     {
9445       if (unformat (i, "del"))
9446         is_add = 0;
9447       else if (unformat (i, "hit-next %U", unformat_ip_next_index,
9448                          &hit_next_index))
9449         ;
9450       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
9451                          &hit_next_index))
9452         ;
9453       else if (unformat (i, "acl-hit-next %U", unformat_acl_next_index,
9454                          &hit_next_index))
9455         ;
9456       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
9457         ;
9458       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
9459         ;
9460       else if (unformat (i, "opaque-index %d", &opaque_index))
9461         ;
9462       else if (unformat (i, "skip_n %d", &skip_n_vectors))
9463         ;
9464       else if (unformat (i, "match_n %d", &match_n_vectors))
9465         ;
9466       else if (unformat (i, "match %U", unformat_classify_match,
9467                          &match, skip_n_vectors, match_n_vectors))
9468         ;
9469       else if (unformat (i, "advance %d", &advance))
9470         ;
9471       else if (unformat (i, "table-index %d", &table_index))
9472         ;
9473       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
9474         action = 1;
9475       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
9476         action = 2;
9477       else if (unformat (i, "action %d", &action))
9478         ;
9479       else if (unformat (i, "metadata %d", &metadata))
9480         ;
9481       else
9482         break;
9483     }
9484
9485   if (table_index == ~0)
9486     {
9487       errmsg ("Table index required\n");
9488       return -99;
9489     }
9490
9491   if (is_add && match == 0)
9492     {
9493       errmsg ("Match value required\n");
9494       return -99;
9495     }
9496
9497   M2 (CLASSIFY_ADD_DEL_SESSION, classify_add_del_session, vec_len (match));
9498
9499   mp->is_add = is_add;
9500   mp->table_index = ntohl (table_index);
9501   mp->hit_next_index = ntohl (hit_next_index);
9502   mp->opaque_index = ntohl (opaque_index);
9503   mp->advance = ntohl (advance);
9504   mp->action = action;
9505   mp->metadata = ntohl (metadata);
9506   clib_memcpy (mp->match, match, vec_len (match));
9507   vec_free (match);
9508
9509   S;
9510   W;
9511   /* NOTREACHED */
9512 }
9513
9514 static int
9515 api_classify_set_interface_ip_table (vat_main_t * vam)
9516 {
9517   unformat_input_t *i = vam->input;
9518   vl_api_classify_set_interface_ip_table_t *mp;
9519   f64 timeout;
9520   u32 sw_if_index;
9521   int sw_if_index_set;
9522   u32 table_index = ~0;
9523   u8 is_ipv6 = 0;
9524
9525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9526     {
9527       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9528         sw_if_index_set = 1;
9529       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9530         sw_if_index_set = 1;
9531       else if (unformat (i, "table %d", &table_index))
9532         ;
9533       else
9534         {
9535           clib_warning ("parse error '%U'", format_unformat_error, i);
9536           return -99;
9537         }
9538     }
9539
9540   if (sw_if_index_set == 0)
9541     {
9542       errmsg ("missing interface name or sw_if_index\n");
9543       return -99;
9544     }
9545
9546
9547   M (CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table);
9548
9549   mp->sw_if_index = ntohl (sw_if_index);
9550   mp->table_index = ntohl (table_index);
9551   mp->is_ipv6 = is_ipv6;
9552
9553   S;
9554   W;
9555   /* NOTREACHED */
9556   return 0;
9557 }
9558
9559 static int
9560 api_classify_set_interface_l2_tables (vat_main_t * vam)
9561 {
9562   unformat_input_t *i = vam->input;
9563   vl_api_classify_set_interface_l2_tables_t *mp;
9564   f64 timeout;
9565   u32 sw_if_index;
9566   int sw_if_index_set;
9567   u32 ip4_table_index = ~0;
9568   u32 ip6_table_index = ~0;
9569   u32 other_table_index = ~0;
9570   u32 is_input = 1;
9571
9572   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9573     {
9574       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9575         sw_if_index_set = 1;
9576       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9577         sw_if_index_set = 1;
9578       else if (unformat (i, "ip4-table %d", &ip4_table_index))
9579         ;
9580       else if (unformat (i, "ip6-table %d", &ip6_table_index))
9581         ;
9582       else if (unformat (i, "other-table %d", &other_table_index))
9583         ;
9584       else if (unformat (i, "is-input %d", &is_input))
9585         ;
9586       else
9587         {
9588           clib_warning ("parse error '%U'", format_unformat_error, i);
9589           return -99;
9590         }
9591     }
9592
9593   if (sw_if_index_set == 0)
9594     {
9595       errmsg ("missing interface name or sw_if_index\n");
9596       return -99;
9597     }
9598
9599
9600   M (CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables);
9601
9602   mp->sw_if_index = ntohl (sw_if_index);
9603   mp->ip4_table_index = ntohl (ip4_table_index);
9604   mp->ip6_table_index = ntohl (ip6_table_index);
9605   mp->other_table_index = ntohl (other_table_index);
9606   mp->is_input = (u8) is_input;
9607
9608   S;
9609   W;
9610   /* NOTREACHED */
9611   return 0;
9612 }
9613
9614 static int
9615 api_set_ipfix_exporter (vat_main_t * vam)
9616 {
9617   unformat_input_t *i = vam->input;
9618   vl_api_set_ipfix_exporter_t *mp;
9619   ip4_address_t collector_address;
9620   u8 collector_address_set = 0;
9621   u32 collector_port = ~0;
9622   ip4_address_t src_address;
9623   u8 src_address_set = 0;
9624   u32 vrf_id = ~0;
9625   u32 path_mtu = ~0;
9626   u32 template_interval = ~0;
9627   u8 udp_checksum = 0;
9628   f64 timeout;
9629
9630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9631     {
9632       if (unformat (i, "collector_address %U", unformat_ip4_address,
9633                     &collector_address))
9634         collector_address_set = 1;
9635       else if (unformat (i, "collector_port %d", &collector_port))
9636         ;
9637       else if (unformat (i, "src_address %U", unformat_ip4_address,
9638                          &src_address))
9639         src_address_set = 1;
9640       else if (unformat (i, "vrf_id %d", &vrf_id))
9641         ;
9642       else if (unformat (i, "path_mtu %d", &path_mtu))
9643         ;
9644       else if (unformat (i, "template_interval %d", &template_interval))
9645         ;
9646       else if (unformat (i, "udp_checksum"))
9647         udp_checksum = 1;
9648       else
9649         break;
9650     }
9651
9652   if (collector_address_set == 0)
9653     {
9654       errmsg ("collector_address required\n");
9655       return -99;
9656     }
9657
9658   if (src_address_set == 0)
9659     {
9660       errmsg ("src_address required\n");
9661       return -99;
9662     }
9663
9664   M (SET_IPFIX_EXPORTER, set_ipfix_exporter);
9665
9666   memcpy (mp->collector_address, collector_address.data,
9667           sizeof (collector_address.data));
9668   mp->collector_port = htons ((u16) collector_port);
9669   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
9670   mp->vrf_id = htonl (vrf_id);
9671   mp->path_mtu = htonl (path_mtu);
9672   mp->template_interval = htonl (template_interval);
9673   mp->udp_checksum = udp_checksum;
9674
9675   S;
9676   W;
9677   /* NOTREACHED */
9678 }
9679
9680 static int
9681 api_set_ipfix_classify_stream (vat_main_t * vam)
9682 {
9683   unformat_input_t *i = vam->input;
9684   vl_api_set_ipfix_classify_stream_t *mp;
9685   u32 domain_id = 0;
9686   u32 src_port = UDP_DST_PORT_ipfix;
9687   f64 timeout;
9688
9689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9690     {
9691       if (unformat (i, "domain %d", &domain_id))
9692         ;
9693       else if (unformat (i, "src_port %d", &src_port))
9694         ;
9695       else
9696         {
9697           errmsg ("unknown input `%U'", format_unformat_error, i);
9698           return -99;
9699         }
9700     }
9701
9702   M (SET_IPFIX_CLASSIFY_STREAM, set_ipfix_classify_stream);
9703
9704   mp->domain_id = htonl (domain_id);
9705   mp->src_port = htons ((u16) src_port);
9706
9707   S;
9708   W;
9709   /* NOTREACHED */
9710 }
9711
9712 static int
9713 api_ipfix_classify_table_add_del (vat_main_t * vam)
9714 {
9715   unformat_input_t *i = vam->input;
9716   vl_api_ipfix_classify_table_add_del_t *mp;
9717   int is_add = -1;
9718   u32 classify_table_index = ~0;
9719   u8 ip_version = 0;
9720   u8 transport_protocol = 255;
9721   f64 timeout;
9722
9723   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9724     {
9725       if (unformat (i, "add"))
9726         is_add = 1;
9727       else if (unformat (i, "del"))
9728         is_add = 0;
9729       else if (unformat (i, "table %d", &classify_table_index))
9730         ;
9731       else if (unformat (i, "ip4"))
9732         ip_version = 4;
9733       else if (unformat (i, "ip6"))
9734         ip_version = 6;
9735       else if (unformat (i, "tcp"))
9736         transport_protocol = 6;
9737       else if (unformat (i, "udp"))
9738         transport_protocol = 17;
9739       else
9740         {
9741           errmsg ("unknown input `%U'", format_unformat_error, i);
9742           return -99;
9743         }
9744     }
9745
9746   if (is_add == -1)
9747     {
9748       errmsg ("expecting: add|del");
9749       return -99;
9750     }
9751   if (classify_table_index == ~0)
9752     {
9753       errmsg ("classifier table not specified");
9754       return -99;
9755     }
9756   if (ip_version == 0)
9757     {
9758       errmsg ("IP version not specified");
9759       return -99;
9760     }
9761
9762   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, ipfix_classify_table_add_del);
9763
9764   mp->is_add = is_add;
9765   mp->table_id = htonl (classify_table_index);
9766   mp->ip_version = ip_version;
9767   mp->transport_protocol = transport_protocol;
9768
9769   S;
9770   W;
9771   /* NOTREACHED */
9772 }
9773
9774 static int
9775 api_get_node_index (vat_main_t * vam)
9776 {
9777   unformat_input_t *i = vam->input;
9778   vl_api_get_node_index_t *mp;
9779   f64 timeout;
9780   u8 *name = 0;
9781
9782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9783     {
9784       if (unformat (i, "node %s", &name))
9785         ;
9786       else
9787         break;
9788     }
9789   if (name == 0)
9790     {
9791       errmsg ("node name required\n");
9792       return -99;
9793     }
9794   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9795     {
9796       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9797       return -99;
9798     }
9799
9800   M (GET_NODE_INDEX, get_node_index);
9801   clib_memcpy (mp->node_name, name, vec_len (name));
9802   vec_free (name);
9803
9804   S;
9805   W;
9806   /* NOTREACHED */
9807   return 0;
9808 }
9809
9810 static int
9811 api_get_next_index (vat_main_t * vam)
9812 {
9813   unformat_input_t *i = vam->input;
9814   vl_api_get_next_index_t *mp;
9815   f64 timeout;
9816   u8 *node_name = 0, *next_node_name = 0;
9817
9818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9819     {
9820       if (unformat (i, "node-name %s", &node_name))
9821         ;
9822       else if (unformat (i, "next-node-name %s", &next_node_name))
9823         break;
9824     }
9825
9826   if (node_name == 0)
9827     {
9828       errmsg ("node name required\n");
9829       return -99;
9830     }
9831   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9832     {
9833       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9834       return -99;
9835     }
9836
9837   if (next_node_name == 0)
9838     {
9839       errmsg ("next node name required\n");
9840       return -99;
9841     }
9842   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9843     {
9844       errmsg ("next node name too long, max %d\n", ARRAY_LEN (mp->next_name));
9845       return -99;
9846     }
9847
9848   M (GET_NEXT_INDEX, get_next_index);
9849   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9850   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9851   vec_free (node_name);
9852   vec_free (next_node_name);
9853
9854   S;
9855   W;
9856   /* NOTREACHED */
9857   return 0;
9858 }
9859
9860 static int
9861 api_add_node_next (vat_main_t * vam)
9862 {
9863   unformat_input_t *i = vam->input;
9864   vl_api_add_node_next_t *mp;
9865   f64 timeout;
9866   u8 *name = 0;
9867   u8 *next = 0;
9868
9869   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9870     {
9871       if (unformat (i, "node %s", &name))
9872         ;
9873       else if (unformat (i, "next %s", &next))
9874         ;
9875       else
9876         break;
9877     }
9878   if (name == 0)
9879     {
9880       errmsg ("node name required\n");
9881       return -99;
9882     }
9883   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9884     {
9885       errmsg ("node name too long, max %d\n", ARRAY_LEN (mp->node_name));
9886       return -99;
9887     }
9888   if (next == 0)
9889     {
9890       errmsg ("next node required\n");
9891       return -99;
9892     }
9893   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9894     {
9895       errmsg ("next name too long, max %d\n", ARRAY_LEN (mp->next_name));
9896       return -99;
9897     }
9898
9899   M (ADD_NODE_NEXT, add_node_next);
9900   clib_memcpy (mp->node_name, name, vec_len (name));
9901   clib_memcpy (mp->next_name, next, vec_len (next));
9902   vec_free (name);
9903   vec_free (next);
9904
9905   S;
9906   W;
9907   /* NOTREACHED */
9908   return 0;
9909 }
9910
9911 static int
9912 api_l2tpv3_create_tunnel (vat_main_t * vam)
9913 {
9914   unformat_input_t *i = vam->input;
9915   ip6_address_t client_address, our_address;
9916   int client_address_set = 0;
9917   int our_address_set = 0;
9918   u32 local_session_id = 0;
9919   u32 remote_session_id = 0;
9920   u64 local_cookie = 0;
9921   u64 remote_cookie = 0;
9922   u8 l2_sublayer_present = 0;
9923   vl_api_l2tpv3_create_tunnel_t *mp;
9924   f64 timeout;
9925
9926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9927     {
9928       if (unformat (i, "client_address %U", unformat_ip6_address,
9929                     &client_address))
9930         client_address_set = 1;
9931       else if (unformat (i, "our_address %U", unformat_ip6_address,
9932                          &our_address))
9933         our_address_set = 1;
9934       else if (unformat (i, "local_session_id %d", &local_session_id))
9935         ;
9936       else if (unformat (i, "remote_session_id %d", &remote_session_id))
9937         ;
9938       else if (unformat (i, "local_cookie %lld", &local_cookie))
9939         ;
9940       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
9941         ;
9942       else if (unformat (i, "l2-sublayer-present"))
9943         l2_sublayer_present = 1;
9944       else
9945         break;
9946     }
9947
9948   if (client_address_set == 0)
9949     {
9950       errmsg ("client_address required\n");
9951       return -99;
9952     }
9953
9954   if (our_address_set == 0)
9955     {
9956       errmsg ("our_address required\n");
9957       return -99;
9958     }
9959
9960   M (L2TPV3_CREATE_TUNNEL, l2tpv3_create_tunnel);
9961
9962   clib_memcpy (mp->client_address, client_address.as_u8,
9963                sizeof (mp->client_address));
9964
9965   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
9966
9967   mp->local_session_id = ntohl (local_session_id);
9968   mp->remote_session_id = ntohl (remote_session_id);
9969   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
9970   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
9971   mp->l2_sublayer_present = l2_sublayer_present;
9972   mp->is_ipv6 = 1;
9973
9974   S;
9975   W;
9976   /* NOTREACHED */
9977   return 0;
9978 }
9979
9980 static int
9981 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
9982 {
9983   unformat_input_t *i = vam->input;
9984   u32 sw_if_index;
9985   u8 sw_if_index_set = 0;
9986   u64 new_local_cookie = 0;
9987   u64 new_remote_cookie = 0;
9988   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
9989   f64 timeout;
9990
9991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9992     {
9993       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
9994         sw_if_index_set = 1;
9995       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9996         sw_if_index_set = 1;
9997       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
9998         ;
9999       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
10000         ;
10001       else
10002         break;
10003     }
10004
10005   if (sw_if_index_set == 0)
10006     {
10007       errmsg ("missing interface name or sw_if_index\n");
10008       return -99;
10009     }
10010
10011   M (L2TPV3_SET_TUNNEL_COOKIES, l2tpv3_set_tunnel_cookies);
10012
10013   mp->sw_if_index = ntohl (sw_if_index);
10014   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
10015   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
10016
10017   S;
10018   W;
10019   /* NOTREACHED */
10020   return 0;
10021 }
10022
10023 static int
10024 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
10025 {
10026   unformat_input_t *i = vam->input;
10027   vl_api_l2tpv3_interface_enable_disable_t *mp;
10028   f64 timeout;
10029   u32 sw_if_index;
10030   u8 sw_if_index_set = 0;
10031   u8 enable_disable = 1;
10032
10033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10034     {
10035       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10036         sw_if_index_set = 1;
10037       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10038         sw_if_index_set = 1;
10039       else if (unformat (i, "enable"))
10040         enable_disable = 1;
10041       else if (unformat (i, "disable"))
10042         enable_disable = 0;
10043       else
10044         break;
10045     }
10046
10047   if (sw_if_index_set == 0)
10048     {
10049       errmsg ("missing interface name or sw_if_index\n");
10050       return -99;
10051     }
10052
10053   M (L2TPV3_INTERFACE_ENABLE_DISABLE, l2tpv3_interface_enable_disable);
10054
10055   mp->sw_if_index = ntohl (sw_if_index);
10056   mp->enable_disable = enable_disable;
10057
10058   S;
10059   W;
10060   /* NOTREACHED */
10061   return 0;
10062 }
10063
10064 static int
10065 api_l2tpv3_set_lookup_key (vat_main_t * vam)
10066 {
10067   unformat_input_t *i = vam->input;
10068   vl_api_l2tpv3_set_lookup_key_t *mp;
10069   f64 timeout;
10070   u8 key = ~0;
10071
10072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10073     {
10074       if (unformat (i, "lookup_v6_src"))
10075         key = L2T_LOOKUP_SRC_ADDRESS;
10076       else if (unformat (i, "lookup_v6_dst"))
10077         key = L2T_LOOKUP_DST_ADDRESS;
10078       else if (unformat (i, "lookup_session_id"))
10079         key = L2T_LOOKUP_SESSION_ID;
10080       else
10081         break;
10082     }
10083
10084   if (key == (u8) ~ 0)
10085     {
10086       errmsg ("l2tp session lookup key unset\n");
10087       return -99;
10088     }
10089
10090   M (L2TPV3_SET_LOOKUP_KEY, l2tpv3_set_lookup_key);
10091
10092   mp->key = key;
10093
10094   S;
10095   W;
10096   /* NOTREACHED */
10097   return 0;
10098 }
10099
10100 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
10101   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10102 {
10103   vat_main_t *vam = &vat_main;
10104
10105   fformat (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)\n",
10106            format_ip6_address, mp->our_address,
10107            format_ip6_address, mp->client_address,
10108            clib_net_to_host_u32 (mp->sw_if_index));
10109
10110   fformat (vam->ofp,
10111            "   local cookies %016llx %016llx remote cookie %016llx\n",
10112            clib_net_to_host_u64 (mp->local_cookie[0]),
10113            clib_net_to_host_u64 (mp->local_cookie[1]),
10114            clib_net_to_host_u64 (mp->remote_cookie));
10115
10116   fformat (vam->ofp, "   local session-id %d remote session-id %d\n",
10117            clib_net_to_host_u32 (mp->local_session_id),
10118            clib_net_to_host_u32 (mp->remote_session_id));
10119
10120   fformat (vam->ofp, "   l2 specific sublayer %s\n\n",
10121            mp->l2_sublayer_present ? "preset" : "absent");
10122
10123 }
10124
10125 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
10126   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
10127 {
10128   vat_main_t *vam = &vat_main;
10129   vat_json_node_t *node = NULL;
10130   struct in6_addr addr;
10131
10132   if (VAT_JSON_ARRAY != vam->json_tree.type)
10133     {
10134       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10135       vat_json_init_array (&vam->json_tree);
10136     }
10137   node = vat_json_array_add (&vam->json_tree);
10138
10139   vat_json_init_object (node);
10140
10141   clib_memcpy (&addr, mp->our_address, sizeof (addr));
10142   vat_json_object_add_ip6 (node, "our_address", addr);
10143   clib_memcpy (&addr, mp->client_address, sizeof (addr));
10144   vat_json_object_add_ip6 (node, "client_address", addr);
10145
10146   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
10147   vat_json_init_array (lc);
10148   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
10149   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
10150   vat_json_object_add_uint (node, "remote_cookie",
10151                             clib_net_to_host_u64 (mp->remote_cookie));
10152
10153   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
10154   vat_json_object_add_uint (node, "local_session_id",
10155                             clib_net_to_host_u32 (mp->local_session_id));
10156   vat_json_object_add_uint (node, "remote_session_id",
10157                             clib_net_to_host_u32 (mp->remote_session_id));
10158   vat_json_object_add_string_copy (node, "l2_sublayer",
10159                                    mp->l2_sublayer_present ? (u8 *) "present"
10160                                    : (u8 *) "absent");
10161 }
10162
10163 static int
10164 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
10165 {
10166   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
10167   f64 timeout;
10168
10169   /* Get list of l2tpv3-tunnel interfaces */
10170   M (SW_IF_L2TPV3_TUNNEL_DUMP, sw_if_l2tpv3_tunnel_dump);
10171   S;
10172
10173   /* Use a control ping for synchronization */
10174   {
10175     vl_api_control_ping_t *mp;
10176     M (CONTROL_PING, control_ping);
10177     S;
10178   }
10179   W;
10180 }
10181
10182
10183 static void vl_api_sw_interface_tap_details_t_handler
10184   (vl_api_sw_interface_tap_details_t * mp)
10185 {
10186   vat_main_t *vam = &vat_main;
10187
10188   fformat (vam->ofp, "%-16s %d\n",
10189            mp->dev_name, clib_net_to_host_u32 (mp->sw_if_index));
10190 }
10191
10192 static void vl_api_sw_interface_tap_details_t_handler_json
10193   (vl_api_sw_interface_tap_details_t * mp)
10194 {
10195   vat_main_t *vam = &vat_main;
10196   vat_json_node_t *node = NULL;
10197
10198   if (VAT_JSON_ARRAY != vam->json_tree.type)
10199     {
10200       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10201       vat_json_init_array (&vam->json_tree);
10202     }
10203   node = vat_json_array_add (&vam->json_tree);
10204
10205   vat_json_init_object (node);
10206   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10207   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
10208 }
10209
10210 static int
10211 api_sw_interface_tap_dump (vat_main_t * vam)
10212 {
10213   vl_api_sw_interface_tap_dump_t *mp;
10214   f64 timeout;
10215
10216   fformat (vam->ofp, "\n%-16s %s\n", "dev_name", "sw_if_index");
10217   /* Get list of tap interfaces */
10218   M (SW_INTERFACE_TAP_DUMP, sw_interface_tap_dump);
10219   S;
10220
10221   /* Use a control ping for synchronization */
10222   {
10223     vl_api_control_ping_t *mp;
10224     M (CONTROL_PING, control_ping);
10225     S;
10226   }
10227   W;
10228 }
10229
10230 static uword unformat_vxlan_decap_next
10231   (unformat_input_t * input, va_list * args)
10232 {
10233   u32 *result = va_arg (*args, u32 *);
10234   u32 tmp;
10235
10236   if (unformat (input, "l2"))
10237     *result = VXLAN_INPUT_NEXT_L2_INPUT;
10238   else if (unformat (input, "%d", &tmp))
10239     *result = tmp;
10240   else
10241     return 0;
10242   return 1;
10243 }
10244
10245 static int
10246 api_vxlan_add_del_tunnel (vat_main_t * vam)
10247 {
10248   unformat_input_t *line_input = vam->input;
10249   vl_api_vxlan_add_del_tunnel_t *mp;
10250   f64 timeout;
10251   ip46_address_t src, dst;
10252   u8 is_add = 1;
10253   u8 ipv4_set = 0, ipv6_set = 0;
10254   u8 src_set = 0;
10255   u8 dst_set = 0;
10256   u8 grp_set = 0;
10257   u32 mcast_sw_if_index = ~0;
10258   u32 encap_vrf_id = 0;
10259   u32 decap_next_index = ~0;
10260   u32 vni = 0;
10261
10262   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
10263   memset (&src, 0, sizeof src);
10264   memset (&dst, 0, sizeof dst);
10265
10266   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10267     {
10268       if (unformat (line_input, "del"))
10269         is_add = 0;
10270       else
10271         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
10272         {
10273           ipv4_set = 1;
10274           src_set = 1;
10275         }
10276       else
10277         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
10278         {
10279           ipv4_set = 1;
10280           dst_set = 1;
10281         }
10282       else
10283         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
10284         {
10285           ipv6_set = 1;
10286           src_set = 1;
10287         }
10288       else
10289         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
10290         {
10291           ipv6_set = 1;
10292           dst_set = 1;
10293         }
10294       else if (unformat (line_input, "group %U %U",
10295                          unformat_ip4_address, &dst.ip4,
10296                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10297         {
10298           grp_set = dst_set = 1;
10299           ipv4_set = 1;
10300         }
10301       else if (unformat (line_input, "group %U",
10302                          unformat_ip4_address, &dst.ip4))
10303         {
10304           grp_set = dst_set = 1;
10305           ipv4_set = 1;
10306         }
10307       else if (unformat (line_input, "group %U %U",
10308                          unformat_ip6_address, &dst.ip6,
10309                          unformat_sw_if_index, vam, &mcast_sw_if_index))
10310         {
10311           grp_set = dst_set = 1;
10312           ipv6_set = 1;
10313         }
10314       else if (unformat (line_input, "group %U",
10315                          unformat_ip6_address, &dst.ip6))
10316         {
10317           grp_set = dst_set = 1;
10318           ipv6_set = 1;
10319         }
10320       else
10321         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10322         ;
10323       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10324         ;
10325       else if (unformat (line_input, "decap-next %U",
10326                          unformat_vxlan_decap_next, &decap_next_index))
10327         ;
10328       else if (unformat (line_input, "vni %d", &vni))
10329         ;
10330       else
10331         {
10332           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10333           return -99;
10334         }
10335     }
10336
10337   if (src_set == 0)
10338     {
10339       errmsg ("tunnel src address not specified\n");
10340       return -99;
10341     }
10342   if (dst_set == 0)
10343     {
10344       errmsg ("tunnel dst address not specified\n");
10345       return -99;
10346     }
10347
10348   if (grp_set && !ip46_address_is_multicast (&dst))
10349     {
10350       errmsg ("tunnel group address not multicast\n");
10351       return -99;
10352     }
10353   if (grp_set && mcast_sw_if_index == ~0)
10354     {
10355       errmsg ("tunnel nonexistent multicast device\n");
10356       return -99;
10357     }
10358
10359
10360   if (ipv4_set && ipv6_set)
10361     {
10362       errmsg ("both IPv4 and IPv6 addresses specified");
10363       return -99;
10364     }
10365
10366   if ((vni == 0) || (vni >> 24))
10367     {
10368       errmsg ("vni not specified or out of range\n");
10369       return -99;
10370     }
10371
10372   M (VXLAN_ADD_DEL_TUNNEL, vxlan_add_del_tunnel);
10373
10374   if (ipv6_set)
10375     {
10376       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
10377       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
10378     }
10379   else
10380     {
10381       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
10382       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
10383     }
10384   mp->encap_vrf_id = ntohl (encap_vrf_id);
10385   mp->decap_next_index = ntohl (decap_next_index);
10386   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10387   mp->vni = ntohl (vni);
10388   mp->is_add = is_add;
10389   mp->is_ipv6 = ipv6_set;
10390
10391   S;
10392   W;
10393   /* NOTREACHED */
10394   return 0;
10395 }
10396
10397 static void vl_api_vxlan_tunnel_details_t_handler
10398   (vl_api_vxlan_tunnel_details_t * mp)
10399 {
10400   vat_main_t *vam = &vat_main;
10401   ip46_address_t src, dst;
10402
10403   ip46_from_addr_buf (mp->is_ipv6, mp->src_address, &src);
10404   ip46_from_addr_buf (mp->is_ipv6, mp->dst_address, &dst);
10405
10406   fformat (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d\n",
10407            ntohl (mp->sw_if_index),
10408            format_ip46_address, &src, IP46_TYPE_ANY,
10409            format_ip46_address, &dst, IP46_TYPE_ANY,
10410            ntohl (mp->encap_vrf_id),
10411            ntohl (mp->decap_next_index), ntohl (mp->vni),
10412            ntohl (mp->mcast_sw_if_index));
10413 }
10414
10415 static void vl_api_vxlan_tunnel_details_t_handler_json
10416   (vl_api_vxlan_tunnel_details_t * mp)
10417 {
10418   vat_main_t *vam = &vat_main;
10419   vat_json_node_t *node = NULL;
10420
10421   if (VAT_JSON_ARRAY != vam->json_tree.type)
10422     {
10423       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10424       vat_json_init_array (&vam->json_tree);
10425     }
10426   node = vat_json_array_add (&vam->json_tree);
10427
10428   vat_json_init_object (node);
10429   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10430   if (mp->is_ipv6)
10431     {
10432       struct in6_addr ip6;
10433
10434       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
10435       vat_json_object_add_ip6 (node, "src_address", ip6);
10436       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
10437       vat_json_object_add_ip6 (node, "dst_address", ip6);
10438     }
10439   else
10440     {
10441       struct in_addr ip4;
10442
10443       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
10444       vat_json_object_add_ip4 (node, "src_address", ip4);
10445       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
10446       vat_json_object_add_ip4 (node, "dst_address", ip4);
10447     }
10448   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10449   vat_json_object_add_uint (node, "decap_next_index",
10450                             ntohl (mp->decap_next_index));
10451   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10452   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10453   vat_json_object_add_uint (node, "mcast_sw_if_index",
10454                             ntohl (mp->mcast_sw_if_index));
10455 }
10456
10457 static int
10458 api_vxlan_tunnel_dump (vat_main_t * vam)
10459 {
10460   unformat_input_t *i = vam->input;
10461   vl_api_vxlan_tunnel_dump_t *mp;
10462   f64 timeout;
10463   u32 sw_if_index;
10464   u8 sw_if_index_set = 0;
10465
10466   /* Parse args required to build the message */
10467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10468     {
10469       if (unformat (i, "sw_if_index %d", &sw_if_index))
10470         sw_if_index_set = 1;
10471       else
10472         break;
10473     }
10474
10475   if (sw_if_index_set == 0)
10476     {
10477       sw_if_index = ~0;
10478     }
10479
10480   if (!vam->json_output)
10481     {
10482       fformat (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s\n",
10483                "sw_if_index", "src_address", "dst_address",
10484                "encap_vrf_id", "decap_next_index", "vni",
10485                "mcast_sw_if_index");
10486     }
10487
10488   /* Get list of vxlan-tunnel interfaces */
10489   M (VXLAN_TUNNEL_DUMP, vxlan_tunnel_dump);
10490
10491   mp->sw_if_index = htonl (sw_if_index);
10492
10493   S;
10494
10495   /* Use a control ping for synchronization */
10496   {
10497     vl_api_control_ping_t *mp;
10498     M (CONTROL_PING, control_ping);
10499     S;
10500   }
10501   W;
10502 }
10503
10504 static int
10505 api_gre_add_del_tunnel (vat_main_t * vam)
10506 {
10507   unformat_input_t *line_input = vam->input;
10508   vl_api_gre_add_del_tunnel_t *mp;
10509   f64 timeout;
10510   ip4_address_t src4, dst4;
10511   u8 is_add = 1;
10512   u8 teb = 0;
10513   u8 src_set = 0;
10514   u8 dst_set = 0;
10515   u32 outer_fib_id = 0;
10516
10517   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10518     {
10519       if (unformat (line_input, "del"))
10520         is_add = 0;
10521       else if (unformat (line_input, "src %U", unformat_ip4_address, &src4))
10522         src_set = 1;
10523       else if (unformat (line_input, "dst %U", unformat_ip4_address, &dst4))
10524         dst_set = 1;
10525       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
10526         ;
10527       else if (unformat (line_input, "teb"))
10528         teb = 1;
10529       else
10530         {
10531           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
10532           return -99;
10533         }
10534     }
10535
10536   if (src_set == 0)
10537     {
10538       errmsg ("tunnel src address not specified\n");
10539       return -99;
10540     }
10541   if (dst_set == 0)
10542     {
10543       errmsg ("tunnel dst address not specified\n");
10544       return -99;
10545     }
10546
10547
10548   M (GRE_ADD_DEL_TUNNEL, gre_add_del_tunnel);
10549
10550   clib_memcpy (&mp->src_address, &src4, sizeof (src4));
10551   clib_memcpy (&mp->dst_address, &dst4, sizeof (dst4));
10552   mp->outer_fib_id = ntohl (outer_fib_id);
10553   mp->is_add = is_add;
10554   mp->teb = teb;
10555
10556   S;
10557   W;
10558   /* NOTREACHED */
10559   return 0;
10560 }
10561
10562 static void vl_api_gre_tunnel_details_t_handler
10563   (vl_api_gre_tunnel_details_t * mp)
10564 {
10565   vat_main_t *vam = &vat_main;
10566
10567   fformat (vam->ofp, "%11d%15U%15U%6d%14d\n",
10568            ntohl (mp->sw_if_index),
10569            format_ip4_address, &mp->src_address,
10570            format_ip4_address, &mp->dst_address,
10571            mp->teb, ntohl (mp->outer_fib_id));
10572 }
10573
10574 static void vl_api_gre_tunnel_details_t_handler_json
10575   (vl_api_gre_tunnel_details_t * mp)
10576 {
10577   vat_main_t *vam = &vat_main;
10578   vat_json_node_t *node = NULL;
10579   struct in_addr ip4;
10580
10581   if (VAT_JSON_ARRAY != vam->json_tree.type)
10582     {
10583       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10584       vat_json_init_array (&vam->json_tree);
10585     }
10586   node = vat_json_array_add (&vam->json_tree);
10587
10588   vat_json_init_object (node);
10589   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10590   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
10591   vat_json_object_add_ip4 (node, "src_address", ip4);
10592   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
10593   vat_json_object_add_ip4 (node, "dst_address", ip4);
10594   vat_json_object_add_uint (node, "teb", mp->teb);
10595   vat_json_object_add_uint (node, "outer_fib_id", ntohl (mp->outer_fib_id));
10596 }
10597
10598 static int
10599 api_gre_tunnel_dump (vat_main_t * vam)
10600 {
10601   unformat_input_t *i = vam->input;
10602   vl_api_gre_tunnel_dump_t *mp;
10603   f64 timeout;
10604   u32 sw_if_index;
10605   u8 sw_if_index_set = 0;
10606
10607   /* Parse args required to build the message */
10608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10609     {
10610       if (unformat (i, "sw_if_index %d", &sw_if_index))
10611         sw_if_index_set = 1;
10612       else
10613         break;
10614     }
10615
10616   if (sw_if_index_set == 0)
10617     {
10618       sw_if_index = ~0;
10619     }
10620
10621   if (!vam->json_output)
10622     {
10623       fformat (vam->ofp, "%11s%15s%15s%6s%14s\n",
10624                "sw_if_index", "src_address", "dst_address", "teb",
10625                "outer_fib_id");
10626     }
10627
10628   /* Get list of gre-tunnel interfaces */
10629   M (GRE_TUNNEL_DUMP, gre_tunnel_dump);
10630
10631   mp->sw_if_index = htonl (sw_if_index);
10632
10633   S;
10634
10635   /* Use a control ping for synchronization */
10636   {
10637     vl_api_control_ping_t *mp;
10638     M (CONTROL_PING, control_ping);
10639     S;
10640   }
10641   W;
10642 }
10643
10644 static int
10645 api_l2_fib_clear_table (vat_main_t * vam)
10646 {
10647 //  unformat_input_t * i = vam->input;
10648   vl_api_l2_fib_clear_table_t *mp;
10649   f64 timeout;
10650
10651   M (L2_FIB_CLEAR_TABLE, l2_fib_clear_table);
10652
10653   S;
10654   W;
10655   /* NOTREACHED */
10656   return 0;
10657 }
10658
10659 static int
10660 api_l2_interface_efp_filter (vat_main_t * vam)
10661 {
10662   unformat_input_t *i = vam->input;
10663   vl_api_l2_interface_efp_filter_t *mp;
10664   f64 timeout;
10665   u32 sw_if_index;
10666   u8 enable = 1;
10667   u8 sw_if_index_set = 0;
10668
10669   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10670     {
10671       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10672         sw_if_index_set = 1;
10673       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10674         sw_if_index_set = 1;
10675       else if (unformat (i, "enable"))
10676         enable = 1;
10677       else if (unformat (i, "disable"))
10678         enable = 0;
10679       else
10680         {
10681           clib_warning ("parse error '%U'", format_unformat_error, i);
10682           return -99;
10683         }
10684     }
10685
10686   if (sw_if_index_set == 0)
10687     {
10688       errmsg ("missing sw_if_index\n");
10689       return -99;
10690     }
10691
10692   M (L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter);
10693
10694   mp->sw_if_index = ntohl (sw_if_index);
10695   mp->enable_disable = enable;
10696
10697   S;
10698   W;
10699   /* NOTREACHED */
10700   return 0;
10701 }
10702
10703 #define foreach_vtr_op                          \
10704 _("disable",  L2_VTR_DISABLED)                  \
10705 _("push-1",  L2_VTR_PUSH_1)                     \
10706 _("push-2",  L2_VTR_PUSH_2)                     \
10707 _("pop-1",  L2_VTR_POP_1)                       \
10708 _("pop-2",  L2_VTR_POP_2)                       \
10709 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
10710 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
10711 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
10712 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
10713
10714 static int
10715 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
10716 {
10717   unformat_input_t *i = vam->input;
10718   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
10719   f64 timeout;
10720   u32 sw_if_index;
10721   u8 sw_if_index_set = 0;
10722   u8 vtr_op_set = 0;
10723   u32 vtr_op = 0;
10724   u32 push_dot1q = 1;
10725   u32 tag1 = ~0;
10726   u32 tag2 = ~0;
10727
10728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10729     {
10730       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10731         sw_if_index_set = 1;
10732       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10733         sw_if_index_set = 1;
10734       else if (unformat (i, "vtr_op %d", &vtr_op))
10735         vtr_op_set = 1;
10736 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
10737       foreach_vtr_op
10738 #undef _
10739         else if (unformat (i, "push_dot1q %d", &push_dot1q))
10740         ;
10741       else if (unformat (i, "tag1 %d", &tag1))
10742         ;
10743       else if (unformat (i, "tag2 %d", &tag2))
10744         ;
10745       else
10746         {
10747           clib_warning ("parse error '%U'", format_unformat_error, i);
10748           return -99;
10749         }
10750     }
10751
10752   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
10753     {
10754       errmsg ("missing vtr operation or sw_if_index\n");
10755       return -99;
10756     }
10757
10758   M (L2_INTERFACE_VLAN_TAG_REWRITE, l2_interface_vlan_tag_rewrite)
10759     mp->sw_if_index = ntohl (sw_if_index);
10760   mp->vtr_op = ntohl (vtr_op);
10761   mp->push_dot1q = ntohl (push_dot1q);
10762   mp->tag1 = ntohl (tag1);
10763   mp->tag2 = ntohl (tag2);
10764
10765   S;
10766   W;
10767   /* NOTREACHED */
10768   return 0;
10769 }
10770
10771 static int
10772 api_create_vhost_user_if (vat_main_t * vam)
10773 {
10774   unformat_input_t *i = vam->input;
10775   vl_api_create_vhost_user_if_t *mp;
10776   f64 timeout;
10777   u8 *file_name;
10778   u8 is_server = 0;
10779   u8 file_name_set = 0;
10780   u32 custom_dev_instance = ~0;
10781   u8 hwaddr[6];
10782   u8 use_custom_mac = 0;
10783   u8 *tag = 0;
10784
10785   /* Shut up coverity */
10786   memset (hwaddr, 0, sizeof (hwaddr));
10787
10788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10789     {
10790       if (unformat (i, "socket %s", &file_name))
10791         {
10792           file_name_set = 1;
10793         }
10794       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10795         ;
10796       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10797         use_custom_mac = 1;
10798       else if (unformat (i, "server"))
10799         is_server = 1;
10800       else if (unformat (i, "tag %s", &tag))
10801         ;
10802       else
10803         break;
10804     }
10805
10806   if (file_name_set == 0)
10807     {
10808       errmsg ("missing socket file name\n");
10809       return -99;
10810     }
10811
10812   if (vec_len (file_name) > 255)
10813     {
10814       errmsg ("socket file name too long\n");
10815       return -99;
10816     }
10817   vec_add1 (file_name, 0);
10818
10819   M (CREATE_VHOST_USER_IF, create_vhost_user_if);
10820
10821   mp->is_server = is_server;
10822   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10823   vec_free (file_name);
10824   if (custom_dev_instance != ~0)
10825     {
10826       mp->renumber = 1;
10827       mp->custom_dev_instance = ntohl (custom_dev_instance);
10828     }
10829   mp->use_custom_mac = use_custom_mac;
10830   clib_memcpy (mp->mac_address, hwaddr, 6);
10831   if (tag)
10832     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10833   vec_free (tag);
10834
10835   S;
10836   W;
10837   /* NOTREACHED */
10838   return 0;
10839 }
10840
10841 static int
10842 api_modify_vhost_user_if (vat_main_t * vam)
10843 {
10844   unformat_input_t *i = vam->input;
10845   vl_api_modify_vhost_user_if_t *mp;
10846   f64 timeout;
10847   u8 *file_name;
10848   u8 is_server = 0;
10849   u8 file_name_set = 0;
10850   u32 custom_dev_instance = ~0;
10851   u8 sw_if_index_set = 0;
10852   u32 sw_if_index = (u32) ~ 0;
10853
10854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10855     {
10856       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10857         sw_if_index_set = 1;
10858       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10859         sw_if_index_set = 1;
10860       else if (unformat (i, "socket %s", &file_name))
10861         {
10862           file_name_set = 1;
10863         }
10864       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10865         ;
10866       else if (unformat (i, "server"))
10867         is_server = 1;
10868       else
10869         break;
10870     }
10871
10872   if (sw_if_index_set == 0)
10873     {
10874       errmsg ("missing sw_if_index or interface name\n");
10875       return -99;
10876     }
10877
10878   if (file_name_set == 0)
10879     {
10880       errmsg ("missing socket file name\n");
10881       return -99;
10882     }
10883
10884   if (vec_len (file_name) > 255)
10885     {
10886       errmsg ("socket file name too long\n");
10887       return -99;
10888     }
10889   vec_add1 (file_name, 0);
10890
10891   M (MODIFY_VHOST_USER_IF, modify_vhost_user_if);
10892
10893   mp->sw_if_index = ntohl (sw_if_index);
10894   mp->is_server = is_server;
10895   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10896   vec_free (file_name);
10897   if (custom_dev_instance != ~0)
10898     {
10899       mp->renumber = 1;
10900       mp->custom_dev_instance = ntohl (custom_dev_instance);
10901     }
10902
10903   S;
10904   W;
10905   /* NOTREACHED */
10906   return 0;
10907 }
10908
10909 static int
10910 api_delete_vhost_user_if (vat_main_t * vam)
10911 {
10912   unformat_input_t *i = vam->input;
10913   vl_api_delete_vhost_user_if_t *mp;
10914   f64 timeout;
10915   u32 sw_if_index = ~0;
10916   u8 sw_if_index_set = 0;
10917
10918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10919     {
10920       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
10921         sw_if_index_set = 1;
10922       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10923         sw_if_index_set = 1;
10924       else
10925         break;
10926     }
10927
10928   if (sw_if_index_set == 0)
10929     {
10930       errmsg ("missing sw_if_index or interface name\n");
10931       return -99;
10932     }
10933
10934
10935   M (DELETE_VHOST_USER_IF, delete_vhost_user_if);
10936
10937   mp->sw_if_index = ntohl (sw_if_index);
10938
10939   S;
10940   W;
10941   /* NOTREACHED */
10942   return 0;
10943 }
10944
10945 static void vl_api_sw_interface_vhost_user_details_t_handler
10946   (vl_api_sw_interface_vhost_user_details_t * mp)
10947 {
10948   vat_main_t *vam = &vat_main;
10949
10950   fformat (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s\n",
10951            (char *) mp->interface_name,
10952            ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10953            clib_net_to_host_u64 (mp->features), mp->is_server,
10954            ntohl (mp->num_regions), (char *) mp->sock_filename);
10955   fformat (vam->ofp, "    Status: '%s'\n", strerror (ntohl (mp->sock_errno)));
10956 }
10957
10958 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10959   (vl_api_sw_interface_vhost_user_details_t * mp)
10960 {
10961   vat_main_t *vam = &vat_main;
10962   vat_json_node_t *node = NULL;
10963
10964   if (VAT_JSON_ARRAY != vam->json_tree.type)
10965     {
10966       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10967       vat_json_init_array (&vam->json_tree);
10968     }
10969   node = vat_json_array_add (&vam->json_tree);
10970
10971   vat_json_init_object (node);
10972   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10973   vat_json_object_add_string_copy (node, "interface_name",
10974                                    mp->interface_name);
10975   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10976                             ntohl (mp->virtio_net_hdr_sz));
10977   vat_json_object_add_uint (node, "features",
10978                             clib_net_to_host_u64 (mp->features));
10979   vat_json_object_add_uint (node, "is_server", mp->is_server);
10980   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10981   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10982   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10983 }
10984
10985 static int
10986 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10987 {
10988   vl_api_sw_interface_vhost_user_dump_t *mp;
10989   f64 timeout;
10990   fformat (vam->ofp,
10991            "Interface name           idx hdr_sz features server regions filename\n");
10992
10993   /* Get list of vhost-user interfaces */
10994   M (SW_INTERFACE_VHOST_USER_DUMP, sw_interface_vhost_user_dump);
10995   S;
10996
10997   /* Use a control ping for synchronization */
10998   {
10999     vl_api_control_ping_t *mp;
11000     M (CONTROL_PING, control_ping);
11001     S;
11002   }
11003   W;
11004 }
11005
11006 static int
11007 api_show_version (vat_main_t * vam)
11008 {
11009   vl_api_show_version_t *mp;
11010   f64 timeout;
11011
11012   M (SHOW_VERSION, show_version);
11013
11014   S;
11015   W;
11016   /* NOTREACHED */
11017   return 0;
11018 }
11019
11020
11021 static int
11022 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
11023 {
11024   unformat_input_t *line_input = vam->input;
11025   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
11026   f64 timeout;
11027   ip4_address_t local4, remote4;
11028   ip6_address_t local6, remote6;
11029   u8 is_add = 1;
11030   u8 ipv4_set = 0, ipv6_set = 0;
11031   u8 local_set = 0;
11032   u8 remote_set = 0;
11033   u32 encap_vrf_id = 0;
11034   u32 decap_vrf_id = 0;
11035   u8 protocol = ~0;
11036   u32 vni;
11037   u8 vni_set = 0;
11038
11039   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11040     {
11041       if (unformat (line_input, "del"))
11042         is_add = 0;
11043       else if (unformat (line_input, "local %U",
11044                          unformat_ip4_address, &local4))
11045         {
11046           local_set = 1;
11047           ipv4_set = 1;
11048         }
11049       else if (unformat (line_input, "remote %U",
11050                          unformat_ip4_address, &remote4))
11051         {
11052           remote_set = 1;
11053           ipv4_set = 1;
11054         }
11055       else if (unformat (line_input, "local %U",
11056                          unformat_ip6_address, &local6))
11057         {
11058           local_set = 1;
11059           ipv6_set = 1;
11060         }
11061       else if (unformat (line_input, "remote %U",
11062                          unformat_ip6_address, &remote6))
11063         {
11064           remote_set = 1;
11065           ipv6_set = 1;
11066         }
11067       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11068         ;
11069       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
11070         ;
11071       else if (unformat (line_input, "vni %d", &vni))
11072         vni_set = 1;
11073       else if (unformat (line_input, "next-ip4"))
11074         protocol = 1;
11075       else if (unformat (line_input, "next-ip6"))
11076         protocol = 2;
11077       else if (unformat (line_input, "next-ethernet"))
11078         protocol = 3;
11079       else if (unformat (line_input, "next-nsh"))
11080         protocol = 4;
11081       else
11082         {
11083           errmsg ("parse error '%U'\n", format_unformat_error, line_input);
11084           return -99;
11085         }
11086     }
11087
11088   if (local_set == 0)
11089     {
11090       errmsg ("tunnel local address not specified\n");
11091       return -99;
11092     }
11093   if (remote_set == 0)
11094     {
11095       errmsg ("tunnel remote address not specified\n");
11096       return -99;
11097     }
11098   if (ipv4_set && ipv6_set)
11099     {
11100       errmsg ("both IPv4 and IPv6 addresses specified");
11101       return -99;
11102     }
11103
11104   if (vni_set == 0)
11105     {
11106       errmsg ("vni not specified\n");
11107       return -99;
11108     }
11109
11110   M (VXLAN_GPE_ADD_DEL_TUNNEL, vxlan_gpe_add_del_tunnel);
11111
11112
11113   if (ipv6_set)
11114     {
11115       clib_memcpy (&mp->local, &local6, sizeof (local6));
11116       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
11117     }
11118   else
11119     {
11120       clib_memcpy (&mp->local, &local4, sizeof (local4));
11121       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
11122     }
11123
11124   mp->encap_vrf_id = ntohl (encap_vrf_id);
11125   mp->decap_vrf_id = ntohl (decap_vrf_id);
11126   mp->protocol = ntohl (protocol);
11127   mp->vni = ntohl (vni);
11128   mp->is_add = is_add;
11129   mp->is_ipv6 = ipv6_set;
11130
11131   S;
11132   W;
11133   /* NOTREACHED */
11134   return 0;
11135 }
11136
11137 static void vl_api_vxlan_gpe_tunnel_details_t_handler
11138   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11139 {
11140   vat_main_t *vam = &vat_main;
11141
11142   fformat (vam->ofp, "%11d%24U%24U%13d%12d%14d%14d\n",
11143            ntohl (mp->sw_if_index),
11144            format_ip46_address, &(mp->local[0]),
11145            format_ip46_address, &(mp->remote[0]),
11146            ntohl (mp->vni),
11147            ntohl (mp->protocol),
11148            ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
11149 }
11150
11151 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
11152   (vl_api_vxlan_gpe_tunnel_details_t * mp)
11153 {
11154   vat_main_t *vam = &vat_main;
11155   vat_json_node_t *node = NULL;
11156   struct in_addr ip4;
11157   struct in6_addr ip6;
11158
11159   if (VAT_JSON_ARRAY != vam->json_tree.type)
11160     {
11161       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11162       vat_json_init_array (&vam->json_tree);
11163     }
11164   node = vat_json_array_add (&vam->json_tree);
11165
11166   vat_json_init_object (node);
11167   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11168   if (mp->is_ipv6)
11169     {
11170       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
11171       vat_json_object_add_ip6 (node, "local", ip6);
11172       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
11173       vat_json_object_add_ip6 (node, "remote", ip6);
11174     }
11175   else
11176     {
11177       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
11178       vat_json_object_add_ip4 (node, "local", ip4);
11179       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
11180       vat_json_object_add_ip4 (node, "remote", ip4);
11181     }
11182   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11183   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
11184   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11185   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
11186   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11187 }
11188
11189 static int
11190 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
11191 {
11192   unformat_input_t *i = vam->input;
11193   vl_api_vxlan_gpe_tunnel_dump_t *mp;
11194   f64 timeout;
11195   u32 sw_if_index;
11196   u8 sw_if_index_set = 0;
11197
11198   /* Parse args required to build the message */
11199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11200     {
11201       if (unformat (i, "sw_if_index %d", &sw_if_index))
11202         sw_if_index_set = 1;
11203       else
11204         break;
11205     }
11206
11207   if (sw_if_index_set == 0)
11208     {
11209       sw_if_index = ~0;
11210     }
11211
11212   if (!vam->json_output)
11213     {
11214       fformat (vam->ofp, "%11s%24s%24s%13s%15s%14s%14s\n",
11215                "sw_if_index", "local", "remote", "vni",
11216                "protocol", "encap_vrf_id", "decap_vrf_id");
11217     }
11218
11219   /* Get list of vxlan-tunnel interfaces */
11220   M (VXLAN_GPE_TUNNEL_DUMP, vxlan_gpe_tunnel_dump);
11221
11222   mp->sw_if_index = htonl (sw_if_index);
11223
11224   S;
11225
11226   /* Use a control ping for synchronization */
11227   {
11228     vl_api_control_ping_t *mp;
11229     M (CONTROL_PING, control_ping);
11230     S;
11231   }
11232   W;
11233 }
11234
11235 u8 *
11236 format_l2_fib_mac_address (u8 * s, va_list * args)
11237 {
11238   u8 *a = va_arg (*args, u8 *);
11239
11240   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
11241                  a[2], a[3], a[4], a[5], a[6], a[7]);
11242 }
11243
11244 static void vl_api_l2_fib_table_entry_t_handler
11245   (vl_api_l2_fib_table_entry_t * mp)
11246 {
11247   vat_main_t *vam = &vat_main;
11248
11249   fformat (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
11250            "       %d       %d     %d\n",
11251            ntohl (mp->bd_id), format_l2_fib_mac_address, &mp->mac,
11252            ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
11253            mp->bvi_mac);
11254 }
11255
11256 static void vl_api_l2_fib_table_entry_t_handler_json
11257   (vl_api_l2_fib_table_entry_t * mp)
11258 {
11259   vat_main_t *vam = &vat_main;
11260   vat_json_node_t *node = NULL;
11261
11262   if (VAT_JSON_ARRAY != vam->json_tree.type)
11263     {
11264       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11265       vat_json_init_array (&vam->json_tree);
11266     }
11267   node = vat_json_array_add (&vam->json_tree);
11268
11269   vat_json_init_object (node);
11270   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
11271   vat_json_object_add_uint (node, "mac", clib_net_to_host_u64 (mp->mac));
11272   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11273   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
11274   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
11275   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
11276 }
11277
11278 static int
11279 api_l2_fib_table_dump (vat_main_t * vam)
11280 {
11281   unformat_input_t *i = vam->input;
11282   vl_api_l2_fib_table_dump_t *mp;
11283   f64 timeout;
11284   u32 bd_id;
11285   u8 bd_id_set = 0;
11286
11287   /* Parse args required to build the message */
11288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11289     {
11290       if (unformat (i, "bd_id %d", &bd_id))
11291         bd_id_set = 1;
11292       else
11293         break;
11294     }
11295
11296   if (bd_id_set == 0)
11297     {
11298       errmsg ("missing bridge domain\n");
11299       return -99;
11300     }
11301
11302   fformat (vam->ofp,
11303            "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI\n");
11304
11305   /* Get list of l2 fib entries */
11306   M (L2_FIB_TABLE_DUMP, l2_fib_table_dump);
11307
11308   mp->bd_id = ntohl (bd_id);
11309   S;
11310
11311   /* Use a control ping for synchronization */
11312   {
11313     vl_api_control_ping_t *mp;
11314     M (CONTROL_PING, control_ping);
11315     S;
11316   }
11317   W;
11318 }
11319
11320
11321 static int
11322 api_interface_name_renumber (vat_main_t * vam)
11323 {
11324   unformat_input_t *line_input = vam->input;
11325   vl_api_interface_name_renumber_t *mp;
11326   u32 sw_if_index = ~0;
11327   f64 timeout;
11328   u32 new_show_dev_instance = ~0;
11329
11330   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11331     {
11332       if (unformat (line_input, "%U", unformat_sw_if_index, vam,
11333                     &sw_if_index))
11334         ;
11335       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11336         ;
11337       else if (unformat (line_input, "new_show_dev_instance %d",
11338                          &new_show_dev_instance))
11339         ;
11340       else
11341         break;
11342     }
11343
11344   if (sw_if_index == ~0)
11345     {
11346       errmsg ("missing interface name or sw_if_index\n");
11347       return -99;
11348     }
11349
11350   if (new_show_dev_instance == ~0)
11351     {
11352       errmsg ("missing new_show_dev_instance\n");
11353       return -99;
11354     }
11355
11356   M (INTERFACE_NAME_RENUMBER, interface_name_renumber);
11357
11358   mp->sw_if_index = ntohl (sw_if_index);
11359   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
11360
11361   S;
11362   W;
11363 }
11364
11365 static int
11366 api_want_ip4_arp_events (vat_main_t * vam)
11367 {
11368   unformat_input_t *line_input = vam->input;
11369   vl_api_want_ip4_arp_events_t *mp;
11370   f64 timeout;
11371   ip4_address_t address;
11372   int address_set = 0;
11373   u32 enable_disable = 1;
11374
11375   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11376     {
11377       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
11378         address_set = 1;
11379       else if (unformat (line_input, "del"))
11380         enable_disable = 0;
11381       else
11382         break;
11383     }
11384
11385   if (address_set == 0)
11386     {
11387       errmsg ("missing addresses\n");
11388       return -99;
11389     }
11390
11391   M (WANT_IP4_ARP_EVENTS, want_ip4_arp_events);
11392   mp->enable_disable = enable_disable;
11393   mp->pid = getpid ();
11394   mp->address = address.as_u32;
11395
11396   S;
11397   W;
11398 }
11399
11400 static int
11401 api_want_ip6_nd_events (vat_main_t * vam)
11402 {
11403   unformat_input_t *line_input = vam->input;
11404   vl_api_want_ip6_nd_events_t *mp;
11405   f64 timeout;
11406   ip6_address_t address;
11407   int address_set = 0;
11408   u32 enable_disable = 1;
11409
11410   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11411     {
11412       if (unformat (line_input, "address %U", unformat_ip6_address, &address))
11413         address_set = 1;
11414       else if (unformat (line_input, "del"))
11415         enable_disable = 0;
11416       else
11417         break;
11418     }
11419
11420   if (address_set == 0)
11421     {
11422       errmsg ("missing addresses\n");
11423       return -99;
11424     }
11425
11426   M (WANT_IP6_ND_EVENTS, want_ip6_nd_events);
11427   mp->enable_disable = enable_disable;
11428   mp->pid = getpid ();
11429   clib_memcpy (mp->address, &address, sizeof (ip6_address_t));
11430
11431   S;
11432   W;
11433 }
11434
11435 static int
11436 api_input_acl_set_interface (vat_main_t * vam)
11437 {
11438   unformat_input_t *i = vam->input;
11439   vl_api_input_acl_set_interface_t *mp;
11440   f64 timeout;
11441   u32 sw_if_index;
11442   int sw_if_index_set;
11443   u32 ip4_table_index = ~0;
11444   u32 ip6_table_index = ~0;
11445   u32 l2_table_index = ~0;
11446   u8 is_add = 1;
11447
11448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11449     {
11450       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11451         sw_if_index_set = 1;
11452       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11453         sw_if_index_set = 1;
11454       else if (unformat (i, "del"))
11455         is_add = 0;
11456       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11457         ;
11458       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11459         ;
11460       else if (unformat (i, "l2-table %d", &l2_table_index))
11461         ;
11462       else
11463         {
11464           clib_warning ("parse error '%U'", format_unformat_error, i);
11465           return -99;
11466         }
11467     }
11468
11469   if (sw_if_index_set == 0)
11470     {
11471       errmsg ("missing interface name or sw_if_index\n");
11472       return -99;
11473     }
11474
11475   M (INPUT_ACL_SET_INTERFACE, input_acl_set_interface);
11476
11477   mp->sw_if_index = ntohl (sw_if_index);
11478   mp->ip4_table_index = ntohl (ip4_table_index);
11479   mp->ip6_table_index = ntohl (ip6_table_index);
11480   mp->l2_table_index = ntohl (l2_table_index);
11481   mp->is_add = is_add;
11482
11483   S;
11484   W;
11485   /* NOTREACHED */
11486   return 0;
11487 }
11488
11489 static int
11490 api_ip_address_dump (vat_main_t * vam)
11491 {
11492   unformat_input_t *i = vam->input;
11493   vl_api_ip_address_dump_t *mp;
11494   u32 sw_if_index = ~0;
11495   u8 sw_if_index_set = 0;
11496   u8 ipv4_set = 0;
11497   u8 ipv6_set = 0;
11498   f64 timeout;
11499
11500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11501     {
11502       if (unformat (i, "sw_if_index %d", &sw_if_index))
11503         sw_if_index_set = 1;
11504       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11505         sw_if_index_set = 1;
11506       else if (unformat (i, "ipv4"))
11507         ipv4_set = 1;
11508       else if (unformat (i, "ipv6"))
11509         ipv6_set = 1;
11510       else
11511         break;
11512     }
11513
11514   if (ipv4_set && ipv6_set)
11515     {
11516       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11517       return -99;
11518     }
11519
11520   if ((!ipv4_set) && (!ipv6_set))
11521     {
11522       errmsg ("no ipv4 nor ipv6 flag set\n");
11523       return -99;
11524     }
11525
11526   if (sw_if_index_set == 0)
11527     {
11528       errmsg ("missing interface name or sw_if_index\n");
11529       return -99;
11530     }
11531
11532   vam->current_sw_if_index = sw_if_index;
11533   vam->is_ipv6 = ipv6_set;
11534
11535   M (IP_ADDRESS_DUMP, ip_address_dump);
11536   mp->sw_if_index = ntohl (sw_if_index);
11537   mp->is_ipv6 = ipv6_set;
11538   S;
11539
11540   /* Use a control ping for synchronization */
11541   {
11542     vl_api_control_ping_t *mp;
11543     M (CONTROL_PING, control_ping);
11544     S;
11545   }
11546   W;
11547 }
11548
11549 static int
11550 api_ip_dump (vat_main_t * vam)
11551 {
11552   vl_api_ip_dump_t *mp;
11553   unformat_input_t *in = vam->input;
11554   int ipv4_set = 0;
11555   int ipv6_set = 0;
11556   int is_ipv6;
11557   f64 timeout;
11558   int i;
11559
11560   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
11561     {
11562       if (unformat (in, "ipv4"))
11563         ipv4_set = 1;
11564       else if (unformat (in, "ipv6"))
11565         ipv6_set = 1;
11566       else
11567         break;
11568     }
11569
11570   if (ipv4_set && ipv6_set)
11571     {
11572       errmsg ("ipv4 and ipv6 flags cannot be both set\n");
11573       return -99;
11574     }
11575
11576   if ((!ipv4_set) && (!ipv6_set))
11577     {
11578       errmsg ("no ipv4 nor ipv6 flag set\n");
11579       return -99;
11580     }
11581
11582   is_ipv6 = ipv6_set;
11583   vam->is_ipv6 = is_ipv6;
11584
11585   /* free old data */
11586   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
11587     {
11588       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
11589     }
11590   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
11591
11592   M (IP_DUMP, ip_dump);
11593   mp->is_ipv6 = ipv6_set;
11594   S;
11595
11596   /* Use a control ping for synchronization */
11597   {
11598     vl_api_control_ping_t *mp;
11599     M (CONTROL_PING, control_ping);
11600     S;
11601   }
11602   W;
11603 }
11604
11605 static int
11606 api_ipsec_spd_add_del (vat_main_t * vam)
11607 {
11608   unformat_input_t *i = vam->input;
11609   vl_api_ipsec_spd_add_del_t *mp;
11610   f64 timeout;
11611   u32 spd_id = ~0;
11612   u8 is_add = 1;
11613
11614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11615     {
11616       if (unformat (i, "spd_id %d", &spd_id))
11617         ;
11618       else if (unformat (i, "del"))
11619         is_add = 0;
11620       else
11621         {
11622           clib_warning ("parse error '%U'", format_unformat_error, i);
11623           return -99;
11624         }
11625     }
11626   if (spd_id == ~0)
11627     {
11628       errmsg ("spd_id must be set\n");
11629       return -99;
11630     }
11631
11632   M (IPSEC_SPD_ADD_DEL, ipsec_spd_add_del);
11633
11634   mp->spd_id = ntohl (spd_id);
11635   mp->is_add = is_add;
11636
11637   S;
11638   W;
11639   /* NOTREACHED */
11640   return 0;
11641 }
11642
11643 static int
11644 api_ipsec_interface_add_del_spd (vat_main_t * vam)
11645 {
11646   unformat_input_t *i = vam->input;
11647   vl_api_ipsec_interface_add_del_spd_t *mp;
11648   f64 timeout;
11649   u32 sw_if_index;
11650   u8 sw_if_index_set = 0;
11651   u32 spd_id = (u32) ~ 0;
11652   u8 is_add = 1;
11653
11654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11655     {
11656       if (unformat (i, "del"))
11657         is_add = 0;
11658       else if (unformat (i, "spd_id %d", &spd_id))
11659         ;
11660       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
11661         sw_if_index_set = 1;
11662       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11663         sw_if_index_set = 1;
11664       else
11665         {
11666           clib_warning ("parse error '%U'", format_unformat_error, i);
11667           return -99;
11668         }
11669
11670     }
11671
11672   if (spd_id == (u32) ~ 0)
11673     {
11674       errmsg ("spd_id must be set\n");
11675       return -99;
11676     }
11677
11678   if (sw_if_index_set == 0)
11679     {
11680       errmsg ("missing interface name or sw_if_index\n");
11681       return -99;
11682     }
11683
11684   M (IPSEC_INTERFACE_ADD_DEL_SPD, ipsec_interface_add_del_spd);
11685
11686   mp->spd_id = ntohl (spd_id);
11687   mp->sw_if_index = ntohl (sw_if_index);
11688   mp->is_add = is_add;
11689
11690   S;
11691   W;
11692   /* NOTREACHED */
11693   return 0;
11694 }
11695
11696 static int
11697 api_ipsec_spd_add_del_entry (vat_main_t * vam)
11698 {
11699   unformat_input_t *i = vam->input;
11700   vl_api_ipsec_spd_add_del_entry_t *mp;
11701   f64 timeout;
11702   u8 is_add = 1, is_outbound = 0, is_ipv6 = 0, is_ip_any = 1;
11703   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
11704   i32 priority = 0;
11705   u32 rport_start = 0, rport_stop = (u32) ~ 0;
11706   u32 lport_start = 0, lport_stop = (u32) ~ 0;
11707   ip4_address_t laddr4_start, laddr4_stop, raddr4_start, raddr4_stop;
11708   ip6_address_t laddr6_start, laddr6_stop, raddr6_start, raddr6_stop;
11709
11710   laddr4_start.as_u32 = raddr4_start.as_u32 = 0;
11711   laddr4_stop.as_u32 = raddr4_stop.as_u32 = (u32) ~ 0;
11712   laddr6_start.as_u64[0] = raddr6_start.as_u64[0] = 0;
11713   laddr6_start.as_u64[1] = raddr6_start.as_u64[1] = 0;
11714   laddr6_stop.as_u64[0] = raddr6_stop.as_u64[0] = (u64) ~ 0;
11715   laddr6_stop.as_u64[1] = raddr6_stop.as_u64[1] = (u64) ~ 0;
11716
11717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11718     {
11719       if (unformat (i, "del"))
11720         is_add = 0;
11721       if (unformat (i, "outbound"))
11722         is_outbound = 1;
11723       if (unformat (i, "inbound"))
11724         is_outbound = 0;
11725       else if (unformat (i, "spd_id %d", &spd_id))
11726         ;
11727       else if (unformat (i, "sa_id %d", &sa_id))
11728         ;
11729       else if (unformat (i, "priority %d", &priority))
11730         ;
11731       else if (unformat (i, "protocol %d", &protocol))
11732         ;
11733       else if (unformat (i, "lport_start %d", &lport_start))
11734         ;
11735       else if (unformat (i, "lport_stop %d", &lport_stop))
11736         ;
11737       else if (unformat (i, "rport_start %d", &rport_start))
11738         ;
11739       else if (unformat (i, "rport_stop %d", &rport_stop))
11740         ;
11741       else
11742         if (unformat
11743             (i, "laddr_start %U", unformat_ip4_address, &laddr4_start))
11744         {
11745           is_ipv6 = 0;
11746           is_ip_any = 0;
11747         }
11748       else
11749         if (unformat (i, "laddr_stop %U", unformat_ip4_address, &laddr4_stop))
11750         {
11751           is_ipv6 = 0;
11752           is_ip_any = 0;
11753         }
11754       else
11755         if (unformat
11756             (i, "raddr_start %U", unformat_ip4_address, &raddr4_start))
11757         {
11758           is_ipv6 = 0;
11759           is_ip_any = 0;
11760         }
11761       else
11762         if (unformat (i, "raddr_stop %U", unformat_ip4_address, &raddr4_stop))
11763         {
11764           is_ipv6 = 0;
11765           is_ip_any = 0;
11766         }
11767       else
11768         if (unformat
11769             (i, "laddr_start %U", unformat_ip6_address, &laddr6_start))
11770         {
11771           is_ipv6 = 1;
11772           is_ip_any = 0;
11773         }
11774       else
11775         if (unformat (i, "laddr_stop %U", unformat_ip6_address, &laddr6_stop))
11776         {
11777           is_ipv6 = 1;
11778           is_ip_any = 0;
11779         }
11780       else
11781         if (unformat
11782             (i, "raddr_start %U", unformat_ip6_address, &raddr6_start))
11783         {
11784           is_ipv6 = 1;
11785           is_ip_any = 0;
11786         }
11787       else
11788         if (unformat (i, "raddr_stop %U", unformat_ip6_address, &raddr6_stop))
11789         {
11790           is_ipv6 = 1;
11791           is_ip_any = 0;
11792         }
11793       else
11794         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11795         {
11796           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11797             {
11798               clib_warning ("unsupported action: 'resolve'");
11799               return -99;
11800             }
11801         }
11802       else
11803         {
11804           clib_warning ("parse error '%U'", format_unformat_error, i);
11805           return -99;
11806         }
11807
11808     }
11809
11810   M (IPSEC_SPD_ADD_DEL_ENTRY, ipsec_spd_add_del_entry);
11811
11812   mp->spd_id = ntohl (spd_id);
11813   mp->priority = ntohl (priority);
11814   mp->is_outbound = is_outbound;
11815
11816   mp->is_ipv6 = is_ipv6;
11817   if (is_ipv6 || is_ip_any)
11818     {
11819       clib_memcpy (mp->remote_address_start, &raddr6_start,
11820                    sizeof (ip6_address_t));
11821       clib_memcpy (mp->remote_address_stop, &raddr6_stop,
11822                    sizeof (ip6_address_t));
11823       clib_memcpy (mp->local_address_start, &laddr6_start,
11824                    sizeof (ip6_address_t));
11825       clib_memcpy (mp->local_address_stop, &laddr6_stop,
11826                    sizeof (ip6_address_t));
11827     }
11828   else
11829     {
11830       clib_memcpy (mp->remote_address_start, &raddr4_start,
11831                    sizeof (ip4_address_t));
11832       clib_memcpy (mp->remote_address_stop, &raddr4_stop,
11833                    sizeof (ip4_address_t));
11834       clib_memcpy (mp->local_address_start, &laddr4_start,
11835                    sizeof (ip4_address_t));
11836       clib_memcpy (mp->local_address_stop, &laddr4_stop,
11837                    sizeof (ip4_address_t));
11838     }
11839   mp->protocol = (u8) protocol;
11840   mp->local_port_start = ntohs ((u16) lport_start);
11841   mp->local_port_stop = ntohs ((u16) lport_stop);
11842   mp->remote_port_start = ntohs ((u16) rport_start);
11843   mp->remote_port_stop = ntohs ((u16) rport_stop);
11844   mp->policy = (u8) policy;
11845   mp->sa_id = ntohl (sa_id);
11846   mp->is_add = is_add;
11847   mp->is_ip_any = is_ip_any;
11848   S;
11849   W;
11850   /* NOTREACHED */
11851   return 0;
11852 }
11853
11854 static int
11855 api_ipsec_sad_add_del_entry (vat_main_t * vam)
11856 {
11857   unformat_input_t *i = vam->input;
11858   vl_api_ipsec_sad_add_del_entry_t *mp;
11859   f64 timeout;
11860   u32 sad_id = 0, spi = 0;
11861   u8 *ck = 0, *ik = 0;
11862   u8 is_add = 1;
11863
11864   u8 protocol = IPSEC_PROTOCOL_AH;
11865   u8 is_tunnel = 0, is_tunnel_ipv6 = 0;
11866   u32 crypto_alg = 0, integ_alg = 0;
11867   ip4_address_t tun_src4;
11868   ip4_address_t tun_dst4;
11869   ip6_address_t tun_src6;
11870   ip6_address_t tun_dst6;
11871
11872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11873     {
11874       if (unformat (i, "del"))
11875         is_add = 0;
11876       else if (unformat (i, "sad_id %d", &sad_id))
11877         ;
11878       else if (unformat (i, "spi %d", &spi))
11879         ;
11880       else if (unformat (i, "esp"))
11881         protocol = IPSEC_PROTOCOL_ESP;
11882       else if (unformat (i, "tunnel_src %U", unformat_ip4_address, &tun_src4))
11883         {
11884           is_tunnel = 1;
11885           is_tunnel_ipv6 = 0;
11886         }
11887       else if (unformat (i, "tunnel_dst %U", unformat_ip4_address, &tun_dst4))
11888         {
11889           is_tunnel = 1;
11890           is_tunnel_ipv6 = 0;
11891         }
11892       else if (unformat (i, "tunnel_src %U", unformat_ip6_address, &tun_src6))
11893         {
11894           is_tunnel = 1;
11895           is_tunnel_ipv6 = 1;
11896         }
11897       else if (unformat (i, "tunnel_dst %U", unformat_ip6_address, &tun_dst6))
11898         {
11899           is_tunnel = 1;
11900           is_tunnel_ipv6 = 1;
11901         }
11902       else
11903         if (unformat
11904             (i, "crypto_alg %U", unformat_ipsec_crypto_alg, &crypto_alg))
11905         {
11906           if (crypto_alg < IPSEC_CRYPTO_ALG_AES_CBC_128 ||
11907               crypto_alg >= IPSEC_CRYPTO_N_ALG)
11908             {
11909               clib_warning ("unsupported crypto-alg: '%U'",
11910                             format_ipsec_crypto_alg, crypto_alg);
11911               return -99;
11912             }
11913         }
11914       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11915         ;
11916       else
11917         if (unformat
11918             (i, "integ_alg %U", unformat_ipsec_integ_alg, &integ_alg))
11919         {
11920 #if DPDK_CRYPTO==1
11921           if (integ_alg < IPSEC_INTEG_ALG_NONE ||
11922 #else
11923           if (integ_alg < IPSEC_INTEG_ALG_SHA1_96 ||
11924 #endif
11925               integ_alg >= IPSEC_INTEG_N_ALG)
11926             {
11927               clib_warning ("unsupported integ-alg: '%U'",
11928                             format_ipsec_integ_alg, integ_alg);
11929               return -99;
11930             }
11931         }
11932       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11933         ;
11934       else
11935         {
11936           clib_warning ("parse error '%U'", format_unformat_error, i);
11937           return -99;
11938         }
11939
11940     }
11941
11942 #if DPDK_CRYPTO==1
11943   /*Special cases, aes-gcm-128 encryption */
11944   if (crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
11945     {
11946       if (integ_alg != IPSEC_INTEG_ALG_NONE
11947           && integ_alg != IPSEC_INTEG_ALG_AES_GCM_128)
11948         {
11949           clib_warning
11950             ("unsupported: aes-gcm-128 crypto-alg needs none as integ-alg");
11951           return -99;
11952         }
11953       else                      /*set integ-alg internally to aes-gcm-128 */
11954         integ_alg = IPSEC_INTEG_ALG_AES_GCM_128;
11955     }
11956   else if (integ_alg == IPSEC_INTEG_ALG_AES_GCM_128)
11957     {
11958       clib_warning ("unsupported integ-alg: aes-gcm-128");
11959       return -99;
11960     }
11961   else if (integ_alg == IPSEC_INTEG_ALG_NONE)
11962     {
11963       clib_warning ("unsupported integ-alg: none");
11964       return -99;
11965     }
11966 #endif
11967
11968
11969   M (IPSEC_SAD_ADD_DEL_ENTRY, ipsec_sad_add_del_entry);
11970
11971   mp->sad_id = ntohl (sad_id);
11972   mp->is_add = is_add;
11973   mp->protocol = protocol;
11974   mp->spi = ntohl (spi);
11975   mp->is_tunnel = is_tunnel;
11976   mp->is_tunnel_ipv6 = is_tunnel_ipv6;
11977   mp->crypto_algorithm = crypto_alg;
11978   mp->integrity_algorithm = integ_alg;
11979   mp->crypto_key_length = vec_len (ck);
11980   mp->integrity_key_length = vec_len (ik);
11981
11982   if (mp->crypto_key_length > sizeof (mp->crypto_key))
11983     mp->crypto_key_length = sizeof (mp->crypto_key);
11984
11985   if (mp->integrity_key_length > sizeof (mp->integrity_key))
11986     mp->integrity_key_length = sizeof (mp->integrity_key);
11987
11988   if (ck)
11989     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
11990   if (ik)
11991     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
11992
11993   if (is_tunnel)
11994     {
11995       if (is_tunnel_ipv6)
11996         {
11997           clib_memcpy (mp->tunnel_src_address, &tun_src6,
11998                        sizeof (ip6_address_t));
11999           clib_memcpy (mp->tunnel_dst_address, &tun_dst6,
12000                        sizeof (ip6_address_t));
12001         }
12002       else
12003         {
12004           clib_memcpy (mp->tunnel_src_address, &tun_src4,
12005                        sizeof (ip4_address_t));
12006           clib_memcpy (mp->tunnel_dst_address, &tun_dst4,
12007                        sizeof (ip4_address_t));
12008         }
12009     }
12010
12011   S;
12012   W;
12013   /* NOTREACHED */
12014   return 0;
12015 }
12016
12017 static int
12018 api_ipsec_sa_set_key (vat_main_t * vam)
12019 {
12020   unformat_input_t *i = vam->input;
12021   vl_api_ipsec_sa_set_key_t *mp;
12022   f64 timeout;
12023   u32 sa_id;
12024   u8 *ck = 0, *ik = 0;
12025
12026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12027     {
12028       if (unformat (i, "sa_id %d", &sa_id))
12029         ;
12030       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
12031         ;
12032       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
12033         ;
12034       else
12035         {
12036           clib_warning ("parse error '%U'", format_unformat_error, i);
12037           return -99;
12038         }
12039     }
12040
12041   M (IPSEC_SA_SET_KEY, ipsec_set_sa_key);
12042
12043   mp->sa_id = ntohl (sa_id);
12044   mp->crypto_key_length = vec_len (ck);
12045   mp->integrity_key_length = vec_len (ik);
12046
12047   if (mp->crypto_key_length > sizeof (mp->crypto_key))
12048     mp->crypto_key_length = sizeof (mp->crypto_key);
12049
12050   if (mp->integrity_key_length > sizeof (mp->integrity_key))
12051     mp->integrity_key_length = sizeof (mp->integrity_key);
12052
12053   if (ck)
12054     clib_memcpy (mp->crypto_key, ck, mp->crypto_key_length);
12055   if (ik)
12056     clib_memcpy (mp->integrity_key, ik, mp->integrity_key_length);
12057
12058   S;
12059   W;
12060   /* NOTREACHED */
12061   return 0;
12062 }
12063
12064 static int
12065 api_ikev2_profile_add_del (vat_main_t * vam)
12066 {
12067   unformat_input_t *i = vam->input;
12068   vl_api_ikev2_profile_add_del_t *mp;
12069   f64 timeout;
12070   u8 is_add = 1;
12071   u8 *name = 0;
12072
12073   const char *valid_chars = "a-zA-Z0-9_";
12074
12075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12076     {
12077       if (unformat (i, "del"))
12078         is_add = 0;
12079       else if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12080         vec_add1 (name, 0);
12081       else
12082         {
12083           errmsg ("parse error '%U'", format_unformat_error, i);
12084           return -99;
12085         }
12086     }
12087
12088   if (!vec_len (name))
12089     {
12090       errmsg ("profile name must be specified");
12091       return -99;
12092     }
12093
12094   if (vec_len (name) > 64)
12095     {
12096       errmsg ("profile name too long");
12097       return -99;
12098     }
12099
12100   M (IKEV2_PROFILE_ADD_DEL, ikev2_profile_add_del);
12101
12102   clib_memcpy (mp->name, name, vec_len (name));
12103   mp->is_add = is_add;
12104   vec_free (name);
12105
12106   S;
12107   W;
12108   /* NOTREACHED */
12109   return 0;
12110 }
12111
12112 static int
12113 api_ikev2_profile_set_auth (vat_main_t * vam)
12114 {
12115   unformat_input_t *i = vam->input;
12116   vl_api_ikev2_profile_set_auth_t *mp;
12117   f64 timeout;
12118   u8 *name = 0;
12119   u8 *data = 0;
12120   u32 auth_method = 0;
12121   u8 is_hex = 0;
12122
12123   const char *valid_chars = "a-zA-Z0-9_";
12124
12125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12126     {
12127       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12128         vec_add1 (name, 0);
12129       else if (unformat (i, "auth_method %U",
12130                          unformat_ikev2_auth_method, &auth_method))
12131         ;
12132       else if (unformat (i, "auth_data 0x%U", unformat_hex_string, &data))
12133         is_hex = 1;
12134       else if (unformat (i, "auth_data %v", &data))
12135         ;
12136       else
12137         {
12138           errmsg ("parse error '%U'", format_unformat_error, i);
12139           return -99;
12140         }
12141     }
12142
12143   if (!vec_len (name))
12144     {
12145       errmsg ("profile name must be specified");
12146       return -99;
12147     }
12148
12149   if (vec_len (name) > 64)
12150     {
12151       errmsg ("profile name too long");
12152       return -99;
12153     }
12154
12155   if (!vec_len (data))
12156     {
12157       errmsg ("auth_data must be specified");
12158       return -99;
12159     }
12160
12161   if (!auth_method)
12162     {
12163       errmsg ("auth_method must be specified");
12164       return -99;
12165     }
12166
12167   M (IKEV2_PROFILE_SET_AUTH, ikev2_profile_set_auth);
12168
12169   mp->is_hex = is_hex;
12170   mp->auth_method = (u8) auth_method;
12171   mp->data_len = vec_len (data);
12172   clib_memcpy (mp->name, name, vec_len (name));
12173   clib_memcpy (mp->data, data, vec_len (data));
12174   vec_free (name);
12175   vec_free (data);
12176
12177   S;
12178   W;
12179   /* NOTREACHED */
12180   return 0;
12181 }
12182
12183 static int
12184 api_ikev2_profile_set_id (vat_main_t * vam)
12185 {
12186   unformat_input_t *i = vam->input;
12187   vl_api_ikev2_profile_set_id_t *mp;
12188   f64 timeout;
12189   u8 *name = 0;
12190   u8 *data = 0;
12191   u8 is_local = 0;
12192   u32 id_type = 0;
12193   ip4_address_t ip4;
12194
12195   const char *valid_chars = "a-zA-Z0-9_";
12196
12197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12198     {
12199       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12200         vec_add1 (name, 0);
12201       else if (unformat (i, "id_type %U", unformat_ikev2_id_type, &id_type))
12202         ;
12203       else if (unformat (i, "id_data %U", unformat_ip4_address, &ip4))
12204         {
12205           data = vec_new (u8, 4);
12206           clib_memcpy (data, ip4.as_u8, 4);
12207         }
12208       else if (unformat (i, "id_data 0x%U", unformat_hex_string, &data))
12209         ;
12210       else if (unformat (i, "id_data %v", &data))
12211         ;
12212       else if (unformat (i, "local"))
12213         is_local = 1;
12214       else if (unformat (i, "remote"))
12215         is_local = 0;
12216       else
12217         {
12218           errmsg ("parse error '%U'", format_unformat_error, i);
12219           return -99;
12220         }
12221     }
12222
12223   if (!vec_len (name))
12224     {
12225       errmsg ("profile name must be specified");
12226       return -99;
12227     }
12228
12229   if (vec_len (name) > 64)
12230     {
12231       errmsg ("profile name too long");
12232       return -99;
12233     }
12234
12235   if (!vec_len (data))
12236     {
12237       errmsg ("id_data must be specified");
12238       return -99;
12239     }
12240
12241   if (!id_type)
12242     {
12243       errmsg ("id_type must be specified");
12244       return -99;
12245     }
12246
12247   M (IKEV2_PROFILE_SET_ID, ikev2_profile_set_id);
12248
12249   mp->is_local = is_local;
12250   mp->id_type = (u8) id_type;
12251   mp->data_len = vec_len (data);
12252   clib_memcpy (mp->name, name, vec_len (name));
12253   clib_memcpy (mp->data, data, vec_len (data));
12254   vec_free (name);
12255   vec_free (data);
12256
12257   S;
12258   W;
12259   /* NOTREACHED */
12260   return 0;
12261 }
12262
12263 static int
12264 api_ikev2_profile_set_ts (vat_main_t * vam)
12265 {
12266   unformat_input_t *i = vam->input;
12267   vl_api_ikev2_profile_set_ts_t *mp;
12268   f64 timeout;
12269   u8 *name = 0;
12270   u8 is_local = 0;
12271   u32 proto = 0, start_port = 0, end_port = (u32) ~ 0;
12272   ip4_address_t start_addr, end_addr;
12273
12274   const char *valid_chars = "a-zA-Z0-9_";
12275
12276   start_addr.as_u32 = 0;
12277   end_addr.as_u32 = (u32) ~ 0;
12278
12279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12280     {
12281       if (unformat (i, "name %U", unformat_token, valid_chars, &name))
12282         vec_add1 (name, 0);
12283       else if (unformat (i, "protocol %d", &proto))
12284         ;
12285       else if (unformat (i, "start_port %d", &start_port))
12286         ;
12287       else if (unformat (i, "end_port %d", &end_port))
12288         ;
12289       else
12290         if (unformat (i, "start_addr %U", unformat_ip4_address, &start_addr))
12291         ;
12292       else if (unformat (i, "end_addr %U", unformat_ip4_address, &end_addr))
12293         ;
12294       else if (unformat (i, "local"))
12295         is_local = 1;
12296       else if (unformat (i, "remote"))
12297         is_local = 0;
12298       else
12299         {
12300           errmsg ("parse error '%U'", format_unformat_error, i);
12301           return -99;
12302         }
12303     }
12304
12305   if (!vec_len (name))
12306     {
12307       errmsg ("profile name must be specified");
12308       return -99;
12309     }
12310
12311   if (vec_len (name) > 64)
12312     {
12313       errmsg ("profile name too long");
12314       return -99;
12315     }
12316
12317   M (IKEV2_PROFILE_SET_TS, ikev2_profile_set_ts);
12318
12319   mp->is_local = is_local;
12320   mp->proto = (u8) proto;
12321   mp->start_port = (u16) start_port;
12322   mp->end_port = (u16) end_port;
12323   mp->start_addr = start_addr.as_u32;
12324   mp->end_addr = end_addr.as_u32;
12325   clib_memcpy (mp->name, name, vec_len (name));
12326   vec_free (name);
12327
12328   S;
12329   W;
12330   /* NOTREACHED */
12331   return 0;
12332 }
12333
12334 static int
12335 api_ikev2_set_local_key (vat_main_t * vam)
12336 {
12337   unformat_input_t *i = vam->input;
12338   vl_api_ikev2_set_local_key_t *mp;
12339   f64 timeout;
12340   u8 *file = 0;
12341
12342   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12343     {
12344       if (unformat (i, "file %v", &file))
12345         vec_add1 (file, 0);
12346       else
12347         {
12348           errmsg ("parse error '%U'", format_unformat_error, i);
12349           return -99;
12350         }
12351     }
12352
12353   if (!vec_len (file))
12354     {
12355       errmsg ("RSA key file must be specified");
12356       return -99;
12357     }
12358
12359   if (vec_len (file) > 256)
12360     {
12361       errmsg ("file name too long");
12362       return -99;
12363     }
12364
12365   M (IKEV2_SET_LOCAL_KEY, ikev2_set_local_key);
12366
12367   clib_memcpy (mp->key_file, file, vec_len (file));
12368   vec_free (file);
12369
12370   S;
12371   W;
12372   /* NOTREACHED */
12373   return 0;
12374 }
12375
12376 /*
12377  * MAP
12378  */
12379 static int
12380 api_map_add_domain (vat_main_t * vam)
12381 {
12382   unformat_input_t *i = vam->input;
12383   vl_api_map_add_domain_t *mp;
12384   f64 timeout;
12385
12386   ip4_address_t ip4_prefix;
12387   ip6_address_t ip6_prefix;
12388   ip6_address_t ip6_src;
12389   u32 num_m_args = 0;
12390   u32 ip6_prefix_len = 0, ip4_prefix_len = 0, ea_bits_len = 0, psid_offset =
12391     0, psid_length = 0;
12392   u8 is_translation = 0;
12393   u32 mtu = 0;
12394   u32 ip6_src_len = 128;
12395
12396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12397     {
12398       if (unformat (i, "ip4-pfx %U/%d", unformat_ip4_address,
12399                     &ip4_prefix, &ip4_prefix_len))
12400         num_m_args++;
12401       else if (unformat (i, "ip6-pfx %U/%d", unformat_ip6_address,
12402                          &ip6_prefix, &ip6_prefix_len))
12403         num_m_args++;
12404       else
12405         if (unformat
12406             (i, "ip6-src %U/%d", unformat_ip6_address, &ip6_src,
12407              &ip6_src_len))
12408         num_m_args++;
12409       else if (unformat (i, "ip6-src %U", unformat_ip6_address, &ip6_src))
12410         num_m_args++;
12411       else if (unformat (i, "ea-bits-len %d", &ea_bits_len))
12412         num_m_args++;
12413       else if (unformat (i, "psid-offset %d", &psid_offset))
12414         num_m_args++;
12415       else if (unformat (i, "psid-len %d", &psid_length))
12416         num_m_args++;
12417       else if (unformat (i, "mtu %d", &mtu))
12418         num_m_args++;
12419       else if (unformat (i, "map-t"))
12420         is_translation = 1;
12421       else
12422         {
12423           clib_warning ("parse error '%U'", format_unformat_error, i);
12424           return -99;
12425         }
12426     }
12427
12428   if (num_m_args < 3)
12429     {
12430       errmsg ("mandatory argument(s) missing\n");
12431       return -99;
12432     }
12433
12434   /* Construct the API message */
12435   M (MAP_ADD_DOMAIN, map_add_domain);
12436
12437   clib_memcpy (mp->ip4_prefix, &ip4_prefix, sizeof (ip4_prefix));
12438   mp->ip4_prefix_len = ip4_prefix_len;
12439
12440   clib_memcpy (mp->ip6_prefix, &ip6_prefix, sizeof (ip6_prefix));
12441   mp->ip6_prefix_len = ip6_prefix_len;
12442
12443   clib_memcpy (mp->ip6_src, &ip6_src, sizeof (ip6_src));
12444   mp->ip6_src_prefix_len = ip6_src_len;
12445
12446   mp->ea_bits_len = ea_bits_len;
12447   mp->psid_offset = psid_offset;
12448   mp->psid_length = psid_length;
12449   mp->is_translation = is_translation;
12450   mp->mtu = htons (mtu);
12451
12452   /* send it... */
12453   S;
12454
12455   /* Wait for a reply, return good/bad news  */
12456   W;
12457 }
12458
12459 static int
12460 api_map_del_domain (vat_main_t * vam)
12461 {
12462   unformat_input_t *i = vam->input;
12463   vl_api_map_del_domain_t *mp;
12464   f64 timeout;
12465
12466   u32 num_m_args = 0;
12467   u32 index;
12468
12469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12470     {
12471       if (unformat (i, "index %d", &index))
12472         num_m_args++;
12473       else
12474         {
12475           clib_warning ("parse error '%U'", format_unformat_error, i);
12476           return -99;
12477         }
12478     }
12479
12480   if (num_m_args != 1)
12481     {
12482       errmsg ("mandatory argument(s) missing\n");
12483       return -99;
12484     }
12485
12486   /* Construct the API message */
12487   M (MAP_DEL_DOMAIN, map_del_domain);
12488
12489   mp->index = ntohl (index);
12490
12491   /* send it... */
12492   S;
12493
12494   /* Wait for a reply, return good/bad news  */
12495   W;
12496 }
12497
12498 static int
12499 api_map_add_del_rule (vat_main_t * vam)
12500 {
12501   unformat_input_t *i = vam->input;
12502   vl_api_map_add_del_rule_t *mp;
12503   f64 timeout;
12504   u8 is_add = 1;
12505   ip6_address_t ip6_dst;
12506   u32 num_m_args = 0, index, psid = 0;
12507
12508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12509     {
12510       if (unformat (i, "index %d", &index))
12511         num_m_args++;
12512       else if (unformat (i, "psid %d", &psid))
12513         num_m_args++;
12514       else if (unformat (i, "dst %U", unformat_ip6_address, &ip6_dst))
12515         num_m_args++;
12516       else if (unformat (i, "del"))
12517         {
12518           is_add = 0;
12519         }
12520       else
12521         {
12522           clib_warning ("parse error '%U'", format_unformat_error, i);
12523           return -99;
12524         }
12525     }
12526
12527   /* Construct the API message */
12528   M (MAP_ADD_DEL_RULE, map_add_del_rule);
12529
12530   mp->index = ntohl (index);
12531   mp->is_add = is_add;
12532   clib_memcpy (mp->ip6_dst, &ip6_dst, sizeof (ip6_dst));
12533   mp->psid = ntohs (psid);
12534
12535   /* send it... */
12536   S;
12537
12538   /* Wait for a reply, return good/bad news  */
12539   W;
12540 }
12541
12542 static int
12543 api_map_domain_dump (vat_main_t * vam)
12544 {
12545   vl_api_map_domain_dump_t *mp;
12546   f64 timeout;
12547
12548   /* Construct the API message */
12549   M (MAP_DOMAIN_DUMP, map_domain_dump);
12550
12551   /* send it... */
12552   S;
12553
12554   /* Use a control ping for synchronization */
12555   {
12556     vl_api_control_ping_t *mp;
12557     M (CONTROL_PING, control_ping);
12558     S;
12559   }
12560   W;
12561 }
12562
12563 static int
12564 api_map_rule_dump (vat_main_t * vam)
12565 {
12566   unformat_input_t *i = vam->input;
12567   vl_api_map_rule_dump_t *mp;
12568   f64 timeout;
12569   u32 domain_index = ~0;
12570
12571   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12572     {
12573       if (unformat (i, "index %u", &domain_index))
12574         ;
12575       else
12576         break;
12577     }
12578
12579   if (domain_index == ~0)
12580     {
12581       clib_warning ("parse error: domain index expected");
12582       return -99;
12583     }
12584
12585   /* Construct the API message */
12586   M (MAP_RULE_DUMP, map_rule_dump);
12587
12588   mp->domain_index = htonl (domain_index);
12589
12590   /* send it... */
12591   S;
12592
12593   /* Use a control ping for synchronization */
12594   {
12595     vl_api_control_ping_t *mp;
12596     M (CONTROL_PING, control_ping);
12597     S;
12598   }
12599   W;
12600 }
12601
12602 static void vl_api_map_add_domain_reply_t_handler
12603   (vl_api_map_add_domain_reply_t * mp)
12604 {
12605   vat_main_t *vam = &vat_main;
12606   i32 retval = ntohl (mp->retval);
12607
12608   if (vam->async_mode)
12609     {
12610       vam->async_errors += (retval < 0);
12611     }
12612   else
12613     {
12614       vam->retval = retval;
12615       vam->result_ready = 1;
12616     }
12617 }
12618
12619 static void vl_api_map_add_domain_reply_t_handler_json
12620   (vl_api_map_add_domain_reply_t * mp)
12621 {
12622   vat_main_t *vam = &vat_main;
12623   vat_json_node_t node;
12624
12625   vat_json_init_object (&node);
12626   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
12627   vat_json_object_add_uint (&node, "index", ntohl (mp->index));
12628
12629   vat_json_print (vam->ofp, &node);
12630   vat_json_free (&node);
12631
12632   vam->retval = ntohl (mp->retval);
12633   vam->result_ready = 1;
12634 }
12635
12636 static int
12637 api_get_first_msg_id (vat_main_t * vam)
12638 {
12639   vl_api_get_first_msg_id_t *mp;
12640   f64 timeout;
12641   unformat_input_t *i = vam->input;
12642   u8 *name;
12643   u8 name_set = 0;
12644
12645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12646     {
12647       if (unformat (i, "client %s", &name))
12648         name_set = 1;
12649       else
12650         break;
12651     }
12652
12653   if (name_set == 0)
12654     {
12655       errmsg ("missing client name\n");
12656       return -99;
12657     }
12658   vec_add1 (name, 0);
12659
12660   if (vec_len (name) > 63)
12661     {
12662       errmsg ("client name too long\n");
12663       return -99;
12664     }
12665
12666   M (GET_FIRST_MSG_ID, get_first_msg_id);
12667   clib_memcpy (mp->name, name, vec_len (name));
12668   S;
12669   W;
12670   /* NOTREACHED */
12671   return 0;
12672 }
12673
12674 static int
12675 api_cop_interface_enable_disable (vat_main_t * vam)
12676 {
12677   unformat_input_t *line_input = vam->input;
12678   vl_api_cop_interface_enable_disable_t *mp;
12679   f64 timeout;
12680   u32 sw_if_index = ~0;
12681   u8 enable_disable = 1;
12682
12683   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12684     {
12685       if (unformat (line_input, "disable"))
12686         enable_disable = 0;
12687       if (unformat (line_input, "enable"))
12688         enable_disable = 1;
12689       else if (unformat (line_input, "%U", unformat_sw_if_index,
12690                          vam, &sw_if_index))
12691         ;
12692       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12693         ;
12694       else
12695         break;
12696     }
12697
12698   if (sw_if_index == ~0)
12699     {
12700       errmsg ("missing interface name or sw_if_index\n");
12701       return -99;
12702     }
12703
12704   /* Construct the API message */
12705   M (COP_INTERFACE_ENABLE_DISABLE, cop_interface_enable_disable);
12706   mp->sw_if_index = ntohl (sw_if_index);
12707   mp->enable_disable = enable_disable;
12708
12709   /* send it... */
12710   S;
12711   /* Wait for the reply */
12712   W;
12713 }
12714
12715 static int
12716 api_cop_whitelist_enable_disable (vat_main_t * vam)
12717 {
12718   unformat_input_t *line_input = vam->input;
12719   vl_api_cop_whitelist_enable_disable_t *mp;
12720   f64 timeout;
12721   u32 sw_if_index = ~0;
12722   u8 ip4 = 0, ip6 = 0, default_cop = 0;
12723   u32 fib_id = 0;
12724
12725   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12726     {
12727       if (unformat (line_input, "ip4"))
12728         ip4 = 1;
12729       else if (unformat (line_input, "ip6"))
12730         ip6 = 1;
12731       else if (unformat (line_input, "default"))
12732         default_cop = 1;
12733       else if (unformat (line_input, "%U", unformat_sw_if_index,
12734                          vam, &sw_if_index))
12735         ;
12736       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
12737         ;
12738       else if (unformat (line_input, "fib-id %d", &fib_id))
12739         ;
12740       else
12741         break;
12742     }
12743
12744   if (sw_if_index == ~0)
12745     {
12746       errmsg ("missing interface name or sw_if_index\n");
12747       return -99;
12748     }
12749
12750   /* Construct the API message */
12751   M (COP_WHITELIST_ENABLE_DISABLE, cop_whitelist_enable_disable);
12752   mp->sw_if_index = ntohl (sw_if_index);
12753   mp->fib_id = ntohl (fib_id);
12754   mp->ip4 = ip4;
12755   mp->ip6 = ip6;
12756   mp->default_cop = default_cop;
12757
12758   /* send it... */
12759   S;
12760   /* Wait for the reply */
12761   W;
12762 }
12763
12764 static int
12765 api_get_node_graph (vat_main_t * vam)
12766 {
12767   vl_api_get_node_graph_t *mp;
12768   f64 timeout;
12769
12770   M (GET_NODE_GRAPH, get_node_graph);
12771
12772   /* send it... */
12773   S;
12774   /* Wait for the reply */
12775   W;
12776 }
12777
12778 /* *INDENT-OFF* */
12779 /** Used for parsing LISP eids */
12780 typedef CLIB_PACKED(struct{
12781   u8 addr[16];   /**< eid address */
12782   u32 len;       /**< prefix length if IP */
12783   u8 type;      /**< type of eid */
12784 }) lisp_eid_vat_t;
12785 /* *INDENT-ON* */
12786
12787 static uword
12788 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
12789 {
12790   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
12791
12792   memset (a, 0, sizeof (a[0]));
12793
12794   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
12795     {
12796       a->type = 0;              /* ipv4 type */
12797     }
12798   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
12799     {
12800       a->type = 1;              /* ipv6 type */
12801     }
12802   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
12803     {
12804       a->type = 2;              /* mac type */
12805     }
12806   else
12807     {
12808       return 0;
12809     }
12810
12811   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
12812     {
12813       return 0;
12814     }
12815
12816   return 1;
12817 }
12818
12819 static int
12820 lisp_eid_size_vat (u8 type)
12821 {
12822   switch (type)
12823     {
12824     case 0:
12825       return 4;
12826     case 1:
12827       return 16;
12828     case 2:
12829       return 6;
12830     }
12831   return 0;
12832 }
12833
12834 static void
12835 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
12836 {
12837   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
12838 }
12839
12840 /* *INDENT-OFF* */
12841 /** Used for transferring locators via VPP API */
12842 typedef CLIB_PACKED(struct
12843 {
12844   u32 sw_if_index; /**< locator sw_if_index */
12845   u8 priority; /**< locator priority */
12846   u8 weight;   /**< locator weight */
12847 }) ls_locator_t;
12848 /* *INDENT-ON* */
12849
12850 static int
12851 api_lisp_add_del_locator_set (vat_main_t * vam)
12852 {
12853   unformat_input_t *input = vam->input;
12854   vl_api_lisp_add_del_locator_set_t *mp;
12855   f64 timeout = ~0;
12856   u8 is_add = 1;
12857   u8 *locator_set_name = NULL;
12858   u8 locator_set_name_set = 0;
12859   ls_locator_t locator, *locators = 0;
12860   u32 sw_if_index, priority, weight;
12861   u32 data_len = 0;
12862
12863   /* Parse args required to build the message */
12864   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12865     {
12866       if (unformat (input, "del"))
12867         {
12868           is_add = 0;
12869         }
12870       else if (unformat (input, "locator-set %s", &locator_set_name))
12871         {
12872           locator_set_name_set = 1;
12873         }
12874       else if (unformat (input, "sw_if_index %u p %u w %u",
12875                          &sw_if_index, &priority, &weight))
12876         {
12877           locator.sw_if_index = htonl (sw_if_index);
12878           locator.priority = priority;
12879           locator.weight = weight;
12880           vec_add1 (locators, locator);
12881         }
12882       else if (unformat (input, "iface %U p %u w %u", unformat_sw_if_index,
12883                          vam, &sw_if_index, &priority, &weight))
12884         {
12885           locator.sw_if_index = htonl (sw_if_index);
12886           locator.priority = priority;
12887           locator.weight = weight;
12888           vec_add1 (locators, locator);
12889         }
12890       else
12891         break;
12892     }
12893
12894   if (locator_set_name_set == 0)
12895     {
12896       errmsg ("missing locator-set name");
12897       vec_free (locators);
12898       return -99;
12899     }
12900
12901   if (vec_len (locator_set_name) > 64)
12902     {
12903       errmsg ("locator-set name too long\n");
12904       vec_free (locator_set_name);
12905       vec_free (locators);
12906       return -99;
12907     }
12908   vec_add1 (locator_set_name, 0);
12909
12910   data_len = sizeof (ls_locator_t) * vec_len (locators);
12911
12912   /* Construct the API message */
12913   M2 (LISP_ADD_DEL_LOCATOR_SET, lisp_add_del_locator_set, data_len);
12914
12915   mp->is_add = is_add;
12916   clib_memcpy (mp->locator_set_name, locator_set_name,
12917                vec_len (locator_set_name));
12918   vec_free (locator_set_name);
12919
12920   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
12921   if (locators)
12922     clib_memcpy (mp->locators, locators, data_len);
12923   vec_free (locators);
12924
12925   /* send it... */
12926   S;
12927
12928   /* Wait for a reply... */
12929   W;
12930
12931   /* NOTREACHED */
12932   return 0;
12933 }
12934
12935 static int
12936 api_lisp_add_del_locator (vat_main_t * vam)
12937 {
12938   unformat_input_t *input = vam->input;
12939   vl_api_lisp_add_del_locator_t *mp;
12940   f64 timeout = ~0;
12941   u32 tmp_if_index = ~0;
12942   u32 sw_if_index = ~0;
12943   u8 sw_if_index_set = 0;
12944   u8 sw_if_index_if_name_set = 0;
12945   u32 priority = ~0;
12946   u8 priority_set = 0;
12947   u32 weight = ~0;
12948   u8 weight_set = 0;
12949   u8 is_add = 1;
12950   u8 *locator_set_name = NULL;
12951   u8 locator_set_name_set = 0;
12952
12953   /* Parse args required to build the message */
12954   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12955     {
12956       if (unformat (input, "del"))
12957         {
12958           is_add = 0;
12959         }
12960       else if (unformat (input, "locator-set %s", &locator_set_name))
12961         {
12962           locator_set_name_set = 1;
12963         }
12964       else if (unformat (input, "iface %U", unformat_sw_if_index, vam,
12965                          &tmp_if_index))
12966         {
12967           sw_if_index_if_name_set = 1;
12968           sw_if_index = tmp_if_index;
12969         }
12970       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
12971         {
12972           sw_if_index_set = 1;
12973           sw_if_index = tmp_if_index;
12974         }
12975       else if (unformat (input, "p %d", &priority))
12976         {
12977           priority_set = 1;
12978         }
12979       else if (unformat (input, "w %d", &weight))
12980         {
12981           weight_set = 1;
12982         }
12983       else
12984         break;
12985     }
12986
12987   if (locator_set_name_set == 0)
12988     {
12989       errmsg ("missing locator-set name");
12990       return -99;
12991     }
12992
12993   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
12994     {
12995       errmsg ("missing sw_if_index");
12996       vec_free (locator_set_name);
12997       return -99;
12998     }
12999
13000   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
13001     {
13002       errmsg ("cannot use both params interface name and sw_if_index");
13003       vec_free (locator_set_name);
13004       return -99;
13005     }
13006
13007   if (priority_set == 0)
13008     {
13009       errmsg ("missing locator-set priority\n");
13010       vec_free (locator_set_name);
13011       return -99;
13012     }
13013
13014   if (weight_set == 0)
13015     {
13016       errmsg ("missing locator-set weight\n");
13017       vec_free (locator_set_name);
13018       return -99;
13019     }
13020
13021   if (vec_len (locator_set_name) > 64)
13022     {
13023       errmsg ("locator-set name too long\n");
13024       vec_free (locator_set_name);
13025       return -99;
13026     }
13027   vec_add1 (locator_set_name, 0);
13028
13029   /* Construct the API message */
13030   M (LISP_ADD_DEL_LOCATOR, lisp_add_del_locator);
13031
13032   mp->is_add = is_add;
13033   mp->sw_if_index = ntohl (sw_if_index);
13034   mp->priority = priority;
13035   mp->weight = weight;
13036   clib_memcpy (mp->locator_set_name, locator_set_name,
13037                vec_len (locator_set_name));
13038   vec_free (locator_set_name);
13039
13040   /* send it... */
13041   S;
13042
13043   /* Wait for a reply... */
13044   W;
13045
13046   /* NOTREACHED */
13047   return 0;
13048 }
13049
13050 uword
13051 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
13052 {
13053   u32 *key_id = va_arg (*args, u32 *);
13054   u8 *s = 0;
13055
13056   if (unformat (input, "%s", &s))
13057     {
13058       if (!strcmp ((char *) s, "sha1"))
13059         key_id[0] = HMAC_SHA_1_96;
13060       else if (!strcmp ((char *) s, "sha256"))
13061         key_id[0] = HMAC_SHA_256_128;
13062       else
13063         {
13064           clib_warning ("invalid key_id: '%s'", s);
13065           key_id[0] = HMAC_NO_KEY;
13066         }
13067     }
13068   else
13069     return 0;
13070
13071   vec_free (s);
13072   return 1;
13073 }
13074
13075 static int
13076 api_lisp_add_del_local_eid (vat_main_t * vam)
13077 {
13078   unformat_input_t *input = vam->input;
13079   vl_api_lisp_add_del_local_eid_t *mp;
13080   f64 timeout = ~0;
13081   u8 is_add = 1;
13082   u8 eid_set = 0;
13083   lisp_eid_vat_t _eid, *eid = &_eid;
13084   u8 *locator_set_name = 0;
13085   u8 locator_set_name_set = 0;
13086   u32 vni = 0;
13087   u16 key_id = 0;
13088   u8 *key = 0;
13089
13090   /* Parse args required to build the message */
13091   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13092     {
13093       if (unformat (input, "del"))
13094         {
13095           is_add = 0;
13096         }
13097       else if (unformat (input, "vni %d", &vni))
13098         {
13099           ;
13100         }
13101       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13102         {
13103           eid_set = 1;
13104         }
13105       else if (unformat (input, "locator-set %s", &locator_set_name))
13106         {
13107           locator_set_name_set = 1;
13108         }
13109       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
13110         ;
13111       else if (unformat (input, "secret-key %_%v%_", &key))
13112         ;
13113       else
13114         break;
13115     }
13116
13117   if (locator_set_name_set == 0)
13118     {
13119       errmsg ("missing locator-set name\n");
13120       return -99;
13121     }
13122
13123   if (0 == eid_set)
13124     {
13125       errmsg ("EID address not set!");
13126       vec_free (locator_set_name);
13127       return -99;
13128     }
13129
13130   if (key && (0 == key_id))
13131     {
13132       errmsg ("invalid key_id!");
13133       return -99;
13134     }
13135
13136   if (vec_len (key) > 64)
13137     {
13138       errmsg ("key too long");
13139       vec_free (key);
13140       return -99;
13141     }
13142
13143   if (vec_len (locator_set_name) > 64)
13144     {
13145       errmsg ("locator-set name too long\n");
13146       vec_free (locator_set_name);
13147       return -99;
13148     }
13149   vec_add1 (locator_set_name, 0);
13150
13151   /* Construct the API message */
13152   M (LISP_ADD_DEL_LOCAL_EID, lisp_add_del_local_eid);
13153
13154   mp->is_add = is_add;
13155   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13156   mp->eid_type = eid->type;
13157   mp->prefix_len = eid->len;
13158   mp->vni = clib_host_to_net_u32 (vni);
13159   mp->key_id = clib_host_to_net_u16 (key_id);
13160   clib_memcpy (mp->locator_set_name, locator_set_name,
13161                vec_len (locator_set_name));
13162   clib_memcpy (mp->key, key, vec_len (key));
13163
13164   vec_free (locator_set_name);
13165   vec_free (key);
13166
13167   /* send it... */
13168   S;
13169
13170   /* Wait for a reply... */
13171   W;
13172
13173   /* NOTREACHED */
13174   return 0;
13175 }
13176
13177 /* *INDENT-OFF* */
13178 /** Used for transferring locators via VPP API */
13179 typedef CLIB_PACKED(struct
13180 {
13181   u8 is_ip4; /**< is locator an IPv4 address? */
13182   u8 priority; /**< locator priority */
13183   u8 weight;   /**< locator weight */
13184   u8 addr[16]; /**< IPv4/IPv6 address */
13185 }) rloc_t;
13186 /* *INDENT-ON* */
13187
13188 static int
13189 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
13190 {
13191   unformat_input_t *input = vam->input;
13192   vl_api_lisp_gpe_add_del_fwd_entry_t *mp;
13193   f64 timeout = ~0;
13194   u8 is_add = 1;
13195   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
13196   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
13197   u8 rmt_eid_set = 0, lcl_eid_set = 0;
13198   u32 action = ~0, p, w;
13199   ip4_address_t rmt_rloc4, lcl_rloc4;
13200   ip6_address_t rmt_rloc6, lcl_rloc6;
13201   rloc_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
13202
13203   memset (&rloc, 0, sizeof (rloc));
13204
13205   /* Parse args required to build the message */
13206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13207     {
13208       if (unformat (input, "del"))
13209         {
13210           is_add = 0;
13211         }
13212       else if (unformat (input, "rmt_eid %U", unformat_lisp_eid_vat, rmt_eid))
13213         {
13214           rmt_eid_set = 1;
13215         }
13216       else if (unformat (input, "lcl_eid %U", unformat_lisp_eid_vat, lcl_eid))
13217         {
13218           lcl_eid_set = 1;
13219         }
13220       else if (unformat (input, "p %d w %d", &p, &w))
13221         {
13222           if (!curr_rloc)
13223             {
13224               errmsg ("No RLOC configured for setting priority/weight!");
13225               return -99;
13226             }
13227           curr_rloc->priority = p;
13228           curr_rloc->weight = w;
13229         }
13230       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
13231                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
13232         {
13233           rloc.is_ip4 = 1;
13234
13235           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
13236           rloc.priority = rloc.weight = 0;
13237           vec_add1 (lcl_locs, rloc);
13238
13239           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
13240           vec_add1 (rmt_locs, rloc);
13241           /* priority and weight saved in rmt loc */
13242           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13243         }
13244       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
13245                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
13246         {
13247           rloc.is_ip4 = 0;
13248           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
13249           rloc.priority = rloc.weight = 0;
13250           vec_add1 (lcl_locs, rloc);
13251
13252           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
13253           vec_add1 (rmt_locs, rloc);
13254           /* priority and weight saved in rmt loc */
13255           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
13256         }
13257       else if (unformat (input, "action %d", &action))
13258         {
13259           ;
13260         }
13261       else
13262         {
13263           clib_warning ("parse error '%U'", format_unformat_error, input);
13264           return -99;
13265         }
13266     }
13267
13268   if (!rmt_eid_set)
13269     {
13270       errmsg ("remote eid addresses not set\n");
13271       return -99;
13272     }
13273
13274   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
13275     {
13276       errmsg ("eid types don't match\n");
13277       return -99;
13278     }
13279
13280   if (0 == rmt_locs && (u32) ~ 0 == action)
13281     {
13282       errmsg ("action not set for negative mapping\n");
13283       return -99;
13284     }
13285
13286   /* Construct the API message */
13287   M (LISP_GPE_ADD_DEL_FWD_ENTRY, lisp_gpe_add_del_fwd_entry);
13288
13289   mp->is_add = is_add;
13290   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
13291   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
13292   mp->eid_type = rmt_eid->type;
13293   mp->rmt_len = rmt_eid->len;
13294   mp->lcl_len = lcl_eid->len;
13295   mp->action = action;
13296
13297   if (0 != rmt_locs && 0 != lcl_locs)
13298     {
13299       mp->loc_num = vec_len (rmt_locs);
13300       clib_memcpy (mp->lcl_locs, lcl_locs,
13301                    (sizeof (rloc_t) * vec_len (lcl_locs)));
13302       clib_memcpy (mp->rmt_locs, rmt_locs,
13303                    (sizeof (rloc_t) * vec_len (rmt_locs)));
13304     }
13305   vec_free (lcl_locs);
13306   vec_free (rmt_locs);
13307
13308   /* send it... */
13309   S;
13310
13311   /* Wait for a reply... */
13312   W;
13313
13314   /* NOTREACHED */
13315   return 0;
13316 }
13317
13318 static int
13319 api_lisp_add_del_map_server (vat_main_t * vam)
13320 {
13321   unformat_input_t *input = vam->input;
13322   vl_api_lisp_add_del_map_server_t *mp;
13323   f64 timeout = ~0;
13324   u8 is_add = 1;
13325   u8 ipv4_set = 0;
13326   u8 ipv6_set = 0;
13327   ip4_address_t ipv4;
13328   ip6_address_t ipv6;
13329
13330   /* Parse args required to build the message */
13331   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13332     {
13333       if (unformat (input, "del"))
13334         {
13335           is_add = 0;
13336         }
13337       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13338         {
13339           ipv4_set = 1;
13340         }
13341       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13342         {
13343           ipv6_set = 1;
13344         }
13345       else
13346         break;
13347     }
13348
13349   if (ipv4_set && ipv6_set)
13350     {
13351       errmsg ("both eid v4 and v6 addresses set\n");
13352       return -99;
13353     }
13354
13355   if (!ipv4_set && !ipv6_set)
13356     {
13357       errmsg ("eid addresses not set\n");
13358       return -99;
13359     }
13360
13361   /* Construct the API message */
13362   M (LISP_ADD_DEL_MAP_SERVER, lisp_add_del_map_server);
13363
13364   mp->is_add = is_add;
13365   if (ipv6_set)
13366     {
13367       mp->is_ipv6 = 1;
13368       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13369     }
13370   else
13371     {
13372       mp->is_ipv6 = 0;
13373       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13374     }
13375
13376   /* send it... */
13377   S;
13378
13379   /* Wait for a reply... */
13380   W;
13381
13382   /* NOTREACHED */
13383   return 0;
13384 }
13385
13386 static int
13387 api_lisp_add_del_map_resolver (vat_main_t * vam)
13388 {
13389   unformat_input_t *input = vam->input;
13390   vl_api_lisp_add_del_map_resolver_t *mp;
13391   f64 timeout = ~0;
13392   u8 is_add = 1;
13393   u8 ipv4_set = 0;
13394   u8 ipv6_set = 0;
13395   ip4_address_t ipv4;
13396   ip6_address_t ipv6;
13397
13398   /* Parse args required to build the message */
13399   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13400     {
13401       if (unformat (input, "del"))
13402         {
13403           is_add = 0;
13404         }
13405       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
13406         {
13407           ipv4_set = 1;
13408         }
13409       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
13410         {
13411           ipv6_set = 1;
13412         }
13413       else
13414         break;
13415     }
13416
13417   if (ipv4_set && ipv6_set)
13418     {
13419       errmsg ("both eid v4 and v6 addresses set\n");
13420       return -99;
13421     }
13422
13423   if (!ipv4_set && !ipv6_set)
13424     {
13425       errmsg ("eid addresses not set\n");
13426       return -99;
13427     }
13428
13429   /* Construct the API message */
13430   M (LISP_ADD_DEL_MAP_RESOLVER, lisp_add_del_map_resolver);
13431
13432   mp->is_add = is_add;
13433   if (ipv6_set)
13434     {
13435       mp->is_ipv6 = 1;
13436       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
13437     }
13438   else
13439     {
13440       mp->is_ipv6 = 0;
13441       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
13442     }
13443
13444   /* send it... */
13445   S;
13446
13447   /* Wait for a reply... */
13448   W;
13449
13450   /* NOTREACHED */
13451   return 0;
13452 }
13453
13454 static int
13455 api_lisp_gpe_enable_disable (vat_main_t * vam)
13456 {
13457   unformat_input_t *input = vam->input;
13458   vl_api_lisp_gpe_enable_disable_t *mp;
13459   f64 timeout = ~0;
13460   u8 is_set = 0;
13461   u8 is_en = 1;
13462
13463   /* Parse args required to build the message */
13464   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13465     {
13466       if (unformat (input, "enable"))
13467         {
13468           is_set = 1;
13469           is_en = 1;
13470         }
13471       else if (unformat (input, "disable"))
13472         {
13473           is_set = 1;
13474           is_en = 0;
13475         }
13476       else
13477         break;
13478     }
13479
13480   if (is_set == 0)
13481     {
13482       errmsg ("Value not set\n");
13483       return -99;
13484     }
13485
13486   /* Construct the API message */
13487   M (LISP_GPE_ENABLE_DISABLE, lisp_gpe_enable_disable);
13488
13489   mp->is_en = is_en;
13490
13491   /* send it... */
13492   S;
13493
13494   /* Wait for a reply... */
13495   W;
13496
13497   /* NOTREACHED */
13498   return 0;
13499 }
13500
13501 static int
13502 api_lisp_rloc_probe_enable_disable (vat_main_t * vam)
13503 {
13504   unformat_input_t *input = vam->input;
13505   vl_api_lisp_rloc_probe_enable_disable_t *mp;
13506   f64 timeout = ~0;
13507   u8 is_set = 0;
13508   u8 is_en = 0;
13509
13510   /* Parse args required to build the message */
13511   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13512     {
13513       if (unformat (input, "enable"))
13514         {
13515           is_set = 1;
13516           is_en = 1;
13517         }
13518       else if (unformat (input, "disable"))
13519         is_set = 1;
13520       else
13521         break;
13522     }
13523
13524   if (!is_set)
13525     {
13526       errmsg ("Value not set\n");
13527       return -99;
13528     }
13529
13530   /* Construct the API message */
13531   M (LISP_RLOC_PROBE_ENABLE_DISABLE, lisp_rloc_probe_enable_disable);
13532
13533   mp->is_enabled = is_en;
13534
13535   /* send it... */
13536   S;
13537
13538   /* Wait for a reply... */
13539   W;
13540
13541   /* NOTREACHED */
13542   return 0;
13543 }
13544
13545 static int
13546 api_lisp_map_register_enable_disable (vat_main_t * vam)
13547 {
13548   unformat_input_t *input = vam->input;
13549   vl_api_lisp_map_register_enable_disable_t *mp;
13550   f64 timeout = ~0;
13551   u8 is_set = 0;
13552   u8 is_en = 0;
13553
13554   /* Parse args required to build the message */
13555   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13556     {
13557       if (unformat (input, "enable"))
13558         {
13559           is_set = 1;
13560           is_en = 1;
13561         }
13562       else if (unformat (input, "disable"))
13563         is_set = 1;
13564       else
13565         break;
13566     }
13567
13568   if (!is_set)
13569     {
13570       errmsg ("Value not set\n");
13571       return -99;
13572     }
13573
13574   /* Construct the API message */
13575   M (LISP_MAP_REGISTER_ENABLE_DISABLE, lisp_map_register_enable_disable);
13576
13577   mp->is_enabled = is_en;
13578
13579   /* send it... */
13580   S;
13581
13582   /* Wait for a reply... */
13583   W;
13584
13585   /* NOTREACHED */
13586   return 0;
13587 }
13588
13589 static int
13590 api_lisp_enable_disable (vat_main_t * vam)
13591 {
13592   unformat_input_t *input = vam->input;
13593   vl_api_lisp_enable_disable_t *mp;
13594   f64 timeout = ~0;
13595   u8 is_set = 0;
13596   u8 is_en = 0;
13597
13598   /* Parse args required to build the message */
13599   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13600     {
13601       if (unformat (input, "enable"))
13602         {
13603           is_set = 1;
13604           is_en = 1;
13605         }
13606       else if (unformat (input, "disable"))
13607         {
13608           is_set = 1;
13609         }
13610       else
13611         break;
13612     }
13613
13614   if (!is_set)
13615     {
13616       errmsg ("Value not set\n");
13617       return -99;
13618     }
13619
13620   /* Construct the API message */
13621   M (LISP_ENABLE_DISABLE, lisp_enable_disable);
13622
13623   mp->is_en = is_en;
13624
13625   /* send it... */
13626   S;
13627
13628   /* Wait for a reply... */
13629   W;
13630
13631   /* NOTREACHED */
13632   return 0;
13633 }
13634
13635 static int
13636 api_show_lisp_map_register_state (vat_main_t * vam)
13637 {
13638   f64 timeout = ~0;
13639   vl_api_show_lisp_map_register_state_t *mp;
13640
13641   M (SHOW_LISP_MAP_REGISTER_STATE, show_lisp_map_register_state);
13642
13643   /* send */
13644   S;
13645
13646   /* wait for reply */
13647   W;
13648
13649   return 0;
13650 }
13651
13652 static int
13653 api_show_lisp_rloc_probe_state (vat_main_t * vam)
13654 {
13655   f64 timeout = ~0;
13656   vl_api_show_lisp_rloc_probe_state_t *mp;
13657
13658   M (SHOW_LISP_RLOC_PROBE_STATE, show_lisp_rloc_probe_state);
13659
13660   /* send */
13661   S;
13662
13663   /* wait for reply */
13664   W;
13665
13666   return 0;
13667 }
13668
13669 static int
13670 api_show_lisp_map_request_mode (vat_main_t * vam)
13671 {
13672   f64 timeout = ~0;
13673   vl_api_show_lisp_map_request_mode_t *mp;
13674
13675   M (SHOW_LISP_MAP_REQUEST_MODE, show_lisp_map_request_mode);
13676
13677   /* send */
13678   S;
13679
13680   /* wait for reply */
13681   W;
13682
13683   return 0;
13684 }
13685
13686 static int
13687 api_lisp_map_request_mode (vat_main_t * vam)
13688 {
13689   f64 timeout = ~0;
13690   unformat_input_t *input = vam->input;
13691   vl_api_lisp_map_request_mode_t *mp;
13692   u8 mode = 0;
13693
13694   /* Parse args required to build the message */
13695   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13696     {
13697       if (unformat (input, "dst-only"))
13698         mode = 0;
13699       else if (unformat (input, "src-dst"))
13700         mode = 1;
13701       else
13702         {
13703           errmsg ("parse error '%U'", format_unformat_error, input);
13704           return -99;
13705         }
13706     }
13707
13708   M (LISP_MAP_REQUEST_MODE, lisp_map_request_mode);
13709
13710   mp->mode = mode;
13711
13712   /* send */
13713   S;
13714
13715   /* wait for reply */
13716   W;
13717
13718   /* notreached */
13719   return 0;
13720 }
13721
13722 /**
13723  * Enable/disable LISP proxy ITR.
13724  *
13725  * @param vam vpp API test context
13726  * @return return code
13727  */
13728 static int
13729 api_lisp_pitr_set_locator_set (vat_main_t * vam)
13730 {
13731   f64 timeout = ~0;
13732   u8 ls_name_set = 0;
13733   unformat_input_t *input = vam->input;
13734   vl_api_lisp_pitr_set_locator_set_t *mp;
13735   u8 is_add = 1;
13736   u8 *ls_name = 0;
13737
13738   /* Parse args required to build the message */
13739   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13740     {
13741       if (unformat (input, "del"))
13742         is_add = 0;
13743       else if (unformat (input, "locator-set %s", &ls_name))
13744         ls_name_set = 1;
13745       else
13746         {
13747           errmsg ("parse error '%U'", format_unformat_error, input);
13748           return -99;
13749         }
13750     }
13751
13752   if (!ls_name_set)
13753     {
13754       errmsg ("locator-set name not set!");
13755       return -99;
13756     }
13757
13758   M (LISP_PITR_SET_LOCATOR_SET, lisp_pitr_set_locator_set);
13759
13760   mp->is_add = is_add;
13761   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
13762   vec_free (ls_name);
13763
13764   /* send */
13765   S;
13766
13767   /* wait for reply */
13768   W;
13769
13770   /* notreached */
13771   return 0;
13772 }
13773
13774 static int
13775 api_show_lisp_pitr (vat_main_t * vam)
13776 {
13777   vl_api_show_lisp_pitr_t *mp;
13778   f64 timeout = ~0;
13779
13780   if (!vam->json_output)
13781     {
13782       fformat (vam->ofp, "%=20s\n", "lisp status:");
13783     }
13784
13785   M (SHOW_LISP_PITR, show_lisp_pitr);
13786   /* send it... */
13787   S;
13788
13789   /* Wait for a reply... */
13790   W;
13791
13792   /* NOTREACHED */
13793   return 0;
13794 }
13795
13796 /**
13797  * Add/delete mapping between vni and vrf
13798  */
13799 static int
13800 api_lisp_eid_table_add_del_map (vat_main_t * vam)
13801 {
13802   f64 timeout = ~0;
13803   unformat_input_t *input = vam->input;
13804   vl_api_lisp_eid_table_add_del_map_t *mp;
13805   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
13806   u32 vni, vrf, bd_index;
13807
13808   /* Parse args required to build the message */
13809   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13810     {
13811       if (unformat (input, "del"))
13812         is_add = 0;
13813       else if (unformat (input, "vrf %d", &vrf))
13814         vrf_set = 1;
13815       else if (unformat (input, "bd_index %d", &bd_index))
13816         bd_index_set = 1;
13817       else if (unformat (input, "vni %d", &vni))
13818         vni_set = 1;
13819       else
13820         break;
13821     }
13822
13823   if (!vni_set || (!vrf_set && !bd_index_set))
13824     {
13825       errmsg ("missing arguments!");
13826       return -99;
13827     }
13828
13829   if (vrf_set && bd_index_set)
13830     {
13831       errmsg ("error: both vrf and bd entered!");
13832       return -99;
13833     }
13834
13835   M (LISP_EID_TABLE_ADD_DEL_MAP, lisp_eid_table_add_del_map);
13836
13837   mp->is_add = is_add;
13838   mp->vni = htonl (vni);
13839   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
13840   mp->is_l2 = bd_index_set;
13841
13842   /* send */
13843   S;
13844
13845   /* wait for reply */
13846   W;
13847
13848   /* notreached */
13849   return 0;
13850 }
13851
13852 uword
13853 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
13854 {
13855   u32 *action = va_arg (*args, u32 *);
13856   u8 *s = 0;
13857
13858   if (unformat (input, "%s", &s))
13859     {
13860       if (!strcmp ((char *) s, "no-action"))
13861         action[0] = 0;
13862       else if (!strcmp ((char *) s, "natively-forward"))
13863         action[0] = 1;
13864       else if (!strcmp ((char *) s, "send-map-request"))
13865         action[0] = 2;
13866       else if (!strcmp ((char *) s, "drop"))
13867         action[0] = 3;
13868       else
13869         {
13870           clib_warning ("invalid action: '%s'", s);
13871           action[0] = 3;
13872         }
13873     }
13874   else
13875     return 0;
13876
13877   vec_free (s);
13878   return 1;
13879 }
13880
13881 /**
13882  * Add/del remote mapping to/from LISP control plane
13883  *
13884  * @param vam vpp API test context
13885  * @return return code
13886  */
13887 static int
13888 api_lisp_add_del_remote_mapping (vat_main_t * vam)
13889 {
13890   unformat_input_t *input = vam->input;
13891   vl_api_lisp_add_del_remote_mapping_t *mp;
13892   f64 timeout = ~0;
13893   u32 vni = 0;
13894   lisp_eid_vat_t _eid, *eid = &_eid;
13895   lisp_eid_vat_t _seid, *seid = &_seid;
13896   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
13897   u32 action = ~0, p, w, data_len;
13898   ip4_address_t rloc4;
13899   ip6_address_t rloc6;
13900   rloc_t *rlocs = 0, rloc, *curr_rloc = 0;
13901
13902   memset (&rloc, 0, sizeof (rloc));
13903
13904   /* Parse args required to build the message */
13905   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13906     {
13907       if (unformat (input, "del-all"))
13908         {
13909           del_all = 1;
13910         }
13911       else if (unformat (input, "del"))
13912         {
13913           is_add = 0;
13914         }
13915       else if (unformat (input, "add"))
13916         {
13917           is_add = 1;
13918         }
13919       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
13920         {
13921           eid_set = 1;
13922         }
13923       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
13924         {
13925           seid_set = 1;
13926         }
13927       else if (unformat (input, "vni %d", &vni))
13928         {
13929           ;
13930         }
13931       else if (unformat (input, "p %d w %d", &p, &w))
13932         {
13933           if (!curr_rloc)
13934             {
13935               errmsg ("No RLOC configured for setting priority/weight!");
13936               return -99;
13937             }
13938           curr_rloc->priority = p;
13939           curr_rloc->weight = w;
13940         }
13941       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
13942         {
13943           rloc.is_ip4 = 1;
13944           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
13945           vec_add1 (rlocs, rloc);
13946           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13947         }
13948       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
13949         {
13950           rloc.is_ip4 = 0;
13951           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
13952           vec_add1 (rlocs, rloc);
13953           curr_rloc = &rlocs[vec_len (rlocs) - 1];
13954         }
13955       else if (unformat (input, "action %U",
13956                          unformat_negative_mapping_action, &action))
13957         {
13958           ;
13959         }
13960       else
13961         {
13962           clib_warning ("parse error '%U'", format_unformat_error, input);
13963           return -99;
13964         }
13965     }
13966
13967   if (0 == eid_set)
13968     {
13969       errmsg ("missing params!");
13970       return -99;
13971     }
13972
13973   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
13974     {
13975       errmsg ("no action set for negative map-reply!");
13976       return -99;
13977     }
13978
13979   data_len = vec_len (rlocs) * sizeof (rloc_t);
13980
13981   M2 (LISP_ADD_DEL_REMOTE_MAPPING, lisp_add_del_remote_mapping, data_len);
13982   mp->is_add = is_add;
13983   mp->vni = htonl (vni);
13984   mp->action = (u8) action;
13985   mp->is_src_dst = seid_set;
13986   mp->eid_len = eid->len;
13987   mp->seid_len = seid->len;
13988   mp->del_all = del_all;
13989   mp->eid_type = eid->type;
13990   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
13991   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
13992
13993   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
13994   clib_memcpy (mp->rlocs, rlocs, data_len);
13995   vec_free (rlocs);
13996
13997   /* send it... */
13998   S;
13999
14000   /* Wait for a reply... */
14001   W;
14002
14003   /* NOTREACHED */
14004   return 0;
14005 }
14006
14007 /**
14008  * Add/del LISP adjacency. Saves mapping in LISP control plane and updates
14009  * forwarding entries in data-plane accordingly.
14010  *
14011  * @param vam vpp API test context
14012  * @return return code
14013  */
14014 static int
14015 api_lisp_add_del_adjacency (vat_main_t * vam)
14016 {
14017   unformat_input_t *input = vam->input;
14018   vl_api_lisp_add_del_adjacency_t *mp;
14019   f64 timeout = ~0;
14020   u32 vni = 0;
14021   ip4_address_t leid4, reid4;
14022   ip6_address_t leid6, reid6;
14023   u8 reid_mac[6] = { 0 };
14024   u8 leid_mac[6] = { 0 };
14025   u8 reid_type, leid_type;
14026   u32 leid_len = 0, reid_len = 0, len;
14027   u8 is_add = 1;
14028
14029   leid_type = reid_type = (u8) ~ 0;
14030
14031   /* Parse args required to build the message */
14032   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14033     {
14034       if (unformat (input, "del"))
14035         {
14036           is_add = 0;
14037         }
14038       else if (unformat (input, "add"))
14039         {
14040           is_add = 1;
14041         }
14042       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
14043                          &reid4, &len))
14044         {
14045           reid_type = 0;        /* ipv4 */
14046           reid_len = len;
14047         }
14048       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
14049                          &reid6, &len))
14050         {
14051           reid_type = 1;        /* ipv6 */
14052           reid_len = len;
14053         }
14054       else if (unformat (input, "reid %U", unformat_ethernet_address,
14055                          reid_mac))
14056         {
14057           reid_type = 2;        /* mac */
14058         }
14059       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
14060                          &leid4, &len))
14061         {
14062           leid_type = 0;        /* ipv4 */
14063           leid_len = len;
14064         }
14065       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
14066                          &leid6, &len))
14067         {
14068           leid_type = 1;        /* ipv6 */
14069           leid_len = len;
14070         }
14071       else if (unformat (input, "leid %U", unformat_ethernet_address,
14072                          leid_mac))
14073         {
14074           leid_type = 2;        /* mac */
14075         }
14076       else if (unformat (input, "vni %d", &vni))
14077         {
14078           ;
14079         }
14080       else
14081         {
14082           errmsg ("parse error '%U'", format_unformat_error, input);
14083           return -99;
14084         }
14085     }
14086
14087   if ((u8) ~ 0 == reid_type)
14088     {
14089       errmsg ("missing params!");
14090       return -99;
14091     }
14092
14093   if (leid_type != reid_type)
14094     {
14095       errmsg ("remote and local EIDs are of different types!");
14096       return -99;
14097     }
14098
14099   M (LISP_ADD_DEL_ADJACENCY, lisp_add_del_adjacency);
14100   mp->is_add = is_add;
14101   mp->vni = htonl (vni);
14102   mp->leid_len = leid_len;
14103   mp->reid_len = reid_len;
14104   mp->eid_type = reid_type;
14105
14106   switch (mp->eid_type)
14107     {
14108     case 0:
14109       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
14110       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
14111       break;
14112     case 1:
14113       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
14114       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
14115       break;
14116     case 2:
14117       clib_memcpy (mp->leid, leid_mac, 6);
14118       clib_memcpy (mp->reid, reid_mac, 6);
14119       break;
14120     default:
14121       errmsg ("unknown EID type %d!", mp->eid_type);
14122       return 0;
14123     }
14124
14125   /* send it... */
14126   S;
14127
14128   /* Wait for a reply... */
14129   W;
14130
14131   /* NOTREACHED */
14132   return 0;
14133 }
14134
14135 static int
14136 api_lisp_gpe_add_del_iface (vat_main_t * vam)
14137 {
14138   unformat_input_t *input = vam->input;
14139   vl_api_lisp_gpe_add_del_iface_t *mp;
14140   f64 timeout = ~0;
14141   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
14142   u32 dp_table = 0, vni = 0;
14143
14144   /* Parse args required to build the message */
14145   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14146     {
14147       if (unformat (input, "up"))
14148         {
14149           action_set = 1;
14150           is_add = 1;
14151         }
14152       else if (unformat (input, "down"))
14153         {
14154           action_set = 1;
14155           is_add = 0;
14156         }
14157       else if (unformat (input, "table_id %d", &dp_table))
14158         {
14159           dp_table_set = 1;
14160         }
14161       else if (unformat (input, "bd_id %d", &dp_table))
14162         {
14163           dp_table_set = 1;
14164           is_l2 = 1;
14165         }
14166       else if (unformat (input, "vni %d", &vni))
14167         {
14168           vni_set = 1;
14169         }
14170       else
14171         break;
14172     }
14173
14174   if (action_set == 0)
14175     {
14176       errmsg ("Action not set\n");
14177       return -99;
14178     }
14179   if (dp_table_set == 0 || vni_set == 0)
14180     {
14181       errmsg ("vni and dp_table must be set\n");
14182       return -99;
14183     }
14184
14185   /* Construct the API message */
14186   M (LISP_GPE_ADD_DEL_IFACE, lisp_gpe_add_del_iface);
14187
14188   mp->is_add = is_add;
14189   mp->dp_table = dp_table;
14190   mp->is_l2 = is_l2;
14191   mp->vni = vni;
14192
14193   /* send it... */
14194   S;
14195
14196   /* Wait for a reply... */
14197   W;
14198
14199   /* NOTREACHED */
14200   return 0;
14201 }
14202
14203 /**
14204  * Add/del map request itr rlocs from LISP control plane and updates
14205  *
14206  * @param vam vpp API test context
14207  * @return return code
14208  */
14209 static int
14210 api_lisp_add_del_map_request_itr_rlocs (vat_main_t * vam)
14211 {
14212   unformat_input_t *input = vam->input;
14213   vl_api_lisp_add_del_map_request_itr_rlocs_t *mp;
14214   f64 timeout = ~0;
14215   u8 *locator_set_name = 0;
14216   u8 locator_set_name_set = 0;
14217   u8 is_add = 1;
14218
14219   /* Parse args required to build the message */
14220   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14221     {
14222       if (unformat (input, "del"))
14223         {
14224           is_add = 0;
14225         }
14226       else if (unformat (input, "%_%v%_", &locator_set_name))
14227         {
14228           locator_set_name_set = 1;
14229         }
14230       else
14231         {
14232           clib_warning ("parse error '%U'", format_unformat_error, input);
14233           return -99;
14234         }
14235     }
14236
14237   if (is_add && !locator_set_name_set)
14238     {
14239       errmsg ("itr-rloc is not set!");
14240       return -99;
14241     }
14242
14243   if (is_add && vec_len (locator_set_name) > 64)
14244     {
14245       errmsg ("itr-rloc locator-set name too long\n");
14246       vec_free (locator_set_name);
14247       return -99;
14248     }
14249
14250   M (LISP_ADD_DEL_MAP_REQUEST_ITR_RLOCS, lisp_add_del_map_request_itr_rlocs);
14251   mp->is_add = is_add;
14252   if (is_add)
14253     {
14254       clib_memcpy (mp->locator_set_name, locator_set_name,
14255                    vec_len (locator_set_name));
14256     }
14257   else
14258     {
14259       memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
14260     }
14261   vec_free (locator_set_name);
14262
14263   /* send it... */
14264   S;
14265
14266   /* Wait for a reply... */
14267   W;
14268
14269   /* NOTREACHED */
14270   return 0;
14271 }
14272
14273 static int
14274 api_lisp_locator_dump (vat_main_t * vam)
14275 {
14276   unformat_input_t *input = vam->input;
14277   vl_api_lisp_locator_dump_t *mp;
14278   f64 timeout = ~0;
14279   u8 is_index_set = 0, is_name_set = 0;
14280   u8 *ls_name = 0;
14281   u32 ls_index = ~0;
14282
14283   /* Parse args required to build the message */
14284   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14285     {
14286       if (unformat (input, "ls_name %_%v%_", &ls_name))
14287         {
14288           is_name_set = 1;
14289         }
14290       else if (unformat (input, "ls_index %d", &ls_index))
14291         {
14292           is_index_set = 1;
14293         }
14294       else
14295         {
14296           errmsg ("parse error '%U'", format_unformat_error, input);
14297           return -99;
14298         }
14299     }
14300
14301   if (!is_index_set && !is_name_set)
14302     {
14303       errmsg ("error: expected one of index or name!\n");
14304       return -99;
14305     }
14306
14307   if (is_index_set && is_name_set)
14308     {
14309       errmsg ("error: only one param expected!\n");
14310       return -99;
14311     }
14312
14313   if (vec_len (ls_name) > 62)
14314     {
14315       errmsg ("error: locator set name too long!");
14316       return -99;
14317     }
14318
14319   if (!vam->json_output)
14320     {
14321       fformat (vam->ofp, "%=16s%=16s%=16s\n", "locator", "priority",
14322                "weight");
14323     }
14324
14325   M (LISP_LOCATOR_DUMP, lisp_locator_dump);
14326   mp->is_index_set = is_index_set;
14327
14328   if (is_index_set)
14329     mp->ls_index = clib_host_to_net_u32 (ls_index);
14330   else
14331     {
14332       vec_add1 (ls_name, 0);
14333       strncpy ((char *) mp->ls_name, (char *) ls_name,
14334                sizeof (mp->ls_name) - 1);
14335     }
14336
14337   /* send it... */
14338   S;
14339
14340   /* Use a control ping for synchronization */
14341   {
14342     vl_api_control_ping_t *mp;
14343     M (CONTROL_PING, control_ping);
14344     S;
14345   }
14346   /* Wait for a reply... */
14347   W;
14348
14349   /* NOTREACHED */
14350   return 0;
14351 }
14352
14353 static int
14354 api_lisp_locator_set_dump (vat_main_t * vam)
14355 {
14356   vl_api_lisp_locator_set_dump_t *mp;
14357   unformat_input_t *input = vam->input;
14358   f64 timeout = ~0;
14359   u8 filter = 0;
14360
14361   /* Parse args required to build the message */
14362   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14363     {
14364       if (unformat (input, "local"))
14365         {
14366           filter = 1;
14367         }
14368       else if (unformat (input, "remote"))
14369         {
14370           filter = 2;
14371         }
14372       else
14373         {
14374           errmsg ("parse error '%U'", format_unformat_error, input);
14375           return -99;
14376         }
14377     }
14378
14379   if (!vam->json_output)
14380     {
14381       fformat (vam->ofp, "%=10s%=15s\n", "ls_index", "ls_name");
14382     }
14383
14384   M (LISP_LOCATOR_SET_DUMP, lisp_locator_set_dump);
14385
14386   mp->filter = filter;
14387
14388   /* send it... */
14389   S;
14390
14391   /* Use a control ping for synchronization */
14392   {
14393     vl_api_control_ping_t *mp;
14394     M (CONTROL_PING, control_ping);
14395     S;
14396   }
14397   /* Wait for a reply... */
14398   W;
14399
14400   /* NOTREACHED */
14401   return 0;
14402 }
14403
14404 static int
14405 api_lisp_eid_table_map_dump (vat_main_t * vam)
14406 {
14407   u8 is_l2 = 0;
14408   u8 mode_set = 0;
14409   unformat_input_t *input = vam->input;
14410   vl_api_lisp_eid_table_map_dump_t *mp;
14411   f64 timeout = ~0;
14412
14413   /* Parse args required to build the message */
14414   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14415     {
14416       if (unformat (input, "l2"))
14417         {
14418           is_l2 = 1;
14419           mode_set = 1;
14420         }
14421       else if (unformat (input, "l3"))
14422         {
14423           is_l2 = 0;
14424           mode_set = 1;
14425         }
14426       else
14427         {
14428           errmsg ("parse error '%U'", format_unformat_error, input);
14429           return -99;
14430         }
14431     }
14432
14433   if (!mode_set)
14434     {
14435       errmsg ("expected one of 'l2' or 'l3' parameter!\n");
14436       return -99;
14437     }
14438
14439   if (!vam->json_output)
14440     {
14441       fformat (vam->ofp, "%=10s%=10s\n", "VNI", is_l2 ? "BD" : "VRF");
14442     }
14443
14444   M (LISP_EID_TABLE_MAP_DUMP, lisp_eid_table_map_dump);
14445   mp->is_l2 = is_l2;
14446
14447   /* send it... */
14448   S;
14449
14450   /* Use a control ping for synchronization */
14451   {
14452     vl_api_control_ping_t *mp;
14453     M (CONTROL_PING, control_ping);
14454     S;
14455   }
14456   /* Wait for a reply... */
14457   W;
14458
14459   /* NOTREACHED */
14460   return 0;
14461 }
14462
14463 static int
14464 api_lisp_eid_table_vni_dump (vat_main_t * vam)
14465 {
14466   vl_api_lisp_eid_table_vni_dump_t *mp;
14467   f64 timeout = ~0;
14468
14469   if (!vam->json_output)
14470     {
14471       fformat (vam->ofp, "VNI\n");
14472     }
14473
14474   M (LISP_EID_TABLE_VNI_DUMP, lisp_eid_table_vni_dump);
14475
14476   /* send it... */
14477   S;
14478
14479   /* Use a control ping for synchronization */
14480   {
14481     vl_api_control_ping_t *mp;
14482     M (CONTROL_PING, control_ping);
14483     S;
14484   }
14485   /* Wait for a reply... */
14486   W;
14487
14488   /* NOTREACHED */
14489   return 0;
14490 }
14491
14492 static int
14493 api_lisp_eid_table_dump (vat_main_t * vam)
14494 {
14495   unformat_input_t *i = vam->input;
14496   vl_api_lisp_eid_table_dump_t *mp;
14497   f64 timeout = ~0;
14498   struct in_addr ip4;
14499   struct in6_addr ip6;
14500   u8 mac[6];
14501   u8 eid_type = ~0, eid_set = 0;
14502   u32 prefix_length = ~0, t, vni = 0;
14503   u8 filter = 0;
14504
14505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14506     {
14507       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
14508         {
14509           eid_set = 1;
14510           eid_type = 0;
14511           prefix_length = t;
14512         }
14513       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
14514         {
14515           eid_set = 1;
14516           eid_type = 1;
14517           prefix_length = t;
14518         }
14519       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
14520         {
14521           eid_set = 1;
14522           eid_type = 2;
14523         }
14524       else if (unformat (i, "vni %d", &t))
14525         {
14526           vni = t;
14527         }
14528       else if (unformat (i, "local"))
14529         {
14530           filter = 1;
14531         }
14532       else if (unformat (i, "remote"))
14533         {
14534           filter = 2;
14535         }
14536       else
14537         {
14538           errmsg ("parse error '%U'", format_unformat_error, i);
14539           return -99;
14540         }
14541     }
14542
14543   if (!vam->json_output)
14544     {
14545       fformat (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s\n", "EID",
14546                "type", "ls_index", "ttl", "authoritative", "key_id", "key");
14547     }
14548
14549   M (LISP_EID_TABLE_DUMP, lisp_eid_table_dump);
14550
14551   mp->filter = filter;
14552   if (eid_set)
14553     {
14554       mp->eid_set = 1;
14555       mp->vni = htonl (vni);
14556       mp->eid_type = eid_type;
14557       switch (eid_type)
14558         {
14559         case 0:
14560           mp->prefix_length = prefix_length;
14561           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
14562           break;
14563         case 1:
14564           mp->prefix_length = prefix_length;
14565           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
14566           break;
14567         case 2:
14568           clib_memcpy (mp->eid, mac, sizeof (mac));
14569           break;
14570         default:
14571           errmsg ("unknown EID type %d!", eid_type);
14572           return -99;
14573         }
14574     }
14575
14576   /* send it... */
14577   S;
14578
14579   /* Use a control ping for synchronization */
14580   {
14581     vl_api_control_ping_t *mp;
14582     M (CONTROL_PING, control_ping);
14583     S;
14584   }
14585
14586   /* Wait for a reply... */
14587   W;
14588
14589   /* NOTREACHED */
14590   return 0;
14591 }
14592
14593 static int
14594 api_lisp_gpe_tunnel_dump (vat_main_t * vam)
14595 {
14596   vl_api_lisp_gpe_tunnel_dump_t *mp;
14597   f64 timeout = ~0;
14598
14599   if (!vam->json_output)
14600     {
14601       fformat (vam->ofp, "%=20s%=30s%=16s%=16s%=16s%=16s"
14602                "%=16s%=16s%=16s%=16s%=16s\n",
14603                "Tunel", "Source", "Destination", "Fib encap", "Fib decap",
14604                "Decap next", "Lisp version", "Flags", "Next protocol",
14605                "ver_res", "res", "iid");
14606     }
14607
14608   M (LISP_GPE_TUNNEL_DUMP, lisp_gpe_tunnel_dump);
14609   /* send it... */
14610   S;
14611
14612   /* Use a control ping for synchronization */
14613   {
14614     vl_api_control_ping_t *mp;
14615     M (CONTROL_PING, control_ping);
14616     S;
14617   }
14618   /* Wait for a reply... */
14619   W;
14620
14621   /* NOTREACHED */
14622   return 0;
14623 }
14624
14625 static int
14626 api_lisp_adjacencies_get (vat_main_t * vam)
14627 {
14628   unformat_input_t *i = vam->input;
14629   vl_api_lisp_adjacencies_get_t *mp;
14630   f64 timeout = ~0;
14631   u8 vni_set = 0;
14632   u32 vni = ~0;
14633
14634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14635     {
14636       if (unformat (i, "vni %d", &vni))
14637         {
14638           vni_set = 1;
14639         }
14640       else
14641         {
14642           errmsg ("parse error '%U'\n", format_unformat_error, i);
14643           return -99;
14644         }
14645     }
14646
14647   if (!vni_set)
14648     {
14649       errmsg ("vni not set!\n");
14650       return -99;
14651     }
14652
14653   if (!vam->json_output)
14654     {
14655       fformat (vam->ofp, "%s %40s\n", "leid", "reid");
14656     }
14657
14658   M (LISP_ADJACENCIES_GET, lisp_adjacencies_get);
14659   mp->vni = clib_host_to_net_u32 (vni);
14660
14661   /* send it... */
14662   S;
14663
14664   /* Wait for a reply... */
14665   W;
14666
14667   /* NOTREACHED */
14668   return 0;
14669 }
14670
14671 static int
14672 api_lisp_map_server_dump (vat_main_t * vam)
14673 {
14674   vl_api_lisp_map_server_dump_t *mp;
14675   f64 timeout = ~0;
14676
14677   if (!vam->json_output)
14678     {
14679       fformat (vam->ofp, "%=20s\n", "Map server");
14680     }
14681
14682   M (LISP_MAP_SERVER_DUMP, lisp_map_server_dump);
14683   /* send it... */
14684   S;
14685
14686   /* Use a control ping for synchronization */
14687   {
14688     vl_api_control_ping_t *mp;
14689     M (CONTROL_PING, control_ping);
14690     S;
14691   }
14692   /* Wait for a reply... */
14693   W;
14694
14695   /* NOTREACHED */
14696   return 0;
14697 }
14698
14699 static int
14700 api_lisp_map_resolver_dump (vat_main_t * vam)
14701 {
14702   vl_api_lisp_map_resolver_dump_t *mp;
14703   f64 timeout = ~0;
14704
14705   if (!vam->json_output)
14706     {
14707       fformat (vam->ofp, "%=20s\n", "Map resolver");
14708     }
14709
14710   M (LISP_MAP_RESOLVER_DUMP, lisp_map_resolver_dump);
14711   /* send it... */
14712   S;
14713
14714   /* Use a control ping for synchronization */
14715   {
14716     vl_api_control_ping_t *mp;
14717     M (CONTROL_PING, control_ping);
14718     S;
14719   }
14720   /* Wait for a reply... */
14721   W;
14722
14723   /* NOTREACHED */
14724   return 0;
14725 }
14726
14727 static int
14728 api_show_lisp_status (vat_main_t * vam)
14729 {
14730   vl_api_show_lisp_status_t *mp;
14731   f64 timeout = ~0;
14732
14733   if (!vam->json_output)
14734     {
14735       fformat (vam->ofp, "%-20s%-16s\n", "lisp status", "locator-set");
14736     }
14737
14738   M (SHOW_LISP_STATUS, show_lisp_status);
14739   /* send it... */
14740   S;
14741   /* Wait for a reply... */
14742   W;
14743
14744   /* NOTREACHED */
14745   return 0;
14746 }
14747
14748 static int
14749 api_lisp_get_map_request_itr_rlocs (vat_main_t * vam)
14750 {
14751   vl_api_lisp_get_map_request_itr_rlocs_t *mp;
14752   f64 timeout = ~0;
14753
14754   if (!vam->json_output)
14755     {
14756       fformat (vam->ofp, "%=20s\n", "itr-rlocs:");
14757     }
14758
14759   M (LISP_GET_MAP_REQUEST_ITR_RLOCS, lisp_get_map_request_itr_rlocs);
14760   /* send it... */
14761   S;
14762   /* Wait for a reply... */
14763   W;
14764
14765   /* NOTREACHED */
14766   return 0;
14767 }
14768
14769 static int
14770 api_af_packet_create (vat_main_t * vam)
14771 {
14772   unformat_input_t *i = vam->input;
14773   vl_api_af_packet_create_t *mp;
14774   f64 timeout;
14775   u8 *host_if_name = 0;
14776   u8 hw_addr[6];
14777   u8 random_hw_addr = 1;
14778
14779   memset (hw_addr, 0, sizeof (hw_addr));
14780
14781   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14782     {
14783       if (unformat (i, "name %s", &host_if_name))
14784         vec_add1 (host_if_name, 0);
14785       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
14786         random_hw_addr = 0;
14787       else
14788         break;
14789     }
14790
14791   if (!vec_len (host_if_name))
14792     {
14793       errmsg ("host-interface name must be specified");
14794       return -99;
14795     }
14796
14797   if (vec_len (host_if_name) > 64)
14798     {
14799       errmsg ("host-interface name too long");
14800       return -99;
14801     }
14802
14803   M (AF_PACKET_CREATE, af_packet_create);
14804
14805   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14806   clib_memcpy (mp->hw_addr, hw_addr, 6);
14807   mp->use_random_hw_addr = random_hw_addr;
14808   vec_free (host_if_name);
14809
14810   S;
14811   W2 (fprintf (vam->ofp, " new sw_if_index = %d ", vam->sw_if_index));
14812   /* NOTREACHED */
14813   return 0;
14814 }
14815
14816 static int
14817 api_af_packet_delete (vat_main_t * vam)
14818 {
14819   unformat_input_t *i = vam->input;
14820   vl_api_af_packet_delete_t *mp;
14821   f64 timeout;
14822   u8 *host_if_name = 0;
14823
14824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14825     {
14826       if (unformat (i, "name %s", &host_if_name))
14827         vec_add1 (host_if_name, 0);
14828       else
14829         break;
14830     }
14831
14832   if (!vec_len (host_if_name))
14833     {
14834       errmsg ("host-interface name must be specified");
14835       return -99;
14836     }
14837
14838   if (vec_len (host_if_name) > 64)
14839     {
14840       errmsg ("host-interface name too long");
14841       return -99;
14842     }
14843
14844   M (AF_PACKET_DELETE, af_packet_delete);
14845
14846   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
14847   vec_free (host_if_name);
14848
14849   S;
14850   W;
14851   /* NOTREACHED */
14852   return 0;
14853 }
14854
14855 static int
14856 api_policer_add_del (vat_main_t * vam)
14857 {
14858   unformat_input_t *i = vam->input;
14859   vl_api_policer_add_del_t *mp;
14860   f64 timeout;
14861   u8 is_add = 1;
14862   u8 *name = 0;
14863   u32 cir = 0;
14864   u32 eir = 0;
14865   u64 cb = 0;
14866   u64 eb = 0;
14867   u8 rate_type = 0;
14868   u8 round_type = 0;
14869   u8 type = 0;
14870   u8 color_aware = 0;
14871   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
14872
14873   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
14874   conform_action.dscp = 0;
14875   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
14876   exceed_action.dscp = 0;
14877   violate_action.action_type = SSE2_QOS_ACTION_DROP;
14878   violate_action.dscp = 0;
14879
14880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14881     {
14882       if (unformat (i, "del"))
14883         is_add = 0;
14884       else if (unformat (i, "name %s", &name))
14885         vec_add1 (name, 0);
14886       else if (unformat (i, "cir %u", &cir))
14887         ;
14888       else if (unformat (i, "eir %u", &eir))
14889         ;
14890       else if (unformat (i, "cb %u", &cb))
14891         ;
14892       else if (unformat (i, "eb %u", &eb))
14893         ;
14894       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
14895                          &rate_type))
14896         ;
14897       else if (unformat (i, "round_type %U", unformat_policer_round_type,
14898                          &round_type))
14899         ;
14900       else if (unformat (i, "type %U", unformat_policer_type, &type))
14901         ;
14902       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
14903                          &conform_action))
14904         ;
14905       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
14906                          &exceed_action))
14907         ;
14908       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
14909                          &violate_action))
14910         ;
14911       else if (unformat (i, "color-aware"))
14912         color_aware = 1;
14913       else
14914         break;
14915     }
14916
14917   if (!vec_len (name))
14918     {
14919       errmsg ("policer name must be specified");
14920       return -99;
14921     }
14922
14923   if (vec_len (name) > 64)
14924     {
14925       errmsg ("policer name too long");
14926       return -99;
14927     }
14928
14929   M (POLICER_ADD_DEL, policer_add_del);
14930
14931   clib_memcpy (mp->name, name, vec_len (name));
14932   vec_free (name);
14933   mp->is_add = is_add;
14934   mp->cir = cir;
14935   mp->eir = eir;
14936   mp->cb = cb;
14937   mp->eb = eb;
14938   mp->rate_type = rate_type;
14939   mp->round_type = round_type;
14940   mp->type = type;
14941   mp->conform_action_type = conform_action.action_type;
14942   mp->conform_dscp = conform_action.dscp;
14943   mp->exceed_action_type = exceed_action.action_type;
14944   mp->exceed_dscp = exceed_action.dscp;
14945   mp->violate_action_type = violate_action.action_type;
14946   mp->violate_dscp = violate_action.dscp;
14947   mp->color_aware = color_aware;
14948
14949   S;
14950   W;
14951   /* NOTREACHED */
14952   return 0;
14953 }
14954
14955 static int
14956 api_policer_dump (vat_main_t * vam)
14957 {
14958   unformat_input_t *i = vam->input;
14959   vl_api_policer_dump_t *mp;
14960   f64 timeout = ~0;
14961   u8 *match_name = 0;
14962   u8 match_name_valid = 0;
14963
14964   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14965     {
14966       if (unformat (i, "name %s", &match_name))
14967         {
14968           vec_add1 (match_name, 0);
14969           match_name_valid = 1;
14970         }
14971       else
14972         break;
14973     }
14974
14975   M (POLICER_DUMP, policer_dump);
14976   mp->match_name_valid = match_name_valid;
14977   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
14978   vec_free (match_name);
14979   /* send it... */
14980   S;
14981
14982   /* Use a control ping for synchronization */
14983   {
14984     vl_api_control_ping_t *mp;
14985     M (CONTROL_PING, control_ping);
14986     S;
14987   }
14988   /* Wait for a reply... */
14989   W;
14990
14991   /* NOTREACHED */
14992   return 0;
14993 }
14994
14995 static int
14996 api_policer_classify_set_interface (vat_main_t * vam)
14997 {
14998   unformat_input_t *i = vam->input;
14999   vl_api_policer_classify_set_interface_t *mp;
15000   f64 timeout;
15001   u32 sw_if_index;
15002   int sw_if_index_set;
15003   u32 ip4_table_index = ~0;
15004   u32 ip6_table_index = ~0;
15005   u32 l2_table_index = ~0;
15006   u8 is_add = 1;
15007
15008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15009     {
15010       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15011         sw_if_index_set = 1;
15012       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15013         sw_if_index_set = 1;
15014       else if (unformat (i, "del"))
15015         is_add = 0;
15016       else if (unformat (i, "ip4-table %d", &ip4_table_index))
15017         ;
15018       else if (unformat (i, "ip6-table %d", &ip6_table_index))
15019         ;
15020       else if (unformat (i, "l2-table %d", &l2_table_index))
15021         ;
15022       else
15023         {
15024           clib_warning ("parse error '%U'", format_unformat_error, i);
15025           return -99;
15026         }
15027     }
15028
15029   if (sw_if_index_set == 0)
15030     {
15031       errmsg ("missing interface name or sw_if_index\n");
15032       return -99;
15033     }
15034
15035   M (POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface);
15036
15037   mp->sw_if_index = ntohl (sw_if_index);
15038   mp->ip4_table_index = ntohl (ip4_table_index);
15039   mp->ip6_table_index = ntohl (ip6_table_index);
15040   mp->l2_table_index = ntohl (l2_table_index);
15041   mp->is_add = is_add;
15042
15043   S;
15044   W;
15045   /* NOTREACHED */
15046   return 0;
15047 }
15048
15049 static int
15050 api_policer_classify_dump (vat_main_t * vam)
15051 {
15052   unformat_input_t *i = vam->input;
15053   vl_api_policer_classify_dump_t *mp;
15054   f64 timeout = ~0;
15055   u8 type = POLICER_CLASSIFY_N_TABLES;
15056
15057   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
15058     ;
15059   else
15060     {
15061       errmsg ("classify table type must be specified\n");
15062       return -99;
15063     }
15064
15065   if (!vam->json_output)
15066     {
15067       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
15068     }
15069
15070   M (POLICER_CLASSIFY_DUMP, policer_classify_dump);
15071   mp->type = type;
15072   /* send it... */
15073   S;
15074
15075   /* Use a control ping for synchronization */
15076   {
15077     vl_api_control_ping_t *mp;
15078     M (CONTROL_PING, control_ping);
15079     S;
15080   }
15081   /* Wait for a reply... */
15082   W;
15083
15084   /* NOTREACHED */
15085   return 0;
15086 }
15087
15088 static int
15089 api_netmap_create (vat_main_t * vam)
15090 {
15091   unformat_input_t *i = vam->input;
15092   vl_api_netmap_create_t *mp;
15093   f64 timeout;
15094   u8 *if_name = 0;
15095   u8 hw_addr[6];
15096   u8 random_hw_addr = 1;
15097   u8 is_pipe = 0;
15098   u8 is_master = 0;
15099
15100   memset (hw_addr, 0, sizeof (hw_addr));
15101
15102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15103     {
15104       if (unformat (i, "name %s", &if_name))
15105         vec_add1 (if_name, 0);
15106       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
15107         random_hw_addr = 0;
15108       else if (unformat (i, "pipe"))
15109         is_pipe = 1;
15110       else if (unformat (i, "master"))
15111         is_master = 1;
15112       else if (unformat (i, "slave"))
15113         is_master = 0;
15114       else
15115         break;
15116     }
15117
15118   if (!vec_len (if_name))
15119     {
15120       errmsg ("interface name must be specified");
15121       return -99;
15122     }
15123
15124   if (vec_len (if_name) > 64)
15125     {
15126       errmsg ("interface name too long");
15127       return -99;
15128     }
15129
15130   M (NETMAP_CREATE, netmap_create);
15131
15132   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15133   clib_memcpy (mp->hw_addr, hw_addr, 6);
15134   mp->use_random_hw_addr = random_hw_addr;
15135   mp->is_pipe = is_pipe;
15136   mp->is_master = is_master;
15137   vec_free (if_name);
15138
15139   S;
15140   W;
15141   /* NOTREACHED */
15142   return 0;
15143 }
15144
15145 static int
15146 api_netmap_delete (vat_main_t * vam)
15147 {
15148   unformat_input_t *i = vam->input;
15149   vl_api_netmap_delete_t *mp;
15150   f64 timeout;
15151   u8 *if_name = 0;
15152
15153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15154     {
15155       if (unformat (i, "name %s", &if_name))
15156         vec_add1 (if_name, 0);
15157       else
15158         break;
15159     }
15160
15161   if (!vec_len (if_name))
15162     {
15163       errmsg ("interface name must be specified");
15164       return -99;
15165     }
15166
15167   if (vec_len (if_name) > 64)
15168     {
15169       errmsg ("interface name too long");
15170       return -99;
15171     }
15172
15173   M (NETMAP_DELETE, netmap_delete);
15174
15175   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
15176   vec_free (if_name);
15177
15178   S;
15179   W;
15180   /* NOTREACHED */
15181   return 0;
15182 }
15183
15184 static void vl_api_mpls_tunnel_details_t_handler
15185   (vl_api_mpls_tunnel_details_t * mp)
15186 {
15187   vat_main_t *vam = &vat_main;
15188   i32 len = mp->mt_next_hop_n_labels;
15189   i32 i;
15190
15191   fformat (vam->ofp, "[%d]: via %U %d labels ",
15192            mp->tunnel_index,
15193            format_ip4_address, mp->mt_next_hop,
15194            ntohl (mp->mt_next_hop_sw_if_index));
15195   for (i = 0; i < len; i++)
15196     {
15197       fformat (vam->ofp, "%u ", ntohl (mp->mt_next_hop_out_labels[i]));
15198     }
15199   fformat (vam->ofp, "\n");
15200 }
15201
15202 static void vl_api_mpls_tunnel_details_t_handler_json
15203   (vl_api_mpls_tunnel_details_t * mp)
15204 {
15205   vat_main_t *vam = &vat_main;
15206   vat_json_node_t *node = NULL;
15207   struct in_addr ip4;
15208   i32 i;
15209   i32 len = mp->mt_next_hop_n_labels;
15210
15211   if (VAT_JSON_ARRAY != vam->json_tree.type)
15212     {
15213       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15214       vat_json_init_array (&vam->json_tree);
15215     }
15216   node = vat_json_array_add (&vam->json_tree);
15217
15218   vat_json_init_object (node);
15219   vat_json_object_add_uint (node, "tunnel_index", ntohl (mp->tunnel_index));
15220   clib_memcpy (&ip4, &(mp->mt_next_hop), sizeof (ip4));
15221   vat_json_object_add_ip4 (node, "next_hop", ip4);
15222   vat_json_object_add_uint (node, "next_hop_sw_if_index",
15223                             ntohl (mp->mt_next_hop_sw_if_index));
15224   vat_json_object_add_uint (node, "l2_only", ntohl (mp->mt_l2_only));
15225   vat_json_object_add_uint (node, "label_count", len);
15226   for (i = 0; i < len; i++)
15227     {
15228       vat_json_object_add_uint (node, "label",
15229                                 ntohl (mp->mt_next_hop_out_labels[i]));
15230     }
15231 }
15232
15233 static int
15234 api_mpls_tunnel_dump (vat_main_t * vam)
15235 {
15236   vl_api_mpls_tunnel_dump_t *mp;
15237   f64 timeout;
15238   i32 index = -1;
15239
15240   /* Parse args required to build the message */
15241   while (unformat_check_input (vam->input) != UNFORMAT_END_OF_INPUT)
15242     {
15243       if (!unformat (vam->input, "tunnel_index %d", &index))
15244         {
15245           index = -1;
15246           break;
15247         }
15248     }
15249
15250   fformat (vam->ofp, "  tunnel_index %d\n", index);
15251
15252   M (MPLS_TUNNEL_DUMP, mpls_tunnel_dump);
15253   mp->tunnel_index = htonl (index);
15254   S;
15255
15256   /* Use a control ping for synchronization */
15257   {
15258     vl_api_control_ping_t *mp;
15259     M (CONTROL_PING, control_ping);
15260     S;
15261   }
15262   W;
15263 }
15264
15265 #define vl_api_mpls_fib_details_t_endian vl_noop_handler
15266 #define vl_api_mpls_fib_details_t_print vl_noop_handler
15267
15268 static void
15269 vl_api_mpls_fib_details_t_handler (vl_api_mpls_fib_details_t * mp)
15270 {
15271   vat_main_t *vam = &vat_main;
15272   int count = ntohl (mp->count);
15273   vl_api_fib_path2_t *fp;
15274   int i;
15275
15276   fformat (vam->ofp,
15277            "table-id %d, label %u, ess_bit %u\n",
15278            ntohl (mp->table_id), ntohl (mp->label), mp->eos_bit);
15279   fp = mp->path;
15280   for (i = 0; i < count; i++)
15281     {
15282       if (fp->afi == IP46_TYPE_IP6)
15283         fformat (vam->ofp,
15284                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15285                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15286                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15287                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15288                  format_ip6_address, fp->next_hop);
15289       else if (fp->afi == IP46_TYPE_IP4)
15290         fformat (vam->ofp,
15291                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15292                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15293                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15294                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15295                  format_ip4_address, fp->next_hop);
15296       fp++;
15297     }
15298 }
15299
15300 static void vl_api_mpls_fib_details_t_handler_json
15301   (vl_api_mpls_fib_details_t * mp)
15302 {
15303   vat_main_t *vam = &vat_main;
15304   int count = ntohl (mp->count);
15305   vat_json_node_t *node = NULL;
15306   struct in_addr ip4;
15307   struct in6_addr ip6;
15308   vl_api_fib_path2_t *fp;
15309   int i;
15310
15311   if (VAT_JSON_ARRAY != vam->json_tree.type)
15312     {
15313       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15314       vat_json_init_array (&vam->json_tree);
15315     }
15316   node = vat_json_array_add (&vam->json_tree);
15317
15318   vat_json_init_object (node);
15319   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15320   vat_json_object_add_uint (node, "s_bit", mp->eos_bit);
15321   vat_json_object_add_uint (node, "label", ntohl (mp->label));
15322   vat_json_object_add_uint (node, "path_count", count);
15323   fp = mp->path;
15324   for (i = 0; i < count; i++)
15325     {
15326       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15327       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15328       vat_json_object_add_uint (node, "is_local", fp->is_local);
15329       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15330       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15331       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15332       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15333       if (fp->afi == IP46_TYPE_IP4)
15334         {
15335           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15336           vat_json_object_add_ip4 (node, "next_hop", ip4);
15337         }
15338       else if (fp->afi == IP46_TYPE_IP6)
15339         {
15340           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15341           vat_json_object_add_ip6 (node, "next_hop", ip6);
15342         }
15343     }
15344 }
15345
15346 static int
15347 api_mpls_fib_dump (vat_main_t * vam)
15348 {
15349   vl_api_mpls_fib_dump_t *mp;
15350   f64 timeout;
15351
15352   M (MPLS_FIB_DUMP, mpls_fib_dump);
15353   S;
15354
15355   /* Use a control ping for synchronization */
15356   {
15357     vl_api_control_ping_t *mp;
15358     M (CONTROL_PING, control_ping);
15359     S;
15360   }
15361   W;
15362 }
15363
15364 #define vl_api_ip_fib_details_t_endian vl_noop_handler
15365 #define vl_api_ip_fib_details_t_print vl_noop_handler
15366
15367 static void
15368 vl_api_ip_fib_details_t_handler (vl_api_ip_fib_details_t * mp)
15369 {
15370   vat_main_t *vam = &vat_main;
15371   int count = ntohl (mp->count);
15372   vl_api_fib_path_t *fp;
15373   int i;
15374
15375   fformat (vam->ofp,
15376            "table-id %d, prefix %U/%d\n",
15377            ntohl (mp->table_id), format_ip4_address, mp->address,
15378            mp->address_length);
15379   fp = mp->path;
15380   for (i = 0; i < count; i++)
15381     {
15382       if (fp->afi == IP46_TYPE_IP6)
15383         fformat (vam->ofp,
15384                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15385                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15386                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15387                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15388                  format_ip6_address, fp->next_hop);
15389       else if (fp->afi == IP46_TYPE_IP4)
15390         fformat (vam->ofp,
15391                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15392                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15393                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15394                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15395                  format_ip4_address, fp->next_hop);
15396       fp++;
15397     }
15398 }
15399
15400 static void vl_api_ip_fib_details_t_handler_json
15401   (vl_api_ip_fib_details_t * mp)
15402 {
15403   vat_main_t *vam = &vat_main;
15404   int count = ntohl (mp->count);
15405   vat_json_node_t *node = NULL;
15406   struct in_addr ip4;
15407   struct in6_addr ip6;
15408   vl_api_fib_path_t *fp;
15409   int i;
15410
15411   if (VAT_JSON_ARRAY != vam->json_tree.type)
15412     {
15413       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15414       vat_json_init_array (&vam->json_tree);
15415     }
15416   node = vat_json_array_add (&vam->json_tree);
15417
15418   vat_json_init_object (node);
15419   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15420   clib_memcpy (&ip4, &mp->address, sizeof (ip4));
15421   vat_json_object_add_ip4 (node, "prefix", ip4);
15422   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15423   vat_json_object_add_uint (node, "path_count", count);
15424   fp = mp->path;
15425   for (i = 0; i < count; i++)
15426     {
15427       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15428       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15429       vat_json_object_add_uint (node, "is_local", fp->is_local);
15430       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15431       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15432       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15433       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15434       if (fp->afi == IP46_TYPE_IP4)
15435         {
15436           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15437           vat_json_object_add_ip4 (node, "next_hop", ip4);
15438         }
15439       else if (fp->afi == IP46_TYPE_IP6)
15440         {
15441           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15442           vat_json_object_add_ip6 (node, "next_hop", ip6);
15443         }
15444     }
15445 }
15446
15447 static int
15448 api_ip_fib_dump (vat_main_t * vam)
15449 {
15450   vl_api_ip_fib_dump_t *mp;
15451   f64 timeout;
15452
15453   M (IP_FIB_DUMP, ip_fib_dump);
15454   S;
15455
15456   /* Use a control ping for synchronization */
15457   {
15458     vl_api_control_ping_t *mp;
15459     M (CONTROL_PING, control_ping);
15460     S;
15461   }
15462   W;
15463 }
15464
15465 static void vl_api_ip_neighbor_details_t_handler
15466   (vl_api_ip_neighbor_details_t * mp)
15467 {
15468   vat_main_t *vam = &vat_main;
15469
15470   fformat (vam->ofp, "%c %U %U\n",
15471            (mp->is_static) ? 'S' : 'D',
15472            format_ethernet_address, &mp->mac_address,
15473            (mp->is_ipv6) ? format_ip6_address : format_ip4_address,
15474            &mp->ip_address);
15475 }
15476
15477 static void vl_api_ip_neighbor_details_t_handler_json
15478   (vl_api_ip_neighbor_details_t * mp)
15479 {
15480
15481   vat_main_t *vam = &vat_main;
15482   vat_json_node_t *node;
15483   struct in_addr ip4;
15484   struct in6_addr ip6;
15485
15486   if (VAT_JSON_ARRAY != vam->json_tree.type)
15487     {
15488       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15489       vat_json_init_array (&vam->json_tree);
15490     }
15491   node = vat_json_array_add (&vam->json_tree);
15492
15493   vat_json_init_object (node);
15494   vat_json_object_add_string_copy (node, "flag",
15495                                    (mp->is_static) ? (u8 *) "static" : (u8 *)
15496                                    "dynamic");
15497
15498   vat_json_object_add_string_copy (node, "link_layer",
15499                                    format (0, "%U", format_ethernet_address,
15500                                            &mp->mac_address));
15501
15502   if (mp->is_ipv6)
15503     {
15504       clib_memcpy (&ip6, &mp->ip_address, sizeof (ip6));
15505       vat_json_object_add_ip6 (node, "ip_address", ip6);
15506     }
15507   else
15508     {
15509       clib_memcpy (&ip4, &mp->ip_address, sizeof (ip4));
15510       vat_json_object_add_ip4 (node, "ip_address", ip4);
15511     }
15512 }
15513
15514 static int
15515 api_ip_neighbor_dump (vat_main_t * vam)
15516 {
15517   unformat_input_t *i = vam->input;
15518   vl_api_ip_neighbor_dump_t *mp;
15519   f64 timeout;
15520   u8 is_ipv6 = 0;
15521   u32 sw_if_index = ~0;
15522
15523   /* Parse args required to build the message */
15524   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15525     {
15526       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
15527         ;
15528       else if (unformat (i, "sw_if_index %d", &sw_if_index))
15529         ;
15530       else if (unformat (i, "ip6"))
15531         is_ipv6 = 1;
15532       else
15533         break;
15534     }
15535
15536   if (sw_if_index == ~0)
15537     {
15538       errmsg ("missing interface name or sw_if_index\n");
15539       return -99;
15540     }
15541
15542   M (IP_NEIGHBOR_DUMP, ip_neighbor_dump);
15543   mp->is_ipv6 = (u8) is_ipv6;
15544   mp->sw_if_index = ntohl (sw_if_index);
15545   S;
15546
15547   /* Use a control ping for synchronization */
15548   {
15549     vl_api_control_ping_t *mp;
15550     M (CONTROL_PING, control_ping);
15551     S;
15552   }
15553   W;
15554 }
15555
15556 #define vl_api_ip6_fib_details_t_endian vl_noop_handler
15557 #define vl_api_ip6_fib_details_t_print vl_noop_handler
15558
15559 static void
15560 vl_api_ip6_fib_details_t_handler (vl_api_ip6_fib_details_t * mp)
15561 {
15562   vat_main_t *vam = &vat_main;
15563   int count = ntohl (mp->count);
15564   vl_api_fib_path_t *fp;
15565   int i;
15566
15567   fformat (vam->ofp,
15568            "table-id %d, prefix %U/%d\n",
15569            ntohl (mp->table_id), format_ip6_address, mp->address,
15570            mp->address_length);
15571   fp = mp->path;
15572   for (i = 0; i < count; i++)
15573     {
15574       if (fp->afi == IP46_TYPE_IP6)
15575         fformat (vam->ofp,
15576                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15577                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15578                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15579                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15580                  format_ip6_address, fp->next_hop);
15581       else if (fp->afi == IP46_TYPE_IP4)
15582         fformat (vam->ofp,
15583                  "  weight %d, sw_if_index %d, is_local %d, is_drop %d, "
15584                  "is_unreach %d, is_prohitbit %d, afi %d, next_hop %U\n",
15585                  ntohl (fp->weight), ntohl (fp->sw_if_index), fp->is_local,
15586                  fp->is_drop, fp->is_unreach, fp->is_prohibit, fp->afi,
15587                  format_ip4_address, fp->next_hop);
15588       fp++;
15589     }
15590 }
15591
15592 static void vl_api_ip6_fib_details_t_handler_json
15593   (vl_api_ip6_fib_details_t * mp)
15594 {
15595   vat_main_t *vam = &vat_main;
15596   int count = ntohl (mp->count);
15597   vat_json_node_t *node = NULL;
15598   struct in_addr ip4;
15599   struct in6_addr ip6;
15600   vl_api_fib_path_t *fp;
15601   int i;
15602
15603   if (VAT_JSON_ARRAY != vam->json_tree.type)
15604     {
15605       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15606       vat_json_init_array (&vam->json_tree);
15607     }
15608   node = vat_json_array_add (&vam->json_tree);
15609
15610   vat_json_init_object (node);
15611   vat_json_object_add_uint (node, "table", ntohl (mp->table_id));
15612   clib_memcpy (&ip6, &mp->address, sizeof (ip6));
15613   vat_json_object_add_ip6 (node, "prefix", ip6);
15614   vat_json_object_add_uint (node, "mask_length", mp->address_length);
15615   vat_json_object_add_uint (node, "path_count", count);
15616   fp = mp->path;
15617   for (i = 0; i < count; i++)
15618     {
15619       vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
15620       vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
15621       vat_json_object_add_uint (node, "is_local", fp->is_local);
15622       vat_json_object_add_uint (node, "is_drop", fp->is_drop);
15623       vat_json_object_add_uint (node, "is_unreach", fp->is_unreach);
15624       vat_json_object_add_uint (node, "is_prohibit", fp->is_prohibit);
15625       vat_json_object_add_uint (node, "next_hop_afi", fp->afi);
15626       if (fp->afi == IP46_TYPE_IP4)
15627         {
15628           clib_memcpy (&ip4, &fp->next_hop, sizeof (ip4));
15629           vat_json_object_add_ip4 (node, "next_hop", ip4);
15630         }
15631       else if (fp->afi == IP46_TYPE_IP6)
15632         {
15633           clib_memcpy (&ip6, &fp->next_hop, sizeof (ip6));
15634           vat_json_object_add_ip6 (node, "next_hop", ip6);
15635         }
15636     }
15637 }
15638
15639 static int
15640 api_ip6_fib_dump (vat_main_t * vam)
15641 {
15642   vl_api_ip6_fib_dump_t *mp;
15643   f64 timeout;
15644
15645   M (IP6_FIB_DUMP, ip6_fib_dump);
15646   S;
15647
15648   /* Use a control ping for synchronization */
15649   {
15650     vl_api_control_ping_t *mp;
15651     M (CONTROL_PING, control_ping);
15652     S;
15653   }
15654   W;
15655 }
15656
15657 int
15658 api_classify_table_ids (vat_main_t * vam)
15659 {
15660   vl_api_classify_table_ids_t *mp;
15661   f64 timeout;
15662
15663   /* Construct the API message */
15664   M (CLASSIFY_TABLE_IDS, classify_table_ids);
15665   mp->context = 0;
15666
15667   S;
15668   W;
15669   /* NOTREACHED */
15670   return 0;
15671 }
15672
15673 int
15674 api_classify_table_by_interface (vat_main_t * vam)
15675 {
15676   unformat_input_t *input = vam->input;
15677   vl_api_classify_table_by_interface_t *mp;
15678   f64 timeout;
15679
15680   u32 sw_if_index = ~0;
15681   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15682     {
15683       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
15684         ;
15685       else if (unformat (input, "sw_if_index %d", &sw_if_index))
15686         ;
15687       else
15688         break;
15689     }
15690   if (sw_if_index == ~0)
15691     {
15692       errmsg ("missing interface name or sw_if_index\n");
15693       return -99;
15694     }
15695
15696   /* Construct the API message */
15697   M (CLASSIFY_TABLE_BY_INTERFACE, classify_table_by_interface);
15698   mp->context = 0;
15699   mp->sw_if_index = ntohl (sw_if_index);
15700
15701   S;
15702   W;
15703   /* NOTREACHED */
15704   return 0;
15705 }
15706
15707 int
15708 api_classify_table_info (vat_main_t * vam)
15709 {
15710   unformat_input_t *input = vam->input;
15711   vl_api_classify_table_info_t *mp;
15712   f64 timeout;
15713
15714   u32 table_id = ~0;
15715   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15716     {
15717       if (unformat (input, "table_id %d", &table_id))
15718         ;
15719       else
15720         break;
15721     }
15722   if (table_id == ~0)
15723     {
15724       errmsg ("missing table id\n");
15725       return -99;
15726     }
15727
15728   /* Construct the API message */
15729   M (CLASSIFY_TABLE_INFO, classify_table_info);
15730   mp->context = 0;
15731   mp->table_id = ntohl (table_id);
15732
15733   S;
15734   W;
15735   /* NOTREACHED */
15736   return 0;
15737 }
15738
15739 int
15740 api_classify_session_dump (vat_main_t * vam)
15741 {
15742   unformat_input_t *input = vam->input;
15743   vl_api_classify_session_dump_t *mp;
15744   f64 timeout;
15745
15746   u32 table_id = ~0;
15747   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15748     {
15749       if (unformat (input, "table_id %d", &table_id))
15750         ;
15751       else
15752         break;
15753     }
15754   if (table_id == ~0)
15755     {
15756       errmsg ("missing table id\n");
15757       return -99;
15758     }
15759
15760   /* Construct the API message */
15761   M (CLASSIFY_SESSION_DUMP, classify_session_dump);
15762   mp->context = 0;
15763   mp->table_id = ntohl (table_id);
15764   S;
15765
15766   /* Use a control ping for synchronization */
15767   {
15768     vl_api_control_ping_t *mp;
15769     M (CONTROL_PING, control_ping);
15770     S;
15771   }
15772   W;
15773   /* NOTREACHED */
15774   return 0;
15775 }
15776
15777 static void
15778 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
15779 {
15780   vat_main_t *vam = &vat_main;
15781
15782   fformat (vam->ofp, "collector_address %U, collector_port %d, "
15783            "src_address %U, vrf_id %d, path_mtu %u, "
15784            "template_interval %u, udp_checksum %d\n",
15785            format_ip4_address, mp->collector_address,
15786            ntohs (mp->collector_port),
15787            format_ip4_address, mp->src_address,
15788            ntohl (mp->vrf_id), ntohl (mp->path_mtu),
15789            ntohl (mp->template_interval), mp->udp_checksum);
15790
15791   vam->retval = 0;
15792   vam->result_ready = 1;
15793 }
15794
15795 static void
15796   vl_api_ipfix_exporter_details_t_handler_json
15797   (vl_api_ipfix_exporter_details_t * mp)
15798 {
15799   vat_main_t *vam = &vat_main;
15800   vat_json_node_t node;
15801   struct in_addr collector_address;
15802   struct in_addr src_address;
15803
15804   vat_json_init_object (&node);
15805   clib_memcpy (&collector_address, &mp->collector_address,
15806                sizeof (collector_address));
15807   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
15808   vat_json_object_add_uint (&node, "collector_port",
15809                             ntohs (mp->collector_port));
15810   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
15811   vat_json_object_add_ip4 (&node, "src_address", src_address);
15812   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
15813   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
15814   vat_json_object_add_uint (&node, "template_interval",
15815                             ntohl (mp->template_interval));
15816   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
15817
15818   vat_json_print (vam->ofp, &node);
15819   vat_json_free (&node);
15820   vam->retval = 0;
15821   vam->result_ready = 1;
15822 }
15823
15824 int
15825 api_ipfix_exporter_dump (vat_main_t * vam)
15826 {
15827   vl_api_ipfix_exporter_dump_t *mp;
15828   f64 timeout;
15829
15830   /* Construct the API message */
15831   M (IPFIX_EXPORTER_DUMP, ipfix_exporter_dump);
15832   mp->context = 0;
15833
15834   S;
15835   W;
15836   /* NOTREACHED */
15837   return 0;
15838 }
15839
15840 static int
15841 api_ipfix_classify_stream_dump (vat_main_t * vam)
15842 {
15843   vl_api_ipfix_classify_stream_dump_t *mp;
15844   f64 timeout;
15845
15846   /* Construct the API message */
15847   M (IPFIX_CLASSIFY_STREAM_DUMP, ipfix_classify_stream_dump);
15848   mp->context = 0;
15849
15850   S;
15851   W;
15852   /* NOTREACHED */
15853   return 0;
15854 }
15855
15856 static void
15857   vl_api_ipfix_classify_stream_details_t_handler
15858   (vl_api_ipfix_classify_stream_details_t * mp)
15859 {
15860   vat_main_t *vam = &vat_main;
15861   fformat (vam->ofp, "domain_id %d, src_port %d\n",
15862            ntohl (mp->domain_id), ntohs (mp->src_port));
15863   vam->retval = 0;
15864   vam->result_ready = 1;
15865 }
15866
15867 static void
15868   vl_api_ipfix_classify_stream_details_t_handler_json
15869   (vl_api_ipfix_classify_stream_details_t * mp)
15870 {
15871   vat_main_t *vam = &vat_main;
15872   vat_json_node_t node;
15873
15874   vat_json_init_object (&node);
15875   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
15876   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
15877
15878   vat_json_print (vam->ofp, &node);
15879   vat_json_free (&node);
15880   vam->retval = 0;
15881   vam->result_ready = 1;
15882 }
15883
15884 static int
15885 api_ipfix_classify_table_dump (vat_main_t * vam)
15886 {
15887   vl_api_ipfix_classify_table_dump_t *mp;
15888   f64 timeout;
15889
15890   if (!vam->json_output)
15891     {
15892       fformat (vam->ofp, "%15s%15s%20s\n", "table_id", "ip_version",
15893                "transport_protocol");
15894     }
15895
15896   /* Construct the API message */
15897   M (IPFIX_CLASSIFY_TABLE_DUMP, ipfix_classify_table_dump);
15898
15899   /* send it... */
15900   S;
15901
15902   /* Use a control ping for synchronization */
15903   {
15904     vl_api_control_ping_t *mp;
15905     M (CONTROL_PING, control_ping);
15906     S;
15907   }
15908   W;
15909 }
15910
15911 static void
15912   vl_api_ipfix_classify_table_details_t_handler
15913   (vl_api_ipfix_classify_table_details_t * mp)
15914 {
15915   vat_main_t *vam = &vat_main;
15916   fformat (vam->ofp, "%15d%15d%20d\n", ntohl (mp->table_id), mp->ip_version,
15917            mp->transport_protocol);
15918 }
15919
15920 static void
15921   vl_api_ipfix_classify_table_details_t_handler_json
15922   (vl_api_ipfix_classify_table_details_t * mp)
15923 {
15924   vat_json_node_t *node = NULL;
15925   vat_main_t *vam = &vat_main;
15926
15927   if (VAT_JSON_ARRAY != vam->json_tree.type)
15928     {
15929       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
15930       vat_json_init_array (&vam->json_tree);
15931     }
15932
15933   node = vat_json_array_add (&vam->json_tree);
15934   vat_json_init_object (node);
15935
15936   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
15937   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
15938   vat_json_object_add_uint (node, "transport_protocol",
15939                             mp->transport_protocol);
15940 }
15941
15942 static int
15943 api_sw_interface_span_enable_disable (vat_main_t * vam)
15944 {
15945   unformat_input_t *i = vam->input;
15946   vl_api_sw_interface_span_enable_disable_t *mp;
15947   f64 timeout;
15948   u32 src_sw_if_index = ~0;
15949   u32 dst_sw_if_index = ~0;
15950   u8 state = 3;
15951
15952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
15953     {
15954       if (unformat (i, "src %U", unformat_sw_if_index, vam, &src_sw_if_index))
15955         ;
15956       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
15957         ;
15958       else
15959         if (unformat
15960             (i, "dst %U", unformat_sw_if_index, vam, &dst_sw_if_index))
15961         ;
15962       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
15963         ;
15964       else if (unformat (i, "disable"))
15965         state = 0;
15966       else if (unformat (i, "rx"))
15967         state = 1;
15968       else if (unformat (i, "tx"))
15969         state = 2;
15970       else if (unformat (i, "both"))
15971         state = 3;
15972       else
15973         break;
15974     }
15975
15976   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, sw_interface_span_enable_disable);
15977
15978   mp->sw_if_index_from = htonl (src_sw_if_index);
15979   mp->sw_if_index_to = htonl (dst_sw_if_index);
15980   mp->state = state;
15981
15982   S;
15983   W;
15984   /* NOTREACHED */
15985   return 0;
15986 }
15987
15988 static void
15989 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
15990                                             * mp)
15991 {
15992   vat_main_t *vam = &vat_main;
15993   u8 *sw_if_from_name = 0;
15994   u8 *sw_if_to_name = 0;
15995   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
15996   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
15997   char *states[] = { "none", "rx", "tx", "both" };
15998   hash_pair_t *p;
15999
16000   /* *INDENT-OFF* */
16001   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16002   ({
16003     if ((u32) p->value[0] == sw_if_index_from)
16004       {
16005         sw_if_from_name = (u8 *)(p->key);
16006         if (sw_if_to_name)
16007           break;
16008       }
16009     if ((u32) p->value[0] == sw_if_index_to)
16010       {
16011         sw_if_to_name = (u8 *)(p->key);
16012         if (sw_if_from_name)
16013           break;
16014       }
16015   }));
16016   /* *INDENT-ON* */
16017   fformat (vam->ofp, "%20s => %20s (%s)\n",
16018            sw_if_from_name, sw_if_to_name, states[mp->state]);
16019 }
16020
16021 static void
16022   vl_api_sw_interface_span_details_t_handler_json
16023   (vl_api_sw_interface_span_details_t * mp)
16024 {
16025   vat_main_t *vam = &vat_main;
16026   vat_json_node_t *node = NULL;
16027   u8 *sw_if_from_name = 0;
16028   u8 *sw_if_to_name = 0;
16029   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
16030   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
16031   hash_pair_t *p;
16032
16033   /* *INDENT-OFF* */
16034   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
16035   ({
16036     if ((u32) p->value[0] == sw_if_index_from)
16037       {
16038         sw_if_from_name = (u8 *)(p->key);
16039         if (sw_if_to_name)
16040           break;
16041       }
16042     if ((u32) p->value[0] == sw_if_index_to)
16043       {
16044         sw_if_to_name = (u8 *)(p->key);
16045         if (sw_if_from_name)
16046           break;
16047       }
16048   }));
16049   /* *INDENT-ON* */
16050
16051   if (VAT_JSON_ARRAY != vam->json_tree.type)
16052     {
16053       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16054       vat_json_init_array (&vam->json_tree);
16055     }
16056   node = vat_json_array_add (&vam->json_tree);
16057
16058   vat_json_init_object (node);
16059   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
16060   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
16061   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
16062   vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
16063   vat_json_object_add_uint (node, "state", mp->state);
16064 }
16065
16066 static int
16067 api_sw_interface_span_dump (vat_main_t * vam)
16068 {
16069   vl_api_sw_interface_span_dump_t *mp;
16070   f64 timeout;
16071
16072   M (SW_INTERFACE_SPAN_DUMP, sw_interface_span_dump);
16073   S;
16074
16075   /* Use a control ping for synchronization */
16076   {
16077     vl_api_control_ping_t *mp;
16078     M (CONTROL_PING, control_ping);
16079     S;
16080   }
16081   W;
16082 }
16083
16084 int
16085 api_pg_create_interface (vat_main_t * vam)
16086 {
16087   unformat_input_t *input = vam->input;
16088   vl_api_pg_create_interface_t *mp;
16089   f64 timeout;
16090
16091   u32 if_id = ~0;
16092   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16093     {
16094       if (unformat (input, "if_id %d", &if_id))
16095         ;
16096       else
16097         break;
16098     }
16099   if (if_id == ~0)
16100     {
16101       errmsg ("missing pg interface index\n");
16102       return -99;
16103     }
16104
16105   /* Construct the API message */
16106   M (PG_CREATE_INTERFACE, pg_create_interface);
16107   mp->context = 0;
16108   mp->interface_id = ntohl (if_id);
16109
16110   S;
16111   W;
16112   /* NOTREACHED */
16113   return 0;
16114 }
16115
16116 int
16117 api_pg_capture (vat_main_t * vam)
16118 {
16119   unformat_input_t *input = vam->input;
16120   vl_api_pg_capture_t *mp;
16121   f64 timeout;
16122
16123   u32 if_id = ~0;
16124   u8 enable = 1;
16125   u32 count = 1;
16126   u8 pcap_file_set = 0;
16127   u8 *pcap_file = 0;
16128   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16129     {
16130       if (unformat (input, "if_id %d", &if_id))
16131         ;
16132       else if (unformat (input, "pcap %s", &pcap_file))
16133         pcap_file_set = 1;
16134       else if (unformat (input, "count %d", &count))
16135         ;
16136       else if (unformat (input, "disable"))
16137         enable = 0;
16138       else
16139         break;
16140     }
16141   if (if_id == ~0)
16142     {
16143       errmsg ("missing pg interface index\n");
16144       return -99;
16145     }
16146   if (pcap_file_set > 0)
16147     {
16148       if (vec_len (pcap_file) > 255)
16149         {
16150           errmsg ("pcap file name is too long\n");
16151           return -99;
16152         }
16153     }
16154
16155   u32 name_len = vec_len (pcap_file);
16156   /* Construct the API message */
16157   M (PG_CAPTURE, pg_capture);
16158   mp->context = 0;
16159   mp->interface_id = ntohl (if_id);
16160   mp->is_enabled = enable;
16161   mp->count = ntohl (count);
16162   mp->pcap_name_length = ntohl (name_len);
16163   if (pcap_file_set != 0)
16164     {
16165       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
16166     }
16167   vec_free (pcap_file);
16168
16169   S;
16170   W;
16171   /* NOTREACHED */
16172   return 0;
16173 }
16174
16175 int
16176 api_pg_enable_disable (vat_main_t * vam)
16177 {
16178   unformat_input_t *input = vam->input;
16179   vl_api_pg_enable_disable_t *mp;
16180   f64 timeout;
16181
16182   u8 enable = 1;
16183   u8 stream_name_set = 0;
16184   u8 *stream_name = 0;
16185   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16186     {
16187       if (unformat (input, "stream %s", &stream_name))
16188         stream_name_set = 1;
16189       else if (unformat (input, "disable"))
16190         enable = 0;
16191       else
16192         break;
16193     }
16194
16195   if (stream_name_set > 0)
16196     {
16197       if (vec_len (stream_name) > 255)
16198         {
16199           errmsg ("stream name too long\n");
16200           return -99;
16201         }
16202     }
16203
16204   u32 name_len = vec_len (stream_name);
16205   /* Construct the API message */
16206   M (PG_ENABLE_DISABLE, pg_enable_disable);
16207   mp->context = 0;
16208   mp->is_enabled = enable;
16209   if (stream_name_set != 0)
16210     {
16211       mp->stream_name_length = ntohl (name_len);
16212       clib_memcpy (mp->stream_name, stream_name, name_len);
16213     }
16214   vec_free (stream_name);
16215
16216   S;
16217   W;
16218   /* NOTREACHED */
16219   return 0;
16220 }
16221
16222 int
16223 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
16224 {
16225   unformat_input_t *input = vam->input;
16226   vl_api_ip_source_and_port_range_check_add_del_t *mp;
16227   f64 timeout;
16228
16229   u16 *low_ports = 0;
16230   u16 *high_ports = 0;
16231   u16 this_low;
16232   u16 this_hi;
16233   ip4_address_t ip4_addr;
16234   ip6_address_t ip6_addr;
16235   u32 length;
16236   u32 tmp, tmp2;
16237   u8 prefix_set = 0;
16238   u32 vrf_id = ~0;
16239   u8 is_add = 1;
16240   u8 is_ipv6 = 0;
16241
16242   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16243     {
16244       if (unformat (input, "%U/%d", unformat_ip4_address, &ip4_addr, &length))
16245         {
16246           prefix_set = 1;
16247         }
16248       else
16249         if (unformat
16250             (input, "%U/%d", unformat_ip6_address, &ip6_addr, &length))
16251         {
16252           prefix_set = 1;
16253           is_ipv6 = 1;
16254         }
16255       else if (unformat (input, "vrf %d", &vrf_id))
16256         ;
16257       else if (unformat (input, "del"))
16258         is_add = 0;
16259       else if (unformat (input, "port %d", &tmp))
16260         {
16261           if (tmp == 0 || tmp > 65535)
16262             {
16263               errmsg ("port %d out of range", tmp);
16264               return -99;
16265             }
16266           this_low = tmp;
16267           this_hi = this_low + 1;
16268           vec_add1 (low_ports, this_low);
16269           vec_add1 (high_ports, this_hi);
16270         }
16271       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
16272         {
16273           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
16274             {
16275               errmsg ("incorrect range parameters\n");
16276               return -99;
16277             }
16278           this_low = tmp;
16279           /* Note: in debug CLI +1 is added to high before
16280              passing to real fn that does "the work"
16281              (ip_source_and_port_range_check_add_del).
16282              This fn is a wrapper around the binary API fn a
16283              control plane will call, which expects this increment
16284              to have occurred. Hence letting the binary API control
16285              plane fn do the increment for consistency between VAT
16286              and other control planes.
16287            */
16288           this_hi = tmp2;
16289           vec_add1 (low_ports, this_low);
16290           vec_add1 (high_ports, this_hi);
16291         }
16292       else
16293         break;
16294     }
16295
16296   if (prefix_set == 0)
16297     {
16298       errmsg ("<address>/<mask> not specified\n");
16299       return -99;
16300     }
16301
16302   if (vrf_id == ~0)
16303     {
16304       errmsg ("VRF ID required, not specified\n");
16305       return -99;
16306     }
16307
16308   if (vrf_id == 0)
16309     {
16310       errmsg
16311         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
16312       return -99;
16313     }
16314
16315   if (vec_len (low_ports) == 0)
16316     {
16317       errmsg ("At least one port or port range required\n");
16318       return -99;
16319     }
16320
16321   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL,
16322      ip_source_and_port_range_check_add_del);
16323
16324   mp->is_add = is_add;
16325
16326   if (is_ipv6)
16327     {
16328       mp->is_ipv6 = 1;
16329       clib_memcpy (mp->address, &ip6_addr, sizeof (ip6_addr));
16330     }
16331   else
16332     {
16333       mp->is_ipv6 = 0;
16334       clib_memcpy (mp->address, &ip4_addr, sizeof (ip4_addr));
16335     }
16336
16337   mp->mask_length = length;
16338   mp->number_of_ranges = vec_len (low_ports);
16339
16340   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
16341   vec_free (low_ports);
16342
16343   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
16344   vec_free (high_ports);
16345
16346   mp->vrf_id = ntohl (vrf_id);
16347
16348   S;
16349   W;
16350   /* NOTREACHED */
16351   return 0;
16352 }
16353
16354 int
16355 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
16356 {
16357   unformat_input_t *input = vam->input;
16358   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
16359   f64 timeout;
16360   u32 sw_if_index = ~0;
16361   int vrf_set = 0;
16362   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
16363   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
16364   u8 is_add = 1;
16365
16366   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16367     {
16368       if (unformat (input, "%U", unformat_sw_if_index, vam, &sw_if_index))
16369         ;
16370       else if (unformat (input, "sw_if_index %d", &sw_if_index))
16371         ;
16372       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
16373         vrf_set = 1;
16374       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
16375         vrf_set = 1;
16376       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
16377         vrf_set = 1;
16378       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
16379         vrf_set = 1;
16380       else if (unformat (input, "del"))
16381         is_add = 0;
16382       else
16383         break;
16384     }
16385
16386   if (sw_if_index == ~0)
16387     {
16388       errmsg ("Interface required but not specified\n");
16389       return -99;
16390     }
16391
16392   if (vrf_set == 0)
16393     {
16394       errmsg ("VRF ID required but not specified\n");
16395       return -99;
16396     }
16397
16398   if (tcp_out_vrf_id == 0
16399       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
16400     {
16401       errmsg
16402         ("VRF ID should not be default. Should be distinct VRF for this purpose.\n");
16403       return -99;
16404     }
16405
16406   /* Construct the API message */
16407   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL,
16408      ip_source_and_port_range_check_interface_add_del);
16409
16410   mp->sw_if_index = ntohl (sw_if_index);
16411   mp->is_add = is_add;
16412   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
16413   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
16414   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
16415   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
16416
16417   /* send it... */
16418   S;
16419
16420   /* Wait for a reply... */
16421   W;
16422 }
16423
16424 static int
16425 api_ipsec_gre_add_del_tunnel (vat_main_t * vam)
16426 {
16427   unformat_input_t *i = vam->input;
16428   vl_api_ipsec_gre_add_del_tunnel_t *mp;
16429   f64 timeout;
16430   u32 local_sa_id = 0;
16431   u32 remote_sa_id = 0;
16432   ip4_address_t src_address;
16433   ip4_address_t dst_address;
16434   u8 is_add = 1;
16435
16436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16437     {
16438       if (unformat (i, "local_sa %d", &local_sa_id))
16439         ;
16440       else if (unformat (i, "remote_sa %d", &remote_sa_id))
16441         ;
16442       else if (unformat (i, "src %U", unformat_ip4_address, &src_address))
16443         ;
16444       else if (unformat (i, "dst %U", unformat_ip4_address, &dst_address))
16445         ;
16446       else if (unformat (i, "del"))
16447         is_add = 0;
16448       else
16449         {
16450           clib_warning ("parse error '%U'", format_unformat_error, i);
16451           return -99;
16452         }
16453     }
16454
16455   M (IPSEC_GRE_ADD_DEL_TUNNEL, ipsec_gre_add_del_tunnel);
16456
16457   mp->local_sa_id = ntohl (local_sa_id);
16458   mp->remote_sa_id = ntohl (remote_sa_id);
16459   clib_memcpy (mp->src_address, &src_address, sizeof (src_address));
16460   clib_memcpy (mp->dst_address, &dst_address, sizeof (dst_address));
16461   mp->is_add = is_add;
16462
16463   S;
16464   W;
16465   /* NOTREACHED */
16466   return 0;
16467 }
16468
16469 static int
16470 api_punt (vat_main_t * vam)
16471 {
16472   unformat_input_t *i = vam->input;
16473   vl_api_punt_t *mp;
16474   f64 timeout;
16475   u32 ipv = ~0;
16476   u32 protocol = ~0;
16477   u32 port = ~0;
16478   int is_add = 1;
16479
16480   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16481     {
16482       if (unformat (i, "ip %d", &ipv))
16483         ;
16484       else if (unformat (i, "protocol %d", &protocol))
16485         ;
16486       else if (unformat (i, "port %d", &port))
16487         ;
16488       else if (unformat (i, "del"))
16489         is_add = 0;
16490       else
16491         {
16492           clib_warning ("parse error '%U'", format_unformat_error, i);
16493           return -99;
16494         }
16495     }
16496
16497   M (PUNT, punt);
16498
16499   mp->is_add = (u8) is_add;
16500   mp->ipv = (u8) ipv;
16501   mp->l4_protocol = (u8) protocol;
16502   mp->l4_port = htons ((u16) port);
16503
16504   S;
16505   W;
16506   /* NOTREACHED */
16507   return 0;
16508 }
16509
16510 static void vl_api_ipsec_gre_tunnel_details_t_handler
16511   (vl_api_ipsec_gre_tunnel_details_t * mp)
16512 {
16513   vat_main_t *vam = &vat_main;
16514
16515   fformat (vam->ofp, "%11d%15U%15U%14d%14d\n",
16516            ntohl (mp->sw_if_index),
16517            format_ip4_address, &mp->src_address,
16518            format_ip4_address, &mp->dst_address,
16519            ntohl (mp->local_sa_id), ntohl (mp->remote_sa_id));
16520 }
16521
16522 static void vl_api_ipsec_gre_tunnel_details_t_handler_json
16523   (vl_api_ipsec_gre_tunnel_details_t * mp)
16524 {
16525   vat_main_t *vam = &vat_main;
16526   vat_json_node_t *node = NULL;
16527   struct in_addr ip4;
16528
16529   if (VAT_JSON_ARRAY != vam->json_tree.type)
16530     {
16531       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16532       vat_json_init_array (&vam->json_tree);
16533     }
16534   node = vat_json_array_add (&vam->json_tree);
16535
16536   vat_json_init_object (node);
16537   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
16538   clib_memcpy (&ip4, &mp->src_address, sizeof (ip4));
16539   vat_json_object_add_ip4 (node, "src_address", ip4);
16540   clib_memcpy (&ip4, &mp->dst_address, sizeof (ip4));
16541   vat_json_object_add_ip4 (node, "dst_address", ip4);
16542   vat_json_object_add_uint (node, "local_sa_id", ntohl (mp->local_sa_id));
16543   vat_json_object_add_uint (node, "remote_sa_id", ntohl (mp->remote_sa_id));
16544 }
16545
16546 static int
16547 api_ipsec_gre_tunnel_dump (vat_main_t * vam)
16548 {
16549   unformat_input_t *i = vam->input;
16550   vl_api_ipsec_gre_tunnel_dump_t *mp;
16551   f64 timeout;
16552   u32 sw_if_index;
16553   u8 sw_if_index_set = 0;
16554
16555   /* Parse args required to build the message */
16556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16557     {
16558       if (unformat (i, "sw_if_index %d", &sw_if_index))
16559         sw_if_index_set = 1;
16560       else
16561         break;
16562     }
16563
16564   if (sw_if_index_set == 0)
16565     {
16566       sw_if_index = ~0;
16567     }
16568
16569   if (!vam->json_output)
16570     {
16571       fformat (vam->ofp, "%11s%15s%15s%14s%14s\n",
16572                "sw_if_index", "src_address", "dst_address",
16573                "local_sa_id", "remote_sa_id");
16574     }
16575
16576   /* Get list of gre-tunnel interfaces */
16577   M (IPSEC_GRE_TUNNEL_DUMP, ipsec_gre_tunnel_dump);
16578
16579   mp->sw_if_index = htonl (sw_if_index);
16580
16581   S;
16582
16583   /* Use a control ping for synchronization */
16584   {
16585     vl_api_control_ping_t *mp;
16586     M (CONTROL_PING, control_ping);
16587     S;
16588   }
16589   W;
16590 }
16591
16592 static int
16593 api_delete_subif (vat_main_t * vam)
16594 {
16595   unformat_input_t *i = vam->input;
16596   vl_api_delete_subif_t *mp;
16597   f64 timeout;
16598   u32 sw_if_index = ~0;
16599
16600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16601     {
16602       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16603         ;
16604       if (unformat (i, "sw_if_index %d", &sw_if_index))
16605         ;
16606       else
16607         break;
16608     }
16609
16610   if (sw_if_index == ~0)
16611     {
16612       errmsg ("missing sw_if_index\n");
16613       return -99;
16614     }
16615
16616   /* Construct the API message */
16617   M (DELETE_SUBIF, delete_subif);
16618   mp->sw_if_index = ntohl (sw_if_index);
16619
16620   S;
16621   W;
16622 }
16623
16624 #define foreach_pbb_vtr_op      \
16625 _("disable",  L2_VTR_DISABLED)  \
16626 _("pop",  L2_VTR_POP_2)         \
16627 _("push",  L2_VTR_PUSH_2)
16628
16629 static int
16630 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
16631 {
16632   unformat_input_t *i = vam->input;
16633   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
16634   f64 timeout;
16635   u32 sw_if_index = ~0, vtr_op = ~0;
16636   u16 outer_tag = ~0;
16637   u8 dmac[6], smac[6];
16638   u8 dmac_set = 0, smac_set = 0;
16639   u16 vlanid = 0;
16640   u32 sid = ~0;
16641   u32 tmp;
16642
16643   /* Shut up coverity */
16644   memset (dmac, 0, sizeof (dmac));
16645   memset (smac, 0, sizeof (smac));
16646
16647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16648     {
16649       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16650         ;
16651       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16652         ;
16653       else if (unformat (i, "vtr_op %d", &vtr_op))
16654         ;
16655 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
16656       foreach_pbb_vtr_op
16657 #undef _
16658         else if (unformat (i, "translate_pbb_stag"))
16659         {
16660           if (unformat (i, "%d", &tmp))
16661             {
16662               vtr_op = L2_VTR_TRANSLATE_2_1;
16663               outer_tag = tmp;
16664             }
16665           else
16666             {
16667               errmsg
16668                 ("translate_pbb_stag operation requires outer tag definition\n");
16669               return -99;
16670             }
16671         }
16672       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
16673         dmac_set++;
16674       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
16675         smac_set++;
16676       else if (unformat (i, "sid %d", &sid))
16677         ;
16678       else if (unformat (i, "vlanid %d", &tmp))
16679         vlanid = tmp;
16680       else
16681         {
16682           clib_warning ("parse error '%U'", format_unformat_error, i);
16683           return -99;
16684         }
16685     }
16686
16687   if ((sw_if_index == ~0) || (vtr_op == ~0))
16688     {
16689       errmsg ("missing sw_if_index or vtr operation\n");
16690       return -99;
16691     }
16692   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
16693       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
16694     {
16695       errmsg
16696         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid\n");
16697       return -99;
16698     }
16699
16700   M (L2_INTERFACE_PBB_TAG_REWRITE, l2_interface_pbb_tag_rewrite);
16701   mp->sw_if_index = ntohl (sw_if_index);
16702   mp->vtr_op = ntohl (vtr_op);
16703   mp->outer_tag = ntohs (outer_tag);
16704   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
16705   clib_memcpy (mp->b_smac, smac, sizeof (smac));
16706   mp->b_vlanid = ntohs (vlanid);
16707   mp->i_sid = ntohl (sid);
16708
16709   S;
16710   W;
16711   /* NOTREACHED */
16712   return 0;
16713 }
16714
16715 static int
16716 api_flow_classify_set_interface (vat_main_t * vam)
16717 {
16718   unformat_input_t *i = vam->input;
16719   vl_api_flow_classify_set_interface_t *mp;
16720   f64 timeout;
16721   u32 sw_if_index;
16722   int sw_if_index_set;
16723   u32 ip4_table_index = ~0;
16724   u32 ip6_table_index = ~0;
16725   u8 is_add = 1;
16726
16727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16728     {
16729       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16730         sw_if_index_set = 1;
16731       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16732         sw_if_index_set = 1;
16733       else if (unformat (i, "del"))
16734         is_add = 0;
16735       else if (unformat (i, "ip4-table %d", &ip4_table_index))
16736         ;
16737       else if (unformat (i, "ip6-table %d", &ip6_table_index))
16738         ;
16739       else
16740         {
16741           clib_warning ("parse error '%U'", format_unformat_error, i);
16742           return -99;
16743         }
16744     }
16745
16746   if (sw_if_index_set == 0)
16747     {
16748       errmsg ("missing interface name or sw_if_index\n");
16749       return -99;
16750     }
16751
16752   M (FLOW_CLASSIFY_SET_INTERFACE, flow_classify_set_interface);
16753
16754   mp->sw_if_index = ntohl (sw_if_index);
16755   mp->ip4_table_index = ntohl (ip4_table_index);
16756   mp->ip6_table_index = ntohl (ip6_table_index);
16757   mp->is_add = is_add;
16758
16759   S;
16760   W;
16761   /* NOTREACHED */
16762   return 0;
16763 }
16764
16765 static int
16766 api_flow_classify_dump (vat_main_t * vam)
16767 {
16768   unformat_input_t *i = vam->input;
16769   vl_api_flow_classify_dump_t *mp;
16770   f64 timeout = ~0;
16771   u8 type = FLOW_CLASSIFY_N_TABLES;
16772
16773   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
16774     ;
16775   else
16776     {
16777       errmsg ("classify table type must be specified\n");
16778       return -99;
16779     }
16780
16781   if (!vam->json_output)
16782     {
16783       fformat (vam->ofp, "%10s%20s\n", "Intfc idx", "Classify table");
16784     }
16785
16786   M (FLOW_CLASSIFY_DUMP, flow_classify_dump);
16787   mp->type = type;
16788   /* send it... */
16789   S;
16790
16791   /* Use a control ping for synchronization */
16792   {
16793     vl_api_control_ping_t *mp;
16794     M (CONTROL_PING, control_ping);
16795     S;
16796   }
16797   /* Wait for a reply... */
16798   W;
16799
16800   /* NOTREACHED */
16801   return 0;
16802 }
16803
16804 static int
16805 api_feature_enable_disable (vat_main_t * vam)
16806 {
16807   unformat_input_t *i = vam->input;
16808   vl_api_feature_enable_disable_t *mp;
16809   f64 timeout;
16810   u8 *arc_name = 0;
16811   u8 *feature_name = 0;
16812   u32 sw_if_index = ~0;
16813   u8 enable = 1;
16814
16815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16816     {
16817       if (unformat (i, "arc_name %s", &arc_name))
16818         ;
16819       else if (unformat (i, "feature_name %s", &feature_name))
16820         ;
16821       else if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16822         ;
16823       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16824         ;
16825       else if (unformat (i, "disable"))
16826         enable = 0;
16827       else
16828         break;
16829     }
16830
16831   if (arc_name == 0)
16832     {
16833       errmsg ("missing arc name\n");
16834       return -99;
16835     }
16836   if (vec_len (arc_name) > 63)
16837     {
16838       errmsg ("arc name too long\n");
16839     }
16840
16841   if (feature_name == 0)
16842     {
16843       errmsg ("missing feature name\n");
16844       return -99;
16845     }
16846   if (vec_len (feature_name) > 63)
16847     {
16848       errmsg ("feature name too long\n");
16849     }
16850
16851   if (sw_if_index == ~0)
16852     {
16853       errmsg ("missing interface name or sw_if_index\n");
16854       return -99;
16855     }
16856
16857   /* Construct the API message */
16858   M (FEATURE_ENABLE_DISABLE, feature_enable_disable);
16859   mp->sw_if_index = ntohl (sw_if_index);
16860   mp->enable = enable;
16861   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
16862   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
16863   vec_free (arc_name);
16864   vec_free (feature_name);
16865
16866   S;
16867   W;
16868 }
16869
16870 static int
16871 api_sw_interface_tag_add_del (vat_main_t * vam)
16872 {
16873   unformat_input_t *i = vam->input;
16874   vl_api_sw_interface_tag_add_del_t *mp;
16875   f64 timeout;
16876   u32 sw_if_index = ~0;
16877   u8 *tag = 0;
16878   u8 enable = 1;
16879
16880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16881     {
16882       if (unformat (i, "tag %s", &tag))
16883         ;
16884       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16885         ;
16886       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16887         ;
16888       else if (unformat (i, "del"))
16889         enable = 0;
16890       else
16891         break;
16892     }
16893
16894   if (sw_if_index == ~0)
16895     {
16896       errmsg ("missing interface name or sw_if_index\n");
16897       return -99;
16898     }
16899
16900   if (enable && (tag == 0))
16901     {
16902       errmsg ("no tag specified\n");
16903       return -99;
16904     }
16905
16906   /* Construct the API message */
16907   M (SW_INTERFACE_TAG_ADD_DEL, sw_interface_tag_add_del);
16908   mp->sw_if_index = ntohl (sw_if_index);
16909   mp->is_add = enable;
16910   if (enable)
16911     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
16912   vec_free (tag);
16913
16914   S;
16915   W;
16916 }
16917
16918 static void vl_api_l2_xconnect_details_t_handler
16919   (vl_api_l2_xconnect_details_t * mp)
16920 {
16921   vat_main_t *vam = &vat_main;
16922
16923   fformat (vam->ofp, "%15d%15d\n",
16924            ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
16925 }
16926
16927 static void vl_api_l2_xconnect_details_t_handler_json
16928   (vl_api_l2_xconnect_details_t * mp)
16929 {
16930   vat_main_t *vam = &vat_main;
16931   vat_json_node_t *node = NULL;
16932
16933   if (VAT_JSON_ARRAY != vam->json_tree.type)
16934     {
16935       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
16936       vat_json_init_array (&vam->json_tree);
16937     }
16938   node = vat_json_array_add (&vam->json_tree);
16939
16940   vat_json_init_object (node);
16941   vat_json_object_add_uint (node, "rx_sw_if_index",
16942                             ntohl (mp->rx_sw_if_index));
16943   vat_json_object_add_uint (node, "tx_sw_if_index",
16944                             ntohl (mp->tx_sw_if_index));
16945 }
16946
16947 static int
16948 api_l2_xconnect_dump (vat_main_t * vam)
16949 {
16950   vl_api_l2_xconnect_dump_t *mp;
16951   f64 timeout;
16952
16953   if (!vam->json_output)
16954     {
16955       fformat (vam->ofp, "%15s%15s\n", "rx_sw_if_index", "tx_sw_if_index");
16956     }
16957
16958   M (L2_XCONNECT_DUMP, l2_xconnect_dump);
16959
16960   S;
16961
16962   /* Use a control ping for synchronization */
16963   {
16964     vl_api_control_ping_t *mp;
16965     M (CONTROL_PING, control_ping);
16966     S;
16967   }
16968   W;
16969 }
16970
16971 static int
16972 api_sw_interface_set_mtu (vat_main_t * vam)
16973 {
16974   unformat_input_t *i = vam->input;
16975   vl_api_sw_interface_set_mtu_t *mp;
16976   f64 timeout;
16977   u32 sw_if_index = ~0;
16978   u32 mtu = 0;
16979
16980   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16981     {
16982       if (unformat (i, "mtu %d", &mtu))
16983         ;
16984       if (unformat (i, "%U", unformat_sw_if_index, vam, &sw_if_index))
16985         ;
16986       else if (unformat (i, "sw_if_index %d", &sw_if_index))
16987         ;
16988       else
16989         break;
16990     }
16991
16992   if (sw_if_index == ~0)
16993     {
16994       errmsg ("missing interface name or sw_if_index\n");
16995       return -99;
16996     }
16997
16998   if (mtu == 0)
16999     {
17000       errmsg ("no mtu specified\n");
17001       return -99;
17002     }
17003
17004   /* Construct the API message */
17005   M (SW_INTERFACE_SET_MTU, sw_interface_set_mtu);
17006   mp->sw_if_index = ntohl (sw_if_index);
17007   mp->mtu = ntohs ((u16) mtu);
17008
17009   S;
17010   W;
17011 }
17012
17013
17014 static int
17015 q_or_quit (vat_main_t * vam)
17016 {
17017   longjmp (vam->jump_buf, 1);
17018   return 0;                     /* not so much */
17019 }
17020
17021 static int
17022 q (vat_main_t * vam)
17023 {
17024   return q_or_quit (vam);
17025 }
17026
17027 static int
17028 quit (vat_main_t * vam)
17029 {
17030   return q_or_quit (vam);
17031 }
17032
17033 static int
17034 comment (vat_main_t * vam)
17035 {
17036   return 0;
17037 }
17038
17039 static int
17040 cmd_cmp (void *a1, void *a2)
17041 {
17042   u8 **c1 = a1;
17043   u8 **c2 = a2;
17044
17045   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
17046 }
17047
17048 static int
17049 help (vat_main_t * vam)
17050 {
17051   u8 **cmds = 0;
17052   u8 *name = 0;
17053   hash_pair_t *p;
17054   unformat_input_t *i = vam->input;
17055   int j;
17056
17057   if (unformat (i, "%s", &name))
17058     {
17059       uword *hs;
17060
17061       vec_add1 (name, 0);
17062
17063       hs = hash_get_mem (vam->help_by_name, name);
17064       if (hs)
17065         fformat (vam->ofp, "usage: %s %s\n", name, hs[0]);
17066       else
17067         fformat (vam->ofp, "No such msg / command '%s'\n", name);
17068       vec_free (name);
17069       return 0;
17070     }
17071
17072   fformat (vam->ofp, "Help is available for the following:\n");
17073
17074     /* *INDENT-OFF* */
17075     hash_foreach_pair (p, vam->function_by_name,
17076     ({
17077       vec_add1 (cmds, (u8 *)(p->key));
17078     }));
17079     /* *INDENT-ON* */
17080
17081   vec_sort_with_function (cmds, cmd_cmp);
17082
17083   for (j = 0; j < vec_len (cmds); j++)
17084     fformat (vam->ofp, "%s\n", cmds[j]);
17085
17086   vec_free (cmds);
17087   return 0;
17088 }
17089
17090 static int
17091 set (vat_main_t * vam)
17092 {
17093   u8 *name = 0, *value = 0;
17094   unformat_input_t *i = vam->input;
17095
17096   if (unformat (i, "%s", &name))
17097     {
17098       /* The input buffer is a vector, not a string. */
17099       value = vec_dup (i->buffer);
17100       vec_delete (value, i->index, 0);
17101       /* Almost certainly has a trailing newline */
17102       if (value[vec_len (value) - 1] == '\n')
17103         value[vec_len (value) - 1] = 0;
17104       /* Make sure it's a proper string, one way or the other */
17105       vec_add1 (value, 0);
17106       (void) clib_macro_set_value (&vam->macro_main,
17107                                    (char *) name, (char *) value);
17108     }
17109   else
17110     errmsg ("usage: set <name> <value>\n");
17111
17112   vec_free (name);
17113   vec_free (value);
17114   return 0;
17115 }
17116
17117 static int
17118 unset (vat_main_t * vam)
17119 {
17120   u8 *name = 0;
17121
17122   if (unformat (vam->input, "%s", &name))
17123     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
17124       errmsg ("unset: %s wasn't set\n", name);
17125   vec_free (name);
17126   return 0;
17127 }
17128
17129 typedef struct
17130 {
17131   u8 *name;
17132   u8 *value;
17133 } macro_sort_t;
17134
17135
17136 static int
17137 macro_sort_cmp (void *a1, void *a2)
17138 {
17139   macro_sort_t *s1 = a1;
17140   macro_sort_t *s2 = a2;
17141
17142   return strcmp ((char *) (s1->name), (char *) (s2->name));
17143 }
17144
17145 static int
17146 dump_macro_table (vat_main_t * vam)
17147 {
17148   macro_sort_t *sort_me = 0, *sm;
17149   int i;
17150   hash_pair_t *p;
17151
17152     /* *INDENT-OFF* */
17153     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
17154     ({
17155       vec_add2 (sort_me, sm, 1);
17156       sm->name = (u8 *)(p->key);
17157       sm->value = (u8 *) (p->value[0]);
17158     }));
17159     /* *INDENT-ON* */
17160
17161   vec_sort_with_function (sort_me, macro_sort_cmp);
17162
17163   if (vec_len (sort_me))
17164     fformat (vam->ofp, "%-15s%s\n", "Name", "Value");
17165   else
17166     fformat (vam->ofp, "The macro table is empty...\n");
17167
17168   for (i = 0; i < vec_len (sort_me); i++)
17169     fformat (vam->ofp, "%-15s%s\n", sort_me[i].name, sort_me[i].value);
17170   return 0;
17171 }
17172
17173 static int
17174 dump_node_table (vat_main_t * vam)
17175 {
17176   int i, j;
17177   vlib_node_t *node, *next_node;
17178
17179   if (vec_len (vam->graph_nodes) == 0)
17180     {
17181       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
17182       return 0;
17183     }
17184
17185   for (i = 0; i < vec_len (vam->graph_nodes); i++)
17186     {
17187       node = vam->graph_nodes[i];
17188       fformat (vam->ofp, "[%d] %s\n", i, node->name);
17189       for (j = 0; j < vec_len (node->next_nodes); j++)
17190         {
17191           if (node->next_nodes[j] != ~0)
17192             {
17193               next_node = vam->graph_nodes[node->next_nodes[j]];
17194               fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
17195             }
17196         }
17197     }
17198   return 0;
17199 }
17200
17201 static int
17202 value_sort_cmp (void *a1, void *a2)
17203 {
17204   name_sort_t *n1 = a1;
17205   name_sort_t *n2 = a2;
17206
17207   if (n1->value < n2->value)
17208     return -1;
17209   if (n1->value > n2->value)
17210     return 1;
17211   return 0;
17212 }
17213
17214
17215 static int
17216 dump_msg_api_table (vat_main_t * vam)
17217 {
17218   api_main_t *am = &api_main;
17219   name_sort_t *nses = 0, *ns;
17220   hash_pair_t *hp;
17221   int i;
17222
17223   /* *INDENT-OFF* */
17224   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
17225   ({
17226     vec_add2 (nses, ns, 1);
17227     ns->name = (u8 *)(hp->key);
17228     ns->value = (u32) hp->value[0];
17229   }));
17230   /* *INDENT-ON* */
17231
17232   vec_sort_with_function (nses, value_sort_cmp);
17233
17234   for (i = 0; i < vec_len (nses); i++)
17235     fformat (vam->ofp, " [%d]: %s\n", nses[i].value, nses[i].name);
17236   vec_free (nses);
17237   return 0;
17238 }
17239
17240 static int
17241 get_msg_id (vat_main_t * vam)
17242 {
17243   u8 *name_and_crc;
17244   u32 message_index;
17245
17246   if (unformat (vam->input, "%s", &name_and_crc))
17247     {
17248       message_index = vl_api_get_msg_index (name_and_crc);
17249       if (message_index == ~0)
17250         {
17251           fformat (vam->ofp, " '%s' not found\n", name_and_crc);
17252           return 0;
17253         }
17254       fformat (vam->ofp, " '%s' has message index %d\n",
17255                name_and_crc, message_index);
17256       return 0;
17257     }
17258   errmsg ("name_and_crc required...\n");
17259   return 0;
17260 }
17261
17262 static int
17263 search_node_table (vat_main_t * vam)
17264 {
17265   unformat_input_t *line_input = vam->input;
17266   u8 *node_to_find;
17267   int j;
17268   vlib_node_t *node, *next_node;
17269   uword *p;
17270
17271   if (vam->graph_node_index_by_name == 0)
17272     {
17273       fformat (vam->ofp, "Node table empty, issue get_node_graph...\n");
17274       return 0;
17275     }
17276
17277   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
17278     {
17279       if (unformat (line_input, "%s", &node_to_find))
17280         {
17281           vec_add1 (node_to_find, 0);
17282           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
17283           if (p == 0)
17284             {
17285               fformat (vam->ofp, "%s not found...\n", node_to_find);
17286               goto out;
17287             }
17288           node = vam->graph_nodes[p[0]];
17289           fformat (vam->ofp, "[%d] %s\n", p[0], node->name);
17290           for (j = 0; j < vec_len (node->next_nodes); j++)
17291             {
17292               if (node->next_nodes[j] != ~0)
17293                 {
17294                   next_node = vam->graph_nodes[node->next_nodes[j]];
17295                   fformat (vam->ofp, "  [%d] %s\n", j, next_node->name);
17296                 }
17297             }
17298         }
17299
17300       else
17301         {
17302           clib_warning ("parse error '%U'", format_unformat_error,
17303                         line_input);
17304           return -99;
17305         }
17306
17307     out:
17308       vec_free (node_to_find);
17309
17310     }
17311
17312   return 0;
17313 }
17314
17315
17316 static int
17317 script (vat_main_t * vam)
17318 {
17319   u8 *s = 0;
17320   char *save_current_file;
17321   unformat_input_t save_input;
17322   jmp_buf save_jump_buf;
17323   u32 save_line_number;
17324
17325   FILE *new_fp, *save_ifp;
17326
17327   if (unformat (vam->input, "%s", &s))
17328     {
17329       new_fp = fopen ((char *) s, "r");
17330       if (new_fp == 0)
17331         {
17332           errmsg ("Couldn't open script file %s\n", s);
17333           vec_free (s);
17334           return -99;
17335         }
17336     }
17337   else
17338     {
17339       errmsg ("Missing script name\n");
17340       return -99;
17341     }
17342
17343   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
17344   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
17345   save_ifp = vam->ifp;
17346   save_line_number = vam->input_line_number;
17347   save_current_file = (char *) vam->current_file;
17348
17349   vam->input_line_number = 0;
17350   vam->ifp = new_fp;
17351   vam->current_file = s;
17352   do_one_file (vam);
17353
17354   clib_memcpy (&vam->input, &save_input, sizeof (vam->input));
17355   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
17356   vam->ifp = save_ifp;
17357   vam->input_line_number = save_line_number;
17358   vam->current_file = (u8 *) save_current_file;
17359   vec_free (s);
17360
17361   return 0;
17362 }
17363
17364 static int
17365 echo (vat_main_t * vam)
17366 {
17367   fformat (vam->ofp, "%v", vam->input->buffer);
17368   return 0;
17369 }
17370
17371 /* List of API message constructors, CLI names map to api_xxx */
17372 #define foreach_vpe_api_msg                                             \
17373 _(create_loopback,"[mac <mac-addr>]")                                   \
17374 _(sw_interface_dump,"")                                                 \
17375 _(sw_interface_set_flags,                                               \
17376   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
17377 _(sw_interface_add_del_address,                                         \
17378   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
17379 _(sw_interface_set_table,                                               \
17380   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
17381 _(sw_interface_set_mpls_enable,                                                \
17382   "<intfc> | sw_if_index [disable | dis]")                                \
17383 _(sw_interface_set_vpath,                                               \
17384   "<intfc> | sw_if_index <id> enable | disable")                        \
17385 _(sw_interface_set_vxlan_bypass,                                               \
17386   "<intfc> | sw_if_index <id> [ip4 | ip6] enable | disable")                        \
17387 _(sw_interface_set_l2_xconnect,                                         \
17388   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17389   "enable | disable")                                                   \
17390 _(sw_interface_set_l2_bridge,                                           \
17391   "<intfc> | sw_if_index <id> bd_id <bridge-domain-id>\n"         \
17392   "[shg <split-horizon-group>] [bvi]\n"                                 \
17393   "enable | disable")                                                   \
17394 _(sw_interface_set_dpdk_hqos_pipe,                                      \
17395   "rx <intfc> | sw_if_index <id> subport <subport-id> pipe <pipe-id>\n" \
17396   "profile <profile-id>\n")                                             \
17397 _(sw_interface_set_dpdk_hqos_subport,                                   \
17398   "rx <intfc> | sw_if_index <id> subport <subport-id> [rate <n>]\n"     \
17399   "[bktsize <n>] [tc0 <n>] [tc1 <n>] [tc2 <n>] [tc3 <n>] [period <n>]\n") \
17400 _(sw_interface_set_dpdk_hqos_tctbl,                                     \
17401   "rx <intfc> | sw_if_index <id> entry <n> tc <n> queue <n>\n")         \
17402 _(bridge_domain_add_del,                                                \
17403   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [del]\n")\
17404 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")     \
17405 _(l2fib_add_del,                                                        \
17406   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
17407 _(l2_flags,                                                             \
17408   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood]\n")       \
17409 _(bridge_flags,                                                         \
17410   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
17411 _(tap_connect,                                                          \
17412   "tapname <name> mac <mac-addr> | random-mac [tag <string>]")          \
17413 _(tap_modify,                                                           \
17414   "<vpp-if-name> | sw_if_index <id> tapname <name> mac <mac-addr> | random-mac") \
17415 _(tap_delete,                                                           \
17416   "<vpp-if-name> | sw_if_index <id>")                                   \
17417 _(sw_interface_tap_dump, "")                                            \
17418 _(ip_add_del_route,                                                     \
17419   "<addr>/<mask> via <addr> [table-id <n>]\n"                           \
17420   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17421   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17422   "[multipath] [count <n>]")                                            \
17423 _(mpls_route_add_del,                                                   \
17424   "<label> <eos> via <addr> [table-id <n>]\n"                           \
17425   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"               \
17426   "[weight <n>] [drop] [local] [classify <n>] [del]\n"                  \
17427   "[multipath] [count <n>]")                                            \
17428 _(mpls_ip_bind_unbind,                                                  \
17429   "<label> <addr/len>")                                                 \
17430 _(mpls_tunnel_add_del,                                                  \
17431   " via <addr> [table-id <n>]\n"                                        \
17432   "sw_if_index <id>] [l2]  [del]")                                      \
17433 _(proxy_arp_add_del,                                                    \
17434   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
17435 _(proxy_arp_intfc_enable_disable,                                       \
17436   "<intfc> | sw_if_index <id> enable | disable")                        \
17437 _(sw_interface_set_unnumbered,                                          \
17438   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
17439 _(ip_neighbor_add_del,                                                  \
17440   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
17441   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
17442 _(reset_vrf, "vrf <id> [ipv6]")                                         \
17443 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
17444 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
17445   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
17446   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
17447   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
17448 _(oam_add_del, "src <ip4-address> dst <ip4-address> [vrf <n>] [del]")   \
17449 _(reset_fib, "vrf <n> [ipv6]")                                          \
17450 _(dhcp_proxy_config,                                                    \
17451   "svr <v46-address> src <v46-address>\n"                               \
17452    "insert-cid <n> [del]")                                              \
17453 _(dhcp_proxy_config_2,                                                  \
17454   "svr <v46-address> src <v46-address>\n"                               \
17455    "rx_vrf_id <nn> server_vrf_id <nn> insert-cid <n> [del]")            \
17456 _(dhcp_proxy_set_vss,                                                   \
17457   "tbl_id <n> fib_id <n> oui <n> [ipv6] [del]")                         \
17458 _(dhcp_client_config,                                                   \
17459   "<intfc> | sw_if_index <id> [hostname <name>] [disable_event] [del]") \
17460 _(set_ip_flow_hash,                                                     \
17461   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
17462 _(sw_interface_ip6_enable_disable,                                      \
17463   "<intfc> | sw_if_index <id> enable | disable")                        \
17464 _(sw_interface_ip6_set_link_local_address,                              \
17465   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>")              \
17466 _(sw_interface_ip6nd_ra_prefix,                                         \
17467   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
17468   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
17469   "[nolink] [isno]")                                                    \
17470 _(sw_interface_ip6nd_ra_config,                                         \
17471   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
17472   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
17473   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
17474 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
17475 _(l2_patch_add_del,                                                     \
17476   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
17477   "enable | disable")                                                   \
17478 _(sr_tunnel_add_del,                                                    \
17479   "[name <name>] src <ip6-addr> dst <ip6-addr>/<mw> \n"                 \
17480   "(next <ip6-addr>)+ [tag <ip6-addr>]* [clean] [reroute] \n"           \
17481   "[policy <policy_name>]")                                             \
17482 _(sr_policy_add_del,                                                    \
17483   "name <name> tunnel <tunnel-name> [tunnel <tunnel-name>]* [del]")     \
17484 _(sr_multicast_map_add_del,                                             \
17485   "address [ip6 multicast address] sr-policy [policy name] [del]")      \
17486 _(classify_add_del_table,                                               \
17487   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
17488   " [del] mask <mask-value>\n"                                          \
17489   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
17490   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
17491 _(classify_add_del_session,                                             \
17492   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
17493   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
17494   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
17495   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
17496 _(classify_set_interface_ip_table,                                      \
17497   "<intfc> | sw_if_index <nn> table <nn>")                              \
17498 _(classify_set_interface_l2_tables,                                     \
17499   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17500   "  [other-table <nn>]")                                               \
17501 _(get_node_index, "node <node-name")                                    \
17502 _(add_node_next, "node <node-name> next <next-node-name>")              \
17503 _(l2tpv3_create_tunnel,                                                 \
17504   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
17505   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n"\
17506   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
17507 _(l2tpv3_set_tunnel_cookies,                                            \
17508   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
17509   "[new_remote_cookie <nn>]\n")                                         \
17510 _(l2tpv3_interface_enable_disable,                                      \
17511   "<intfc> | sw_if_index <nn> enable | disable")                        \
17512 _(l2tpv3_set_lookup_key,                                                \
17513   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
17514 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
17515 _(vxlan_add_del_tunnel,                                                 \
17516   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
17517   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
17518   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
17519 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
17520 _(gre_add_del_tunnel,                                                   \
17521   "src <ip4-addr> dst <ip4-addr> [outer-fib-id <nn>] [teb] [del]\n")    \
17522 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
17523 _(l2_fib_clear_table, "")                                               \
17524 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
17525 _(l2_interface_vlan_tag_rewrite,                                        \
17526   "<intfc> | sw_if_index <nn> \n"                                       \
17527   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
17528   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
17529 _(create_vhost_user_if,                                                 \
17530         "socket <filename> [server] [renumber <dev_instance>] "         \
17531         "[mac <mac_address>]")                                          \
17532 _(modify_vhost_user_if,                                                 \
17533         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
17534         "[server] [renumber <dev_instance>]")                           \
17535 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
17536 _(sw_interface_vhost_user_dump, "")                                     \
17537 _(show_version, "")                                                     \
17538 _(vxlan_gpe_add_del_tunnel,                                             \
17539   "local <addr> remote <addr> vni <nn>\n"                               \
17540     "[encap-vrf-id <nn>] [decap-vrf-id <nn>] [next-ip4][next-ip6]"      \
17541   "[next-ethernet] [next-nsh]\n")                                       \
17542 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
17543 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
17544 _(interface_name_renumber,                                              \
17545   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
17546 _(input_acl_set_interface,                                              \
17547   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17548   "  [l2-table <nn>] [del]")                                            \
17549 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
17550 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
17551 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
17552 _(ip_dump, "ipv4 | ipv6")                                               \
17553 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
17554 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
17555   "  spid_id <n> ")                                                     \
17556 _(ipsec_sad_add_del_entry, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
17557   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
17558   "  integ_alg <alg> integ_key <hex>")                                  \
17559 _(ipsec_spd_add_del_entry, "spd_id <n> priority <n> action <action>\n"  \
17560   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
17561   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
17562   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" )\
17563 _(ipsec_sa_set_key, "sa_id <n> crypto_key <hex> integ_key <hex>")       \
17564 _(ikev2_profile_add_del, "name <profile_name> [del]")                   \
17565 _(ikev2_profile_set_auth, "name <profile_name> auth_method <method>\n"  \
17566   "(auth_data 0x<data> | auth_data <data>)")                            \
17567 _(ikev2_profile_set_id, "name <profile_name> id_type <type>\n"          \
17568   "(id_data 0x<data> | id_data <data>) (local|remote)")                 \
17569 _(ikev2_profile_set_ts, "name <profile_name> protocol <proto>\n"        \
17570   "start_port <port> end_port <port> start_addr <ip4> end_addr <ip4>\n" \
17571   "(local|remote)")                                                     \
17572 _(ikev2_set_local_key, "file <absolute_file_path>")                     \
17573 _(delete_loopback,"sw_if_index <nn>")                                   \
17574 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
17575 _(map_add_domain,                                                       \
17576   "ip4-pfx <ip4pfx> ip6-pfx <ip6pfx> "                                  \
17577   "ip6-src <ip6addr> "                                                  \
17578   "ea-bits-len <n> psid-offset <n> psid-len <n>")                       \
17579 _(map_del_domain, "index <n>")                                          \
17580 _(map_add_del_rule,                                                     \
17581   "index <n> psid <n> dst <ip6addr> [del]")                             \
17582 _(map_domain_dump, "")                                                  \
17583 _(map_rule_dump, "index <map-domain>")                                  \
17584 _(want_interface_events,  "enable|disable")                             \
17585 _(want_stats,"enable|disable")                                          \
17586 _(get_first_msg_id, "client <name>")                                    \
17587 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
17588 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
17589   "fib-id <nn> [ip4][ip6][default]")                                    \
17590 _(get_node_graph, " ")                                                  \
17591 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
17592 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")               \
17593 _(ioam_disable, "")                                                \
17594 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
17595                             " sw_if_index <sw_if_index> p <priority> "  \
17596                             "w <weight>] [del]")                        \
17597 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
17598                         "iface <intf> | sw_if_index <sw_if_index> "     \
17599                         "p <priority> w <weight> [del]")                \
17600 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
17601                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
17602                          "locator-set <locator_name> [del]"             \
17603                          "[key-id sha1|sha256 secret-key <secret-key>]")\
17604 _(lisp_gpe_add_del_fwd_entry, "rmt_eid <eid> [lcl_eid <eid>] vni <vni>" \
17605   "dp_table <table> loc-pair <lcl_loc> <rmt_loc> ... [del]")            \
17606 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
17607 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
17608 _(lisp_gpe_enable_disable, "enable|disable")                            \
17609 _(lisp_enable_disable, "enable|disable")                                \
17610 _(lisp_map_register_enable_disable, "enable|disable")                   \
17611 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
17612 _(lisp_gpe_add_del_iface, "up|down")                                    \
17613 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
17614                                "[seid <seid>] "                         \
17615                                "rloc <locator> p <prio> "               \
17616                                "w <weight> [rloc <loc> ... ] "          \
17617                                "action <action> [del-all]")             \
17618 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
17619                           "<local-eid>")                                \
17620 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
17621 _(lisp_map_request_mode, "src-dst|dst-only")                            \
17622 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
17623 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
17624 _(lisp_locator_set_dump, "[local | remote]")                            \
17625 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
17626 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
17627                        "[local] | [remote]")                            \
17628 _(lisp_eid_table_vni_dump, "")                                          \
17629 _(lisp_eid_table_map_dump, "l2|l3")                                     \
17630 _(lisp_gpe_tunnel_dump, "")                                             \
17631 _(lisp_map_resolver_dump, "")                                           \
17632 _(lisp_map_server_dump, "")                                             \
17633 _(lisp_adjacencies_get, "vni <vni>")                                    \
17634 _(show_lisp_rloc_probe_state, "")                                       \
17635 _(show_lisp_map_register_state, "")                                     \
17636 _(show_lisp_status, "")                                                 \
17637 _(lisp_get_map_request_itr_rlocs, "")                                   \
17638 _(show_lisp_pitr, "")                                                   \
17639 _(show_lisp_map_request_mode, "")                                       \
17640 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
17641 _(af_packet_delete, "name <host interface name>")                       \
17642 _(policer_add_del, "name <policer name> <params> [del]")                \
17643 _(policer_dump, "[name <policer name>]")                                \
17644 _(policer_classify_set_interface,                                       \
17645   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
17646   "  [l2-table <nn>] [del]")                                            \
17647 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
17648 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
17649     "[master|slave]")                                                   \
17650 _(netmap_delete, "name <interface name>")                               \
17651 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
17652 _(mpls_fib_dump, "")                                                    \
17653 _(classify_table_ids, "")                                               \
17654 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
17655 _(classify_table_info, "table_id <nn>")                                 \
17656 _(classify_session_dump, "table_id <nn>")                               \
17657 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
17658     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
17659     "[template_interval <nn>] [udp_checksum]")                          \
17660 _(ipfix_exporter_dump, "")                                              \
17661 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
17662 _(ipfix_classify_stream_dump, "")                                       \
17663 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]")\
17664 _(ipfix_classify_table_dump, "")                                        \
17665 _(sw_interface_span_enable_disable, "[src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
17666 _(sw_interface_span_dump, "")                                           \
17667 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
17668 _(pg_create_interface, "if_id <nn>")                                    \
17669 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
17670 _(pg_enable_disable, "[stream <id>] disable")                           \
17671 _(ip_source_and_port_range_check_add_del,                               \
17672   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
17673 _(ip_source_and_port_range_check_interface_add_del,                     \
17674   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
17675   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
17676 _(ipsec_gre_add_del_tunnel,                                             \
17677   "src <addr> dst <addr> local_sa <sa-id> remote_sa <sa-id> [del]")     \
17678 _(ipsec_gre_tunnel_dump, "[sw_if_index <nn>]")                          \
17679 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
17680 _(l2_interface_pbb_tag_rewrite,                                         \
17681   "<intfc> | sw_if_index <nn> \n"                                       \
17682   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
17683   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
17684 _(punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
17685 _(flow_classify_set_interface,                                          \
17686   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
17687 _(flow_classify_dump, "type [ip4|ip6]")                                 \
17688 _(ip_fib_dump, "")                                                      \
17689 _(ip6_fib_dump, "")                                                     \
17690 _(feature_enable_disable, "arc_name <arc_name> "                        \
17691   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
17692 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
17693 "[disable]")                                                            \
17694 _(l2_xconnect_dump, "")                                                 \
17695 _(sw_interface_set_mtu, "<intfc> | sw_if_index <nn> mtu <nn>")        \
17696 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
17697 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")
17698
17699 /* List of command functions, CLI names map directly to functions */
17700 #define foreach_cli_function                                    \
17701 _(comment, "usage: comment <ignore-rest-of-line>")              \
17702 _(dump_interface_table, "usage: dump_interface_table")          \
17703 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
17704 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
17705 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
17706 _(dump_stats_table, "usage: dump_stats_table")                  \
17707 _(dump_macro_table, "usage: dump_macro_table ")                 \
17708 _(dump_node_table, "usage: dump_node_table")                    \
17709 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
17710 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
17711 _(echo, "usage: echo <message>")                                \
17712 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
17713 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
17714 _(help, "usage: help")                                          \
17715 _(q, "usage: quit")                                             \
17716 _(quit, "usage: quit")                                          \
17717 _(search_node_table, "usage: search_node_table <name>...")      \
17718 _(set, "usage: set <variable-name> <value>")                    \
17719 _(script, "usage: script <file-name>")                          \
17720 _(unset, "usage: unset <variable-name>")
17721
17722 #define _(N,n)                                  \
17723     static void vl_api_##n##_t_handler_uni      \
17724     (vl_api_##n##_t * mp)                       \
17725     {                                           \
17726         vat_main_t * vam = &vat_main;           \
17727         if (vam->json_output) {                 \
17728             vl_api_##n##_t_handler_json(mp);    \
17729         } else {                                \
17730             vl_api_##n##_t_handler(mp);         \
17731         }                                       \
17732     }
17733 foreach_vpe_api_reply_msg;
17734 #undef _
17735
17736 void
17737 vat_api_hookup (vat_main_t * vam)
17738 {
17739 #define _(N,n)                                                  \
17740     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
17741                            vl_api_##n##_t_handler_uni,          \
17742                            vl_noop_handler,                     \
17743                            vl_api_##n##_t_endian,               \
17744                            vl_api_##n##_t_print,                \
17745                            sizeof(vl_api_##n##_t), 1);
17746   foreach_vpe_api_reply_msg;
17747 #undef _
17748
17749   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
17750
17751   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
17752
17753   vam->function_by_name = hash_create_string (0, sizeof (uword));
17754
17755   vam->help_by_name = hash_create_string (0, sizeof (uword));
17756
17757   /* API messages we can send */
17758 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
17759   foreach_vpe_api_msg;
17760 #undef _
17761
17762   /* Help strings */
17763 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17764   foreach_vpe_api_msg;
17765 #undef _
17766
17767   /* CLI functions */
17768 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
17769   foreach_cli_function;
17770 #undef _
17771
17772   /* Help strings */
17773 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
17774   foreach_cli_function;
17775 #undef _
17776 }
17777
17778 /*
17779  * fd.io coding-style-patch-verification: ON
17780  *
17781  * Local Variables:
17782  * eval: (c-set-style "gnu")
17783  * End:
17784  */